17#include "libavutil/hwcontext_videotoolbox.h"
18#include "libavcodec/videotoolbox.h"
19#include "libavutil/pixdesc.h"
22#define LOC QString("VTBDec: ")
39 Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
40 DirectRendering =
false;
49 if (AvFrame->format != AV_PIX_FMT_VIDEOTOOLBOX)
65 Context->hw_device_ctx = device;
78 const AVCodec ** Codec,
82 bool decodeonly =
Decoder ==
"vtb-dec";
112 QString codec = avcodec_get_name((*Context)->codec_id);
113 QString
profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
114 QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);
117 if (!profiles.contains(mythprofile))
119 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VideoToolbox does not support decoding '%1 %2 %3'")
120 .arg(codec).arg(
profile).arg(pixfmt));
126 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VideoToolbox MAY support decoding '%1 %2 %3'")
127 .arg(codec).arg(
profile).arg(pixfmt));
128 (*Context)->pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX;
155 auto * deviceref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VIDEOTOOLBOX);
158 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create device context");
164 auto * devicectx =
reinterpret_cast<AVHWDeviceContext*
>(deviceref->data);
165 devicectx->user_opaque = interop;
169 if (av_hwdevice_ctx_init(deviceref) < 0)
171 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise device context");
172 av_buffer_unref(&deviceref);
176 Context->hw_device_ctx = deviceref;
177 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Created hw device '%1'")
178 .arg(av_hwdevice_get_type_name(AV_HWDEVICE_TYPE_VIDEOTOOLBOX)));
184 enum AVPixelFormat ret = AV_PIX_FMT_NONE;
185 while (*PixFmt != AV_PIX_FMT_NONE)
187 if (*PixFmt == AV_PIX_FMT_VIDEOTOOLBOX)
192 auto* me =
dynamic_cast<MythVTBContext*
>(decoder->GetMythCodecContext());
205 static QRecursiveMutex lock;
206 static bool s_initialised =
false;
209 QMutexLocker locker(&lock);
212 s_initialised =
true;
214 if (__builtin_available(macOS 10.13, *))
225 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Unable to check hardware decode support. Assuming all.");
239 static QRecursiveMutex lock;
240 QMutexLocker locker(&lock);
241 static bool s_checked =
false;
242 static bool s_available =
false;
243 if (!s_checked || Reinit)
246 if (profiles.empty())
248 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No VideoToolbox decoders found");
253 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Supported/available VideoToolbox decoders:");
257 LOG(VB_GENERAL, LOG_INFO,
LOC +
269 if (profiles.isEmpty())
273 Decoders.append(
"VideoToolbox:");
305 AVPixelFormat format = AV_PIX_FMT_NV12;
307 format = AV_PIX_FMT_P010;
311 auto *frames =
reinterpret_cast<AVHWFramesContext*
>(
m_framesContext->data);
312 if ((frames->sw_format == format) && (frames->width == Context->coded_width) &&
313 (frames->height == Context->coded_height))
327 AVBufferRef* framesref = av_hwframe_ctx_alloc(Context->hw_device_ctx);
328 auto *frames =
reinterpret_cast<AVHWFramesContext*
>(framesref->data);
330 frames->user_opaque =
nullptr;
331 frames->sw_format = format;
332 frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
333 frames->width = Context->coded_width;
334 frames->height = Context->coded_height;
335 if (av_hwframe_ctx_init(framesref) < 0)
337 av_buffer_unref(&framesref);
341 Context->hw_frames_ctx = framesref;
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
static void DeviceContextFinished(AVHWDeviceContext *Context)
static bool IsUnsupportedProfile(AVCodecContext *Context)
Most hardware decoders do not support these codecs/profiles.
static bool FrameTypeIsSupported(AVCodecContext *Context, VideoFrameType Format)
virtual bool RetrieveHWFrame(MythVideoFrame *Frame, AVFrame *AvFrame)
static AVBufferRef * CreateDevice(AVHWDeviceType Type, MythInteropGPU *Interop, const QString &Device=QString())
static int InitialiseDecoder2(AVCodecContext *Context, CreateHWDecoder Callback, const QString &Debug)
Initialise a hardware decoder that is NOT expected to use AVHWFramesContext.
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 bool GetBuffer2(struct AVCodecContext *Context, MythVideoFrame *Frame, AVFrame *AvFrame, int Flags)
A generic hardware buffer initialisation method when AVHWFramesContext is NOT used.
static MythPlayerUI * GetPlayerUI(AVCodecContext *Context)
void DiscardVideoFrames(bool KeyFrame, bool Flushed)
Places frames in the available frames queue.
static enum AVPixelFormat GetFormat(AVCodecContext *Context, const enum AVPixelFormat *PixFmt)
int HwDecoderInit(AVCodecContext *Context) override
MythVTBContext(DecoderBase *Parent, MythCodecID CodecID)
static bool HaveVTB(bool Reinit=false)
void InitFramesContext(AVCodecContext *Context)
Create a hardware frames context if needed.
static MythCodecID GetSupportedCodec(AVCodecContext **Context, const AVCodec **Codec, const QString &Decoder, uint StreamType)
AVBufferRef * m_framesContext
void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering) override
static const VTBProfiles & GetProfiles(void)
static void GetDecoderList(QStringList &Decoders)
~MythVTBContext() override
static int InitialiseDecoder(AVCodecContext *Context)
bool RetrieveFrame(AVCodecContext *Context, MythVideoFrame *Frame, AVFrame *AvFrame) override
static MythVTBInterop * CreateVTB(MythPlayerUI *Player, MythRenderOpenGL *Context)
static int ColorDepth(int Format)
static bool codec_is_vtb_dec(MythCodecID id)
static bool codec_is_vtb(MythCodecID id)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QList< MythCodecContext::CodecProfile > VTBProfiles