2010-01-30 17:57:40 +01:00
|
|
|
/*
|
2015-04-13 09:36:54 +02:00
|
|
|
* This file is part of mpv.
|
2010-01-30 17:57:40 +01:00
|
|
|
*
|
2015-04-13 09:36:54 +02:00
|
|
|
* mpv is free software; you can redistribute it and/or modify
|
2010-01-30 17:57:40 +01:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
2015-04-13 09:36:54 +02:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2010-01-30 17:57:40 +01:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
2015-04-13 09:36:54 +02:00
|
|
|
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
vd, vd_lavc: change license to LGPL (almost)
iive agreed only to LGPL 3.0+ only. All of his relevant changes are for
XvMC, for which mpv completely dropped support back in mplayer2 times.
But you could claim that the get_format code represents some residual
copyright (everything else added by iive was removed, only get_format
still is around in some form). While I doubt that this is relly
copyright-relevant, consider it is for now.
michael is the original author of vd_lavc.c, so this file can become
LGPL only after the core becomes LGPL.
cehoyos did not agree with the LGPL relicensing, but all of his code is
gone.
Some others could not be reached, but their code is gone as well. In
particular, vdpau support, which was originally done by Nvidia, had
larger impact on vd_lavc.c, but vdpau support was first refactored a few
times (for the purpose of modularization) and moved to different files,
and then decoding was completely moved to libavcodec.
Lastly, assigning the "opaque" field was moved by Gwenole Beauchesne in
commit 8e5edec13eab. Agreement is pending (due to copyright apparently
owned by the author's employer). So just undo the change, so we don't
have to think about whether the change is copyrightable.
2017-06-15 15:52:18 +02:00
|
|
|
*
|
|
|
|
* Almost LGPLv3+.
|
|
|
|
*
|
|
|
|
* The parts potentially making this file LGPL v3 (instead of v2.1 or later) are:
|
|
|
|
* 376e3abf5c7d2 xvmc use get_format for IDCT/MC recognition
|
|
|
|
* c73f0e18bd1d6 Return PIX_FMT_NONE if the video system refuses all other formats.
|
|
|
|
* (iive agreed to LGPL v3+ only. Jeremy agreed to LGPL v2.1 or later.)
|
|
|
|
* Once these changes are not relevant to for copyright anymore (e.g. because
|
|
|
|
* they have been removed), and the core is LGPL, this file will change to
|
|
|
|
* LGPLv2.1+.
|
2010-01-30 17:57:40 +01:00
|
|
|
*/
|
|
|
|
|
2002-03-06 21:54:43 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <assert.h>
|
2002-07-28 17:54:26 +02:00
|
|
|
#include <time.h>
|
2010-01-20 15:31:13 +01:00
|
|
|
#include <stdbool.h>
|
2012-07-31 23:37:56 +02:00
|
|
|
#include <sys/types.h>
|
2002-03-06 21:54:43 +01:00
|
|
|
|
2012-01-28 12:41:36 +01:00
|
|
|
#include <libavutil/common.h>
|
|
|
|
#include <libavutil/opt.h>
|
2017-01-12 09:40:16 +01:00
|
|
|
#include <libavutil/hwcontext.h>
|
2012-02-01 19:01:16 +01:00
|
|
|
#include <libavutil/intreadwrite.h>
|
2012-12-11 18:16:42 +01:00
|
|
|
#include <libavutil/pixdesc.h>
|
2012-01-28 12:41:36 +01:00
|
|
|
|
2016-01-11 19:03:40 +01:00
|
|
|
#include "mpv_talloc.h"
|
2002-03-06 21:54:43 +01:00
|
|
|
#include "config.h"
|
2013-12-17 02:39:45 +01:00
|
|
|
#include "common/msg.h"
|
2013-12-17 02:02:25 +01:00
|
|
|
#include "options/options.h"
|
2014-08-29 12:09:04 +02:00
|
|
|
#include "misc/bstr.h"
|
2013-12-17 02:39:45 +01:00
|
|
|
#include "common/av_common.h"
|
|
|
|
#include "common/codecs.h"
|
2002-03-06 21:54:43 +01:00
|
|
|
|
2012-11-09 01:06:43 +01:00
|
|
|
#include "video/fmt-conversion.h"
|
2002-03-06 21:54:43 +01:00
|
|
|
|
2009-11-21 19:53:10 +01:00
|
|
|
#include "vd.h"
|
2012-11-09 01:06:43 +01:00
|
|
|
#include "video/img_format.h"
|
2012-11-04 17:17:11 +01:00
|
|
|
#include "video/filter/vf.h"
|
2013-11-04 00:00:18 +01:00
|
|
|
#include "video/decode/dec_video.h"
|
2015-12-22 02:35:15 +01:00
|
|
|
#include "demux/demux.h"
|
2012-11-09 01:06:43 +01:00
|
|
|
#include "demux/stheader.h"
|
2013-11-18 18:46:44 +01:00
|
|
|
#include "demux/packet.h"
|
2012-11-09 01:06:43 +01:00
|
|
|
#include "video/csputils.h"
|
2015-02-06 23:20:41 +01:00
|
|
|
#include "video/sws_utils.h"
|
2002-03-06 21:54:43 +01:00
|
|
|
|
2017-01-24 08:11:42 +01:00
|
|
|
#if LIBAVCODEC_VERSION_MICRO >= 100
|
2016-06-29 09:43:55 +02:00
|
|
|
#include <libavutil/mastering_display_metadata.h>
|
|
|
|
#endif
|
|
|
|
|
2012-12-11 18:27:34 +01:00
|
|
|
#include "lavc.h"
|
2002-03-06 21:54:43 +01:00
|
|
|
|
mp_image: simplify image allocation
mp_image_alloc_planes() allocated images with minimal stride, even if
the resulting stride was unaligned. It was the responsibility of
vf_get_image() to set an image's width to something larger than
required to get an aligned stride, and then crop it. Always allocate
with aligned strides instead.
Get rid of IMGFMT_IF09 special handling. This format is not used
anymore. (IF09 has 4x4 chroma sub-sampling, and that is what it was
mainly used for - this is still supported.) Get rid of swapped chroma
plane allocation. This is not used anywhere, and VOs like vo_xv,
vo_direct3d and vo_sdl do their own swapping.
Always round chroma width/height up instead of down. Consider 4:2:0 and
an uneven image size. For luma, the size was left uneven, and the chroma
size was rounded down. This doesn't make sense, because chroma would be
missing for the bottom/right border.
Remove mp_image_new_empty() and mp_image_alloc_planes(), they were not
used anymore, except in draw_bmp.c. (It's still allowed to setup
mp_images manually, you just can't allocate image data with them
anymore - this is also done in draw_bmp.c.)
2012-12-19 12:04:32 +01:00
|
|
|
#if AVPALETTE_SIZE != MP_PALETTE_SIZE
|
|
|
|
#error palette too large, adapt video/mp_image.h:MP_PALETTE_SIZE
|
2009-12-26 12:51:19 +01:00
|
|
|
#endif
|
|
|
|
|
2013-12-17 02:02:25 +01:00
|
|
|
#include "options/m_option.h"
|
2002-06-02 14:48:55 +02:00
|
|
|
|
2013-11-23 21:36:20 +01:00
|
|
|
static void init_avctx(struct dec_video *vd, const char *decoder,
|
2013-08-11 23:23:12 +02:00
|
|
|
struct vd_lavc_hwdec *hwdec);
|
2013-11-23 21:36:20 +01:00
|
|
|
static void uninit_avctx(struct dec_video *vd);
|
2002-07-16 02:56:12 +02:00
|
|
|
|
2014-03-16 09:21:21 +01:00
|
|
|
static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags);
|
2013-11-29 17:39:57 +01:00
|
|
|
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
|
|
|
|
const enum AVPixelFormat *pix_fmt);
|
2012-11-06 15:27:44 +01:00
|
|
|
|
2014-06-11 01:35:39 +02:00
|
|
|
#define OPT_BASE_STRUCT struct vd_lavc_params
|
|
|
|
|
|
|
|
struct vd_lavc_params {
|
|
|
|
int fast;
|
|
|
|
int show_all;
|
2014-06-13 02:03:45 +02:00
|
|
|
int skip_loop_filter;
|
|
|
|
int skip_idct;
|
|
|
|
int skip_frame;
|
2014-08-09 00:35:25 +02:00
|
|
|
int framedrop;
|
2014-06-11 01:35:39 +02:00
|
|
|
int threads;
|
|
|
|
int bitexact;
|
|
|
|
int check_hw_profile;
|
2015-10-25 10:45:44 +01:00
|
|
|
int software_fallback;
|
2014-08-02 03:12:09 +02:00
|
|
|
char **avopts;
|
2014-06-11 01:35:39 +02:00
|
|
|
};
|
|
|
|
|
2014-06-13 02:03:45 +02:00
|
|
|
static const struct m_opt_choice_alternatives discard_names[] = {
|
|
|
|
{"none", AVDISCARD_NONE},
|
|
|
|
{"default", AVDISCARD_DEFAULT},
|
|
|
|
{"nonref", AVDISCARD_NONREF},
|
|
|
|
{"bidir", AVDISCARD_BIDIR},
|
|
|
|
{"nonkey", AVDISCARD_NONKEY},
|
|
|
|
{"all", AVDISCARD_ALL},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
#define OPT_DISCARD(name, field, flags) \
|
|
|
|
OPT_GENERAL(int, name, field, flags, .type = CONF_TYPE_CHOICE, \
|
|
|
|
.priv = (void *)discard_names)
|
|
|
|
|
2014-06-11 01:35:39 +02:00
|
|
|
const struct m_sub_options vd_lavc_conf = {
|
|
|
|
.opts = (const m_option_t[]){
|
2014-06-13 02:08:48 +02:00
|
|
|
OPT_FLAG("fast", fast, 0),
|
2014-06-11 01:35:39 +02:00
|
|
|
OPT_FLAG("show-all", show_all, 0),
|
2014-06-13 02:03:45 +02:00
|
|
|
OPT_DISCARD("skiploopfilter", skip_loop_filter, 0),
|
|
|
|
OPT_DISCARD("skipidct", skip_idct, 0),
|
|
|
|
OPT_DISCARD("skipframe", skip_frame, 0),
|
2014-08-09 00:35:25 +02:00
|
|
|
OPT_DISCARD("framedrop", framedrop, 0),
|
2015-07-23 17:17:26 +02:00
|
|
|
OPT_INT("threads", threads, M_OPT_MIN, .min = 0),
|
2014-06-13 02:08:48 +02:00
|
|
|
OPT_FLAG("bitexact", bitexact, 0),
|
2014-06-11 01:35:39 +02:00
|
|
|
OPT_FLAG("check-hw-profile", check_hw_profile, 0),
|
2015-11-03 14:03:02 +01:00
|
|
|
OPT_CHOICE_OR_INT("software-fallback", software_fallback, 0, 1, INT_MAX,
|
|
|
|
({"no", INT_MAX}, {"yes", 1})),
|
2014-08-02 03:12:09 +02:00
|
|
|
OPT_KEYVALUELIST("o", avopts, 0),
|
2014-06-11 01:35:39 +02:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
.size = sizeof(struct vd_lavc_params),
|
|
|
|
.defaults = &(const struct vd_lavc_params){
|
|
|
|
.show_all = 0,
|
|
|
|
.check_hw_profile = 1,
|
2015-11-03 14:03:02 +01:00
|
|
|
.software_fallback = 3,
|
2014-06-13 02:03:45 +02:00
|
|
|
.skip_loop_filter = AVDISCARD_DEFAULT,
|
|
|
|
.skip_idct = AVDISCARD_DEFAULT,
|
|
|
|
.skip_frame = AVDISCARD_DEFAULT,
|
2014-08-09 00:35:25 +02:00
|
|
|
.framedrop = AVDISCARD_NONREF,
|
2014-06-11 01:35:39 +02:00
|
|
|
},
|
2002-06-02 14:48:55 +02:00
|
|
|
};
|
|
|
|
|
2015-10-30 09:41:55 +01:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox;
|
2016-07-14 20:14:22 +02:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox_copy;
|
2016-01-30 10:04:34 +01:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2;
|
2015-10-30 09:41:55 +01:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2_copy;
|
2016-04-27 13:49:47 +02:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va;
|
2016-03-18 07:28:29 +01:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy;
|
2017-05-05 00:44:03 +02:00
|
|
|
extern const struct vd_lavc_hwdec mp_vd_lavc_cuda_old;
|
2016-04-25 12:09:09 +02:00
|
|
|
|
2016-07-02 01:12:34 +02:00
|
|
|
#if HAVE_RPI
|
2016-04-25 12:09:09 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_rpi = {
|
|
|
|
.type = HWDEC_RPI,
|
|
|
|
.lavc_suffix = "_mmal",
|
|
|
|
.image_format = IMGFMT_MMAL,
|
|
|
|
};
|
2016-09-30 11:35:25 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_rpi_copy = {
|
|
|
|
.type = HWDEC_RPI_COPY,
|
|
|
|
.lavc_suffix = "_mmal",
|
|
|
|
.copying = true,
|
|
|
|
};
|
2016-07-02 01:12:34 +02:00
|
|
|
#endif
|
2016-04-25 12:09:09 +02:00
|
|
|
|
2016-07-02 01:12:34 +02:00
|
|
|
#if HAVE_ANDROID
|
2016-04-25 12:09:09 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_mediacodec = {
|
|
|
|
.type = HWDEC_MEDIACODEC,
|
|
|
|
.lavc_suffix = "_mediacodec",
|
2016-05-11 16:18:58 +02:00
|
|
|
.copying = true,
|
2016-04-25 12:09:09 +02:00
|
|
|
};
|
2016-07-02 01:12:34 +02:00
|
|
|
#endif
|
2013-08-11 23:23:12 +02:00
|
|
|
|
2017-05-05 00:44:03 +02:00
|
|
|
#if NEW_CUDA_HWACCEL
|
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_cuda = {
|
|
|
|
.type = HWDEC_CUDA,
|
|
|
|
.image_format = IMGFMT_CUDA,
|
|
|
|
.lavc_suffix = "_cuvid",
|
|
|
|
.generic_hwaccel = true,
|
|
|
|
};
|
|
|
|
#endif
|
2016-09-16 05:15:36 +02:00
|
|
|
#if HAVE_CUDA_HWACCEL
|
2016-09-11 05:12:27 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_cuda_copy = {
|
|
|
|
.type = HWDEC_CUDA_COPY,
|
|
|
|
.lavc_suffix = "_cuvid",
|
|
|
|
.copying = true,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2016-10-09 18:18:14 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_crystalhd = {
|
|
|
|
.type = HWDEC_CRYSTALHD,
|
|
|
|
.lavc_suffix = "_crystalhd",
|
|
|
|
.copying = true,
|
|
|
|
};
|
|
|
|
|
2017-02-20 08:39:55 +01:00
|
|
|
#if HAVE_VAAPI_HWACCEL
|
2017-05-03 05:23:25 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_vaapi = {
|
2017-02-20 08:39:55 +01:00
|
|
|
.type = HWDEC_VAAPI,
|
|
|
|
.image_format = IMGFMT_VAAPI,
|
|
|
|
.generic_hwaccel = true,
|
2017-05-03 05:23:25 +02:00
|
|
|
.set_hwframes = true,
|
2017-02-20 08:39:55 +01:00
|
|
|
.static_pool = true,
|
|
|
|
.pixfmt_map = (const enum AVPixelFormat[][2]) {
|
|
|
|
{AV_PIX_FMT_YUV420P10, AV_PIX_FMT_P010},
|
|
|
|
{AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12},
|
|
|
|
{AV_PIX_FMT_NONE}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
#include "video/vaapi.h"
|
|
|
|
|
2017-05-03 05:23:25 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy = {
|
2017-02-20 08:39:55 +01:00
|
|
|
.type = HWDEC_VAAPI_COPY,
|
|
|
|
.copying = true,
|
|
|
|
.image_format = IMGFMT_VAAPI,
|
|
|
|
.generic_hwaccel = true,
|
2017-05-03 05:23:25 +02:00
|
|
|
.set_hwframes = true,
|
2017-02-20 08:39:55 +01:00
|
|
|
.static_pool = true,
|
|
|
|
.create_dev = va_create_standalone,
|
|
|
|
.pixfmt_map = (const enum AVPixelFormat[][2]) {
|
|
|
|
{AV_PIX_FMT_YUV420P10, AV_PIX_FMT_P010},
|
|
|
|
{AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12},
|
|
|
|
{AV_PIX_FMT_NONE}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2017-03-23 11:06:28 +01:00
|
|
|
#if HAVE_VDPAU_HWACCEL
|
2017-05-03 05:23:25 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_vdpau = {
|
2017-03-23 11:06:28 +01:00
|
|
|
.type = HWDEC_VDPAU,
|
|
|
|
.image_format = IMGFMT_VDPAU,
|
|
|
|
.generic_hwaccel = true,
|
2017-05-03 05:23:25 +02:00
|
|
|
.set_hwframes = true,
|
2017-03-23 11:06:28 +01:00
|
|
|
.pixfmt_map = (const enum AVPixelFormat[][2]) {
|
|
|
|
{AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P},
|
|
|
|
{AV_PIX_FMT_NONE}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
#include "video/vdpau.h"
|
|
|
|
|
2017-05-03 05:23:25 +02:00
|
|
|
static const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy = {
|
2017-03-23 11:06:28 +01:00
|
|
|
.type = HWDEC_VDPAU_COPY,
|
|
|
|
.copying = true,
|
|
|
|
.image_format = IMGFMT_VDPAU,
|
|
|
|
.generic_hwaccel = true,
|
2017-05-03 05:23:25 +02:00
|
|
|
.set_hwframes = true,
|
2017-03-23 11:06:28 +01:00
|
|
|
.create_dev = vdpau_create_standalone,
|
|
|
|
.pixfmt_map = (const enum AVPixelFormat[][2]) {
|
|
|
|
{AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P},
|
|
|
|
{AV_PIX_FMT_NONE}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2014-06-10 23:56:05 +02:00
|
|
|
static const struct vd_lavc_hwdec *const hwdec_list[] = {
|
2015-03-29 15:12:11 +02:00
|
|
|
#if HAVE_RPI
|
|
|
|
&mp_vd_lavc_rpi,
|
2016-09-30 11:35:25 +02:00
|
|
|
&mp_vd_lavc_rpi_copy,
|
2015-03-29 15:12:11 +02:00
|
|
|
#endif
|
2017-04-23 15:56:45 +02:00
|
|
|
#if HAVE_VDPAU_HWACCEL
|
2013-08-11 23:23:12 +02:00
|
|
|
&mp_vd_lavc_vdpau,
|
2016-10-20 16:43:02 +02:00
|
|
|
&mp_vd_lavc_vdpau_copy,
|
2013-07-16 13:28:28 +02:00
|
|
|
#endif
|
2015-07-11 17:21:39 +02:00
|
|
|
#if HAVE_VIDEOTOOLBOX_HWACCEL
|
|
|
|
&mp_vd_lavc_videotoolbox,
|
2016-07-14 20:14:22 +02:00
|
|
|
&mp_vd_lavc_videotoolbox_copy,
|
2015-07-11 17:21:39 +02:00
|
|
|
#endif
|
2017-04-23 15:56:45 +02:00
|
|
|
#if HAVE_VAAPI_HWACCEL
|
2015-03-05 13:02:30 +01:00
|
|
|
&mp_vd_lavc_vaapi,
|
2015-06-29 15:14:38 +02:00
|
|
|
&mp_vd_lavc_vaapi_copy,
|
2014-10-25 19:23:46 +02:00
|
|
|
#endif
|
2016-05-11 14:37:03 +02:00
|
|
|
#if HAVE_D3D_HWACCEL
|
2016-04-27 13:54:20 +02:00
|
|
|
&mp_vd_lavc_d3d11va,
|
2016-01-30 10:04:34 +01:00
|
|
|
&mp_vd_lavc_dxva2,
|
2014-10-25 19:23:46 +02:00
|
|
|
&mp_vd_lavc_dxva2_copy,
|
2016-03-18 07:28:29 +01:00
|
|
|
&mp_vd_lavc_d3d11va_copy,
|
|
|
|
#endif
|
2016-02-25 23:46:15 +01:00
|
|
|
#if HAVE_ANDROID
|
|
|
|
&mp_vd_lavc_mediacodec,
|
hwdec/opengl: Add support for CUDA and cuvid/NvDecode
Nvidia's "NvDecode" API (up until recently called "cuvid" is a cross
platform, but nvidia proprietary API that exposes their hardware
video decoding capabilities. It is analogous to their DXVA or VDPAU
support on Windows or Linux but without using platform specific API
calls.
As a rule, you'd rather use DXVA or VDPAU as these are more mature
and well supported APIs, but on Linux, VDPAU is falling behind the
hardware capabilities, and there's no sign that nvidia are making
the investments to update it.
Most concretely, this means that there is no VP8/9 or HEVC Main10
support in VDPAU. On the other hand, NvDecode does export vp8/9 and
partial support for HEVC Main10 (more on that below).
ffmpeg already has support in the form of the "cuvid" family of
decoders. Due to the design of the API, it is best exposed as a full
decoder rather than an hwaccel. As such, there are decoders like
h264_cuvid, hevc_cuvid, etc.
These decoders support two output paths today - in both cases, NV12
frames are returned, either in CUDA device memory or regular system
memory.
In the case of the system memory path, the decoders can be used
as-is in mpv today with a command line like:
mpv --vd=lavc:h264_cuvid foobar.mp4
Doing this will take advantage of hardware decoding, but the cost
of the memcpy to system memory adds up, especially for high
resolution video (4K etc).
To avoid that, we need an hwdec that takes advantage of CUDA's
OpenGL interop to copy from device memory into OpenGL textures.
That is what this change implements.
The process is relatively simple as only basic device context
aquisition needs to be done by us - the CUDA buffer pool is managed
by the decoder - thankfully.
The hwdec looks a bit like the vdpau interop one - the hwdec
maintains a single set of plane textures and each output frame
is repeatedly mapped into these textures to pass on.
The frames are always in NV12 format, at least until 10bit output
supports emerges.
The only slightly interesting part of the copying process is that
CUDA works by associating PBOs, so we need to define these for
each of the textures.
TODO Items:
* I need to add a download_image function for screenshots. This
would do the same copy to system memory that the decoder's
system memory output does.
* There are items to investigate on the ffmpeg side. There appears
to be a problem with timestamps for some content.
Final note: I mentioned HEVC Main10. While there is no 10bit output
support, NvDecode can return dithered 8bit NV12 so you can take
advantage of the hardware acceleration.
This particular mode requires compiling ffmpeg with a modified
header (or possibly the CUDA 8 RC) and is not upstream in ffmpeg
yet.
Usage:
You will need to specify vo=opengl and hwdec=cuda.
Note that hwdec=auto will probably not work as it will try to use
vdpau first.
mpv --hwdec=cuda --vo=opengl foobar.mp4
If you want to use filters that require frames in system memory,
just use the decoder directly without the hwdec, as documented
above.
2016-09-05 00:23:55 +02:00
|
|
|
#endif
|
2016-09-16 05:15:36 +02:00
|
|
|
#if HAVE_CUDA_HWACCEL
|
2017-05-05 00:44:03 +02:00
|
|
|
#if NEW_CUDA_HWACCEL
|
hwdec/opengl: Add support for CUDA and cuvid/NvDecode
Nvidia's "NvDecode" API (up until recently called "cuvid" is a cross
platform, but nvidia proprietary API that exposes their hardware
video decoding capabilities. It is analogous to their DXVA or VDPAU
support on Windows or Linux but without using platform specific API
calls.
As a rule, you'd rather use DXVA or VDPAU as these are more mature
and well supported APIs, but on Linux, VDPAU is falling behind the
hardware capabilities, and there's no sign that nvidia are making
the investments to update it.
Most concretely, this means that there is no VP8/9 or HEVC Main10
support in VDPAU. On the other hand, NvDecode does export vp8/9 and
partial support for HEVC Main10 (more on that below).
ffmpeg already has support in the form of the "cuvid" family of
decoders. Due to the design of the API, it is best exposed as a full
decoder rather than an hwaccel. As such, there are decoders like
h264_cuvid, hevc_cuvid, etc.
These decoders support two output paths today - in both cases, NV12
frames are returned, either in CUDA device memory or regular system
memory.
In the case of the system memory path, the decoders can be used
as-is in mpv today with a command line like:
mpv --vd=lavc:h264_cuvid foobar.mp4
Doing this will take advantage of hardware decoding, but the cost
of the memcpy to system memory adds up, especially for high
resolution video (4K etc).
To avoid that, we need an hwdec that takes advantage of CUDA's
OpenGL interop to copy from device memory into OpenGL textures.
That is what this change implements.
The process is relatively simple as only basic device context
aquisition needs to be done by us - the CUDA buffer pool is managed
by the decoder - thankfully.
The hwdec looks a bit like the vdpau interop one - the hwdec
maintains a single set of plane textures and each output frame
is repeatedly mapped into these textures to pass on.
The frames are always in NV12 format, at least until 10bit output
supports emerges.
The only slightly interesting part of the copying process is that
CUDA works by associating PBOs, so we need to define these for
each of the textures.
TODO Items:
* I need to add a download_image function for screenshots. This
would do the same copy to system memory that the decoder's
system memory output does.
* There are items to investigate on the ffmpeg side. There appears
to be a problem with timestamps for some content.
Final note: I mentioned HEVC Main10. While there is no 10bit output
support, NvDecode can return dithered 8bit NV12 so you can take
advantage of the hardware acceleration.
This particular mode requires compiling ffmpeg with a modified
header (or possibly the CUDA 8 RC) and is not upstream in ffmpeg
yet.
Usage:
You will need to specify vo=opengl and hwdec=cuda.
Note that hwdec=auto will probably not work as it will try to use
vdpau first.
mpv --hwdec=cuda --vo=opengl foobar.mp4
If you want to use filters that require frames in system memory,
just use the decoder directly without the hwdec, as documented
above.
2016-09-05 00:23:55 +02:00
|
|
|
&mp_vd_lavc_cuda,
|
2017-05-05 00:44:03 +02:00
|
|
|
#else
|
|
|
|
&mp_vd_lavc_cuda_old,
|
|
|
|
#endif
|
2016-09-11 05:12:27 +02:00
|
|
|
&mp_vd_lavc_cuda_copy,
|
video: add vaapi decode and output support
This is based on the MPlayer VA API patches. To be exact it's based on
a very stripped down version of commit f1ad459a263f8537f6c from
git://gitorious.org/vaapi/mplayer.git.
This doesn't contain useless things like benchmarking hacks and the
demo code for GLX interop. Also, unlike in the original patch, decoding
and video output are split into separate source files (the separation
between decoding and display also makes pixel format hacks unnecessary).
On the other hand, some features not present in the original patch were
added, like screenshot support.
VA API is rather bad for actual video output. Dealing with older libva
versions or the completely broken vdpau backend doesn't help. OSD is
low quality and should be rather slow. In some cases, only either OSD
or subtitles can be shown at the same time (because OSD is drawn first,
OSD is prefered).
Also, libva can't decide whether it accepts straight or premultiplied
alpha for OSD sub-pictures: the vdpau backend seems to assume
premultiplied, while a native vaapi driver uses straight. So I picked
straight alpha. It doesn't matter much, because the blending code for
straight alpha I added to img_convert.c is probably buggy, and ASS
subtitles might be blended incorrectly.
Really good video output with VA API would probably use OpenGL and the
GL interop features, but at this point you might just use vo_opengl.
(Patches for making HW decoding with vo_opengl have a chance of being
accepted.)
Despite these issues, decoding seems to work ok. I still got tearing
on the Intel system I tested (Intel(R) Core(TM) i3-2350M). It was also
tested with the vdpau vaapi wrapper on a nvidia system; however this
was rather broken. (Fortunately, there is no reason to use mpv's VAAPI
support over native VDPAU.)
2013-08-09 14:01:30 +02:00
|
|
|
#endif
|
2016-10-09 18:18:14 +02:00
|
|
|
&mp_vd_lavc_crystalhd,
|
2013-08-11 23:23:12 +02:00
|
|
|
NULL
|
2012-12-11 18:16:42 +01:00
|
|
|
};
|
|
|
|
|
2013-08-11 23:23:12 +02:00
|
|
|
static struct vd_lavc_hwdec *find_hwcodec(enum hwdec_type api)
|
2012-12-11 18:16:42 +01:00
|
|
|
{
|
2013-08-11 23:23:12 +02:00
|
|
|
for (int n = 0; hwdec_list[n]; n++) {
|
|
|
|
if (hwdec_list[n]->type == api)
|
|
|
|
return (struct vd_lavc_hwdec *)hwdec_list[n];
|
2012-12-11 18:16:42 +01:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-11-23 21:36:20 +01:00
|
|
|
static bool hwdec_codec_allowed(struct dec_video *vd, const char *codec)
|
2013-05-03 21:00:05 +02:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
bstr s = bstr0(vd->opts->hwdec_codecs);
|
2013-05-03 21:00:05 +02:00
|
|
|
while (s.len) {
|
|
|
|
bstr item;
|
|
|
|
bstr_split_tok(s, ",", &item, &s);
|
2013-08-11 23:23:12 +02:00
|
|
|
if (bstr_equals0(item, "all") || bstr_equals0(item, codec))
|
2013-05-03 21:00:05 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-01 17:14:05 +01:00
|
|
|
// Find the correct profile entry for the current codec and profile.
|
|
|
|
// Assumes the table has higher profiles first (for each codec).
|
|
|
|
const struct hwdec_profile_entry *hwdec_find_profile(
|
|
|
|
struct lavc_ctx *ctx, const struct hwdec_profile_entry *table)
|
|
|
|
{
|
|
|
|
assert(AV_CODEC_ID_NONE == 0);
|
2014-06-11 01:35:39 +02:00
|
|
|
struct vd_lavc_params *lavc_param = ctx->opts->vd_lavc_params;
|
2013-11-01 17:14:05 +01:00
|
|
|
enum AVCodecID codec = ctx->avctx->codec_id;
|
|
|
|
int profile = ctx->avctx->profile;
|
|
|
|
// Assume nobody cares about these aspects of the profile
|
2013-11-14 19:24:20 +01:00
|
|
|
if (codec == AV_CODEC_ID_H264) {
|
|
|
|
if (profile == FF_PROFILE_H264_CONSTRAINED_BASELINE)
|
|
|
|
profile = FF_PROFILE_H264_MAIN;
|
|
|
|
}
|
2013-11-01 17:14:05 +01:00
|
|
|
for (int n = 0; table[n].av_codec; n++) {
|
|
|
|
if (table[n].av_codec == codec) {
|
2015-10-11 18:48:02 +02:00
|
|
|
if (table[n].ff_profile == profile ||
|
2013-11-01 17:14:05 +01:00
|
|
|
!lavc_param->check_hw_profile)
|
|
|
|
return &table[n];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check codec support, without checking the profile.
|
2016-04-07 17:48:00 +02:00
|
|
|
bool hwdec_check_codec_support(const char *codec,
|
2013-11-01 17:14:05 +01:00
|
|
|
const struct hwdec_profile_entry *table)
|
|
|
|
{
|
2016-04-07 17:48:00 +02:00
|
|
|
enum AVCodecID codecid = mp_codec_to_av_codec_id(codec);
|
2013-11-01 17:14:05 +01:00
|
|
|
for (int n = 0; table[n].av_codec; n++) {
|
2016-04-07 17:48:00 +02:00
|
|
|
if (table[n].av_codec == codecid)
|
2013-11-01 17:14:05 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hwdec_get_max_refs(struct lavc_ctx *ctx)
|
|
|
|
{
|
2017-01-26 11:37:47 +01:00
|
|
|
switch (ctx->avctx->codec_id) {
|
|
|
|
case AV_CODEC_ID_H264:
|
|
|
|
case AV_CODEC_ID_HEVC:
|
2015-08-24 23:02:40 +02:00
|
|
|
return 16;
|
2017-01-26 11:37:47 +01:00
|
|
|
case AV_CODEC_ID_VP9:
|
|
|
|
return 8;
|
|
|
|
}
|
2015-08-24 23:02:40 +02:00
|
|
|
return 2;
|
2013-11-01 17:14:05 +01:00
|
|
|
}
|
|
|
|
|
2016-04-25 11:28:25 +02:00
|
|
|
// This is intended to return the name of a decoder for a given wrapper API.
|
|
|
|
// Decoder wrappers are usually added to libavcodec with a specific suffix.
|
|
|
|
// For example the mmal h264 decoder is named h264_mmal.
|
|
|
|
// This API would e.g. return h264_mmal for
|
|
|
|
// hwdec_find_decoder("h264", "_mmal").
|
|
|
|
// Just concatenating the two names will not always work due to inconsistencies
|
|
|
|
// (e.g. "mpeg2video" vs. "mpeg2").
|
|
|
|
const char *hwdec_find_decoder(const char *codec, const char *suffix)
|
|
|
|
{
|
|
|
|
enum AVCodecID codec_id = mp_codec_to_av_codec_id(codec);
|
|
|
|
if (codec_id == AV_CODEC_ID_NONE)
|
|
|
|
return NULL;
|
|
|
|
AVCodec *cur = NULL;
|
|
|
|
for (;;) {
|
|
|
|
cur = av_codec_next(cur);
|
|
|
|
if (!cur)
|
|
|
|
break;
|
|
|
|
if (cur->id == codec_id && av_codec_is_decoder(cur) &&
|
|
|
|
bstr_endswith0(bstr0(cur->name), suffix))
|
|
|
|
return cur->name;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parallel to hwdec_find_decoder(): return whether a hwdec can use the given
|
|
|
|
// decoder. This can't be answered accurately; it works for wrapper decoders
|
|
|
|
// only (like mmal), and for real hwaccels this will always return false.
|
|
|
|
static bool hwdec_is_wrapper(struct vd_lavc_hwdec *hwdec, const char *decoder)
|
|
|
|
{
|
|
|
|
if (!hwdec->lavc_suffix)
|
|
|
|
return false;
|
|
|
|
return bstr_endswith0(bstr0(decoder), hwdec->lavc_suffix);
|
|
|
|
}
|
|
|
|
|
2017-02-20 08:39:55 +01:00
|
|
|
static struct mp_hwdec_ctx *hwdec_create_dev(struct dec_video *vd,
|
|
|
|
struct vd_lavc_hwdec *hwdec,
|
|
|
|
bool autoprobe)
|
|
|
|
{
|
|
|
|
if (hwdec->create_dev)
|
|
|
|
return hwdec->create_dev(vd->global, vd->log, autoprobe);
|
|
|
|
if (vd->hwdec_devs) {
|
|
|
|
hwdec_devices_request(vd->hwdec_devs, hwdec->type);
|
|
|
|
return hwdec_devices_get(vd->hwdec_devs, hwdec->type);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-05-09 19:42:03 +02:00
|
|
|
static int hwdec_probe(struct dec_video *vd, struct vd_lavc_hwdec *hwdec,
|
2017-02-20 08:39:55 +01:00
|
|
|
const char *codec, bool autoprobe)
|
2013-08-11 23:23:12 +02:00
|
|
|
{
|
2016-05-09 19:42:03 +02:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2013-08-11 23:23:12 +02:00
|
|
|
int r = 0;
|
|
|
|
if (hwdec->probe)
|
2016-05-09 19:42:03 +02:00
|
|
|
r = hwdec->probe(ctx, hwdec, codec);
|
2017-02-20 08:39:55 +01:00
|
|
|
if (hwdec->generic_hwaccel) {
|
|
|
|
assert(!hwdec->probe && !hwdec->init && !hwdec->init_decoder &&
|
2017-06-08 21:16:11 +02:00
|
|
|
!hwdec->uninit && !hwdec->allocate_image);
|
2017-02-20 08:39:55 +01:00
|
|
|
struct mp_hwdec_ctx *dev = hwdec_create_dev(vd, hwdec, autoprobe);
|
|
|
|
if (!dev)
|
|
|
|
return hwdec->copying ? -1 : HWDEC_ERR_NO_CTX;
|
|
|
|
if (dev->emulated)
|
|
|
|
r = HWDEC_ERR_EMULATED;
|
|
|
|
if (hwdec->create_dev && dev->destroy)
|
|
|
|
dev->destroy(dev);
|
|
|
|
}
|
2016-04-25 11:28:25 +02:00
|
|
|
if (r >= 0) {
|
|
|
|
if (hwdec->lavc_suffix && !hwdec_find_decoder(codec, hwdec->lavc_suffix))
|
|
|
|
return HWDEC_ERR_NO_CODEC;
|
|
|
|
}
|
2013-08-11 23:23:12 +02:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2014-03-16 09:21:21 +01:00
|
|
|
static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
|
|
|
|
enum hwdec_type api,
|
2016-04-07 17:48:00 +02:00
|
|
|
const char *codec)
|
2013-08-11 23:23:12 +02:00
|
|
|
{
|
2015-09-02 23:31:01 +02:00
|
|
|
MP_VERBOSE(vd, "Probing '%s'...\n", m_opt_choice_str(mp_hwdec_names, api));
|
2013-08-11 23:23:12 +02:00
|
|
|
struct vd_lavc_hwdec *hwdec = find_hwcodec(api);
|
|
|
|
if (!hwdec) {
|
2017-02-20 08:41:23 +01:00
|
|
|
int level = autoprobe ? MSGL_V : MSGL_WARN;
|
|
|
|
MP_MSG(vd, level, "Requested hardware decoder not compiled.\n");
|
2014-03-16 09:21:21 +01:00
|
|
|
return NULL;
|
2013-08-11 23:23:12 +02:00
|
|
|
}
|
2017-02-20 08:39:55 +01:00
|
|
|
int r = hwdec_probe(vd, hwdec, codec, autoprobe);
|
2014-05-28 01:37:53 +02:00
|
|
|
if (r == HWDEC_ERR_EMULATED) {
|
|
|
|
if (autoprobe)
|
|
|
|
return NULL;
|
|
|
|
// User requested this explicitly.
|
|
|
|
MP_WARN(vd, "Using emulated hardware decoding API.\n");
|
|
|
|
r = 0;
|
|
|
|
}
|
2013-08-11 23:23:12 +02:00
|
|
|
if (r >= 0) {
|
2014-03-16 09:21:21 +01:00
|
|
|
return hwdec;
|
2013-08-11 23:23:12 +02:00
|
|
|
} else if (r == HWDEC_ERR_NO_CODEC) {
|
2016-04-07 17:48:00 +02:00
|
|
|
MP_VERBOSE(vd, "Hardware decoder for '%s' with the given API not found "
|
|
|
|
"in libavcodec.\n", codec);
|
2013-08-11 23:23:12 +02:00
|
|
|
} else if (r == HWDEC_ERR_NO_CTX && !autoprobe) {
|
2015-06-20 22:26:57 +02:00
|
|
|
MP_WARN(vd, "VO does not support requested hardware decoder, or "
|
|
|
|
"loading it failed.\n");
|
2013-08-11 23:23:12 +02:00
|
|
|
}
|
2014-03-16 09:21:21 +01:00
|
|
|
return NULL;
|
2013-08-11 23:23:12 +02:00
|
|
|
}
|
|
|
|
|
2014-09-29 20:37:12 +02:00
|
|
|
static void uninit(struct dec_video *vd)
|
|
|
|
{
|
|
|
|
uninit_avctx(vd);
|
|
|
|
talloc_free(vd->priv);
|
|
|
|
}
|
2013-08-11 23:23:12 +02:00
|
|
|
|
2016-04-22 15:45:23 +02:00
|
|
|
static void force_fallback(struct dec_video *vd)
|
2015-09-02 23:10:39 +02:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
uninit_avctx(vd);
|
2015-09-02 23:31:01 +02:00
|
|
|
int lev = ctx->hwdec_notified ? MSGL_WARN : MSGL_V;
|
|
|
|
mp_msg(vd->log, lev, "Falling back to software decoding.\n");
|
2016-01-29 22:46:46 +01:00
|
|
|
init_avctx(vd, ctx->decoder, NULL);
|
2015-09-02 23:10:39 +02:00
|
|
|
}
|
|
|
|
|
2016-01-29 22:47:27 +01:00
|
|
|
static void reinit(struct dec_video *vd)
|
2011-10-22 02:51:37 +02:00
|
|
|
{
|
2016-01-29 22:47:27 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
const char *decoder = ctx->decoder;
|
2016-04-07 17:48:00 +02:00
|
|
|
const char *codec = vd->codec->codec;
|
2009-02-12 16:41:59 +01:00
|
|
|
|
2016-01-29 22:47:27 +01:00
|
|
|
uninit_avctx(vd);
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-28 01:49:45 +02:00
|
|
|
|
2013-08-11 23:23:12 +02:00
|
|
|
struct vd_lavc_hwdec *hwdec = NULL;
|
|
|
|
|
2016-04-07 17:48:00 +02:00
|
|
|
if (hwdec_codec_allowed(vd, codec)) {
|
2016-05-11 16:18:58 +02:00
|
|
|
int api = vd->opts->hwdec_api;
|
|
|
|
if (HWDEC_IS_AUTO(api)) {
|
2016-04-25 11:28:25 +02:00
|
|
|
// If a specific decoder is forced, we should try a hwdec method
|
|
|
|
// that works with it, instead of simply failing later at runtime.
|
|
|
|
// This is good for avoiding trying "normal" hwaccels on wrapper
|
|
|
|
// decoders (like vaapi on a mmal decoder). Since libavcodec doesn't
|
|
|
|
// tell us which decoder supports which hwaccel methods without
|
|
|
|
// actually running it, do it by detecting such wrapper decoders.
|
|
|
|
// On the other hand, e.g. "--hwdec=rpi" should always force the
|
|
|
|
// wrapper decoder, so be careful not to break this case.
|
|
|
|
bool might_be_wrapper = false;
|
|
|
|
for (int n = 0; hwdec_list[n]; n++) {
|
|
|
|
struct vd_lavc_hwdec *other = (void *)hwdec_list[n];
|
|
|
|
if (hwdec_is_wrapper(other, decoder))
|
|
|
|
might_be_wrapper = true;
|
|
|
|
}
|
2013-08-11 23:23:12 +02:00
|
|
|
for (int n = 0; hwdec_list[n]; n++) {
|
2016-04-07 17:48:00 +02:00
|
|
|
hwdec = probe_hwdec(vd, true, hwdec_list[n]->type, codec);
|
2016-04-25 11:28:25 +02:00
|
|
|
if (hwdec) {
|
|
|
|
if (might_be_wrapper && !hwdec_is_wrapper(hwdec, decoder)) {
|
|
|
|
MP_VERBOSE(vd, "This hwaccel is not compatible.\n");
|
|
|
|
continue;
|
|
|
|
}
|
2016-05-11 16:18:58 +02:00
|
|
|
if (api == HWDEC_AUTO_COPY && !hwdec->copying) {
|
|
|
|
MP_VERBOSE(vd, "Not using this for auto-copy mode.\n");
|
|
|
|
continue;
|
|
|
|
}
|
2013-08-11 23:23:12 +02:00
|
|
|
break;
|
2016-04-25 11:28:25 +02:00
|
|
|
}
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-28 01:49:45 +02:00
|
|
|
}
|
2016-05-11 16:18:58 +02:00
|
|
|
} else if (api != HWDEC_NONE) {
|
|
|
|
hwdec = probe_hwdec(vd, false, api, codec);
|
2012-12-11 18:16:42 +01:00
|
|
|
}
|
2013-08-11 23:23:12 +02:00
|
|
|
} else {
|
2015-03-20 22:14:14 +01:00
|
|
|
MP_VERBOSE(vd, "Not trying to use hardware decoding: codec %s is not "
|
|
|
|
"on whitelist, or does not support hardware acceleration.\n",
|
2016-04-07 17:48:00 +02:00
|
|
|
codec);
|
2013-08-11 23:23:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hwdec) {
|
2016-09-30 12:06:55 +02:00
|
|
|
const char *orig_decoder = decoder;
|
2016-04-25 11:28:25 +02:00
|
|
|
if (hwdec->lavc_suffix)
|
|
|
|
decoder = hwdec_find_decoder(codec, hwdec->lavc_suffix);
|
2015-09-02 23:31:01 +02:00
|
|
|
MP_VERBOSE(vd, "Trying hardware decoding.\n");
|
2016-09-30 12:06:55 +02:00
|
|
|
if (strcmp(orig_decoder, decoder) != 0)
|
|
|
|
MP_VERBOSE(vd, "Using underlying hw-decoder '%s'\n", decoder);
|
2015-09-02 23:31:01 +02:00
|
|
|
} else {
|
|
|
|
MP_VERBOSE(vd, "Using software decoding.\n");
|
2012-12-11 18:16:42 +01:00
|
|
|
}
|
|
|
|
|
2013-11-23 21:36:20 +01:00
|
|
|
init_avctx(vd, decoder, hwdec);
|
2016-04-22 15:45:23 +02:00
|
|
|
if (!ctx->avctx && hwdec)
|
2015-09-02 23:10:39 +02:00
|
|
|
force_fallback(vd);
|
2016-01-29 22:47:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int init(struct dec_video *vd, const char *decoder)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx;
|
|
|
|
ctx = vd->priv = talloc_zero(NULL, vd_ffmpeg_ctx);
|
|
|
|
ctx->log = vd->log;
|
|
|
|
ctx->opts = vd->opts;
|
|
|
|
ctx->decoder = talloc_strdup(ctx, decoder);
|
2016-05-09 19:42:03 +02:00
|
|
|
ctx->hwdec_devs = vd->hwdec_devs;
|
2017-01-12 13:15:45 +01:00
|
|
|
ctx->hwdec_swpool = talloc_steal(ctx, mp_image_pool_new(17));
|
2016-01-29 22:47:27 +01:00
|
|
|
|
|
|
|
reinit(vd);
|
|
|
|
|
|
|
|
if (!ctx->avctx) {
|
|
|
|
uninit(vd);
|
|
|
|
return 0;
|
|
|
|
}
|
2012-12-11 18:16:42 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-23 21:36:20 +01:00
|
|
|
static void init_avctx(struct dec_video *vd, const char *decoder,
|
2013-08-11 23:23:12 +02:00
|
|
|
struct vd_lavc_hwdec *hwdec)
|
2012-12-11 18:16:42 +01:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2014-06-11 01:35:39 +02:00
|
|
|
struct vd_lavc_params *lavc_param = vd->opts->vd_lavc_params;
|
2016-02-15 20:34:45 +01:00
|
|
|
struct mp_codec_params *c = vd->codec;
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 15:15:19 +01:00
|
|
|
|
2013-04-27 13:36:09 +02:00
|
|
|
assert(!ctx->avctx);
|
|
|
|
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 15:15:19 +01:00
|
|
|
AVCodec *lavc_codec = avcodec_find_decoder_by_name(decoder);
|
|
|
|
if (!lavc_codec)
|
2013-04-27 13:36:09 +02:00
|
|
|
return;
|
2012-07-24 08:01:47 +02:00
|
|
|
|
2016-08-19 14:19:46 +02:00
|
|
|
ctx->codec_timebase = mp_get_codec_timebase(vd->codec);
|
2016-08-29 12:49:18 +02:00
|
|
|
|
|
|
|
// This decoder does not read pkt_timebase correctly yet.
|
|
|
|
if (strstr(decoder, "_mmal"))
|
|
|
|
ctx->codec_timebase = (AVRational){1, 1000000};
|
|
|
|
|
2013-11-29 17:39:57 +01:00
|
|
|
ctx->pix_fmt = AV_PIX_FMT_NONE;
|
2012-12-11 18:16:42 +01:00
|
|
|
ctx->hwdec = hwdec;
|
2014-03-10 22:36:23 +01:00
|
|
|
ctx->hwdec_fmt = 0;
|
2012-01-28 12:41:36 +01:00
|
|
|
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
2012-12-11 18:16:42 +01:00
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2014-12-12 17:28:22 +01:00
|
|
|
if (!ctx->avctx)
|
2014-12-13 22:00:42 +01:00
|
|
|
goto error;
|
2011-04-20 01:59:45 +02:00
|
|
|
avctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
2009-09-23 21:21:38 +02:00
|
|
|
avctx->codec_id = lavc_codec->id;
|
2016-08-29 12:46:12 +02:00
|
|
|
|
|
|
|
#if LIBAVCODEC_VERSION_MICRO >= 100
|
|
|
|
avctx->pkt_timebase = ctx->codec_timebase;
|
|
|
|
#endif
|
2016-04-25 11:47:35 +02:00
|
|
|
|
2013-10-31 18:12:39 +01:00
|
|
|
ctx->pic = av_frame_alloc();
|
2014-12-12 17:28:22 +01:00
|
|
|
if (!ctx->pic)
|
2014-12-13 22:00:42 +01:00
|
|
|
goto error;
|
2013-10-31 18:12:39 +01:00
|
|
|
|
2013-12-04 20:58:06 +01:00
|
|
|
if (ctx->hwdec) {
|
vd, vd_lavc: change license to LGPL (almost)
iive agreed only to LGPL 3.0+ only. All of his relevant changes are for
XvMC, for which mpv completely dropped support back in mplayer2 times.
But you could claim that the get_format code represents some residual
copyright (everything else added by iive was removed, only get_format
still is around in some form). While I doubt that this is relly
copyright-relevant, consider it is for now.
michael is the original author of vd_lavc.c, so this file can become
LGPL only after the core becomes LGPL.
cehoyos did not agree with the LGPL relicensing, but all of his code is
gone.
Some others could not be reached, but their code is gone as well. In
particular, vdpau support, which was originally done by Nvidia, had
larger impact on vd_lavc.c, but vdpau support was first refactored a few
times (for the purpose of modularization) and moved to different files,
and then decoding was completely moved to libavcodec.
Lastly, assigning the "opaque" field was moved by Gwenole Beauchesne in
commit 8e5edec13eab. Agreement is pending (due to copyright apparently
owned by the author's employer). So just undo the change, so we don't
have to think about whether the change is copyrightable.
2017-06-15 15:52:18 +02:00
|
|
|
avctx->opaque = vd;
|
2016-04-25 12:12:40 +02:00
|
|
|
avctx->thread_count = 1;
|
2017-04-23 15:56:45 +02:00
|
|
|
#if HAVE_VDPAU_HWACCEL
|
2017-03-23 11:06:28 +01:00
|
|
|
avctx->hwaccel_flags |= AV_HWACCEL_FLAG_IGNORE_LEVEL;
|
|
|
|
#endif
|
2016-04-25 12:12:40 +02:00
|
|
|
if (ctx->hwdec->image_format)
|
|
|
|
avctx->get_format = get_format_hwdec;
|
2015-03-29 15:12:11 +02:00
|
|
|
if (ctx->hwdec->allocate_image)
|
|
|
|
avctx->get_buffer2 = get_buffer2_hwdec;
|
2016-04-25 11:58:04 +02:00
|
|
|
if (ctx->hwdec->init && ctx->hwdec->init(ctx) < 0)
|
2014-12-13 22:00:42 +01:00
|
|
|
goto error;
|
2017-02-20 08:39:55 +01:00
|
|
|
if (ctx->hwdec->generic_hwaccel) {
|
|
|
|
ctx->hwdec_dev = hwdec_create_dev(vd, ctx->hwdec, false);
|
|
|
|
if (!ctx->hwdec_dev)
|
|
|
|
goto error;
|
vdpau: crappy hack to allow initializing hw decoding after preemption
If vo_opengl is used, and vo_opengl already created the vdpau interop
(for whatever reasons), and then preemption happens, and then you try to
enable hw decoding, it failed. The reason was that preemption recovery
is not run at any point before libavcodec accesses the vdpau device.
The actual impact was that with libmpv + opengl-cb use, hardware
decoding was permanently broken after display mode switching (something
that caused the display to get preempted at least with older drivers).
With mpv CLI, you can for example enable hw decoding during playback,
then disable it, VT switch to console, switch back to X, and try to
enable hw decoding again.
This is mostly because libav* does not deal with preemption, and NVIDIA
driver preemption behavior being horrible garbage. In addition to being
misdesigned API, the preemption callback is not called before you try to
access vdpau API, and then only with _some_ accesses.
In summary, the preemption callback was never called, neither before nor
after libavcodec tried to init the decoder. So we have to get
mp_vdpau_handle_preemption() called before libavcodec accesses it. This
in turn will do a dummy API access which usually triggers the preemption
callback immediately (with NVIDIA's drivers).
In addition, we have to update the AVHWDeviceContext's device. In theory
it could change (in practice it usually seems to use handle "0").
Creating a new device would cause chaos, as we don't have a concept of
switching the device context on the fly. So we simply update it
directly. I'm fairly sure this violates the libav* API, but it's the
best we can do.
2017-05-19 15:24:38 +02:00
|
|
|
if (ctx->hwdec_dev->restore_device)
|
|
|
|
ctx->hwdec_dev->restore_device(ctx->hwdec_dev);
|
2017-05-04 01:00:35 +02:00
|
|
|
if (!ctx->hwdec->set_hwframes) {
|
|
|
|
#if HAVE_VDPAU_HWACCEL
|
2017-05-03 05:23:25 +02:00
|
|
|
avctx->hw_device_ctx = av_buffer_ref(ctx->hwdec_dev->av_device_ref);
|
2017-05-04 01:00:35 +02:00
|
|
|
#else
|
|
|
|
goto error;
|
|
|
|
#endif
|
|
|
|
}
|
2017-02-20 08:39:55 +01:00
|
|
|
}
|
2016-04-07 18:26:58 +02:00
|
|
|
ctx->max_delay_queue = ctx->hwdec->delay_queue;
|
2017-01-10 16:49:06 +01:00
|
|
|
ctx->hw_probing = true;
|
2013-03-09 20:21:12 +01:00
|
|
|
} else {
|
2015-01-05 12:17:55 +01:00
|
|
|
mp_set_avcodec_threads(vd->log, avctx, lavc_param->threads);
|
2010-12-20 04:53:28 +01:00
|
|
|
}
|
2002-09-07 00:53:26 +02:00
|
|
|
|
2016-12-29 07:37:31 +01:00
|
|
|
avctx->flags |= lavc_param->bitexact ? AV_CODEC_FLAG_BITEXACT : 0;
|
|
|
|
avctx->flags2 |= lavc_param->fast ? AV_CODEC_FLAG2_FAST : 0;
|
2009-02-12 16:41:59 +01:00
|
|
|
|
2016-04-25 19:11:16 +02:00
|
|
|
if (lavc_param->show_all)
|
2016-12-29 07:37:31 +01:00
|
|
|
avctx->flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT;
|
2013-12-29 14:07:08 +01:00
|
|
|
|
2014-06-13 02:03:45 +02:00
|
|
|
avctx->skip_loop_filter = lavc_param->skip_loop_filter;
|
|
|
|
avctx->skip_idct = lavc_param->skip_idct;
|
|
|
|
avctx->skip_frame = lavc_param->skip_frame;
|
2008-05-10 20:55:31 +02:00
|
|
|
|
2014-08-02 03:12:09 +02:00
|
|
|
mp_set_avopts(vd->log, avctx, lavc_param->avopts);
|
2008-05-10 20:55:31 +02:00
|
|
|
|
2011-07-09 12:50:16 +02:00
|
|
|
// Do this after the above avopt handling in case it changes values
|
|
|
|
ctx->skip_frame = avctx->skip_frame;
|
|
|
|
|
2017-01-25 08:24:19 +01:00
|
|
|
if (mp_set_avctx_codec_headers(avctx, c) < 0) {
|
|
|
|
MP_ERR(vd, "Could not set codec parameters.\n");
|
|
|
|
goto error;
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 15:15:19 +01:00
|
|
|
}
|
|
|
|
|
2002-03-06 21:54:43 +01:00
|
|
|
/* open it */
|
2014-12-13 22:00:42 +01:00
|
|
|
if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
MP_ERR(vd, "Could not open codec.\n");
|
|
|
|
uninit_avctx(vd);
|
2002-03-06 21:54:43 +01:00
|
|
|
}
|
|
|
|
|
2015-11-10 16:06:42 +01:00
|
|
|
static void reset_avctx(struct dec_video *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
2016-02-06 10:09:13 +01:00
|
|
|
if (ctx->avctx && avcodec_is_open(ctx->avctx))
|
2015-11-10 16:06:42 +01:00
|
|
|
avcodec_flush_buffers(ctx->avctx);
|
|
|
|
ctx->flushing = false;
|
|
|
|
}
|
|
|
|
|
2016-01-25 21:00:53 +01:00
|
|
|
static void flush_all(struct dec_video *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
for (int n = 0; n < ctx->num_delay_queue; n++)
|
|
|
|
talloc_free(ctx->delay_queue[n]);
|
|
|
|
ctx->num_delay_queue = 0;
|
|
|
|
|
2017-01-10 16:49:06 +01:00
|
|
|
for (int n = 0; n < ctx->num_sent_packets; n++)
|
|
|
|
talloc_free(ctx->sent_packets[n]);
|
|
|
|
ctx->num_sent_packets = 0;
|
|
|
|
|
|
|
|
for (int n = 0; n < ctx->num_requeue_packets; n++)
|
|
|
|
talloc_free(ctx->requeue_packets[n]);
|
|
|
|
ctx->num_requeue_packets = 0;
|
2017-01-10 16:19:57 +01:00
|
|
|
|
2016-01-25 21:00:53 +01:00
|
|
|
reset_avctx(vd);
|
|
|
|
}
|
|
|
|
|
2013-11-23 21:36:20 +01:00
|
|
|
static void uninit_avctx(struct dec_video *vd)
|
2011-10-22 02:51:37 +02:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2009-02-12 16:41:59 +01:00
|
|
|
|
2016-01-30 20:59:25 +01:00
|
|
|
flush_all(vd);
|
|
|
|
av_frame_free(&ctx->pic);
|
2017-01-17 10:56:16 +01:00
|
|
|
av_buffer_unref(&ctx->cached_hw_frames_ctx);
|
2016-01-30 20:59:25 +01:00
|
|
|
|
2016-02-05 17:46:46 +01:00
|
|
|
if (ctx->avctx) {
|
|
|
|
if (avcodec_close(ctx->avctx) < 0)
|
2013-12-21 17:47:38 +01:00
|
|
|
MP_ERR(vd, "Could not close codec.\n");
|
2016-02-05 17:46:46 +01:00
|
|
|
av_freep(&ctx->avctx->extradata);
|
2007-02-03 14:19:21 +01:00
|
|
|
}
|
2005-01-08 20:16:21 +01:00
|
|
|
|
2017-02-20 08:39:55 +01:00
|
|
|
if (ctx->hwdec_dev && ctx->hwdec && ctx->hwdec->generic_hwaccel &&
|
|
|
|
ctx->hwdec_dev->destroy)
|
|
|
|
ctx->hwdec_dev->destroy(ctx->hwdec_dev);
|
|
|
|
ctx->hwdec_dev = NULL;
|
|
|
|
|
2015-02-14 16:45:01 +01:00
|
|
|
if (ctx->hwdec && ctx->hwdec->uninit)
|
|
|
|
ctx->hwdec->uninit(ctx);
|
2015-11-01 22:55:43 +01:00
|
|
|
ctx->hwdec = NULL;
|
2016-11-10 08:39:09 +01:00
|
|
|
assert(ctx->hwdec_priv == NULL);
|
2015-02-14 16:45:01 +01:00
|
|
|
|
2016-02-06 10:09:13 +01:00
|
|
|
av_freep(&ctx->avctx);
|
|
|
|
|
vd_lavc: make hardware decoding fallback less violent
Most of hardware decoding is initialized lazily. When the first packet
is parsed, libavcodec will call get_format() to check whether hw or sw
decoding is wanted. Until now, we've returned AV_PIX_FMT_NONE from
get_format() if hw decoder initialization failed. This caused the
avcodec_decode_video2() call to fail, which in turn let us trigger the
fallback. We didn't return a sw format from get_format(), because we
didn't want to continue decoding at all. (The reason being that full
reinitialization is more robust when continuing sw decoding.)
This has some disadvantages. libavcodec vomited some unwanted error
messages. Sometimes the failures are more severe, like it happened with
HEVC. In this case, the error code path simply acted up in a way that
was extremely inconvenient (and had to be fixed by myself). In general,
libavcodec is not designed to fallback this way.
Make it a bit less violent from the API usage point of view. Return a sw
format if hw decoder initialization fails. In this case, we let
get_buffer2() call avcodec_default_get_buffer2() as well. libavcodec is
allowed to perform its own sw fallback. But once the decode function
returns, we do the full reinitialization we wanted to do.
The result is that the fallback is more robust, and doesn't trigger any
decoder error codepaths or messages either. Change our own fallback
message to a warning, since there are no other messages with error
severity anymore.
2015-05-28 21:52:04 +02:00
|
|
|
ctx->hwdec_failed = false;
|
2015-11-03 14:03:02 +01:00
|
|
|
ctx->hwdec_fail_count = 0;
|
2016-01-25 21:00:53 +01:00
|
|
|
ctx->max_delay_queue = 0;
|
2017-01-10 16:49:06 +01:00
|
|
|
ctx->hw_probing = false;
|
2002-03-06 21:54:43 +01:00
|
|
|
}
|
|
|
|
|
2013-12-10 19:07:29 +01:00
|
|
|
static void update_image_params(struct dec_video *vd, AVFrame *frame,
|
2017-01-12 11:54:53 +01:00
|
|
|
struct mp_image_params *params)
|
2012-12-11 18:16:42 +01:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2017-06-10 14:02:55 +02:00
|
|
|
AVFrameSideData *sd;
|
2013-11-23 21:40:51 +01:00
|
|
|
|
2017-06-10 14:02:55 +02:00
|
|
|
#if HAVE_AVUTIL_CONTENT_LIGHT_LEVEL
|
|
|
|
// Get the content light metadata if available
|
|
|
|
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
2016-06-29 09:43:55 +02:00
|
|
|
if (sd) {
|
2017-06-10 14:02:55 +02:00
|
|
|
AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
|
|
|
|
params->color.sig_peak = clm->MaxCLL / MP_REF_WHITE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if LIBAVCODEC_VERSION_MICRO >= 100
|
|
|
|
// Otherwise, try getting the mastering metadata if available
|
|
|
|
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
|
|
|
if (!params->color.sig_peak && sd) {
|
2016-06-29 09:43:55 +02:00
|
|
|
AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data;
|
2017-06-10 14:02:55 +02:00
|
|
|
if (mdm->has_luminance)
|
|
|
|
params->color.sig_peak = av_q2d(mdm->max_luminance) / MP_REF_WHITE;
|
2016-06-29 09:43:55 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-06-10 14:02:55 +02:00
|
|
|
if (params->color.sig_peak) {
|
|
|
|
ctx->cached_sig_peak = params->color.sig_peak;
|
|
|
|
} else {
|
|
|
|
params->color.sig_peak = ctx->cached_sig_peak;
|
|
|
|
}
|
|
|
|
|
2017-01-12 11:54:53 +01:00
|
|
|
params->rotate = vd->codec->rotate;
|
|
|
|
params->stereo_in = vd->codec->stereo_mode;
|
2002-07-14 21:44:40 +02:00
|
|
|
}
|
|
|
|
|
2017-01-17 10:56:16 +01:00
|
|
|
// Allocate and set AVCodecContext.hw_frames_ctx. Also caches them on redundant
|
|
|
|
// calls (useful because seeks issue get_format, which clears hw_frames_ctx).
|
|
|
|
// device_ctx: reference to an AVHWDeviceContext
|
|
|
|
// av_sw_format: AV_PIX_FMT_ for the underlying hardware frame format
|
|
|
|
// initial_pool_size: number of frames in the memory pool on creation
|
|
|
|
// Return >=0 on success, <0 on error.
|
|
|
|
int hwdec_setup_hw_frames_ctx(struct lavc_ctx *ctx, AVBufferRef *device_ctx,
|
|
|
|
int av_sw_format, int initial_pool_size)
|
|
|
|
{
|
|
|
|
int w = ctx->avctx->coded_width;
|
|
|
|
int h = ctx->avctx->coded_height;
|
|
|
|
int av_hw_format = imgfmt2pixfmt(ctx->hwdec_fmt);
|
|
|
|
|
2017-05-24 14:40:25 +02:00
|
|
|
if (!device_ctx) {
|
|
|
|
MP_ERR(ctx, "Missing device context.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-01-17 10:56:16 +01:00
|
|
|
if (ctx->cached_hw_frames_ctx) {
|
|
|
|
AVHWFramesContext *fctx = (void *)ctx->cached_hw_frames_ctx->data;
|
|
|
|
if (fctx->width != w || fctx->height != h ||
|
|
|
|
fctx->sw_format != av_sw_format ||
|
|
|
|
fctx->format != av_hw_format)
|
|
|
|
{
|
|
|
|
av_buffer_unref(&ctx->cached_hw_frames_ctx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ctx->cached_hw_frames_ctx) {
|
|
|
|
ctx->cached_hw_frames_ctx = av_hwframe_ctx_alloc(device_ctx);
|
|
|
|
if (!ctx->cached_hw_frames_ctx)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
AVHWFramesContext *fctx = (void *)ctx->cached_hw_frames_ctx->data;
|
|
|
|
|
|
|
|
fctx->format = av_hw_format;
|
|
|
|
fctx->sw_format = av_sw_format;
|
|
|
|
fctx->width = w;
|
|
|
|
fctx->height = h;
|
|
|
|
|
|
|
|
fctx->initial_pool_size = initial_pool_size;
|
|
|
|
|
2017-06-08 21:16:11 +02:00
|
|
|
if (ctx->hwdec->hwframes_refine)
|
|
|
|
ctx->hwdec->hwframes_refine(ctx, ctx->cached_hw_frames_ctx);
|
|
|
|
|
2017-01-17 10:56:16 +01:00
|
|
|
int res = av_hwframe_ctx_init(ctx->cached_hw_frames_ctx);
|
2017-02-16 17:00:37 +01:00
|
|
|
if (res < 0) {
|
2017-01-17 10:56:16 +01:00
|
|
|
MP_ERR(ctx, "Failed to allocate hw frames.\n");
|
|
|
|
av_buffer_unref(&ctx->cached_hw_frames_ctx);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!ctx->avctx->hw_frames_ctx);
|
|
|
|
ctx->avctx->hw_frames_ctx = av_buffer_ref(ctx->cached_hw_frames_ctx);
|
|
|
|
return ctx->avctx->hw_frames_ctx ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
2017-02-16 16:28:36 +01:00
|
|
|
static int init_generic_hwaccel(struct dec_video *vd)
|
|
|
|
{
|
|
|
|
struct lavc_ctx *ctx = vd->priv;
|
|
|
|
struct vd_lavc_hwdec *hwdec = ctx->hwdec;
|
|
|
|
|
|
|
|
if (!ctx->hwdec_dev)
|
|
|
|
return -1;
|
|
|
|
|
2017-05-03 05:23:25 +02:00
|
|
|
if (!hwdec->set_hwframes)
|
|
|
|
return 0;
|
|
|
|
|
2017-02-16 16:28:36 +01:00
|
|
|
// libavcodec has no way yet to communicate the exact surface format needed
|
|
|
|
// for the frame pool, or the required minimum size of the frame pool.
|
|
|
|
// Hopefully, this weakness in the libavcodec API will be fixed in the
|
|
|
|
// future.
|
|
|
|
// For the pixel format, we try to second-guess from what the libavcodec
|
|
|
|
// software decoder would require (sw_pix_fmt). It could break and require
|
|
|
|
// adjustment if new hwaccel surface formats are added.
|
|
|
|
enum AVPixelFormat av_sw_format = AV_PIX_FMT_NONE;
|
2017-05-03 05:23:25 +02:00
|
|
|
assert(hwdec->pixfmt_map);
|
2017-02-16 16:28:36 +01:00
|
|
|
for (int n = 0; hwdec->pixfmt_map[n][0] != AV_PIX_FMT_NONE; n++) {
|
|
|
|
if (ctx->avctx->sw_pix_fmt == hwdec->pixfmt_map[n][0]) {
|
|
|
|
av_sw_format = hwdec->pixfmt_map[n][1];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-24 15:07:45 +02:00
|
|
|
if (hwdec->image_format == IMGFMT_VIDEOTOOLBOX)
|
|
|
|
av_sw_format = imgfmt2pixfmt(vd->opts->videotoolbox_format);
|
|
|
|
|
2017-02-16 16:28:36 +01:00
|
|
|
if (av_sw_format == AV_PIX_FMT_NONE) {
|
|
|
|
MP_VERBOSE(ctx, "Unsupported hw decoding format: %s\n",
|
|
|
|
mp_imgfmt_to_name(pixfmt2imgfmt(ctx->avctx->sw_pix_fmt)));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The video output might not support all formats.
|
|
|
|
// Note that supported_formats==NULL means any are accepted.
|
|
|
|
int *render_formats = ctx->hwdec_dev->supported_formats;
|
|
|
|
if (render_formats) {
|
|
|
|
int mp_format = pixfmt2imgfmt(av_sw_format);
|
|
|
|
bool found = false;
|
|
|
|
for (int n = 0; render_formats[n]; n++) {
|
|
|
|
if (render_formats[n] == mp_format) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
MP_WARN(ctx, "Surface format %s not supported for direct rendering.\n",
|
|
|
|
mp_imgfmt_to_name(mp_format));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int pool_size = 0;
|
|
|
|
if (hwdec->static_pool)
|
|
|
|
pool_size = hwdec_get_max_refs(ctx) + HWDEC_EXTRA_SURFACES;
|
|
|
|
|
|
|
|
ctx->hwdec_fmt = hwdec->image_format;
|
|
|
|
|
2017-03-23 11:06:28 +01:00
|
|
|
if (hwdec->image_format == IMGFMT_VDPAU &&
|
|
|
|
ctx->avctx->codec_id == AV_CODEC_ID_HEVC)
|
|
|
|
{
|
|
|
|
MP_WARN(ctx, "HEVC video output may be broken due to nVidia bugs.\n");
|
|
|
|
}
|
|
|
|
|
2017-02-16 16:28:36 +01:00
|
|
|
return hwdec_setup_hw_frames_ctx(ctx, ctx->hwdec_dev->av_device_ref,
|
|
|
|
av_sw_format, pool_size);
|
|
|
|
}
|
|
|
|
|
2013-11-29 17:39:57 +01:00
|
|
|
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
|
|
|
|
const enum AVPixelFormat *fmt)
|
2012-11-06 15:27:44 +01:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
struct dec_video *vd = avctx->opaque;
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2012-11-06 15:27:44 +01:00
|
|
|
|
2013-12-21 17:47:38 +01:00
|
|
|
MP_VERBOSE(vd, "Pixel formats supported by decoder:");
|
2013-11-29 17:39:57 +01:00
|
|
|
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
|
2013-12-21 17:47:38 +01:00
|
|
|
MP_VERBOSE(vd, " %s", av_get_pix_fmt_name(fmt[i]));
|
|
|
|
MP_VERBOSE(vd, "\n");
|
2012-12-11 18:16:42 +01:00
|
|
|
|
2016-01-08 09:13:56 +01:00
|
|
|
const char *profile = avcodec_profile_name(avctx->codec_id, avctx->profile);
|
|
|
|
MP_VERBOSE(vd, "Codec profile: %s (0x%x)\n", profile ? profile : "unknown",
|
|
|
|
avctx->profile);
|
|
|
|
|
2013-08-11 23:23:12 +02:00
|
|
|
assert(ctx->hwdec);
|
2012-12-11 18:16:42 +01:00
|
|
|
|
2015-10-12 21:24:25 +02:00
|
|
|
ctx->hwdec_request_reinit |= ctx->hwdec_failed;
|
|
|
|
ctx->hwdec_failed = false;
|
|
|
|
|
2017-03-01 16:02:08 +01:00
|
|
|
enum AVPixelFormat select = AV_PIX_FMT_NONE;
|
2016-04-25 12:12:40 +02:00
|
|
|
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) {
|
|
|
|
if (ctx->hwdec->image_format == pixfmt2imgfmt(fmt[i])) {
|
2017-02-16 16:28:36 +01:00
|
|
|
if (ctx->hwdec->generic_hwaccel) {
|
|
|
|
if (init_generic_hwaccel(vd) < 0)
|
|
|
|
break;
|
2017-03-01 16:02:08 +01:00
|
|
|
select = fmt[i];
|
|
|
|
break;
|
2017-02-16 16:28:36 +01:00
|
|
|
}
|
2016-04-25 12:12:40 +02:00
|
|
|
// There could be more reasons for a change, and it's possible
|
|
|
|
// that we miss some. (Might also depend on the hwaccel type.)
|
|
|
|
bool change =
|
|
|
|
ctx->hwdec_w != avctx->coded_width ||
|
|
|
|
ctx->hwdec_h != avctx->coded_height ||
|
|
|
|
ctx->hwdec_fmt != ctx->hwdec->image_format ||
|
|
|
|
ctx->hwdec_profile != avctx->profile ||
|
2017-01-11 16:27:58 +01:00
|
|
|
ctx->hwdec_request_reinit ||
|
|
|
|
ctx->hwdec->volatile_context;
|
2016-04-25 12:12:40 +02:00
|
|
|
ctx->hwdec_w = avctx->coded_width;
|
|
|
|
ctx->hwdec_h = avctx->coded_height;
|
|
|
|
ctx->hwdec_fmt = ctx->hwdec->image_format;
|
|
|
|
ctx->hwdec_profile = avctx->profile;
|
|
|
|
ctx->hwdec_request_reinit = false;
|
|
|
|
if (change && ctx->hwdec->init_decoder) {
|
|
|
|
if (ctx->hwdec->init_decoder(ctx, ctx->hwdec_w, ctx->hwdec_h) < 0)
|
|
|
|
{
|
|
|
|
ctx->hwdec_fmt = 0;
|
|
|
|
break;
|
2014-03-10 22:36:23 +01:00
|
|
|
}
|
|
|
|
}
|
2017-03-01 16:02:08 +01:00
|
|
|
select = fmt[i];
|
|
|
|
break;
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-28 01:49:45 +02:00
|
|
|
}
|
2012-11-06 15:27:44 +01:00
|
|
|
}
|
2012-12-11 18:16:42 +01:00
|
|
|
|
2017-03-01 16:02:08 +01:00
|
|
|
if (select == AV_PIX_FMT_NONE) {
|
|
|
|
ctx->hwdec_failed = true;
|
|
|
|
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) {
|
|
|
|
const AVPixFmtDescriptor *d = av_pix_fmt_desc_get(fmt[i]);
|
|
|
|
if (d && !(d->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
|
|
|
|
select = fmt[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-05-29 14:17:51 +02:00
|
|
|
}
|
2017-03-01 16:02:08 +01:00
|
|
|
|
|
|
|
const char *name = av_get_pix_fmt_name(select);
|
|
|
|
MP_VERBOSE(vd, "Requesting pixfmt '%s' from decoder.\n", name ? name : "-");
|
|
|
|
return select;
|
2012-11-06 15:27:44 +01:00
|
|
|
}
|
|
|
|
|
2015-05-28 21:53:37 +02:00
|
|
|
static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags)
|
|
|
|
{
|
|
|
|
struct dec_video *vd = avctx->opaque;
|
2013-11-23 21:36:20 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2012-11-06 15:27:44 +01:00
|
|
|
|
2012-12-20 13:28:39 +01:00
|
|
|
int imgfmt = pixfmt2imgfmt(pic->format);
|
2016-02-20 11:56:31 +01:00
|
|
|
if (!ctx->hwdec || ctx->hwdec_fmt != imgfmt)
|
2015-09-23 14:01:45 +02:00
|
|
|
ctx->hwdec_failed = true;
|
|
|
|
|
|
|
|
/* Hardware decoding failed, and we will trigger a proper fallback later
|
|
|
|
* when returning from the decode call. (We are forcing complete
|
|
|
|
* reinitialization later to reset the thread count properly.)
|
|
|
|
*/
|
|
|
|
if (ctx->hwdec_failed)
|
|
|
|
return avcodec_default_get_buffer2(avctx, pic, flags);
|
2012-11-06 15:27:44 +01:00
|
|
|
|
2015-05-28 21:55:16 +02:00
|
|
|
// We expect it to use the exact size used to create the hw decoder in
|
|
|
|
// get_format_hwdec(). For cropped video, this is expected to be the
|
|
|
|
// uncropped size (usually coded_width/coded_height).
|
|
|
|
int w = pic->width;
|
|
|
|
int h = pic->height;
|
2013-08-15 18:20:15 +02:00
|
|
|
|
2015-08-19 21:33:18 +02:00
|
|
|
if (imgfmt != ctx->hwdec_fmt && w != ctx->hwdec_w && h != ctx->hwdec_h)
|
2017-01-11 08:26:32 +01:00
|
|
|
return AVERROR(EINVAL);
|
2014-03-10 22:36:23 +01:00
|
|
|
|
2015-08-19 21:33:18 +02:00
|
|
|
struct mp_image *mpi = ctx->hwdec->allocate_image(ctx, w, h);
|
2013-03-09 20:50:06 +01:00
|
|
|
if (!mpi)
|
2017-01-11 08:26:32 +01:00
|
|
|
return AVERROR(ENOMEM);
|
2013-03-09 20:50:06 +01:00
|
|
|
|
video: replace our own refcounting with libavutil's
mpv had refcounted frames before libav*, so we were not using
libavutil's facilities. Change this and drop our own code.
Since AVFrames are not actually refcounted, and only the image data
they reference, the semantics change a bit. This affects mainly
mp_image_pool, which was operating on whole images instead of buffers.
While we could work on AVBufferRefs instead (and use AVBufferPool),
this doesn't work for use with hardware decoding, which doesn't
map cleanly to FFmpeg's reference counting. But it worked out. One
weird consequence is that we still need our custom image data
allocation function (for normal image data), because AVFrame's uses
multiple buffers.
There also seems to be a timing-dependent problem with vaapi (the
pool appears to be "leaking" surfaces). I don't know if this is a new
problem, or whether the code changes just happened to cause it more
often. Raising the number of reserved surfaces seemed to fix it, but
since it appears to be timing dependent, and I couldn't find anything
wrong with the code, I'm just going to assume it's not a new bug.
2015-07-05 23:56:00 +02:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2015-05-28 21:53:37 +02:00
|
|
|
pic->data[i] = mpi->planes[i];
|
video: replace our own refcounting with libavutil's
mpv had refcounted frames before libav*, so we were not using
libavutil's facilities. Change this and drop our own code.
Since AVFrames are not actually refcounted, and only the image data
they reference, the semantics change a bit. This affects mainly
mp_image_pool, which was operating on whole images instead of buffers.
While we could work on AVBufferRefs instead (and use AVBufferPool),
this doesn't work for use with hardware decoding, which doesn't
map cleanly to FFmpeg's reference counting. But it worked out. One
weird consequence is that we still need our custom image data
allocation function (for normal image data), because AVFrame's uses
multiple buffers.
There also seems to be a timing-dependent problem with vaapi (the
pool appears to be "leaking" surfaces). I don't know if this is a new
problem, or whether the code changes just happened to cause it more
often. Raising the number of reserved surfaces seemed to fix it, but
since it appears to be timing dependent, and I couldn't find anything
wrong with the code, I'm just going to assume it's not a new bug.
2015-07-05 23:56:00 +02:00
|
|
|
pic->buf[i] = mpi->bufs[i];
|
|
|
|
mpi->bufs[i] = NULL;
|
|
|
|
}
|
|
|
|
talloc_free(mpi);
|
2013-03-09 20:50:06 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
static bool prepare_decoding(struct dec_video *vd)
|
2009-11-21 19:53:10 +01:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2002-07-14 21:44:40 +02:00
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2015-11-03 14:03:02 +01:00
|
|
|
struct vd_lavc_params *opts = ctx->opts->vd_lavc_params;
|
2002-07-14 21:44:40 +02:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
if (!avctx || ctx->hwdec_failed)
|
|
|
|
return false;
|
2015-12-05 23:53:55 +01:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
int drop = ctx->framedrop_flags;
|
|
|
|
if (drop) {
|
2014-08-09 00:35:25 +02:00
|
|
|
// hr-seek framedrop vs. normal framedrop
|
2017-01-10 16:19:57 +01:00
|
|
|
avctx->skip_frame = drop == 2 ? AVDISCARD_NONREF : opts->framedrop;
|
2014-08-09 00:35:25 +02:00
|
|
|
} else {
|
|
|
|
// normal playback
|
2011-07-09 12:50:16 +02:00
|
|
|
avctx->skip_frame = ctx->skip_frame;
|
2014-08-09 00:35:25 +02:00
|
|
|
}
|
2002-07-14 21:44:40 +02:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
if (ctx->hwdec_request_reinit)
|
2015-11-10 16:06:42 +01:00
|
|
|
reset_avctx(vd);
|
2013-06-03 01:55:48 +02:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_err(struct dec_video *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
struct vd_lavc_params *opts = ctx->opts->vd_lavc_params;
|
|
|
|
|
|
|
|
MP_WARN(vd, "Error while decoding frame!\n");
|
|
|
|
|
|
|
|
if (ctx->hwdec) {
|
|
|
|
ctx->hwdec_fail_count += 1;
|
|
|
|
// The FFmpeg VT hwaccel is buggy and can crash after 1 broken frame.
|
2017-03-07 12:20:04 +01:00
|
|
|
bool force = false;
|
|
|
|
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 82, 101)
|
|
|
|
force |= ctx->hwdec && ctx->hwdec->type == HWDEC_VIDEOTOOLBOX;
|
|
|
|
#endif
|
|
|
|
if (ctx->hwdec_fail_count >= opts->software_fallback || force)
|
2017-01-10 16:19:57 +01:00
|
|
|
ctx->hwdec_failed = true;
|
2016-03-24 17:53:30 +01:00
|
|
|
}
|
2017-01-10 16:19:57 +01:00
|
|
|
}
|
|
|
|
|
2017-01-10 16:49:06 +01:00
|
|
|
static bool do_send_packet(struct dec_video *vd, struct demux_packet *pkt)
|
2017-01-10 16:19:57 +01:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
|
|
|
|
|
|
|
if (!prepare_decoding(vd))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
AVPacket avpkt;
|
|
|
|
mp_set_av_packet(&avpkt, pkt, &ctx->codec_timebase);
|
|
|
|
|
|
|
|
int ret = avcodec_send_packet(avctx, pkt ? &avpkt : NULL);
|
|
|
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
|
|
return false;
|
2015-11-10 16:06:42 +01:00
|
|
|
|
2017-01-10 16:49:06 +01:00
|
|
|
if (ctx->hw_probing && ctx->num_sent_packets < 32) {
|
|
|
|
pkt = pkt ? demux_copy_packet(pkt) : NULL;
|
|
|
|
MP_TARRAY_APPEND(ctx, ctx->sent_packets, ctx->num_sent_packets, pkt);
|
|
|
|
}
|
2003-04-07 01:37:56 +02:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
if (ret < 0)
|
|
|
|
handle_err(vd);
|
|
|
|
return true;
|
|
|
|
}
|
2015-10-19 17:49:30 +02:00
|
|
|
|
2017-01-10 16:49:06 +01:00
|
|
|
static bool send_packet(struct dec_video *vd, struct demux_packet *pkt)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
if (ctx->num_requeue_packets) {
|
2017-01-11 08:27:46 +01:00
|
|
|
if (do_send_packet(vd, ctx->requeue_packets[0])) {
|
|
|
|
talloc_free(ctx->requeue_packets[0]);
|
2017-01-10 16:49:06 +01:00
|
|
|
MP_TARRAY_REMOVE_AT(ctx->requeue_packets, ctx->num_requeue_packets, 0);
|
2017-01-11 08:27:46 +01:00
|
|
|
}
|
2017-01-10 16:49:06 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return do_send_packet(vd, pkt);
|
|
|
|
}
|
|
|
|
|
2017-01-11 10:56:25 +01:00
|
|
|
// Returns whether decoder is still active (!EOF state).
|
2017-01-10 16:19:57 +01:00
|
|
|
static bool decode_frame(struct dec_video *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2016-02-19 18:35:11 +01:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
if (!prepare_decoding(vd))
|
2017-01-11 10:56:25 +01:00
|
|
|
return true;
|
2017-01-10 16:19:57 +01:00
|
|
|
|
|
|
|
int ret = avcodec_receive_frame(avctx, ctx->pic);
|
|
|
|
if (ret == AVERROR_EOF) {
|
|
|
|
// If flushing was initialized earlier and has ended now, make it start
|
|
|
|
// over in case we get new packets at some point in the future.
|
|
|
|
reset_avctx(vd);
|
2017-01-11 10:56:25 +01:00
|
|
|
return false;
|
2017-01-10 16:19:57 +01:00
|
|
|
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
|
|
|
|
handle_err(vd);
|
2016-01-25 21:00:53 +01:00
|
|
|
}
|
2015-10-19 18:19:57 +02:00
|
|
|
|
2017-01-10 16:19:57 +01:00
|
|
|
if (!ctx->pic->buf[0])
|
2017-01-11 10:56:25 +01:00
|
|
|
return true;
|
2017-01-10 16:19:57 +01:00
|
|
|
|
2015-11-03 14:03:02 +01:00
|
|
|
ctx->hwdec_fail_count = 0;
|
|
|
|
|
2015-12-22 02:35:15 +01:00
|
|
|
AVFrameSideData *sd = NULL;
|
|
|
|
sd = av_frame_get_side_data(ctx->pic, AV_FRAME_DATA_A53_CC);
|
|
|
|
if (sd) {
|
|
|
|
struct demux_packet *cc = new_demux_packet_from(sd->data, sd->size);
|
|
|
|
cc->pts = vd->codec_pts;
|
|
|
|
cc->dts = vd->codec_dts;
|
|
|
|
demuxer_feed_caption(vd->header, cc);
|
|
|
|
}
|
|
|
|
|
2014-03-16 09:21:21 +01:00
|
|
|
struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
|
2016-01-25 20:47:13 +01:00
|
|
|
if (!mpi) {
|
|
|
|
av_frame_unref(ctx->pic);
|
2017-01-11 10:56:25 +01:00
|
|
|
return true;
|
2016-01-25 20:47:13 +01:00
|
|
|
}
|
2014-03-23 19:20:43 +01:00
|
|
|
assert(mpi->planes[0] || mpi->planes[3]);
|
2016-12-07 19:44:29 +01:00
|
|
|
mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
|
2016-03-24 16:38:14 +01:00
|
|
|
mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase);
|
2016-01-25 20:47:13 +01:00
|
|
|
|
2016-12-21 18:18:24 +01:00
|
|
|
#if LIBAVCODEC_VERSION_MICRO >= 100
|
|
|
|
mpi->pkt_duration =
|
|
|
|
mp_pts_from_av(av_frame_get_pkt_duration(ctx->pic), &ctx->codec_timebase);
|
|
|
|
#endif
|
|
|
|
|
2017-01-12 11:54:53 +01:00
|
|
|
update_image_params(vd, ctx->pic, &mpi->params);
|
2002-03-06 21:54:43 +01:00
|
|
|
|
2016-01-25 20:47:13 +01:00
|
|
|
av_frame_unref(ctx->pic);
|
|
|
|
|
2016-01-25 21:00:53 +01:00
|
|
|
MP_TARRAY_APPEND(ctx, ctx->delay_queue, ctx->num_delay_queue, mpi);
|
2017-01-11 10:56:25 +01:00
|
|
|
return true;
|
2012-12-11 18:16:42 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 10:56:25 +01:00
|
|
|
static bool receive_frame(struct dec_video *vd, struct mp_image **out_image)
|
2013-12-10 19:07:29 +01:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
2017-01-11 10:58:30 +01:00
|
|
|
assert(!*out_image);
|
|
|
|
|
2017-01-11 10:56:25 +01:00
|
|
|
bool progress = decode_frame(vd);
|
2017-01-10 16:19:57 +01:00
|
|
|
|
2015-09-23 20:37:47 +02:00
|
|
|
if (ctx->hwdec_failed) {
|
2013-12-10 19:07:29 +01:00
|
|
|
// Failed hardware decoding? Try again in software.
|
2017-01-10 16:49:06 +01:00
|
|
|
struct demux_packet **pkts = ctx->sent_packets;
|
|
|
|
int num_pkts = ctx->num_sent_packets;
|
|
|
|
ctx->sent_packets = NULL;
|
|
|
|
ctx->num_sent_packets = 0;
|
2017-01-10 16:19:57 +01:00
|
|
|
|
2016-04-22 15:45:23 +02:00
|
|
|
force_fallback(vd);
|
2012-12-11 18:16:42 +01:00
|
|
|
|
2017-01-10 16:49:06 +01:00
|
|
|
ctx->requeue_packets = pkts;
|
|
|
|
ctx->num_requeue_packets = num_pkts;
|
2015-09-02 23:31:01 +02:00
|
|
|
}
|
|
|
|
|
2017-01-11 10:58:30 +01:00
|
|
|
if (!ctx->num_delay_queue)
|
|
|
|
return progress;
|
|
|
|
|
|
|
|
if (ctx->num_delay_queue <= ctx->max_delay_queue && progress)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
struct mp_image *res = ctx->delay_queue[0];
|
|
|
|
MP_TARRAY_REMOVE_AT(ctx->delay_queue, ctx->num_delay_queue, 0);
|
|
|
|
|
|
|
|
if (ctx->hwdec && ctx->hwdec->process_image)
|
|
|
|
res = ctx->hwdec->process_image(ctx, res);
|
|
|
|
|
|
|
|
res = res ? mp_img_swap_to_native(res) : NULL;
|
|
|
|
if (!res)
|
|
|
|
return progress;
|
|
|
|
|
2017-01-12 13:15:45 +01:00
|
|
|
if (ctx->hwdec && ctx->hwdec->copying && (res->fmt.flags & MP_IMGFLAG_HWACCEL))
|
|
|
|
{
|
|
|
|
struct mp_image *sw = mp_image_hw_download(res, ctx->hwdec_swpool);
|
|
|
|
mp_image_unrefp(&res);
|
|
|
|
res = sw;
|
|
|
|
if (!res) {
|
|
|
|
MP_ERR(vd, "Could not copy back hardware decoded frame.\n");
|
2017-01-17 11:03:42 +01:00
|
|
|
ctx->hwdec_fail_count = INT_MAX - 1; // force fallback
|
2017-01-12 13:15:45 +01:00
|
|
|
handle_err(vd);
|
2017-04-07 12:24:26 +02:00
|
|
|
return false;
|
2017-01-12 13:15:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-11 10:58:30 +01:00
|
|
|
if (!ctx->hwdec_notified && vd->opts->hwdec_api != HWDEC_NONE) {
|
|
|
|
if (ctx->hwdec) {
|
|
|
|
MP_INFO(vd, "Using hardware decoding (%s).\n",
|
|
|
|
m_opt_choice_str(mp_hwdec_names, ctx->hwdec->type));
|
|
|
|
} else {
|
2017-01-13 18:52:07 +01:00
|
|
|
MP_VERBOSE(vd, "Using software decoding.\n");
|
2017-01-11 10:58:30 +01:00
|
|
|
}
|
|
|
|
ctx->hwdec_notified = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx->hw_probing) {
|
|
|
|
for (int n = 0; n < ctx->num_sent_packets; n++)
|
|
|
|
talloc_free(ctx->sent_packets[n]);
|
|
|
|
ctx->num_sent_packets = 0;
|
|
|
|
ctx->hw_probing = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_image = res;
|
|
|
|
return true;
|
2002-03-06 21:54:43 +01:00
|
|
|
}
|
|
|
|
|
2013-11-23 21:36:20 +01:00
|
|
|
static int control(struct dec_video *vd, int cmd, void *arg)
|
2011-11-14 19:12:20 +01:00
|
|
|
{
|
2013-11-23 21:36:20 +01:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2011-11-14 19:12:20 +01:00
|
|
|
switch (cmd) {
|
2013-11-27 20:54:07 +01:00
|
|
|
case VDCTRL_RESET:
|
2016-01-25 21:00:53 +01:00
|
|
|
flush_all(vd);
|
2011-11-14 19:12:20 +01:00
|
|
|
return CONTROL_TRUE;
|
2017-01-10 16:19:57 +01:00
|
|
|
case VDCTRL_SET_FRAMEDROP:
|
|
|
|
ctx->framedrop_flags = *(int *)arg;
|
|
|
|
return CONTROL_TRUE;
|
video: approximate AVI timestamps via DTS handling
Until now (and in mplayer traditionally), avi timestamps were handled
with a timestamp FIFO. AVI timestamps are essentially just strictly
increasing frame numbers and are not reordered like normal timestamps.
Limiting the FIFO is required because frames can be dropped. To make
it worse, frame dropping can't be distinguished from the decoder not
returning output due to increasing the buffering required for B-frames.
("Measuring" the buffering at playback start seems like an interesting
idea, but won't work as the buffering could be increased mid-playback.)
Another problem are skipped frames (packets with data, but which do
not contain a video frame).
Besides dropped and skipped frames, there is the problem that we can't
always know the delay. External decoders like MMAL are not going to
tell us. (And later perhaps others, like direct VideoToolbox usage.)
In general, this works not-well enough that I prefer the solution of
passing through AVI timestamps as DTS. This is slightly incorrect,
because most decoders treat DTS as mpeg-style timestamps, which
already include a b-frame delay, and thus will be shifted by a few
frames. This means there will be a problem with A/V sync in some
situations.
Note that the FFmpeg AVI demuxer shifts timestamps by an additional
amount (which increases after the first seek!?!?), which makes the
situation worse. It works well with VfW-muxed Matroska files, though.
On RPI, the first X timestamps are broken until the MMAL decoder "locks
on".
2016-02-11 16:01:11 +01:00
|
|
|
case VDCTRL_GET_BFRAMES: {
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 14:38:47 +01:00
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2015-12-05 23:53:55 +01:00
|
|
|
if (!avctx)
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 14:38:47 +01:00
|
|
|
break;
|
|
|
|
if (ctx->hwdec && ctx->hwdec->type == HWDEC_RPI)
|
|
|
|
break; // MMAL has arbitrary buffering, thus unknown
|
video: approximate AVI timestamps via DTS handling
Until now (and in mplayer traditionally), avi timestamps were handled
with a timestamp FIFO. AVI timestamps are essentially just strictly
increasing frame numbers and are not reordered like normal timestamps.
Limiting the FIFO is required because frames can be dropped. To make
it worse, frame dropping can't be distinguished from the decoder not
returning output due to increasing the buffering required for B-frames.
("Measuring" the buffering at playback start seems like an interesting
idea, but won't work as the buffering could be increased mid-playback.)
Another problem are skipped frames (packets with data, but which do
not contain a video frame).
Besides dropped and skipped frames, there is the problem that we can't
always know the delay. External decoders like MMAL are not going to
tell us. (And later perhaps others, like direct VideoToolbox usage.)
In general, this works not-well enough that I prefer the solution of
passing through AVI timestamps as DTS. This is slightly incorrect,
because most decoders treat DTS as mpeg-style timestamps, which
already include a b-frame delay, and thus will be shifted by a few
frames. This means there will be a problem with A/V sync in some
situations.
Note that the FFmpeg AVI demuxer shifts timestamps by an additional
amount (which increases after the first seek!?!?), which makes the
situation worse. It works well with VfW-muxed Matroska files, though.
On RPI, the first X timestamps are broken until the MMAL decoder "locks
on".
2016-02-11 16:01:11 +01:00
|
|
|
*(int *)arg = avctx->has_b_frames;
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 14:38:47 +01:00
|
|
|
return CONTROL_TRUE;
|
|
|
|
}
|
2014-04-23 01:17:28 +02:00
|
|
|
case VDCTRL_GET_HWDEC: {
|
2016-01-29 22:46:46 +01:00
|
|
|
*(int *)arg = ctx->hwdec ? ctx->hwdec->type : 0;
|
2014-04-23 01:17:28 +02:00
|
|
|
return CONTROL_TRUE;
|
|
|
|
}
|
2013-12-10 19:07:29 +01:00
|
|
|
case VDCTRL_FORCE_HWDEC_FALLBACK:
|
2016-04-22 15:45:23 +02:00
|
|
|
if (ctx->hwdec) {
|
|
|
|
force_fallback(vd);
|
2015-09-02 23:10:39 +02:00
|
|
|
return ctx->avctx ? CONTROL_OK : CONTROL_ERROR;
|
2016-04-22 15:45:23 +02:00
|
|
|
}
|
2015-09-02 23:10:39 +02:00
|
|
|
return CONTROL_FALSE;
|
2016-01-29 22:47:27 +01:00
|
|
|
case VDCTRL_REINIT:
|
|
|
|
reinit(vd);
|
|
|
|
return CONTROL_TRUE;
|
2011-11-14 19:12:20 +01:00
|
|
|
}
|
|
|
|
return CONTROL_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 15:15:19 +01:00
|
|
|
static void add_decoders(struct mp_decoder_list *list)
|
|
|
|
{
|
|
|
|
mp_add_lavc_decoders(list, AVMEDIA_TYPE_VIDEO);
|
|
|
|
}
|
|
|
|
|
2009-11-21 19:53:10 +01:00
|
|
|
const struct vd_functions mpcodecs_vd_ffmpeg = {
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 15:15:19 +01:00
|
|
|
.name = "lavc",
|
|
|
|
.add_decoders = add_decoders,
|
2009-11-21 19:53:10 +01:00
|
|
|
.init = init,
|
|
|
|
.uninit = uninit,
|
|
|
|
.control = control,
|
2017-01-10 16:19:57 +01:00
|
|
|
.send_packet = send_packet,
|
|
|
|
.receive_frame = receive_frame,
|
2009-11-21 19:53:10 +01:00
|
|
|
};
|