8 #include "libavutil/opt.h"
11 #define LOC QString("MMAL: ")
32 if (Width > 1920 || Height > 1088)
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 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],
193 AvFrame->reordered_opaque = Context->reordered_opaque;
202 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error");
207 if (
Frame->m_type !=
FMT_MMAL ||
static_cast<AVPixelFormat
>(AvFrame->format) != AV_PIX_FMT_MMAL)
209 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not an MMAL frame");
213 Frame->m_width = AvFrame->width;
214 Frame->m_height = AvFrame->height;
215 Frame->m_pixFmt = Context->pix_fmt;
216 Frame->m_swPixFmt = Context->sw_pix_fmt;
217 Frame->m_directRendering = 1;
218 AvFrame->opaque =
Frame;
219 AvFrame->reordered_opaque = Context->reordered_opaque;
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 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
247 static QMutex lock(QMutex::Recursive);
249 static QRecursiveMutex lock;
251 QMutexLocker locker(&lock);
252 static bool s_checked =
false;
253 static bool s_available =
false;
255 if (s_checked && !Reinit)
260 if (profiles.isEmpty())
263 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Supported/available MMAL decoders:");
266 for (
auto profile : qAsConst(profiles))
274 if (profiles.isEmpty())
278 Decoders.append(
"MMAL:");
285 #include "interface/vmcs_host/vc_vchi_gencmd.h"
290 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
291 static QMutex lock(QMutex::Recursive);
293 static QRecursiveMutex lock;
295 static bool s_initialised =
false;
298 QMutexLocker locker(&lock);
301 s_initialised =
true;
303 static const QPair<QString, MythCodecContext::CodecProfile> s_map[] =
312 VCHI_INSTANCE_T vchi_instance;
313 if (vchi_initialise(&vchi_instance) != 0)
315 if (vchi_connect(
nullptr, 0, vchi_instance) != 0)
317 VCHI_CONNECTION_T *vchi_connection =
nullptr;
318 vc_vchi_gencmd_init(vchi_instance, &vchi_connection, 1 );
323 char* response =
nullptr;
324 int responsesize = 0;
325 QString msg = QString(
"codec_enabled %1").arg(
profile.first);
326 if (!vc_gencmd(command,
sizeof(command), msg.toLocal8Bit().constData()))
327 vc_gencmd_string_property(command,
profile.first.toLocal8Bit().constData(), &response, &responsesize);
329 if (response && responsesize && qstrcmp(response,
"enabled") == 0)
330 s_profiles.append(
profile.second);
334 vchi_disconnect(vchi_instance);