[FFmpeg-devel] [PATCH] FLAC parser
Benoit Fouet
benoit.fouet
Fri Mar 27 09:32:00 CET 2009
Hi,
(my 2 cents review follows)
On 03/27/2009 06:05 AM, Justin Ruggles wrote:
> Hi,
>
> I finally got a working FLAC parser without resorting to buffering
> max_frame_size bytes like the FLAC decoder does. It requires a slight
> change to ff_combine_frame() since the header can be up to 16 bytes long
> and ff_combine_frame() currently only supports up to 8 bytes of overread
> data (FF_INPUT_BUFFER_PADDING_SIZE).
>
> This works with all samples I've tested, but it would be great to have
> more tested as well. There are quite a few corner cases, and while I've
> tried to think of everything I can, I might have missed something.
>
>
> diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
> new file mode 100644
> index 0000000..fb33680
> --- /dev/null
> +++ b/libavcodec/flac_parser.c
> @@ -0,0 +1,226 @@
>
> [...]
>
> +static int frame_header_is_valid(const uint8_t *buf)
> +{
> + GetBitContext gb;
> + FLACFrameInfo fi;
> +
> + init_get_bits(&gb, buf, MAX_FRAME_HEADER_SIZE*8);
> + if (ff_flac_decode_frame_header(NULL, &gb, &fi))
> + return 0;
> +
> + return 1;
> +}
>
maybe a return !ff_flac_decode_frame_header(NULL, &gb, &fi); could do
> +static int find_next_header(FLACParseContext *fpc, const uint8_t *buf,
> + int buf_size, int start, int save_state)
> +{
> + int i;
> + for (i = start; i <= buf_size-16; i++) {
> + if (frame_header_is_valid(buf+i))
> + return i;
> + }
> + if (save_state) {
> + for (; i < buf_size-1; i++) {
> + if ((AV_RB16(buf+i) & 0xFFFE) == 0xFFF8) {
> + fpc->state_size = buf_size - i;
> + memcpy(fpc->state, &buf[i], fpc->state_size);
> + return END_NOT_FOUND;
> + }
> + }
> + for (; i < buf_size; i++) {
> + if (buf[i] == 0xFF) {
> + fpc->state[0] = 0xFF;
> + fpc->state_size = 1;
> + }
> + }
>
the last 'for' loop is unneeded
> diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
> index 04e81c6..9efa42b 100644
> --- a/libavcodec/flacdec.c
> +++ b/libavcodec/flacdec.c
>
> [...]
>
> @@ -480,20 +466,17 @@ static inline int decode_subframe(FLACContext
*s, int channel)
> return 0;
> }
>
> -/**
> - * Validate and decode a frame header.
> - * @param avctx AVCodecContext to use as av_log() context
> - * @param gb GetBitContext from which to read frame header
> - * @param[out] fi frame information
> - * @return non-zero on error, 0 if ok
> - */
> -static int decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
> +int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
> FLACFrameInfo *fi)
> {
> int bs_code, sr_code, bps_code;
>
> /* frame sync code */
> - skip_bits(gb, 16);
> + if ((get_bits(gb, 16) & 0xFFFE) != 0xFFF8) {
> + if (avctx)
> + av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
> + return -1;
> + }
>
indentation (copy paste I guess ;)
> @@ -563,7 +552,8 @@ static int decode_frame_header(AVCodecContext
*avctx, GetBitContext *gb,
> skip_bits(gb, 8);
> if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,
> get_bits_count(gb)/8)) {
> - av_log(avctx, AV_LOG_ERROR, "header crc mismatch\n");
> + if (avctx)
> + av_log(avctx, AV_LOG_ERROR, "header crc mismatch\n");
> return -1;
>
the other way round
Ben
More information about the ffmpeg-devel
mailing list