MythTV  master
mythcodeccontext.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-19 MythTV Developers <mythtv-dev@mythtv.org>
3 //
4 // This is part of MythTV (https://www.mythtv.org)
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 //
24 
25 #include "mythcorecontext.h"
26 #include "mythlogging.h"
27 #include "mythmainwindow.h"
28 #include "mythopenglinterop.h"
29 #include "avformatdecoder.h"
30 
31 #ifdef USING_VAAPI
32 #include "mythvaapicontext.h"
33 #endif
34 #ifdef USING_VDPAU
35 #include "mythvdpauhelper.h"
36 #include "mythvdpaucontext.h"
37 #endif
38 #ifdef USING_NVDEC
39 #include "mythnvdeccontext.h"
40 #endif
41 #ifdef USING_VTB
42 #include "mythvtbcontext.h"
43 #endif
44 #ifdef USING_MEDIACODEC
45 #include "mythmediacodeccontext.h"
46 #endif
47 #ifdef USING_V4L2
48 #include "mythv4l2m2mcontext.h"
49 #endif
50 #ifdef USING_MMAL
51 #include "mythmmalcontext.h"
52 #endif
53 #ifdef USING_EGL
54 #include "mythdrmprimecontext.h"
55 #endif
56 #include "mythcodeccontext.h"
57 
58 extern "C" {
59 #include "libavutil/pixdesc.h"
60 }
61 
62 #define LOC QString("MythCodecContext: ")
63 
65 
67  : m_parent(Parent),
68  m_codecID(CodecID)
69 {
70 }
71 
73 {
74  MythCodecContext *mctx = nullptr;
75 #ifdef USING_VAAPI
76  if (codec_is_vaapi(Codec) || codec_is_vaapi_dec(Codec))
77  mctx = new MythVAAPIContext(Parent, Codec);
78 #endif
79 #ifdef USING_VDPAU
80  if (codec_is_vdpau_hw(Codec) || codec_is_vdpau_dechw(Codec))
81  mctx = new MythVDPAUContext(Parent, Codec);
82 #endif
83 #ifdef USING_NVDEC
84  if (codec_is_nvdec_dec(Codec) || codec_is_nvdec(Codec))
85  mctx = new MythNVDECContext(Parent, Codec);
86 #endif
87 #ifdef USING_VTB
88  if (codec_is_vtb_dec(Codec) || codec_is_vtb(Codec))
89  mctx = new MythVTBContext(Parent, Codec);
90 #endif
91 #ifdef USING_MEDIACODEC
92  if (codec_is_mediacodec(Codec) || codec_is_mediacodec_dec(Codec))
93  mctx = new MythMediaCodecContext(Parent, Codec);
94 #endif
95 #ifdef USING_V4L2
96  if (codec_is_v4l2_dec(Codec) || codec_is_v4l2(Codec))
97  mctx = new MythV4L2M2MContext(Parent, Codec);
98 #endif
99 #ifdef USING_MMAL
100  if (codec_is_mmal_dec(Codec) || codec_is_mmal(Codec))
101  mctx = new MythMMALContext(Parent, Codec);
102 #endif
103 #ifdef USING_EGL
104  if (codec_is_drmprime(Codec))
105  mctx = new MythDRMPRIMEContext(Parent, Codec);
106 #endif
107  Q_UNUSED(Codec);
108 
109  if (!mctx)
110  mctx = new MythCodecContext(Parent, Codec);
111  return mctx;
112 }
113 
115 {
116 #ifdef USING_VDPAU
117  // Only enable VDPAU support if it is actually present
119  {
120  Opts.decoders->append("vdpau");
121  (*Opts.equiv_decoders)["vdpau"].append("dummy");
122  Opts.decoders->append("vdpau-dec");
123  (*Opts.equiv_decoders)["vdpau-dec"].append("dummy");
124  }
125 #endif
126 #ifdef USING_DXVA2
127  Opts.decoders->append("dxva2");
128  (*Opts.equiv_decoders)["dxva2"].append("dummy");
129 #endif
130 
131 #ifdef USING_VAAPI
132  // Only enable VAAPI if it is actually present and isn't actually VDPAU
134  {
135  Opts.decoders->append("vaapi");
136  (*Opts.equiv_decoders)["vaapi"].append("dummy");
137  Opts.decoders->append("vaapi-dec");
138  (*Opts.equiv_decoders)["vaapi-dec"].append("dummy");
139  }
140 #endif
141 #ifdef USING_NVDEC
142  // Only enable NVDec support if it is actually present
144  {
145  Opts.decoders->append("nvdec");
146  (*Opts.equiv_decoders)["nvdec"].append("dummy");
147  Opts.decoders->append("nvdec-dec");
148  (*Opts.equiv_decoders)["nvdec-dec"].append("dummy");
149  }
150 #endif
151 #ifdef USING_MEDIACODEC
152  Opts.decoders->append("mediacodec");
153  (*Opts.equiv_decoders)["mediacodec"].append("dummy");
154  Opts.decoders->append("mediacodec-dec");
155  (*Opts.equiv_decoders)["mediacodec-dec"].append("dummy");
156 #endif
157 #ifdef USING_VTB
158  Opts.decoders->append("vtb");
159  Opts.decoders->append("vtb-dec");
160  (*Opts.equiv_decoders)["vtb"].append("dummy");
161  (*Opts.equiv_decoders)["vtb-dec"].append("dummy");
162 #endif
163 #ifdef USING_V4L2
165  {
166 #ifdef USING_V4L2PRIME
167  Opts.decoders->append("v4l2");
168  (*Opts.equiv_decoders)["v4l2"].append("dummy");
169 #endif
170  Opts.decoders->append("v4l2-dec");
171  (*Opts.equiv_decoders)["v4l2-dec"].append("dummy");
172  }
173 #endif
174 #ifdef USING_EGL
176  {
177  Opts.decoders->append("drmprime");
178  (*Opts.equiv_decoders)["drmprime"].append("dummy");
179  }
180 #endif
181 #ifdef USING_MMAL
182  Opts.decoders->append("mmal-dec");
183  (*Opts.equiv_decoders)["mmal-dec"].append("dummy");
185  {
186  Opts.decoders->append("mmal");
187  (*Opts.equiv_decoders)["mmal"].append("dummy");
188  }
189 #endif
190 }
191 
192 MythCodecID MythCodecContext::FindDecoder(const QString &Decoder, AVStream *Stream,
193  AVCodecContext **Context, AVCodec **Codec)
194 {
195  MythCodecID result = kCodec_NONE;
196  uint streamtype = mpeg_version((*Context)->codec_id);
197 
198 #ifdef USING_VDPAU
199  result = MythVDPAUContext::GetSupportedCodec(Context, Codec, Decoder, streamtype);
200  if (codec_is_vdpau_hw(result) || codec_is_vdpau_dechw(result))
201  return result;
202 #endif
203 #ifdef USING_VAAPI
204  result = MythVAAPIContext::GetSupportedCodec(Context, Codec, Decoder, streamtype);
205  if (codec_is_vaapi(result) || codec_is_vaapi_dec(result))
206  return result;
207 #endif
208 #ifdef USING_VTB
209  (void)Stream;
210  result = MythVTBContext::GetSupportedCodec(Context, Codec, Decoder, streamtype);
211  if (codec_is_vtb(result) || codec_is_vtb_dec(result))
212  return result;
213 #endif
214 #ifdef USING_DXVA2
215  result = VideoOutputD3D::GetBestSupportedCodec(width, height, Decoder, streamtype, false);
216  if (codec_is_dxva2(result))
217  return result;
218 #endif
219 #ifdef USING_MEDIACODEC
220  result = MythMediaCodecContext::GetBestSupportedCodec(Context, Codec, Decoder, Stream, streamtype);
221  if (codec_is_mediacodec(result) || codec_is_mediacodec_dec(result))
222  return result;
223 #endif
224 #ifdef USING_NVDEC
225  result = MythNVDECContext::GetSupportedCodec(Context, Codec, Decoder, Stream, streamtype);
226  if (codec_is_nvdec(result) || codec_is_nvdec_dec(result))
227  return result;
228 #endif
229 #ifdef USING_V4L2
230  result = MythV4L2M2MContext::GetSupportedCodec(Context, Codec, Decoder, Stream, streamtype);
231  if (codec_is_v4l2_dec(result) || codec_is_v4l2(result))
232  return result;
233 #endif
234 #ifdef USING_MMAL
235  result = MythMMALContext::GetSupportedCodec(Context, Codec, Decoder, Stream, streamtype);
236  if (codec_is_mmal_dec(result) || codec_is_mmal(result))
237  return result;
238 #endif
239 #ifdef USING_EGL
240  result = MythDRMPRIMEContext::GetSupportedCodec(Context, Codec, Decoder, Stream, streamtype);
241  if (codec_is_drmprime(result))
242  return result;
243 #endif
244 
245  return kCodec_NONE;
246 }
247 
249  bool SelectedStream, bool &DirectRendering)
250 {
251  const AVCodec *codec1 = Context->codec;
252  if (codec1 && codec1->capabilities & AV_CODEC_CAP_DR1)
253  {
254  // Context->flags |= CODEC_FLAG_EMU_EDGE;
255  }
256  else
257  {
258  if (SelectedStream)
259  DirectRendering = false;
260  LOG(VB_PLAYBACK, LOG_INFO, LOC +
261  QString("Using software scaling to convert pixel format %1 for "
262  "codec %2").arg(av_get_pix_fmt_name(Context->pix_fmt))
263  .arg(ff_codec_id_string(Context->codec_id)));
264  }
265 }
266 
268 int MythCodecContext::GetBuffer(struct AVCodecContext *Context, AVFrame *Frame, int Flags)
269 {
270  auto *avfd = static_cast<AvFormatDecoder*>(Context->opaque);
271  VideoFrame *videoframe = avfd->GetPlayer()->GetNextVideoFrame();
272 
273  // set fields required for directrendering
274  for (int i = 0; i < 4; i++)
275  {
276  Frame->data[i] = nullptr;
277  Frame->linesize[i] = 0;
278  }
279  Frame->opaque = videoframe;
280  videoframe->pix_fmt = Context->pix_fmt;
281  Frame->reordered_opaque = Context->reordered_opaque;
282 
283  int ret = avcodec_default_get_buffer2(Context, Frame, Flags);
284  if (ret < 0)
285  return ret;
286 
287  // set the underlying pixel format. Set here rather than guessing later.
288  if (Frame->hw_frames_ctx)
289  {
290  auto *context = reinterpret_cast<AVHWFramesContext*>(Frame->hw_frames_ctx->data);
291  if (context)
292  videoframe->sw_pix_fmt = context->sw_format;
293  }
294 
295  // VAAPI 'fixes' 10/12/16bit colour values. Irrelevant for VDPAU.
296  videoframe->colorshifted = 1;
297 
298  // avcodec_default_get_buffer2 will retrieve an AVBufferRef from the pool of
299  // hardware surfaces stored within AVHWFramesContext. The pointer to the surface is stored
300  // in Frame->data[3]. Store this in VideoFrame::buf for the interop class to use.
301  videoframe->buf = Frame->data[3];
302  // Frame->buf(0) also contains a reference to the buffer. Take an additional reference to this
303  // buffer to retain the surface until it has been displayed (otherwise it is
304  // reused once the decoder is finished with it).
305  videoframe->priv[0] = reinterpret_cast<unsigned char*>(av_buffer_ref(Frame->buf[0]));
306  // frame->hw_frames_ctx contains a reference to the AVHWFramesContext. Take an additional
307  // reference to ensure AVHWFramesContext is not released until we are finished with it.
308  // This also contains the underlying MythOpenGLInterop class reference.
309  videoframe->priv[1] = reinterpret_cast<unsigned char*>(av_buffer_ref(Frame->hw_frames_ctx));
310 
311  // Set release method
312  Frame->buf[1] = av_buffer_create(reinterpret_cast<uint8_t*>(videoframe), 0,
314  return ret;
315 }
316 
317 
319 bool MythCodecContext::GetBuffer2(struct AVCodecContext *Context, VideoFrame* Frame,
320  AVFrame *AvFrame, int /*Flags*/)
321 {
322  if (!AvFrame || !Context || !Frame)
323  return false;
324 
325  auto *avfd = static_cast<AvFormatDecoder*>(Context->opaque);
326 
327  Frame->pix_fmt = Context->pix_fmt;
328  Frame->directrendering = 1;
329  Frame->colorshifted = 1;
330 
331  AvFrame->reordered_opaque = Context->reordered_opaque;
332  AvFrame->opaque = Frame;
333 
334  // retrieve the software format
335  if (AvFrame->hw_frames_ctx)
336  {
337  auto *context = reinterpret_cast<AVHWFramesContext*>(AvFrame->hw_frames_ctx->data);
338  if (context)
339  Frame->sw_pix_fmt = context->sw_format;
340  }
341 
342  // the hardware surface is stored in Frame->data[3]
343  Frame->buf = AvFrame->data[3];
344 
345  // Frame->buf[0] contains the release method. Take another reference to
346  // ensure the frame is not released before it is displayed.
347  Frame->priv[0] = reinterpret_cast<unsigned char*>(av_buffer_ref(AvFrame->buf[0]));
348 
349  // Retrieve and set the interop class
350  auto *devicectx = reinterpret_cast<AVHWDeviceContext*>(Context->hw_device_ctx->data);
351  Frame->priv[1] = reinterpret_cast<unsigned char*>(devicectx->user_opaque);
352 
353  // Set release method
354  AvFrame->buf[1] = av_buffer_create(reinterpret_cast<uint8_t*>(Frame), 0,
356  return true;
357 }
358 
359 void MythCodecContext::ReleaseBuffer(void *Opaque, uint8_t *Data)
360 {
361  auto *decoder = static_cast<AvFormatDecoder*>(Opaque);
362  auto *frame = reinterpret_cast<VideoFrame*>(Data);
363  if (decoder && decoder->GetPlayer())
364  decoder->GetPlayer()->DeLimboFrame(frame);
365 }
366 
367 void MythCodecContext::DestroyInteropCallback(void *Wait, void *Interop, void* /*unused*/)
368 {
369  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Destroy interop callback");
370  auto *wait = reinterpret_cast<QWaitCondition*>(Wait);
371  auto *interop = reinterpret_cast<MythOpenGLInterop*>(Interop);
372  if (interop)
373  interop->DecrRef();
374  if (wait)
375  wait->wakeAll();
376 }
377 
386 {
387  int count = ++s_hwFramesContextCount;
388  if (count != 1)
389  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Error: %1 concurrent hardware frames contexts").arg(count));
390 }
391 
393 {
395  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("%1 frames context finished")
396  .arg(av_hwdevice_get_type_name(Context->device_ctx->type)));
397  auto *interop = reinterpret_cast<MythOpenGLInterop*>(Context->user_opaque);
398  if (interop)
399  DestroyInterop(interop);
400 }
401 
403 {
404  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("%1 device context finished")
405  .arg(av_hwdevice_get_type_name(Context->type)));
406  auto *interop = reinterpret_cast<MythOpenGLInterop*>(Context->user_opaque);
407  if (interop)
408  {
409  DestroyInterop(interop);
410  FreeAVHWDeviceContext free = interop->GetDefaultFree();
411  if (free)
412  {
413  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Calling default device context free");
414  Context->user_opaque = interop->GetDefaultUserOpaque();
415  free(Context);
416  }
417  }
418 }
419 
421 {
422  if (gCoreContext->IsUIThread())
423  Interop->DecrRef();
424  else
425  MythMainWindow::HandleCallback("destroy OpenGL interop", MythCodecContext::DestroyInteropCallback, Interop, nullptr);
426 }
427 
429 {
430  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Create decoder callback");
431  auto *wait = reinterpret_cast<QWaitCondition*>(Wait);
432  auto *context = reinterpret_cast<AVCodecContext*>(Context);
433  auto callback = reinterpret_cast<CreateHWDecoder>(Callback);
434  if (context && callback)
435  (void)callback(context);
436  if (wait)
437  wait->wakeAll();
438 }
439 
442  const QString &Debug)
443 {
444  if (!Context || !Callback)
445  return -1;
446  if (gCoreContext->IsUIThread())
447  return Callback(Context);
449  Context, reinterpret_cast<void*>(Callback));
450  return Context->hw_frames_ctx ? 0 : -1;
451 }
452 
455  const QString &Debug)
456 {
457  if (!Context || !Callback)
458  return -1;
459  if (gCoreContext->IsUIThread())
460  return Callback(Context);
462  Context, reinterpret_cast<void*>(Callback));
463  return Context->hw_device_ctx ? 0 : -1;
464 }
465 
466 AVBufferRef* MythCodecContext::CreateDevice(AVHWDeviceType Type, MythOpenGLInterop *Interop, const QString &Device)
467 {
468  AVBufferRef* result = nullptr;
469  int res = av_hwdevice_ctx_create(&result, Type, Device.isEmpty() ? nullptr :
470  Device.toLocal8Bit().constData(), nullptr, 0);
471  if (res == 0)
472  {
473  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created hardware device '%1'%2")
474  .arg(av_hwdevice_get_type_name(Type))
475  .arg(Device == nullptr ? "" : QString(" (%1)").arg(Device)));
476  auto *context = reinterpret_cast<AVHWDeviceContext*>(result->data);
477 
478  if ((context->free || context->user_opaque) && !Interop)
479  {
480  LOG(VB_PLAYBACK, LOG_INFO, "Creating dummy interop");
481  Interop = MythOpenGLInterop::CreateDummy();
482  }
483 
484  if (Interop)
485  {
486  Interop->SetDefaultFree(context->free);
487  Interop->SetDefaultUserOpaque(context->user_opaque);
488  Interop->IncrRef();
489  }
490 
492  context->user_opaque = Interop;
493  return result;
494  }
495 
496  char error[AV_ERROR_MAX_STRING_SIZE];
497  LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Failed to create hardware device '%1'%2 Error '%3'")
498  .arg(av_hwdevice_get_type_name(Type))
499  .arg(Device == nullptr ? "" : QString(" (%1)").arg(Device))
500  .arg(av_make_error_string(error, sizeof(error), res)));
501  return nullptr;
502 }
503 
506 {
507  switch (Context->codec_id)
508  {
509  case AV_CODEC_ID_H264:
510  switch (Context->profile)
511  {
512  case FF_PROFILE_H264_HIGH_10:
513  case FF_PROFILE_H264_HIGH_10_INTRA:
514  case FF_PROFILE_H264_HIGH_422:
515  case FF_PROFILE_H264_HIGH_422_INTRA:
516  case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
517  case FF_PROFILE_H264_HIGH_444_INTRA:
518  case FF_PROFILE_H264_CAVLC_444: return true;
519  default: break;
520  }
521  break;
522  default: break;
523  }
524  return false;
525 }
526 
531 {
532  return avcodec_receive_frame(Context, Frame);
533 }
534 
536 {
537  if (!Frame || !AvFrame)
538  return false;
539 
540  AVFrame *temp = av_frame_alloc();
541  if (!temp)
542  return false;
543 
544  AVPixelFormat *pixelformats = nullptr;
545  int ret = av_hwframe_transfer_get_formats(AvFrame->hw_frames_ctx,
546  AV_HWFRAME_TRANSFER_DIRECTION_FROM,
547  &pixelformats, 0);
548  if (ret == 0)
549  {
550  AVPixelFormat best = m_parent->GetBestVideoFormat(pixelformats);
551  if (best != AV_PIX_FMT_NONE)
552  {
554  bool valid = Frame->codec == type;
555  if (!valid || (Frame->width != AvFrame->width) || (Frame->height != AvFrame->height))
557  AvFrame->width, AvFrame->height);
558 
559  if (valid)
560  {
561  // Retrieve the picture directly into the VideoFrame Buffer
562  temp->format = best;
563  uint max = planes(Frame->codec);
564  for (uint i = 0; i < 3; i++)
565  {
566  temp->data[i] = (i < max) ? (Frame->buf + Frame->offsets[i]) : nullptr;
567  temp->linesize[i] = Frame->pitches[i];
568  }
569 
570  // Dummy release method - we do not want to free the buffer
571  temp->buf[0] = av_buffer_create(reinterpret_cast<uint8_t*>(Frame), 0,
572  [](void* /*unused*/, uint8_t* /*unused*/){}, this, 0);
573  temp->width = AvFrame->width;
574  temp->height = AvFrame->height;
575  }
576  }
577  }
578  av_freep(&pixelformats);
579 
580  // retrieve data from GPU to CPU
581  if (ret >= 0)
582  if ((ret = av_hwframe_transfer_data(temp, AvFrame, 0)) < 0)
583  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error %1 transferring the data to system memory").arg(ret));
584 
585  Frame->colorshifted = 1;
586  av_frame_free(&temp);
587  return ret >= 0;
588 }
int(*)(AVCodecContext *Context) CreateHWDecoder
static bool HaveVAAPI(bool ReCheck=false)
Check whether VAAPI is available and not emulated via VDPAU.
static bool HaveV4L2Codecs(AVCodecID Codec=AV_CODEC_ID_NONE)
static void ReleaseBuffer(void *Opaque, uint8_t *Data)
#define codec_is_mmal(id)
Definition: mythcodecid.h:324
void(*)(struct AVHWDeviceContext *) FreeAVHWDeviceContext
unsigned char * buf
Definition: mythframe.h:139
QHash< QString, Action * > Context
Definition: action.h:75
virtual MythCodecID GetVideoCodecID(void) const =0
static Type GetInteropType(VideoFrameType Format)
Check whether we support direct rendering for the given VideoFrameType.
MythCodecID
Definition: mythcodecid.h:10
#define codec_is_vtb_dec(id)
Definition: mythcodecid.h:318
static void error(const char *str,...)
Definition: vbi.c:42
static MythCodecID GetSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
#define codec_is_mmal_dec(id)
Definition: mythcodecid.h:325
static int InitialiseDecoder(AVCodecContext *Context, CreateHWDecoder Callback, const QString &Debug)
Initialise a hardware decoder that is expected to use AVHWFramesContext.
static MythCodecID GetSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
struct AVFrame AVFrame
static bool HaveNVDEC(void)
static int GetBuffer(struct AVCodecContext *Context, AVFrame *Frame, int Flags)
A generic hardware buffer initialisation method when using AVHWFramesContext.
VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt)
Definition: mythavutil.cpp:68
VideoFrameType
Definition: mythframe.h:23
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define codec_is_v4l2_dec(id)
Definition: mythcodecid.h:322
static bool IsUnsupportedProfile(AVCodecContext *Context)
Most hardware decoders do not support these codecs/profiles.
static uint planes(VideoFrameType Type)
Definition: mythframe.h:567
DecoderBase * m_parent
#define LOC
static bool ReinitBuffer(VideoFrame *Frame, VideoFrameType Type, MythCodecID CodecID, int Width, int Height)
static bool HavePrimeDecoders(AVCodecID Codec=AV_CODEC_ID_NONE)
static MythCodecID FindDecoder(const QString &Decoder, AVStream *Stream, AVCodecContext **Context, AVCodec **Codec)
A generic context handler for codecs that return AV_PIX_FMT_DRM_PRIME frames.
virtual int FilteredReceiveFrame(AVCodecContext *Context, AVFrame *Frame)
Retrieve and process/filter AVFrame.
static MythCodecID GetBestSupportedCodec(uint width, uint height, const QString &decoder, uint stream_type, bool no_acceleration, AVPixelFormat &pix_fmt)
static void HandleCallback(const QString &Debug, MythCallbackEvent::Callback Function, void *Opaque1, void *Opaque2)
Static convenience method to initiate a callback into the UI thread and wait for the result.
static MythOpenGLInterop * CreateDummy(void)
#define codec_is_nvdec_dec(id)
Definition: mythcodecid.h:313
A device containing images (ie. USB stick, CD, storage group etc)
#define codec_is_vaapi(id)
Definition: mythcodecid.h:294
static void DestroyInteropCallback(void *Wait, void *Interop, void *)
unsigned char * priv[4]
random empty storage
Definition: mythframe.h:151
virtual int IncrRef(void)
Increments reference count.
static void CreateDecoderCallback(void *Wait, void *Context, void *Callback)
#define codec_is_dxva2(id)
Definition: mythcodecid.h:299
MythCodecContext(DecoderBase *Parent, MythCodecID CodecID)
static int InitialiseDecoder2(AVCodecContext *Context, CreateHWDecoder Callback, const QString &Debug)
Initialise a hardware decoder that is NOT expected to use AVHWFramesContext.
static MythCodecID GetBestSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
virtual void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
void SetDefaultUserOpaque(void *UserOpaque)
#define codec_is_vaapi_dec(id)
Definition: mythcodecid.h:296
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
int pix_fmt
Definition: mythframe.h:161
static MythCodecID GetSupportedCodec(AVCodecContext **CodecContext, AVCodec **Codec, const QString &Decoder, uint StreamType)
unsigned int uint
Definition: compat.h:140
static MythCodecContext * CreateContext(DecoderBase *Parent, MythCodecID Codec)
#define codec_is_mediacodec(id)
Definition: mythcodecid.h:306
static MythCodecID GetSupportedCodec(AVCodecContext **CodecContext, AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
Determine whether NVDEC decoding is supported for this codec.
A handler for V4L2 Memory2Memory codecs.
static void FramesContextFinished(AVHWFramesContext *Context)
AVPixelFormat GetBestVideoFormat(AVPixelFormat *Formats)
Find a suitable frame format that is mutually acceptable to the decoder and render device.
QMap< QString, QStringList > * equiv_decoders
static bool HaveVDPAU(void)
QStringList * decoders
uint mpeg_version(int codec_id)
#define codec_is_vtb(id)
Definition: mythcodecid.h:316
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
static void DestroyInterop(MythOpenGLInterop *Interop)
static bool GetBuffer2(struct AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame, int Flags)
A generic hardware buffer initialisation method when AVHWFramesContext is NOT used.
#define codec_is_vdpau_dechw(id)
Definition: mythcodecid.h:289
int sw_pix_fmt
Definition: mythframe.h:162
static void DeviceContextFinished(AVHWDeviceContext *Context)
int colorshifted
0 for software decoded 10/12/16bit frames. 1 for hardware decoders.
Definition: mythframe.h:169
static void NewHardwareFramesContext(void)
Track the number of concurrent frames contexts.
static QAtomicInt s_hwFramesContextCount
#define codec_is_vdpau_hw(id)
Definition: mythcodecid.h:283
#define codec_is_nvdec(id)
Definition: mythcodecid.h:311
static MythCodecID GetSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, uint StreamType)
virtual bool RetrieveHWFrame(VideoFrame *Frame, AVFrame *AvFrame)
#define codec_is_drmprime(id)
Definition: mythcodecid.h:279
void SetDefaultFree(FreeAVHWDeviceContext FreeContext)
static MythCodecID GetSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
static MythCodecID GetSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, uint StreamType)
Confirm whether VAAPI support is available given Decoder and Context.
static AVBufferRef * CreateDevice(AVHWDeviceType Type, MythOpenGLInterop *Interop, const QString &Device=QString())
#define codec_is_v4l2(id)
Definition: mythcodecid.h:321
#define codec_is_mediacodec_dec(id)
Definition: mythcodecid.h:308
static void GetDecoders(RenderOptions &Opts)