Skip to content

Commit

Permalink
feat: add lhvc, vexu, hfov, sgpd, colr boxes
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyoucao577 committed Nov 30, 2023
1 parent 7af5a62 commit bda3c53
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 17 deletions.
14 changes: 12 additions & 2 deletions container/mp4/box/box_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,18 @@ const (
TypeAvcC = "avcC"
TypeHev1 = "hev1"
TypeHvc1 = "hvc1"
TypehvcC = "hvcC"
TypeHvcC = "hvcC"
TypeLhvC = "lhvC"
TypeAv01 = "av01"
TypeAv1C = "av1C"
TypeBtrt = "btrt"
TypeMp4a = "mp4a"
TypeEsds = "esds"
TypePasp = "pasp"
TypeVexu = "vexu"
TypeColr = "colr"
TypeHfov = "hfov"
TypeSgpd = "sgpd"
)

var boxTypes = map[string]BasicInfo{
Expand Down Expand Up @@ -136,13 +141,18 @@ var boxTypes = map[string]BasicInfo{
TypeAvcC: {Name: "AVC Configuration Box"},
TypeHev1: {Name: "HEVC Sample Entry"},
TypeHvc1: {Name: "HEVC Sample Entry"},
TypehvcC: {Name: "HEVC Configuration Box"},
TypeHvcC: {Name: "HEVC Decoder Configuration Record"},
TypeLhvC: {Name: "L-HEVC Decoder Configuration Record"},
TypeAv01: {Name: "AV1 Sample Entry"},
TypeAv1C: {Name: "AV1 Configuration Box"},
TypeBtrt: {Name: "MPEG4 Bit Rate Box"},
TypeMp4a: {Name: "MP4 Visual Sample Entry"},
TypeEsds: {Name: "ES Descriptor Box"},
TypePasp: {Name: "Pixel Aspect Ratio Box"},
TypeVexu: {Name: "Video Extended Usage Box"},
TypeColr: {Name: "Colour Information Box"},
TypeHfov: {Name: "hfov Box"},
TypeSgpd: {Name: "Sample Group Description Box"},
}

// BoxTypes returns box types map.
Expand Down
8 changes: 7 additions & 1 deletion container/mp4/box/moov/moov_box.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/golang/glog"
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/container/mp4/box/meta"
"github.com/wangyoucao577/medialib/container/mp4/box/mvex"
"github.com/wangyoucao577/medialib/container/mp4/box/mvhd"
"github.com/wangyoucao577/medialib/container/mp4/box/trak"
Expand All @@ -21,6 +22,7 @@ type Box struct {
Udta *udta.Box `json:"udta,omitempty"`
Trak []trak.Box `json:"trak,omitempty"`
Mvex *mvex.Box `json:"mvex,omitempty"`
Meta []meta.Box `json:"meta,omitempty"`

boxesCreator map[string]box.NewFunc `json:"-"`
}
Expand All @@ -35,6 +37,7 @@ func New(h box.Header) box.Box {
box.TypeUdta: udta.New,
box.TypeTrak: trak.New,
box.TypeMvex: mvex.New,
box.TypeMeta: meta.New,
},
}
}
Expand All @@ -59,9 +62,12 @@ func (b *Box) CreateSubBox(h box.Header) (box.Box, error) {
b.Udta = createdBox.(*udta.Box)
case box.TypeTrak:
b.Trak = append(b.Trak, *createdBox.(*trak.Box))
createdBox = &b.Trak[len(b.Trak)-1] // reference to the last empty free box
createdBox = &b.Trak[len(b.Trak)-1] // reference to the last empty box
case box.TypeMvex:
b.Mvex = createdBox.(*mvex.Box)
case box.TypeMeta:
b.Meta = append(b.Meta, *createdBox.(*meta.Box))
createdBox = &b.Meta[len(b.Meta)-1] // reference to the last empty box
}

return createdBox, nil
Expand Down
38 changes: 38 additions & 0 deletions container/mp4/box/sampleentry/colr/colr_box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Package colr represents ColourInformationBox.
package colr

import (
"io"

"github.com/golang/glog"
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/util"
)

// Box represents a colr box.
type Box struct {
box.Header `json:"header"`
}

// New creates a new Box.
func New(h box.Header) box.Box {
return &Box{
Header: h,
}
}

// ParsePayload parse payload which requires basic box already exist.
func (b *Box) ParsePayload(r io.Reader) error {
if err := b.Validate(); err != nil {
glog.Warningf("box %s invalid, err %v", b.Type, err)
return nil
}

//TODO: these can be removed if we have supported full AVCDecoderConfigurationRecord parsing
glog.Warningf("box type %s still has %d bytes hasn't been parsed yet, ignore them", b.Type, b.PayloadSize())
if err := util.ReadOrError(r, make([]byte, b.PayloadSize())); err != nil {
return err
}

return nil
}
31 changes: 26 additions & 5 deletions container/mp4/box/sampleentry/hev1/hev1_sample_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,25 @@ import (
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/btrt"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/colr"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/hfov"
hvcc "github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/hvcC"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/vexu"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/vide"
)

// HEVCSampleEntry defined HEVC SampleEntry box.
type HEVCSampleEntry struct {
vide.VisualSampleEntry

HEVCConfig *hvcc.HEVCConfigrationBox `json:"hvcC"`
Btrt *btrt.Box `json:"btrt,omitempty"`
HvccConfig *hvcc.HEVCConfigrationBox `json:"hvcC"`

LhvcConfig *hvcc.HEVCConfigrationBox `json:"lhvC,omitempty"`
Colr *colr.Box `json:"colr,omitempty"`
Hfov *hfov.Box `json:"hfov,omitempty"`
Vexu *vexu.Box `json:"vexu,omitempty"`

Btrt *btrt.Box `json:"btrt,omitempty"`

boxesCreator map[string]box.NewFunc `json:"-"`
}
Expand All @@ -32,7 +41,11 @@ func New(h box.Header) box.Box {
},

boxesCreator: map[string]box.NewFunc{
box.TypehvcC: hvcc.New,
box.TypeHvcC: hvcc.New,
box.TypeLhvC: hvcc.New,
box.TypeColr: colr.New,
box.TypeHfov: hfov.New,
box.TypeVexu: vexu.New,
box.TypeBtrt: btrt.New,
},
}
Expand All @@ -52,8 +65,16 @@ func (a *HEVCSampleEntry) CreateSubBox(h box.Header) (box.Box, error) {
}

switch h.Type.String() {
case box.TypehvcC:
a.HEVCConfig = createdBox.(*hvcc.HEVCConfigrationBox)
case box.TypeHvcC:
a.HvccConfig = createdBox.(*hvcc.HEVCConfigrationBox)
case box.TypeLhvC:
a.LhvcConfig = createdBox.(*hvcc.HEVCConfigrationBox)
case box.TypeColr:
a.Colr = createdBox.(*colr.Box)
case box.TypeHfov:
a.Hfov = createdBox.(*hfov.Box)
case box.TypeVexu:
a.Vexu = createdBox.(*vexu.Box)
case box.TypeBtrt:
a.Btrt = createdBox.(*btrt.Box)
}
Expand Down
38 changes: 38 additions & 0 deletions container/mp4/box/sampleentry/hfov/hfov_box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Package hfov represents hfov box.
package hfov

import (
"io"

"github.com/golang/glog"
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/util"
)

// Box represents a hfov box.
type Box struct {
box.Header `json:"header"`
}

// New creates a new Box.
func New(h box.Header) box.Box {
return &Box{
Header: h,
}
}

// ParsePayload parse payload which requires basic box already exist.
func (b *Box) ParsePayload(r io.Reader) error {
if err := b.Validate(); err != nil {
glog.Warningf("box %s invalid, err %v", b.Type, err)
return nil
}

//TODO: these can be removed if we have supported full AVCDecoderConfigurationRecord parsing
glog.Warningf("box type %s still has %d bytes hasn't been parsed yet, ignore them", b.Type, b.PayloadSize())
if err := util.ReadOrError(r, make([]byte, b.PayloadSize())); err != nil {
return err
}

return nil
}
38 changes: 38 additions & 0 deletions container/mp4/box/sampleentry/sgpd/sgpd_box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Package sgpd represents Sample Group Description Box.
package sgpd

import (
"io"

"github.com/golang/glog"
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/util"
)

// Box represents a hfov box.
type Box struct {
box.Header `json:"header"`
}

// New creates a new Box.
func New(h box.Header) box.Box {
return &Box{
Header: h,
}
}

// ParsePayload parse payload which requires basic box already exist.
func (b *Box) ParsePayload(r io.Reader) error {
if err := b.Validate(); err != nil {
glog.Warningf("box %s invalid, err %v", b.Type, err)
return nil
}

//TODO: these can be removed if we have supported full AVCDecoderConfigurationRecord parsing
glog.Warningf("box type %s still has %d bytes hasn't been parsed yet, ignore them", b.Type, b.PayloadSize())
if err := util.ReadOrError(r, make([]byte, b.PayloadSize())); err != nil {
return err
}

return nil
}
38 changes: 38 additions & 0 deletions container/mp4/box/sampleentry/vexu/vexu_box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Package vexu represents Video Extended Usage Box for Multiview HEVC.
package vexu

import (
"io"

"github.com/golang/glog"
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/util"
)

// Box represents a vexu box.
type Box struct {
box.Header `json:"header"`
}

// New creates a new Box.
func New(h box.Header) box.Box {
return &Box{
Header: h,
}
}

// ParsePayload parse payload which requires basic box already exist.
func (b *Box) ParsePayload(r io.Reader) error {
if err := b.Validate(); err != nil {
glog.Warningf("box %s invalid, err %v", b.Type, err)
return nil
}

//TODO: these can be removed if we have supported full AVCDecoderConfigurationRecord parsing
glog.Warningf("box type %s still has %d bytes hasn't been parsed yet, ignore them", b.Type, b.PayloadSize())
if err := util.ReadOrError(r, make([]byte, b.PayloadSize())); err != nil {
return err
}

return nil
}
22 changes: 14 additions & 8 deletions container/mp4/box/stbl/stbl_box.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/container/mp4/box/ctts"
"github.com/wangyoucao577/medialib/container/mp4/box/hdlr"
"github.com/wangyoucao577/medialib/container/mp4/box/sampleentry/sgpd"
"github.com/wangyoucao577/medialib/container/mp4/box/sdtp"
"github.com/wangyoucao577/medialib/container/mp4/box/stco"
"github.com/wangyoucao577/medialib/container/mp4/box/stsc"
Expand All @@ -21,14 +22,15 @@ import (
type Box struct {
box.Header `json:"header"`

Stsd *stsd.Box `json:"stsd,omitempty"`
Stts *stts.Box `json:"stts,omitempty"`
Stss *stss.Box `json:"stss,omitempty"`
Stsc *stsc.Box `json:"stsc,omitempty"`
Stsz *stsz.Box `json:"stsz,omitempty"`
Stco *stco.Box `json:"stco,omitempty"`
Ctts *ctts.Box `json:"ctts,omitempty"`
Sdtp *sdtp.Box `json:"sdtp,omitempty"`
Stsd *stsd.Box `json:"stsd,omitempty"`
Stts *stts.Box `json:"stts,omitempty"`
Stss *stss.Box `json:"stss,omitempty"`
Stsc *stsc.Box `json:"stsc,omitempty"`
Stsz *stsz.Box `json:"stsz,omitempty"`
Stco *stco.Box `json:"stco,omitempty"`
Ctts *ctts.Box `json:"ctts,omitempty"`
Sdtp *sdtp.Box `json:"sdtp,omitempty"`
Sgpd []sgpd.Box `json:"sgpd,omitempty"`

// passed from parent for later use
hdlr *hdlr.Box `json:"-"`
Expand All @@ -55,6 +57,7 @@ func New(h box.Header) box.Box {
box.TypeStco: stco.New,
box.TypeCtts: ctts.New,
box.TypeSdtp: sdtp.New,
box.TypeSgpd: sgpd.New,
},
}
}
Expand Down Expand Up @@ -92,6 +95,9 @@ func (b *Box) CreateSubBox(h box.Header) (box.Box, error) {
b.Ctts = createdBox.(*ctts.Box)
case box.TypeSdtp:
b.Sdtp = createdBox.(*sdtp.Box)
case box.TypeSgpd:
b.Sgpd = append(b.Sgpd, *createdBox.(*sgpd.Box))
createdBox = &b.Sgpd[len(b.Sgpd)-1] // reference to the last empty box
}

return createdBox, nil
Expand Down
8 changes: 7 additions & 1 deletion container/mp4/box/trak/trak_box.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/wangyoucao577/medialib/container/mp4/box"
"github.com/wangyoucao577/medialib/container/mp4/box/edts"
"github.com/wangyoucao577/medialib/container/mp4/box/mdia"
"github.com/wangyoucao577/medialib/container/mp4/box/meta"
"github.com/wangyoucao577/medialib/container/mp4/box/tkhd"
"github.com/wangyoucao577/medialib/container/mp4/box/uuid"
)
Expand All @@ -20,6 +21,7 @@ type Box struct {
Mdia *mdia.Box `json:"mdia,omitempty"`
Uuid *uuid.Box `json:"uuid,omitempty"`
Edts []edts.Box `json:"edts,omitempty"`
Meta []meta.Box `json:"meta,omitempty"`

boxesCreator map[string]box.NewFunc `json:"-"`
}
Expand All @@ -36,6 +38,7 @@ func New(h box.Header) box.Box {
box.TypeMdia: mdia.New,
box.TypeUUID: uuid.New,
box.TypeEdts: edts.New,
box.TypeMeta: meta.New,
},
}
}
Expand All @@ -62,7 +65,10 @@ func (b *Box) CreateSubBox(h box.Header) (box.Box, error) {
b.Uuid = createdBox.(*uuid.Box)
case box.TypeEdts:
b.Edts = append(b.Edts, *createdBox.(*edts.Box))
createdBox = &b.Edts[len(b.Edts)-1] // reference to the last empty free box
createdBox = &b.Edts[len(b.Edts)-1] // reference to the last empty box
case box.TypeMeta:
b.Meta = append(b.Meta, *createdBox.(*meta.Box))
createdBox = &b.Meta[len(b.Meta)-1] // reference to the last empty box
}

return createdBox, nil
Expand Down

0 comments on commit bda3c53

Please sign in to comment.