Mercurial > libavcodec.hg
comparison flacdec.c @ 9134:e82d5e006de5 libavcodec
flacdec: Split the metadata_parse() function into 2 separate functions,
parse_streaminfo() and get_metadata_size().
author | jbr |
---|---|
date | Thu, 05 Mar 2009 00:56:09 +0000 |
parents | c78af85f414d |
children | 05c6e8598143 |
comparison
equal
deleted
inserted
replaced
9133:c78af85f414d | 9134:e82d5e006de5 |
---|---|
37 | 37 |
38 #include "libavutil/crc.h" | 38 #include "libavutil/crc.h" |
39 #include "avcodec.h" | 39 #include "avcodec.h" |
40 #include "internal.h" | 40 #include "internal.h" |
41 #include "bitstream.h" | 41 #include "bitstream.h" |
42 #include "bytestream.h" | |
42 #include "golomb.h" | 43 #include "golomb.h" |
43 #include "flac.h" | 44 #include "flac.h" |
44 | 45 |
45 #undef NDEBUG | 46 #undef NDEBUG |
46 #include <assert.h> | 47 #include <assert.h> |
218 | 219 |
219 dump_headers(avctx, s); | 220 dump_headers(avctx, s); |
220 } | 221 } |
221 | 222 |
222 /** | 223 /** |
223 * Parse a list of metadata blocks. This list of blocks must begin with | 224 * Parse the STREAMINFO from an inline header. |
224 * the fLaC marker. | 225 * @param s the flac decoding context |
225 * @param s the flac decoding context containing the gb bit reader used to | 226 * @param buf input buffer, starting with the "fLaC" marker |
226 * parse metadata | 227 * @param buf_size buffer size |
227 * @return non-zero if metadata is invalid | 228 * @return non-zero if metadata is invalid |
228 */ | 229 */ |
229 static int metadata_parse(FLACContext *s) | 230 static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) |
230 { | 231 { |
231 int i, metadata_last, metadata_type, metadata_size; | 232 int metadata_type, metadata_size; |
232 | 233 |
233 skip_bits_long(&s->gb, 32); | 234 if (buf_size < FLAC_STREAMINFO_SIZE+8) { |
234 | 235 /* need more data */ |
236 return 0; | |
237 } | |
238 buf += 4; | |
239 metadata_type = bytestream_get_byte(&buf) & 0x7F; | |
240 metadata_size = bytestream_get_be24(&buf); | |
241 if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO || | |
242 metadata_size != FLAC_STREAMINFO_SIZE) { | |
243 return AVERROR_INVALIDDATA; | |
244 } | |
245 ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, buf); | |
246 allocate_buffers(s); | |
247 s->got_streaminfo = 1; | |
248 | |
249 return 0; | |
250 } | |
251 | |
252 /** | |
253 * Determine the size of an inline header. | |
254 * @param buf input buffer, starting with the "fLaC" marker | |
255 * @param buf_size buffer size | |
256 * @return number of bytes in the header, or 0 if more data is needed | |
257 */ | |
258 static int get_metadata_size(const uint8_t *buf, int buf_size) | |
259 { | |
260 int metadata_last, metadata_size; | |
261 const uint8_t *buf_end = buf + buf_size; | |
262 | |
263 buf += 4; | |
235 do { | 264 do { |
236 metadata_last = get_bits1(&s->gb); | 265 metadata_last = bytestream_get_byte(&buf) & 0x80; |
237 metadata_type = get_bits(&s->gb, 7); | 266 metadata_size = bytestream_get_be24(&buf); |
238 metadata_size = get_bits_long(&s->gb, 24); | 267 if (buf + metadata_size > buf_end) { |
239 | 268 /* need more data in order to read the complete header */ |
240 if (get_bits_count(&s->gb) + 8*metadata_size > s->gb.size_in_bits) { | 269 return 0; |
241 /* need more data. reset the bitstream reader and return. */ | 270 } |
242 init_get_bits(&s->gb, s->gb.buffer, s->gb.size_in_bits); | 271 buf += metadata_size; |
243 break; | |
244 } | |
245 | |
246 if (metadata_size) { | |
247 switch (metadata_type) { | |
248 case FLAC_METADATA_TYPE_STREAMINFO: | |
249 if (!s->got_streaminfo) { | |
250 ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, | |
251 s->gb.buffer+get_bits_count(&s->gb)/8); | |
252 allocate_buffers(s); | |
253 s->got_streaminfo = 1; | |
254 } | |
255 default: | |
256 for (i = 0; i < metadata_size; i++) | |
257 skip_bits(&s->gb, 8); | |
258 } | |
259 } | |
260 } while (!metadata_last); | 272 } while (!metadata_last); |
261 | 273 |
262 return 0; | 274 return buf_size - (buf_end - buf); |
263 } | 275 } |
264 | 276 |
265 static int decode_residuals(FLACContext *s, int channel, int pred_order) | 277 static int decode_residuals(FLACContext *s, int channel, int pred_order) |
266 { | 278 { |
267 int i, tmp, partition, method_type, rice_order; | 279 int i, tmp, partition, method_type, rice_order; |
635 if (buf_size < s->max_framesize && input_buf_size) { | 647 if (buf_size < s->max_framesize && input_buf_size) { |
636 return input_buf_size; | 648 return input_buf_size; |
637 } | 649 } |
638 } | 650 } |
639 | 651 |
640 init_get_bits(&s->gb, buf, buf_size*8); | |
641 | |
642 /* check that there is at least the smallest decodable amount of data. | 652 /* check that there is at least the smallest decodable amount of data. |
643 this amount corresponds to the smallest valid FLAC frame possible. */ | 653 this amount corresponds to the smallest valid FLAC frame possible. */ |
644 if (buf_size < 24) | 654 if (buf_size < 24) |
645 goto end; | 655 goto end; |
646 | 656 |
647 /* check for inline header */ | 657 /* check for inline header */ |
648 if (show_bits_long(&s->gb, 32) == MKBETAG('f','L','a','C')) { | 658 if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { |
649 if (metadata_parse(s)) { | 659 if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { |
650 av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); | 660 av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); |
651 return -1; | 661 return -1; |
652 } | 662 } |
663 bytes_read = get_metadata_size(buf, buf_size); | |
653 goto end; | 664 goto end; |
654 } | 665 } |
666 | |
667 init_get_bits(&s->gb, buf, buf_size*8); | |
655 | 668 |
656 tmp = show_bits(&s->gb, 16); | 669 tmp = show_bits(&s->gb, 16); |
657 if ((tmp & 0xFFFE) != 0xFFF8) { | 670 if ((tmp & 0xFFFE) != 0xFFF8) { |
658 av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); | 671 av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); |
659 while (get_bits_count(&s->gb)/8+2 < buf_size && (show_bits(&s->gb, 16) & 0xFFFE) != 0xFFF8) | 672 while (get_bits_count(&s->gb)/8+2 < buf_size && (show_bits(&s->gb, 16) & 0xFFFE) != 0xFFF8) |
660 skip_bits(&s->gb, 8); | 673 skip_bits(&s->gb, 8); |
661 goto end; // we may not have enough bits left to decode a frame, so try next time | 674 goto hdr_end; // we may not have enough bits left to decode a frame, so try next time |
662 } | 675 } |
663 skip_bits(&s->gb, 16); | 676 skip_bits(&s->gb, 16); |
664 if (decode_frame(s, alloc_data_size) < 0) { | 677 if (decode_frame(s, alloc_data_size) < 0) { |
665 av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); | 678 av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); |
666 s->bitstream_size=0; | 679 s->bitstream_size=0; |
702 DECORRELATE( (a-=b>>1) + b, a) | 715 DECORRELATE( (a-=b>>1) + b, a) |
703 } | 716 } |
704 | 717 |
705 *data_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); | 718 *data_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); |
706 | 719 |
720 hdr_end: | |
721 bytes_read = (get_bits_count(&s->gb)+7)/8; | |
707 end: | 722 end: |
708 bytes_read = (get_bits_count(&s->gb)+7)/8; | |
709 if (bytes_read > buf_size) { | 723 if (bytes_read > buf_size) { |
710 av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); | 724 av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); |
711 s->bitstream_size=0; | 725 s->bitstream_size=0; |
712 s->bitstream_index=0; | 726 s->bitstream_index=0; |
713 return -1; | 727 return -1; |