1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 13:22:58 +03:00

decode: Simplify and move format arg into DecodeOptions

This commit is contained in:
Mattias Wadman 2021-09-16 15:29:11 +02:00
parent 26d615b852
commit 473b2243c9
35 changed files with 148 additions and 153 deletions

View File

@ -55,7 +55,7 @@ func apev2Decode(d *decode.D, in interface{}) interface{} {
d.DecodeLenFn(int64(itemSize)*8, func(d *decode.D) {
d.FieldStrNullTerminated("filename")
// assume image if binary
dv, _, _ := d.FieldTryFormat("value", imageFormat)
dv, _, _ := d.FieldTryFormat("value", imageFormat, nil)
if dv == nil {
// TODO: framed and unknown instead?
d.FieldBitBufLen("value", d.BitsLeft())

View File

@ -26,7 +26,7 @@ func init() {
func frameDecode(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("frame", func(d *decode.D) {
for d.NotEnd() {
d.FieldFormat("obu", obuFormat)
d.FieldFormat("obu", obuFormat, nil)
}
})

View File

@ -96,7 +96,7 @@ func gzDecode(d *decode.D, in interface{}) interface{} {
}
// calculatedCRC32 := crc32W.Sum(nil)
uncompressedBB := bitio.NewBufferFromBytes(uncompressed.Bytes(), -1)
dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat)
dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat, nil)
if dv == nil {
d.FieldRootBitBuf("uncompressed", uncompressedBB)
}

View File

@ -40,7 +40,7 @@ func flacDecode(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("metadatablocks", func(d *decode.D) {
for {
_, v := d.FieldFormat("metadatablock", flacMetadatablockFormat)
_, v := d.FieldFormat("metadatablock", flacMetadatablockFormat, nil)
flacMetadatablockOut, ok := v.(format.FlacMetadatablockOut)
if !ok {
panic(fmt.Sprintf("expected FlacMetadatablockOut got %#+v", v))
@ -60,7 +60,7 @@ func flacDecode(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("frames", func(d *decode.D) {
for d.NotEnd() {
// flac frame might need some fields from stream info to decode
_, v := d.FieldFormat("frame", flacFrameFormat, decode.FormatOptions{InArg: flacFrameIn})
_, v := d.FieldFormat("frame", flacFrameFormat, flacFrameIn)
ffo, ok := v.(format.FlacFrameOut)
if !ok {
panic(fmt.Sprintf("expected FlacFrameOut got %#+v", v))

View File

@ -83,9 +83,9 @@ func metadatablockDecode(d *decode.D, in interface{}) interface{} {
}
mb.HasStreamInfo = true
case MetadataBlockVorbisComment:
d.FieldFormatLen("comment", int64(length*8), vorbisCommentFormat)
d.FieldFormatLen("comment", int64(length*8), vorbisCommentFormat, nil)
case MetadataBlockPicture:
d.FieldFormatLen("picture", int64(length*8), flacPicture)
d.FieldFormatLen("picture", int64(length*8), flacPicture, nil)
case MetadataBlockSeektable:
seektableCount := length / 18
d.FieldArrayFn("seekpoints", func(d *decode.D) {

View File

@ -32,7 +32,7 @@ func pictureDecode(d *decode.D, in interface{}) interface{} {
d.FieldU32("color_depth")
d.FieldU32("number_of_index_colors")
pictureLen := d.FieldU32("picture_length")
d.FieldFormatLen("picture_data", int64(pictureLen)*8, images)
d.FieldFormatLen("picture_data", int64(pictureLen)*8, images, nil)
return nil
}

View File

@ -117,7 +117,7 @@ func gzDecode(d *decode.D, in interface{}) interface{} {
}
calculatedCRC32 = crc32W.Sum(nil)
uncompressedBB := bitio.NewBufferFromBytes(uncompressed.Bytes(), -1)
dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat)
dv, _, _ := d.FieldTryFormatBitBuf("uncompressed", uncompressedBB, probeFormat, nil)
if dv == nil {
d.FieldRootBitBuf("uncompressed", uncompressedBB)
}

View File

@ -454,7 +454,7 @@ func decodeFrame(d *decode.D, version int) uint64 {
fieldTextNull(d, "mime_type", encodingUTF8)
d.FieldU8("picture_type") // TODO: table
fieldTextNull(d, "description", int(encoding))
dv, _, _ := d.FieldTryFormatLen("picture", d.BitsLeft(), imageFormat)
dv, _, _ := d.FieldTryFormatLen("picture", d.BitsLeft(), imageFormat, nil)
if dv == nil {
d.FieldBitBufLen("picture", d.BitsLeft())
}
@ -471,9 +471,9 @@ func decodeFrame(d *decode.D, version int) uint64 {
fieldTextNull(d, "mime_type", encodingUTF8)
fieldTextNull(d, "filename", int(encoding))
fieldTextNull(d, "description", int(encoding))
dv, _, _ := d.FieldTryFormatLen("picture", d.BitsLeft(), imageFormat)
dv, _, _ := d.FieldTryFormatLen("data", d.BitsLeft(), imageFormat, nil)
if dv == nil {
d.FieldBitBufLen("picture", d.BitsLeft())
d.FieldBitBufLen("data", d.BitsLeft())
}
},
@ -569,7 +569,7 @@ func decodeFrame(d *decode.D, version int) uint64 {
}
return nil
}))
}), nil)
d.FieldBitBufLen("data", int64(dataSize*8))
} else {
if fn, ok := frames[idNormalized]; ok {

View File

@ -296,7 +296,7 @@ func jpegDecode(d *decode.D, in interface{}) interface{} {
d.FieldBitBufLen("data", int64(xThumbnail*yThumbnail)*3*8)
case markerCode == APP1 && d.TryHasBytes(app1ExifPrefix):
d.FieldUTF8("exif_prefix", len(app1ExifPrefix))
d.FieldFormatLen("exif", d.BitsLeft(), exifFormat)
d.FieldFormatLen("exif", d.BitsLeft(), exifFormat, nil)
case markerCode == APP1 && d.TryHasBytes(extendedXMPPrefix):
d.FieldStructFn("extended_xmp_chunk", func(d *decode.D) {
d.FieldUTF8("signature", len(extendedXMPPrefix))
@ -316,7 +316,7 @@ func jpegDecode(d *decode.D, in interface{}) interface{} {
// TODO: support multimarker?
d.FieldU8("cur_marker")
d.FieldU8("num_markers")
d.FieldFormatLen("icc_profile", d.BitsLeft(), iccProfileFormat)
d.FieldFormatLen("icc_profile", d.BitsLeft(), iccProfileFormat, nil)
case markerCode == APP13 && d.TryHasBytes(app13PhotoshopPrefix):
d.FieldUTF8("identifier", len(app13PhotoshopPrefix))
signature := d.FieldUTF8("signature", 4)

View File

@ -133,7 +133,7 @@ type track struct {
codec string
codecPrivatePos int64
codecPrivateTagSize int64
decodeOpts []decode.Options
formatInArg interface{}
}
type block struct {
@ -286,7 +286,7 @@ func decodeMaster(d *decode.D, bitsLimit int64, tag ebml.Tag, dc *decodeContext)
}
d.SeekRel(int64(tagSize) * 8)
case ebml_matroska.FileDataID:
d.FieldFormatLen("value", int64(tagSize)*8, imageFormat)
d.FieldFormatLen("value", int64(tagSize)*8, imageFormat, nil)
default:
d.FieldBitBufLen("value", int64(tagSize)*8)
// if tagID == CRC {
@ -357,29 +357,28 @@ func matroskaDecode(d *decode.D, in interface{}) interface{} {
})
d.FieldArrayFn("packets", func(d *decode.D) {
for _, l := range packetLengths {
d.FieldFormatLen("packet", l*8, vorbisPacketFormat)
d.FieldFormatLen("packet", l*8, vorbisPacketFormat, nil)
}
d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat)
d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat, nil)
})
})
case "A_AAC":
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegASCFrameFormat)
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegASCFrameFormat, nil)
case "A_OPUS":
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, opusPacketFrameFormat)
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, opusPacketFrameFormat, nil)
case "A_FLAC":
t.parentD.DecodeRangeFn(t.codecPrivatePos, t.codecPrivateTagSize, func(d *decode.D) {
d.FieldStructFn("value", func(d *decode.D) {
d.FieldValidateUTF8("magic", "fLaC")
d.FieldArrayFn("metadatablocks", func(d *decode.D) {
for {
_, v := d.FieldFormat("metadatablock", flacMetadatablockFormat)
_, v := d.FieldFormat("metadatablock", flacMetadatablockFormat, nil)
flacMetadatablockOut, ok := v.(format.FlacMetadatablockOut)
if !ok {
d.Invalid(fmt.Sprintf("expected FlacMetadatablockOut got %#+v", v))
}
if flacMetadatablockOut.HasStreamInfo {
t.decodeOpts = append(t.decodeOpts,
decode.FormatOptions{InArg: format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo}})
t.formatInArg = format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo}
}
if flacMetadatablockOut.IsLastBlock {
return
@ -389,25 +388,23 @@ func matroskaDecode(d *decode.D, in interface{}) interface{} {
})
})
case "V_MPEG4/ISO/AVC":
_, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegAVCDCRFormat)
_, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegAVCDCRFormat, nil)
avcDcrOut, ok := v.(format.AvcDcrOut)
if !ok {
d.Invalid(fmt.Sprintf("expected AvcDcrOut got %#+v", v))
}
t.decodeOpts = append(t.decodeOpts,
decode.FormatOptions{InArg: format.AvcIn{LengthSize: avcDcrOut.LengthSize}}) //nolint:gosimple
t.formatInArg = format.AvcIn{LengthSize: avcDcrOut.LengthSize} //nolint:gosimple
case "V_MPEGH/ISO/HEVC":
_, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegHEVCDCRFormat)
_, v := t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, mpegHEVCDCRFormat, nil)
hevcDcrOut, ok := v.(format.HevcDcrOut)
if !ok {
d.Invalid(fmt.Sprintf("expected HevcDcrOut got %#+v", v))
}
t.decodeOpts = append(t.decodeOpts,
decode.FormatOptions{InArg: format.HevcIn{LengthSize: hevcDcrOut.LengthSize}}) //nolint:gosimple
t.formatInArg = format.HevcIn{LengthSize: hevcDcrOut.LengthSize} //nolint:gosimple
case "V_AV1":
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, av1CCRFormat)
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, av1CCRFormat, nil)
case "V_VP9":
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, vp9CFMFormat)
t.parentD.FieldFormatRange("value", t.codecPrivatePos, t.codecPrivateTagSize, vp9CFMFormat, nil)
default:
t.parentD.FieldBitBufRange("value", t.codecPrivatePos, t.codecPrivateTagSize)
}
@ -438,7 +435,7 @@ func matroskaDecode(d *decode.D, in interface{}) interface{} {
// TODO: fixed/unknown?
if t, ok := trackNumberToTrack[int(trackNumber)]; ok {
if f, ok := codecToFormat[t.codec]; ok {
d.FieldFormat("packet", *f, t.decodeOpts...)
d.FieldFormat("packet", *f, t.formatInArg)
}
}

View File

@ -36,7 +36,7 @@ func mp3Decode(d *decode.D, in interface{}) interface{} {
// there are mp3s files in the wild with multiple headers, two id3v2 tags etc
d.FieldArrayFn("headers", func(d *decode.D) {
for d.NotEnd() {
if dv, _, _ := d.FieldTryFormat("header", headerFormat); dv == nil {
if dv, _, _ := d.FieldTryFormat("header", headerFormat, nil); dv == nil {
return
}
}
@ -59,7 +59,7 @@ func mp3Decode(d *decode.D, in interface{}) interface{} {
d.SeekRel(syncLen)
}
if dv, _, _ := d.FieldTryFormat("frame", mp3Frame); dv == nil {
if dv, _, _ := d.FieldTryFormat("frame", mp3Frame, nil); dv == nil {
decodeFailures++
d.SeekRel(8)
continue
@ -77,7 +77,7 @@ func mp3Decode(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("footers", func(d *decode.D) {
for d.NotEnd() {
if dv, _, _ := d.FieldTryFormat("footer", footerFormat); dv == nil {
if dv, _, _ := d.FieldTryFormat("footer", footerFormat, nil); dv == nil {
return
}
}

View File

@ -432,25 +432,23 @@ func init() {
})
},
"avcC": func(ctx *decodeContext, d *decode.D) {
_, v := d.FieldFormat("value", mpegAVCDCRFormat)
_, v := d.FieldFormat("value", mpegAVCDCRFormat, nil)
avcDcrOut, ok := v.(format.AvcDcrOut)
if !ok {
d.Invalid(fmt.Sprintf("expected AvcDcrOut got %#+v", v))
}
if ctx.currentTrack != nil {
ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts,
decode.FormatOptions{InArg: format.AvcIn{LengthSize: avcDcrOut.LengthSize}}) //nolint:gosimple
ctx.currentTrack.formatInArg = format.AvcIn{LengthSize: avcDcrOut.LengthSize} //nolint:gosimple
}
},
"hvcC": func(ctx *decodeContext, d *decode.D) {
_, v := d.FieldFormat("value", mpegHEVCDCRFrameFormat)
_, v := d.FieldFormat("value", mpegHEVCDCRFrameFormat, nil)
hevcDcrOut, ok := v.(format.HevcDcrOut)
if !ok {
d.Invalid(fmt.Sprintf("expected HevcDcrOut got %#+v", v))
}
if ctx.currentTrack != nil {
ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts,
decode.FormatOptions{InArg: format.HevcIn{LengthSize: hevcDcrOut.LengthSize}}) //nolint:gosimple
ctx.currentTrack.formatInArg = format.HevcIn{LengthSize: hevcDcrOut.LengthSize} //nolint:gosimple
}
},
"dfLa": func(ctx *decodeContext, d *decode.D) {
@ -458,15 +456,14 @@ func init() {
d.FieldU24("flags")
d.FieldArrayFn("metadatablocks", func(d *decode.D) {
for {
_, v := d.FieldFormat("metadatablock", flacMetadatablockFormat)
_, v := d.FieldFormat("metadatablock", flacMetadatablockFormat, nil)
flacMetadatablockOut, ok := v.(format.FlacMetadatablockOut)
if !ok {
d.Invalid(fmt.Sprintf("expected FlacMetadatablockOut got %#+v", v))
}
if flacMetadatablockOut.HasStreamInfo {
if ctx.currentTrack != nil {
ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts,
decode.FormatOptions{InArg: format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo}})
ctx.currentTrack.formatInArg = format.FlacFrameIn{StreamInfo: flacMetadatablockOut.StreamInfo}
}
}
if flacMetadatablockOut.IsLastBlock {
@ -476,20 +473,20 @@ func init() {
})
},
"dOps": func(_ *decodeContext, d *decode.D) {
d.FieldFormat("value", opusPacketFrameFormat)
d.FieldFormat("value", opusPacketFrameFormat, nil)
},
"av1C": func(_ *decodeContext, d *decode.D) {
d.FieldFormat("value", av1CCRFormat)
d.FieldFormat("value", av1CCRFormat, nil)
},
"vpcC": func(_ *decodeContext, d *decode.D) {
d.FieldU8("version")
d.FieldU24("flags")
d.FieldFormat("value", vpxCCRFormat)
d.FieldFormat("value", vpxCCRFormat, nil)
},
"esds": func(ctx *decodeContext, d *decode.D) {
d.FieldU32("version")
_, v := d.FieldFormat("es_descriptor", mpegESFormat)
_, v := d.FieldFormat("es_descriptor", mpegESFormat, nil)
mpegEsOut, ok := v.(format.MpegEsOut)
if !ok {
d.Invalid(fmt.Sprintf("expected mpegEsOut got %#+v", v))
@ -498,8 +495,7 @@ func init() {
if ctx.currentTrack != nil && len(mpegEsOut.DecoderConfigs) > 0 {
dc := mpegEsOut.DecoderConfigs[0]
ctx.currentTrack.objectType = dc.ObjectType
ctx.currentTrack.decodeOpts = append(ctx.currentTrack.decodeOpts,
decode.FormatOptions{InArg: format.AACFrameIn{ObjectType: dc.ASCObjectType}})
ctx.currentTrack.formatInArg = format.AACFrameIn{ObjectType: dc.ASCObjectType}
}
},
"stts": func(_ *decodeContext, d *decode.D) {
@ -671,7 +667,7 @@ func init() {
d.FieldU24("flags")
d.FieldU32("reserved")
if isParent(ctx, "covr") {
dv, _, _ := d.FieldTryFormatLen("data", d.BitsLeft(), imageFormat)
dv, _, _ := d.FieldTryFormatLen("data", d.BitsLeft(), imageFormat, nil)
if dv == nil {
d.FieldBitBufLen("data", d.BitsLeft())
}
@ -938,7 +934,7 @@ func init() {
}
return s, ""
})
d.FieldFormat("data", id3v2Format)
d.FieldFormat("data", id3v2Format, nil)
},
"mehd": func(_ *decodeContext, d *decode.D) {
d.FieldU8("version")
@ -978,9 +974,9 @@ func init() {
switch {
case bytes.Equal(systemID, systemIDWidevine[:]):
d.FieldFormatLen("data", int64(dataLen)*8, protoBufWidevineFormat)
d.FieldFormatLen("data", int64(dataLen)*8, protoBufWidevineFormat, nil)
case bytes.Equal(systemID, systemIDPlayReady[:]):
d.FieldFormatLen("data", int64(dataLen)*8, psshPlayreadyFormat)
d.FieldFormatLen("data", int64(dataLen)*8, psshPlayreadyFormat, nil)
case systemID == nil:
fallthrough
default:

View File

@ -107,7 +107,7 @@ type track struct {
stco []uint64 //
stsc []stsc
stsz []uint32
decodeOpts []decode.Options
formatInArg interface{}
objectType int // if data format is "mp4a"
moofs []*moof // for fmp4
@ -156,43 +156,43 @@ func mp4Decode(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("tracks", func(d *decode.D) {
for _, t := range sortedTracks {
decodeSampleRange := func(d *decode.D, t *track, dataFormat string, name string, firstBit int64, nBits int64, opts ...decode.Options) {
decodeSampleRange := func(d *decode.D, t *track, dataFormat string, name string, firstBit int64, nBits int64, inArg interface{}) {
switch dataFormat {
case "fLaC":
d.FieldFormatRange(name, firstBit, nBits, flacFrameFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, flacFrameFormat, inArg)
case "Opus":
d.FieldFormatRange(name, firstBit, nBits, opusPacketFrameFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, opusPacketFrameFormat, inArg)
case "vp09":
d.FieldFormatRange(name, firstBit, nBits, vp9FrameFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, vp9FrameFormat, inArg)
case "avc1":
d.FieldFormatRange(name, firstBit, nBits, mpegAVCAUFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, mpegAVCAUFormat, inArg)
case "hev1", "hvc1":
d.FieldFormatRange(name, firstBit, nBits, mpegHEVCSampleFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, mpegHEVCSampleFormat, inArg)
case "av01":
d.FieldFormatRange(name, firstBit, nBits, av1FrameFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, av1FrameFormat, inArg)
case "mp4a":
switch t.objectType {
case format.MPEGObjectTypeMP3:
d.FieldFormatRange(name, firstBit, nBits, mp3FrameFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, mp3FrameFormat, inArg)
case format.MPEGObjectTypeAAC:
// TODO: MPEGObjectTypeAACLow, Main etc?
d.FieldFormatRange(name, firstBit, nBits, aacFrameFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, aacFrameFormat, inArg)
case format.MPEGObjectTypeVORBIS:
d.FieldFormatRange(name, firstBit, nBits, vorbisPacketFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, vorbisPacketFormat, inArg)
default:
d.FieldBitBufRange(name, firstBit, nBits)
}
case "mp4v":
switch t.objectType {
case format.MPEGObjectTypeMPEG2VideoMain:
d.FieldFormatRange(name, firstBit, nBits, mpegPESPacketSampleFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, mpegPESPacketSampleFormat, inArg)
case format.MPEGObjectTypeMJPEG:
d.FieldFormatRange(name, firstBit, nBits, jpegFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, jpegFormat, inArg)
default:
d.FieldBitBufRange(name, firstBit, nBits)
}
case "jpeg":
d.FieldFormatRange(name, firstBit, nBits, jpegFormat, opts...)
d.FieldFormatRange(name, firstBit, nBits, jpegFormat, inArg)
default:
d.FieldBitBufRange(name, firstBit, nBits)
}
@ -234,7 +234,7 @@ func mp4Decode(d *decode.D, in interface{}) interface{} {
}
sampleSize := t.stsz[sampleNr]
decodeSampleRange(d, t, trackSdDataFormat, "sample", int64(sampleOffset)*8, int64(sampleSize)*8, t.decodeOpts...)
decodeSampleRange(d, t, trackSdDataFormat, "sample", int64(sampleOffset)*8, int64(sampleSize)*8, t.formatInArg)
// log.Printf("%s %d/%d %d/%d sample=%d/%d chunk=%d size=%d %d-%d\n",
// trackSdDataFormat, stscIndex, len(t.stsc),
@ -272,7 +272,7 @@ func mp4Decode(d *decode.D, in interface{}) interface{} {
// log.Printf("moof %#+v dataFormat: %#+v\n", m, dataFormat)
decodeSampleRange(d, t, dataFormat, "sample", sampleOffset*8, int64(sz)*8, t.decodeOpts...)
decodeSampleRange(d, t, dataFormat, "sample", sampleOffset*8, int64(sz)*8, t.formatInArg)
sampleOffset += int64(sz)
}
}

View File

@ -24,7 +24,7 @@ func adtsDecoder(d *decode.D, in interface{}) interface{} {
validFrames := 0
d.FieldArrayFn("frames", func(d *decode.D) {
for !d.End() {
if dv, _, _ := d.FieldTryFormat("frame", adtsFrame); dv == nil {
if dv, _, _ := d.FieldTryFormat("frame", adtsFrame, nil); dv == nil {
break
}
validFrames++

View File

@ -95,9 +95,7 @@ func adtsFrameDecoder(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("raw_data_blocks", func(d *decode.D) {
for i := uint64(0); i < numberOfRDBs; i++ {
d.FieldFormatLen("raw_data_block", int64(dataLength)*8, aacFrameFormat, decode.FormatOptions{
InArg: format.AACFrameIn{ObjectType: int(objectType)}},
)
d.FieldFormatLen("raw_data_block", int64(dataLength)*8, aacFrameFormat, format.AACFrameIn{ObjectType: int(objectType)})
}
})

View File

@ -40,7 +40,7 @@ func annexBDecode(d *decode.D, _ interface{}, format []*decode.Format) interface
}
naluLen := nextOffset
d.FieldFormatLen("nalu", naluLen, format)
d.FieldFormatLen("nalu", naluLen, format, nil)
currentPrefixLen = nextPrefixLen
}

View File

@ -31,7 +31,7 @@ func avcAUDecode(d *decode.D, in interface{}) interface{} {
for d.NotEnd() {
d.FieldStructFn("nalu", func(d *decode.D) {
l := d.FieldU("length", int(avcIn.LengthSize)*8)
d.FieldFormatLen("nalu", int64(l)*8, avcNALUFormat)
d.FieldFormatLen("nalu", int64(l)*8, avcNALUFormat, nil)
})
}
})

View File

@ -110,7 +110,7 @@ func avcDcrParameterSet(d *decode.D, numParamSets uint64) {
for i := uint64(0); i < numParamSets; i++ {
d.FieldStructFn("set", func(d *decode.D) {
paramSetLen := d.FieldU16("length")
d.FieldFormatLen("nal", int64(paramSetLen)*8, avcDCRNALFormat)
d.FieldFormatLen("nal", int64(paramSetLen)*8, avcDCRNALFormat, nil)
})
}
}

View File

@ -129,11 +129,11 @@ func avcNALUDecode(d *decode.D, in interface{}) interface{} {
// TODO: if ( separate_colour_plane_flag from SPS ) colour_plane_id; frame_num
})
case avcNALSupplementalEnhancementInformation:
d.FieldFormatBitBuf("sei", unescapedBb, avcSEIFormat)
d.FieldFormatBitBuf("sei", unescapedBb, avcSEIFormat, nil)
case avcNALSequenceParameterSet:
d.FieldFormatBitBuf("sps", unescapedBb, avcSPSFormat)
d.FieldFormatBitBuf("sps", unescapedBb, avcSPSFormat, nil)
case avcNALPictureParameterSet:
d.FieldFormatBitBuf("pps", unescapedBb, avcPPSFormat)
d.FieldFormatBitBuf("pps", unescapedBb, avcPPSFormat, nil)
}
d.FieldBitBufLen("data", d.BitsLeft())

View File

@ -29,7 +29,7 @@ func hevcAUDecode(d *decode.D, in interface{}) interface{} {
for d.NotEnd() {
d.FieldStructFn("nalu", func(d *decode.D) {
l := d.FieldU("length", int(hevcIn.LengthSize)*8)
d.FieldFormatLen("nalu", int64(l)*8, hevcAUNALFormat)
d.FieldFormatLen("nalu", int64(l)*8, hevcAUNALFormat, nil)
})
}
})

View File

@ -54,7 +54,7 @@ func hevcDcrDecode(d *decode.D, in interface{}) interface{} {
for i := uint64(0); i < numNals; i++ {
d.FieldStructFn("nal", func(d *decode.D) {
nalUnitLength := int64(d.FieldU16("nal_unit_length"))
d.FieldFormatLen("nal", nalUnitLength*8, hevcDCRNALFormat)
d.FieldFormatLen("nal", nalUnitLength*8, hevcDCRNALFormat, nil)
})
}
})

View File

@ -321,7 +321,7 @@ func frameDecode(d *decode.D, in interface{}) interface{} {
calcFrameBytes := int64(144*bitRate/sampleRate + paddingBytes)
dataWithPaddingBytes := calcFrameBytes - headerBytes - crcBytes - sideInfoBytes
if dv, _, _ := d.FieldTryFormat("xing", xingHeader); dv != nil {
if dv, _, _ := d.FieldTryFormat("xing", xingHeader, nil); dv != nil {
// TODO: allow shorter?
paddingBytes := dataWithPaddingBytes - dv.Range.Len/8
d.FieldBitBufLen("padding", paddingBytes*8)

View File

@ -238,16 +238,16 @@ func odDecodeTag(d *decode.D, edc *esDecodeContext, expectedTagID int, fn func(d
})
d.FieldArrayFn("packets", func(d *decode.D) {
for _, l := range packetLengths {
d.FieldFormatLen("packet", l*8, vorbisPacketFormat)
d.FieldFormatLen("packet", l*8, vorbisPacketFormat, nil)
}
d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat)
d.FieldFormatLen("packet", d.BitsLeft(), vorbisPacketFormat, nil)
})
})
default:
switch format.MpegObjectTypeStreamType[objectType] {
case format.MPEGStreamTypeAudio:
fieldODDecodeTag(d, edc, "decoder_specific_info", -1, func(d *decode.D) {
_, v := d.FieldFormat("audio_specific_config", mpegASCFormat)
_, v := d.FieldFormat("audio_specific_config", mpegASCFormat, nil)
mpegASCout, ok := v.(format.MPEGASCOut)
if !ok {
panic(fmt.Sprintf("expected MPEGASCOut got %#+v", v))

View File

@ -47,7 +47,7 @@ func pesDecode(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("packets", func(d *decode.D) {
for d.NotEnd() {
dv, v, err := d.FieldTryFormat("packet", pesPacketFormat)
dv, v, err := d.FieldTryFormat("packet", pesPacketFormat, nil)
if dv == nil || err != nil {
log.Printf("errs[0]: %#+v\n", err)
break
@ -70,7 +70,7 @@ func pesDecode(d *decode.D, in interface{}) interface{} {
// TODO: is this how spu end is signalled?
if s.l == len(s.b) {
spuD.FieldFormatBitBuf("spu", bitio.NewBufferFromBytes(s.b, -1), spuFormat)
spuD.FieldFormatBitBuf("spu", bitio.NewBufferFromBytes(s.b, -1), spuFormat, nil)
s.b = nil
s.l = 0
}

View File

@ -57,7 +57,7 @@ func decodeOgg(d *decode.D, in interface{}) interface{} {
d.FieldArrayFn("pages", func(d *decode.D) {
for !d.End() {
_, dv, _ := d.FieldTryFormat("page", oggPage)
_, dv, _ := d.FieldTryFormat("page", oggPage, nil)
if dv == nil {
break
}
@ -119,10 +119,10 @@ func decodeOgg(d *decode.D, in interface{}) interface{} {
switch s.codec {
case codecVorbis:
// TODO: err
_, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, vorbisPacket)
_, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, vorbisPacket, nil)
case codecOpus:
// TODO: err
_, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, opusPacket)
_, _, _ = s.packetD.FieldTryFormatBitBuf("packet", bb, opusPacket, nil)
case codecUnknown:
s.packetD.FieldBitBuf("packet", bb)
}

View File

@ -49,7 +49,7 @@ func opusDecode(d *decode.D, in interface{}) interface{} {
case bytes.Equal(prefix, []byte("OpusTags")):
d.FieldValueStr("type", "tags", "")
d.FieldUTF8("prefix", 8)
d.FieldFormat("comment", vorbisComment)
d.FieldFormat("comment", vorbisComment, nil)
default:
d.FieldValueStr("type", "audio", "")
d.FieldStructFn("toc", func(d *decode.D) {

View File

@ -162,7 +162,7 @@ func pngDecode(d *decode.D, in interface{}) interface{} {
d.FieldFloatFn("blue_x", df)
d.FieldFloatFn("blue_y", df)
case "eXIf":
d.FieldFormatLen("exif", int64(chunkLength)*8, exifFormat)
d.FieldFormatLen("exif", int64(chunkLength)*8, exifFormat, nil)
case "acTL":
d.FieldU32("num_frames")
d.FieldU32("num_plays")

View File

@ -41,7 +41,7 @@ func widevineDecode(d *decode.D, in interface{}) interface{} {
}},
}
d.Format(widevineProtoBufFormat, decode.FormatOptions{InArg: format.ProtoBufIn{Message: widewinePb}})
d.Format(widevineProtoBufFormat, format.ProtoBufIn{Message: widewinePb})
return nil
}

View File

@ -88,7 +88,7 @@ func tarDecode(d *decode.D, in interface{}) interface{} {
fieldStr(d, "prefix", 155)
fieldBlockPadding(d, "header_block_padding")
if size > 0 {
dv, _, _ := d.FieldTryFormatLen("data", int64(size)*8, probeFormat)
dv, _, _ := d.FieldTryFormatLen("data", int64(size)*8, probeFormat, nil)
if dv == nil {
d.FieldBitBufLen("data", int64(size)*8)
}

View File

@ -137,7 +137,7 @@ func decodeIfd(d *decode.D, s *strips, tagNames map[uint64]string) int64 {
case typ == UNDEFINED:
switch tag {
case InterColorProfile:
d.FieldFormatRange("icc", int64(valueByteOffset)*8, int64(valueByteSize)*8, tiffIccProfile)
d.FieldFormatRange("icc", int64(valueByteOffset)*8, int64(valueByteSize)*8, tiffIccProfile, nil)
default:
// log.Printf("tag: %#+v\n", tag)
// log.Printf("valueByteSize: %#+v\n", valueByteSize)

View File

@ -40,7 +40,7 @@ func commentDecode(d *decode.D, in interface{}) interface{} {
bs, err := base64.StdEncoding.DecodeString(v)
if err == nil {
bb := bitio.NewBufferFromBytes(bs, -1)
d.FieldFormatBitBuf("picture", bb, flacPicture)
d.FieldFormatBitBuf("picture", bb, flacPicture, nil)
} else {
panic(err)
}

View File

@ -119,7 +119,7 @@ func vorbisDecode(d *decode.D, in interface{}) interface{} {
// }
case packetTypeComment:
d.FieldFormat("comment", vorbisComment)
d.FieldFormat("comment", vorbisComment, nil)
// note this uses vorbis bitpacking convention, bits are added LSB first per byte
d.FieldValidateZeroPadding("padding0", 7)

View File

@ -196,11 +196,11 @@ func decodeChunks(d *decode.D, stringData bool) {
func wavDecode(d *decode.D, in interface{}) interface{} {
// there are wav files in the wild with id3v2 header id3v1 footer
_, _, _ = d.FieldTryFormat("header", headerFormat)
_, _, _ = d.FieldTryFormat("header", headerFormat, nil)
decodeChunk(d, "RIFF", false)
_, _, _ = d.FieldTryFormat("footer", footerFormat)
_, _, _ = d.FieldTryFormat("footer", footerFormat, nil)
return nil
}

View File

@ -57,7 +57,7 @@ func webpDecode(d *decode.D, in interface{}) interface{} {
case bytes.Equal(p, []byte("VP8 ")):
d.FieldStructFn("image", func(d *decode.D) {
decodeChunk(d, "VP8", func(d *decode.D) {
d.Format(vp8Frame)
d.Format(vp8Frame, nil)
})
})
case bytes.Equal(p, []byte("VP8L")):

View File

@ -112,47 +112,28 @@ type DecodeOptions struct {
func (DecodeOptions) decodeOptions() {}
type FormatOptions struct {
InArg interface{}
}
func (FormatOptions) decodeOptions() {}
// Decode try decode formats and return first success and all other decoder errors
func Decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts ...Options) (*Value, interface{}, error) {
opts = append(opts, DecodeOptions{IsRoot: true})
func Decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts DecodeOptions) (*Value, interface{}, error) {
opts.IsRoot = true
return decode(ctx, bb, formats, opts)
}
func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts []Options) (*Value, interface{}, error) {
func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts DecodeOptions) (*Value, interface{}, error) {
if formats == nil {
panic("formats is nil, failed to register format?")
}
var forceOne = len(formats) == 1
var decodeOpts DecodeOptions
var formatOpts FormatOptions
for _, opts := range opts {
switch opt := opts.(type) {
case DecodeOptions:
decodeOpts = opt
case FormatOptions:
formatOpts = opt
default:
panic(fmt.Sprintf("unknown decode option %#+v", opts))
}
}
decodeErr := DecodeFormatsError{}
for _, f := range formats {
d := NewDecoder(ctx, f, bb, decodeOpts)
d := NewDecoder(ctx, f, bb, opts)
var decodeV interface{}
r, rOk := recoverfn.Run(func() {
decodeV = f.DecodeFn(d, formatOpts.InArg)
decodeV = f.DecodeFn(d, opts.FormatInArg)
})
if ctx != nil && ctx.Err() != nil {
@ -187,16 +168,16 @@ func decode(ctx context.Context, bb *bitio.Buffer, formats []*Format, opts []Opt
}
maxRange = ranges.MinMax(maxRange, v.Range)
v.Range.Start += decodeOpts.StartOffset
v.Range.Start += opts.StartOffset
v.RootBitBuf = d.Value.RootBitBuf
return nil
}); err != nil {
return nil, nil, err
}
d.Value.Range = ranges.Range{Start: decodeOpts.StartOffset, Len: maxRange.Len}
d.Value.Range = ranges.Range{Start: opts.StartOffset, Len: maxRange.Len}
if decodeOpts.IsRoot {
if opts.IsRoot {
d.FillGaps("unknown")
// sort and set ranges for struct and arrays
@ -863,10 +844,14 @@ func (d *D) DecodeRangeFn(firstBit int64, nBits int64, fn func(d *D)) {
}
}
func (d *D) Format(formats []*Format, opts ...Options) interface{} {
func (d *D) Format(formats []*Format, inArg interface{}) interface{} {
bb := d.BitBufRange(d.Pos(), d.BitsLeft())
opts = append(opts, DecodeOptions{ReadBuf: d.readBuf, IsRoot: false, StartOffset: d.Pos()})
dv, v, err := decode(d.Ctx, bb, formats, opts)
dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{
ReadBuf: d.readBuf,
IsRoot: false,
StartOffset: d.Pos(),
FormatInArg: inArg,
})
if dv == nil || dv.Errors() != nil {
panic(err)
}
@ -891,10 +876,15 @@ func (d *D) Format(formats []*Format, opts ...Options) interface{} {
return v
}
func (d *D) FieldTryFormat(name string, formats []*Format, opts ...Options) (*Value, interface{}, error) {
func (d *D) FieldTryFormat(name string, formats []*Format, inArg interface{}) (*Value, interface{}, error) {
bb := d.BitBufRange(d.Pos(), d.BitsLeft())
opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: false, StartOffset: d.Pos()})
dv, v, err := decode(d.Ctx, bb, formats, opts)
dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{
Name: name,
ReadBuf: d.readBuf,
IsRoot: false,
StartOffset: d.Pos(),
FormatInArg: inArg,
})
if dv == nil || dv.Errors() != nil {
return nil, nil, err
}
@ -907,18 +897,23 @@ func (d *D) FieldTryFormat(name string, formats []*Format, opts ...Options) (*Va
return dv, v, err
}
func (d *D) FieldFormat(name string, formats []*Format, opts ...Options) (*Value, interface{}) {
dv, v, err := d.FieldTryFormat(name, formats, opts...)
func (d *D) FieldFormat(name string, formats []*Format, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormat(name, formats, inArg)
if dv == nil || dv.Errors() != nil {
panic(err)
}
return dv, v
}
func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}, error) {
func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}, error) {
bb := d.BitBufRange(d.Pos(), nBits)
opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: false, StartOffset: d.Pos()})
dv, v, err := decode(d.Ctx, bb, formats, opts)
dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{
Name: name,
ReadBuf: d.readBuf,
IsRoot: false,
StartOffset: d.Pos(),
FormatInArg: inArg,
})
if dv == nil || dv.Errors() != nil {
return nil, nil, err
}
@ -931,8 +926,8 @@ func (d *D) FieldTryFormatLen(name string, nBits int64, formats []*Format, opts
return dv, v, err
}
func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatLen(name, nBits, formats, opts...)
func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatLen(name, nBits, formats, inArg)
if dv == nil || dv.Errors() != nil {
panic(err)
}
@ -940,10 +935,15 @@ func (d *D) FieldFormatLen(name string, nBits int64, formats []*Format, opts ...
}
// TODO: return decooder?
func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}, error) {
func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}, error) {
bb := d.BitBufRange(firstBit, nBits)
opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: false, StartOffset: firstBit})
dv, v, err := decode(d.Ctx, bb, formats, opts)
dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{
Name: name,
ReadBuf: d.readBuf,
IsRoot: false,
StartOffset: firstBit,
FormatInArg: inArg,
})
if dv == nil || dv.Errors() != nil {
return nil, nil, err
}
@ -953,8 +953,8 @@ func (d *D) FieldTryFormatRange(name string, firstBit int64, nBits int64, format
return dv, v, err
}
func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats []*Format, opts ...Options) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatRange(name, firstBit, nBits, formats, opts...)
func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats []*Format, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatRange(name, firstBit, nBits, formats, inArg)
if dv == nil || dv.Errors() != nil {
panic(err)
}
@ -962,9 +962,13 @@ func (d *D) FieldFormatRange(name string, firstBit int64, nBits int64, formats [
return dv, v
}
func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, opts ...Options) (*Value, interface{}, error) {
opts = append(opts, DecodeOptions{Name: name, ReadBuf: d.readBuf, IsRoot: true})
dv, v, err := decode(d.Ctx, bb, formats, opts)
func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, inArg interface{}) (*Value, interface{}, error) {
dv, v, err := decode(d.Ctx, bb, formats, DecodeOptions{
Name: name,
ReadBuf: d.readBuf,
IsRoot: true,
FormatInArg: inArg,
})
if dv == nil || dv.Errors() != nil {
return nil, nil, err
}
@ -974,8 +978,8 @@ func (d *D) FieldTryFormatBitBuf(name string, bb *bitio.Buffer, formats []*Forma
return dv, v, err
}
func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, opts ...Options) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatBitBuf(name, bb, formats, opts...)
func (d *D) FieldFormatBitBuf(name string, bb *bitio.Buffer, formats []*Format, inArg interface{}) (*Value, interface{}) {
dv, v, err := d.FieldTryFormatBitBuf(name, bb, formats, inArg)
if dv == nil || dv.Errors() != nil {
panic(err)
}
@ -1036,7 +1040,7 @@ func (d *D) FieldFormatZlibLen(name string, nBits int64, formats []*Format) (*Va
}
zbb := bitio.NewBufferFromBytes(zd, -1)
return d.FieldFormatBitBuf(name, zbb, formats)
return d.FieldFormatBitBuf(name, zbb, formats, nil)
}
func (d *D) FieldStrNullTerminated(name string) string {