fix struct read funcs compile error
This commit is contained in:
parent
13d151545c
commit
dff1b98e9d
113
atom/atom.go
113
atom/atom.go
@ -1,116 +1,3 @@
|
|||||||
|
|
||||||
package atom
|
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 {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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
354
atom/genStruct.js
Normal 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()));
|
||||||
|
|
@ -6,15 +6,24 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Reader struct {
|
type Fixed32 uint32
|
||||||
io.LimitedReader
|
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) {
|
func ReadUInt(r io.Reader, n int) (res uint, err error) {
|
||||||
b := make([]byte, n)
|
var b []byte
|
||||||
if n, err = self.Read(b); err != nil {
|
if b, err = ReadBytes(r, n); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
@ -24,29 +33,48 @@ func (self Reader) ReadUInt(n int) (res uint, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Reader) ReadInt(n int) (res int, err error) {
|
func ReadInt(r io.Reader, n int) (res int, err error) {
|
||||||
var resu uint
|
var ui uint
|
||||||
if resu, err = self.ReadUInt(n); err != nil {
|
if ui, err = ReadUInt(r, n); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res = int(resu)
|
res = int(ui)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Reader) ReadString(n int) (res string, err error) {
|
func ReadFixed32(r io.Reader, n int) (res Fixed32, err error) {
|
||||||
b := make([]byte, n)
|
var ui uint
|
||||||
if n, err = self.Read(b); err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
res = string(b)
|
res = string(b)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Reader) Skip(n int) (err error) {
|
func ReadDummy(r io.Reader, n int) (res int, err error) {
|
||||||
_, err = io.CopyN(ioutil.Discard, self.Reader, int64(n))
|
_, err = io.CopyN(ioutil.Discard, r, int64(n))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func (self Reader) ReadAtom(atom Atom) (res Atom, err error) {
|
func (self Reader) ReadAtom(atom Atom) (res Atom, err error) {
|
||||||
for {
|
for {
|
||||||
var size int
|
var size int
|
||||||
@ -83,4 +111,5 @@ func (self Reader) ReadAtom(atom Atom) (res Atom, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
503
atom/struct.go
503
atom/struct.go
@ -1,134 +1,547 @@
|
|||||||
|
// THIS FILE IS AUTO GENERATED
|
||||||
package atom
|
package atom
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
type FileTypeAtom struct {
|
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 {
|
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 {
|
type MovieHeaderAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags int
|
Flags int
|
||||||
CTime Ts
|
CTime TimeStamp
|
||||||
MTime Ts
|
MTime TimeStamp
|
||||||
TimeScale int
|
TimeScale int
|
||||||
Duration int
|
Duration int
|
||||||
PreferredRate int
|
PreferredRate int
|
||||||
PreferredVolume int
|
PreferredVolume int
|
||||||
|
|
||||||
Matrix []byte
|
Matrix []byte
|
||||||
PreviewTime Ts
|
PreviewTime TimeStamp
|
||||||
PreviewDuration Ts
|
PreviewDuration TimeStamp
|
||||||
PosterTime Ts
|
PosterTime TimeStamp
|
||||||
SelectionTime Ts
|
SelectionTime TimeStamp
|
||||||
SelectionDuration Ts
|
SelectionDuration TimeStamp
|
||||||
CurrentTime Ts
|
CurrentTime TimeStamp
|
||||||
NextTrackId int
|
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 {
|
type TrackAtom struct {
|
||||||
TrackHeader *TrackHeader
|
Header *TrackHeaderAtom
|
||||||
Media *Media
|
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 {
|
type TrackHeaderAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags int
|
Flags int
|
||||||
CTime Ts
|
CTime TimeStamp
|
||||||
MTime Ts
|
MTime TimeStamp
|
||||||
TrackId int
|
TrackId int
|
||||||
|
Duration int
|
||||||
Duration int
|
|
||||||
|
|
||||||
Layer int
|
Layer int
|
||||||
AlternateGroup int
|
AlternateGroup int
|
||||||
Volume int
|
Volume int
|
||||||
|
Matrix []byte
|
||||||
|
TrackWidth Fixed32
|
||||||
|
TrackHeight Fixed32
|
||||||
|
}
|
||||||
|
|
||||||
Matrix []byte
|
func ReadTrackHeaderAtom(r *io.LimitedReader) (res *TrackHeaderAtom, err error) {
|
||||||
TrackWidth fixed32
|
self := &TrackHeaderAtom{}
|
||||||
TrackHeight fixed32
|
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 {
|
type MediaAtom struct {
|
||||||
MediaHeader *MediaHeader
|
Header *MediaHeaderAtom
|
||||||
MediaInfo *MediaInfo
|
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 {
|
type MediaHeaderAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags int
|
Flags int
|
||||||
CTime Ts
|
CTime TimeStamp
|
||||||
MTime Ts
|
MTime TimeStamp
|
||||||
TimeScale int
|
TimeScale int
|
||||||
Duration int
|
Duration int
|
||||||
Language int
|
Language int
|
||||||
Quality 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 {
|
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 {
|
type VideoMediaInfoAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags int
|
Flags int
|
||||||
GraphicsMode 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 {
|
type SampleTableAtom struct {
|
||||||
SampleDesc *SampleDesc
|
SampleDesc *SampleDescAtom
|
||||||
TimeToSample *TimeToSample
|
TimeToSample *TimeToSampleAtom
|
||||||
CompositionOffset *CompositionOffset
|
CompositionOffset *CompositionOffsetAtom
|
||||||
SyncSample *SyncSample
|
SyncSample *SyncSampleAtom
|
||||||
SampleSize *SampleSize
|
SampleSize *SampleSizeAtom
|
||||||
ChunkOffset *ChunkOffset
|
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 {
|
type SampleDescAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags 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 {
|
type TimeToSampleAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags 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 {
|
type CompositionOffsetAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags 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 {
|
type SyncSampleAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags 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 {
|
type SampleSizeAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags 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 {
|
type ChunkOffsetAtom struct {
|
||||||
Version int
|
Version int
|
||||||
Flags int
|
Flags int
|
||||||
|
Entries []int
|
||||||
}
|
}
|
||||||
|
|
||||||
type sampleDescEntry struct {
|
func ReadChunkOffsetAtom(r *io.LimitedReader) (res *ChunkOffsetAtom, err error) {
|
||||||
Format string
|
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
|
DataRefIdx int
|
||||||
Data []byte
|
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
|
Count int
|
||||||
Duration 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
|
Count int
|
||||||
Offset 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
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user