21 | * Counters should be written from the playback thread only. Counters may be read from any thread. 22 | * To ensure that the counter values are correctly reflected between threads, users of this class 23 | * should invoke {@link #ensureUpdated()} prior to reading and after writing. 24 | */ 25 | public final class CodecCounters { 26 | 27 | public int codecInitCount; 28 | public int codecReleaseCount; 29 | public int outputFormatChangedCount; 30 | public int outputBuffersChangedCount; 31 | public int renderedOutputBufferCount; 32 | public int skippedOutputBufferCount; 33 | public int droppedOutputBufferCount; 34 | 35 | /** 36 | * Should be invoked from the playback thread after the counters have been updated. Should also 37 | * be invoked from any other thread that wishes to read the counters, before reading. These calls 38 | * ensure that counter updates are made visible to the reading threads. 39 | */ 40 | public synchronized void ensureUpdated() { 41 | // Do nothing. The use of synchronized ensures a memory barrier should another thread also 42 | // call this method. 43 | } 44 | 45 | public String getDebugString() { 46 | ensureUpdated(); 47 | StringBuilder builder = new StringBuilder(); 48 | builder.append("cic(").append(codecInitCount).append(")"); 49 | builder.append("crc(").append(codecReleaseCount).append(")"); 50 | builder.append("ofc(").append(outputFormatChangedCount).append(")"); 51 | builder.append("obc(").append(outputBuffersChangedCount).append(")"); 52 | builder.append("ren(").append(renderedOutputBufferCount).append(")"); 53 | builder.append("sob(").append(skippedOutputBufferCount).append(")"); 54 | builder.append("dob(").append(droppedOutputBufferCount).append(")"); 55 | return builder.toString(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /library/src/main/java/com/google/android/exoplayer/CryptoInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.android.exoplayer; 17 | 18 | import com.google.android.exoplayer.util.Util; 19 | 20 | import android.annotation.TargetApi; 21 | import android.media.MediaExtractor; 22 | 23 | /** 24 | * Compatibility wrapper around {@link android.media.MediaCodec.CryptoInfo}. 25 | */ 26 | public class CryptoInfo { 27 | 28 | /** 29 | * @see android.media.MediaCodec.CryptoInfo#iv 30 | */ 31 | public byte[] iv; 32 | /** 33 | * @see android.media.MediaCodec.CryptoInfo#key 34 | */ 35 | public byte[] key; 36 | /** 37 | * @see android.media.MediaCodec.CryptoInfo#mode 38 | */ 39 | public int mode; 40 | /** 41 | * @see android.media.MediaCodec.CryptoInfo#numBytesOfClearData 42 | */ 43 | public int[] numBytesOfClearData; 44 | /** 45 | * @see android.media.MediaCodec.CryptoInfo#numBytesOfEncryptedData 46 | */ 47 | public int[] numBytesOfEncryptedData; 48 | /** 49 | * @see android.media.MediaCodec.CryptoInfo#numSubSamples 50 | */ 51 | public int numSubSamples; 52 | 53 | private final android.media.MediaCodec.CryptoInfo frameworkCryptoInfo; 54 | 55 | public CryptoInfo() { 56 | frameworkCryptoInfo = Util.SDK_INT >= 16 ? newFrameworkCryptoInfoV16() : null; 57 | } 58 | 59 | /** 60 | * @see android.media.MediaCodec.CryptoInfo#set(int, int[], int[], byte[], byte[], int) 61 | */ 62 | public void set(int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData, 63 | byte[] key, byte[] iv, int mode) { 64 | this.numSubSamples = numSubSamples; 65 | this.numBytesOfClearData = numBytesOfClearData; 66 | this.numBytesOfEncryptedData = numBytesOfEncryptedData; 67 | this.key = key; 68 | this.iv = iv; 69 | this.mode = mode; 70 | if (Util.SDK_INT >= 16) { 71 | updateFrameworkCryptoInfoV16(); 72 | } 73 | } 74 | 75 | /** 76 | * Equivalent to {@link MediaExtractor#getSampleCryptoInfo(android.media.MediaCodec.CryptoInfo)}. 77 | * 78 | * @param extractor The extractor from which to retrieve the crypto information. 79 | */ 80 | @TargetApi(16) 81 | public void setFromExtractorV16(MediaExtractor extractor) { 82 | extractor.getSampleCryptoInfo(frameworkCryptoInfo); 83 | numSubSamples = frameworkCryptoInfo.numSubSamples; 84 | numBytesOfClearData = frameworkCryptoInfo.numBytesOfClearData; 85 | numBytesOfEncryptedData = frameworkCryptoInfo.numBytesOfEncryptedData; 86 | key = frameworkCryptoInfo.key; 87 | iv = frameworkCryptoInfo.iv; 88 | mode = frameworkCryptoInfo.mode; 89 | } 90 | 91 | /** 92 | * Returns an equivalent {@link android.media.MediaCodec.CryptoInfo} instance. 93 | *
94 | * Successive calls to this method on a single {@link CryptoInfo} will return the same instance. 95 | * Changes to the {@link CryptoInfo} will be reflected in the returned object. The return object 96 | * should not be modified directly. 97 | * 98 | * @return The equivalent {@link android.media.MediaCodec.CryptoInfo} instance. 99 | */ 100 | @TargetApi(16) 101 | public android.media.MediaCodec.CryptoInfo getFrameworkCryptoInfoV16() { 102 | return frameworkCryptoInfo; 103 | } 104 | 105 | @TargetApi(16) 106 | private android.media.MediaCodec.CryptoInfo newFrameworkCryptoInfoV16() { 107 | return new android.media.MediaCodec.CryptoInfo(); 108 | } 109 | 110 | @TargetApi(16) 111 | private void updateFrameworkCryptoInfoV16() { 112 | frameworkCryptoInfo.set(numSubSamples, numBytesOfClearData, numBytesOfEncryptedData, key, iv, 113 | mode); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /library/src/main/java/com/google/android/exoplayer/DecoderInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.android.exoplayer; 17 | 18 | /** 19 | * Contains information about a media decoder. 20 | */ 21 | public final class DecoderInfo { 22 | 23 | /** 24 | * The name of the decoder. 25 | *
26 | * May be passed to {@link android.media.MediaCodec#createByCodecName(String)} to create an 27 | * instance of the decoder. 28 | */ 29 | public final String name; 30 | 31 | /** 32 | * Whether the decoder is adaptive. 33 | * 34 | * @see android.media.MediaCodecInfo.CodecCapabilities#isFeatureSupported(String) 35 | * @see android.media.MediaCodecInfo.CodecCapabilities#FEATURE_AdaptivePlayback 36 | */ 37 | public final boolean adaptive; 38 | 39 | /** 40 | * @param name The name of the decoder. 41 | * @param adaptive Whether the decoder is adaptive. 42 | */ 43 | /* package */ DecoderInfo(String name, boolean adaptive) { 44 | this.name = name; 45 | this.adaptive = adaptive; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.android.exoplayer; 17 | 18 | /** 19 | * A {@link TrackRenderer} that does nothing. 20 | *
21 | * This renderer returns {@link TrackRenderer#STATE_IGNORE} from {@link #doPrepare()} in order to 22 | * request that it should be ignored. {@link IllegalStateException} is thrown from all methods that 23 | * are documented to indicate that they should not be invoked unless the renderer is prepared. 24 | */ 25 | public class DummyTrackRenderer extends TrackRenderer { 26 | 27 | @Override 28 | protected int doPrepare() throws ExoPlaybackException { 29 | return STATE_IGNORE; 30 | } 31 | 32 | @Override 33 | protected boolean isEnded() { 34 | throw new IllegalStateException(); 35 | } 36 | 37 | @Override 38 | protected boolean isReady() { 39 | throw new IllegalStateException(); 40 | } 41 | 42 | @Override 43 | protected void seekTo(long timeUs) { 44 | throw new IllegalStateException(); 45 | } 46 | 47 | @Override 48 | protected void doSomeWork(long timeUs) { 49 | throw new IllegalStateException(); 50 | } 51 | 52 | @Override 53 | protected long getDurationUs() { 54 | throw new IllegalStateException(); 55 | } 56 | 57 | @Override 58 | protected long getBufferedPositionUs() { 59 | throw new IllegalStateException(); 60 | } 61 | 62 | @Override 63 | protected long getCurrentPositionUs() { 64 | throw new IllegalStateException(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /library/src/main/java/com/google/android/exoplayer/ExoPlaybackException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.android.exoplayer; 17 | 18 | /** 19 | * Thrown when a non-recoverable playback failure occurs. 20 | *
21 | * Where possible, the cause returned by {@link #getCause()} will indicate the reason for failure. 22 | */ 23 | public class ExoPlaybackException extends Exception { 24 | 25 | public ExoPlaybackException(String message) { 26 | super(message); 27 | } 28 | 29 | public ExoPlaybackException(Throwable cause) { 30 | super(cause); 31 | } 32 | 33 | public ExoPlaybackException(String message, Throwable cause) { 34 | super(message, cause); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /library/src/main/java/com/google/android/exoplayer/ExoPlayerLibraryInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.android.exoplayer; 17 | 18 | /** 19 | * Information about the ExoPlayer library. 20 | */ 21 | // TODO: This file should be automatically generated by the build system. 22 | public class ExoPlayerLibraryInfo { 23 | 24 | private ExoPlayerLibraryInfo() {} 25 | 26 | /** 27 | * The version of the library, expressed as a string. 28 | */ 29 | public static final String VERSION = "1.0.13"; 30 | 31 | /** 32 | * The version of the library, expressed as an integer. 33 | *
34 | * Three digits are used for each component of {@link #VERSION}. For example "1.2.3" has the 35 | * corresponding integer version 1002003. 36 | */ 37 | public static final int VERSION_INT = 1000013; 38 | 39 | /** 40 | * Whether the library was compiled with {@link com.google.android.exoplayer.util.Assertions} 41 | * checks enabled. 42 | */ 43 | public static final boolean ASSERTIONS_ENABLED = true; 44 | 45 | /** 46 | * Whether the library was compiled with {@link com.google.android.exoplayer.util.TraceUtil} 47 | * trace enabled. 48 | */ 49 | public static final boolean TRACE_ENABLED = true; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /library/src/main/java/com/google/android/exoplayer/LoadControl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.android.exoplayer; 17 | 18 | import com.google.android.exoplayer.upstream.Allocator; 19 | 20 | /** 21 | * Coordinates multiple loaders of time series data. 22 | */ 23 | public interface LoadControl { 24 | 25 | /** 26 | * Registers a loader. 27 | * 28 | * @param loader The loader being registered. 29 | * @param bufferSizeContribution For controls whose {@link Allocator}s maintain a pool of memory 30 | * for the purpose of satisfying allocation requests, this is a hint indicating the loader's 31 | * desired contribution to the size of the pool, in bytes. 32 | */ 33 | void register(Object loader, int bufferSizeContribution); 34 | 35 | /** 36 | * Unregisters a loader. 37 | * 38 | * @param loader The loader being unregistered. 39 | */ 40 | void unregister(Object loader); 41 | 42 | /** 43 | * Gets the {@link Allocator} that loaders should use to obtain memory allocations into which 44 | * data can be loaded. 45 | * 46 | * @return The {@link Allocator} to use. 47 | */ 48 | Allocator getAllocator(); 49 | 50 | /** 51 | * Hints to the control that it should consider trimming any unused memory being held in order 52 | * to satisfy allocation requests. 53 | *
54 | * This method is typically invoked by a recently unregistered loader, once it has released all 55 | * of its allocations back to the {@link Allocator}. 56 | */ 57 | void trimAllocator(); 58 | 59 | /** 60 | * Invoked by a loader to update the control with its current state. 61 | *
62 | * This method must be called by a registered loader whenever its state changes. This is true
63 | * even if the registered loader does not itself wish to start its next load (since the state of
64 | * the loader will still affect whether other registered loaders are allowed to proceed).
65 | *
66 | * @param loader The loader invoking the update.
67 | * @param playbackPositionUs The loader's playback position.
68 | * @param nextLoadPositionUs The loader's next load position, or -1 if finished.
69 | * @param loading Whether the loader is currently loading data.
70 | * @param failed Whether the loader has failed, meaning it does not wish to load more data.
71 | * @return True if the loader is allowed to start its next load. False otherwise.
72 | */
73 | boolean update(Object loader, long playbackPositionUs, long nextLoadPositionUs,
74 | boolean loading, boolean failed);
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/MediaClock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer;
17 |
18 | import android.os.SystemClock;
19 |
20 | /**
21 | * A simple clock for tracking the progression of media time. The clock can be started, stopped and
22 | * its time can be set and retrieved. When started, this clock is based on
23 | * {@link SystemClock#elapsedRealtime()}.
24 | */
25 | /* package */ class MediaClock {
26 |
27 | private boolean started;
28 |
29 | /**
30 | * The media time when the clock was last set or stopped.
31 | */
32 | private long timeUs;
33 |
34 | /**
35 | * The difference between {@link SystemClock#elapsedRealtime()} and {@link #timeUs}
36 | * when the clock was last set or started.
37 | */
38 | private long deltaUs;
39 |
40 | /**
41 | * Starts the clock. Does nothing if the clock is already started.
42 | */
43 | public void start() {
44 | if (!started) {
45 | started = true;
46 | deltaUs = elapsedRealtimeMinus(timeUs);
47 | }
48 | }
49 |
50 | /**
51 | * Stops the clock. Does nothing if the clock is already stopped.
52 | */
53 | public void stop() {
54 | if (started) {
55 | timeUs = elapsedRealtimeMinus(deltaUs);
56 | started = false;
57 | }
58 | }
59 |
60 | /**
61 | * @param timeUs The time to set in microseconds.
62 | */
63 | public void setTimeUs(long timeUs) {
64 | this.timeUs = timeUs;
65 | deltaUs = elapsedRealtimeMinus(timeUs);
66 | }
67 |
68 | /**
69 | * @return The current time in microseconds.
70 | */
71 | public long getTimeUs() {
72 | return started ? elapsedRealtimeMinus(deltaUs) : timeUs;
73 | }
74 |
75 | private long elapsedRealtimeMinus(long microSeconds) {
76 | return SystemClock.elapsedRealtime() * 1000 - microSeconds;
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/MediaFormatHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer;
17 |
18 | import java.util.Map;
19 | import java.util.UUID;
20 |
21 | /**
22 | * Holds a {@link MediaFormat} and corresponding drm scheme initialization data.
23 | */
24 | public final class MediaFormatHolder {
25 |
26 | /**
27 | * The format of the media.
28 | */
29 | public MediaFormat format;
30 | /**
31 | * Initialization data for each of the drm schemes supported by the media, keyed by scheme UUID.
32 | * Null if the media is not encrypted.
33 | */
34 | public Map
31 | * This tolerance is useful for fullscreen playbacks, since it ensures that the surface will
32 | * occupy the whole of the screen when playing content that has the same (or virtually the same)
33 | * aspect ratio as the device. This typically reduces the number of view layers that need to be
34 | * composited by the underlying system, which can help to reduce power consumption.
35 | */
36 | private static final float MAX_ASPECT_RATIO_DEFORMATION_PERCENT = 0.01f;
37 |
38 | private float videoAspectRatio;
39 |
40 | public VideoSurfaceView(Context context) {
41 | super(context);
42 | }
43 |
44 | public VideoSurfaceView(Context context, AttributeSet attrs) {
45 | super(context, attrs);
46 | }
47 |
48 | /**
49 | * Set the aspect ratio that this {@link VideoSurfaceView} should satisfy.
50 | *
51 | * @param widthHeightRatio The width to height ratio.
52 | */
53 | public void setVideoWidthHeightRatio(float widthHeightRatio) {
54 | if (this.videoAspectRatio != widthHeightRatio) {
55 | this.videoAspectRatio = widthHeightRatio;
56 | requestLayout();
57 | }
58 | }
59 |
60 | @Override
61 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
62 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
63 | int width = getMeasuredWidth();
64 | int height = getMeasuredHeight();
65 | if (videoAspectRatio != 0) {
66 | float viewAspectRatio = (float) width / height;
67 | float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
68 | if (aspectDeformation > MAX_ASPECT_RATIO_DEFORMATION_PERCENT) {
69 | height = (int) (width / videoAspectRatio);
70 | } else if (aspectDeformation < -MAX_ASPECT_RATIO_DEFORMATION_PERCENT) {
71 | width = (int) (height * videoAspectRatio);
72 | }
73 | }
74 | setMeasuredDimension(width, height);
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/chunk/ChunkOperationHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.chunk;
17 |
18 | /**
19 | * Holds a chunk operation, which consists of a {@link Chunk} to load together with the number of
20 | * {@link MediaChunk}s that should be retained on the queue.
21 | */
22 | public final class ChunkOperationHolder {
23 |
24 | /**
25 | * The number of {@link MediaChunk}s to retain in a queue.
26 | */
27 | public int queueSize;
28 |
29 | /**
30 | * The chunk.
31 | */
32 | public Chunk chunk;
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.chunk;
17 |
18 | import com.google.android.exoplayer.ExoPlaybackException;
19 | import com.google.android.exoplayer.ExoPlayer.ExoPlayerComponent;
20 | import com.google.android.exoplayer.MediaFormat;
21 | import com.google.android.exoplayer.TrackInfo;
22 | import com.google.android.exoplayer.util.Assertions;
23 |
24 | import java.io.IOException;
25 | import java.util.List;
26 |
27 | /**
28 | * A {@link ChunkSource} providing the ability to switch between multiple other {@link ChunkSource}
29 | * instances.
30 | */
31 | public class MultiTrackChunkSource implements ChunkSource, ExoPlayerComponent {
32 |
33 | /**
34 | * A message to indicate a source selection. Source selection can only be performed when the
35 | * source is disabled.
36 | */
37 | public static final int MSG_SELECT_TRACK = 1;
38 |
39 | private final ChunkSource[] allSources;
40 |
41 | private ChunkSource selectedSource;
42 | private boolean enabled;
43 |
44 | public MultiTrackChunkSource(ChunkSource... sources) {
45 | this.allSources = sources;
46 | this.selectedSource = sources[0];
47 | }
48 |
49 | /**
50 | * Gets the number of tracks that this source can switch between. May be called safely from any
51 | * thread.
52 | *
53 | * @return The number of tracks.
54 | */
55 | public int getTrackCount() {
56 | return allSources.length;
57 | }
58 |
59 | @Override
60 | public TrackInfo getTrackInfo() {
61 | return selectedSource.getTrackInfo();
62 | }
63 |
64 | @Override
65 | public void enable() {
66 | selectedSource.enable();
67 | enabled = true;
68 | }
69 |
70 | @Override
71 | public void disable(List extends MediaChunk> queue) {
72 | selectedSource.disable(queue);
73 | enabled = false;
74 | }
75 |
76 | @Override
77 | public void continueBuffering(long playbackPositionUs) {
78 | selectedSource.continueBuffering(playbackPositionUs);
79 | }
80 |
81 | @Override
82 | public void getChunkOperation(List extends MediaChunk> queue, long seekPositionUs,
83 | long playbackPositionUs, ChunkOperationHolder out) {
84 | selectedSource.getChunkOperation(queue, seekPositionUs, playbackPositionUs, out);
85 | }
86 |
87 | @Override
88 | public IOException getError() {
89 | return null;
90 | }
91 |
92 | @Override
93 | public void getMaxVideoDimensions(MediaFormat out) {
94 | selectedSource.getMaxVideoDimensions(out);
95 | }
96 |
97 | @Override
98 | public void handleMessage(int what, Object msg) throws ExoPlaybackException {
99 | Assertions.checkState(!enabled);
100 | if (what == MSG_SELECT_TRACK) {
101 | selectedSource = allSources[(Integer) msg];
102 | }
103 | }
104 |
105 | @Override
106 | public void onChunkLoadError(Chunk chunk, Exception e) {
107 | selectedSource.onChunkLoadError(chunk, e);
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/dash/DashSegmentIndex.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.dash;
17 |
18 | import com.google.android.exoplayer.dash.mpd.RangedUri;
19 |
20 | /**
21 | * Indexes the segments within a media stream.
22 | *
23 | * TODO: Generalize to cover all chunk streaming modes (e.g. SmoothStreaming) if possible.
24 | */
25 | public interface DashSegmentIndex {
26 |
27 | /**
28 | * Returns the segment number of the segment containing a given media time.
29 | *
30 | * @param timeUs The time in microseconds.
31 | * @return The segment number of the corresponding segment.
32 | */
33 | int getSegmentNum(long timeUs);
34 |
35 | /**
36 | * Returns the start time of a segment.
37 | *
38 | * @param segmentNum The segment number.
39 | * @return The corresponding start time in microseconds.
40 | */
41 | long getTimeUs(int segmentNum);
42 |
43 | /**
44 | * Returns the duration of a segment.
45 | *
46 | * @param segmentNum The segment number.
47 | * @return The duration of the segment, in microseconds.
48 | */
49 | long getDurationUs(int segmentNum);
50 |
51 | /**
52 | * Returns a {@link RangedUri} defining the location of a segment.
53 | *
54 | * @param segmentNum The segment number.
55 | * @return The {@link RangedUri} defining the location of the data.
56 | */
57 | RangedUri getSegmentUrl(int segmentNum);
58 |
59 | /**
60 | * Returns the segment number of the first segment.
61 | *
62 | * @return The segment number of the first segment.
63 | */
64 | int getFirstSegmentNum();
65 |
66 | /**
67 | * Returns the segment number of the last segment.
68 | *
69 | * @return The segment number of the last segment.
70 | */
71 | int getLastSegmentNum();
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/dash/DashWrappingSegmentIndex.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.dash;
17 |
18 | import com.google.android.exoplayer.dash.mpd.RangedUri;
19 | import com.google.android.exoplayer.parser.SegmentIndex;
20 | import com.google.android.exoplayer.util.Util;
21 |
22 | import android.net.Uri;
23 |
24 | /**
25 | * An implementation of {@link DashSegmentIndex} that wraps a {@link SegmentIndex} parsed from a
26 | * media stream.
27 | */
28 | public class DashWrappingSegmentIndex implements DashSegmentIndex {
29 |
30 | private final SegmentIndex segmentIndex;
31 | private final Uri uri;
32 | private final long indexAnchor;
33 |
34 | /**
35 | * @param segmentIndex The {@link SegmentIndex} to wrap.
36 | * @param uri The {@link Uri} where the data is located.
37 | * @param indexAnchor The index anchor point. This value is added to the byte offsets specified
38 | * in the wrapped {@link SegmentIndex}.
39 | */
40 | public DashWrappingSegmentIndex(SegmentIndex segmentIndex, Uri uri, long indexAnchor) {
41 | this.segmentIndex = segmentIndex;
42 | this.uri = uri;
43 | this.indexAnchor = indexAnchor;
44 | }
45 |
46 | @Override
47 | public int getFirstSegmentNum() {
48 | return 0;
49 | }
50 |
51 | @Override
52 | public int getLastSegmentNum() {
53 | return segmentIndex.length - 1;
54 | }
55 |
56 | @Override
57 | public long getTimeUs(int segmentNum) {
58 | return segmentIndex.timesUs[segmentNum];
59 | }
60 |
61 | @Override
62 | public long getDurationUs(int segmentNum) {
63 | return segmentIndex.durationsUs[segmentNum];
64 | }
65 |
66 | @Override
67 | public RangedUri getSegmentUrl(int segmentNum) {
68 | return new RangedUri(uri, null, indexAnchor + segmentIndex.offsets[segmentNum],
69 | segmentIndex.sizes[segmentNum]);
70 | }
71 |
72 | @Override
73 | public int getSegmentNum(long timeUs) {
74 | return Util.binarySearchFloor(segmentIndex.timesUs, timeUs, true, true);
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/dash/mpd/AdaptationSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.dash.mpd;
17 |
18 | import java.util.Collections;
19 | import java.util.List;
20 |
21 | /**
22 | * Represents a set of interchangeable encoded versions of a media content component.
23 | */
24 | public final class AdaptationSet {
25 |
26 | public static final int TYPE_UNKNOWN = -1;
27 | public static final int TYPE_VIDEO = 0;
28 | public static final int TYPE_AUDIO = 1;
29 | public static final int TYPE_TEXT = 2;
30 |
31 | public final int id;
32 |
33 | public final int type;
34 |
35 | public final List
29 | * This class is provided for convenience, however it is expected that most applications will
30 | * contain their own mechanisms for making asynchronous network requests and parsing the response.
31 | * In such cases it is recommended that application developers use their existing solution rather
32 | * than this one.
33 | */
34 | public final class MediaPresentationDescriptionFetcher extends
35 | ManifestFetcher
77 | * This method may be called when the manager is in the following states:
78 | * {@link #STATE_OPENED}, {@link #STATE_OPENED_WITH_KEYS}
79 | *
80 | * @return A {@link MediaCrypto} for the open session.
81 | * @throws IllegalStateException If called when a session isn't opened.
82 | */
83 | MediaCrypto getMediaCrypto();
84 |
85 | /**
86 | * Whether the session requires a secure decoder for the specified mime type.
87 | *
88 | * Normally this method should return {@link MediaCrypto#requiresSecureDecoderComponent(String)},
89 | * however in some cases implementations may wish to modify the return value (i.e. to force a
90 | * secure decoder even when one is not required).
91 | *
92 | * This method may be called when the manager is in the following states:
93 | * {@link #STATE_OPENED}, {@link #STATE_OPENED_WITH_KEYS}
94 | *
95 | * @return Whether the open session requires a secure decoder for the specified mime type.
96 | * @throws IllegalStateException If called when a session isn't opened.
97 | */
98 | boolean requiresSecureDecoderComponent(String mimeType);
99 |
100 | /**
101 | * Gets the cause of the error state.
102 | *
103 | * This method may be called when the manager is in any state.
104 | *
105 | * @return An exception if the state is {@link #STATE_ERROR}. Null otherwise.
106 | */
107 | Exception getError();
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/drm/MediaDrmCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.drm;
17 |
18 | import android.annotation.TargetApi;
19 | import android.media.MediaDrm;
20 |
21 | import java.util.UUID;
22 |
23 | /**
24 | * Performs {@link MediaDrm} key and provisioning requests.
25 | */
26 | @TargetApi(18)
27 | public interface MediaDrmCallback {
28 |
29 | /**
30 | * Executes a provisioning request.
31 | *
32 | * @param uuid The UUID of the content protection scheme.
33 | * @param request The request.
34 | * @return The response data.
35 | * @throws Exception If an error occurred executing the request.
36 | */
37 | byte[] executeProvisionRequest(UUID uuid, MediaDrm.ProvisionRequest request) throws Exception;
38 |
39 | /**
40 | * Executes a key request.
41 | *
42 | * @param uuid The UUID of the content protection scheme.
43 | * @param request The request.
44 | * @return The response data.
45 | * @throws Exception If an error occurred executing the request.
46 | */
47 | byte[] executeKeyRequest(UUID uuid, MediaDrm.KeyRequest request) throws Exception;
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/parser/Extractor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.parser;
17 |
18 | import com.google.android.exoplayer.MediaFormat;
19 | import com.google.android.exoplayer.ParserException;
20 | import com.google.android.exoplayer.SampleHolder;
21 | import com.google.android.exoplayer.upstream.NonBlockingInputStream;
22 |
23 | import java.util.Map;
24 | import java.util.UUID;
25 |
26 | /**
27 | * Facilitates extraction of media samples from a container format.
28 | */
29 | public interface Extractor {
30 |
31 | /**
32 | * An attempt to read from the input stream returned insufficient data.
33 | */
34 | public static final int RESULT_NEED_MORE_DATA = 1;
35 | /**
36 | * The end of the input stream was reached.
37 | */
38 | public static final int RESULT_END_OF_STREAM = 2;
39 | /**
40 | * A media sample was read.
41 | */
42 | public static final int RESULT_READ_SAMPLE = 4;
43 | /**
44 | * Initialization data was read. The parsed data can be read using {@link #getFormat()} and
45 | * {@link #getPsshInfo}.
46 | */
47 | public static final int RESULT_READ_INIT = 8;
48 | /**
49 | * A sidx atom was read. The parsed data can be read using {@link #getIndex()}.
50 | */
51 | public static final int RESULT_READ_INDEX = 16;
52 | /**
53 | * The next thing to be read is a sample, but a {@link SampleHolder} was not supplied.
54 | */
55 | public static final int RESULT_NEED_SAMPLE_HOLDER = 32;
56 |
57 | /**
58 | * Returns the segment index parsed from the stream.
59 | *
60 | * @return The segment index, or null if a SIDX atom has yet to be parsed.
61 | */
62 | public SegmentIndex getIndex();
63 |
64 | /**
65 | * Returns true if the offsets in the index returned by {@link #getIndex()} are relative to the
66 | * first byte following the initialization data, or false if they are absolute (i.e. relative to
67 | * the first byte of the stream).
68 | *
69 | * @return True if the offsets are relative to the first byte following the initialization data.
70 | * False otherwise.
71 | */
72 | public boolean hasRelativeIndexOffsets();
73 |
74 | /**
75 | * Returns the format of the samples contained within the media stream.
76 | *
77 | * @return The sample media format, or null if the format has yet to be parsed.
78 | */
79 | public MediaFormat getFormat();
80 |
81 | /**
82 | * Returns the pssh information parsed from the stream.
83 | *
84 | * @return The pssh information. May be null if pssh data has yet to be parsed, or if the stream
85 | * does not contain any pssh data.
86 | */
87 | public Map
92 | * The read terminates if the end of the input stream is reached, if an attempt to read from the
93 | * input stream returned 0 bytes of data, or if a sample is read. The returned flags indicate
94 | * both the reason for termination and data that was parsed during the read.
95 | *
96 | * @param inputStream The input stream from which data should be read.
97 | * @param out A {@link SampleHolder} into which the next sample should be read. If null then
98 | * {@link #RESULT_NEED_SAMPLE_HOLDER} will be returned once a sample has been reached.
99 | * @return One or more of the {@code RESULT_*} flags defined in this class.
100 | * @throws ParserException If an error occurs parsing the media data.
101 | */
102 | public int read(NonBlockingInputStream inputStream, SampleHolder out) throws ParserException;
103 |
104 | /**
105 | * Seeks to a position before or equal to the requested time.
106 | *
107 | * @param seekTimeUs The desired seek time in microseconds.
108 | * @param allowNoop Allow the seek operation to do nothing if the seek time is in the current
109 | * fragment run, is equal to or greater than the time of the current sample, and if there
110 | * does not exist a sync frame between these two times.
111 | * @return True if the operation resulted in a change of state. False if it was a no-op.
112 | */
113 | public boolean seekTo(long seekTimeUs, boolean allowNoop);
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/parser/SegmentIndex.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.parser;
17 |
18 | /**
19 | * Defines segments within a media stream.
20 | */
21 | public final class SegmentIndex {
22 |
23 | /**
24 | * The size in bytes of the segment index as it exists in the stream.
25 | */
26 | public final int sizeBytes;
27 |
28 | /**
29 | * The number of segments.
30 | */
31 | public final int length;
32 |
33 | /**
34 | * The segment sizes, in bytes.
35 | */
36 | public final int[] sizes;
37 |
38 | /**
39 | * The segment byte offsets.
40 | */
41 | public final long[] offsets;
42 |
43 | /**
44 | * The segment durations, in microseconds.
45 | */
46 | public final long[] durationsUs;
47 |
48 | /**
49 | * The start time of each segment, in microseconds.
50 | */
51 | public final long[] timesUs;
52 |
53 | /**
54 | * @param sizeBytes The size in bytes of the segment index as it exists in the stream.
55 | * @param sizes The segment sizes, in bytes.
56 | * @param offsets The segment byte offsets.
57 | * @param durationsUs The segment durations, in microseconds.
58 | * @param timesUs The start time of each segment, in microseconds.
59 | */
60 | public SegmentIndex(int sizeBytes, int[] sizes, long[] offsets, long[] durationsUs,
61 | long[] timesUs) {
62 | this.sizeBytes = sizeBytes;
63 | this.length = sizes.length;
64 | this.sizes = sizes;
65 | this.offsets = offsets;
66 | this.durationsUs = durationsUs;
67 | this.timesUs = timesUs;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/parser/mp4/Atom.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.parser.mp4;
17 |
18 | import java.util.ArrayList;
19 |
20 | /* package */ abstract class Atom {
21 |
22 | public static final int TYPE_avc1 = 0x61766331;
23 | public static final int TYPE_avc3 = 0x61766333;
24 | public static final int TYPE_esds = 0x65736473;
25 | public static final int TYPE_mdat = 0x6D646174;
26 | public static final int TYPE_mp4a = 0x6D703461;
27 | public static final int TYPE_tfdt = 0x74666474;
28 | public static final int TYPE_tfhd = 0x74666864;
29 | public static final int TYPE_trex = 0x74726578;
30 | public static final int TYPE_trun = 0x7472756E;
31 | public static final int TYPE_sidx = 0x73696478;
32 | public static final int TYPE_moov = 0x6D6F6F76;
33 | public static final int TYPE_trak = 0x7472616B;
34 | public static final int TYPE_mdia = 0x6D646961;
35 | public static final int TYPE_minf = 0x6D696E66;
36 | public static final int TYPE_stbl = 0x7374626C;
37 | public static final int TYPE_avcC = 0x61766343;
38 | public static final int TYPE_moof = 0x6D6F6F66;
39 | public static final int TYPE_traf = 0x74726166;
40 | public static final int TYPE_mvex = 0x6D766578;
41 | public static final int TYPE_tkhd = 0x746B6864;
42 | public static final int TYPE_mdhd = 0x6D646864;
43 | public static final int TYPE_hdlr = 0x68646C72;
44 | public static final int TYPE_stsd = 0x73747364;
45 | public static final int TYPE_pssh = 0x70737368;
46 | public static final int TYPE_sinf = 0x73696E66;
47 | public static final int TYPE_schm = 0x7363686D;
48 | public static final int TYPE_schi = 0x73636869;
49 | public static final int TYPE_tenc = 0x74656E63;
50 | public static final int TYPE_encv = 0x656E6376;
51 | public static final int TYPE_enca = 0x656E6361;
52 | public static final int TYPE_frma = 0x66726D61;
53 | public static final int TYPE_saiz = 0x7361697A;
54 | public static final int TYPE_uuid = 0x75756964;
55 | public static final int TYPE_senc = 0x73656E63;
56 |
57 | public final int type;
58 |
59 | Atom(int type) {
60 | this.type = type;
61 | }
62 |
63 | public final static class LeafAtom extends Atom {
64 |
65 | public final ParsableByteArray data;
66 |
67 | public LeafAtom(int type, ParsableByteArray data) {
68 | super(type);
69 | this.data = data;
70 | }
71 |
72 | }
73 |
74 | public final static class ContainerAtom extends Atom {
75 |
76 | public final ArrayList EBML can be summarized as a binary XML format somewhat similar to Protocol Buffers.
27 | * It was originally designed for the Matroska container format. More information about EBML and
28 | * Matroska is available here.
29 | */
30 | /* package */ interface EbmlReader {
31 |
32 | // Element Types
33 | /** Undefined element. */
34 | public static final int TYPE_UNKNOWN = 0;
35 | /** Contains child elements. */
36 | public static final int TYPE_MASTER = 1;
37 | /** Unsigned integer value of up to 8 bytes. */
38 | public static final int TYPE_UNSIGNED_INT = 2;
39 | public static final int TYPE_STRING = 3;
40 | public static final int TYPE_BINARY = 4;
41 | /** IEEE floating point value of either 4 or 8 bytes. */
42 | public static final int TYPE_FLOAT = 5;
43 |
44 | // Return values for reading methods.
45 | public static final int READ_RESULT_CONTINUE = 0;
46 | public static final int READ_RESULT_NEED_MORE_DATA = 1;
47 | public static final int READ_RESULT_END_OF_STREAM = 2;
48 |
49 | public void setEventHandler(EbmlEventHandler eventHandler);
50 |
51 | /**
52 | * Reads from a {@link NonBlockingInputStream}, invoking an event callback if possible.
53 | *
54 | * @param inputStream The input stream from which data should be read
55 | * @return One of the {@code RESULT_*} flags defined in this interface
56 | */
57 | public int read(NonBlockingInputStream inputStream);
58 |
59 | /**
60 | * The total number of bytes consumed by the reader since first created or last {@link #reset()}.
61 | */
62 | public long getBytesRead();
63 |
64 | /**
65 | * Resets the entire state of the reader so that it will read a new EBML structure from scratch.
66 | *
67 | * This includes resetting the value returned from {@link #getBytesRead()} to 0 and discarding
68 | * all pending {@link EbmlEventHandler#onMasterElementEnd(int)} events.
69 | */
70 | public void reset();
71 |
72 | /**
73 | * Reads, parses, and returns an EBML variable-length integer (varint) from the contents
74 | * of a binary element.
75 | *
76 | * @param inputStream The input stream from which data should be read
77 | * @return The varint value at the current position of the contents of a binary element
78 | */
79 | public long readVarint(NonBlockingInputStream inputStream);
80 |
81 | /**
82 | * Reads a fixed number of bytes from the contents of a binary element into a {@link ByteBuffer}.
83 | *
84 | * @param inputStream The input stream from which data should be read
85 | * @param byteBuffer The {@link ByteBuffer} to which data should be written
86 | * @param totalBytes The fixed number of bytes to be read and written
87 | */
88 | public void readBytes(NonBlockingInputStream inputStream, ByteBuffer byteBuffer, int totalBytes);
89 |
90 | /**
91 | * Reads a fixed number of bytes from the contents of a binary element into a {@code byte[]}.
92 | *
93 | * @param inputStream The input stream from which data should be read
94 | * @param byteArray The byte array to which data should be written
95 | * @param totalBytes The fixed number of bytes to be read and written
96 | */
97 | public void readBytes(NonBlockingInputStream inputStream, byte[] byteArray, int totalBytes);
98 |
99 | /**
100 | * Skips a fixed number of bytes from the contents of a binary element.
101 | *
102 | * @param inputStream The input stream from which data should be skipped
103 | * @param totalBytes The fixed number of bytes to be skipped
104 | */
105 | public void skipBytes(NonBlockingInputStream inputStream, int totalBytes);
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestFetcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.smoothstreaming;
17 |
18 | import com.google.android.exoplayer.ParserException;
19 | import com.google.android.exoplayer.util.ManifestFetcher;
20 |
21 | import android.net.Uri;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 |
26 | /**
27 | * A concrete implementation of {@link ManifestFetcher} for loading SmoothStreaming
28 | * manifests.
29 | *
30 | * This class is provided for convenience, however it is expected that most applications will
31 | * contain their own mechanisms for making asynchronous network requests and parsing the response.
32 | * In such cases it is recommended that application developers use their existing solution rather
33 | * than this one.
34 | */
35 | public final class SmoothStreamingManifestFetcher extends ManifestFetcher
26 | * Note that the value returned may be less than {@code getEventTime(0)}, since a subtitle may
27 | * begin prior to the time of the first event.
28 | *
29 | * @return The start time of the subtitle in microseconds.
30 | */
31 | public long getStartTime();
32 |
33 | /**
34 | * Gets the index of the first event that occurs after a given time (exclusive).
35 | *
36 | * @param timeUs The time in microseconds.
37 | * @return The index of the next event, or -1 if there are no events after the specified time.
38 | */
39 | public int getNextEventTimeIndex(long timeUs);
40 |
41 | /**
42 | * Gets the number of event times, where events are defined as points in time at which the text
43 | * returned by {@link #getText(long)} changes.
44 | *
45 | * @return The number of event times.
46 | */
47 | public int getEventTimeCount();
48 |
49 | /**
50 | * Gets the event time at a specified index.
51 | *
52 | * @param index The index of the event time to obtain.
53 | * @return The event time in microseconds.
54 | */
55 | public long getEventTime(int index);
56 |
57 | /**
58 | * Convenience method for obtaining the last event time.
59 | *
60 | * @return The time of the last event in microseconds, or -1 if {@code getEventTimeCount() == 0}.
61 | */
62 | public long getLastEventTime();
63 |
64 | /**
65 | * Retrieve the subtitle text that should be displayed at a given time.
66 | *
67 | * @param timeUs The time in microseconds.
68 | * @return The text that should be displayed, or null.
69 | */
70 | public String getText(long timeUs);
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/text/SubtitleParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.text;
17 |
18 | import java.io.IOException;
19 | import java.io.InputStream;
20 |
21 | /**
22 | * Parses {@link Subtitle}s from {@link InputStream}s.
23 | */
24 | public interface SubtitleParser {
25 |
26 | /**
27 | * Checks whether the parser supports a given subtitle mime type.
28 | *
29 | * @param mimeType A subtitle mime type.
30 | * @return Whether the mime type is supported.
31 | */
32 | public boolean canParse(String mimeType);
33 |
34 | /**
35 | * Parses a {@link Subtitle} from the provided {@link InputStream}.
36 | *
37 | * @param inputStream The stream from which to parse the subtitle.
38 | * @param inputEncoding The encoding of the input stream.
39 | * @param startTimeUs The start time of the subtitle.
40 | * @return A parsed representation of the subtitle.
41 | * @throws IOException If a problem occurred reading from the stream.
42 | */
43 | public Subtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs)
44 | throws IOException;
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlSubtitle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.text.ttml;
17 |
18 | import com.google.android.exoplayer.text.Subtitle;
19 | import com.google.android.exoplayer.util.Util;
20 |
21 | /**
22 | * A representation of a TTML subtitle.
23 | */
24 | public final class TtmlSubtitle implements Subtitle {
25 |
26 | private final TtmlNode root;
27 | private final long startTimeUs;
28 | private final long[] eventTimesUs;
29 |
30 | public TtmlSubtitle(TtmlNode root, long startTimeUs) {
31 | this.root = root;
32 | this.startTimeUs = startTimeUs;
33 | this.eventTimesUs = root.getEventTimesUs();
34 | }
35 |
36 | @Override
37 | public long getStartTime() {
38 | return startTimeUs;
39 | }
40 |
41 | @Override
42 | public int getNextEventTimeIndex(long timeUs) {
43 | int index = Util.binarySearchCeil(eventTimesUs, timeUs - startTimeUs, false, false);
44 | return index < eventTimesUs.length ? index : -1;
45 | }
46 |
47 | @Override
48 | public int getEventTimeCount() {
49 | return eventTimesUs.length;
50 | }
51 |
52 | @Override
53 | public long getEventTime(int index) {
54 | return eventTimesUs[index] + startTimeUs;
55 | }
56 |
57 | @Override
58 | public long getLastEventTime() {
59 | return (eventTimesUs.length == 0 ? -1 : eventTimesUs[eventTimesUs.length - 1]) + startTimeUs;
60 | }
61 |
62 | @Override
63 | public String getText(long timeUs) {
64 | return root.getText(timeUs - startTimeUs);
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/Allocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | /**
19 | * An {@link Allocation}, defined to consist of a set of fragments of underlying byte arrays.
20 | *
21 | * The byte arrays in which the fragments are located are obtained by {@link #getBuffers}. For
22 | * each, the offset and length of the fragment within the byte array are obtained using
23 | * {@link #getFragmentOffset} and {@link #getFragmentLength} respectively.
24 | */
25 | public interface Allocation {
26 |
27 | /**
28 | * Ensures the allocation has a capacity greater than or equal to the specified size in bytes.
29 | *
30 | * If {@code size} is greater than the current capacity of the allocation, then it will grow
31 | * to have a capacity of at least {@code size}. The allocation is grown by adding new fragments.
32 | * Existing fragments remain unchanged, and any data that has been written to them will be
33 | * preserved.
34 | *
35 | * If {@code size} is less than or equal to the capacity of the allocation, then the call is a
36 | * no-op.
37 | *
38 | * @param size The minimum required capacity, in bytes.
39 | */
40 | public void ensureCapacity(int size);
41 |
42 | /**
43 | * Gets the capacity of the allocation, in bytes.
44 | *
45 | * @return The capacity of the allocation, in bytes.
46 | */
47 | public int capacity();
48 |
49 | /**
50 | * Gets the buffers in which the fragments are allocated.
51 | *
52 | * @return The buffers in which the fragments are allocated.
53 | */
54 | public byte[][] getBuffers();
55 |
56 | /**
57 | * The offset of the fragment in the buffer at the specified index.
58 | *
59 | * @param index The index of the buffer.
60 | * @return The offset of the fragment in the buffer.
61 | */
62 | public int getFragmentOffset(int index);
63 |
64 | /**
65 | * The length of the fragment in the buffer at the specified index.
66 | *
67 | * @param index The index of the buffer.
68 | * @return The length of the fragment in the buffer.
69 | */
70 | public int getFragmentLength(int index);
71 |
72 | /**
73 | * Releases the allocation.
74 | */
75 | public void release();
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/Allocator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | /**
19 | * A source of {@link Allocation}s.
20 | */
21 | public interface Allocator {
22 |
23 | /**
24 | * Obtains an allocation of at least the specified size.
25 | *
26 | * @param size The size of the required allocation, in bytes.
27 | * @return The allocation.
28 | */
29 | public Allocation allocate(int size);
30 |
31 | /**
32 | * Hints to the {@link Allocator} that it should make a best effort to release any memory that it
33 | * has allocated for the purpose of backing {@link Allocation}s, beyond the specified target
34 | * number of bytes.
35 | *
36 | * @param targetSize The target size in bytes.
37 | */
38 | public void trim(int targetSize);
39 |
40 | /**
41 | * Returns the number of bytes currently allocated in the form of {@link Allocation}s.
42 | *
43 | * @return The number of allocated bytes.
44 | */
45 | public int getAllocatedSize();
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/BandwidthMeter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | /**
19 | * Provides estimates of the currently available bandwidth.
20 | */
21 | public interface BandwidthMeter {
22 |
23 | /**
24 | * Indicates no bandwidth estimate is available.
25 | */
26 | final long NO_ESTIMATE = -1;
27 |
28 | /**
29 | * Gets the estimated bandwidth, in bits/sec.
30 | *
31 | * @return Estimated bandwidth in bits/sec, or {@link #NO_ESTIMATE} if no estimate is available.
32 | */
33 | long getBitrateEstimate();
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/ByteArrayDataSink.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.C;
19 | import com.google.android.exoplayer.util.Assertions;
20 |
21 | import java.io.ByteArrayOutputStream;
22 | import java.io.IOException;
23 |
24 | /**
25 | * A {@link DataSink} for writing to a byte array.
26 | */
27 | public class ByteArrayDataSink implements DataSink {
28 |
29 | private ByteArrayOutputStream stream;
30 |
31 | @Override
32 | public DataSink open(DataSpec dataSpec) throws IOException {
33 | if (dataSpec.length == C.LENGTH_UNBOUNDED) {
34 | stream = new ByteArrayOutputStream();
35 | } else {
36 | Assertions.checkArgument(dataSpec.length <= Integer.MAX_VALUE);
37 | stream = new ByteArrayOutputStream((int) dataSpec.length);
38 | }
39 | return this;
40 | }
41 |
42 | @Override
43 | public void close() throws IOException {
44 | stream.close();
45 | }
46 |
47 | @Override
48 | public void write(byte[] buffer, int offset, int length) throws IOException {
49 | stream.write(buffer, offset, length);
50 | }
51 |
52 | /**
53 | * Returns the data written to the sink since the last call to {@link #open(DataSpec)}.
54 | *
55 | * @return The data, or null if {@link #open(DataSpec)} has never been called.
56 | */
57 | public byte[] getData() {
58 | return stream == null ? null : stream.toByteArray();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/ByteArrayDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.C;
19 | import com.google.android.exoplayer.util.Assertions;
20 |
21 | import java.io.IOException;
22 |
23 | /**
24 | * A {@link DataSource} for reading from a byte array.
25 | */
26 | public class ByteArrayDataSource implements DataSource {
27 |
28 | private final byte[] data;
29 | private int readPosition;
30 |
31 | /**
32 | * @param data The data to be read.
33 | */
34 | public ByteArrayDataSource(byte[] data) {
35 | this.data = Assertions.checkNotNull(data);
36 | }
37 |
38 | @Override
39 | public long open(DataSpec dataSpec) throws IOException {
40 | if (dataSpec.length == C.LENGTH_UNBOUNDED) {
41 | Assertions.checkArgument(dataSpec.position < data.length);
42 | } else {
43 | Assertions.checkArgument(dataSpec.position + dataSpec.length <= data.length);
44 | }
45 | readPosition = (int) dataSpec.position;
46 | return (dataSpec.length == C.LENGTH_UNBOUNDED) ? (data.length - dataSpec.position)
47 | : dataSpec.length;
48 | }
49 |
50 | @Override
51 | public void close() throws IOException {
52 | // Do nothing.
53 | }
54 |
55 | @Override
56 | public int read(byte[] buffer, int offset, int length) throws IOException {
57 | System.arraycopy(data, readPosition, buffer, offset, length);
58 | readPosition += length;
59 | return length;
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/ByteArrayNonBlockingInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.util.Assertions;
19 |
20 | import java.nio.ByteBuffer;
21 |
22 | /**
23 | * An implementation of {@link NonBlockingInputStream} for reading data from a byte array.
24 | */
25 | public final class ByteArrayNonBlockingInputStream implements NonBlockingInputStream {
26 |
27 | private final byte[] data;
28 |
29 | private int position;
30 |
31 | public ByteArrayNonBlockingInputStream(byte[] data) {
32 | this.data = Assertions.checkNotNull(data);
33 | }
34 |
35 | @Override
36 | public int skip(int length) {
37 | int skipLength = getReadLength(length);
38 | position += skipLength;
39 | return skipLength;
40 | }
41 |
42 | @Override
43 | public int read(byte[] buffer, int offset, int length) {
44 | if (isEndOfStream()) {
45 | return -1;
46 | }
47 | int readLength = getReadLength(length);
48 | System.arraycopy(data, position, buffer, offset, readLength);
49 | position += readLength;
50 | return readLength;
51 | }
52 |
53 | @Override
54 | public int read(ByteBuffer buffer, int length) {
55 | if (isEndOfStream()) {
56 | return -1;
57 | }
58 | int readLength = getReadLength(length);
59 | buffer.put(data, position, readLength);
60 | position += readLength;
61 | return readLength;
62 | }
63 |
64 | @Override
65 | public long getAvailableByteCount() {
66 | return data.length - position;
67 | }
68 |
69 | @Override
70 | public boolean isEndOfStream() {
71 | return position == data.length;
72 | }
73 |
74 | @Override
75 | public void close() {
76 | // Do nothing.
77 | }
78 |
79 | private int getReadLength(int requestedLength) {
80 | return Math.min(requestedLength, data.length - position);
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/DataSink.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import java.io.IOException;
19 |
20 | /**
21 | * A component that consumes media data.
22 | */
23 | public interface DataSink {
24 |
25 | /**
26 | * Opens the {@link DataSink} to consume the specified data. Calls to {@link #open(DataSpec)} and
27 | * {@link #close()} must be balanced.
28 | *
29 | * @param dataSpec Defines the data to be consumed.
30 | * @return This {@link DataSink}, for convenience.
31 | * @throws IOException
32 | */
33 | public DataSink open(DataSpec dataSpec) throws IOException;
34 |
35 | /**
36 | * Closes the {@link DataSink}.
37 | *
38 | * @throws IOException
39 | */
40 | public void close() throws IOException;
41 |
42 | /**
43 | * Consumes the provided data.
44 | *
45 | * @param buffer The buffer from which data should be consumed.
46 | * @param offset The offset of the data to consume in {@code buffer}.
47 | * @param length The length of the data to consume, in bytes.
48 | * @throws IOException
49 | */
50 | public void write(byte[] buffer, int offset, int length) throws IOException;
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/DataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.C;
19 |
20 | import java.io.IOException;
21 |
22 | /**
23 | * A component that provides media data.
24 | */
25 | public interface DataSource {
26 |
27 | /**
28 | * Opens the {@link DataSource} to read the specified data. Calls to {@link #open(DataSpec)} and
29 | * {@link #close()} must be balanced.
30 | *
31 | * Note: If {@link #open(DataSpec)} throws an {@link IOException}, callers must still call
32 | * {@link #close()} to ensure that any partial effects of the {@link #open(DataSpec)} invocation
33 | * are cleaned up. Implementations of this class can assume that callers will call
34 | * {@link #close()} in this case.
35 | *
36 | * @param dataSpec Defines the data to be read.
37 | * @throws IOException If an error occurs opening the source.
38 | * @return The number of bytes that can be read from the opened source. For unbounded requests
39 | * (i.e. requests where {@link DataSpec#length} equals {@link C#LENGTH_UNBOUNDED}) this value
40 | * is the resolved length of the request, or {@link C#LENGTH_UNBOUNDED} if the length is still
41 | * unresolved. For all other requests, the value returned will be equal to the request's
42 | * {@link DataSpec#length}.
43 | */
44 | public long open(DataSpec dataSpec) throws IOException;
45 |
46 | /**
47 | * Closes the {@link DataSource}.
48 | *
49 | * Note: This method will be called even if the corresponding call to {@link #open(DataSpec)}
50 | * threw an {@link IOException}. See {@link #open(DataSpec)} for more details.
51 | *
52 | * @throws IOException If an error occurs closing the source.
53 | */
54 | public void close() throws IOException;
55 |
56 | /**
57 | * Reads up to {@code length} bytes of data and stores them into {@code buffer}, starting at
58 | * index {@code offset}. This method blocks until at least one byte of data can be read, the end
59 | * of the opened range is detected, or an exception is thrown.
60 | *
61 | * @param buffer The buffer into which the read data should be stored.
62 | * @param offset The start offset into {@code buffer} at which data should be written.
63 | * @param readLength The maximum number of bytes to read.
64 | * @return The actual number of bytes read, or -1 if the end of the opened range is reached.
65 | * @throws IOException If an error occurs reading from the source.
66 | */
67 | public int read(byte[] buffer, int offset, int readLength) throws IOException;
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/DataSourceInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.util.Assertions;
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 |
23 | /**
24 | * Allows data corresponding to a given {@link DataSpec} to be read from a {@link DataSource} and
25 | * consumed as an {@link InputStream}.
26 | */
27 | public class DataSourceInputStream extends InputStream {
28 |
29 | private final DataSource dataSource;
30 | private final DataSpec dataSpec;
31 | private final byte[] singleByteArray;
32 |
33 | private boolean opened = false;
34 | private boolean closed = false;
35 |
36 | /**
37 | * @param dataSource The {@link DataSource} from which the data should be read.
38 | * @param dataSpec The {@link DataSpec} defining the data to be read from {@code dataSource}.
39 | */
40 | public DataSourceInputStream(DataSource dataSource, DataSpec dataSpec) {
41 | this.dataSource = dataSource;
42 | this.dataSpec = dataSpec;
43 | singleByteArray = new byte[1];
44 | }
45 |
46 | @Override
47 | public int read() throws IOException {
48 | read(singleByteArray);
49 | return singleByteArray[0];
50 | }
51 |
52 | @Override
53 | public int read(byte[] buffer) throws IOException {
54 | return read(buffer, 0, buffer.length);
55 | }
56 |
57 | @Override
58 | public int read(byte[] buffer, int offset, int length) throws IOException {
59 | Assertions.checkState(!closed);
60 | checkOpened();
61 | return dataSource.read(buffer, offset, length);
62 | }
63 |
64 | @Override
65 | public long skip(long byteCount) throws IOException {
66 | Assertions.checkState(!closed);
67 | checkOpened();
68 | return super.skip(byteCount);
69 | }
70 |
71 | @Override
72 | public void close() throws IOException {
73 | if (!closed) {
74 | dataSource.close();
75 | closed = true;
76 | }
77 | }
78 |
79 | private void checkOpened() throws IOException {
80 | if (!opened) {
81 | dataSource.open(dataSpec);
82 | opened = true;
83 | }
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/DataSpec.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.C;
19 | import com.google.android.exoplayer.util.Assertions;
20 |
21 | import android.net.Uri;
22 |
23 | /**
24 | * Defines a region of media data.
25 | */
26 | public final class DataSpec {
27 |
28 | /**
29 | * Identifies the source from which data should be read.
30 | */
31 | public final Uri uri;
32 | /**
33 | * True if the data at {@link #uri} is the full stream. False otherwise. An example where this
34 | * may be false is if {@link #uri} defines the location of a cached part of the stream.
35 | */
36 | public final boolean uriIsFullStream;
37 | /**
38 | * The absolute position of the data in the full stream.
39 | */
40 | public final long absoluteStreamPosition;
41 | /**
42 | * The position of the data when read from {@link #uri}. Always equal to
43 | * {@link #absoluteStreamPosition} if {@link #uriIsFullStream}.
44 | */
45 | public final long position;
46 | /**
47 | * The length of the data. Greater than zero, or equal to {@link C#LENGTH_UNBOUNDED}.
48 | */
49 | public final long length;
50 | /**
51 | * A key that uniquely identifies the original stream. Used for cache indexing. May be null if the
52 | * {@link DataSpec} is not intended to be used in conjunction with a cache.
53 | */
54 | public final String key;
55 |
56 | /**
57 | * Construct a {@link DataSpec} for which {@link #uriIsFullStream} is true.
58 | *
59 | * @param uri {@link #uri}.
60 | * @param absoluteStreamPosition {@link #absoluteStreamPosition}, equal to {@link #position}.
61 | * @param length {@link #length}.
62 | * @param key {@link #key}.
63 | */
64 | public DataSpec(Uri uri, long absoluteStreamPosition, long length, String key) {
65 | this(uri, absoluteStreamPosition, length, key, absoluteStreamPosition, true);
66 | }
67 |
68 | /**
69 | * Construct a {@link DataSpec} for which {@link #uriIsFullStream} is false.
70 | *
71 | * @param uri {@link #uri}.
72 | * @param absoluteStreamPosition {@link #absoluteStreamPosition}.
73 | * @param length {@link #length}.
74 | * @param key {@link #key}.
75 | * @param position {@link #position}.
76 | */
77 | public DataSpec(Uri uri, long absoluteStreamPosition, long length, String key, long position) {
78 | this(uri, absoluteStreamPosition, length, key, position, false);
79 | }
80 |
81 | /**
82 | * Construct a {@link DataSpec}.
83 | *
84 | * @param uri {@link #uri}.
85 | * @param absoluteStreamPosition {@link #absoluteStreamPosition}.
86 | * @param length {@link #length}.
87 | * @param key {@link #key}.
88 | * @param position {@link #position}.
89 | * @param uriIsFullStream {@link #uriIsFullStream}.
90 | */
91 | public DataSpec(Uri uri, long absoluteStreamPosition, long length, String key, long position,
92 | boolean uriIsFullStream) {
93 | Assertions.checkArgument(absoluteStreamPosition >= 0);
94 | Assertions.checkArgument(position >= 0);
95 | Assertions.checkArgument(length > 0 || length == C.LENGTH_UNBOUNDED);
96 | Assertions.checkArgument(absoluteStreamPosition == position || !uriIsFullStream);
97 | this.uri = uri;
98 | this.uriIsFullStream = uriIsFullStream;
99 | this.absoluteStreamPosition = absoluteStreamPosition;
100 | this.position = position;
101 | this.length = length;
102 | this.key = key;
103 | }
104 |
105 | @Override
106 | public String toString() {
107 | return "DataSpec[" + uri + ", " + uriIsFullStream + ", " + absoluteStreamPosition + ", " +
108 | position + ", " + length + ", " + key + "]";
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/FileDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.C;
19 |
20 | import java.io.IOException;
21 | import java.io.RandomAccessFile;
22 |
23 | /**
24 | * A local file {@link DataSource}.
25 | */
26 | public final class FileDataSource implements DataSource {
27 |
28 | /**
29 | * Thrown when IOException is encountered during local file read operation.
30 | */
31 | public static class FileDataSourceException extends IOException {
32 |
33 | public FileDataSourceException(IOException cause) {
34 | super(cause);
35 | }
36 |
37 | }
38 |
39 | private RandomAccessFile file;
40 | private long bytesRemaining;
41 |
42 | @Override
43 | public long open(DataSpec dataSpec) throws FileDataSourceException {
44 | try {
45 | file = new RandomAccessFile(dataSpec.uri.getPath(), "r");
46 | file.seek(dataSpec.position);
47 | bytesRemaining = dataSpec.length == C.LENGTH_UNBOUNDED ? file.length() - dataSpec.position
48 | : dataSpec.length;
49 | return bytesRemaining;
50 | } catch (IOException e) {
51 | throw new FileDataSourceException(e);
52 | }
53 | }
54 |
55 | @Override
56 | public int read(byte[] buffer, int offset, int readLength) throws FileDataSourceException {
57 | if (bytesRemaining == 0) {
58 | return -1;
59 | } else {
60 | int bytesRead = 0;
61 | try {
62 | bytesRead = file.read(buffer, offset, (int) Math.min(bytesRemaining, readLength));
63 | } catch (IOException e) {
64 | throw new FileDataSourceException(e);
65 | }
66 | bytesRemaining -= bytesRead;
67 | return bytesRead;
68 | }
69 | }
70 |
71 | @Override
72 | public void close() throws FileDataSourceException {
73 | if (file != null) {
74 | try {
75 | file.close();
76 | } catch (IOException e) {
77 | throw new FileDataSourceException(e);
78 | }
79 | file = null;
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/NetworkLock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import java.io.IOException;
19 | import java.util.PriorityQueue;
20 |
21 | /**
22 | * A network task prioritization mechanism.
23 | *
24 | * Manages different priority network tasks. A network task that wishes to have its priority
25 | * respected, and respect the priority of other tasks, should register itself with the lock prior
26 | * to making network requests. It should then call one of the lock's proceed methods frequently
27 | * during execution, so as to ensure that it continues only if it is the highest (or equally
28 | * highest) priority task.
29 | *
30 | * Note that lower integer values correspond to higher priorities.
31 | */
32 | public final class NetworkLock {
33 |
34 | /**
35 | * Thrown when a task is attempts to proceed when it does not have the highest priority.
36 | */
37 | public static class PriorityTooLowException extends IOException {
38 |
39 | public PriorityTooLowException(int priority, int highestPriority) {
40 | super("Priority too low [priority=" + priority + ", highest=" + highestPriority + "]");
41 | }
42 |
43 | }
44 |
45 | public static final NetworkLock instance = new NetworkLock();
46 |
47 | /**
48 | * Priority for network tasks associated with media streaming.
49 | */
50 | public static final int STREAMING_PRIORITY = 0;
51 | /**
52 | * Priority for network tasks associated with background downloads.
53 | */
54 | public static final int DOWNLOAD_PRIORITY = 10;
55 |
56 | private final PriorityQueue
99 | * The task must call {@link #remove(int)} when done.
100 | *
101 | * @param priority The priority of the task.
102 | */
103 | public synchronized void add(int priority) {
104 | queue.add(priority);
105 | }
106 |
107 | /**
108 | * Unregister a task.
109 | *
110 | * @param priority The priority of the task.
111 | */
112 | public synchronized void remove(int priority) {
113 | queue.remove(priority);
114 | notifyAll();
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/NonBlockingInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import java.nio.ByteBuffer;
19 |
20 | /**
21 | * Represents a source of bytes that can be consumed by downstream components.
22 | *
23 | * The read and skip methods are non-blocking, and hence return 0 (indicating that no data has
24 | * been read) in the case that data is not yet available to be consumed.
25 | */
26 | public interface NonBlockingInputStream {
27 |
28 | /**
29 | * Skips over and discards up to {@code length} bytes of data. This method may skip over some
30 | * smaller number of bytes, possibly 0.
31 | *
32 | * @param length The maximum number of bytes to skip.
33 | * @return The actual number of bytes skipped, or -1 if the end of the data is reached.
34 | */
35 | int skip(int length);
36 |
37 | /**
38 | * Reads up to {@code length} bytes of data and stores them into {@code buffer}, starting at
39 | * index {@code offset}. This method may read fewer bytes, possibly 0.
40 | *
41 | * @param buffer The buffer into which the read data should be stored.
42 | * @param offset The start offset into {@code buffer} at which data should be written.
43 | * @param length The maximum number of bytes to read.
44 | * @return The actual number of bytes read, or -1 if the end of the data is reached.
45 | */
46 | int read(byte[] buffer, int offset, int length);
47 |
48 | /**
49 | * Reads up to {@code length} bytes of data and stores them into {@code buffer}. This method may
50 | * read fewer bytes, possibly 0.
51 | *
52 | * @param buffer The buffer into which the read data should be stored.
53 | * @param length The maximum number of bytes to read.
54 | * @return The actual number of bytes read, or -1 if the end of the data is reached.
55 | */
56 | int read(ByteBuffer buffer, int length);
57 |
58 | /**
59 | * Returns the number of bytes currently available for reading or skipping. Calls to the read()
60 | * and skip() methods are guaranteed to be satisfied in full if they request less than or
61 | * equal to the value returned.
62 | *
63 | * @return The number of bytes currently available.
64 | */
65 | long getAvailableByteCount();
66 |
67 | /**
68 | * Whether the end of the data has been reached.
69 | *
70 | * @return True if the end of the data has been reached, false otherwise.
71 | */
72 | boolean isEndOfStream();
73 |
74 | /**
75 | * Closes the input stream.
76 | */
77 | void close();
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/PriorityDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.util.Assertions;
19 |
20 | import java.io.IOException;
21 |
22 | /**
23 | * Allows {@link #open(DataSpec)} and {@link #read(byte[], int, int)} calls only if the specified
24 | * priority is the highest priority of any task. {@link NetworkLock.PriorityTooLowException} is
25 | * thrown when this condition does not hold.
26 | */
27 | public class PriorityDataSource implements DataSource {
28 |
29 | private final DataSource upstream;
30 | private final int priority;
31 |
32 | /**
33 | * @param priority The priority of the source.
34 | * @param upstream The upstream {@link DataSource}.
35 | */
36 | public PriorityDataSource(int priority, DataSource upstream) {
37 | this.priority = priority;
38 | this.upstream = Assertions.checkNotNull(upstream);
39 | }
40 |
41 | @Override
42 | public long open(DataSpec dataSpec) throws IOException {
43 | NetworkLock.instance.proceedOrThrow(priority);
44 | return upstream.open(dataSpec);
45 | }
46 |
47 | @Override
48 | public int read(byte[] buffer, int offset, int max) throws IOException {
49 | NetworkLock.instance.proceedOrThrow(priority);
50 | return upstream.read(buffer, offset, max);
51 | }
52 |
53 | @Override
54 | public void close() throws IOException {
55 | upstream.close();
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/TeeDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import com.google.android.exoplayer.C;
19 | import com.google.android.exoplayer.util.Assertions;
20 |
21 | import java.io.IOException;
22 |
23 | /**
24 | * Tees data into a {@link DataSink} as the data is read.
25 | */
26 | public final class TeeDataSource implements DataSource {
27 |
28 | private final DataSource upstream;
29 | private final DataSink dataSink;
30 |
31 | /**
32 | * @param upstream The upstream {@link DataSource}.
33 | * @param dataSink The {@link DataSink} into which data is written.
34 | */
35 | public TeeDataSource(DataSource upstream, DataSink dataSink) {
36 | this.upstream = Assertions.checkNotNull(upstream);
37 | this.dataSink = Assertions.checkNotNull(dataSink);
38 | }
39 |
40 | @Override
41 | public long open(DataSpec dataSpec) throws IOException {
42 | long dataLength = upstream.open(dataSpec);
43 | if (dataSpec.length == C.LENGTH_UNBOUNDED && dataLength != C.LENGTH_UNBOUNDED) {
44 | // Reconstruct dataSpec in order to provide the resolved length to the sink.
45 | dataSpec = new DataSpec(dataSpec.uri, dataSpec.absoluteStreamPosition, dataLength,
46 | dataSpec.key, dataSpec.position, dataSpec.uriIsFullStream);
47 | }
48 | dataSink.open(dataSpec);
49 | return dataLength;
50 | }
51 |
52 | @Override
53 | public int read(byte[] buffer, int offset, int max) throws IOException {
54 | int num = upstream.read(buffer, offset, max);
55 | if (num > 0) {
56 | // TODO: Consider continuing even if disk writes fail.
57 | dataSink.write(buffer, offset, num);
58 | }
59 | return num;
60 | }
61 |
62 | @Override
63 | public void close() throws IOException {
64 | upstream.close();
65 | dataSink.close();
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/TransferListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | /**
19 | * Interface definition for a callback to be notified of data transfer events.
20 | */
21 | public interface TransferListener {
22 |
23 | /**
24 | * Invoked when a transfer starts.
25 | */
26 | void onTransferStart();
27 |
28 | /**
29 | * Called incrementally during a transfer.
30 | *
31 | * @param bytesTransferred The number of bytes transferred since the previous call to this
32 | * method (or if the first call, since the transfer was started).
33 | */
34 | void onBytesTransferred(int bytesTransferred);
35 |
36 | /**
37 | * Invoked when a transfer ends.
38 | */
39 | void onTransferEnd();
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/UnexpectedLengthException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream;
17 |
18 | import java.io.IOException;
19 |
20 | /**
21 | * Thrown when the length of some data does not match an expected length.
22 | */
23 | public final class UnexpectedLengthException extends IOException {
24 |
25 | /**
26 | * The length that was expected, in bytes.
27 | */
28 | public final long expectedLength;
29 |
30 | /**
31 | * The actual length encountered, in bytes.
32 | */
33 | public final long actualLength;
34 |
35 | /**
36 | * @param expectedLength The length that was expected, in bytes.
37 | * @param actualLength The actual length encountered, in bytes.
38 | */
39 | public UnexpectedLengthException(long expectedLength, long actualLength) {
40 | super("Expected: " + expectedLength + ", got: " + actualLength);
41 | this.expectedLength = expectedLength;
42 | this.actualLength = actualLength;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/cache/CacheDataSink.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream.cache;
17 |
18 | import com.google.android.exoplayer.C;
19 | import com.google.android.exoplayer.upstream.DataSink;
20 | import com.google.android.exoplayer.upstream.DataSpec;
21 | import com.google.android.exoplayer.util.Assertions;
22 |
23 | import java.io.File;
24 | import java.io.FileNotFoundException;
25 | import java.io.FileOutputStream;
26 | import java.io.IOException;
27 |
28 | /**
29 | * Writes data into a cache.
30 | */
31 | public class CacheDataSink implements DataSink {
32 |
33 | private final Cache cache;
34 | private final long maxCacheFileSize;
35 |
36 | private DataSpec dataSpec;
37 | private File file;
38 | private FileOutputStream outputStream;
39 | private long outputStreamBytesWritten;
40 | private long dataSpecBytesWritten;
41 |
42 | /**
43 | * Thrown when IOException is encountered when writing data into sink.
44 | */
45 | public static class CacheDataSinkException extends IOException {
46 |
47 | public CacheDataSinkException(IOException cause) {
48 | super(cause);
49 | }
50 |
51 | }
52 |
53 |
54 | /**
55 | * @param cache The cache into which data should be written.
56 | * @param maxCacheFileSize The maximum size of a cache file, in bytes. If the sink is opened for
57 | * a {@link DataSpec} whose size exceeds this value, then the data will be fragmented into
58 | * multiple cache files.
59 | */
60 | public CacheDataSink(Cache cache, long maxCacheFileSize) {
61 | this.cache = Assertions.checkNotNull(cache);
62 | this.maxCacheFileSize = maxCacheFileSize;
63 | }
64 |
65 | @Override
66 | public DataSink open(DataSpec dataSpec) throws CacheDataSinkException {
67 | // TODO: Support caching for unbounded requests. See TODO in {@link CacheDataSource} for
68 | // more details.
69 | Assertions.checkState(dataSpec.length != C.LENGTH_UNBOUNDED);
70 | try {
71 | this.dataSpec = dataSpec;
72 | dataSpecBytesWritten = 0;
73 | openNextOutputStream();
74 | return this;
75 | } catch (FileNotFoundException e) {
76 | throw new CacheDataSinkException(e);
77 | }
78 | }
79 |
80 | @Override
81 | public void write(byte[] buffer, int offset, int length) throws CacheDataSinkException {
82 | try {
83 | int bytesWritten = 0;
84 | while (bytesWritten < length) {
85 | if (outputStreamBytesWritten == maxCacheFileSize) {
86 | closeCurrentOutputStream();
87 | openNextOutputStream();
88 | }
89 | int bytesToWrite = (int) Math.min(length - bytesWritten,
90 | maxCacheFileSize - outputStreamBytesWritten);
91 | outputStream.write(buffer, offset + bytesWritten, bytesToWrite);
92 | bytesWritten += bytesToWrite;
93 | outputStreamBytesWritten += bytesToWrite;
94 | dataSpecBytesWritten += bytesToWrite;
95 | }
96 | } catch (IOException e) {
97 | throw new CacheDataSinkException(e);
98 | }
99 | }
100 |
101 | @Override
102 | public void close() throws CacheDataSinkException {
103 | try {
104 | closeCurrentOutputStream();
105 | } catch (IOException e) {
106 | throw new CacheDataSinkException(e);
107 | }
108 | }
109 |
110 | private void openNextOutputStream() throws FileNotFoundException {
111 | file = cache.startFile(dataSpec.key, dataSpec.absoluteStreamPosition + dataSpecBytesWritten,
112 | Math.min(dataSpec.length - dataSpecBytesWritten, maxCacheFileSize));
113 | outputStream = new FileOutputStream(file);
114 | outputStreamBytesWritten = 0;
115 | }
116 |
117 | private void closeCurrentOutputStream() throws IOException {
118 | if (outputStream != null) {
119 | outputStream.flush();
120 | outputStream.close();
121 | outputStream = null;
122 | cache.commitFile(file);
123 | file = null;
124 | }
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/cache/CacheEvictor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream.cache;
17 |
18 | /**
19 | * Evicts data from a {@link Cache}. Implementations should call {@link Cache#removeSpan(CacheSpan)}
20 | * to evict cache entries based on their eviction policies.
21 | */
22 | public interface CacheEvictor extends Cache.Listener {
23 |
24 | /**
25 | * Invoked when a writer starts writing to the cache.
26 | *
27 | * @param cache The source of the event.
28 | * @param key The key being written.
29 | * @param position The starting position of the data being written.
30 | * @param length The maximum length of the data being written.
31 | */
32 | void onStartFile(Cache cache, String key, long position, long length);
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/upstream/cache/LeastRecentlyUsedCacheEvictor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.upstream.cache;
17 |
18 | import java.util.Comparator;
19 | import java.util.TreeSet;
20 |
21 | /**
22 | * Evicts least recently used cache files first.
23 | */
24 | public class LeastRecentlyUsedCacheEvictor implements CacheEvictor, Comparator
25 | * This class is provided for convenience, however it is expected that most applications will
26 | * implement their own player controls and therefore not require this class.
27 | */
28 | public class PlayerControl implements MediaPlayerControl {
29 |
30 | private final ExoPlayer exoPlayer;
31 |
32 | public PlayerControl(ExoPlayer exoPlayer) {
33 | this.exoPlayer = exoPlayer;
34 | }
35 |
36 | @Override
37 | public boolean canPause() {
38 | return true;
39 | }
40 |
41 | @Override
42 | public boolean canSeekBackward() {
43 | return true;
44 | }
45 |
46 | @Override
47 | public boolean canSeekForward() {
48 | return true;
49 | }
50 |
51 | /**
52 | * This is an unsupported operation.
53 | *
54 | * Application of audio effects is dependent on the audio renderer used. When using
55 | * {@link com.google.android.exoplayer.MediaCodecAudioTrackRenderer}, the recommended approach is
56 | * to extend the class and override
57 | * {@link com.google.android.exoplayer.MediaCodecAudioTrackRenderer#onAudioSessionId}.
58 | *
59 | * @throws UnsupportedOperationException Always thrown.
60 | */
61 | @Override
62 | public int getAudioSessionId() {
63 | throw new UnsupportedOperationException();
64 | }
65 |
66 | @Override
67 | public int getBufferPercentage() {
68 | return exoPlayer.getBufferedPercentage();
69 | }
70 |
71 | @Override
72 | public int getCurrentPosition() {
73 | return exoPlayer.getCurrentPosition();
74 | }
75 |
76 | @Override
77 | public int getDuration() {
78 | return exoPlayer.getDuration();
79 | }
80 |
81 | @Override
82 | public boolean isPlaying() {
83 | return exoPlayer.getPlayWhenReady();
84 | }
85 |
86 | @Override
87 | public void start() {
88 | exoPlayer.setPlayWhenReady(true);
89 | }
90 |
91 | @Override
92 | public void pause() {
93 | exoPlayer.setPlayWhenReady(false);
94 | }
95 |
96 | @Override
97 | public void seekTo(int timeMillis) {
98 | // MediaController arrow keys generate unbounded values.
99 | exoPlayer.seekTo(Math.min(Math.max(0, timeMillis), getDuration()));
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/library/src/main/java/com/google/android/exoplayer/util/Predicate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.google.android.exoplayer.util;
17 |
18 | /**
19 | * Determines a true of false value for a given input.
20 | *
21 | * @param