mirror of https://github.com/mpv-player/mpv
vdpau: add support for the "new" libavcodec vdpau API
Yet another of these dozens of hwaccel changes. This time, libavcodec provides utility functions, which initialize the vdpau decoder and map codec profiles. So a lot of work the API user had to do falls away. This also will give us support for high bit depth profiles, and possibly HEVC once libavcodec supports it.
This commit is contained in:
parent
0699a6c598
commit
6f5a10542c
|
@ -79,7 +79,7 @@ SOURCES-$(PULSE) += audio/out/ao_pulse.c
|
||||||
SOURCES-$(RSOUND) += audio/out/ao_rsound.c
|
SOURCES-$(RSOUND) += audio/out/ao_rsound.c
|
||||||
SOURCES-$(SNDIO) += audio/out/ao_sndio.c
|
SOURCES-$(SNDIO) += audio/out/ao_sndio.c
|
||||||
SOURCES-$(VDPAU) += video/vdpau.c video/vdpau_mixer.c \
|
SOURCES-$(VDPAU) += video/vdpau.c video/vdpau_mixer.c \
|
||||||
video/out/vo_vdpau.c video/decode/vdpau_old.c \
|
video/out/vo_vdpau.c video/decode/vdpau.c \
|
||||||
video/filter/vf_vdpaupp.c
|
video/filter/vf_vdpaupp.c
|
||||||
SOURCES-$(VDPAU_GL_X11) += video/out/gl_hwdec_vdpau.c
|
SOURCES-$(VDPAU_GL_X11) += video/out/gl_hwdec_vdpau.c
|
||||||
SOURCES-$(VAAPI) += video/out/vo_vaapi.c \
|
SOURCES-$(VAAPI) += video/out/vo_vaapi.c \
|
||||||
|
|
|
@ -31,6 +31,8 @@ typedef struct lavc_ctx {
|
||||||
int hwdec_w;
|
int hwdec_w;
|
||||||
int hwdec_h;
|
int hwdec_h;
|
||||||
int hwdec_profile;
|
int hwdec_profile;
|
||||||
|
|
||||||
|
bool hwdec_request_reinit;
|
||||||
} vd_ffmpeg_ctx;
|
} vd_ffmpeg_ctx;
|
||||||
|
|
||||||
struct vd_lavc_hwdec {
|
struct vd_lavc_hwdec {
|
||||||
|
|
|
@ -517,11 +517,13 @@ static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
|
||||||
ctx->hwdec_w != avctx->coded_width ||
|
ctx->hwdec_w != avctx->coded_width ||
|
||||||
ctx->hwdec_h != avctx->coded_height ||
|
ctx->hwdec_h != avctx->coded_height ||
|
||||||
ctx->hwdec_fmt != ctx->hwdec->image_format ||
|
ctx->hwdec_fmt != ctx->hwdec->image_format ||
|
||||||
ctx->hwdec_profile != avctx->profile;
|
ctx->hwdec_profile != avctx->profile ||
|
||||||
|
ctx->hwdec_request_reinit;
|
||||||
ctx->hwdec_w = avctx->coded_width;
|
ctx->hwdec_w = avctx->coded_width;
|
||||||
ctx->hwdec_h = avctx->coded_height;
|
ctx->hwdec_h = avctx->coded_height;
|
||||||
ctx->hwdec_fmt = ctx->hwdec->image_format;
|
ctx->hwdec_fmt = ctx->hwdec->image_format;
|
||||||
ctx->hwdec_profile = avctx->profile;
|
ctx->hwdec_profile = avctx->profile;
|
||||||
|
ctx->hwdec_request_reinit = false;
|
||||||
if (ctx->hwdec->init_decoder && change) {
|
if (ctx->hwdec->init_decoder && change) {
|
||||||
if (ctx->hwdec->init_decoder(ctx, ctx->hwdec_fmt,
|
if (ctx->hwdec->init_decoder(ctx, ctx->hwdec_fmt,
|
||||||
ctx->hwdec_w, ctx->hwdec_h) < 0)
|
ctx->hwdec_w, ctx->hwdec_h) < 0)
|
||||||
|
@ -620,6 +622,9 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->hwdec_request_reinit)
|
||||||
|
avcodec_flush_buffers(avctx);
|
||||||
|
|
||||||
// Skipped frame, or delayed output due to multithreaded decoding.
|
// Skipped frame, or delayed output due to multithreaded decoding.
|
||||||
if (!got_picture)
|
if (!got_picture)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* This file is part of mpv.
|
||||||
|
*
|
||||||
|
* mpv is free software; you can redistribute it and/or modify
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* mpv is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavcodec/vdpau.h>
|
||||||
|
#include <libavutil/common.h>
|
||||||
|
|
||||||
|
#include "lavc.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "video/vdpau.h"
|
||||||
|
#include "video/hwdec.h"
|
||||||
|
|
||||||
|
struct priv {
|
||||||
|
struct mp_log *log;
|
||||||
|
struct mp_vdpau_ctx *mpvdp;
|
||||||
|
uint64_t preemption_counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h)
|
||||||
|
{
|
||||||
|
struct priv *p = ctx->hwdec_priv;
|
||||||
|
|
||||||
|
// During preemption, pretend everything is ok.
|
||||||
|
if (mp_vdpau_handle_preemption(p->mpvdp, &p->preemption_counter) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return av_vdpau_bind_context(ctx->avctx, p->mpvdp->vdp_device,
|
||||||
|
p->mpvdp->get_proc_address,
|
||||||
|
AV_HWACCEL_FLAG_IGNORE_LEVEL |
|
||||||
|
AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mp_image *allocate_image(struct lavc_ctx *ctx, int fmt,
|
||||||
|
int w, int h)
|
||||||
|
{
|
||||||
|
struct priv *p = ctx->hwdec_priv;
|
||||||
|
|
||||||
|
// In case of preemption, reinit the decoder. Setting hwdec_request_reinit
|
||||||
|
// will cause init_decoder() to be called again.
|
||||||
|
if (mp_vdpau_handle_preemption(p->mpvdp, &p->preemption_counter) == 0)
|
||||||
|
ctx->hwdec_request_reinit = true;
|
||||||
|
|
||||||
|
VdpChromaType chroma = 0;
|
||||||
|
uint32_t s_w = w, s_h = h;
|
||||||
|
if (av_vdpau_get_surface_parameters(ctx->avctx, &chroma, &s_w, &s_h) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return mp_vdpau_get_video_surface(p->mpvdp, chroma, s_w, s_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uninit(struct lavc_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct priv *p = ctx->hwdec_priv;
|
||||||
|
|
||||||
|
talloc_free(p);
|
||||||
|
|
||||||
|
av_freep(&ctx->avctx->hwaccel_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init(struct lavc_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct priv *p = talloc_ptrtype(NULL, p);
|
||||||
|
*p = (struct priv) {
|
||||||
|
.log = mp_log_new(p, ctx->log, "vdpau"),
|
||||||
|
.mpvdp = ctx->hwdec_info->hwctx->vdpau_ctx,
|
||||||
|
};
|
||||||
|
ctx->hwdec_priv = p;
|
||||||
|
|
||||||
|
if (mp_vdpau_handle_preemption(p->mpvdp, &p->preemption_counter) < 1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
uninit(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
||||||
|
const char *decoder)
|
||||||
|
{
|
||||||
|
hwdec_request_api(info, "vdpau");
|
||||||
|
if (!info || !info->hwctx || !info->hwctx->vdpau_ctx)
|
||||||
|
return HWDEC_ERR_NO_CTX;
|
||||||
|
if (mp_vdpau_guess_if_emulated(info->hwctx->vdpau_ctx))
|
||||||
|
return HWDEC_ERR_EMULATED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct vd_lavc_hwdec mp_vd_lavc_vdpau = {
|
||||||
|
.type = HWDEC_VDPAU,
|
||||||
|
.image_format = IMGFMT_VDPAU,
|
||||||
|
.probe = probe,
|
||||||
|
.init = init,
|
||||||
|
.uninit = uninit,
|
||||||
|
.init_decoder = init_decoder,
|
||||||
|
.allocate_image = allocate_image,
|
||||||
|
};
|
8
wscript
8
wscript
|
@ -718,6 +718,14 @@ hwaccel_features = [
|
||||||
'name': '--vdpau-hwaccel',
|
'name': '--vdpau-hwaccel',
|
||||||
'desc': 'libavcodec VDPAU hwaccel',
|
'desc': 'libavcodec VDPAU hwaccel',
|
||||||
'deps': [ 'vdpau' ],
|
'deps': [ 'vdpau' ],
|
||||||
|
'func': check_statement('libavcodec/vdpau.h',
|
||||||
|
'av_vdpau_bind_context(0,0,0,AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH)',
|
||||||
|
use='libav'),
|
||||||
|
}, {
|
||||||
|
'name': '--vdpau-old-hwaccel',
|
||||||
|
'desc': 'libavcodec VDPAU hwaccel (old API)',
|
||||||
|
'deps': [ 'vdpau' ],
|
||||||
|
'deps_neg': [ 'vdpau-hwaccel' ],
|
||||||
'func': check_statement('libavcodec/vdpau.h',
|
'func': check_statement('libavcodec/vdpau.h',
|
||||||
'av_vdpau_alloc_context()',
|
'av_vdpau_alloc_context()',
|
||||||
use='libav'),
|
use='libav'),
|
||||||
|
|
|
@ -296,7 +296,8 @@ def build(ctx):
|
||||||
( "video/decode/vaapi.c", "vaapi-hwaccel" ),
|
( "video/decode/vaapi.c", "vaapi-hwaccel" ),
|
||||||
( "video/decode/vd_lavc.c" ),
|
( "video/decode/vd_lavc.c" ),
|
||||||
( "video/decode/vda.c", "vda-hwaccel" ),
|
( "video/decode/vda.c", "vda-hwaccel" ),
|
||||||
( "video/decode/vdpau_old.c", "vdpau-hwaccel" ),
|
( "video/decode/vdpau.c", "vdpau-hwaccel" ),
|
||||||
|
( "video/decode/vdpau_old.c", "vdpau-old-hwaccel" ),
|
||||||
( "video/filter/vf.c" ),
|
( "video/filter/vf.c" ),
|
||||||
( "video/filter/vf_buffer.c" ),
|
( "video/filter/vf_buffer.c" ),
|
||||||
( "video/filter/vf_crop.c" ),
|
( "video/filter/vf_crop.c" ),
|
||||||
|
|
Loading…
Reference in New Issue