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;