diff options
Diffstat (limited to 'video/decode/vd_lavc.c')
-rw-r--r-- | video/decode/vd_lavc.c | 116 |
1 files changed, 47 insertions, 69 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 1661ddd210..77fb800994 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -35,6 +35,8 @@ #include "core/mp_msg.h" #include "core/options.h" #include "core/av_opts.h" +#include "core/av_common.h" +#include "core/codecs.h" #include "compat/mpbswap.h" #include "video/fmt-conversion.h" @@ -45,19 +47,9 @@ #include "video/filter/vf.h" #include "demux/stheader.h" #include "demux/demux_packet.h" -#include "core/codec-cfg.h" #include "osdep/numcores.h" #include "video/csputils.h" -static const vd_info_t info = { - "libavcodec video codecs", - "ffmpeg", - "", - "", - "native codecs", - .print_name = "libavcodec", -}; - #include "libavcodec/avcodec.h" #include "lavc.h" @@ -67,7 +59,7 @@ static const vd_info_t info = { #include "core/m_option.h" -static int init_avctx(sh_video_t *sh, AVCodec *lavc_codec, struct hwdec *hwdec); +static int init_avctx(sh_video_t *sh, const char *decoder, struct hwdec *hwdec); static void uninit_avctx(sh_video_t *sh); static int get_buffer_hwdec(AVCodecContext *avctx, AVFrame *pic); static void release_buffer_hwdec(AVCodecContext *avctx, AVFrame *pic); @@ -155,70 +147,53 @@ static enum AVDiscard str2AVDiscard(char *str) return AVDISCARD_DEFAULT; } -static int init(sh_video_t *sh) +static int init(sh_video_t *sh, const char *decoder) { vd_ffmpeg_ctx *ctx; - AVCodec *lavc_codec = NULL; - ctx = sh->context = talloc_zero(NULL, vd_ffmpeg_ctx); ctx->non_dr1_pool = talloc_steal(ctx, mp_image_pool_new(16)); - if (sh->codec->dll) { - lavc_codec = avcodec_find_decoder_by_name(sh->codec->dll); - if (!lavc_codec) { - mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, - "Cannot find codec '%s' in libavcodec...\n", - sh->codec->dll); - uninit(sh); - return 0; - } - } else if (sh->libav_codec_id) { - lavc_codec = avcodec_find_decoder(sh->libav_codec_id); - if (!lavc_codec) { - mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Libavcodec has no decoder " - "for this codec\n"); - uninit(sh); - return 0; - } - } - if (!lavc_codec) { - uninit(sh); - return 0; - } - - struct hwdec *hwdec = find_hwcodec(sh->opts->hwdec_api, lavc_codec->name); + struct hwdec *hwdec = find_hwcodec(sh->opts->hwdec_api, decoder); if (hwdec) { AVCodec *lavc_hwcodec = avcodec_find_decoder_by_name(hwdec->hw_codec); if (lavc_hwcodec) { - ctx->software_fallback = lavc_codec; - lavc_codec = lavc_hwcodec; + ctx->software_fallback_decoder = decoder; + decoder = lavc_hwcodec->name; } else { hwdec = NULL; mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "Using software decoding.\n"); } } - if (!init_avctx(sh, lavc_codec, hwdec)) { - mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error initializing hardware " - "decoding, falling back to software decoding.\n"); - lavc_codec = ctx->software_fallback; - ctx->software_fallback = NULL; - if (!init_avctx(sh, lavc_codec, NULL)) { - uninit(sh); - return 0; + if (!init_avctx(sh, decoder, hwdec)) { + if (ctx->software_fallback_decoder) { + mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error initializing hardware " + "decoding, falling back to software decoding.\n"); + decoder = ctx->software_fallback_decoder; + ctx->software_fallback_decoder = NULL; + if (!init_avctx(sh, decoder, NULL)) { + uninit(sh); + return 0; + } } } return 1; } -static int init_avctx(sh_video_t *sh, AVCodec *lavc_codec, struct hwdec *hwdec) +static int init_avctx(sh_video_t *sh, const char *decoder, struct hwdec *hwdec) { vd_ffmpeg_ctx *ctx = sh->context; struct lavc_param *lavc_param = &sh->opts->lavc_param; + bool mp_rawvideo = false; + + if (strcmp(decoder, "mp-rawvideo") == 0) { + mp_rawvideo = true; + decoder = "rawvideo"; + } - sh->codecname = lavc_codec->long_name; - if (!sh->codecname) - sh->codecname = lavc_codec->name; + AVCodec *lavc_codec = avcodec_find_decoder_by_name(decoder); + if (!lavc_codec) + return 0; ctx->do_dr1 = ctx->do_hw_dr1 = 0; ctx->pix_fmt = PIX_FMT_NONE; @@ -264,8 +239,8 @@ static int init_avctx(sh_video_t *sh, AVCodec *lavc_codec, struct hwdec *hwdec) avctx->flags |= lavc_param->bitexact; - avctx->coded_width = sh->disp_w; - avctx->coded_height = sh->disp_h; + avctx->coded_width = sh->bih ? sh->bih->biWidth : sh->disp_w; + avctx->coded_height = sh->bih ? sh->bih->biHeight : sh->disp_h; avctx->workaround_bugs = lavc_param->workaround_bugs; if (lavc_param->gray) avctx->flags |= CODEC_FLAG_GRAY; @@ -340,14 +315,6 @@ static int init_avctx(sh_video_t *sh, AVCodec *lavc_codec, struct hwdec *hwdec) } break; - case MKTAG('M', 'P', 'v', 'f'): - avctx->codec_tag = 0; - avctx->pix_fmt = imgfmt2pixfmt(sh->imgfmt); - break; - case MKTAG('M', 'P', 'r', 'v'): - avctx->codec_tag = sh->imgfmt; - break; - default: if (!sh->bih || sh->bih->biSize <= sizeof(*sh->bih)) break; @@ -361,6 +328,11 @@ static int init_avctx(sh_video_t *sh, AVCodec *lavc_codec, struct hwdec *hwdec) if (sh->bih) avctx->bits_per_coded_sample = sh->bih->biBitCount; + if (mp_rawvideo && sh->format >= IMGFMT_START && sh->format < IMGFMT_END) { + avctx->pix_fmt = imgfmt2pixfmt(sh->format); + avctx->codec_tag = 0; + } + /* open it */ if (avcodec_open2(avctx, lavc_codec, NULL) < 0) { mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Could not open codec.\n"); @@ -375,8 +347,6 @@ static void uninit_avctx(sh_video_t *sh) vd_ffmpeg_ctx *ctx = sh->context; AVCodecContext *avctx = ctx->avctx; - sh->codecname = NULL; - if (avctx) { if (avctx->codec && avcodec_close(avctx) < 0) mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Could not close codec.\n"); @@ -661,14 +631,14 @@ static struct mp_image *decode_with_fallback(struct sh_video *sh, return mpi; // Failed hardware decoding? Try again in software. - if (ctx->software_fallback) { + if (ctx->software_fallback_decoder) { uninit_avctx(sh); sh->vf_initialized = 0; mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error using hardware " "decoding, falling back to software decoding.\n"); - AVCodec *codec = ctx->software_fallback; - ctx->software_fallback = NULL; - if (init_avctx(sh, codec, NULL)) { + const char *decoder = ctx->software_fallback_decoder; + ctx->software_fallback_decoder = NULL; + if (init_avctx(sh, decoder, NULL)) { mpi = NULL; decode(sh, packet, data, len, flags, reordered_pts, &mpi); return mpi; @@ -700,8 +670,16 @@ static int control(sh_video_t *sh, int cmd, void *arg) return CONTROL_UNKNOWN; } +static void add_decoders(struct mp_decoder_list *list) +{ + mp_add_lavc_decoders(list, AVMEDIA_TYPE_VIDEO); + mp_add_decoder(list, "lavc", "mp-rawvideo", "mp-rawvideo", + "raw video"); +} + const struct vd_functions mpcodecs_vd_ffmpeg = { - .info = &info, + .name = "lavc", + .add_decoders = add_decoders, .init = init, .uninit = uninit, .control = control, |