Merge pull request #7667 from willtrking:dev-v2-mkv-dovi

PiperOrigin-RevId: 328536503
This commit is contained in:
kim-vde 2020-08-26 16:40:35 +01:00
commit bcad98b9ff
2 changed files with 51 additions and 0 deletions

View File

@ -5,6 +5,9 @@
* Audio: Add an event for the audio position starting to advance, to make it
easier for apps to determine when audio playout started
([#7577](https://github.com/google/ExoPlayer/issues/7577)).
* Extractors:
* Support Dolby Vision extraction in Matroska
([#7267](https://github.com/google/ExoPlayer/issues/7267).
### 2.12.0 (not yet released - targeted for 2020-08-TBD) ###

View File

@ -48,6 +48,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.AvcConfig;
import com.google.android.exoplayer2.video.ColorInfo;
import com.google.android.exoplayer2.video.DolbyVisionConfig;
import com.google.android.exoplayer2.video.HevcConfig;
import java.io.IOException;
import java.lang.annotation.Documented;
@ -170,6 +171,9 @@ public class MatroskaExtractor implements Extractor {
private static final int ID_FLAG_FORCED = 0x55AA;
private static final int ID_DEFAULT_DURATION = 0x23E383;
private static final int ID_MAX_BLOCK_ADDITION_ID = 0x55EE;
private static final int ID_BLOCK_ADDITION_MAPPING = 0x41E4;
private static final int ID_BLOCK_ADD_ID_TYPE = 0x41E7;
private static final int ID_BLOCK_ADD_ID_EXTRA_DATA = 0x41ED;
private static final int ID_NAME = 0x536E;
private static final int ID_CODEC_ID = 0x86;
private static final int ID_CODEC_PRIVATE = 0x63A2;
@ -234,6 +238,17 @@ public class MatroskaExtractor implements Extractor {
*/
private static final int BLOCK_ADDITIONAL_ID_VP9_ITU_T_35 = 4;
/**
* BlockAddIdType value for Dolby Vision configuration with profile <= 7. See also
* https://www.matroska.org/technical/codec_specs.html.
*/
private static final int BLOCK_ADD_ID_TYPE_DVCC = 0x64766343;
/**
* BlockAddIdType value for Dolby Vision configuration with profile > 7. See also
* https://www.matroska.org/technical/codec_specs.html.
*/
private static final int BLOCK_ADD_ID_TYPE_DVVC = 0x64767643;
private static final int LACING_NONE = 0;
private static final int LACING_XIPH = 1;
private static final int LACING_FIXED_SIZE = 2;
@ -501,6 +516,7 @@ public class MatroskaExtractor implements Extractor {
case ID_CLUSTER:
case ID_TRACKS:
case ID_TRACK_ENTRY:
case ID_BLOCK_ADDITION_MAPPING:
case ID_AUDIO:
case ID_VIDEO:
case ID_CONTENT_ENCODINGS:
@ -535,6 +551,7 @@ public class MatroskaExtractor implements Extractor {
case ID_FLAG_FORCED:
case ID_DEFAULT_DURATION:
case ID_MAX_BLOCK_ADDITION_ID:
case ID_BLOCK_ADD_ID_TYPE:
case ID_CODEC_DELAY:
case ID_SEEK_PRE_ROLL:
case ID_CHANNELS:
@ -562,6 +579,7 @@ public class MatroskaExtractor implements Extractor {
case ID_LANGUAGE:
return EbmlProcessor.ELEMENT_TYPE_STRING;
case ID_SEEK_ID:
case ID_BLOCK_ADD_ID_EXTRA_DATA:
case ID_CONTENT_COMPRESSION_SETTINGS:
case ID_CONTENT_ENCRYPTION_KEY_ID:
case ID_SIMPLE_BLOCK:
@ -814,6 +832,9 @@ public class MatroskaExtractor implements Extractor {
case ID_MAX_BLOCK_ADDITION_ID:
currentTrack.maxBlockAdditionId = (int) value;
break;
case ID_BLOCK_ADD_ID_TYPE:
currentTrack.blockAddIdType = (int) value;
break;
case ID_CODEC_DELAY:
currentTrack.codecDelayNs = value;
break;
@ -1076,6 +1097,9 @@ public class MatroskaExtractor implements Extractor {
seekEntryIdBytes.setPosition(0);
seekEntryId = (int) seekEntryIdBytes.readUnsignedInt();
break;
case ID_BLOCK_ADD_ID_EXTRA_DATA:
handleBlockAddIDExtraData(currentTrack, input, contentSize);
break;
case ID_CODEC_PRIVATE:
currentTrack.codecPrivate = new byte[contentSize];
input.readFully(currentTrack.codecPrivate, 0, contentSize);
@ -1244,6 +1268,18 @@ public class MatroskaExtractor implements Extractor {
}
}
protected void handleBlockAddIDExtraData(Track track, ExtractorInput input, int contentSize)
throws IOException {
if (track.blockAddIdType == BLOCK_ADD_ID_TYPE_DVVC
|| track.blockAddIdType == BLOCK_ADD_ID_TYPE_DVCC) {
track.dolbyVisionConfigBytes = new byte[contentSize];
input.readFully(track.dolbyVisionConfigBytes, 0, contentSize);
} else {
// Unhandled BlockAddIDExtraData.
input.skipFully(contentSize);
}
}
protected void handleBlockAdditionalData(
Track track, int blockAdditionalId, ExtractorInput input, int contentSize)
throws IOException {
@ -1883,6 +1919,7 @@ public class MatroskaExtractor implements Extractor {
public int type;
public int defaultSampleDurationNs;
public int maxBlockAdditionId;
private int blockAddIdType;
public boolean hasContentEncryption;
public byte[] sampleStrippedBytes;
public TrackOutput.CryptoData cryptoData;
@ -1921,6 +1958,7 @@ public class MatroskaExtractor implements Extractor {
public float whitePointChromaticityY = Format.NO_VALUE;
public float maxMasteringLuminance = Format.NO_VALUE;
public float minMasteringLuminance = Format.NO_VALUE;
@Nullable public byte[] dolbyVisionConfigBytes;
// Audio elements. Initially set to their default values.
public int channelCount = 1;
@ -2091,6 +2129,16 @@ public class MatroskaExtractor implements Extractor {
throw new ParserException("Unrecognized codec identifier.");
}
if (dolbyVisionConfigBytes != null) {
@Nullable
DolbyVisionConfig dolbyVisionConfig =
DolbyVisionConfig.parse(new ParsableByteArray(this.dolbyVisionConfigBytes));
if (dolbyVisionConfig != null) {
codecs = dolbyVisionConfig.codecs;
mimeType = MimeTypes.VIDEO_DOLBY_VISION;
}
}
@C.SelectionFlags int selectionFlags = 0;
selectionFlags |= flagDefault ? C.SELECTION_FLAG_DEFAULT : 0;
selectionFlags |= flagForced ? C.SELECTION_FLAG_FORCED : 0;