15#include "libavutil/hwcontext_vdpau.h"
16#include "libavutil/pixdesc.h"
17#include "libavcodec/vdpau.h"
20#define LOC QString("VDPAUDec: ")
62 auto * hwdevicecontext =
reinterpret_cast<AVHWDeviceContext*
>(hwdeviceref->data);
63 if (!hwdevicecontext || !hwdevicecontext->hwctx)
67 if (av_hwdevice_ctx_init(hwdeviceref) < 0)
69 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise device context");
70 av_buffer_unref(&hwdeviceref);
76 Context->hw_frames_ctx = av_hwframe_ctx_alloc(hwdeviceref);
77 if (!Context->hw_frames_ctx)
79 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create VDPAU hardware frames context");
80 av_buffer_unref(&hwdeviceref);
86 auto * hwframesctx =
reinterpret_cast<AVHWFramesContext*
>(Context->hw_frames_ctx->data);
87 hwframesctx->user_opaque = interop;
91 hwframesctx->sw_format = Context->sw_pix_fmt == AV_PIX_FMT_YUVJ420P ? AV_PIX_FMT_YUV420P : Context->sw_pix_fmt;
92 hwframesctx->format = AV_PIX_FMT_VDPAU;
93 hwframesctx->width = Context->coded_width;
94 hwframesctx->height = Context->coded_height;
95 int res = av_hwframe_ctx_init(Context->hw_frames_ctx);
98 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise VDPAU frames context");
99 av_buffer_unref(&hwdeviceref);
100 av_buffer_unref(&(Context->hw_frames_ctx));
104 auto * vdpaudevicectx =
static_cast<AVVDPAUDeviceContext*
>(hwdevicecontext->hwctx);
105 if (av_vdpau_bind_context(Context, vdpaudevicectx->device,
106 vdpaudevicectx->get_proc_address, AV_HWACCEL_FLAG_IGNORE_LEVEL) != 0)
108 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to bind VDPAU context");
109 av_buffer_unref(&hwdeviceref);
110 av_buffer_unref(&(Context->hw_frames_ctx));
114 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VDPAU buffer pool created"));
115 av_buffer_unref(&hwdeviceref);
127 bool decodeonly =
Decoder ==
"vdpau-dec";
138 QString codec = avcodec_get_name((*Context)->codec_id);
139 QString
profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
140 QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);
153 for (
const auto& vdpauprofile : profiles)
155 bool match = vdpauprofile.first == mythprofile;
158 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Trying %1")
160 if (vdpauprofile.second.Supported((*Context)->width, (*Context)->height, (*Context)->level))
174 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"H264 decode check failed");
177 QString desc = QString(
"'%1 %2 %3 %4x%5'")
178 .arg(codec,
profile, pixfmt).arg((*Context)->width).arg((*Context)->height);
182 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VDPAU does not support decoding %1").arg(desc));
186 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VDPAU supports decoding %1").arg(desc));
187 (*Context)->pix_fmt = AV_PIX_FMT_VDPAU;
194 while (*PixFmt != AV_PIX_FMT_NONE)
196 if (*PixFmt == AV_PIX_FMT_VDPAU)
198 return AV_PIX_FMT_VDPAU;
201 return AV_PIX_FMT_NONE;
207 while (*PixFmt != AV_PIX_FMT_NONE)
209 if (*PixFmt == AV_PIX_FMT_VDPAU)
215 if (Context->sw_pix_fmt == AV_PIX_FMT_YUVJ420P)
216 Context->sw_pix_fmt = AV_PIX_FMT_YUV420P;
217 Context->hw_device_ctx = device;
218 return AV_PIX_FMT_VDPAU;
223 return AV_PIX_FMT_NONE;
228 if (AvFrame->format != AV_PIX_FMT_VDPAU)
263 if (!Context->hw_frames_ctx)
266 auto* hwframesctx =
reinterpret_cast<AVHWFramesContext*
>(Context->hw_frames_ctx->data);
267 auto* interop =
reinterpret_cast<MythVDPAUInterop*
>(hwframesctx->user_opaque);
268 if (interop && interop->IsPreempted())
282 Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
288 Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
289 DirectRendering =
false;
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
static int InitialiseDecoder(AVCodecContext *Context, CreateHWDecoder Callback, const QString &Debug)
Initialise a hardware decoder that is expected to use AVHWFramesContext.
static bool IsUnsupportedProfile(AVCodecContext *Context)
Most hardware decoders do not support these codecs/profiles.
static bool FrameTypeIsSupported(AVCodecContext *Context, VideoFrameType Format)
static int GetBuffer(struct AVCodecContext *Context, AVFrame *Frame, int Flags)
A generic hardware buffer initialisation method when using AVHWFramesContext.
virtual bool RetrieveHWFrame(MythVideoFrame *Frame, AVFrame *AvFrame)
static AVBufferRef * CreateDevice(AVHWDeviceType Type, MythInteropGPU *Interop, const QString &Device=QString())
virtual void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
static void FramesContextFinished(AVHWFramesContext *Context)
static void NewHardwareFramesContext(void)
Track the number of concurrent frames contexts.
static QString GetProfileDescription(CodecProfile Profile, QSize Size, VideoFrameType Format=FMT_NONE, uint ColorDepth=0)
static MythPlayerUI * GetPlayerUI(AVCodecContext *Context)
static CodecProfile FFmpegToMythProfile(AVCodecID CodecID, int Profile)
MythVDPAUContext(DecoderBase *Parent, MythCodecID CodecID)
bool DecoderWillResetOnFlush(void) override
bool RetrieveFrame(AVCodecContext *Context, MythVideoFrame *Frame, AVFrame *AvFrame) override
static int InitialiseContext(AVCodecContext *Context)
Create a VDPAU device for use with direct rendering.
static enum AVPixelFormat GetFormat2(AVCodecContext *Context, const enum AVPixelFormat *PixFmt)
\ brief Confirm pixel format and create VDPAU device for copy back (no MythVDPAUInterop required)
void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering) override
static MythCodecID GetSupportedCodec(AVCodecContext **CodecContext, const AVCodec **Codec, const QString &Decoder, uint StreamType)
static enum AVPixelFormat GetFormat(AVCodecContext *Context, const enum AVPixelFormat *PixFmt)
\ brief Confirm pixel format and create VDPAU device for direct rendering (MythVDPAUInterop required)
bool DecoderNeedsReset(AVCodecContext *Context) override
Report whether the decoder is known to be errored.
bool DecoderWillResetOnAspect(void) override
static bool CheckH264Decode(AVCodecContext *Context)
static bool HaveVDPAU(bool Reinit=false)
static const VDPAUProfiles & GetProfiles(void)
static MythVDPAUInterop * CreateVDPAU(MythPlayerUI *Player, MythRenderOpenGL *Context, MythCodecID CodecId)
uint mpeg_version(AVCodecID codec_id)
static bool codec_is_vdpau_dechw(MythCodecID id)
static bool codec_is_vdpau_hw(MythCodecID id)
static bool codec_is_vdpau_dec(MythCodecID id)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
std::vector< VDPAUProfile > VDPAUProfiles