AtomParser: Update initialization data to CodecPrivate format for Vp9

PiperOrigin-RevId: 666188937
This commit is contained in:
Googler 2024-08-21 22:31:10 -07:00 committed by Copybara-Service
parent 410b26fba1
commit 6b56f12f15
4 changed files with 43 additions and 1 deletions

View File

@ -21,6 +21,7 @@ import android.util.Pair;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.MimeTypes;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -80,6 +81,35 @@ public final class CodecSpecificDataUtil {
&& initializationData.get(0)[0] == 1;
}
/**
* Returns initialization data in CodecPrivate format of VP9.
*
* <p>Each feature of VP9 CodecPrivate is defined by the binary format of ID (1 byte), length (1
* byte), and data (1 byte). See <a>
* href="https://www.webmproject.org/docs/container/#vp9-codec-feature-metadata-codecprivate">CodecPrivate
* format of VP9</a> for more details.
*
* @param profile The VP9 codec profile.
* @param level The VP9 codec level.
* @param bitDepth The bit depth of the luma and color components.
* @param chromaSubsampling The chroma subsampling.
*/
public static ImmutableList<byte[]> buildVp9CodecPrivateInitializationData(
byte profile, byte level, byte bitDepth, byte chromaSubsampling) {
byte profileId = 0x01;
byte levelId = 0x02;
byte bitDepthId = 0x03;
byte chromaSubsamplingId = 0x04;
byte length = 0x01;
return ImmutableList.of(
new byte[] {
profileId, length, profile,
levelId, length, level,
bitDepthId, length, bitDepth,
chromaSubsamplingId, length, chromaSubsampling
});
}
/**
* Parses an MPEG-4 Visual configuration information, as defined in ISO/IEC14496-2.
*

View File

@ -1306,10 +1306,18 @@ public final class BoxParser {
mimeType = (atomType == Mp4Box.TYPE_vp08) ? MimeTypes.VIDEO_VP8 : MimeTypes.VIDEO_VP9;
parent.setPosition(childStartPosition + Mp4Box.FULL_HEADER_SIZE);
// See vpcC atom syntax: https://www.webmproject.org/vp9/mp4/#syntax_1
parent.skipBytes(2); // profile(8), level(8)
byte profile = (byte) parent.readUnsignedByte();
byte level = (byte) parent.readUnsignedByte();
int byte3 = parent.readUnsignedByte();
bitdepthLuma = byte3 >> 4;
bitdepthChroma = bitdepthLuma;
byte chromaSubsampling = (byte) ((byte3 >> 1) & 0b111);
if (mimeType.equals(MimeTypes.VIDEO_VP9)) {
// CSD should be in CodecPrivate format according to VP9 Codec spec.
initializationData =
CodecSpecificDataUtil.buildVp9CodecPrivateInitializationData(
profile, level, (byte) bitdepthLuma, chromaSubsampling);
}
boolean fullRangeFlag = (byte3 & 0b1) != 0;
int colorPrimaries = parent.readUnsignedByte();
int transferCharacteristics = parent.readUnsignedByte();

View File

@ -23,6 +23,8 @@ track 0:
lumaBitdepth = 8
chromaBitdepth = 8
metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 12, hash 31B20D86
sample 0:
time = 0
flags = 1

View File

@ -21,6 +21,8 @@ track 0:
lumaBitdepth = 8
chromaBitdepth = 8
metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 12, hash 53AEAE99
sample 0:
time = 0
flags = 1