mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-02 21:33:52 +02:00
Support AVC3 in ISOBMFF (fixes #216)
This commit is contained in:
+5
-2
@@ -337,6 +337,7 @@ export const extractVideoCodecString = (trackInfo: {
|
|||||||
codec: VideoCodec | null;
|
codec: VideoCodec | null;
|
||||||
codecDescription: Uint8Array | null;
|
codecDescription: Uint8Array | null;
|
||||||
colorSpace: VideoColorSpaceInit | null;
|
colorSpace: VideoColorSpaceInit | null;
|
||||||
|
avcType: 1 | 3 | null;
|
||||||
avcCodecInfo: AvcDecoderConfigurationRecord | null;
|
avcCodecInfo: AvcDecoderConfigurationRecord | null;
|
||||||
hevcCodecInfo: HevcDecoderConfigurationRecord | null;
|
hevcCodecInfo: HevcDecoderConfigurationRecord | null;
|
||||||
vp9CodecInfo: Vp9CodecInfo | null;
|
vp9CodecInfo: Vp9CodecInfo | null;
|
||||||
@@ -345,6 +346,8 @@ export const extractVideoCodecString = (trackInfo: {
|
|||||||
const { codec, codecDescription, colorSpace, avcCodecInfo, hevcCodecInfo, vp9CodecInfo, av1CodecInfo } = trackInfo;
|
const { codec, codecDescription, colorSpace, avcCodecInfo, hevcCodecInfo, vp9CodecInfo, av1CodecInfo } = trackInfo;
|
||||||
|
|
||||||
if (codec === 'avc') {
|
if (codec === 'avc') {
|
||||||
|
assert(trackInfo.avcType !== null);
|
||||||
|
|
||||||
if (avcCodecInfo) {
|
if (avcCodecInfo) {
|
||||||
const bytes = new Uint8Array([
|
const bytes = new Uint8Array([
|
||||||
avcCodecInfo.avcProfileIndication,
|
avcCodecInfo.avcProfileIndication,
|
||||||
@@ -352,14 +355,14 @@ export const extractVideoCodecString = (trackInfo: {
|
|||||||
avcCodecInfo.avcLevelIndication,
|
avcCodecInfo.avcLevelIndication,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return `avc1.${bytesToHexString(bytes)}`;
|
return `avc${trackInfo.avcType}.${bytesToHexString(bytes)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codecDescription || codecDescription.byteLength < 4) {
|
if (!codecDescription || codecDescription.byteLength < 4) {
|
||||||
throw new TypeError('AVC decoder description is not provided or is not at least 4 bytes long.');
|
throw new TypeError('AVC decoder description is not provided or is not at least 4 bytes long.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return `avc1.${bytesToHexString(codecDescription.subarray(1, 4))}`;
|
return `avc${trackInfo.avcType}.${bytesToHexString(codecDescription.subarray(1, 4))}`;
|
||||||
} else if (codec === 'hevc') {
|
} else if (codec === 'hevc') {
|
||||||
let generalProfileSpace: number;
|
let generalProfileSpace: number;
|
||||||
let generalProfileIdc: number;
|
let generalProfileIdc: number;
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ type InternalTrack = {
|
|||||||
codec: VideoCodec | null;
|
codec: VideoCodec | null;
|
||||||
codecDescription: Uint8Array | null;
|
codecDescription: Uint8Array | null;
|
||||||
colorSpace: VideoColorSpaceInit | null;
|
colorSpace: VideoColorSpaceInit | null;
|
||||||
|
avcType: 1 | 3 | null;
|
||||||
avcCodecInfo: AvcDecoderConfigurationRecord | null;
|
avcCodecInfo: AvcDecoderConfigurationRecord | null;
|
||||||
hevcCodecInfo: HevcDecoderConfigurationRecord | null;
|
hevcCodecInfo: HevcDecoderConfigurationRecord | null;
|
||||||
vp9CodecInfo: Vp9CodecInfo | null;
|
vp9CodecInfo: Vp9CodecInfo | null;
|
||||||
@@ -836,6 +837,7 @@ export class IsobmffDemuxer extends Demuxer {
|
|||||||
codec: null,
|
codec: null,
|
||||||
codecDescription: null,
|
codecDescription: null,
|
||||||
colorSpace: null,
|
colorSpace: null,
|
||||||
|
avcType: null,
|
||||||
avcCodecInfo: null,
|
avcCodecInfo: null,
|
||||||
hevcCodecInfo: null,
|
hevcCodecInfo: null,
|
||||||
vp9CodecInfo: null,
|
vp9CodecInfo: null,
|
||||||
@@ -890,8 +892,9 @@ export class IsobmffDemuxer extends Demuxer {
|
|||||||
const lowercaseBoxName = sampleBoxInfo.name.toLowerCase();
|
const lowercaseBoxName = sampleBoxInfo.name.toLowerCase();
|
||||||
|
|
||||||
if (track.info.type === 'video') {
|
if (track.info.type === 'video') {
|
||||||
if (lowercaseBoxName === 'avc1') {
|
if (lowercaseBoxName === 'avc1' || lowercaseBoxName === 'avc3') {
|
||||||
track.info.codec = 'avc';
|
track.info.codec = 'avc';
|
||||||
|
track.info.avcType = lowercaseBoxName === 'avc1' ? 1 : 3;
|
||||||
} else if (lowercaseBoxName === 'hvc1' || lowercaseBoxName === 'hev1') {
|
} else if (lowercaseBoxName === 'hvc1' || lowercaseBoxName === 'hev1') {
|
||||||
track.info.codec = 'hevc';
|
track.info.codec = 'hevc';
|
||||||
} else if (lowercaseBoxName === 'vp08') {
|
} else if (lowercaseBoxName === 'vp08') {
|
||||||
|
|||||||
@@ -2319,6 +2319,7 @@ class MatroskaVideoTrackBacking extends MatroskaTrackBacking implements InputVid
|
|||||||
codec: this.internalTrack.info.codec,
|
codec: this.internalTrack.info.codec,
|
||||||
codecDescription: this.internalTrack.info.codecDescription,
|
codecDescription: this.internalTrack.info.codecDescription,
|
||||||
colorSpace: this.internalTrack.info.colorSpace,
|
colorSpace: this.internalTrack.info.colorSpace,
|
||||||
|
avcType: 1, // We don't know better (or do we?) so just assume 'avc1'
|
||||||
avcCodecInfo: this.internalTrack.info.codec === 'avc' && firstPacket
|
avcCodecInfo: this.internalTrack.info.codec === 'avc' && firstPacket
|
||||||
? extractAvcDecoderConfigurationRecord(firstPacket.data)
|
? extractAvcDecoderConfigurationRecord(firstPacket.data)
|
||||||
: null,
|
: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user