From 950cc70003d7633d69afb2e2d4d0859c9b1fa0c6 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 26 Oct 2015 10:44:19 +0000 Subject: [PATCH] Purely stylistic changes to FLV extractor --- .../extractor/flv/AudioTagPayloadReader.java | 38 ++++----- .../exoplayer/extractor/flv/FlvExtractor.java | 10 +-- .../extractor/flv/ScriptTagPayloadReader.java | 12 +-- .../extractor/flv/TagPayloadReader.java | 77 +++++++++++-------- .../extractor/flv/VideoTagPayloadReader.java | 12 ++- 5 files changed, 75 insertions(+), 74 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/flv/AudioTagPayloadReader.java b/library/src/main/java/com/google/android/exoplayer/extractor/flv/AudioTagPayloadReader.java index 446cab92f8..8d13de415a 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/flv/AudioTagPayloadReader.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/flv/AudioTagPayloadReader.java @@ -30,8 +30,9 @@ import java.util.Collections; /** * Parses audio tags of from an FLV stream and extracts AAC frames. */ -final class AudioTagPayloadReader extends TagPayloadReader { - // Sound format +/* package */ final class AudioTagPayloadReader extends TagPayloadReader { + + // Audio format private static final int AUDIO_FORMAT_AAC = 10; // AAC PACKET TYPE @@ -47,48 +48,40 @@ final class AudioTagPayloadReader extends TagPayloadReader { private boolean hasParsedAudioDataHeader; private boolean hasOutputFormat; - public AudioTagPayloadReader(TrackOutput output) { super(output); } @Override public void seek() { - + // Do nothing. } @Override - protected boolean parseHeader(ParsableByteArray data) throws UnsupportedTrack { - // Parse audio data header, if it was not done, to extract information - // about the audio codec and audio configuration. + protected boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException { + // Parse audio data header, if it was not done, to extract information about the audio codec + // and audio configuration. if (!hasParsedAudioDataHeader) { int header = data.readUnsignedByte(); - int soundFormat = (header >> 4) & 0x0F; + int audioFormat = (header >> 4) & 0x0F; int sampleRateIndex = (header >> 2) & 0x03; - int bitsPerSample = (header & 0x02) == 0x02 ? 16 : 8; - int channels = (header & 0x01) + 1; - if (sampleRateIndex < 0 || sampleRateIndex >= AUDIO_SAMPLING_RATE_TABLE.length) { - throw new UnsupportedTrack("Invalid sample rate for the audio track"); + throw new UnsupportedFormatException("Invalid sample rate for the audio track"); } - - if (!hasOutputFormat) { + if (audioFormat != AUDIO_FORMAT_AAC) { // TODO: Adds support for MP3 and PCM - if (soundFormat != AUDIO_FORMAT_AAC) { - throw new UnsupportedTrack("Audio track not supported. Format: " + soundFormat + - ", Sample rate: " + sampleRateIndex + ", bps: " + bitsPerSample + ", channels: " + - channels); + if (audioFormat != AUDIO_FORMAT_AAC) { + throw new UnsupportedFormatException("Audio format not supported: " + audioFormat); } } - hasParsedAudioDataHeader = true; } else { // Skip header if it was parsed previously. data.skipBytes(1); } - // In all the cases we will be managing AAC format (otherwise an exception would be - // fired so we can just always return true + // In all the cases we will be managing AAC format (otherwise an exception would be fired so we + // can just always return true. return true; } @@ -110,10 +103,9 @@ final class AudioTagPayloadReader extends TagPayloadReader { audioSpecificConfig); MediaFormat mediaFormat = MediaFormat.createAudioFormat(MediaFormat.NO_VALUE, - MimeTypes.AUDIO_AAC, MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, durationUs, + MimeTypes.AUDIO_AAC, MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, getDurationUs(), audioParams.second, audioParams.first, Collections.singletonList(audioSpecificConfig), null); - output.format(mediaFormat); hasOutputFormat = true; } else if (packetType == AAC_PACKET_TYPE_AAC_RAW) { diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/flv/FlvExtractor.java b/library/src/main/java/com/google/android/exoplayer/extractor/flv/FlvExtractor.java index 563361d97d..ebf3efe8ef 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/flv/FlvExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/flv/FlvExtractor.java @@ -129,7 +129,7 @@ public final class FlvExtractor implements Extractor, SeekMap { return readSample(input); } } - } catch (AudioTagPayloadReader.UnsupportedTrack unsupportedTrack) { + } catch (AudioTagPayloadReader.UnsupportedFormatException unsupportedTrack) { unsupportedTrack.printStackTrace(); return RESULT_END_OF_INPUT; } @@ -186,11 +186,11 @@ public final class FlvExtractor implements Extractor, SeekMap { * @return True if tag header was read successfully. Otherwise, false. * @throws IOException If an error occurred reading from the source. * @throws InterruptedException If the thread was interrupted. - * @throws TagPayloadReader.UnsupportedTrack If payload of the tag is using a codec non + * @throws TagPayloadReader.UnsupportedFormatException If payload of the tag is using a codec non * supported codec. */ private boolean readTagHeader(ExtractorInput input) throws IOException, InterruptedException, - TagPayloadReader.UnsupportedTrack { + TagPayloadReader.UnsupportedFormatException { try { // skipping previous tag size field input.skipFully(4); @@ -235,11 +235,11 @@ public final class FlvExtractor implements Extractor, SeekMap { * @return One of {@link Extractor#RESULT_CONTINUE} and {@link Extractor#RESULT_END_OF_INPUT}. * @throws IOException If an error occurred reading from the source. * @throws InterruptedException If the thread was interrupted. - * @throws TagPayloadReader.UnsupportedTrack If payload of the tag is using a codec non + * @throws TagPayloadReader.UnsupportedFormatException If payload of the tag is using a codec non * supported codec. */ private int readSample(ExtractorInput input) throws IOException, - InterruptedException, AudioTagPayloadReader.UnsupportedTrack { + InterruptedException, AudioTagPayloadReader.UnsupportedFormatException { if (tagData != null) { if (!input.readFully(tagData.data, 0, currentTagHeader.dataSize, true)) { return RESULT_END_OF_INPUT; diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/flv/ScriptTagPayloadReader.java b/library/src/main/java/com/google/android/exoplayer/extractor/flv/ScriptTagPayloadReader.java index d11185207a..eac5570475 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/flv/ScriptTagPayloadReader.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/flv/ScriptTagPayloadReader.java @@ -28,7 +28,7 @@ import java.util.Map; /** * Parses Script Data tags from an FLV stream and extracts metadata information. */ -final class ScriptTagPayloadReader extends TagPayloadReader { +/* package */ final class ScriptTagPayloadReader extends TagPayloadReader { // AMF object types private static final int AMF_TYPE_UNKNOWN = -1; @@ -50,19 +50,20 @@ final class ScriptTagPayloadReader extends TagPayloadReader { @Override public void seek() { - + // Do nothing. } @Override - protected boolean parseHeader(ParsableByteArray data) throws UnsupportedTrack { + protected boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException { return true; } @SuppressWarnings("unchecked") @Override protected void parsePayload(ParsableByteArray data, long timeUs) { - // Read message name (don't storing it as we are not going to give it any use) + // Read message name (don't store it because we don't yet have a use for it). readAMFData(data, AMF_TYPE_UNKNOWN); + // Read message data. Object obj = readAMFData(data, AMF_TYPE_UNKNOWN); if (obj instanceof Map) { @@ -74,7 +75,7 @@ final class ScriptTagPayloadReader extends TagPayloadReader { switch (entry.getKey()) { case "duration": - this.durationUs = (long)(C.MICROS_PER_SECOND * (Double)(entry.getValue())); + setDurationUs((long) (C.MICROS_PER_SECOND * (Double)(entry.getValue()))); break; default: @@ -198,4 +199,5 @@ final class ScriptTagPayloadReader extends TagPayloadReader { data.readUnsignedShort(); return date; } + } diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/flv/TagPayloadReader.java b/library/src/main/java/com/google/android/exoplayer/extractor/flv/TagPayloadReader.java index c032e3a8a1..da259bb4b7 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/flv/TagPayloadReader.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/flv/TagPayloadReader.java @@ -24,10 +24,20 @@ import com.google.android.exoplayer.util.ParsableByteArray; */ /* package */ abstract class TagPayloadReader { + /** + * Thrown when the format is not supported. + */ + public static final class UnsupportedFormatException extends Exception { + + public UnsupportedFormatException(String msg) { + super(msg); + } + + } + protected final TrackOutput output; - // Duration of the track - protected long durationUs; + private long durationUs; /** * @param output A {@link TrackOutput} to which samples should be written. @@ -37,6 +47,24 @@ import com.google.android.exoplayer.util.ParsableByteArray; this.durationUs = C.UNKNOWN_TIME_US; } + /** + * Sets duration in microseconds. + * + * @param durationUs duration in microseconds. + */ + public final void setDurationUs(long durationUs) { + this.durationUs = durationUs; + } + + /** + * Gets the duration in microseconds. + * + * @return The duration in microseconds. + */ + public final long getDurationUs() { + return durationUs; + } + /** * Notifies the reader that a seek has occurred. *

@@ -46,53 +74,34 @@ import com.google.android.exoplayer.util.ParsableByteArray; */ public abstract void seek(); - /** - * Parses tag header - * @param data Buffer where the tag header is stored - * @return True if header was parsed successfully and then payload should be read; - * Otherwise, false - * @throws UnsupportedTrack - */ - protected abstract boolean parseHeader(ParsableByteArray data) throws UnsupportedTrack; - - /** - * Parses tag payload - * @param data Buffer where tag payload is stored - * @param timeUs Time position of the frame - */ - protected abstract void parsePayload(ParsableByteArray data, long timeUs); - /** * Consumes payload data. * * @param data The payload data to consume. * @param timeUs The timestamp associated with the payload. */ - public void consume(ParsableByteArray data, long timeUs) throws UnsupportedTrack { + public final void consume(ParsableByteArray data, long timeUs) throws UnsupportedFormatException { if (parseHeader(data)) { parsePayload(data, timeUs); } } /** - * Sets duration in microseconds - * @param durationUs duration in microseconds + * Parses tag header. + * + * @param data Buffer where the tag header is stored. + * @return True if the header was parsed successfully and the payload should be read. False + * otherwise. + * @throws UnsupportedFormatException */ - public void setDurationUs(long durationUs) { - this.durationUs = durationUs; - } + protected abstract boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException; - public long getDurationUs() { - return durationUs; - } /** - * Thrown when format described in the AudioTrack is not supported + * Parses tag payload. + * + * @param data Buffer where tag payload is stored + * @param timeUs Time position of the frame */ - public static final class UnsupportedTrack extends Exception { + protected abstract void parsePayload(ParsableByteArray data, long timeUs); - public UnsupportedTrack(String msg) { - super(msg); - } - - } } diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/flv/VideoTagPayloadReader.java b/library/src/main/java/com/google/android/exoplayer/extractor/flv/VideoTagPayloadReader.java index e02a9f516c..620aa18e58 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/flv/VideoTagPayloadReader.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/flv/VideoTagPayloadReader.java @@ -34,7 +34,7 @@ import java.util.List; /** * Parses video tags from an FLV stream and extracts H.264 nal units. */ -final class VideoTagPayloadReader extends TagPayloadReader { +/* package */ final class VideoTagPayloadReader extends TagPayloadReader { private static final String TAG = "VideoTagPayloadReader"; // Video codec @@ -63,25 +63,23 @@ final class VideoTagPayloadReader extends TagPayloadReader { */ public VideoTagPayloadReader(TrackOutput output) { super(output); - nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE); nalLength = new ParsableByteArray(4); } @Override public void seek() { - + // Do nothing. } @Override - protected boolean parseHeader(ParsableByteArray data) throws UnsupportedTrack { + protected boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException { int header = data.readUnsignedByte(); int frameType = (header >> 4) & 0x0F; int videoCodec = (header & 0x0F); - // Support just H.264 encoded content. if (videoCodec != VIDEO_CODEC_AVC) { - throw new UnsupportedTrack("Video codec not supported. Codec: " + videoCodec); + throw new UnsupportedFormatException("Video format not supported: " + videoCodec); } this.frameType = frameType; return (frameType != VIDEO_FRAME_VIDEO_INFO); @@ -113,7 +111,7 @@ final class VideoTagPayloadReader extends TagPayloadReader { // Construct and output the format. MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.NO_VALUE, - MimeTypes.VIDEO_H264, MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, durationUs, + MimeTypes.VIDEO_H264, MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, getDurationUs(), avcData.width, avcData.height, avcData.initializationData, MediaFormat.NO_VALUE, avcData.pixelWidthAspectRatio); output.format(mediaFormat);