Mercurial > libavcodec.hg
annotate flacdec.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | 87b01c645235 |
children | 8a4984c5cacc |
rev | line source |
---|---|
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
1 /* |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
2 * FLAC (Free Lossless Audio Codec) decoder |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
3 * Copyright (c) 2003 Alex Beregszaszi |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3649
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3649
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3649
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3649
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3649
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
16 * |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3649
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
20 */ |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
21 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
22 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8712
diff
changeset
|
23 * @file libavcodec/flacdec.c |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
24 * FLAC (Free Lossless Audio Codec) decoder |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
25 * @author Alex Beregszaszi |
2071
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
26 * |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
27 * For more information on the FLAC format, visit: |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
28 * http://flac.sourceforge.net/ |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
29 * |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
30 * This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
31 * through, starting from the initial 'fLaC' signature; or by passing the |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
32 * 34-byte streaminfo structure through avctx->extradata[_size] followed |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
33 * by data starting with the 0xFFF8 marker. |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
34 */ |
2967 | 35 |
1812 | 36 #include <limits.h> |
2967 | 37 |
6763 | 38 #include "libavutil/crc.h" |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
39 #include "avcodec.h" |
9101
03a05f3afbae
flacdec: Avoid trying to read 33 bits. This occurs when the source
jbr
parents:
9100
diff
changeset
|
40 #include "internal.h" |
9428 | 41 #include "get_bits.h" |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
42 #include "bytestream.h" |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
43 #include "golomb.h" |
6728
56c5bbd0996f
split out some decoder context params to a shared macro
jbr
parents:
6727
diff
changeset
|
44 #include "flac.h" |
9213
782d31263979
share sample rate and blocksize tables between the FLAC encoder and FLAC
jbr
parents:
9211
diff
changeset
|
45 #include "flacdata.h" |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
46 |
1812 | 47 #undef NDEBUG |
48 #include <assert.h> | |
49 | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
50 typedef struct FLACContext { |
6728
56c5bbd0996f
split out some decoder context params to a shared macro
jbr
parents:
6727
diff
changeset
|
51 FLACSTREAMINFO |
56c5bbd0996f
split out some decoder context params to a shared macro
jbr
parents:
6727
diff
changeset
|
52 |
8711 | 53 AVCodecContext *avctx; ///< parent AVCodecContext |
54 GetBitContext gb; ///< GetBitContext initialized to start at the current frame | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
55 |
8711 | 56 int blocksize; ///< number of samples in the current frame |
57 int curr_bps; ///< bps for current subframe, adjusted for channel correlation and wasted bits | |
8712 | 58 int sample_shift; ///< shift required to make output samples 16-bit or 32-bit |
59 int is32; ///< flag to indicate if output should be 32-bit instead of 16-bit | |
9210
ca10c935dc56
flacdec: cosmetics: rename 'decorrelation' to 'ch_mode'
jbr
parents:
9208
diff
changeset
|
60 int ch_mode; ///< channel decorrelation type in the current frame |
9115 | 61 int got_streaminfo; ///< indicates if the STREAMINFO has been read |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
62 |
9188
f534d0cca450
share some constants between the FLAC encoder and FLAC decoder
jbr
parents:
9146
diff
changeset
|
63 int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples |
1812 | 64 uint8_t *bitstream; |
7303 | 65 unsigned int bitstream_size; |
66 unsigned int bitstream_index; | |
3066
04b924f8f5a5
warning fixes by Luca Abeni, lucabe72 ##@## email ##.## it
diego
parents:
3036
diff
changeset
|
67 unsigned int allocated_bitstream_size; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
68 } FLACContext; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
69 |
7129 | 70 static const int sample_size_table[] = |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
71 { 0, 8, 12, 0, 16, 20, 24, 0 }; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
72 |
8656 | 73 static int64_t get_utf8(GetBitContext *gb) |
74 { | |
3436 | 75 int64_t val; |
76 GET_UTF8(val, get_bits(gb, 8), return -1;) | |
1812 | 77 return val; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
78 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
79 |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
80 static void allocate_buffers(FLACContext *s); |
9054 | 81 |
82 int ff_flac_is_extradata_valid(AVCodecContext *avctx, | |
83 enum FLACExtradataFormat *format, | |
84 uint8_t **streaminfo_start) | |
85 { | |
86 if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) { | |
87 av_log(avctx, AV_LOG_ERROR, "extradata NULL or too small.\n"); | |
88 return 0; | |
89 } | |
90 if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) { | |
91 /* extradata contains STREAMINFO only */ | |
92 if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) { | |
93 av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n", | |
94 FLAC_STREAMINFO_SIZE-avctx->extradata_size); | |
95 } | |
96 *format = FLAC_EXTRADATA_FORMAT_STREAMINFO; | |
97 *streaminfo_start = avctx->extradata; | |
98 } else { | |
99 if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) { | |
100 av_log(avctx, AV_LOG_ERROR, "extradata too small.\n"); | |
101 return 0; | |
102 } | |
103 *format = FLAC_EXTRADATA_FORMAT_FULL_HEADER; | |
104 *streaminfo_start = &avctx->extradata[8]; | |
105 } | |
106 return 1; | |
107 } | |
2071
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
108 |
8656 | 109 static av_cold int flac_decode_init(AVCodecContext *avctx) |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
110 { |
9054 | 111 enum FLACExtradataFormat format; |
112 uint8_t *streaminfo; | |
2071
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
113 FLACContext *s = avctx->priv_data; |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
114 s->avctx = avctx; |
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
115 |
8728
329e332e829f
flacdec: set default sample_fmt before parsing extradata
jbr
parents:
8718
diff
changeset
|
116 avctx->sample_fmt = SAMPLE_FMT_S16; |
329e332e829f
flacdec: set default sample_fmt before parsing extradata
jbr
parents:
8718
diff
changeset
|
117 |
9054 | 118 /* for now, the raw FLAC header is allowed to be passed to the decoder as |
119 frame data instead of extradata. */ | |
120 if (!avctx->extradata) | |
121 return 0; | |
122 | |
123 if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo)) | |
124 return -1; | |
125 | |
9055
15515243f476
cosmetics: line wrap and indentation after last commit.
jbr
parents:
9054
diff
changeset
|
126 /* initialize based on the demuxer-supplied streamdata header */ |
15515243f476
cosmetics: line wrap and indentation after last commit.
jbr
parents:
9054
diff
changeset
|
127 ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); |
10485
87b01c645235
Set sample format in flac_decode_init() rather than in
jbr
parents:
10183
diff
changeset
|
128 if (s->bps > 16) |
87b01c645235
Set sample format in flac_decode_init() rather than in
jbr
parents:
10183
diff
changeset
|
129 avctx->sample_fmt = SAMPLE_FMT_S32; |
87b01c645235
Set sample format in flac_decode_init() rather than in
jbr
parents:
10183
diff
changeset
|
130 else |
87b01c645235
Set sample format in flac_decode_init() rather than in
jbr
parents:
10183
diff
changeset
|
131 avctx->sample_fmt = SAMPLE_FMT_S16; |
9055
15515243f476
cosmetics: line wrap and indentation after last commit.
jbr
parents:
9054
diff
changeset
|
132 allocate_buffers(s); |
9115 | 133 s->got_streaminfo = 1; |
2071
41d30bae5019
attempt to create some separation in the FLAC system with respect to
melanson
parents:
2028
diff
changeset
|
134 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
135 return 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
136 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
137 |
6729 | 138 static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s) |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
139 { |
9106 | 140 av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize); |
6727 | 141 av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize); |
142 av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate); | |
143 av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels); | |
144 av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps); | |
1812 | 145 } |
146 | |
8656 | 147 static void allocate_buffers(FLACContext *s) |
148 { | |
1812 | 149 int i; |
150 | |
151 assert(s->max_blocksize); | |
152 | |
8656 | 153 if (s->max_framesize == 0 && s->max_blocksize) { |
9216
64246d9e583a
add a function to calculate a more accurate estimate for maximum FLAC
jbr
parents:
9215
diff
changeset
|
154 s->max_framesize = ff_flac_get_max_frame_size(s->max_blocksize, |
64246d9e583a
add a function to calculate a more accurate estimate for maximum FLAC
jbr
parents:
9215
diff
changeset
|
155 s->channels, s->bps); |
1812 | 156 } |
157 | |
8656 | 158 for (i = 0; i < s->channels; i++) { |
8658 | 159 s->decoded[i] = av_realloc(s->decoded[i], |
160 sizeof(int32_t)*s->max_blocksize); | |
1812 | 161 } |
162 | |
8656 | 163 if (s->allocated_bitstream_size < s->max_framesize) |
8658 | 164 s->bitstream= av_fast_realloc(s->bitstream, |
165 &s->allocated_bitstream_size, | |
166 s->max_framesize); | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
167 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
168 |
6729 | 169 void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, |
170 const uint8_t *buffer) | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
171 { |
6726 | 172 GetBitContext gb; |
173 init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8); | |
174 | |
9106 | 175 skip_bits(&gb, 16); /* skip min blocksize */ |
6726 | 176 s->max_blocksize = get_bits(&gb, 16); |
9188
f534d0cca450
share some constants between the FLAC encoder and FLAC decoder
jbr
parents:
9146
diff
changeset
|
177 if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) { |
9109
8053722e1c7f
flacdec: Warn about invalid max blocksize and limit the minimum value.
jbr
parents:
9107
diff
changeset
|
178 av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n", |
8053722e1c7f
flacdec: Warn about invalid max blocksize and limit the minimum value.
jbr
parents:
9107
diff
changeset
|
179 s->max_blocksize); |
8053722e1c7f
flacdec: Warn about invalid max blocksize and limit the minimum value.
jbr
parents:
9107
diff
changeset
|
180 s->max_blocksize = 16; |
8053722e1c7f
flacdec: Warn about invalid max blocksize and limit the minimum value.
jbr
parents:
9107
diff
changeset
|
181 } |
2967 | 182 |
6726 | 183 skip_bits(&gb, 24); /* skip min frame size */ |
184 s->max_framesize = get_bits_long(&gb, 24); | |
185 | |
186 s->samplerate = get_bits_long(&gb, 20); | |
187 s->channels = get_bits(&gb, 3) + 1; | |
188 s->bps = get_bits(&gb, 5) + 1; | |
2967 | 189 |
6726 | 190 avctx->channels = s->channels; |
191 avctx->sample_rate = s->samplerate; | |
8701 | 192 avctx->bits_per_raw_sample = s->bps; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
193 |
8661 | 194 s->samples = get_bits_long(&gb, 32) << 4; |
9094
39425084bd5c
flacdec: Use get/skip_bits_long() for more than 17-bits and
jbr
parents:
9055
diff
changeset
|
195 s->samples |= get_bits(&gb, 4); |
2967 | 196 |
9094
39425084bd5c
flacdec: Use get/skip_bits_long() for more than 17-bits and
jbr
parents:
9055
diff
changeset
|
197 skip_bits_long(&gb, 64); /* md5 sum */ |
39425084bd5c
flacdec: Use get/skip_bits_long() for more than 17-bits and
jbr
parents:
9055
diff
changeset
|
198 skip_bits_long(&gb, 64); /* md5 sum */ |
2967 | 199 |
6727 | 200 dump_headers(avctx, s); |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
201 } |
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
202 |
9146
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
203 void ff_flac_parse_block_header(const uint8_t *block_header, |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
204 int *last, int *type, int *size) |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
205 { |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
206 int tmp = bytestream_get_byte(&block_header); |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
207 if (last) |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
208 *last = tmp & 0x80; |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
209 if (type) |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
210 *type = tmp & 0x7F; |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
211 if (size) |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
212 *size = bytestream_get_be24(&block_header); |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
213 } |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
214 |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
215 /** |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
216 * Parse the STREAMINFO from an inline header. |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
217 * @param s the flac decoding context |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
218 * @param buf input buffer, starting with the "fLaC" marker |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
219 * @param buf_size buffer size |
9119
f3d87e34599f
flacdec: Check for an inline header before calling metadata_parse().
jbr
parents:
9118
diff
changeset
|
220 * @return non-zero if metadata is invalid |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
221 */ |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
222 static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
223 { |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
224 int metadata_type, metadata_size; |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
225 |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
226 if (buf_size < FLAC_STREAMINFO_SIZE+8) { |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
227 /* need more data */ |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
228 return 0; |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
229 } |
9146
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
230 ff_flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size); |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
231 if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO || |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
232 metadata_size != FLAC_STREAMINFO_SIZE) { |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
233 return AVERROR_INVALIDDATA; |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
234 } |
9146
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
235 ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
236 allocate_buffers(s); |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
237 s->got_streaminfo = 1; |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
238 |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
239 return 0; |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
240 } |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
241 |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
242 /** |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
243 * Determine the size of an inline header. |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
244 * @param buf input buffer, starting with the "fLaC" marker |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
245 * @param buf_size buffer size |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
246 * @return number of bytes in the header, or 0 if more data is needed |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
247 */ |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
248 static int get_metadata_size(const uint8_t *buf, int buf_size) |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
249 { |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
250 int metadata_last, metadata_size; |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
251 const uint8_t *buf_end = buf + buf_size; |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
252 |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
253 buf += 4; |
9120 | 254 do { |
9146
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
255 ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size); |
b980183eb831
flacdec: Add a shared function for parsing a FLAC metadata block header.
jbr
parents:
9139
diff
changeset
|
256 buf += 4; |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
257 if (buf + metadata_size > buf_end) { |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
258 /* need more data in order to read the complete header */ |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
259 return 0; |
9120 | 260 } |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
261 buf += metadata_size; |
9120 | 262 } while (!metadata_last); |
4231
c769e4b0c75e
flac: allow reading of full metadata headers from extradata
aurel
parents:
3947
diff
changeset
|
263 |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
264 return buf_size - (buf_end - buf); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
265 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
266 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
267 static int decode_residuals(FLACContext *s, int channel, int pred_order) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
268 { |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
269 int i, tmp, partition, method_type, rice_order; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
270 int sample = 0, samples; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
271 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
272 method_type = get_bits(&s->gb, 2); |
8656 | 273 if (method_type > 1) { |
8658 | 274 av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n", |
275 method_type); | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
276 return -1; |
1812 | 277 } |
2967 | 278 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
279 rice_order = get_bits(&s->gb, 4); |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
280 |
1812 | 281 samples= s->blocksize >> rice_order; |
4366
f8753597422c
Fix crash when pred_order greater s->blocksize >> rice_order.
reimar
parents:
4351
diff
changeset
|
282 if (pred_order > samples) { |
8658 | 283 av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n", |
284 pred_order, samples); | |
4366
f8753597422c
Fix crash when pred_order greater s->blocksize >> rice_order.
reimar
parents:
4351
diff
changeset
|
285 return -1; |
f8753597422c
Fix crash when pred_order greater s->blocksize >> rice_order.
reimar
parents:
4351
diff
changeset
|
286 } |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
287 |
2967 | 288 sample= |
1812 | 289 i= pred_order; |
8656 | 290 for (partition = 0; partition < (1 << rice_order); partition++) { |
5871
83554c0e9ce6
Add support for FLAC's new RICE2 entropy coding method. Patch by Josh Coalson.
jbr
parents:
5741
diff
changeset
|
291 tmp = get_bits(&s->gb, method_type == 0 ? 4 : 5); |
8656 | 292 if (tmp == (method_type == 0 ? 15 : 31)) { |
1812 | 293 tmp = get_bits(&s->gb, 5); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
294 for (; i < samples; i++, sample++) |
9099 | 295 s->decoded[channel][sample] = get_sbits_long(&s->gb, tmp); |
8656 | 296 } else { |
297 for (; i < samples; i++, sample++) { | |
1813 | 298 s->decoded[channel][sample] = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); |
1812 | 299 } |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
300 } |
1812 | 301 i= 0; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
302 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
303 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
304 return 0; |
2967 | 305 } |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
306 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
307 static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
308 { |
5740 | 309 const int blocksize = s->blocksize; |
310 int32_t *decoded = s->decoded[channel]; | |
8952
49817775b44f
flacdec: Silence false positive warning about uninitialized variables in
jbr
parents:
8728
diff
changeset
|
311 int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; |
2967 | 312 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
313 /* warm up samples */ |
8656 | 314 for (i = 0; i < pred_order; i++) { |
9099 | 315 decoded[i] = get_sbits_long(&s->gb, s->curr_bps); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
316 } |
2967 | 317 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
318 if (decode_residuals(s, channel, pred_order) < 0) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
319 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
320 |
8656 | 321 if (pred_order > 0) |
6746 | 322 a = decoded[pred_order-1]; |
8656 | 323 if (pred_order > 1) |
6746 | 324 b = a - decoded[pred_order-2]; |
8656 | 325 if (pred_order > 2) |
6746 | 326 c = b - decoded[pred_order-2] + decoded[pred_order-3]; |
8656 | 327 if (pred_order > 3) |
6746 | 328 d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4]; |
5740 | 329 |
8656 | 330 switch (pred_order) { |
331 case 0: | |
332 break; | |
333 case 1: | |
334 for (i = pred_order; i < blocksize; i++) | |
335 decoded[i] = a += decoded[i]; | |
336 break; | |
337 case 2: | |
338 for (i = pred_order; i < blocksize; i++) | |
339 decoded[i] = a += b += decoded[i]; | |
340 break; | |
341 case 3: | |
342 for (i = pred_order; i < blocksize; i++) | |
343 decoded[i] = a += b += c += decoded[i]; | |
344 break; | |
345 case 4: | |
346 for (i = pred_order; i < blocksize; i++) | |
347 decoded[i] = a += b += c += d += decoded[i]; | |
348 break; | |
349 default: | |
350 av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); | |
351 return -1; | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
352 } |
1812 | 353 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
354 return 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
355 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
356 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
357 static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
358 { |
3351
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
359 int i, j; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
360 int coeff_prec, qlevel; |
10066 | 361 int coeffs[32]; |
5741 | 362 int32_t *decoded = s->decoded[channel]; |
2967 | 363 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
364 /* warm up samples */ |
8656 | 365 for (i = 0; i < pred_order; i++) { |
9099 | 366 decoded[i] = get_sbits_long(&s->gb, s->curr_bps); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
367 } |
2967 | 368 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
369 coeff_prec = get_bits(&s->gb, 4) + 1; |
8656 | 370 if (coeff_prec == 16) { |
8652 | 371 av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n"); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
372 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
373 } |
1812 | 374 qlevel = get_sbits(&s->gb, 5); |
8656 | 375 if (qlevel < 0) { |
8658 | 376 av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n", |
377 qlevel); | |
1814
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
378 return -1; |
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
379 } |
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
380 |
8656 | 381 for (i = 0; i < pred_order; i++) { |
1812 | 382 coeffs[i] = get_sbits(&s->gb, coeff_prec); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
383 } |
2967 | 384 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
385 if (decode_residuals(s, channel, pred_order) < 0) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
386 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
387 |
3351
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
388 if (s->bps > 16) { |
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
389 int64_t sum; |
8656 | 390 for (i = pred_order; i < s->blocksize; i++) { |
3351
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
391 sum = 0; |
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
392 for (j = 0; j < pred_order; j++) |
5741 | 393 sum += (int64_t)coeffs[j] * decoded[i-j-1]; |
394 decoded[i] += sum >> qlevel; | |
3351
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
395 } |
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
396 } else { |
8656 | 397 for (i = pred_order; i < s->blocksize-1; i += 2) { |
5741 | 398 int c; |
399 int d = decoded[i-pred_order]; | |
400 int s0 = 0, s1 = 0; | |
8656 | 401 for (j = pred_order-1; j > 0; j--) { |
5741 | 402 c = coeffs[j]; |
5721 | 403 s0 += c*d; |
5741 | 404 d = decoded[i-j]; |
405 s1 += c*d; | |
5721 | 406 } |
5741 | 407 c = coeffs[0]; |
408 s0 += c*d; | |
409 d = decoded[i] += s0 >> qlevel; | |
410 s1 += c*d; | |
411 decoded[i+1] += s1 >> qlevel; | |
5721 | 412 } |
8656 | 413 if (i < s->blocksize) { |
5721 | 414 int sum = 0; |
3351
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
415 for (j = 0; j < pred_order; j++) |
5741 | 416 sum += coeffs[j] * decoded[i-j-1]; |
417 decoded[i] += sum >> qlevel; | |
3351
42b85e03b408
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
lu_zero
parents:
3171
diff
changeset
|
418 } |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
419 } |
2967 | 420 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
421 return 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
422 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
423 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
424 static inline int decode_subframe(FLACContext *s, int channel) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
425 { |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
426 int type, wasted = 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
427 int i, tmp; |
2967 | 428 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
429 s->curr_bps = s->bps; |
8656 | 430 if (channel == 0) { |
9210
ca10c935dc56
flacdec: cosmetics: rename 'decorrelation' to 'ch_mode'
jbr
parents:
9208
diff
changeset
|
431 if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) |
1812 | 432 s->curr_bps++; |
8656 | 433 } else { |
9210
ca10c935dc56
flacdec: cosmetics: rename 'decorrelation' to 'ch_mode'
jbr
parents:
9208
diff
changeset
|
434 if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE) |
1812 | 435 s->curr_bps++; |
436 } | |
437 | |
8656 | 438 if (get_bits1(&s->gb)) { |
2859 | 439 av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
440 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
441 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
442 type = get_bits(&s->gb, 6); |
2967 | 443 |
8656 | 444 if (get_bits1(&s->gb)) { |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
445 wasted = 1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
446 while (!get_bits1(&s->gb)) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
447 wasted++; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
448 s->curr_bps -= wasted; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
449 } |
9130
721e21aca252
flacdec: Check curr_bps after wasted bits are subtracted.
jbr
parents:
9121
diff
changeset
|
450 if (s->curr_bps > 32) { |
9891
7ad7d4094d1f
Rename ff_log_missing_feature() to av_log_missing_feature().
rbultje
parents:
9428
diff
changeset
|
451 av_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0); |
9130
721e21aca252
flacdec: Check curr_bps after wasted bits are subtracted.
jbr
parents:
9121
diff
changeset
|
452 return -1; |
721e21aca252
flacdec: Check curr_bps after wasted bits are subtracted.
jbr
parents:
9121
diff
changeset
|
453 } |
8649 | 454 |
1812 | 455 //FIXME use av_log2 for types |
8656 | 456 if (type == 0) { |
9099 | 457 tmp = get_sbits_long(&s->gb, s->curr_bps); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
458 for (i = 0; i < s->blocksize; i++) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
459 s->decoded[channel][i] = tmp; |
8656 | 460 } else if (type == 1) { |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
461 for (i = 0; i < s->blocksize; i++) |
9099 | 462 s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps); |
8656 | 463 } else if ((type >= 8) && (type <= 12)) { |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
464 if (decode_subframe_fixed(s, channel, type & ~0x8) < 0) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
465 return -1; |
8656 | 466 } else if (type >= 32) { |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
467 if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
468 return -1; |
8656 | 469 } else { |
2859 | 470 av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
471 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
472 } |
2967 | 473 |
8656 | 474 if (wasted) { |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
475 int i; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
476 for (i = 0; i < s->blocksize; i++) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
477 s->decoded[channel][i] <<= wasted; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
478 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
479 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
480 return 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
481 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
482 |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
483 /** |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
484 * Validate and decode a frame header. |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
485 * @param avctx AVCodecContext to use as av_log() context |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
486 * @param gb GetBitContext from which to read frame header |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
487 * @param[out] fi frame information |
9256
eb5f74d90304
cosmetics: add an @return to documentation for decode_frame_header()
jbr
parents:
9254
diff
changeset
|
488 * @return non-zero on error, 0 if ok |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
489 */ |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
490 static int decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
491 FLACFrameInfo *fi) |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
492 { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
493 int bs_code, sr_code, bps_code; |
2967 | 494 |
9232 | 495 /* frame sync code */ |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
496 skip_bits(gb, 16); |
9232 | 497 |
498 /* block size and sample rate codes */ | |
9229 | 499 bs_code = get_bits(gb, 4); |
500 sr_code = get_bits(gb, 4); | |
2967 | 501 |
9232 | 502 /* channels and decorrelation */ |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
503 fi->ch_mode = get_bits(gb, 4); |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
504 if (fi->ch_mode < FLAC_MAX_CHANNELS) { |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
505 fi->channels = fi->ch_mode + 1; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
506 fi->ch_mode = FLAC_CHMODE_INDEPENDENT; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
507 } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) { |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
508 fi->channels = 2; |
9235
df759d70d6f9
flacdec: give a more accurate error message when validating channel
jbr
parents:
9233
diff
changeset
|
509 } else { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
510 av_log(avctx, AV_LOG_ERROR, "invalid channel mode: %d\n", fi->ch_mode); |
9235
df759d70d6f9
flacdec: give a more accurate error message when validating channel
jbr
parents:
9233
diff
changeset
|
511 return -1; |
df759d70d6f9
flacdec: give a more accurate error message when validating channel
jbr
parents:
9233
diff
changeset
|
512 } |
2967 | 513 |
9232 | 514 /* bits per sample */ |
9229 | 515 bps_code = get_bits(gb, 3); |
9239
af76987c8d53
flacdec: change frame bps validation to return an error value if bps
jbr
parents:
9238
diff
changeset
|
516 if (bps_code == 3 || bps_code == 7) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
517 av_log(avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n", |
9229 | 518 bps_code); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
519 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
520 } |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
521 fi->bps = sample_size_table[bps_code]; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
522 |
9232 | 523 /* reserved bit */ |
9228
2b7bc08cf831
flacdec: use a local variable for GetBitContext in decode_frame()
jbr
parents:
9216
diff
changeset
|
524 if (get_bits1(gb)) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
525 av_log(avctx, AV_LOG_ERROR, "broken stream, invalid padding\n"); |
1816 | 526 return -1; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
527 } |
2967 | 528 |
9232 | 529 /* sample or frame count */ |
9228
2b7bc08cf831
flacdec: use a local variable for GetBitContext in decode_frame()
jbr
parents:
9216
diff
changeset
|
530 if (get_utf8(gb) < 0) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
531 av_log(avctx, AV_LOG_ERROR, "utf8 fscked\n"); |
1816 | 532 return -1; |
533 } | |
2967 | 534 |
9232 | 535 /* blocksize */ |
9229 | 536 if (bs_code == 0) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
537 av_log(avctx, AV_LOG_ERROR, "reserved blocksize code: 0\n"); |
9105
9ae9d486669a
flacdec: Return error when blocksize code of 0 is found. It is a
jbr
parents:
9101
diff
changeset
|
538 return -1; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
539 } else if (bs_code == 6) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
540 fi->blocksize = get_bits(gb, 8) + 1; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
541 } else if (bs_code == 7) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
542 fi->blocksize = get_bits(gb, 16) + 1; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
543 } else { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
544 fi->blocksize = ff_flac_blocksize_table[bs_code]; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
545 } |
1812 | 546 |
9232 | 547 /* sample rate */ |
9244
cbf65173eed3
flacdec: allow sample rate to change mid-stream, but log a warning
jbr
parents:
9241
diff
changeset
|
548 if (sr_code < 12) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
549 fi->samplerate = ff_flac_sample_rate_table[sr_code]; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
550 } else if (sr_code == 12) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
551 fi->samplerate = get_bits(gb, 8) * 1000; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
552 } else if (sr_code == 13) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
553 fi->samplerate = get_bits(gb, 16); |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
554 } else if (sr_code == 14) { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
555 fi->samplerate = get_bits(gb, 16) * 10; |
9238
11a79ab2279d
flacdec: cosmetics: add some braces to if/else statements
jbr
parents:
9237
diff
changeset
|
556 } else { |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
557 av_log(avctx, AV_LOG_ERROR, "illegal sample rate code %d\n", |
9229 | 558 sr_code); |
1812 | 559 return -1; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
560 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
561 |
9232 | 562 /* header CRC-8 check */ |
9228
2b7bc08cf831
flacdec: use a local variable for GetBitContext in decode_frame()
jbr
parents:
9216
diff
changeset
|
563 skip_bits(gb, 8); |
9230 | 564 if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer, |
565 get_bits_count(gb)/8)) { | |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
566 av_log(avctx, AV_LOG_ERROR, "header crc mismatch\n"); |
1814
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
567 return -1; |
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
568 } |
2967 | 569 |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
570 return 0; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
571 } |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
572 |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
573 static int decode_frame(FLACContext *s) |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
574 { |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
575 int i; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
576 GetBitContext *gb = &s->gb; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
577 FLACFrameInfo fi; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
578 |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
579 if (decode_frame_header(s->avctx, gb, &fi)) { |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
580 av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n"); |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
581 return -1; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
582 } |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
583 |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
584 if (fi.channels != s->channels) { |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
585 av_log(s->avctx, AV_LOG_ERROR, "switching channel layout mid-stream " |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
586 "is not supported\n"); |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
587 return -1; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
588 } |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
589 s->ch_mode = fi.ch_mode; |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
590 |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
591 if (fi.bps && fi.bps != s->bps) { |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
592 av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not " |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
593 "supported\n"); |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
594 return -1; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
595 } |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
596 if (s->bps > 16) { |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
597 s->avctx->sample_fmt = SAMPLE_FMT_S32; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
598 s->sample_shift = 32 - s->bps; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
599 s->is32 = 1; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
600 } else { |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
601 s->avctx->sample_fmt = SAMPLE_FMT_S16; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
602 s->sample_shift = 16 - s->bps; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
603 s->is32 = 0; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
604 } |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
605 |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
606 if (fi.blocksize > s->max_blocksize) { |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
607 av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize, |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
608 s->max_blocksize); |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
609 return -1; |
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
610 } |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
611 s->blocksize = fi.blocksize; |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
612 |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
613 if (fi.samplerate == 0) { |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
614 fi.samplerate = s->samplerate; |
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
615 } else if (fi.samplerate != s->samplerate) { |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
616 av_log(s->avctx, AV_LOG_WARNING, "sample rate changed from %d to %d\n", |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
617 s->samplerate, fi.samplerate); |
9248
f8973e93809a
flacdec: cosmetics: separate the pure frame header parsing code from
jbr
parents:
9244
diff
changeset
|
618 } |
9254
8d570fb097f8
flacdec: split frame header decoding and validation into a separate
jbr
parents:
9249
diff
changeset
|
619 s->samplerate = s->avctx->sample_rate = fi.samplerate; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
620 |
6729 | 621 // dump_headers(s->avctx, (FLACStreaminfo *)s); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
622 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
623 /* subframes */ |
8656 | 624 for (i = 0; i < s->channels; i++) { |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
625 if (decode_subframe(s, i) < 0) |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
626 return -1; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
627 } |
2967 | 628 |
9228
2b7bc08cf831
flacdec: use a local variable for GetBitContext in decode_frame()
jbr
parents:
9216
diff
changeset
|
629 align_get_bits(gb); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
630 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
631 /* frame footer */ |
9228
2b7bc08cf831
flacdec: use a local variable for GetBitContext in decode_frame()
jbr
parents:
9216
diff
changeset
|
632 skip_bits(gb, 16); /* data crc */ |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
633 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
634 return 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
635 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
636 |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
637 static int flac_decode_frame(AVCodecContext *avctx, |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
638 void *data, int *data_size, |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9256
diff
changeset
|
639 AVPacket *avpkt) |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
640 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9256
diff
changeset
|
641 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9256
diff
changeset
|
642 int buf_size = avpkt->size; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
643 FLACContext *s = avctx->priv_data; |
9135
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
644 int i, j = 0, input_buf_size = 0, bytes_read = 0; |
8701 | 645 int16_t *samples_16 = data; |
646 int32_t *samples_32 = data; | |
4351 | 647 int alloc_data_size= *data_size; |
9233 | 648 int output_size; |
4351 | 649 |
650 *data_size=0; | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
651 |
8656 | 652 if (s->max_framesize == 0) { |
7785
a969253a82ff
fix issue 616 on roundup : decoding of short flac files
jai_menon
parents:
7451
diff
changeset
|
653 s->max_framesize= FFMAX(4, buf_size); // should hopefully be enough for the first header |
1812 | 654 s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); |
655 } | |
656 | |
8656 | 657 if (1 && s->max_framesize) { //FIXME truncated |
8657 | 658 if (s->bitstream_size < 4 || AV_RL32(s->bitstream) != MKTAG('f','L','a','C')) |
659 buf_size= FFMIN(buf_size, s->max_framesize - FFMIN(s->bitstream_size, s->max_framesize)); | |
660 input_buf_size= buf_size; | |
1812 | 661 |
8657 | 662 if (s->bitstream_size + buf_size < buf_size || s->bitstream_index + s->bitstream_size + buf_size < s->bitstream_index) |
663 return -1; | |
7304 | 664 |
8657 | 665 if (s->allocated_bitstream_size < s->bitstream_size + buf_size) |
666 s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->bitstream_size + buf_size); | |
7304 | 667 |
8657 | 668 if (s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size) { |
8658 | 669 memmove(s->bitstream, &s->bitstream[s->bitstream_index], |
670 s->bitstream_size); | |
8657 | 671 s->bitstream_index=0; |
672 } | |
8658 | 673 memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], |
674 buf, buf_size); | |
8657 | 675 buf= &s->bitstream[s->bitstream_index]; |
676 buf_size += s->bitstream_size; | |
677 s->bitstream_size= buf_size; | |
2967 | 678 |
8657 | 679 if (buf_size < s->max_framesize && input_buf_size) { |
680 return input_buf_size; | |
681 } | |
1812 | 682 } |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
683 |
9133
c78af85f414d
flacdec: Add a check for small buffer size. This ensures reading as
jbr
parents:
9132
diff
changeset
|
684 /* check that there is at least the smallest decodable amount of data. |
9139
4564ec1f21b0
flacdec: cosmetics: Add a comment with the data of the smallest FLAC
jbr
parents:
9138
diff
changeset
|
685 this amount corresponds to the smallest valid FLAC frame possible. |
4564ec1f21b0
flacdec: cosmetics: Add a comment with the data of the smallest FLAC
jbr
parents:
9138
diff
changeset
|
686 FF F8 69 02 00 00 9A 00 00 34 46 */ |
9138
063854fdfe73
flacdec: There is an even smaller FLAC frame size possibility.
jbr
parents:
9137
diff
changeset
|
687 if (buf_size < 11) |
9133
c78af85f414d
flacdec: Add a check for small buffer size. This ensures reading as
jbr
parents:
9132
diff
changeset
|
688 goto end; |
c78af85f414d
flacdec: Add a check for small buffer size. This ensures reading as
jbr
parents:
9132
diff
changeset
|
689 |
9119
f3d87e34599f
flacdec: Check for an inline header before calling metadata_parse().
jbr
parents:
9118
diff
changeset
|
690 /* check for inline header */ |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
691 if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { |
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
692 if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { |
9119
f3d87e34599f
flacdec: Check for an inline header before calling metadata_parse().
jbr
parents:
9118
diff
changeset
|
693 av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); |
f3d87e34599f
flacdec: Check for an inline header before calling metadata_parse().
jbr
parents:
9118
diff
changeset
|
694 return -1; |
f3d87e34599f
flacdec: Check for an inline header before calling metadata_parse().
jbr
parents:
9118
diff
changeset
|
695 } |
9134
e82d5e006de5
flacdec: Split the metadata_parse() function into 2 separate functions,
jbr
parents:
9133
diff
changeset
|
696 bytes_read = get_metadata_size(buf, buf_size); |
7301
aab7f1fb59ea
If metadata has been parsed goto end instead of trying to
michael
parents:
7273
diff
changeset
|
697 goto end; |
9119
f3d87e34599f
flacdec: Check for an inline header before calling metadata_parse().
jbr
parents:
9118
diff
changeset
|
698 } |
7301
aab7f1fb59ea
If metadata has been parsed goto end instead of trying to
michael
parents:
7273
diff
changeset
|
699 |
9135
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
700 /* check for frame sync code and resync stream if necessary */ |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
701 if ((AV_RB16(buf) & 0xFFFE) != 0xFFF8) { |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
702 const uint8_t *buf_end = buf + buf_size; |
8653 | 703 av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); |
9135
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
704 while (buf+2 < buf_end && (AV_RB16(buf) & 0xFFFE) != 0xFFF8) |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
705 buf++; |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
706 bytes_read = buf_size - (buf_end - buf); |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
707 goto end; // we may not have enough bits left to decode a frame, so try next time |
8653 | 708 } |
9135
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
709 |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
710 /* decode frame */ |
05c6e8598143
flacdec: Simplify frame sync by not using the bitstream reader.
jbr
parents:
9134
diff
changeset
|
711 init_get_bits(&s->gb, buf, buf_size*8); |
9233 | 712 if (decode_frame(s) < 0) { |
8653 | 713 av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); |
714 s->bitstream_size=0; | |
715 s->bitstream_index=0; | |
716 return -1; | |
717 } | |
9136
ebad2cb9e015
flacdec: cosmetics: move 2 statements to immediately after frame
jbr
parents:
9135
diff
changeset
|
718 bytes_read = (get_bits_count(&s->gb)+7)/8; |
1812 | 719 |
9233 | 720 /* check if allocated data size is large enough for output */ |
721 output_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); | |
722 if (output_size > alloc_data_size) { | |
723 av_log(s->avctx, AV_LOG_ERROR, "output data size is larger than " | |
724 "allocated data size\n"); | |
9237
69779b592b9d
flacdec: skip frame when allocated data size is too small
jbr
parents:
9236
diff
changeset
|
725 goto end; |
9233 | 726 } |
727 *data_size = output_size; | |
728 | |
3434 | 729 #define DECORRELATE(left, right)\ |
730 assert(s->channels == 2);\ | |
8656 | 731 for (i = 0; i < s->blocksize; i++) {\ |
3434 | 732 int a= s->decoded[0][i];\ |
733 int b= s->decoded[1][i];\ | |
8701 | 734 if (s->is32) {\ |
735 *samples_32++ = (left) << s->sample_shift;\ | |
736 *samples_32++ = (right) << s->sample_shift;\ | |
737 } else {\ | |
738 *samples_16++ = (left) << s->sample_shift;\ | |
739 *samples_16++ = (right) << s->sample_shift;\ | |
740 }\ | |
3434 | 741 }\ |
742 break; | |
743 | |
9210
ca10c935dc56
flacdec: cosmetics: rename 'decorrelation' to 'ch_mode'
jbr
parents:
9208
diff
changeset
|
744 switch (s->ch_mode) { |
9208
443f056ba7e7
share channel mode constants between the FLAC decoder and FLAC encoder
jbr
parents:
9188
diff
changeset
|
745 case FLAC_CHMODE_INDEPENDENT: |
8656 | 746 for (j = 0; j < s->blocksize; j++) { |
8701 | 747 for (i = 0; i < s->channels; i++) { |
748 if (s->is32) | |
749 *samples_32++ = s->decoded[i][j] << s->sample_shift; | |
750 else | |
751 *samples_16++ = s->decoded[i][j] << s->sample_shift; | |
752 } | |
8656 | 753 } |
754 break; | |
9208
443f056ba7e7
share channel mode constants between the FLAC decoder and FLAC encoder
jbr
parents:
9188
diff
changeset
|
755 case FLAC_CHMODE_LEFT_SIDE: |
8656 | 756 DECORRELATE(a,a-b) |
9208
443f056ba7e7
share channel mode constants between the FLAC decoder and FLAC encoder
jbr
parents:
9188
diff
changeset
|
757 case FLAC_CHMODE_RIGHT_SIDE: |
8656 | 758 DECORRELATE(a+b,b) |
9208
443f056ba7e7
share channel mode constants between the FLAC decoder and FLAC encoder
jbr
parents:
9188
diff
changeset
|
759 case FLAC_CHMODE_MID_SIDE: |
8656 | 760 DECORRELATE( (a-=b>>1) + b, a) |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
761 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
762 |
1812 | 763 end: |
9132
37bb2785a35b
flacdec: cosmetics: Use a more descriptive variable name for the number
jbr
parents:
9131
diff
changeset
|
764 if (bytes_read > buf_size) { |
37bb2785a35b
flacdec: cosmetics: Use a more descriptive variable name for the number
jbr
parents:
9131
diff
changeset
|
765 av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); |
1814
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
766 s->bitstream_size=0; |
4804dddf2d0e
crc8 checking, based upon a patch by (Miroslav Lichvar <lichvarm at phoenix dot inf dot upol dot cz>)
michael
parents:
1813
diff
changeset
|
767 s->bitstream_index=0; |
1812 | 768 return -1; |
769 } | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
770 |
8656 | 771 if (s->bitstream_size) { |
9132
37bb2785a35b
flacdec: cosmetics: Use a more descriptive variable name for the number
jbr
parents:
9131
diff
changeset
|
772 s->bitstream_index += bytes_read; |
37bb2785a35b
flacdec: cosmetics: Use a more descriptive variable name for the number
jbr
parents:
9131
diff
changeset
|
773 s->bitstream_size -= bytes_read; |
1812 | 774 return input_buf_size; |
8656 | 775 } else |
9132
37bb2785a35b
flacdec: cosmetics: Use a more descriptive variable name for the number
jbr
parents:
9131
diff
changeset
|
776 return bytes_read; |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
777 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
778 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6377
diff
changeset
|
779 static av_cold int flac_decode_close(AVCodecContext *avctx) |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
780 { |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
781 FLACContext *s = avctx->priv_data; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
782 int i; |
2967 | 783 |
8656 | 784 for (i = 0; i < s->channels; i++) { |
1812 | 785 av_freep(&s->decoded[i]); |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
786 } |
1812 | 787 av_freep(&s->bitstream); |
2967 | 788 |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
789 return 0; |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
790 } |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
791 |
8656 | 792 static void flac_flush(AVCodecContext *avctx) |
793 { | |
1817 | 794 FLACContext *s = avctx->priv_data; |
795 | |
796 s->bitstream_size= | |
797 s->bitstream_index= 0; | |
798 } | |
799 | |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
800 AVCodec flac_decoder = { |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
801 "flac", |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
802 CODEC_TYPE_AUDIO, |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
803 CODEC_ID_FLAC, |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
804 sizeof(FLACContext), |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
805 flac_decode_init, |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
806 NULL, |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
807 flac_decode_close, |
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
808 flac_decode_frame, |
10183
f2d62b685d49
add CODEC_CAP_SUBFRAMES to the FLAC decoder capabilities. also add a FIXME
jbr
parents:
10066
diff
changeset
|
809 CODEC_CAP_DELAY | CODEC_CAP_SUBFRAMES, /* FIXME: add a FLAC parser so that |
f2d62b685d49
add CODEC_CAP_SUBFRAMES to the FLAC decoder capabilities. also add a FIXME
jbr
parents:
10066
diff
changeset
|
810 we will not need to use either |
f2d62b685d49
add CODEC_CAP_SUBFRAMES to the FLAC decoder capabilities. also add a FIXME
jbr
parents:
10066
diff
changeset
|
811 of these capabilities */ |
2967 | 812 .flush= flac_flush, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6763
diff
changeset
|
813 .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), |
1811
98d4d32b90e8
flac decoder by (Alex Beregszaszi <alex at fsn dot hu>)
michael
parents:
diff
changeset
|
814 }; |