fix struct read funcs compile error

This commit is contained in:
nareix 2015-11-19 18:26:32 +08:00
parent 13d151545c
commit dff1b98e9d
5 changed files with 856 additions and 467 deletions

View File

@ -1,116 +1,3 @@
package atom
import (
"log"
)
type Atom interface {
CC4() string
Read(Reader) error
}
type Ftyp struct {
}
func (self Ftyp) CC4() string {
return "ftyp"
}
func (self Ftyp) Read(r Reader) (err error) {
log.Println("read ftyp")
return
}
type Moov struct {
*Mvhd
Trak []*Trak
}
func (self Moov) CC4() string {
return "moov"
}
func (self *Moov) Read(r Reader) (err error) {
var atom Atom
if atom, err = r.ReadAtom(&Mvhd{}); err != nil {
return
}
self.Mvhd = atom.(*Mvhd)
for {
if atom, err := r.ReadAtom(&Trak{}); err != nil {
break
} else {
self.Trak = append(self.Trak, atom.(*Trak))
}
}
return
}
type Mvhd struct {
}
func (self Mvhd) CC4() string {
return "mvhd"
}
func (self Mvhd) Read(r Reader) (err error) {
return
}
type Tkhd struct {
}
func (self Tkhd) CC4() string {
return "tkhd"
}
func (self *Tkhd) Read(r Reader) (err error) {
return
}
type Minf struct {
}
type Mdia struct {
*Minf
}
type Trak struct {
Tkhd []*Tkhd
*Mdia
}
func (self Trak) CC4() string {
return "tkhd"
}
func (self *Trak) Read(r Reader) (err error) {
return
}
// Time-to-Sample Atoms
type Stts struct {
}
// Composition Offset Atom
type Ctts struct {
}
// Sync Sample Atoms (Keyframe)
type Stss struct {
}
// Sample-to-Chunk Atoms
type Stsc struct {
}
// Sample Size Atoms
type Stsz struct {
}
// Chunk Offset Atoms
type Stco struct {
}

View File

@ -1,294 +0,0 @@
var ucfirst = x => x.substr(0,1).toUpperCase() + x.slice(1);
var D = (cls, prop, ...fields) => {
var ctor = function (args) {
this.cls = cls;
Object.assign(this, prop);
fields.forEach((f, i) => this[f] = typeof(args[i]) == 'string' ? ucfirst(args[i]) : args[i]);
if (cls == 'Atom' || cls == 'AtomPtr')
this.type = this.type + 'Atom';
};
global[cls] = (...args) => new ctor(args);
}
D('Int', {basic: true, type: 'int'}, 'name', 'len');
D('Str', {basic: true, type: 'string'}, 'name', 'len');
D('TimeStamp', {basic: true, type: 'TimeStamp'}, 'name', 'len');
D('Bytes', {basic: true, type: '[]byte'}, 'name', 'len');
D('Fixed32', {basic: true, type: 'Fixed32'}, 'name', 'len');
D('Atom', {}, 'type', 'name');
D('AtomPtr', {}, 'type', 'name');
D('Struct', {}, 'type', 'name');
D('StructPtr', {}, 'type', 'name');
D('Arr', {}, 'name', 'elem', 'count');
D('LenArr', {}, 'len', 'name', 'elem', 'isptr');
D('Size', {hide: true}, 'len');
D('_', {type: 'Dummy', hide: true}, 'len');
var atoms = {
fileType: [
'ftyp',
AtomPtr('movie', 'movie'),
],
movie: [
'moov',
AtomPtr('movieHeader', 'header'),
Arr('tracks', AtomPtr('track')),
],
movieHeader: [
'mvhd',
Int('version', 1),
Int('flags', 3),
TimeStamp('cTime', 4),
TimeStamp('mTime', 4),
Int('timeScale', 4),
Int('duration', 4),
Int('preferredRate', 4),
Int('preferredVolume', 2),
_(10),
Bytes('matrix', 36),
TimeStamp('previewTime', 4),
TimeStamp('previewDuration', 4),
TimeStamp('posterTime', 4),
TimeStamp('selectionTime', 4),
TimeStamp('selectionDuration', 4),
TimeStamp('currentTime', 4),
Int('nextTrackId', 4),
],
track: [
'trak',
AtomPtr('trackHeader', 'header'),
AtomPtr('media', 'media'),
],
trackHeader: [
'tkhd',
Int('version', 1),
Int('flags', 3),
TimeStamp('cTime', 4),
TimeStamp('mTime', 4),
Int('trackId', 4),
_(4),
Int('duration', 4),
_(8),
Int('layer', 2),
Int('alternateGroup', 2),
Int('volume', 2),
_(2),
Bytes('matrix', 36),
Fixed32('trackWidth', 4),
Fixed32('trackHeight', 4),
],
media: [
'mdia',
AtomPtr('mediaHeader', 'header'),
AtomPtr('mediaInfo', 'info'),
],
mediaHeader: [
'mdhd',
Int('version', 1),
Int('flags', 3),
TimeStamp('cTime', 4),
TimeStamp('mTime', 4),
Int('timeScale', 4),
Int('duration', 4),
Int('language', 2),
Int('quality', 2),
],
mediaInfo: [
'minf',
AtomPtr('videoMediaInfo', 'video'),
AtomPtr('sampleTable', 'sample'),
],
videoMediaInfo: [
'vmhd',
Int('version', 1),
Int('flags', 3),
Int('graphicsMode', 2),
Arr('opcolor', Int('', 2), 3),
],
sampleTable: [
'stbl',
AtomPtr('sampleDesc', 'sampleDesc'),
AtomPtr('timeToSample', 'timeToSample'),
AtomPtr('compositionOffset', 'compositionOffset'),
AtomPtr('syncSample', 'syncSample'),
AtomPtr('sampleSize', 'sampleSize'),
AtomPtr('chunkOffset', 'chunkOffset'),
],
sampleDesc: [
'stsd',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Struct('sampleDescEntry')),
],
timeToSample: [
'stts',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Struct('timeToSampleEntry')),
],
compositionOffset: [
'ctts',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Struct('compositionOffsetEntry')),
],
syncSample: [
'stss',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Int('', 4)),
],
sampleSize: [
'stsz',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Int('', 4)),
],
chunkOffset: [
'stco',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Int('', 4)),
],
};
var structs = {
sampleDescEntry: [
Size(4),
Str('format', 4),
_(6),
Int('dataRefIdx', 2),
Bytes('data'),
],
timeToSampleEntry: [
Int('count', 4),
Int('duration', 4),
],
compositionOffsetEntry: [
Int('count', 4),
Int('offset', 4),
],
};
var typeStr = field => (
field.cls == 'AtomPtr' || field.cls == 'StructPtr') ? '*'+field.type : field.type;
var dumpStruct = (name, list) => {
console.log(`type ${name} struct {
%s
}`, list
.filter(field => !field.hide)
.map(field => {
if (field.cls == 'Arr' || field.cls == 'LenArr')
return field.name +' []'+typeStr(field.elem);
return field.name+' '+typeStr(field)
}).join('\n')
);
dumpReadFn(name, null, false, list);
};
var dumpReadFn = (type, cc4, retptr, list) => {
var useSize;
if (retptr) {
console.log(`func Read${type}(r io.LimitedReader) (res *${type}, err error) {`);
console.log(`self := &${type}{}`);
} else {
console.log(`func Read${type}(r io.LimitedReader) (self ${type}, err error) {`);
}
list.forEach(field => {
if (field.cls == 'Size') {
useSize = true;
console.log(`size := ReadInt(r, ${field.len})`);
} else if (field.cls == 'Arr') {
var cond = field.count ? `i := 0; i < ${field.count}; i++` : `r.N > 0`;
console.log(`for ${cond} {`);
console.log(`var item ${typeStr(field.elem)}`);
console.log(`if item, err = Read${field.elem.type}(r); err != nil {
return
} else {
self.${field.name} = append(self.${field.name}, item)
}`);
console.log(`}`);
} else if (field.cls == 'LenArr') {
console.log(`if n, err := ReadInt(r, ${field.len}); err != nil {
return nil, err
} else {
for i := 0; i < n; i++ {
self.${field.name} = append(self.${field.name}, item)
}
}`);
} else {
var fn = field.basic ? field.cls : field.type;
var args = field.basic ? 'r, ' + field.len : 'r';
console.log(`if self.${field.name}, err = Read${fn}(${args}); err != nil {
return
}`);
}
});
if (retptr) {
console.log(`res = self`);
}
console.log(`return`);
console.log(`}`);
};
var dumpWriteFn = (name, list) => {
var useSize;
console.log(`func Write${name}(w Writer, atom ${name}) (err error) {`);
list.map(x => {
if (x.type == 'size') {
useSize = true;
return `ReadInt(r, ${x.len})`;
}
});
console.log(`}`);
};
console.log('// THIS FILE IS AUTO GENERATED');
console.log('');
console.log('package atom');
for (var k in atoms) {
var list = atoms[k];
var name = ucfirst(k)+'Atom';
var cc4 = list[0];
list = list.slice(1);
dumpStruct(name, list);
dumpReadFn(name, cc4, true, list);
}
for (var k in structs) {
var list = structs[k];
dumpStruct(ucfirst(k), list)
}

354
atom/genStruct.js Normal file
View File

@ -0,0 +1,354 @@
var uc = x => x && x.substr(0,1).toUpperCase()+x.slice(1);
Array.prototype.nonull = function () {
return this.filter(x => x);
};
var Int = (name,len) => {return {name:uc(name),len,type:'int',fn:'Int'}};
var Str = (name,len) => {return {name:uc(name),len,type:'string',fn:'String'}};
var TimeStamp = (name,len) => {return {name:uc(name),len,type:'TimeStamp',fn:'TimeStamp'}};
var Bytes = (name,len) => {return {name:uc(name),len,type:'[]byte',fn:'Bytes'}};
var BytesLeft = (name) => {return {name:uc(name),type:'[]byte',fn:'BytesLeft'}};
var Fixed32 = (name,len) => {return {name:uc(name),len,type:'Fixed32',fn:'Fixed32'}};
var Atom = (type,name) => {return {name:uc(name),type:uc(type)+'Atom',fn:uc(type)+'Atom'}};
var AtomPtr = (type,name) => {return {name:uc(name),type:'*'+uc(type)+'Atom',fn:uc(type)+'Atom'}};
var Struct = (type,name) => {return {name:uc(name),type:uc(type),fn:uc(type)}};
var StructPtr = (type,name) => {return {name:uc(name),type:'*'+uc(type),fn:uc(type)}};
var Arr = (name,elem,count) => {return {name:uc(name),elem,count,type:'[]'+elem.type}};
var LenArr = (sizelen,name,elem) => {return {sizelen,name:uc(name),elem,type:'[]'+elem.type}};
var Size = (len) => {return {len,hide:true,fn:'Int'}};
var _ = (len) => {return {len,hide:true,fn:'Dummy'}};
var atoms = {
fileType: [
'ftyp',
AtomPtr('movie', 'movie'),
],
movie: [
'moov',
AtomPtr('movieHeader', 'header'),
Arr('tracks', AtomPtr('track')),
],
movieHeader: [
'mvhd',
Int('version', 1),
Int('flags', 3),
TimeStamp('cTime', 4),
TimeStamp('mTime', 4),
Int('timeScale', 4),
Int('duration', 4),
Int('preferredRate', 4),
Int('preferredVolume', 2),
_(10),
Bytes('matrix', 36),
TimeStamp('previewTime', 4),
TimeStamp('previewDuration', 4),
TimeStamp('posterTime', 4),
TimeStamp('selectionTime', 4),
TimeStamp('selectionDuration', 4),
TimeStamp('currentTime', 4),
Int('nextTrackId', 4),
],
track: [
'trak',
AtomPtr('trackHeader', 'header'),
AtomPtr('media', 'media'),
],
trackHeader: [
'tkhd',
Int('version', 1),
Int('flags', 3),
TimeStamp('cTime', 4),
TimeStamp('mTime', 4),
Int('trackId', 4),
_(4),
Int('duration', 4),
_(8),
Int('layer', 2),
Int('alternateGroup', 2),
Int('volume', 2),
_(2),
Bytes('matrix', 36),
Fixed32('trackWidth', 4),
Fixed32('trackHeight', 4),
],
media: [
'mdia',
AtomPtr('mediaHeader', 'header'),
AtomPtr('mediaInfo', 'info'),
],
mediaHeader: [
'mdhd',
Int('version', 1),
Int('flags', 3),
TimeStamp('cTime', 4),
TimeStamp('mTime', 4),
Int('timeScale', 4),
Int('duration', 4),
Int('language', 2),
Int('quality', 2),
],
mediaInfo: [
'minf',
AtomPtr('videoMediaInfo', 'video'),
AtomPtr('sampleTable', 'sample'),
],
videoMediaInfo: [
'vmhd',
Int('version', 1),
Int('flags', 3),
Int('graphicsMode', 2),
Arr('opcolor', Int('', 2), 3),
],
sampleTable: [
'stbl',
AtomPtr('sampleDesc', 'sampleDesc'),
AtomPtr('timeToSample', 'timeToSample'),
AtomPtr('compositionOffset', 'compositionOffset'),
AtomPtr('syncSample', 'syncSample'),
AtomPtr('sampleSize', 'sampleSize'),
AtomPtr('chunkOffset', 'chunkOffset'),
],
sampleDesc: [
'stsd',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Struct('sampleDescEntry')),
],
timeToSample: [
'stts',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Struct('timeToSampleEntry')),
],
compositionOffset: [
'ctts',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Struct('compositionOffsetEntry')),
],
syncSample: [
'stss',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Int('', 4)),
],
sampleSize: [
'stsz',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Int('', 4)),
],
chunkOffset: [
'stco',
Int('version', 1),
Int('flags', 3),
LenArr(4, 'entries', Int('', 4)),
],
};
var structs = {
sampleDescEntry: [
Size(4),
Str('format', 4),
_(6),
Int('dataRefIdx', 2),
BytesLeft('data'),
],
timeToSampleEntry: [
Int('count', 4),
Int('duration', 4),
],
compositionOffsetEntry: [
Int('count', 4),
Int('offset', 4),
],
};
var genReadStmts = (opts) => {
var stmts = [];
if (opts.resIsPtr)
stmts = stmts.concat([StrStmt(`self := &${opts.atomType}{}`)]);
var readElemStmts = field => {
var arr = 'self.'+field.name;
return [
DeclVar('item', field.elem.type),
CallCheckAssign('Read'+field.elem.fn, ['r', field.elem.len].nonull(), ['item']),
StrStmt(`${arr} = append(${arr}, item)`),
]
};
stmts = stmts.concat(opts.fields.map(field => {
if (field.sizelen) {
var arr = 'self.'+field.name;
return [
DeclVar('count', 'int'),
CallCheckAssign('ReadInt', ['r', field.sizelen], ['count']),
For(RangeN('i', 'count'), readElemStmts(field)),
];
} else if (field.elem) {
var cond = field.count ? RangeN('i', field.count) : StrStmt('r.N > 0');
return For(cond, readElemStmts(field));
} else if (!field.hide) {
return CallCheckAssign('Read'+field.fn, ['r', field.len].nonull(), ['self.'+field.name]);
}
}).nonull());
if (opts.resIsPtr)
stmts = stmts.concat([StrStmt(`res = self`)]);
return Func(
'Read'+opts.fnName,
[['r', '*io.LimitedReader']],
[[opts.resIsPtr?'res':'self', (opts.resIsPtr?'*':'')+opts.atomType], ['err', 'error']],
stmts
);
};
var D = (cls, ...fields) => {
global[cls] = (...args) => {
var obj = {cls: cls};
fields.forEach((k, i) => obj[k] = args[i]);
return obj;
};
};
D('Func', 'name', 'args', 'rets', 'body');
D('CallCheckAssign', 'fn', 'args', 'rets');
D('DeclVar', 'name', 'type');
D('For', 'cond', 'body');
D('RangeN', 'i', 'n');
D('DeclStruct', 'name', 'body');
D('StrStmt', 'content');
var dumpFn = f => {
var dumpArgs = x => x.map(x => x.join(' ')).join(',');
return `func ${f.name}(${dumpArgs(f.args)}) (${dumpArgs(f.rets)}) {
${dumpStmts(f.body)}
return
}`;
};
var dumpStmts = stmts => {
var dumpStmt = stmt => {
if (stmt instanceof Array) {
return dumpStmts(stmt);
} if (stmt.cls == 'CallCheckAssign') {
return `if ${stmt.rets.concat(['err']).join(',')} = ${stmt.fn}(${stmt.args.join(',')}); err != nil {
return
}`;
} else if (stmt.cls == 'DeclVar') {
return `var ${stmt.name} ${stmt.type}`;
} else if (stmt.cls == 'For') {
return `for ${dumpStmt(stmt.cond)} {
${dumpStmts(stmt.body)}
}`;
} else if (stmt.cls == 'RangeN') {
return `${stmt.i} := 0; ${stmt.i} < ${stmt.n}; ${stmt.i}++`;
} else if (stmt.cls == 'DeclStruct') {
return `type ${stmt.name} struct {
${stmt.body.map(line => line.join(' ')).join('\n')}
}`;
} else if (stmt.cls == 'Func') {
return dumpFn(stmt);
} else if (stmt.cls == 'StrStmt') {
return stmt.content;
}
};
return stmts.map(dumpStmt).join('\n')
};
(() => {
var len = 3;
var f = Func('Readxx', [['f', '*io.LimitedReader']], [['res', '*xx'], ['err', 'error']], [
CallCheckAssign('ReadInt', ['f', len], ['self.xx']),
CallCheckAssign('WriteInt', ['f', len], ['self.xx']),
DeclVar('n', 'int'),
For(RangeN('i', 'n'), [
CallCheckAssign('WriteInt', ['f', len], ['self.xx']),
DeclStruct('hi', [['a', 'b'], ['c', 'd'], ['e', 'f']]),
]),
]);
console.log(dumpFn(f));
});
var allStmts = () => {
var stmts = [];
var convStructFields = fields => {
var typeStr = field => (
field.cls == 'AtomPtr' || field.cls == 'StructPtr') ? '*'+field.type : field.type;
return fields.filter(field => !field.hide)
.map(field => {
if (field.cls == 'Arr' || field.cls == 'LenArr')
return [field.name, '[]'+typeStr(field.elem)];
return [field.name, typeStr(field)];
});
};
for (var k in atoms) {
var list = atoms[k];
var name = uc(k)+'Atom';
var cc4 = list[0];
var fields = list.slice(1);
stmts = stmts.concat([
DeclStruct(name, convStructFields(fields)),
genReadStmts({
cc4: cc4,
fields: fields,
fnName: name,
atomType: name,
resIsPtr: true,
}),
]);
}
for (var k in structs) {
var fields = structs[k];
var name = uc(k);
stmts = stmts.concat([
DeclStruct(name, convStructFields(fields)),
genReadStmts({
fields: fields,
fnName: name,
atomType: name,
}),
]);
}
return stmts;
};
console.log(`// THIS FILE IS AUTO GENERATED
package atom
import (
"io"
)
`, dumpStmts(allStmts()));

View File

@ -6,15 +6,24 @@ import (
"io/ioutil"
)
type Reader struct {
io.LimitedReader
type Fixed32 uint32
type TimeStamp uint32
func ReadBytes(r io.Reader, n int) (res []byte, err error) {
res = make([]byte, n)
if n, err = r.Read(res); err != nil {
return
}
return
}
type Fixed32 uint32
func ReadBytesLeft(r *io.LimitedReader) (res []byte, err error) {
return ReadBytes(r, int(r.N))
}
func (self Reader) ReadUInt(n int) (res uint, err error) {
b := make([]byte, n)
if n, err = self.Read(b); err != nil {
func ReadUInt(r io.Reader, n int) (res uint, err error) {
var b []byte
if b, err = ReadBytes(r, n); err != nil {
return
}
for i := 0; i < n; i++ {
@ -24,29 +33,48 @@ func (self Reader) ReadUInt(n int) (res uint, err error) {
return
}
func (self Reader) ReadInt(n int) (res int, err error) {
var resu uint
if resu, err = self.ReadUInt(n); err != nil {
func ReadInt(r io.Reader, n int) (res int, err error) {
var ui uint
if ui, err = ReadUInt(r, n); err != nil {
return
}
res = int(resu)
res = int(ui)
return
}
func (self Reader) ReadString(n int) (res string, err error) {
b := make([]byte, n)
if n, err = self.Read(b); err != nil {
func ReadFixed32(r io.Reader, n int) (res Fixed32, err error) {
var ui uint
if ui, err = ReadUInt(r, n); err != nil {
return
}
res = Fixed32(ui)
return
}
func ReadTimeStamp(r io.Reader, n int) (res TimeStamp, err error) {
var ui uint
if ui, err = ReadUInt(r, n); err != nil {
return
}
res = TimeStamp(ui)
return
}
func ReadString(r io.Reader, n int) (res string, err error) {
var b []byte
if b, err = ReadBytes(r, n); err != nil {
return
}
res = string(b)
return
}
func (self Reader) Skip(n int) (err error) {
_, err = io.CopyN(ioutil.Discard, self.Reader, int64(n))
func ReadDummy(r io.Reader, n int) (res int, err error) {
_, err = io.CopyN(ioutil.Discard, r, int64(n))
return
}
/*
func (self Reader) ReadAtom(atom Atom) (res Atom, err error) {
for {
var size int
@ -83,4 +111,5 @@ func (self Reader) ReadAtom(atom Atom) (res Atom, err error) {
return
}
}
*/

View File

@ -1,134 +1,547 @@
// THIS FILE IS AUTO GENERATED
package atom
import (
"io"
)
type FileTypeAtom struct {
Movie *Movie
Movie *MovieAtom
}
func ReadFileTypeAtom(r *io.LimitedReader) (res *FileTypeAtom, err error) {
self := &FileTypeAtom{}
if self.Movie, err = ReadMovieAtom(r); err != nil {
return
}
res = self
return
}
type MovieAtom struct {
MovieHeader *MovieHeader
Header *MovieHeaderAtom
Tracks []*TrackAtom
}
func ReadMovieAtom(r *io.LimitedReader) (res *MovieAtom, err error) {
self := &MovieAtom{}
if self.Header, err = ReadMovieHeaderAtom(r); err != nil {
return
}
for r.N > 0 {
var item *TrackAtom
if item, err = ReadTrackAtom(r); err != nil {
return
}
self.Tracks = append(self.Tracks, item)
}
res = self
return
}
type MovieHeaderAtom struct {
Version int
Flags int
CTime Ts
MTime Ts
TimeScale int
Duration int
PreferredRate int
PreferredVolume int
Version int
Flags int
CTime TimeStamp
MTime TimeStamp
TimeScale int
Duration int
PreferredRate int
PreferredVolume int
Matrix []byte
PreviewTime Ts
PreviewDuration Ts
PosterTime Ts
SelectionTime Ts
SelectionDuration Ts
CurrentTime Ts
PreviewTime TimeStamp
PreviewDuration TimeStamp
PosterTime TimeStamp
SelectionTime TimeStamp
SelectionDuration TimeStamp
CurrentTime TimeStamp
NextTrackId int
}
func ReadMovieHeaderAtom(r *io.LimitedReader) (res *MovieHeaderAtom, err error) {
self := &MovieHeaderAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
if self.CTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.MTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.TimeScale, err = ReadInt(r, 4); err != nil {
return
}
if self.Duration, err = ReadInt(r, 4); err != nil {
return
}
if self.PreferredRate, err = ReadInt(r, 4); err != nil {
return
}
if self.PreferredVolume, err = ReadInt(r, 2); err != nil {
return
}
if self.Matrix, err = ReadBytes(r, 36); err != nil {
return
}
if self.PreviewTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.PreviewDuration, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.PosterTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.SelectionTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.SelectionDuration, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.CurrentTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.NextTrackId, err = ReadInt(r, 4); err != nil {
return
}
res = self
return
}
type TrackAtom struct {
TrackHeader *TrackHeader
Media *Media
Header *TrackHeaderAtom
Media *MediaAtom
}
func ReadTrackAtom(r *io.LimitedReader) (res *TrackAtom, err error) {
self := &TrackAtom{}
if self.Header, err = ReadTrackHeaderAtom(r); err != nil {
return
}
if self.Media, err = ReadMediaAtom(r); err != nil {
return
}
res = self
return
}
type TrackHeaderAtom struct {
Version int
Flags int
CTime Ts
MTime Ts
TrackId int
Duration int
Version int
Flags int
CTime TimeStamp
MTime TimeStamp
TrackId int
Duration int
Layer int
AlternateGroup int
Volume int
Matrix []byte
TrackWidth Fixed32
TrackHeight Fixed32
}
Matrix []byte
TrackWidth fixed32
TrackHeight fixed32
func ReadTrackHeaderAtom(r *io.LimitedReader) (res *TrackHeaderAtom, err error) {
self := &TrackHeaderAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
if self.CTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.MTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.TrackId, err = ReadInt(r, 4); err != nil {
return
}
if self.Duration, err = ReadInt(r, 4); err != nil {
return
}
if self.Layer, err = ReadInt(r, 2); err != nil {
return
}
if self.AlternateGroup, err = ReadInt(r, 2); err != nil {
return
}
if self.Volume, err = ReadInt(r, 2); err != nil {
return
}
if self.Matrix, err = ReadBytes(r, 36); err != nil {
return
}
if self.TrackWidth, err = ReadFixed32(r, 4); err != nil {
return
}
if self.TrackHeight, err = ReadFixed32(r, 4); err != nil {
return
}
res = self
return
}
type MediaAtom struct {
MediaHeader *MediaHeader
MediaInfo *MediaInfo
Header *MediaHeaderAtom
Info *MediaInfoAtom
}
func ReadMediaAtom(r *io.LimitedReader) (res *MediaAtom, err error) {
self := &MediaAtom{}
if self.Header, err = ReadMediaHeaderAtom(r); err != nil {
return
}
if self.Info, err = ReadMediaInfoAtom(r); err != nil {
return
}
res = self
return
}
type MediaHeaderAtom struct {
Version int
Flags int
CTime Ts
MTime Ts
CTime TimeStamp
MTime TimeStamp
TimeScale int
Duration int
Language int
Quality int
}
func ReadMediaHeaderAtom(r *io.LimitedReader) (res *MediaHeaderAtom, err error) {
self := &MediaHeaderAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
if self.CTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.MTime, err = ReadTimeStamp(r, 4); err != nil {
return
}
if self.TimeScale, err = ReadInt(r, 4); err != nil {
return
}
if self.Duration, err = ReadInt(r, 4); err != nil {
return
}
if self.Language, err = ReadInt(r, 2); err != nil {
return
}
if self.Quality, err = ReadInt(r, 2); err != nil {
return
}
res = self
return
}
type MediaInfoAtom struct {
VideoMediaInfo *VideoMediaInfo
Video *VideoMediaInfoAtom
Sample *SampleTableAtom
}
func ReadMediaInfoAtom(r *io.LimitedReader) (res *MediaInfoAtom, err error) {
self := &MediaInfoAtom{}
if self.Video, err = ReadVideoMediaInfoAtom(r); err != nil {
return
}
if self.Sample, err = ReadSampleTableAtom(r); err != nil {
return
}
res = self
return
}
type VideoMediaInfoAtom struct {
Version int
Flags int
GraphicsMode int
Opcolor []int
}
func ReadVideoMediaInfoAtom(r *io.LimitedReader) (res *VideoMediaInfoAtom, err error) {
self := &VideoMediaInfoAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
if self.GraphicsMode, err = ReadInt(r, 2); err != nil {
return
}
for i := 0; i < 3; i++ {
var item int
if item, err = ReadInt(r, 2); err != nil {
return
}
self.Opcolor = append(self.Opcolor, item)
}
res = self
return
}
type SampleTableAtom struct {
SampleDesc *SampleDesc
TimeToSample *TimeToSample
CompositionOffset *CompositionOffset
SyncSample *SyncSample
SampleSize *SampleSize
ChunkOffset *ChunkOffset
SampleDesc *SampleDescAtom
TimeToSample *TimeToSampleAtom
CompositionOffset *CompositionOffsetAtom
SyncSample *SyncSampleAtom
SampleSize *SampleSizeAtom
ChunkOffset *ChunkOffsetAtom
}
func ReadSampleTableAtom(r *io.LimitedReader) (res *SampleTableAtom, err error) {
self := &SampleTableAtom{}
if self.SampleDesc, err = ReadSampleDescAtom(r); err != nil {
return
}
if self.TimeToSample, err = ReadTimeToSampleAtom(r); err != nil {
return
}
if self.CompositionOffset, err = ReadCompositionOffsetAtom(r); err != nil {
return
}
if self.SyncSample, err = ReadSyncSampleAtom(r); err != nil {
return
}
if self.SampleSize, err = ReadSampleSizeAtom(r); err != nil {
return
}
if self.ChunkOffset, err = ReadChunkOffsetAtom(r); err != nil {
return
}
res = self
return
}
type SampleDescAtom struct {
Version int
Flags int
Entries []SampleDescEntry
}
func ReadSampleDescAtom(r *io.LimitedReader) (res *SampleDescAtom, err error) {
self := &SampleDescAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
var count int
if count, err = ReadInt(r, 4); err != nil {
return
}
for i := 0; i < count; i++ {
var item SampleDescEntry
if item, err = ReadSampleDescEntry(r); err != nil {
return
}
self.Entries = append(self.Entries, item)
}
res = self
return
}
type TimeToSampleAtom struct {
Version int
Flags int
Entries []TimeToSampleEntry
}
func ReadTimeToSampleAtom(r *io.LimitedReader) (res *TimeToSampleAtom, err error) {
self := &TimeToSampleAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
var count int
if count, err = ReadInt(r, 4); err != nil {
return
}
for i := 0; i < count; i++ {
var item TimeToSampleEntry
if item, err = ReadTimeToSampleEntry(r); err != nil {
return
}
self.Entries = append(self.Entries, item)
}
res = self
return
}
type CompositionOffsetAtom struct {
Version int
Flags int
Entries []CompositionOffsetEntry
}
func ReadCompositionOffsetAtom(r *io.LimitedReader) (res *CompositionOffsetAtom, err error) {
self := &CompositionOffsetAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
var count int
if count, err = ReadInt(r, 4); err != nil {
return
}
for i := 0; i < count; i++ {
var item CompositionOffsetEntry
if item, err = ReadCompositionOffsetEntry(r); err != nil {
return
}
self.Entries = append(self.Entries, item)
}
res = self
return
}
type SyncSampleAtom struct {
Version int
Flags int
Entries []int
}
func ReadSyncSampleAtom(r *io.LimitedReader) (res *SyncSampleAtom, err error) {
self := &SyncSampleAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
var count int
if count, err = ReadInt(r, 4); err != nil {
return
}
for i := 0; i < count; i++ {
var item int
if item, err = ReadInt(r, 4); err != nil {
return
}
self.Entries = append(self.Entries, item)
}
res = self
return
}
type SampleSizeAtom struct {
Version int
Flags int
Entries []int
}
func ReadSampleSizeAtom(r *io.LimitedReader) (res *SampleSizeAtom, err error) {
self := &SampleSizeAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
var count int
if count, err = ReadInt(r, 4); err != nil {
return
}
for i := 0; i < count; i++ {
var item int
if item, err = ReadInt(r, 4); err != nil {
return
}
self.Entries = append(self.Entries, item)
}
res = self
return
}
type ChunkOffsetAtom struct {
Version int
Flags int
Entries []int
}
type sampleDescEntry struct {
Format string
func ReadChunkOffsetAtom(r *io.LimitedReader) (res *ChunkOffsetAtom, err error) {
self := &ChunkOffsetAtom{}
if self.Version, err = ReadInt(r, 1); err != nil {
return
}
if self.Flags, err = ReadInt(r, 3); err != nil {
return
}
var count int
if count, err = ReadInt(r, 4); err != nil {
return
}
for i := 0; i < count; i++ {
var item int
if item, err = ReadInt(r, 4); err != nil {
return
}
self.Entries = append(self.Entries, item)
}
res = self
return
}
type SampleDescEntry struct {
Format string
DataRefIdx int
Data []byte
}
type timeToSampleEntry struct {
func ReadSampleDescEntry(r *io.LimitedReader) (self SampleDescEntry, err error) {
if self.Format, err = ReadString(r, 4); err != nil {
return
}
if self.DataRefIdx, err = ReadInt(r, 2); err != nil {
return
}
if self.Data, err = ReadBytesLeft(r); err != nil {
return
}
return
}
type TimeToSampleEntry struct {
Count int
Duration int
}
type compositionOffsetEntry struct {
func ReadTimeToSampleEntry(r *io.LimitedReader) (self TimeToSampleEntry, err error) {
if self.Count, err = ReadInt(r, 4); err != nil {
return
}
if self.Duration, err = ReadInt(r, 4); err != nil {
return
}
return
}
type CompositionOffsetEntry struct {
Count int
Offset int
}
func ReadCompositionOffsetEntry(r *io.LimitedReader) (self CompositionOffsetEntry, err error) {
if self.Count, err = ReadInt(r, 4); err != nil {
return
}
if self.Offset, err = ReadInt(r, 4); err != nil {
return
}
return
}