av01 parsing

This commit is contained in:
Muaz Ahmad 2023-10-12 14:21:20 +05:00
parent 5e38691180
commit fd6867bc57

View file

@ -49,19 +49,21 @@ class MP4Tree {
if (!this.parse_until('trak')) { // if no more tracks in file
break;
}
const curr_track_end = this.idx + this.read_next_head().len;
let curr_track_end = this.idx + this.read_next_head().len;
this.idx += 8
this.parse_into('mdia', 8);
this.parse_into('minf', 8);
const track_type_head = this.read_next_head().name;
let track_type_head = this.read_next_head().name;
if (track_type_head == 'smhd' || track_type_head == 'vmhd') {
this.parse_into('stbl', 8);
this.parse_into('stsd', 16);
const media_sample = this.read_next_head().name;
let media_sample = this.read_next_head().name;
if (media_sample == 'avc1') {
this.parse_avc1();
} else if (media_sample == 'vp09') {
this.parse_vp09();
} else if (media_sample == 'av01') {
this.parse_av01();
} else if (media_sample == 'mp4a') {
this.parse_mp4a();
} else if (media_sample == 'Opus') {
@ -80,27 +82,62 @@ class MP4Tree {
// ex, 01 64 00 1f
// 01 is avc version (always 1, bit-and it off)
// rest is video codec profile, rep as hex
const avc_profile = (this.data.getUint32(this.idx) & 0xffffff).toString(16);
let avc_profile = (this.data.getUint32(this.idx) & 0xffffff).toString(16);
this.codecs.push('avc1.' + avc_profile);
}
parse_vp09() {
this.parse_into('vp09', 86);
this.parse_into('vpcC', 12);
const profile = this.data.getUint8(this.idx).toString().padStart(2, "0");
const level = this.data.getUint8(this.idx + 1).toString();
const depth = (this.data.getUint8(this.idx + 2) >> 4).toString().padStart(2, "0");
let profile = this.data.getUint8(this.idx).toString().padStart(2, "0");
let level = this.data.getUint8(this.idx + 1).toString();
let depth = (this.data.getUint8(this.idx + 2) >> 4).toString().padStart(2, "0");
this.codecs.push(["vp09", profile, level, depth].join('.'));
}
parse_av01() {
this.parse_into('av01', 101);
this.parse_into('av1C', 8);
let tmp = this.data.getUint8(this.idx + 1);
let profile = tmp >> 5;
let level = tmp & 0x1f;
let tmp = this.data.getUint8(this.idx + 2);
switch (tmp >> 7) {
case 0:
let level_profile = "M";
break;
case 1:
let level_profile = "H";
break;
default:
let level_profile = "";
}
let depth_bits = (tmp >> 5) & 0x3;
switch (depth_bits) {
case 0:
let bit_depth = "8";
break;
case 1:
let bit_depth = "12";
break;
case 2:
let bit_depth = "10";
break;
default:
let bit_depth = "0";
break;
}
this.codecs.push(["av01", profile, level.toString().padStart(2, "0") + level_profile, bit_depth].join('.'))
}
parse_mp4a() {
this.parse_into('mp4a', 36); // 28 bytes of subboxes with unclear offsets
this.parse_into('esds', 12);
// mp4a is as mp4a.40.2
// oti has defined position, rep as hex
// aot as a subtype is defined as 5 bits of the fetched byte, rep as dec
const oti = this.data.getUint8(this.idx + 13).toString(16);
const aot = (this.data.getUint8(this.idx + 31) >> 3).toString(10);
let oti = this.data.getUint8(this.idx + 13).toString(16);
let aot = (this.data.getUint8(this.idx + 31) >> 3).toString(10);
this.codecs.push(["mp4a", oti, aot].join('.'));
}