Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avi: Add type, handler, format_tag and compreession per stream #775

Merged
merged 1 commit into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)