From 5082fcc0e2c899484534637544463effbf50d9d1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 28 Sep 2013 17:52:45 +0200 Subject: [PATCH] avformat: add support to force specific AVCodecs previously only codec_ids could be forced, which did not allow forcing a specific implementation like libopenjpeg vs jpeg2000. Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- doc/APIchanges | 4 ++++ libavformat/avformat.h | 30 ++++++++++++++++++++++++++++++ libavformat/utils.c | 15 +++++++++++++++ libavformat/version.h | 4 ++-- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index ab932c34d0..743b5b0a2b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2012-10-22 API changes, most recent first: +2013-10-02 - xxxxxxx - lavf 55.19.100 - avformat.h + Add audio/video/subtitle AVCodec fields to AVFormatContext to force specific + decoders + 2013-08-xx - xxxxxxx - lavfi 3.11.0 - avfilter.h Add AVFilterGraph.execute and AVFilterGraph.opaque for custom slice threading implementations. diff --git a/libavformat/avformat.h b/libavformat/avformat.h index b18eb3f545..4e5683c66a 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1315,9 +1315,39 @@ typedef struct AVFormatContext { * Demuxers can use the flag to detect such changes. */ int io_repositioned; + + /** + * Forced video codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user via av_format_set_video_codec (NO direct access). + */ + AVCodec *video_codec; + + /** + * Forced audio codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user via av_format_set_audio_codec (NO direct access). + */ + AVCodec *audio_codec; + + /** + * Forced subtitle codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user via av_format_set_subtitle_codec (NO direct access). + */ + AVCodec *subtitle_codec; } AVFormatContext; int av_format_get_probe_score(const AVFormatContext *s); +AVCodec * av_format_get_video_codec(const AVFormatContext *s); +void av_format_set_video_codec(AVFormatContext *s, AVCodec *c); +AVCodec * av_format_get_audio_codec(const AVFormatContext *s); +void av_format_set_audio_codec(AVFormatContext *s, AVCodec *c); +AVCodec * av_format_get_subtitle_codec(const AVFormatContext *s); +void av_format_set_subtitle_codec(AVFormatContext *s, AVCodec *c); /** * Returns the method used to set ctx->duration. diff --git a/libavformat/utils.c b/libavformat/utils.c index b47787a8ee..61405d7c97 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -98,12 +98,27 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp) } MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate) +MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec) +MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec) +MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec) static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id) { if (st->codec->codec) return st->codec->codec; + switch(st->codec->codec_type){ + case AVMEDIA_TYPE_VIDEO: + if(s->video_codec) return s->video_codec; + break; + case AVMEDIA_TYPE_AUDIO: + if(s->audio_codec) return s->audio_codec; + break; + case AVMEDIA_TYPE_SUBTITLE: + if(s->subtitle_codec) return s->subtitle_codec; + break; + } + return avcodec_find_decoder(codec_id); } diff --git a/libavformat/version.h b/libavformat/version.h index 10b6a36b98..32e76c78c0 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 55 -#define LIBAVFORMAT_VERSION_MINOR 18 -#define LIBAVFORMAT_VERSION_MICRO 104 +#define LIBAVFORMAT_VERSION_MINOR 19 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \