From b0e9edc44f1722787adacbff9aa60343206a58c0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 10 Apr 2012 16:33:45 -0400 Subject: [PATCH] avcodec: add a cook parser to get subpacket duration Fixes jittery video playback of rm files with cook audio. --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/cook_parser.c | 59 ++++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 4 +-- libavformat/rmdec.c | 1 + 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 libavcodec/cook_parser.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 4dc218aa47..b3309e57cb 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -620,6 +620,7 @@ OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \ aac_ac3_parser.o OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o +OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 60b3e08d17..0b519bbf82 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -400,6 +400,7 @@ void avcodec_register_all(void) REGISTER_PARSER (AC3, ac3); REGISTER_PARSER (ADX, adx); REGISTER_PARSER (CAVSVIDEO, cavsvideo); + REGISTER_PARSER (COOK, cook); REGISTER_PARSER (DCA, dca); REGISTER_PARSER (DIRAC, dirac); REGISTER_PARSER (DNXHD, dnxhd); diff --git a/libavcodec/cook_parser.c b/libavcodec/cook_parser.c new file mode 100644 index 0000000000..c16f7c8a5f --- /dev/null +++ b/libavcodec/cook_parser.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Cook audio parser + * + * Determines subpacket duration from extradata. + */ + +#include + +#include "libavutil/intreadwrite.h" +#include "parser.h" + +typedef struct CookParseContext { + int duration; +} CookParseContext; + +static int cook_parse(AVCodecParserContext *s1, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + CookParseContext *s = s1->priv_data; + + if (s->duration) + s1->duration = s->duration; + else if (avctx->extradata && avctx->extradata_size >= 8 && avctx->channels) + s->duration = AV_RB16(avctx->extradata + 4) / avctx->channels; + + /* always return the full packet. this parser isn't doing any splitting or + combining, only setting packet duration */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +AVCodecParser ff_cook_parser = { + .codec_ids = { CODEC_ID_COOK }, + .priv_data_size = sizeof(CookParseContext), + .parser_parse = cook_parse, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index c35fce40e3..58a228c4a2 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -27,8 +27,8 @@ */ #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 11 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MINOR 12 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index c85208b3fb..0113251bc6 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -205,6 +205,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, st->codec->block_align = coded_framesize; break; case CODEC_ID_COOK: + st->need_parsing = AVSTREAM_PARSE_HEADERS; case CODEC_ID_ATRAC3: case CODEC_ID_SIPR: avio_rb16(pb); avio_r8(pb);