MythTV master
mythavutil.cpp
Go to the documentation of this file.
1//
2// mythavutil.cpp
3// MythTV
4//
5// Created by Jean-Yves Avenard on 28/06/2014.
6// Copyright (c) 2014 Bubblestuff Pty Ltd. All rights reserved.
7//
8
9// Qt
10#include <QtGlobal>
11#include <QChar> // Fix Qt6 GCC SFINAE warning
12#include <QMutexLocker>
13#include <QFile>
14#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
15#include <QtProcessorDetection>
16#endif
17
18// MythTV
19#include "mythaverror.h"
20#include "libmythbase/mythconfig.h"
22#include "mythdeinterlacer.h"
23#include "mythavutil.h"
24
25// FFmpeg
26extern "C" {
27#include "libavcodec/avcodec.h"
28#include "libavutil/imgutils.h"
29#include "libavformat/avformat.h"
30}
31
33{
34 switch (Type)
35 {
36 case FMT_YV12: return AV_PIX_FMT_YUV420P;
37 case FMT_YUV420P9: return AV_PIX_FMT_YUV420P9;
38 case FMT_YUV420P10: return AV_PIX_FMT_YUV420P10;
39 case FMT_YUV420P12: return AV_PIX_FMT_YUV420P12;
40 case FMT_YUV420P14: return AV_PIX_FMT_YUV420P14;
41 case FMT_YUV420P16: return AV_PIX_FMT_YUV420P16;
42 case FMT_NV12: return AV_PIX_FMT_NV12;
43 case FMT_P010: return AV_PIX_FMT_P010;
44 case FMT_P016: return AV_PIX_FMT_P016;
45 case FMT_YUV422P: return AV_PIX_FMT_YUV422P;
46 case FMT_YUV422P9: return AV_PIX_FMT_YUV422P9;
47 case FMT_YUV422P10: return AV_PIX_FMT_YUV422P10;
48 case FMT_YUV422P12: return AV_PIX_FMT_YUV422P12;
49 case FMT_YUV422P14: return AV_PIX_FMT_YUV422P14;
50 case FMT_YUV422P16: return AV_PIX_FMT_YUV422P16;
51 case FMT_YUV444P: return AV_PIX_FMT_YUV444P;
52 case FMT_YUV444P9: return AV_PIX_FMT_YUV444P9;
53 case FMT_YUV444P10: return AV_PIX_FMT_YUV444P10;
54 case FMT_YUV444P12: return AV_PIX_FMT_YUV444P12;
55 case FMT_YUV444P14: return AV_PIX_FMT_YUV444P14;
56 case FMT_YUV444P16: return AV_PIX_FMT_YUV444P16;
57 case FMT_RGB24: return AV_PIX_FMT_RGB24;
58 case FMT_BGRA: return AV_PIX_FMT_BGRA; // NOLINT(bugprone-branch-clone)
59 case FMT_RGB32: return AV_PIX_FMT_RGB32;
60 case FMT_ARGB32: return AV_PIX_FMT_ARGB;
61 case FMT_RGBA32: return AV_PIX_FMT_RGBA;
62 case FMT_YUY2: return AV_PIX_FMT_UYVY422;
63 case FMT_VDPAU: return AV_PIX_FMT_VDPAU;
64 case FMT_VTB: return AV_PIX_FMT_VIDEOTOOLBOX;
65 case FMT_VAAPI: return AV_PIX_FMT_VAAPI;
66 case FMT_MEDIACODEC: return AV_PIX_FMT_MEDIACODEC;
67 case FMT_NVDEC: return AV_PIX_FMT_CUDA;
68 case FMT_DXVA2: return AV_PIX_FMT_DXVA2_VLD;
69 case FMT_MMAL: return AV_PIX_FMT_MMAL;
70 case FMT_DRMPRIME: return AV_PIX_FMT_DRM_PRIME;
71 case FMT_NONE: break;
72 }
73 return AV_PIX_FMT_NONE;
74}
75
77{
78 switch (Fmt)
79 {
80 case AV_PIX_FMT_YUVJ420P:
81 case AV_PIX_FMT_YUV420P: return FMT_YV12;
82 case AV_PIX_FMT_YUV420P9: return FMT_YUV420P9;
83 case AV_PIX_FMT_YUV420P10: return FMT_YUV420P10;
84 case AV_PIX_FMT_YUV420P12: return FMT_YUV420P12;
85 case AV_PIX_FMT_YUV420P14: return FMT_YUV420P14;
86 case AV_PIX_FMT_YUV420P16: return FMT_YUV420P16;
87 case AV_PIX_FMT_NV12: return FMT_NV12;
88 case AV_PIX_FMT_P010: return FMT_P010;
89 case AV_PIX_FMT_P016: return FMT_P016;
90 case AV_PIX_FMT_YUVJ422P:
91 case AV_PIX_FMT_YUV422P: return FMT_YUV422P;
92 case AV_PIX_FMT_YUV422P9: return FMT_YUV422P9;
93 case AV_PIX_FMT_YUV422P10: return FMT_YUV422P10;
94 case AV_PIX_FMT_YUV422P12: return FMT_YUV422P12;
95 case AV_PIX_FMT_YUV422P14: return FMT_YUV422P14;
96 case AV_PIX_FMT_YUV422P16: return FMT_YUV422P16;
97 case AV_PIX_FMT_YUVJ444P:
98 case AV_PIX_FMT_YUV444P: return FMT_YUV444P;
99 case AV_PIX_FMT_YUV444P9: return FMT_YUV444P9;
100 case AV_PIX_FMT_YUV444P10: return FMT_YUV444P10;
101 case AV_PIX_FMT_YUV444P12: return FMT_YUV444P12;
102 case AV_PIX_FMT_YUV444P14: return FMT_YUV444P14;
103 case AV_PIX_FMT_YUV444P16: return FMT_YUV444P16;
104 case AV_PIX_FMT_UYVY422: return FMT_YUY2;
105 case AV_PIX_FMT_RGB24: return FMT_RGB24;
106 case AV_PIX_FMT_ARGB: return FMT_ARGB32;
107 case AV_PIX_FMT_RGBA: return FMT_RGBA32;
108 case AV_PIX_FMT_BGRA: return FMT_BGRA;
109 case AV_PIX_FMT_CUDA: return FMT_NVDEC;
110 case AV_PIX_FMT_MMAL: return FMT_MMAL;
111 case AV_PIX_FMT_VDPAU: return FMT_VDPAU;
112 case AV_PIX_FMT_VIDEOTOOLBOX: return FMT_VTB;
113 case AV_PIX_FMT_VAAPI: return FMT_VAAPI;
114 case AV_PIX_FMT_DXVA2_VLD: return FMT_DXVA2;
115 case AV_PIX_FMT_MEDIACODEC: return FMT_MEDIACODEC;
116 case AV_PIX_FMT_DRM_PRIME: return FMT_DRMPRIME;
117 default: break;
118 }
119 return FMT_NONE;
120}
121
123{
124 switch (Transfer)
125 {
126 case AVCOL_TRC_SMPTE2084: return MythHDR::HDR10;
127 case AVCOL_TRC_BT2020_10:
128 case AVCOL_TRC_ARIB_STD_B67: return MythHDR::HLG;
129 default: break;
130 }
131 return MythHDR::SDR;
132}
133
140{
141 if (!Frame)
142 return;
143
144 // Create a wrapper frame and set it up
145 // (yes - this will end up being a wrapper around a wrapper!)
146 if (VideoFrameType type = PixelFormatToFrameType(static_cast<AVPixelFormat>(Frame->format));
148 {
149 // AVFrame video data consists of 3 independent buffers.
150 // MythVideoFrame requires video data to be in one memory block.
151 // Create a copy of the frame with all video data in one memory block.
152 AVFrame tempFrame = *Frame;
153 AVFrame *tf = &tempFrame;
154
155 size_t b0 = tf->buf[0]->size;
156 size_t b1 = tf->buf[1]->size;
157 size_t b2 = tf->buf[2]->size;
158
159 // Extend size to a multiple of 16 bytes for MythVideoFrame alignment constraints
160 size_t b0a = ((b0 + 15) / 16) * 16;
161 size_t b1a = ((b1 + 15) / 16) * 16;
162 size_t b2a = ((b2 + 15) / 16) * 16;
163
164 // Allocate contiguous buffer with enough space for the three segments
165 uint8_t *tbuf{ new uint8_t[b0a + b1a + b2a]{} };
166
167 tf->data[0] = tbuf;
168 tf->data[1] = tbuf + b0a;
169 tf->data[2] = tbuf + b0a + b1a;
170 memcpy(tf->data[0], tf->buf[0]->data, b0);
171 memcpy(tf->data[1], tf->buf[1]->data, b1);
172 memcpy(tf->data[2], tf->buf[2]->data, b2);
173
174 // Create a MythVideoFrame from the temporary AVFrame
175 MythVideoFrame mythframe(type, tf->data[0],
176 MythVideoFrame::GetBufferSize(type, tf->width, tf->height),
177 tf->width, tf->height);
178 mythframe.m_offsets[0] = 0;
179 mythframe.m_offsets[1] = tf->data[1] - tf->data[0];
180 mythframe.m_offsets[2] = tf->data[2] - tf->data[0];
181 mythframe.m_pitches[0] = tf->linesize[0];
182 mythframe.m_pitches[1] = tf->linesize[1];
183 mythframe.m_pitches[2] = tf->linesize[2];
184
185 // Deinterlacing
188 MythDeinterlacer deinterlacer;
189 deinterlacer.Filter(&mythframe, kScan_Interlaced, nullptr, true);
190
191 // Copy back our deinterlaced frame and free the video buffer of the temporary AVFrame
192 memcpy(Frame->data[0], tf->data[0], b0);
193 memcpy(Frame->data[1], tf->data[1], b1);
194 memcpy(Frame->data[2], tf->data[2], b2);
195 delete[] tbuf;
196
197 // Must remove buffer before mythframe is deleted
198 mythframe.m_buffer = nullptr;
199 }
200}
201
203int MythAVUtil::FillAVFrame(AVFrame *Frame, const MythVideoFrame *From, AVPixelFormat Fmt)
204{
205 if (Fmt == AV_PIX_FMT_NONE)
206 Fmt = FrameTypeToPixelFormat(From->m_type);
207
208 av_image_fill_arrays(Frame->data, Frame->linesize, From->m_buffer,
209 Fmt, From->m_width, From->m_height, IMAGE_ALIGN);
210 Frame->data[1] = From->m_buffer + From->m_offsets[1];
211 Frame->data[2] = From->m_buffer + From->m_offsets[2];
212 Frame->linesize[0] = From->m_pitches[0];
213 Frame->linesize[1] = From->m_pitches[1];
214 Frame->linesize[2] = From->m_pitches[2];
215 return static_cast<int>(MythVideoFrame::GetBufferSize(From->m_type, From->m_width, From->m_height));
216}
217
222{
223 sws_freeContext(m_swsctx);
224}
225
226int MythAVCopy::SizeData(int Width, int Height, AVPixelFormat Fmt)
227{
228 if (Width == m_width && Height == m_height && Fmt == m_format)
229 return m_size;
230
231 m_size = av_image_get_buffer_size(Fmt, Width, Height, IMAGE_ALIGN);
232 m_width = Width;
233 m_height = Height;
234 m_format = Fmt;
235 return m_size;
236}
237
238int MythAVCopy::Copy(AVFrame* To, AVPixelFormat ToFmt, const AVFrame* From, AVPixelFormat FromFmt,
239 int Width, int Height)
240{
241 int newwidth = Width;
242#ifdef Q_PROCESSOR_ARM
243 // references https://code.mythtv.org/trac/ticket/12888 and
244 // https://trac.ffmpeg.org/ticket/6192
245 // TODO: This is from 2017-02-17 and probably needs to be tested again.
246
247 // The ARM build of FFMPEG has a bug that if sws_scale is
248 // called with source and dest sizes the same, and
249 // formats as shown below, it causes a bus error and the
250 // application core dumps. To avoid this I make a -1
251 // difference in the new width, causing it to bypass
252 // the code optimization which is failing.
253 if (FromFmt == AV_PIX_FMT_YUV420P && ToFmt == AV_PIX_FMT_BGRA)
254 newwidth = Width - 1;
255#endif
256 m_swsctx = sws_getCachedContext(m_swsctx, Width, Height, FromFmt,
257 newwidth, Height, ToFmt, SWS_FAST_BILINEAR,
258 nullptr, nullptr, nullptr);
259 if (m_swsctx == nullptr)
260 return -1;
261 sws_scale(m_swsctx, From->data, From->linesize, 0, Height, To->data, To->linesize);
262 return SizeData(Width, Height, ToFmt);
263}
264
272 unsigned char* Buffer, AVPixelFormat Fmt)
273{
274 if (!Buffer)
275 return 0;
276 AVFrame frame;
277 AVPixelFormat fromfmt = MythAVUtil::FrameTypeToPixelFormat(From->m_type);
278 MythAVUtil::FillAVFrame(&frame, From, fromfmt);
279 av_image_fill_arrays(To->data, To->linesize, Buffer, Fmt, From->m_width, From->m_height, IMAGE_ALIGN);
280 return Copy(To, Fmt, &frame, fromfmt, From->m_width, From->m_height);
281}
282
288{
290}
291
292AVCodecContext *MythCodecMap::GetCodecContext(const AVStream* Stream,
293 const AVCodec* Codec,
294 bool NullCodec)
295{
296 if (Stream == nullptr || Stream->codecpar == nullptr)
297 return nullptr;
298 QMutexLocker lock(&m_mapLock);
299 AVCodecContext* avctx = m_streamMap.value(Stream, nullptr);
300 if (avctx == nullptr)
301 {
302 if (NullCodec)
303 {
304 Codec = nullptr;
305 }
306 else if (Codec == nullptr)
307 {
308 Codec = avcodec_find_decoder(Stream->codecpar->codec_id);
309 if (Codec == nullptr)
310 {
311 LOG(VB_GENERAL, LOG_WARNING, QString("avcodec_find_decoder fail for %1")
312 .arg(Stream->codecpar->codec_id));
313 return nullptr;
314 }
315 }
316 avctx = avcodec_alloc_context3(Codec);
317 if (avctx != nullptr && avcodec_parameters_to_context(avctx, Stream->codecpar) < 0)
318 avcodec_free_context(&avctx);
319
320 if (avctx != nullptr)
321 {
322 avctx->pkt_timebase = Stream->time_base;
323 m_streamMap.insert(Stream, avctx);
324 }
325 }
326 return avctx;
327}
328
329AVCodecContext *MythCodecMap::FindCodecContext(const AVStream* Stream)
330{
331 return m_streamMap.value(Stream, nullptr);
332}
333
337void MythCodecMap::FreeCodecContext(const AVStream* Stream)
338{
339 QMutexLocker lock(&m_mapLock);
340 AVCodecContext* avctx = m_streamMap.take(Stream);
341 if (avctx)
342 {
343 if (avctx->internal)
344 avcodec_flush_buffers(avctx);
345 avcodec_free_context(&avctx);
346 }
347}
348
350{
351 QMutexLocker lock(&m_mapLock);
352 QMap<const AVStream*, AVCodecContext*>::iterator i = m_streamMap.begin();
353 while (i != m_streamMap.end())
354 {
355 const AVStream *stream = i.key();
356 ++i;
357 FreeCodecContext(stream);
358 }
359}
360
362{
363 const int probeBufferSize = 8 * 1024;
364 const AVInputFormat *fmt = nullptr;
365 AVProbeData probe;
366 memset(&probe, 0, sizeof(AVProbeData));
367 probe.filename = "";
368 probe.buf = new unsigned char[probeBufferSize + AVPROBE_PADDING_SIZE];
369 probe.buf_size = probeBufferSize;
370 memset(probe.buf, 0, probeBufferSize + AVPROBE_PADDING_SIZE);
371 av_log_set_level(AV_LOG_FATAL);
372 if (filename == "")
373 m_errorCode = 97;
374 QFile infile(filename);
375 if (m_errorCode == 0 && !infile.open(QIODevice::ReadOnly))
376 m_errorCode = 99;
377 if (m_errorCode==0) {
378 int64_t leng = infile.read(reinterpret_cast<char*>(probe.buf), probeBufferSize);
379 probe.buf_size = static_cast<int>(leng);
380 infile.close();
381 fmt = av_probe_input_format(&probe, static_cast<int>(true));
382 if (fmt == nullptr)
383 m_errorCode = 98;
384 }
385 AVFormatContext *ctx = nullptr;
386 if (m_errorCode==0)
387 {
388 ctx = avformat_alloc_context();
389 m_errorCode = avformat_open_input(&ctx, filename.toUtf8().constData(),
390 fmt, nullptr);
391 }
392 if (m_errorCode==0)
393 m_errorCode = avformat_find_stream_info(ctx, nullptr);
394
395 if (m_errorCode==0)
396 {
397 for (uint ix = 0; ix < ctx->nb_streams; ix++)
398 {
399 AVStream *stream = ctx->streams[ix];
400 if (stream == nullptr)
401 continue;
402 AVCodecParameters *codecpar = stream->codecpar;
403 const AVCodecDescriptor* desc = nullptr;
405 info.m_codecType = ' ';
406 if (codecpar != nullptr)
407 {
408 desc = avcodec_descriptor_get(codecpar->codec_id);
409 switch (codecpar->codec_type)
410 {
411 case AVMEDIA_TYPE_VIDEO:
412 info.m_codecType = 'V';
413 break;
414 case AVMEDIA_TYPE_AUDIO:
415 info.m_codecType = 'A';
416 break;
417 case AVMEDIA_TYPE_SUBTITLE:
418 info.m_codecType = 'S';
419 break;
420 default:
421 continue;
422 }
423 }
424 if (desc != nullptr)
425 info.m_codecName = desc->name;
426 if (stream->duration != AV_NOPTS_VALUE)
427 info.m_duration = stream->duration * stream->time_base.num / stream->time_base.den;
428 else if (ctx->duration != AV_NOPTS_VALUE)
429 info.m_duration = ctx->duration / AV_TIME_BASE;
430 else
431 info.m_duration = 0;
432 if (info.m_codecType == 'V')
433 {
434 if (codecpar != nullptr)
435 {
436 info.m_width = codecpar->width;
437 info.m_height = codecpar->height;
438 info.m_SampleAspectRatio = static_cast<float>(codecpar->sample_aspect_ratio.num)
439 / static_cast<float>(codecpar->sample_aspect_ratio.den);
440 switch (codecpar->field_order)
441 {
442 case AV_FIELD_PROGRESSIVE:
443 info.m_fieldOrder = "PR";
444 break;
445 case AV_FIELD_TT:
446 info.m_fieldOrder = "TT";
447 break;
448 case AV_FIELD_BB:
449 info.m_fieldOrder = "BB";
450 break;
451 case AV_FIELD_TB:
452 info.m_fieldOrder = "TB";
453 break;
454 case AV_FIELD_BT:
455 info.m_fieldOrder = "BT";
456 break;
457 default:
458 break;
459 }
460 }
461 info.m_frameRate = static_cast<float>(stream->r_frame_rate.num)
462 / static_cast<float>(stream->r_frame_rate.den);
463 info.m_avgFrameRate = static_cast<float>(stream->avg_frame_rate.num)
464 / static_cast<float>(stream->avg_frame_rate.den);
465 }
466 if (info.m_codecType == 'A')
467 info.m_channels = codecpar->ch_layout.nb_channels;
468 m_streamInfoList.append(info);
469 }
470 }
471 if (m_errorCode != 0)
472 {
473 switch(m_errorCode) {
474 case 97:
475 m_errorMsg = "File Not Found";
476 break;
477 case 98:
478 m_errorMsg = "av_probe_input_format returned no result";
479 break;
480 case 99:
481 m_errorMsg = "File could not be opened";
482 break;
483 default:
484 m_errorMsg = QString::fromStdString(av_make_error_stdstring_unknown(m_errorCode));
485 }
486 LOG(VB_GENERAL, LOG_ERR,
487 QString("MythStreamInfoList failed for %1. Error code:%2 Message:%3")
488 .arg(filename).arg(m_errorCode).arg(m_errorMsg));
489
490 }
491
492 if (ctx != nullptr)
493 {
494 avformat_close_input(&ctx);
495 avformat_free_context(ctx);
496 }
497 delete [] probe.buf;
498}
AVFrame AVFrame
int m_width
Definition: mythavutil.h:59
int m_height
Definition: mythavutil.h:60
int Copy(AVFrame *To, const MythVideoFrame *From, unsigned char *Buffer, AVPixelFormat Fmt=AV_PIX_FMT_YUV420P)
Initialise AVFrame and copy contents of VideoFrame frame into it, performing any required conversion.
Definition: mythavutil.cpp:271
SwsContext * m_swsctx
Definition: mythavutil.h:58
AVPixelFormat m_format
Definition: mythavutil.h:57
int SizeData(int Width, int Height, AVPixelFormat Fmt)
Definition: mythavutil.cpp:226
int m_size
Definition: mythavutil.h:61
static void DeinterlaceAVFrame(AVFrame *Frame)
Deinterlace an AVFrame.
Definition: mythavutil.cpp:139
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
Definition: mythavutil.cpp:76
static MythHDR::HDRType FFmpegTransferToHDRType(int Transfer)
Definition: mythavutil.cpp:122
static int FillAVFrame(AVFrame *Frame, const MythVideoFrame *From, AVPixelFormat Fmt=AV_PIX_FMT_NONE)
Initialise AVFrame with content from MythVideoFrame.
Definition: mythavutil.cpp:203
static AVPixelFormat FrameTypeToPixelFormat(VideoFrameType Type)
Definition: mythavutil.cpp:32
void FreeAllContexts()
Definition: mythavutil.cpp:349
AVCodecContext * FindCodecContext(const AVStream *Stream)
Definition: mythavutil.cpp:329
QRecursiveMutex m_mapLock
Definition: mythavutil.h:40
AVCodecContext * GetCodecContext(const AVStream *Stream, const AVCodec *Codec=nullptr, bool NullCodec=false)
Definition: mythavutil.cpp:292
void FreeCodecContext(const AVStream *Stream)
Definition: mythavutil.cpp:337
QMap< const AVStream *, AVCodecContext * > m_streamMap
Definition: mythavutil.h:39
Handles software based deinterlacing of video frames.
void Filter(MythVideoFrame *Frame, FrameScanType Scan, MythVideoProfile *Profile, bool Force=false)
Deinterlace Frame if needed.
HDRType
Definition: mythhdr.h:37
@ SDR
Definition: mythhdr.h:38
@ HDR10
Definition: mythhdr.h:39
@ HLG
Definition: mythhdr.h:40
QVector< MythStreamInfo > m_streamInfoList
Definition: mythavutil.h:104
MythStreamInfoList(const QString &filename)
Definition: mythavutil.cpp:361
VideoFrameType m_type
Definition: mythframe.h:118
static size_t GetBufferSize(VideoFrameType Type, int Width, int Height, int Aligned=MYTH_WIDTH_ALIGNMENT)
Definition: mythframe.cpp:416
MythDeintType m_deinterlaceAllowed
Definition: mythframe.h:159
FramePitches m_pitches
Definition: mythframe.h:141
uint8_t * m_buffer
Definition: mythframe.h:119
MythDeintType m_deinterlaceSingle
Definition: mythframe.h:157
static bool YUVFormat(VideoFrameType Type)
Definition: mythframe.h:465
FrameOffsets m_offsets
Definition: mythframe.h:142
unsigned int uint
Definition: compat.h:60
MTV_PUBLIC std::string av_make_error_stdstring_unknown(int errnum)
Definition: mythaverror.h:47
@ DEINT_MEDIUM
Definition: mythframe.h:70
@ DEINT_ALL
Definition: mythframe.h:75
@ DEINT_CPU
Definition: mythframe.h:72
VideoFrameType
Definition: mythframe.h:20
@ FMT_RGB32
endian dependent format, ARGB or BGRA
Definition: mythframe.h:32
@ FMT_YUV420P9
Definition: mythframe.h:24
@ FMT_RGBA32
Definition: mythframe.h:34
@ FMT_YUV444P
Definition: mythframe.h:43
@ FMT_YUV420P14
Definition: mythframe.h:27
@ FMT_VAAPI
Definition: mythframe.h:57
@ FMT_YUV420P12
Definition: mythframe.h:26
@ FMT_VTB
Definition: mythframe.h:61
@ FMT_YUV422P10
Definition: mythframe.h:38
@ FMT_YUV444P16
Definition: mythframe.h:48
@ FMT_YUV422P9
Definition: mythframe.h:37
@ FMT_YUV422P14
Definition: mythframe.h:40
@ FMT_ARGB32
Definition: mythframe.h:33
@ FMT_YV12
Definition: mythframe.h:23
@ FMT_P016
Definition: mythframe.h:54
@ FMT_DRMPRIME
Definition: mythframe.h:63
@ FMT_RGB24
Definition: mythframe.h:30
@ FMT_VDPAU
Definition: mythframe.h:56
@ FMT_YUV444P12
Definition: mythframe.h:46
@ FMT_YUV444P9
Definition: mythframe.h:44
@ FMT_NONE
Definition: mythframe.h:21
@ FMT_YUV444P10
Definition: mythframe.h:45
@ FMT_NVDEC
Definition: mythframe.h:62
@ FMT_YUV422P
Definition: mythframe.h:36
@ FMT_YUV422P16
Definition: mythframe.h:41
@ FMT_YUV420P10
Definition: mythframe.h:25
@ FMT_YUV420P16
Definition: mythframe.h:28
@ FMT_P010
Definition: mythframe.h:53
@ FMT_NV12
Definition: mythframe.h:52
@ FMT_MMAL
Definition: mythframe.h:59
@ FMT_DXVA2
Definition: mythframe.h:58
@ FMT_YUY2
Definition: mythframe.h:50
@ FMT_YUV444P14
Definition: mythframe.h:47
@ FMT_BGRA
Definition: mythframe.h:31
@ FMT_YUV422P12
Definition: mythframe.h:39
@ FMT_MEDIACODEC
Definition: mythframe.h:60
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
dictionary info
Definition: azlyrics.py:7
@ kScan_Interlaced
Definition: videoouttypes.h:98