Skip to content

Commit

Permalink
feat: add support for VP8 and VP9 video codecs
Browse files Browse the repository at this point in the history
Added support for VP8 and VP9 video codecs in MP4 containers:
- Added vp08 and vp09 boxes to decoder map
- Added VP Codec Configuration Box (vpcC)
- Updated StsdBox to support VP8/VP9 codec configurations
  • Loading branch information
tobbee committed Jan 25, 2025
1 parent 9019d6c commit 7978de0
Show file tree
Hide file tree
Showing 8 changed files with 402 additions and 211 deletions.
338 changes: 157 additions & 181 deletions CHANGELOG.md

Large diffs are not rendered by default.

27 changes: 15 additions & 12 deletions mp4/box.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ var decoders map[string]BoxDecoder

func init() {
decoders = map[string]BoxDecoder{
"\xa9ART": DecodeGenericContainerBox,
"\xa9nam": DecodeGenericContainerBox,
"\xa9too": DecodeGenericContainerBox,
"\xa9cpy": DecodeGenericContainerBox,
"ac-3": DecodeAudioSampleEntry,
"alou": DecodeAlou,
"av01": DecodeVisualSampleEntry,
"av1C": DecodeAv1C,
"avc1": DecodeVisualSampleEntry,
"avc3": DecodeVisualSampleEntry,
"avcC": DecodeAvcC,
"av1C": DecodeAv1C,
"btrt": DecodeBtrt,
"cdat": DecodeCdat,
"cdsc": DecodeTrefType,
"clap": DecodeClap,
"cslg": DecodeCslg,
"co64": DecodeCo64,
"colr": DecodeColr,
"cslg": DecodeCslg,
"ctim": DecodeCtim,
"ctts": DecodeCtts,
"dac3": DecodeDac3,
Expand All @@ -43,15 +47,15 @@ func init() {
"dpnd": DecodeTrefType,
"dref": DecodeDref,
"ec-3": DecodeAudioSampleEntry,
"elng": DecodeElng,
"esds": DecodeEsds,
"edts": DecodeEdts,
"elng": DecodeElng,
"elst": DecodeElst,
"emeb": DecodeEmeb,
"emib": DecodeEmib,
"emsg": DecodeEmsg,
"enca": DecodeAudioSampleEntry,
"encv": DecodeVisualSampleEntry,
"emsg": DecodeEmsg,
"esds": DecodeEsds,
"evte": DecodeEvte,
"font": DecodeTrefType,
"free": DecodeFree,
Expand All @@ -61,8 +65,8 @@ func init() {
"hev1": DecodeVisualSampleEntry,
"hind": DecodeTrefType,
"hint": DecodeTrefType,
"hvcC": DecodeHvcC,
"hvc1": DecodeVisualSampleEntry,
"hvcC": DecodeHvcC,
"iden": DecodeIden,
"ilst": DecodeIlst,
"iods": DecodeUnknown,
Expand All @@ -82,10 +86,10 @@ func init() {
"minf": DecodeMinf,
"moof": DecodeMoof,
"moov": DecodeMoov,
"mp4a": DecodeAudioSampleEntry,
"mpod": DecodeTrefType,
"mvex": DecodeMvex,
"mvhd": DecodeMvhd,
"mp4a": DecodeAudioSampleEntry,
"nmhd": DecodeNmhd,
"pasp": DecodePasp,
"payl": DecodePayl,
Expand All @@ -105,9 +109,9 @@ func init() {
"skip": DecodeFree,
"smhd": DecodeSmhd,
"ssix": DecodeSsix,
"sthd": DecodeSthd,
"stbl": DecodeStbl,
"stco": DecodeStco,
"sthd": DecodeSthd,
"stpp": DecodeStpp,
"stsc": DecodeStsc,
"stsd": DecodeStsd,
Expand Down Expand Up @@ -137,17 +141,16 @@ func init() {
"vdep": DecodeTrefType,
"vlab": DecodeVlab,
"vmhd": DecodeVmhd,
"vp08": DecodeVisualSampleEntry,
"vp09": DecodeVisualSampleEntry,
"vpcC": DecodeVppC,
"vplx": DecodeTrefType,
"vsid": DecodeVsid,
"vtta": DecodeVtta,
"vttc": DecodeVttc,
"vttC": DecodeVttC,
"vtte": DecodeVtte,
"wvtt": DecodeWvtt,
"\xa9cpy": DecodeGenericContainerBox,
"\xa9nam": DecodeGenericContainerBox,
"\xa9too": DecodeGenericContainerBox,
"\xa9ART": DecodeGenericContainerBox,
}
}

Expand Down
31 changes: 17 additions & 14 deletions mp4/boxsr.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,24 @@ var decodersSR map[string]BoxDecoderSR

func init() {
decodersSR = map[string]BoxDecoderSR{
"\xa9ART": DecodeGenericContainerBoxSR,
"\xa9cpy": DecodeGenericContainerBoxSR,
"\xa9nam": DecodeGenericContainerBoxSR,
"\xa9too": DecodeGenericContainerBoxSR,
"ac-3": DecodeAudioSampleEntrySR,
"alou": DecodeAlouBoxSR,
"av01": DecodeVisualSampleEntrySR,
"av1C": DecodeAv1CSR,
"avc1": DecodeVisualSampleEntrySR,
"avc3": DecodeVisualSampleEntrySR,
"alou": DecodeAlouBoxSR,
"avcC": DecodeAvcCSR,
"av1C": DecodeAv1CSR,
"btrt": DecodeBtrtSR,
"cdat": DecodeCdatSR,
"cdsc": DecodeTrefTypeSR,
"clap": DecodeClapSR,
"cslg": DecodeCslgSR,
"co64": DecodeCo64SR,
"colr": DecodeColrSR,
"cslg": DecodeCslgSR,
"ctim": DecodeCtimSR,
"ctts": DecodeCttsSR,
"dac3": DecodeDac3SR,
Expand All @@ -34,15 +38,15 @@ func init() {
"dpnd": DecodeTrefTypeSR,
"dref": DecodeDrefSR,
"ec-3": DecodeAudioSampleEntrySR,
"edts": DecodeEdtsSR,
"elng": DecodeElngSR,
"elst": DecodeElstSR,
"emeb": DecodeEmebSR,
"emib": DecodeEmibSR,
"esds": DecodeEsdsSR,
"edts": DecodeEdtsSR,
"elst": DecodeElstSR,
"emsg": DecodeEmsgSR,
"enca": DecodeAudioSampleEntrySR,
"encv": DecodeVisualSampleEntrySR,
"emsg": DecodeEmsgSR,
"esds": DecodeEsdsSR,
"evte": DecodeEvteSR,
"font": DecodeTrefTypeSR,
"free": DecodeFreeSR,
Expand All @@ -52,8 +56,8 @@ func init() {
"hev1": DecodeVisualSampleEntrySR,
"hind": DecodeTrefTypeSR,
"hint": DecodeTrefTypeSR,
"hvcC": DecodeHvcCSR,
"hvc1": DecodeVisualSampleEntrySR,
"hvcC": DecodeHvcCSR,
"iden": DecodeIdenSR,
"ilst": DecodeIlstSR,
"iods": DecodeUnknownSR,
Expand All @@ -73,10 +77,10 @@ func init() {
"minf": DecodeMinfSR,
"moof": DecodeMoofSR,
"moov": DecodeMoovSR,
"mp4a": DecodeAudioSampleEntrySR,
"mpod": DecodeTrefTypeSR,
"mvex": DecodeMvexSR,
"mvhd": DecodeMvhdSR,
"mp4a": DecodeAudioSampleEntrySR,
"nmhd": DecodeNmhdSR,
"pasp": DecodePaspSR,
"payl": DecodePaylSR,
Expand All @@ -96,9 +100,9 @@ func init() {
"skip": DecodeFreeSR,
"smhd": DecodeSmhdSR,
"ssix": DecodeSsixSR,
"sthd": DecodeSthdSR,
"stbl": DecodeStblSR,
"stco": DecodeStcoSR,
"sthd": DecodeSthdSR,
"stpp": DecodeStppSR,
"stsc": DecodeStscSR,
"stsd": DecodeStsdSR,
Expand Down Expand Up @@ -128,17 +132,16 @@ func init() {
"vdep": DecodeTrefTypeSR,
"vlab": DecodeVlabSR,
"vmhd": DecodeVmhdSR,
"vp08": DecodeVisualSampleEntrySR,
"vp09": DecodeVisualSampleEntrySR,
"vpcC": DecodeVppCSR,
"vplx": DecodeTrefTypeSR,
"vsid": DecodeVsidSR,
"vtta": DecodeVttaSR,
"vttc": DecodeVttcSR,
"vttC": DecodeVttCSR,
"vtte": DecodeVtteSR,
"wvtt": DecodeWvttSR,
"\xa9cpy": DecodeGenericContainerBoxSR,
"\xa9nam": DecodeGenericContainerBoxSR,
"\xa9too": DecodeGenericContainerBoxSR,
"\xa9ART": DecodeGenericContainerBoxSR,
}
}

Expand Down
4 changes: 4 additions & 0 deletions mp4/stsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type StsdBox struct {
Av01 *VisualSampleEntryBox
// Encv is a pointer to a box with name encv
Encv *VisualSampleEntryBox
// VppX is a pointer to a box with name vp08 or vp09 (VP8 or VP9 video)
VppX *VisualSampleEntryBox
// Mp4a is a pointer to a box with name mp4a
Mp4a *AudioSampleEntryBox
// AC3 is a pointer to a box with name ac-3
Expand Down Expand Up @@ -57,6 +59,8 @@ func (s *StsdBox) AddChild(box Box) {
s.Encv = box.(*VisualSampleEntryBox)
case "av01":
s.Av01 = box.(*VisualSampleEntryBox)
case "vp08", "vp09":
s.VppX = box.(*VisualSampleEntryBox)
case "mp4a":
s.Mp4a = box.(*AudioSampleEntryBox)
case "ac-3":
Expand Down
18 changes: 18 additions & 0 deletions mp4/stsd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mp4

import (
"bytes"
"encoding/hex"
"testing"

"github.com/Eyevinn/mp4ff/aac"
Expand Down Expand Up @@ -72,3 +73,20 @@ func TestStsdEncodeDecode(t *testing.T) {
t.Errorf("Expected nil, got %v", btrt)
}
}

func TestStsdVP9(t *testing.T) {
hexData := "" +
"000000a87374736400000000000000010000009876703039000000000000" +
"000100000000000000000000000000000000050002d00048000000480000" +
"000000000001184c61766336312e31392e313030206c69627670782d7670" +
"39000000000000000018ffff000000147670634301000000001f80020202" +
"00000000000a6669656c0100000000107061737000000001000000010000" +
"001462747274000000000010152200101522"

binData, err := hex.DecodeString(hexData)
if err != nil {
t.Error(err)
}

cmpAfterDecodeEncodeBox(t, binData)
}
10 changes: 6 additions & 4 deletions mp4/visualsampleentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type VisualSampleEntryBox struct {
AvcC *AvcCBox
HvcC *HvcCBox
Av1C *Av1CBox
VppC *VppCBox
Btrt *BtrtBox
Clap *ClapBox
Pasp *PaspBox
Expand Down Expand Up @@ -63,6 +64,8 @@ func (b *VisualSampleEntryBox) AddChild(child Box) {
b.HvcC = box
case *Av1CBox:
b.Av1C = box
case *VppCBox:
b.VppC = box
case *BtrtBox:
b.Btrt = box
case *ClapBox:
Expand All @@ -72,7 +75,6 @@ func (b *VisualSampleEntryBox) AddChild(child Box) {
case *SinfBox:
b.Sinf = box
}

b.Children = append(b.Children, child)
}

Expand Down Expand Up @@ -112,7 +114,7 @@ func DecodeVisualSampleEntrySR(hdr BoxHeader, startPos uint64, sr bits.SliceRead
}
b.CompressorName = sr.ReadFixedLengthString(int(compressorNameLength))
sr.SkipBytes(int(31 - compressorNameLength))
sr.ReadUint16() // depth == 0x0018
sr.SkipBytes(2) // Skip depth
sr.ReadUint16() // pre_defined == -1

// Now there may be clap and pasp boxes
Expand Down Expand Up @@ -179,7 +181,7 @@ func (b *VisualSampleEntryBox) Encode(w io.Writer) error {
sw.WriteUint8(compressorNameLength)
sw.WriteString(b.CompressorName, false)
sw.WriteZeroBytes(int(31 - compressorNameLength))
sw.WriteUint16(0x0018) // depth == 0x0018
sw.WriteUint16(0x0018) // depth
sw.WriteUint16(0xffff) // pre_defined == -1 //86 bytes

_, err = w.Write(buf[:sw.Offset()]) // Only write written bytes
Expand Down Expand Up @@ -218,7 +220,7 @@ func (b *VisualSampleEntryBox) EncodeSW(sw bits.SliceWriter) error {
sw.WriteUint8(compressorNameLength)
sw.WriteString(b.CompressorName, false)
sw.WriteZeroBytes(int(31 - compressorNameLength))
sw.WriteUint16(0x0018) // depth == 0x0018
sw.WriteUint16(0x0018) // depth
sw.WriteUint16(0xffff) // pre_defined == -1 //86 bytes

// Next output child boxes in order
Expand Down
Loading

0 comments on commit 7978de0

Please sign in to comment.