Add a flag to enable EMSG output from FMP4 extractor
Issue #2176 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=144999302
This commit is contained in:
parent
e3b3c8b69c
commit
641597d708
@ -20,6 +20,7 @@ import android.util.Log;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||||
@ -74,7 +75,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef(flag = true, value = {FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME,
|
@IntDef(flag = true, value = {FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME,
|
||||||
FLAG_WORKAROUND_IGNORE_TFDT_BOX, FLAG_SIDELOADED})
|
FLAG_WORKAROUND_IGNORE_TFDT_BOX, FLAG_ENABLE_EMSG_TRACK, FLAG_SIDELOADED})
|
||||||
public @interface Flags {}
|
public @interface Flags {}
|
||||||
/**
|
/**
|
||||||
* Flag to work around an issue in some video streams where every frame is marked as a sync frame.
|
* Flag to work around an issue in some video streams where every frame is marked as a sync frame.
|
||||||
@ -88,11 +89,16 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
* Flag to ignore any tfdt boxes in the stream.
|
* Flag to ignore any tfdt boxes in the stream.
|
||||||
*/
|
*/
|
||||||
public static final int FLAG_WORKAROUND_IGNORE_TFDT_BOX = 2;
|
public static final int FLAG_WORKAROUND_IGNORE_TFDT_BOX = 2;
|
||||||
|
/**
|
||||||
|
* Flag to indicate that the extractor should output an event message metadata track. Any event
|
||||||
|
* messages in the stream will be delivered as samples to this track.
|
||||||
|
*/
|
||||||
|
public static final int FLAG_ENABLE_EMSG_TRACK = 4;
|
||||||
/**
|
/**
|
||||||
* Flag to indicate that the {@link Track} was sideloaded, instead of being declared by the MP4
|
* Flag to indicate that the {@link Track} was sideloaded, instead of being declared by the MP4
|
||||||
* container.
|
* container.
|
||||||
*/
|
*/
|
||||||
private static final int FLAG_SIDELOADED = 4;
|
private static final int FLAG_SIDELOADED = 8;
|
||||||
|
|
||||||
private static final byte[] PIFF_SAMPLE_ENCRYPTION_BOX_EXTENDED_TYPE =
|
private static final byte[] PIFF_SAMPLE_ENCRYPTION_BOX_EXTENDED_TYPE =
|
||||||
new byte[] {-94, 57, 79, 82, 90, -101, 79, 20, -94, 68, 108, 66, 124, 100, -115, -12};
|
new byte[] {-94, 57, 79, 82, 90, -101, 79, 20, -94, 68, 108, 66, 124, 100, -115, -12};
|
||||||
@ -143,7 +149,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
|
|
||||||
// Extractor output.
|
// Extractor output.
|
||||||
private ExtractorOutput extractorOutput;
|
private ExtractorOutput extractorOutput;
|
||||||
private TrackOutput metadataTrackOutput;
|
private TrackOutput eventMessageTrackOutput;
|
||||||
|
|
||||||
// Whether extractorOutput.seekMap has been called.
|
// Whether extractorOutput.seekMap has been called.
|
||||||
private boolean haveOutputSeekMap;
|
private boolean haveOutputSeekMap;
|
||||||
@ -196,6 +202,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
TrackBundle bundle = new TrackBundle(output.track(0));
|
TrackBundle bundle = new TrackBundle(output.track(0));
|
||||||
bundle.init(sideloadedTrack, new DefaultSampleValues(0, 0, 0, 0));
|
bundle.init(sideloadedTrack, new DefaultSampleValues(0, 0, 0, 0));
|
||||||
trackBundles.put(0, bundle);
|
trackBundles.put(0, bundle);
|
||||||
|
maybeInitEventMessageTrack();
|
||||||
extractorOutput.endTracks();
|
extractorOutput.endTracks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -406,6 +413,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
trackBundles.put(track.id, new TrackBundle(extractorOutput.track(i)));
|
trackBundles.put(track.id, new TrackBundle(extractorOutput.track(i)));
|
||||||
durationUs = Math.max(durationUs, track.durationUs);
|
durationUs = Math.max(durationUs, track.durationUs);
|
||||||
}
|
}
|
||||||
|
maybeInitEventMessageTrack();
|
||||||
extractorOutput.endTracks();
|
extractorOutput.endTracks();
|
||||||
} else {
|
} else {
|
||||||
Assertions.checkState(trackBundles.size() == trackCount);
|
Assertions.checkState(trackBundles.size() == trackCount);
|
||||||
@ -429,12 +437,20 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeInitEventMessageTrack() {
|
||||||
|
if ((flags & FLAG_ENABLE_EMSG_TRACK) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eventMessageTrackOutput = extractorOutput.track(trackBundles.size());
|
||||||
|
eventMessageTrackOutput.format(Format.createSampleFormat(null, MimeTypes.APPLICATION_EMSG,
|
||||||
|
Format.OFFSET_SAMPLE_RELATIVE));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles an emsg atom (defined in 23009-1).
|
* Handles an emsg atom (defined in 23009-1).
|
||||||
*/
|
*/
|
||||||
private void onEmsgLeafAtomRead(ParsableByteArray atom) {
|
private void onEmsgLeafAtomRead(ParsableByteArray atom) {
|
||||||
// TODO: Enable metadata output.
|
if (eventMessageTrackOutput == null) {
|
||||||
if (metadataTrackOutput == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Parse the event's presentation time delta.
|
// Parse the event's presentation time delta.
|
||||||
@ -447,11 +463,11 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
// Output the sample data.
|
// Output the sample data.
|
||||||
atom.setPosition(Atom.FULL_HEADER_SIZE);
|
atom.setPosition(Atom.FULL_HEADER_SIZE);
|
||||||
int sampleSize = atom.bytesLeft();
|
int sampleSize = atom.bytesLeft();
|
||||||
metadataTrackOutput.sampleData(atom, sampleSize);
|
eventMessageTrackOutput.sampleData(atom, sampleSize);
|
||||||
// Output the sample metadata.
|
// Output the sample metadata.
|
||||||
if (segmentIndexEarliestPresentationTimeUs != C.TIME_UNSET) {
|
if (segmentIndexEarliestPresentationTimeUs != C.TIME_UNSET) {
|
||||||
// We can output the sample metadata immediately.
|
// We can output the sample metadata immediately.
|
||||||
metadataTrackOutput.sampleMetadata(
|
eventMessageTrackOutput.sampleMetadata(
|
||||||
segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs,
|
segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs,
|
||||||
C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0 /* offset */, null);
|
C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0 /* offset */, null);
|
||||||
} else {
|
} else {
|
||||||
@ -673,7 +689,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
|
DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
|
||||||
int defaultSampleDescriptionIndex =
|
int defaultSampleDescriptionIndex =
|
||||||
((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
|
((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
|
||||||
? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
|
? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
|
||||||
int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
|
int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
|
||||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
|
? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
|
||||||
int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
|
int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
|
||||||
@ -1081,7 +1097,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
while (!pendingMetadataSampleInfos.isEmpty()) {
|
while (!pendingMetadataSampleInfos.isEmpty()) {
|
||||||
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
|
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
|
||||||
pendingMetadataSampleBytes -= sampleInfo.size;
|
pendingMetadataSampleBytes -= sampleInfo.size;
|
||||||
metadataTrackOutput.sampleMetadata(
|
eventMessageTrackOutput.sampleMetadata(
|
||||||
sampleTimeUs + sampleInfo.presentationTimeDeltaUs,
|
sampleTimeUs + sampleInfo.presentationTimeDeltaUs,
|
||||||
C.BUFFER_FLAG_KEY_FRAME, sampleInfo.size, pendingMetadataSampleBytes, null);
|
C.BUFFER_FLAG_KEY_FRAME, sampleInfo.size, pendingMetadataSampleBytes, null);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user