mirror of
https://github.com/androidx/media.git
synced 2025-05-16 12:09:50 +08:00
Don't copy primary-track format to non-primary tracks
This time plumbing the track type in from the other side. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=166898172
This commit is contained in:
parent
d9cd13ce74
commit
5bed2bf503
@ -29,9 +29,10 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An {@link Extractor} wrapper for loading chunks containing a single track.
|
||||
* An {@link Extractor} wrapper for loading chunks that contain a single primary track, and possibly
|
||||
* additional embedded tracks.
|
||||
* <p>
|
||||
* The wrapper allows switching of the {@link TrackOutput} that receives parsed data.
|
||||
* The wrapper allows switching of the {@link TrackOutput}s that receive parsed data.
|
||||
*/
|
||||
public final class ChunkExtractorWrapper implements ExtractorOutput {
|
||||
|
||||
@ -56,7 +57,8 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
|
||||
|
||||
public final Extractor extractor;
|
||||
|
||||
private final Format manifestFormat;
|
||||
private final int primaryTrackType;
|
||||
private final Format primaryTrackManifestFormat;
|
||||
private final SparseArray<BindingTrackOutput> bindingTrackOutputs;
|
||||
|
||||
private boolean extractorInitialized;
|
||||
@ -66,12 +68,16 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
|
||||
|
||||
/**
|
||||
* @param extractor The extractor to wrap.
|
||||
* @param manifestFormat A manifest defined {@link Format} whose data should be merged into any
|
||||
* sample {@link Format} output from the {@link Extractor}.
|
||||
* @param primaryTrackType The type of the primary track. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param primaryTrackManifestFormat A manifest defined {@link Format} whose data should be merged
|
||||
* into any sample {@link Format} output from the {@link Extractor} for the primary track.
|
||||
*/
|
||||
public ChunkExtractorWrapper(Extractor extractor, Format manifestFormat) {
|
||||
public ChunkExtractorWrapper(Extractor extractor, int primaryTrackType,
|
||||
Format primaryTrackManifestFormat) {
|
||||
this.extractor = extractor;
|
||||
this.manifestFormat = manifestFormat;
|
||||
this.primaryTrackType = primaryTrackType;
|
||||
this.primaryTrackManifestFormat = primaryTrackManifestFormat;
|
||||
bindingTrackOutputs = new SparseArray<>();
|
||||
}
|
||||
|
||||
@ -90,8 +96,8 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the extractor to output to the provided {@link TrackOutput}, and configures it to
|
||||
* receive data from a new chunk.
|
||||
* Initializes the wrapper to output to {@link TrackOutput}s provided by the specified
|
||||
* {@link TrackOutputProvider}, and configures the extractor to receive data from a new chunk.
|
||||
*
|
||||
* @param trackOutputProvider The provider of {@link TrackOutput}s that will receive sample data.
|
||||
*/
|
||||
@ -116,7 +122,9 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
|
||||
if (bindingTrackOutput == null) {
|
||||
// Assert that if we're seeing a new track we have not seen endTracks.
|
||||
Assertions.checkState(sampleFormats == null);
|
||||
bindingTrackOutput = new BindingTrackOutput(id, type, manifestFormat);
|
||||
// TODO: Manifest formats for embedded tracks should also be passed here.
|
||||
bindingTrackOutput = new BindingTrackOutput(id, type,
|
||||
type == primaryTrackType ? primaryTrackManifestFormat : null);
|
||||
bindingTrackOutput.bind(trackOutputProvider);
|
||||
bindingTrackOutputs.put(id, bindingTrackOutput);
|
||||
}
|
||||
@ -160,16 +168,15 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
|
||||
return;
|
||||
}
|
||||
trackOutput = trackOutputProvider.track(id, type);
|
||||
if (trackOutput != null) {
|
||||
if (sampleFormat != null) {
|
||||
trackOutput.format(sampleFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void format(Format format) {
|
||||
// TODO: This should only happen for the primary track. Additional metadata/text tracks need
|
||||
// to be copied with different manifest derived formats.
|
||||
sampleFormat = format.copyWithManifestFormatInfo(manifestFormat);
|
||||
sampleFormat = manifestFormat != null ? format.copyWithManifestFormatInfo(manifestFormat)
|
||||
: format;
|
||||
trackOutput.format(sampleFormat);
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,11 @@ public final class DashUtil {
|
||||
*/
|
||||
public static DrmInitData loadDrmInitData(DataSource dataSource, Period period)
|
||||
throws IOException, InterruptedException {
|
||||
Representation representation = getFirstRepresentation(period, C.TRACK_TYPE_VIDEO);
|
||||
int primaryTrackType = C.TRACK_TYPE_VIDEO;
|
||||
Representation representation = getFirstRepresentation(period, primaryTrackType);
|
||||
if (representation == null) {
|
||||
representation = getFirstRepresentation(period, C.TRACK_TYPE_AUDIO);
|
||||
primaryTrackType = C.TRACK_TYPE_AUDIO;
|
||||
representation = getFirstRepresentation(period, primaryTrackType);
|
||||
if (representation == null) {
|
||||
return null;
|
||||
}
|
||||
@ -85,7 +87,7 @@ public final class DashUtil {
|
||||
// as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
|
||||
return drmInitData;
|
||||
}
|
||||
Format sampleFormat = DashUtil.loadSampleFormat(dataSource, representation);
|
||||
Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation);
|
||||
return sampleFormat == null ? null : sampleFormat.drmInitData;
|
||||
}
|
||||
|
||||
@ -93,15 +95,17 @@ public final class DashUtil {
|
||||
* Loads initialization data for the {@code representation} and returns the sample {@link Format}.
|
||||
*
|
||||
* @param dataSource The source from which the data should be loaded.
|
||||
* @param trackType The type of the representation. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param representation The representation which initialization chunk belongs to.
|
||||
* @return the sample {@link Format} of the given representation.
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
public static Format loadSampleFormat(DataSource dataSource, Representation representation)
|
||||
throws IOException, InterruptedException {
|
||||
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, representation,
|
||||
false);
|
||||
public static Format loadSampleFormat(DataSource dataSource, int trackType,
|
||||
Representation representation) throws IOException, InterruptedException {
|
||||
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
|
||||
representation, false);
|
||||
return extractorWrapper == null ? null : extractorWrapper.getSampleFormats()[0];
|
||||
}
|
||||
|
||||
@ -110,16 +114,18 @@ public final class DashUtil {
|
||||
* ChunkIndex}.
|
||||
*
|
||||
* @param dataSource The source from which the data should be loaded.
|
||||
* @param trackType The type of the representation. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param representation The representation which initialization chunk belongs to.
|
||||
* @return The {@link ChunkIndex} of the given representation, or null if no initialization or
|
||||
* index data exists.
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
public static ChunkIndex loadChunkIndex(DataSource dataSource, Representation representation)
|
||||
throws IOException, InterruptedException {
|
||||
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, representation,
|
||||
true);
|
||||
public static ChunkIndex loadChunkIndex(DataSource dataSource, int trackType,
|
||||
Representation representation) throws IOException, InterruptedException {
|
||||
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
|
||||
representation, true);
|
||||
return extractorWrapper == null ? null : (ChunkIndex) extractorWrapper.getSeekMap();
|
||||
}
|
||||
|
||||
@ -128,6 +134,8 @@ public final class DashUtil {
|
||||
* returns a {@link ChunkExtractorWrapper} which contains the output.
|
||||
*
|
||||
* @param dataSource The source from which the data should be loaded.
|
||||
* @param trackType The type of the representation. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param representation The representation which initialization chunk belongs to.
|
||||
* @param loadIndex Whether to load index data too.
|
||||
* @return A {@link ChunkExtractorWrapper} for the {@code representation}, or null if no
|
||||
@ -135,14 +143,13 @@ public final class DashUtil {
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource,
|
||||
Representation representation, boolean loadIndex)
|
||||
throws IOException, InterruptedException {
|
||||
private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource, int trackType,
|
||||
Representation representation, boolean loadIndex) throws IOException, InterruptedException {
|
||||
RangedUri initializationUri = representation.getInitializationUri();
|
||||
if (initializationUri == null) {
|
||||
return null;
|
||||
}
|
||||
ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(representation.format);
|
||||
ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(trackType, representation.format);
|
||||
RangedUri requestUri;
|
||||
if (loadIndex) {
|
||||
RangedUri indexUri = representation.getIndexUri();
|
||||
@ -174,12 +181,12 @@ public final class DashUtil {
|
||||
initializationChunk.load();
|
||||
}
|
||||
|
||||
private static ChunkExtractorWrapper newWrappedExtractor(Format format) {
|
||||
private static ChunkExtractorWrapper newWrappedExtractor(int trackType, Format format) {
|
||||
String mimeType = format.containerMimeType;
|
||||
boolean isWebm = mimeType.startsWith(MimeTypes.VIDEO_WEBM)
|
||||
|| mimeType.startsWith(MimeTypes.AUDIO_WEBM);
|
||||
Extractor extractor = isWebm ? new MatroskaExtractor() : new FragmentedMp4Extractor();
|
||||
return new ChunkExtractorWrapper(extractor, format);
|
||||
return new ChunkExtractorWrapper(extractor, trackType, format);
|
||||
}
|
||||
|
||||
private static Representation getFirstRepresentation(Period period, int type) {
|
||||
|
@ -134,8 +134,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||
representationHolders = new RepresentationHolder[trackSelection.length()];
|
||||
for (int i = 0; i < representationHolders.length; i++) {
|
||||
Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i));
|
||||
representationHolders[i] = new RepresentationHolder(periodDurationUs, representation,
|
||||
enableEventMessageTrack, enableCea608Track);
|
||||
representationHolders[i] = new RepresentationHolder(periodDurationUs, trackType,
|
||||
representation, enableEventMessageTrack, enableCea608Track);
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,8 +390,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||
private long periodDurationUs;
|
||||
private int segmentNumShift;
|
||||
|
||||
/* package */ RepresentationHolder(long periodDurationUs, Representation representation,
|
||||
boolean enableEventMessageTrack, boolean enableCea608Track) {
|
||||
/* package */ RepresentationHolder(long periodDurationUs, int trackType,
|
||||
Representation representation, boolean enableEventMessageTrack, boolean enableCea608Track) {
|
||||
this.periodDurationUs = periodDurationUs;
|
||||
this.representation = representation;
|
||||
String containerMimeType = representation.format.containerMimeType;
|
||||
@ -415,7 +415,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||
}
|
||||
// Prefer drmInitData obtained from the manifest over drmInitData obtained from the stream,
|
||||
// as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
|
||||
extractorWrapper = new ChunkExtractorWrapper(extractor, representation.format);
|
||||
extractorWrapper = new ChunkExtractorWrapper(extractor, trackType, representation.format);
|
||||
}
|
||||
segmentIndex = representation.getIndex();
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
||||
FragmentedMp4Extractor extractor = new FragmentedMp4Extractor(
|
||||
FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
|
||||
| FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX, null, track);
|
||||
extractorWrappers[i] = new ChunkExtractorWrapper(extractor, format);
|
||||
extractorWrappers[i] = new ChunkExtractorWrapper(extractor, streamElement.type, format);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user