10#include "libavutil/opt.h"
13#define LOC QString("MMAL: ")
34 if (Width > 1920 || Height > 1088)
43 const AVCodec **Codec,
48 bool decodeonly =
Decoder ==
"mmal-dec";
52 if (!
Decoder.startsWith(
"mmal"))
62 case AV_CODEC_ID_H264:
63 if ((*Context)->profile == FF_PROFILE_H264_HIGH_10 ||
64 (*Context)->profile == FF_PROFILE_H264_HIGH_10_INTRA)
81 if (!profiles.contains(mythprofile))
89 QString name = QString((*Codec)->name) +
"_mmal";
90 if (name ==
"mpeg2video_mmal")
92 const AVCodec *codec = avcodec_find_decoder_by_name(name.toLocal8Bit());
94 if (!codec || !decoder)
96 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to find %1").arg(name));
100 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Found MMAL/FFmpeg decoder '%1'").arg(name));
104 (*Context)->pix_fmt = decodeonly ? (*Context)->pix_fmt : AV_PIX_FMT_MMAL;
112 DirectRendering =
false;
118 DirectRendering =
false;
146 if (
auto * player =
GetPlayerUI(Context); player !=
nullptr)
157 if (!(Context && Codec))
159 if (!(Codec->priv_class && Context->priv_data))
161 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Setting number of extra buffers to 8");
162 av_opt_set(Context->priv_data,
"extra_buffers",
"8", 0);
168 if (!Context || !AvFrame || !
Frame)
175 auto foundIt =
std::find(supported->cbegin(), supported->cend(),
type);
177 if (foundIt == supported->end())
181 if ((
Frame->m_type !=
type) || (
Frame->m_width != AvFrame->width) || (
Frame->m_height != AvFrame->height))
187 for (
uint plane = 0; plane < count; ++plane)
190 AvFrame->data[plane], AvFrame->linesize[plane],
203 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error");
208 if (
Frame->m_type !=
FMT_MMAL ||
static_cast<AVPixelFormat
>(AvFrame->format) != AV_PIX_FMT_MMAL)
210 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not an MMAL frame");
214 Frame->m_width = AvFrame->width;
215 Frame->m_height = AvFrame->height;
216 Frame->m_pixFmt = Context->pix_fmt;
217 Frame->m_swPixFmt = Context->sw_pix_fmt;
218 Frame->m_directRendering = 1;
219 AvFrame->opaque =
Frame;
222 Frame->m_buffer = AvFrame->data[3];
224 Frame->m_priv[0] =
reinterpret_cast<unsigned char*
>(av_buffer_ref(AvFrame->buf[0]));
235 while (*PixFmt != AV_PIX_FMT_NONE)
237 if (*PixFmt == AV_PIX_FMT_MMAL)
238 return AV_PIX_FMT_MMAL;
241 return AV_PIX_FMT_NONE;
246 static QRecursiveMutex lock;
247 QMutexLocker locker(&lock);
248 static bool s_checked =
false;
249 static bool s_available =
false;
251 if (s_checked && !Reinit)
256 if (profiles.isEmpty())
259 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Supported/available MMAL decoders:");
262 for (
auto profile : std::as_const(profiles))
270 if (profiles.isEmpty())
274 Decoders.append(
"MMAL:");
281#include "interface/vmcs_host/vc_vchi_gencmd.h"
286 static QRecursiveMutex lock;
287 static bool s_initialised =
false;
290 QMutexLocker locker(&lock);
293 s_initialised =
true;
295 static const QPair<QString, MythCodecContext::CodecProfile> s_map[] =
304 VCHI_INSTANCE_T vchi_instance;
305 if (vchi_initialise(&vchi_instance) != 0)
307 if (vchi_connect(
nullptr, 0, vchi_instance) != 0)
309 VCHI_CONNECTION_T *vchi_connection =
nullptr;
310 vc_vchi_gencmd_init(vchi_instance, &vchi_connection, 1 );
315 char* response =
nullptr;
316 int responsesize = 0;
317 QString msg = QString(
"codec_enabled %1").arg(
profile.first);
318 if (!vc_gencmd(command,
sizeof(command), msg.toLocal8Bit().constData()))
319 vc_gencmd_string_property(command,
profile.first.toLocal8Bit().constData(), &response, &responsesize);
321 if (response && responsesize && qstrcmp(response,
"enabled") == 0)
322 s_profiles.append(
profile.second);
326 vchi_disconnect(vchi_instance);
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
static bool FrameTypeIsSupported(AVCodecContext *Context, VideoFrameType Format)
static void ReleaseBuffer(void *Opaque, uint8_t *Data)
static void DestroyInterop(MythInteropGPU *Interop)
virtual void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
static QString GetProfileDescription(CodecProfile Profile, QSize Size, VideoFrameType Format=FMT_NONE, uint ColorDepth=0)
static MythPlayerUI * GetPlayerUI(AVCodecContext *Context)
AVCodecContext * GetCodecContext(const AVStream *Stream, const AVCodec *Codec=nullptr, bool NullCodec=false)
void FreeCodecContext(const AVStream *Stream)
static const MMALProfiles & GetProfiles(void)
static bool GetBuffer(AVCodecContext *Context, MythVideoFrame *Frame, AVFrame *AvFrame, int)
MythMMALInterop * m_interop
int HwDecoderInit(AVCodecContext *Context) override
static bool HaveMMAL(bool Reinit=false)
~MythMMALContext() override
bool RetrieveFrame(AVCodecContext *Context, MythVideoFrame *Frame, AVFrame *AvFrame) override
bool GetBuffer2(AVCodecContext *Context, MythVideoFrame *Frame, AVFrame *AvFrame, int)
void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering) override
static bool CheckCodecSize(int Width, int Height, MythCodecContext::CodecProfile Profile)
void SetDecoderOptions(AVCodecContext *Context, const AVCodec *Codec) override
static void GetDecoderList(QStringList &Decoders)
static MythCodecID GetSupportedCodec(AVCodecContext **Context, const AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
static enum AVPixelFormat GetFormat(AVCodecContext *, const AVPixelFormat *PixFmt)
MythMMALContext(DecoderBase *Parent, MythCodecID Codec)
static MythMMALInterop * CreateMMAL(MythRenderOpenGL *Context)
Create an MMAL interop.
static uint GetNumPlanes(VideoFrameType Type)
static int GetPitchForPlane(VideoFrameType Type, int Width, uint Plane)
static int GetHeightForPlane(VideoFrameType Type, int Height, uint Plane)
static void CopyPlane(uint8_t *To, int ToPitch, const uint8_t *From, int FromPitch, int PlaneWidth, int PlaneHeight)
static bool ReinitBuffer(MythVideoFrame *Frame, VideoFrameType Type, MythCodecID CodecID, int Width, int Height)
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
static bool codec_is_mmal_dec(MythCodecID id)
static bool codec_is_mmal(MythCodecID id)
std::vector< VideoFrameType > VideoFrameTypes
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QList< MythCodecContext::CodecProfile > MMALProfiles