diff --git a/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java b/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java index 908664495f..63afbdf0f5 100644 --- a/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java @@ -112,7 +112,7 @@ public final class FrameworkSampleSource implements SampleSource { } @Override - public int readData(int track, long playbackPositionUs, FormatHolder formatHolder, + public int readData(int track, long playbackPositionUs, MediaFormatHolder formatHolder, SampleHolder sampleHolder, boolean onlyReadDiscontinuity) { Assertions.checkState(prepared); Assertions.checkState(trackStates[track] != TRACK_STATE_DISABLED); diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java index 3004032076..d990d369b8 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java @@ -124,7 +124,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { private final boolean playClearSamplesWithoutKeys; private final SampleSource source; private final SampleHolder sampleHolder; - private final FormatHolder formatHolder; + private final MediaFormatHolder formatHolder; private final HashSet decodeOnlyPresentationTimestamps; private final MediaCodec.BufferInfo outputBufferInfo; private final EventListener eventListener; @@ -174,7 +174,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { this.eventListener = eventListener; codecCounters = new CodecCounters(); sampleHolder = new SampleHolder(false); - formatHolder = new FormatHolder(); + formatHolder = new MediaFormatHolder(); decodeOnlyPresentationTimestamps = new HashSet(); outputBufferInfo = new MediaCodec.BufferInfo(); } @@ -619,7 +619,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { * @param formatHolder Holds the new format. * @throws ExoPlaybackException If an error occurs reinitializing the {@link MediaCodec}. */ - private void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException { + private void onInputFormatChanged(MediaFormatHolder formatHolder) throws ExoPlaybackException { MediaFormat oldFormat = format; format = formatHolder.format; drmInitData = formatHolder.drmInitData; diff --git a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java index 3188e36db0..d703a72a84 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java @@ -27,7 +27,7 @@ import java.util.Collections; import java.util.List; /** - * Encapsulates the information describing the format of media data, be it audio or video. + * Defines the format of an elementary media stream. */ public class MediaFormat { diff --git a/library/src/main/java/com/google/android/exoplayer/FormatHolder.java b/library/src/main/java/com/google/android/exoplayer/MediaFormatHolder.java similarity index 96% rename from library/src/main/java/com/google/android/exoplayer/FormatHolder.java rename to library/src/main/java/com/google/android/exoplayer/MediaFormatHolder.java index 04a6d7d85f..621a0f7986 100644 --- a/library/src/main/java/com/google/android/exoplayer/FormatHolder.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaFormatHolder.java @@ -21,7 +21,7 @@ import java.util.UUID; /** * Holds a {@link MediaFormat} and corresponding drm scheme initialization data. */ -public final class FormatHolder { +public final class MediaFormatHolder { /** * The format of the media. diff --git a/library/src/main/java/com/google/android/exoplayer/SampleSource.java b/library/src/main/java/com/google/android/exoplayer/SampleSource.java index fc29ef1ad5..2f26d30e9a 100644 --- a/library/src/main/java/com/google/android/exoplayer/SampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/SampleSource.java @@ -80,7 +80,7 @@ public interface SampleSource { /** * Enable the specified track. This allows the track's format and samples to be read from - * {@link #readData(int, long, FormatHolder, SampleHolder, boolean)}. + * {@link #readData(int, long, MediaFormatHolder, SampleHolder, boolean)}. *

* This method should not be called until after the source has been successfully prepared. * @@ -119,7 +119,7 @@ public interface SampleSource { * * @param track The track from which to read. * @param playbackPositionUs The current playback position. - * @param formatHolder A {@link FormatHolder} object to populate in the case of a new format. + * @param formatHolder A {@link MediaFormatHolder} object to populate in the case of a new format. * @param sampleHolder A {@link SampleHolder} object to populate in the case of a new sample. If * the caller requires the sample data then it must ensure that {@link SampleHolder#data} * references a valid output buffer. @@ -129,7 +129,7 @@ public interface SampleSource { * {@link #DISCONTINUITY_READ}, {@link #NOTHING_READ} or {@link #END_OF_STREAM}. * @throws IOException If an error occurred reading from the source. */ - public int readData(int track, long playbackPositionUs, FormatHolder formatHolder, + public int readData(int track, long playbackPositionUs, MediaFormatHolder formatHolder, SampleHolder sampleHolder, boolean onlyReadDiscontinuity) throws IOException; /** diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java index 980de4ec23..c48b6056ef 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java @@ -16,9 +16,9 @@ package com.google.android.exoplayer.chunk; import com.google.android.exoplayer.C; -import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.LoadControl; import com.google.android.exoplayer.MediaFormat; +import com.google.android.exoplayer.MediaFormatHolder; import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.TrackInfo; @@ -267,7 +267,7 @@ public class ChunkSampleSource implements SampleSource, Loader.Listener { } @Override - public int readData(int track, long playbackPositionUs, FormatHolder formatHolder, + public int readData(int track, long playbackPositionUs, MediaFormatHolder formatHolder, SampleHolder sampleHolder, boolean onlyReadDiscontinuity) throws IOException { Assertions.checkState(state == STATE_ENABLED); Assertions.checkState(track == 0); diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/Format.java b/library/src/main/java/com/google/android/exoplayer/chunk/Format.java index 3482d160fc..b2948c06a9 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/Format.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/Format.java @@ -20,7 +20,7 @@ import com.google.android.exoplayer.util.Assertions; import java.util.Comparator; /** - * A format definition for streams. + * Defines the high level format of a media stream. */ public class Format { diff --git a/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java b/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java index 936bd565d0..158c0be4ca 100644 --- a/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java @@ -23,6 +23,7 @@ import com.google.android.exoplayer.parser.mp4.Atom.ContainerAtom; import com.google.android.exoplayer.parser.mp4.Atom.LeafAtom; import com.google.android.exoplayer.upstream.NonBlockingInputStream; import com.google.android.exoplayer.util.Assertions; +import com.google.android.exoplayer.util.CodecSpecificDataUtil; import com.google.android.exoplayer.util.MimeTypes; import android.annotation.SuppressLint; diff --git a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java index d6a70e0364..052a100a2d 100644 --- a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java @@ -26,7 +26,6 @@ import com.google.android.exoplayer.chunk.FormatEvaluator; import com.google.android.exoplayer.chunk.FormatEvaluator.Evaluation; import com.google.android.exoplayer.chunk.MediaChunk; import com.google.android.exoplayer.chunk.Mp4MediaChunk; -import com.google.android.exoplayer.parser.mp4.CodecSpecificDataUtil; import com.google.android.exoplayer.parser.mp4.FragmentedMp4Extractor; import com.google.android.exoplayer.parser.mp4.Track; import com.google.android.exoplayer.parser.mp4.TrackEncryptionBox; @@ -35,6 +34,7 @@ import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.Stre import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.TrackElement; import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DataSpec; +import com.google.android.exoplayer.util.CodecSpecificDataUtil; import android.net.Uri; import android.util.Base64; diff --git a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestParser.java b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestParser.java index d8834f1dd4..0aa137d7bd 100644 --- a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestParser.java +++ b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestParser.java @@ -16,11 +16,11 @@ package com.google.android.exoplayer.smoothstreaming; import com.google.android.exoplayer.ParserException; -import com.google.android.exoplayer.parser.mp4.CodecSpecificDataUtil; import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.ProtectionElement; import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.StreamElement; import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.TrackElement; import com.google.android.exoplayer.util.Assertions; +import com.google.android.exoplayer.util.CodecSpecificDataUtil; import android.util.Base64; import android.util.Pair; diff --git a/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java index 1fd213eda1..d6504461b2 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer.text; import com.google.android.exoplayer.ExoPlaybackException; -import com.google.android.exoplayer.FormatHolder; +import com.google.android.exoplayer.MediaFormatHolder; import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.TrackRenderer; @@ -64,7 +64,7 @@ public class TextTrackRenderer extends TrackRenderer implements Callback { private final TextRenderer textRenderer; private final SampleSource source; private final SampleHolder sampleHolder; - private final FormatHolder formatHolder; + private final MediaFormatHolder formatHolder; private final SubtitleParser subtitleParser; private int trackIndex; @@ -93,7 +93,7 @@ public class TextTrackRenderer extends TrackRenderer implements Callback { this.textRenderer = Assertions.checkNotNull(textRenderer); this.textRendererHandler = textRendererLooper == null ? null : new Handler(textRendererLooper, this); - formatHolder = new FormatHolder(); + formatHolder = new MediaFormatHolder(); sampleHolder = new SampleHolder(true); } diff --git a/library/src/main/java/com/google/android/exoplayer/parser/mp4/CodecSpecificDataUtil.java b/library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java similarity index 86% rename from library/src/main/java/com/google/android/exoplayer/parser/mp4/CodecSpecificDataUtil.java rename to library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java index 851c4925b6..019f7459c0 100644 --- a/library/src/main/java/com/google/android/exoplayer/parser/mp4/CodecSpecificDataUtil.java +++ b/library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.parser.mp4; - -import com.google.android.exoplayer.util.Assertions; +package com.google.android.exoplayer.util; import android.annotation.SuppressLint; import android.media.MediaCodecInfo.CodecProfileLevel; @@ -35,6 +33,10 @@ public final class CodecSpecificDataUtil { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 }; + private static final int[] AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE = new int[] { + 0, 1, 2, 3, 4, 5, 6, 8 + }; + private static final int SPS_NAL_UNIT_TYPE = 7; private CodecSpecificDataUtil() {} @@ -42,7 +44,7 @@ public final class CodecSpecificDataUtil { /** * Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 * - * @param audioSpecificConfig + * @param audioSpecificConfig The AudioSpecificConfig to parse. * @return A pair consisting of the sample rate in Hz and the channel count. */ public static Pair parseAudioSpecificConfig(byte[] audioSpecificConfig) { @@ -56,11 +58,27 @@ public final class CodecSpecificDataUtil { return Pair.create(sampleRate, channelCount); } + /** + * Builds a simple AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 + * + * @param audioObjectType The audio object type. + * @param sampleRateIndex The sample rate index. + * @param channelConfig The channel configuration. + * @return The AudioSpecificConfig. + */ + public static byte[] buildAudioSpecificConfig(int audioObjectType, int sampleRateIndex, + int channelConfig) { + byte[] audioSpecificConfig = new byte[2]; + audioSpecificConfig[0] = (byte) ((audioObjectType << 3) & 0xF8 | (sampleRateIndex >> 1) & 0x07); + audioSpecificConfig[1] = (byte) ((sampleRateIndex << 7) & 0x80 | (channelConfig << 3) & 0x78); + return audioSpecificConfig; + } + /** * Builds a simple HE-AAC LC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 * * @param sampleRate The sample rate in Hz. - * @param numChannels The number of channels + * @param numChannels The number of channels. * @return The AudioSpecificConfig. */ public static byte[] buildAudioSpecificConfig(int sampleRate, int numChannels) { @@ -70,10 +88,16 @@ public final class CodecSpecificDataUtil { sampleRateIndex = i; } } + int channelConfig = -1; + for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE.length; ++i) { + if (numChannels == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) { + channelConfig = i; + } + } // The full specification for AudioSpecificConfig is stated in ISO 14496-3 Section 1.6.2.1 byte[] csd = new byte[2]; csd[0] = (byte) ((2 /* AAC LC */ << 3) | (sampleRateIndex >> 1)); - csd[1] = (byte) (((sampleRateIndex & 0x1) << 7) | (numChannels << 3)); + csd[1] = (byte) (((sampleRateIndex & 0x1) << 7) | (channelConfig << 3)); return csd; }