|
|
@ -39,6 +39,7 @@ |
|
|
|
#include "avcodec.h" |
|
|
|
#include "avcodec.h" |
|
|
|
#include "internal.h" |
|
|
|
#include "internal.h" |
|
|
|
#include "bitstream.h" |
|
|
|
#include "bitstream.h" |
|
|
|
|
|
|
|
#include "bytestream.h" |
|
|
|
#include "golomb.h" |
|
|
|
#include "golomb.h" |
|
|
|
#include "flac.h" |
|
|
|
#include "flac.h" |
|
|
|
|
|
|
|
|
|
|
@ -220,46 +221,57 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Parse a list of metadata blocks. This list of blocks must begin with |
|
|
|
* Parse the STREAMINFO from an inline header. |
|
|
|
* the fLaC marker. |
|
|
|
* @param s the flac decoding context |
|
|
|
* @param s the flac decoding context containing the gb bit reader used to |
|
|
|
* @param buf input buffer, starting with the "fLaC" marker |
|
|
|
* parse metadata |
|
|
|
* @param buf_size buffer size |
|
|
|
* @return non-zero if metadata is invalid |
|
|
|
* @return non-zero if metadata is invalid |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static int metadata_parse(FLACContext *s) |
|
|
|
static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i, metadata_last, metadata_type, metadata_size; |
|
|
|
int metadata_type, metadata_size; |
|
|
|
|
|
|
|
|
|
|
|
skip_bits_long(&s->gb, 32); |
|
|
|
if (buf_size < FLAC_STREAMINFO_SIZE+8) { |
|
|
|
|
|
|
|
/* need more data */ |
|
|
|
do { |
|
|
|
return 0; |
|
|
|
metadata_last = get_bits1(&s->gb); |
|
|
|
|
|
|
|
metadata_type = get_bits(&s->gb, 7); |
|
|
|
|
|
|
|
metadata_size = get_bits_long(&s->gb, 24); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (get_bits_count(&s->gb) + 8*metadata_size > s->gb.size_in_bits) { |
|
|
|
|
|
|
|
/* need more data. reset the bitstream reader and return. */ |
|
|
|
|
|
|
|
init_get_bits(&s->gb, s->gb.buffer, s->gb.size_in_bits); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
buf += 4; |
|
|
|
if (metadata_size) { |
|
|
|
metadata_type = bytestream_get_byte(&buf) & 0x7F; |
|
|
|
switch (metadata_type) { |
|
|
|
metadata_size = bytestream_get_be24(&buf); |
|
|
|
case FLAC_METADATA_TYPE_STREAMINFO: |
|
|
|
if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO || |
|
|
|
if (!s->got_streaminfo) { |
|
|
|
metadata_size != FLAC_STREAMINFO_SIZE) { |
|
|
|
ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
s->gb.buffer+get_bits_count(&s->gb)/8); |
|
|
|
} |
|
|
|
|
|
|
|
ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, buf); |
|
|
|
allocate_buffers(s); |
|
|
|
allocate_buffers(s); |
|
|
|
s->got_streaminfo = 1; |
|
|
|
s->got_streaminfo = 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Determine the size of an inline header. |
|
|
|
|
|
|
|
* @param buf input buffer, starting with the "fLaC" marker |
|
|
|
|
|
|
|
* @param buf_size buffer size |
|
|
|
|
|
|
|
* @return number of bytes in the header, or 0 if more data is needed |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
static int get_metadata_size(const uint8_t *buf, int buf_size) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int metadata_last, metadata_size; |
|
|
|
|
|
|
|
const uint8_t *buf_end = buf + buf_size; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf += 4; |
|
|
|
|
|
|
|
do { |
|
|
|
|
|
|
|
metadata_last = bytestream_get_byte(&buf) & 0x80; |
|
|
|
|
|
|
|
metadata_size = bytestream_get_be24(&buf); |
|
|
|
|
|
|
|
if (buf + metadata_size > buf_end) { |
|
|
|
|
|
|
|
/* need more data in order to read the complete header */ |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
default: |
|
|
|
buf += metadata_size; |
|
|
|
for (i = 0; i < metadata_size; i++) |
|
|
|
|
|
|
|
skip_bits(&s->gb, 8); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} while (!metadata_last); |
|
|
|
} while (!metadata_last); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return buf_size - (buf_end - buf); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int decode_residuals(FLACContext *s, int channel, int pred_order) |
|
|
|
static int decode_residuals(FLACContext *s, int channel, int pred_order) |
|
|
@ -637,28 +649,29 @@ static int flac_decode_frame(AVCodecContext *avctx, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
init_get_bits(&s->gb, buf, buf_size*8); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* check that there is at least the smallest decodable amount of data.
|
|
|
|
/* check that there is at least the smallest decodable amount of data.
|
|
|
|
this amount corresponds to the smallest valid FLAC frame possible. */ |
|
|
|
this amount corresponds to the smallest valid FLAC frame possible. */ |
|
|
|
if (buf_size < 24) |
|
|
|
if (buf_size < 24) |
|
|
|
goto end; |
|
|
|
goto end; |
|
|
|
|
|
|
|
|
|
|
|
/* check for inline header */ |
|
|
|
/* check for inline header */ |
|
|
|
if (show_bits_long(&s->gb, 32) == MKBETAG('f','L','a','C')) { |
|
|
|
if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { |
|
|
|
if (metadata_parse(s)) { |
|
|
|
if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bytes_read = get_metadata_size(buf, buf_size); |
|
|
|
goto end; |
|
|
|
goto end; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init_get_bits(&s->gb, buf, buf_size*8); |
|
|
|
|
|
|
|
|
|
|
|
tmp = show_bits(&s->gb, 16); |
|
|
|
tmp = show_bits(&s->gb, 16); |
|
|
|
if ((tmp & 0xFFFE) != 0xFFF8) { |
|
|
|
if ((tmp & 0xFFFE) != 0xFFF8) { |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); |
|
|
|
while (get_bits_count(&s->gb)/8+2 < buf_size && (show_bits(&s->gb, 16) & 0xFFFE) != 0xFFF8) |
|
|
|
while (get_bits_count(&s->gb)/8+2 < buf_size && (show_bits(&s->gb, 16) & 0xFFFE) != 0xFFF8) |
|
|
|
skip_bits(&s->gb, 8); |
|
|
|
skip_bits(&s->gb, 8); |
|
|
|
goto end; // we may not have enough bits left to decode a frame, so try next time
|
|
|
|
goto hdr_end; // we may not have enough bits left to decode a frame, so try next time
|
|
|
|
} |
|
|
|
} |
|
|
|
skip_bits(&s->gb, 16); |
|
|
|
skip_bits(&s->gb, 16); |
|
|
|
if (decode_frame(s, alloc_data_size) < 0) { |
|
|
|
if (decode_frame(s, alloc_data_size) < 0) { |
|
|
@ -704,8 +717,9 @@ static int flac_decode_frame(AVCodecContext *avctx, |
|
|
|
|
|
|
|
|
|
|
|
*data_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); |
|
|
|
*data_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); |
|
|
|
|
|
|
|
|
|
|
|
end: |
|
|
|
hdr_end: |
|
|
|
bytes_read = (get_bits_count(&s->gb)+7)/8; |
|
|
|
bytes_read = (get_bits_count(&s->gb)+7)/8; |
|
|
|
|
|
|
|
end: |
|
|
|
if (bytes_read > buf_size) { |
|
|
|
if (bytes_read > buf_size) { |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); |
|
|
|
s->bitstream_size=0; |
|
|
|
s->bitstream_size=0; |
|
|
|