diff --git a/ffmpeg.h b/ffmpeg.h index 56eb66a6e8..c45660309e 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -490,6 +490,7 @@ extern int stdin_interaction; extern int frame_bits_per_raw_sample; extern AVIOContext *progress_avio; extern float max_error_rate; +extern int vdpau_api_ver; extern const AVIOInterruptCB int_cb; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 4fb6fa36b1..10aaa3a6af 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -2984,6 +2984,9 @@ const OptionDef options[] = { { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) }, "select a device for HW acceleration" "devicename" }, +#if HAVE_VDPAU_X11 + { "vdpau_api_ver", HAS_ARG | OPT_INT | OPT_EXPERT, { &vdpau_api_ver }, "" }, +#endif /* audio options */ { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames }, diff --git a/ffmpeg_vdpau.c b/ffmpeg_vdpau.c index fe0930695e..ef35d22ae8 100644 --- a/ffmpeg_vdpau.c +++ b/ffmpeg_vdpau.c @@ -57,6 +57,8 @@ typedef struct VDPAUContext { VdpYCbCrFormat vdpau_format; } VDPAUContext; +int vdpau_api_ver = 2; + static void vdpau_uninit(AVCodecContext *s) { InputStream *ist = s->opaque; @@ -291,6 +293,49 @@ fail: return AVERROR(EINVAL); } +static int vdpau_old_init(AVCodecContext *s) +{ + InputStream *ist = s->opaque; + int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR; + AVVDPAUContext *vdpau_ctx; + VDPAUContext *ctx; + VdpStatus err; + int profile, ret; + + if (!ist->hwaccel_ctx) { + ret = vdpau_alloc(s); + if (ret < 0) + return ret; + } + ctx = ist->hwaccel_ctx; + vdpau_ctx = s->hwaccel_context; + + ret = av_vdpau_get_profile(s, &profile); + if (ret < 0) { + av_log(NULL, loglevel, "No known VDPAU decoder profile for this stream.\n"); + return AVERROR(EINVAL); + } + + if (ctx->decoder) + ctx->decoder_destroy(ctx->decoder); + + err = ctx->decoder_create(ctx->device, profile, + s->coded_width, s->coded_height, + 16, &ctx->decoder); + if (err != VDP_STATUS_OK) { + av_log(NULL, loglevel, "Error creating the VDPAU decoder: %s\n", + ctx->get_error_string(err)); + return AVERROR_UNKNOWN; + } + + vdpau_ctx->decoder = ctx->decoder; + + ist->hwaccel_get_buffer = vdpau_get_buffer; + ist->hwaccel_retrieve_data = vdpau_retrieve_data; + + return 0; +} + int vdpau_init(AVCodecContext *s) { InputStream *ist = s->opaque; @@ -300,6 +345,9 @@ int vdpau_init(AVCodecContext *s) VdpStatus err; int profile, ret; + if (vdpau_api_ver == 1) + return vdpau_old_init(s); + if (!ist->hwaccel_ctx) { ret = vdpau_alloc(s); if (ret < 0)