Skip to content

Commit

Permalink
Merge pull request #775 from wader/avi-stream-type-handler
Browse files Browse the repository at this point in the history
avi: Add type, handler, format_tag and compreession per stream
  • Loading branch information
wader authored Oct 7, 2023
2 parents 4fbeacd + 5196554 commit 3549e5e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 45 deletions.
81 changes: 44 additions & 37 deletions format/riff/avi.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,6 @@ var aviStreamChunkTypeDescriptions = scalar.StrMapDescription{

const aviRiffType = "AVI "

type aviStrl struct {
typ string
handler string
stream *aviStream
}

type idx1Sample struct {
offset int64
size int64
Expand All @@ -119,6 +113,10 @@ type idx1Sample struct {
}

type aviStream struct {
typ string
handler string
formatTag uint64
compression string
hasFormat bool
format *decode.Group
formatInArg any
Expand Down Expand Up @@ -244,7 +242,7 @@ func aviDecode(d *decode.D) any {
typ := d.FieldUTF8("type", 4, aviListTypeDescriptions)
switch typ {
case "strl":
return true, &aviStrl{}
return true, &aviStream{}
case "movi":
moviListPos = d.Pos()
}
Expand Down Expand Up @@ -337,21 +335,19 @@ func aviDecode(d *decode.D) any {
d.FieldU16("bottom")
})

if aviStrl, aviStrlOk := path.topData().(*aviStrl); aviStrlOk {
aviStrl.typ = typ
aviStrl.handler = handler
if stream, ok := path.topData().(*aviStream); ok {
stream.typ = typ
stream.handler = handler
}

return false, nil

case "strf":
s := &aviStream{}

typ := ""
if aviStrl, aviStrlOk := path.topData().(*aviStrl); aviStrlOk {
typ = aviStrl.typ
aviStrl.stream = s
stream, streamOk := path.topData().(*aviStream)
if !streamOk {
stream = &aviStream{}
}
typ := stream.typ

switch typ {
case "vids":
Expand All @@ -372,6 +368,8 @@ func aviDecode(d *decode.D) any {
d.FieldRawLen("extra", d.BitsLeft())
}

stream.compression = compression

// TODO: if dvsd handler and extraSize >= 32 then DVINFO?

switch compression {
Expand All @@ -389,12 +387,12 @@ func aviDecode(d *decode.D) any {
format.BMPTagH264_UMSV,
format.BMPTagH264_tshd,
format.BMPTagH264_INMC:
s.format = &aviMpegAVCAUGroup
s.hasFormat = true
stream.format = &aviMpegAVCAUGroup
stream.hasFormat = true
case format.BMPTagHEVC,
format.BMPTagHEVC_H265:
s.format = &aviMpegHEVCAUGroup
s.hasFormat = true
stream.format = &aviMpegHEVCAUGroup
stream.hasFormat = true
}

case "auds":
Expand All @@ -411,14 +409,16 @@ func aviDecode(d *decode.D) any {
d.FieldRawLen("extra", int64(cbSize)*8)
}

stream.formatTag = formatTag

switch formatTag {
case format.WAVTagMP3:
s.format = &aviMp3FrameGroup
s.hasFormat = true
stream.format = &aviMp3FrameGroup
stream.hasFormat = true
case format.WAVTagFLAC:
// TODO: can flac in avi have streaminfo somehow?
s.format = &aviFLACFrameGroup
s.hasFormat = true
stream.format = &aviFLACFrameGroup
stream.hasFormat = true
}
case "iavs":
// DVINFO
Expand All @@ -431,15 +431,12 @@ func aviDecode(d *decode.D) any {
d.FieldRawLen("dvv_reserved", 32*2)
}

streams = append(streams, s)
streams = append(streams, stream)

return false, nil

case "indx":
var stream *aviStream
if aviStrl, aviStrlOk := path.topData().(*aviStrl); aviStrlOk {
stream = aviStrl.stream
}
stream, _ := path.topData().(*aviStream)

d.FieldU16("longs_per_entry") // TODO: use?
d.FieldU8("index_subtype")
Expand Down Expand Up @@ -532,12 +529,22 @@ func aviDecode(d *decode.D) any {
}

d.FieldArray("streams", func(d *decode.D) {
for si, s := range streams {
for streamIndex, stream := range streams {

d.FieldStruct("stream", func(d *decode.D) {
d.FieldValueStr("type", stream.typ)
d.FieldValueStr("handler", stream.handler)
switch stream.typ {
case "auds":
d.FieldValueUint("format_tag", stream.formatTag, format.WAVTagNames)
case "vids":
d.FieldValueStr("compression", stream.compression)
}

var streamIndexSampleRanges []ranges.Range
if len(s.indexes) > 0 {
if len(stream.indexes) > 0 {
d.FieldArray("indexes", func(d *decode.D) {
for _, i := range s.indexes {
for _, i := range stream.indexes {
d.FieldStruct("index", func(d *decode.D) {
d.RangeFn(i.Start, i.Len, func(d *decode.D) {
d.FieldUTF8("type", 4)
Expand All @@ -554,8 +561,8 @@ func aviDecode(d *decode.D) any {
// TODO: palette change
decodeSample := func(d *decode.D, sr ranges.Range) {
d.RangeFn(sr.Start, sr.Len, func(d *decode.D) {
if sr.Len > 0 && ai.DecodeSamples && s.hasFormat {
d.FieldFormat("sample", s.format, s.formatInArg)
if sr.Len > 0 && ai.DecodeSamples && stream.hasFormat {
d.FieldFormat("sample", stream.format, stream.formatInArg)
} else {
d.FieldRawLen("sample", d.BitsLeft())
}
Expand All @@ -572,16 +579,16 @@ func aviDecode(d *decode.D) any {
decodeSample(d, sr)
}
})
} else if len(s.ixSamples) > 0 {
} else if len(stream.ixSamples) > 0 {
d.FieldArray("samples", func(d *decode.D) {
for _, sr := range s.ixSamples {
for _, sr := range stream.ixSamples {
decodeSample(d, sr)
}
})
} else if len(idx1Samples) > 0 {
d.FieldArray("samples", func(d *decode.D) {
for _, is := range idx1Samples {
if is.streamNr != si {
if is.streamNr != streamIndex {
continue
}
decodeSample(d, ranges.Range{
Expand Down
7 changes: 5 additions & 2 deletions format/riff/testdata/avc.avi.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ $ fq dv avc.avi
0x02430| 54 0d 00 00 | T... | offset: 3412 0x243a-0x243d.7 (4)
0x02430| 38 00| 8.| length: 56 0x243e-0x2441.7 (4)
0x02440|00 00| |..| |
| | | streams[0:1]: 0x1682-0x2409.7 (3464)
| | | [0]{}: stream 0x1682-0x2409.7 (3464)
| | | streams[0:1]: 0x1682-0x2441.7 (3520)
| | | [0]{}: stream 0x1682-0x2441.7 (3520)
| | | samples[0:3]: 0x1682-0x2409.7 (3464)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0][0:8]: sample (avc_au) 0x1682-0x2272.7 (3057)
0x01680| 00 00 00 01 | .... | [0]: raw bits start_code 0x1682-0x1685.7 (4)
Expand Down Expand Up @@ -487,3 +487,6 @@ $ fq dv avc.avi
0x023d0| 9e 41 79 0a ff 01 f9 2d 04| .Ay....-.| data: raw bits 0x23d7.7-0x2409.7 (50.1)
0x023e0|d3 29 fe 4d 76 42 26 f6 cd 13 9c 32 05 69 f5 56|.).MvB&....2.i.V|
* |until 0x2409.7 (51) | |
| | | type: "vids" 0x2442-NA (0)
| | | handler: "H264" 0x2442-NA (0)
| | | compression: "H264" 0x2442-NA (0)
7 changes: 5 additions & 2 deletions format/riff/testdata/flac.avi.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ $ fq dv flac.avi
0x18c0| 00 00 00 | ... | unused2: raw bits 0x18c1-0x18c3.7 (3)
0x18c0| 66 02 00 00 | f... | offset: 614 0x18c4-0x18c7.7 (4)
0x18c0| 00 00 00 00| | ....| | length: 0 0x18c8-0x18cb.7 (4)
| | | streams[0:1]: 0x1642-0x18a3.7 (610)
| | | [0]{}: stream 0x1642-0x18a3.7 (610)
| | | streams[0:1]: 0x1642-0x18cb.7 (650)
| | | [0]{}: stream 0x1642-0x18cb.7 (650)
| | | samples[0:2]: 0x1642-0x18a3.7 (610)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0]{}: sample (flac_frame) 0x1642-0x189b.7 (602)
| | | header{}: 0x1642-0x1649.7 (8)
Expand Down Expand Up @@ -260,3 +260,6 @@ $ fq dv flac.avi
0x1890| c0 | . | byte_align: 0 (valid) 0x1899.2-0x1899.7 (0.6)
0x1890| 7b 66 | {f | footer_crc: "7b66" (raw bits) (valid) 0x189a-0x189b.7 (2)
| | | [1]: raw bits sample 0x18a4-NA (0)
| | | type: "auds" 0x18cc-NA (0)
| | | handler: "\x01\x00\x00\x00" 0x18cc-NA (0)
| | | format_tag: "flac" (61868) 0x18cc-NA (0)
7 changes: 5 additions & 2 deletions format/riff/testdata/mp3.avi.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ $ fq dv mp3.avi
0x18d0| 00 00 00| ...| unused2: raw bits 0x18dd-0x18df.7 (3)
0x18e0|b6 01 00 00 |.... | offset: 438 0x18e0-0x18e3.7 (4)
0x18e0| d1 00 00 00| | ....| | length: 209 0x18e4-0x18e7.7 (4)
| | | streams[0:1]: 0x162c-0x18ae.7 (643)
| | | [0]{}: stream 0x162c-0x18ae.7 (643)
| | | streams[0:1]: 0x162c-0x18e7.7 (700)
| | | [0]{}: stream 0x162c-0x18e7.7 (700)
| | | samples[0:3]: 0x162c-0x18ae.7 (643)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0]{}: sample (mp3_frame) 0x162c-0x16fb.7 (208)
| | | header{}: 0x162c-0x162f.7 (4)
Expand Down Expand Up @@ -534,3 +534,6 @@ $ fq dv mp3.avi
0x1800|cb a0 77 10 07 47 8b 8c 7b 2e 82 33 01 c4 c0 04|..w..G..{..3....|
* |until 0x18ae.7 (188) | |
| | | crc_calculated: "c36b" (raw bits) 0x18af-NA (0)
| | | type: "auds" 0x18e8-NA (0)
| | | handler: "\x01\x00\x00\x00" 0x18e8-NA (0)
| | | format_tag: "mp3" (85) 0x18e8-NA (0)
7 changes: 5 additions & 2 deletions format/riff/testdata/pcm.avi.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ $ fq dv pcm.avi
0x3900|00 00 |.. |
0x3900| 24 20 00 00 | $ .. | offset: 8228 0x3902-0x3905.7 (4)
0x3900| 74 02 00 00| | t...| | length: 628 0x3906-0x3909.7 (4)
| | | streams[0:1]: 0x161e-0x38b1.7 (8852)
| | | [0]{}: stream 0x161e-0x38b1.7 (8852)
| | | streams[0:1]: 0x161e-0x3909.7 (8940)
| | | [0]{}: stream 0x161e-0x3909.7 (8940)
| | | samples[0:5]: 0x161e-0x38b1.7 (8852)
0x1610| 00 00| ..| [0]: raw bits sample 0x161e-0x1e1d.7 (2048)
0x1620|00 01 ff 01 fd 02 f8 03 ee 04 e0 05 cc 06 b0 07|................|
Expand All @@ -240,3 +240,6 @@ $ fq dv pcm.avi
0x3630| 24 f4| $.| [4]: raw bits sample 0x363e-0x38b1.7 (628)
0x3640|d6 f4 94 f5 5c f6 2d f7 08 f8 ea f8 d4 f9 c4 fa|....\.-.........|
* |until 0x38b1.7 (628) | |
| | | type: "auds" 0x390a-NA (0)
| | | handler: "\x01\x00\x00\x00" 0x390a-NA (0)
| | | format_tag: "pcm_s16le" (1) 0x390a-NA (0)

0 comments on commit 3549e5e

Please sign in to comment.