mirror of
https://github.com/wader/fq.git
synced 2024-12-23 21:31:33 +03:00
flac_frame: Properly decode zero escape sample size
This commit is contained in:
parent
d5b15d2853
commit
7859be1e5d
@ -455,12 +455,19 @@ func frameDecode(d *decode.D, in any) any {
|
||||
|
||||
if riceParameter == riceEscape {
|
||||
escapeSampleSize := int(d.FieldU5("escape_sample_size"))
|
||||
d.RangeFn(d.Pos(), int64(count*escapeSampleSize), func(d *decode.D) {
|
||||
d.FieldRawLen("samples", int64(count*escapeSampleSize))
|
||||
})
|
||||
for j := 0; j < count; j++ {
|
||||
samples[n] = d.S(escapeSampleSize)
|
||||
n++
|
||||
if escapeSampleSize == 0 {
|
||||
// Zero sample size, we can just skip ahead count samples as they are already zero. From spec:
|
||||
// Note that it is possible that the number of bits is 0, which means all residual samples in that partition have
|
||||
// a value of 0, and no bits code for the partition itself.
|
||||
n += count
|
||||
} else {
|
||||
d.RangeFn(d.Pos(), int64(count*escapeSampleSize), func(d *decode.D) {
|
||||
d.FieldRawLen("samples", int64(count*escapeSampleSize))
|
||||
})
|
||||
for j := 0; j < count; j++ {
|
||||
samples[n] = d.S(escapeSampleSize)
|
||||
n++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
samplesStart := d.Pos()
|
||||
@ -493,17 +500,15 @@ func frameDecode(d *decode.D, in any) any {
|
||||
}
|
||||
}
|
||||
|
||||
var samples []int64
|
||||
samples := make([]int64, blockSize)
|
||||
switch subframeTypeS.SymStr() {
|
||||
case SubframeConstant:
|
||||
samples = make([]int64, blockSize)
|
||||
// <n> Unencoded constant value of the subblock, n = frame's bits-per-sample.
|
||||
v := d.FieldS("value", subframeSampleSize)
|
||||
for i := 0; i < blockSize; i++ {
|
||||
samples[i] = v
|
||||
}
|
||||
case SubframeVerbatim:
|
||||
samples = make([]int64, blockSize)
|
||||
// <n*i> Unencoded subblock; n = frame's bits-per-sample, i = frame's blocksize.
|
||||
// TODO: refactor into some kind of FieldBitBufLenFn?
|
||||
d.RangeFn(d.Pos(), int64(blockSize*subframeSampleSize), func(d *decode.D) {
|
||||
@ -514,8 +519,6 @@ func frameDecode(d *decode.D, in any) any {
|
||||
samples[i] = d.S(subframeSampleSize)
|
||||
}
|
||||
case SubframeFixed:
|
||||
samples = make([]int64, blockSize)
|
||||
|
||||
// <n> Unencoded warm-up samples (n = frame's bits-per-sample * predictor order).
|
||||
decodeWarmupSamples(samples, lpcOrder, subframeSampleSize)
|
||||
// Encoded residual
|
||||
@ -531,8 +534,6 @@ func frameDecode(d *decode.D, in any) any {
|
||||
coeffs := fixedCoeffs[lpcOrder]
|
||||
decodeLPC(lpcOrder, samples, coeffs, 0)
|
||||
case SubframeLPC:
|
||||
samples = make([]int64, blockSize)
|
||||
|
||||
// <n> Unencoded warm-up samples (n = frame's bits-per-sample * lpc order).
|
||||
decodeWarmupSamples(samples, lpcOrder, subframeSampleSize)
|
||||
// <4> (Quantized linear predictor coefficients' precision in bits)-1 (1111 = invalid).
|
||||
|
1
format/flac/testdata/README.md
vendored
Normal file
1
format/flac/testdata/README.md
vendored
Normal file
@ -0,0 +1 @@
|
||||
More test files can by found at https://github.com/ietf-wg-cellar/flac-test-files/ at the time of writing the decoder passes tests 01-64.
|
BIN
format/flac/testdata/frame
vendored
BIN
format/flac/testdata/frame
vendored
Binary file not shown.
98
format/flac/testdata/frame.fqtest
vendored
98
format/flac/testdata/frame.fqtest
vendored
@ -1,58 +1,42 @@
|
||||
# test decode separate frame
|
||||
# ffmpeg -f lavfi -i sine -t 0.01s -f flac pipe:1 | fq - '.frames[0]._bytes' > frame
|
||||
$ fq -d flac_frame dv frame
|
||||
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: frame (flac_frame) 0x0-0x1ff.7 (512)
|
||||
| | | header{}: 0x0-0x7.7 (8)
|
||||
0x000|ff f8 |.. | sync: 0b11111111111110 (valid) 0x0-0x1.5 (1.6)
|
||||
0x000| f8 | . | reserved0: 0 (valid) 0x1.6-0x1.6 (0.1)
|
||||
0x000| f8 | . | blocking_strategy: "fixed" (0) 0x1.7-0x1.7 (0.1)
|
||||
0x000| 79 | y | block_size: 0b111 (end of header (16 bit)) 0x2-0x2.3 (0.4)
|
||||
0x000| 79 | y | sample_rate: 44100 (0b1001) 0x2.4-0x2.7 (0.4)
|
||||
0x000| 08 | . | channel_assignment: 1 (0) (mono) 0x3-0x3.3 (0.4)
|
||||
0x000| 08 | . | sample_size: 16 (0b100) 0x3.4-0x3.6 (0.3)
|
||||
0x000| 08 | . | reserved1: 0 (valid) 0x3.7-0x3.7 (0.1)
|
||||
| | | end_of_header{}: 0x4-0x6.7 (3)
|
||||
0x000| 00 | . | frame_number: 0 0x4-0x4.7 (1)
|
||||
0x000| 01 b8 | .. | block_size: 441 0x5-0x6.7 (2)
|
||||
0x000| 55 | U | crc: 0x55 (valid) 0x7-0x7.7 (1)
|
||||
| | | subframes[0:1]: 0x8-0x1fd.2 (501.3)
|
||||
| | | [0]{}: subframe 0x8-0x1fd.2 (501.3)
|
||||
0x000| 4e | N | zero_bit: 0 (valid) 0x8-0x8 (0.1)
|
||||
0x000| 4e | N | subframe_type: "lpc" (0b100111) 0x8.1-0x8.6 (0.6)
|
||||
| | | lpc_order: 8 0x8.7-NA (0)
|
||||
0x000| 4e | N | wasted_bits_flag: 0 0x8.7-0x8.7 (0.1)
|
||||
| | | subframe_sample_size: 16 0x9-NA (0)
|
||||
| | | warmup_samples[0:8]: 0x9-0x18.7 (16)
|
||||
0x000| 00 00 | .. | [0]: 0 value 0x9-0xa.7 (2)
|
||||
0x000| 01 00 | .. | [1]: 256 value 0xb-0xc.7 (2)
|
||||
0x000| 01 ff | .. | [2]: 511 value 0xd-0xe.7 (2)
|
||||
0x000| 02| .| [3]: 765 value 0xf-0x10.7 (2)
|
||||
0x010|fd |. |
|
||||
0x010| 03 f8 | .. | [4]: 1016 value 0x11-0x12.7 (2)
|
||||
0x010| 04 ee | .. | [5]: 1262 value 0x13-0x14.7 (2)
|
||||
0x010| 05 e0 | .. | [6]: 1504 value 0x15-0x16.7 (2)
|
||||
0x010| 06 cc | .. | [7]: 1740 value 0x17-0x18.7 (2)
|
||||
0x010| e7 | . | precision: 15 0x19-0x19.3 (0.4)
|
||||
0x010| e7 b7 | .. | shift: 15 0x19.4-0x1a (0.5)
|
||||
| | | coefficients[0:8]: 0x1a.1-0x29 (15)
|
||||
0x010| b7 52 | .R | [0]: 14162 value 0x1a.1-0x1b.7 (1.7)
|
||||
0x010| 5c 9c | \. | [1]: 11854 value 0x1c-0x1d.6 (1.7)
|
||||
0x010| 9c 8d e8| ...| [2]: 9082 value 0x1d.7-0x1f.5 (1.7)
|
||||
0x010| e8| .| [3]: 5975 value 0x1f.6-0x21.4 (1.7)
|
||||
0x020|ba b8 |.. |
|
||||
0x020| b8 a5 df | ... | [4]: 2653 value 0x21.5-0x23.3 (1.7)
|
||||
0x020| df a3 fc | ... | [5]: -737 value 0x23.4-0x25.2 (1.7)
|
||||
0x020| fc 03 71 | ..q | [6]: -4083 value 0x25.3-0x27.1 (1.7)
|
||||
0x020| 71 e5 80 | q.. | [7]: -7221 value 0x27.2-0x29 (1.7)
|
||||
0x020| 80 | . | residual_coding_method: 4 (0) (rice) 0x29.1-0x29.2 (0.2)
|
||||
0x020| 80 | . | partition_order: 0 0x29.3-0x29.6 (0.4)
|
||||
| | | rice_partitions: 1 0x29.7-NA (0)
|
||||
| | | partitions[0:1]: 0x29.7-0x1fd.2 (467.4)
|
||||
| | | [0]{}: partition 0x29.7-0x1fd.2 (467.4)
|
||||
| | | count: 433 0x29.7-NA (0)
|
||||
0x020| 80 ee | .. | rice_parameter: 7 0x29.7-0x2a.2 (0.4)
|
||||
0x020| ee e7 63 a9 cc e0| ..c...| samples: raw bits 0x2a.3-0x1fd.2 (467)
|
||||
0x030|6d 35 19 8c 25 c2 c9 4c 9a 47 20 bd ba 36 b3 2f|m5..%..L.G ..6./|
|
||||
* |until 0x1fd.2 (467) | |
|
||||
0x1f0| 20 | | byte_align: 0 (valid) 0x1fd.3-0x1fd.7 (0.5)
|
||||
0x1f0| 7f ab| ..| footer_crc: "7fab" (raw bits) (valid) 0x1fe-0x1ff.7 (2)
|
||||
$ fq '.frames[1] | tobytes | flac_frame | d' mono8.flac
|
||||
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: (flac_frame)
|
||||
| | | header{}:
|
||||
0x000|ff f8 |.. | sync: 0b11111111111110 (valid)
|
||||
0x000| f8 | . | reserved0: 0 (valid)
|
||||
0x000| f8 | . | blocking_strategy: "fixed" (0)
|
||||
0x000| c9 | . | block_size: 4096 (0b1100)
|
||||
0x000| c9 | . | sample_rate: 44100 (0b1001)
|
||||
0x000| 02 | . | channel_assignment: 1 (0) (mono)
|
||||
0x000| 02 | . | sample_size: 8 (0b1)
|
||||
0x000| 02 | . | reserved1: 0 (valid)
|
||||
| | | end_of_header{}:
|
||||
0x000| 01 | . | frame_number: 1
|
||||
0x000| 10 | . | crc: 0x10 (valid)
|
||||
| | | subframes[0:1]:
|
||||
| | | [0]{}: subframe
|
||||
0x000| 12 | . | zero_bit: 0 (valid)
|
||||
0x000| 12 | . | subframe_type: "fixed" (0b1001)
|
||||
| | | lpc_order: 1
|
||||
0x000| 12 | . | wasted_bits_flag: 0
|
||||
| | | subframe_sample_size: 8
|
||||
| | | warmup_samples[0:1]:
|
||||
0x000| 00 | . | [0]: 0
|
||||
0x000| 04 | . | residual_coding_method: 4 (0) (rice)
|
||||
0x000| 04 | . | partition_order: 1
|
||||
| | | rice_partitions: 2
|
||||
| | | partitions[0:2]:
|
||||
| | | [0]{}: partition
|
||||
| | | count: 2047
|
||||
0x000| 04 3f | .? | rice_parameter: 0
|
||||
0x000| 3f ff ff ff ff ff ff| ?......| samples: raw bits
|
||||
0x010|ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff|................|
|
||||
* |until 0x196.1 (397) | |
|
||||
| | | [1]{}: partition
|
||||
| | | count: 2048
|
||||
0x190| c1 | . | rice_parameter: 0
|
||||
0x190| c1 bb ff 39 99 32 4c 92 64 99| ...9.2L.d.| samples: raw bits
|
||||
0x1a0|33 39 ff bb 6d 6d b6 df fe 66 66 4c 93 26 4c 99|39..mm...ffL.&L.|
|
||||
* |until 0x33d.7 (424) | |
|
||||
| | | byte_align: 0 (valid)
|
||||
0x330| 5c 65| \e| footer_crc: "5c65" (raw bits) (valid)
|
||||
|
BIN
format/flac/testdata/zero_esc_size.flac
vendored
BIN
format/flac/testdata/zero_esc_size.flac
vendored
Binary file not shown.
3
format/flac/testdata/zero_esc_size.fqtest
vendored
3
format/flac/testdata/zero_esc_size.fqtest
vendored
@ -1,3 +0,0 @@
|
||||
# TODO: figure out a nicer way to test errors
|
||||
$ fq -d flac '._error.error' zero_esc_size.flac
|
||||
"FieldFormat: TryFieldFormat: failed at position 9755 (read size 0 seek pos 0): S: failed at position 4831.5 (read size 0 seek pos 0): trySEndian nBits must be >= 1 (0)"
|
Loading…
Reference in New Issue
Block a user