13 #include "libavutil/hwcontext_vdpau.h"
14 #include "libavutil/pixdesc.h"
15 #include "libavcodec/vdpau.h"
18 #define LOC QString("VDPAUDec: ")
60 auto * hwdevicecontext =
reinterpret_cast<AVHWDeviceContext*
>(hwdeviceref->data);
61 if (!hwdevicecontext || !hwdevicecontext->hwctx)
65 if (av_hwdevice_ctx_init(hwdeviceref) < 0)
67 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise device context");
68 av_buffer_unref(&hwdeviceref);
74 Context->hw_frames_ctx = av_hwframe_ctx_alloc(hwdeviceref);
75 if (!Context->hw_frames_ctx)
77 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create VDPAU hardware frames context");
78 av_buffer_unref(&hwdeviceref);
84 auto * hwframesctx =
reinterpret_cast<AVHWFramesContext*
>(Context->hw_frames_ctx->data);
85 hwframesctx->user_opaque = interop;
89 hwframesctx->sw_format = Context->sw_pix_fmt == AV_PIX_FMT_YUVJ420P ? AV_PIX_FMT_YUV420P : Context->sw_pix_fmt;
90 hwframesctx->format = AV_PIX_FMT_VDPAU;
91 hwframesctx->width = Context->coded_width;
92 hwframesctx->height = Context->coded_height;
93 int res = av_hwframe_ctx_init(Context->hw_frames_ctx);
96 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise VDPAU frames context");
97 av_buffer_unref(&hwdeviceref);
98 av_buffer_unref(&(Context->hw_frames_ctx));
102 auto * vdpaudevicectx =
static_cast<AVVDPAUDeviceContext*
>(hwdevicecontext->hwctx);
103 if (av_vdpau_bind_context(Context, vdpaudevicectx->device,
104 vdpaudevicectx->get_proc_address, AV_HWACCEL_FLAG_IGNORE_LEVEL) != 0)
106 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to bind VDPAU context");
107 av_buffer_unref(&hwdeviceref);
108 av_buffer_unref(&(Context->hw_frames_ctx));
112 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VDPAU buffer pool created"));
113 av_buffer_unref(&hwdeviceref);
125 bool decodeonly =
Decoder ==
"vdpau-dec";
136 QString codec = avcodec_get_name((*Context)->codec_id);
137 QString
profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
138 QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);
151 for (
const auto& vdpauprofile : profiles)
153 bool match = vdpauprofile.first == mythprofile;
156 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Trying %1")
158 if (vdpauprofile.second.Supported((*Context)->width, (*Context)->height, (*Context)->level))
172 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"H264 decode check failed");
175 QString desc = QString(
"'%1 %2 %3 %4x%5'")
176 .arg(codec,
profile, pixfmt).arg((*Context)->width).arg((*Context)->height);
180 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VDPAU does not support decoding %1").arg(desc));
184 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VDPAU supports decoding %1").arg(desc));
185 (*Context)->pix_fmt = AV_PIX_FMT_VDPAU;
192 while (*PixFmt != AV_PIX_FMT_NONE)
194 if (*PixFmt == AV_PIX_FMT_VDPAU)
196 return AV_PIX_FMT_VDPAU;
199 return AV_PIX_FMT_NONE;
205 while (*PixFmt != AV_PIX_FMT_NONE)
207 if (*PixFmt == AV_PIX_FMT_VDPAU)
213 if (Context->sw_pix_fmt == AV_PIX_FMT_YUVJ420P)
214 Context->sw_pix_fmt = AV_PIX_FMT_YUV420P;
215 Context->hw_device_ctx = device;
216 return AV_PIX_FMT_VDPAU;
221 return AV_PIX_FMT_NONE;
226 if (AvFrame->format != AV_PIX_FMT_VDPAU)
261 if (!Context->hw_frames_ctx)
264 auto* hwframesctx =
reinterpret_cast<AVHWFramesContext*
>(Context->hw_frames_ctx->data);
265 auto* interop =
reinterpret_cast<MythVDPAUInterop*
>(hwframesctx->user_opaque);
266 if (interop && interop->IsPreempted())
280 Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
286 Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
287 DirectRendering =
false;