8 #include "libavutil/opt.h"
11 #define LOC QString("MMAL: ")
32 if (Width > 1920 || Height > 1088)
41 const AVCodec **Codec,
46 bool decodeonly =
Decoder ==
"mmal-dec";
50 if (!
Decoder.startsWith(
"mmal"))
60 case AV_CODEC_ID_H264:
61 if ((*Context)->profile == FF_PROFILE_H264_HIGH_10 ||
62 (*Context)->profile == FF_PROFILE_H264_HIGH_10_INTRA)
79 if (!profiles.contains(mythprofile))
87 QString name = QString((*Codec)->name) +
"_mmal";
88 if (name ==
"mpeg2video_mmal")
90 const AVCodec *codec = avcodec_find_decoder_by_name(name.toLocal8Bit());
92 if (!codec || !decoder)
94 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to find %1").arg(name));
98 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Found MMAL/FFmpeg decoder '%1'").arg(name));
102 (*Context)->pix_fmt = decodeonly ? (*Context)->pix_fmt : AV_PIX_FMT_MMAL;
110 DirectRendering =
false;
116 DirectRendering =
false;
144 if (
auto * player =
GetPlayerUI(Context); player !=
nullptr)
155 if (!(Context && Codec))
157 if (!(Codec->priv_class && Context->priv_data))
159 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Setting number of extra buffers to 8");
160 av_opt_set(Context->priv_data,
"extra_buffers",
"8", 0);
166 if (!Context || !AvFrame || !
Frame)
173 auto foundIt =
std::find(supported->cbegin(), supported->cend(),
type);
175 if (foundIt == supported->end())
179 if ((
Frame->m_type !=
type) || (
Frame->m_width != AvFrame->width) || (
Frame->m_height != AvFrame->height))
185 for (
uint plane = 0; plane < count; ++plane)
188 AvFrame->data[plane], AvFrame->linesize[plane],
201 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error");
206 if (
Frame->m_type !=
FMT_MMAL ||
static_cast<AVPixelFormat
>(AvFrame->format) != AV_PIX_FMT_MMAL)
208 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not an MMAL frame");
212 Frame->m_width = AvFrame->width;
213 Frame->m_height = AvFrame->height;
214 Frame->m_pixFmt = Context->pix_fmt;
215 Frame->m_swPixFmt = Context->sw_pix_fmt;
216 Frame->m_directRendering = 1;
217 AvFrame->opaque =
Frame;
220 Frame->m_buffer = AvFrame->data[3];
222 Frame->m_priv[0] =
reinterpret_cast<unsigned char*
>(av_buffer_ref(AvFrame->buf[0]));
233 while (*PixFmt != AV_PIX_FMT_NONE)
235 if (*PixFmt == AV_PIX_FMT_MMAL)
236 return AV_PIX_FMT_MMAL;
239 return AV_PIX_FMT_NONE;
244 static QRecursiveMutex lock;
245 QMutexLocker locker(&lock);
246 static bool s_checked =
false;
247 static bool s_available =
false;
249 if (s_checked && !Reinit)
254 if (profiles.isEmpty())
257 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Supported/available MMAL decoders:");
260 for (
auto profile : std::as_const(profiles))
268 if (profiles.isEmpty())
272 Decoders.append(
"MMAL:");
279 #include "interface/vmcs_host/vc_vchi_gencmd.h"
284 static QRecursiveMutex lock;
285 static bool s_initialised =
false;
288 QMutexLocker locker(&lock);
291 s_initialised =
true;
293 static const QPair<QString, MythCodecContext::CodecProfile> s_map[] =
302 VCHI_INSTANCE_T vchi_instance;
303 if (vchi_initialise(&vchi_instance) != 0)
305 if (vchi_connect(
nullptr, 0, vchi_instance) != 0)
307 VCHI_CONNECTION_T *vchi_connection =
nullptr;
308 vc_vchi_gencmd_init(vchi_instance, &vchi_connection, 1 );
313 char* response =
nullptr;
314 int responsesize = 0;
315 QString msg = QString(
"codec_enabled %1").arg(
profile.first);
316 if (!vc_gencmd(command,
sizeof(command), msg.toLocal8Bit().constData()))
317 vc_gencmd_string_property(command,
profile.first.toLocal8Bit().constData(), &response, &responsesize);
319 if (response && responsesize && qstrcmp(response,
"enabled") == 0)
320 s_profiles.append(
profile.second);
324 vchi_disconnect(vchi_instance);