MythTV  master
videoout_nullvaapi.cpp
Go to the documentation of this file.
1 #include "videoout_nullvaapi.h"
2 #include "vaapicontext.h"
3 
4 #define LOC QString("NullVAAPI: ")
5 
7 {
8  opts.renderers->append("nullvaapi");
9  (*opts.osds)["nullvaapi"].append("dummy");
10  QStringList dummy(QString("dummy"));
11  opts.deints->insert("nullvaapi", dummy);
12  if (opts.decoders->contains("vaapi"))
13  (*opts.safe_renderers)["vaapi"].append("nullvaapi");
14  if (opts.decoders->contains("ffmpeg"))
15  (*opts.safe_renderers)["ffmpeg"].append("nullvaapi");
16  if (opts.decoders->contains("crystalhd"))
17  (*opts.safe_renderers)["crystalhd"].append("nullvaapi");
18  (*opts.safe_renderers)["dummy"].append("nullvaapi");
19  (*opts.safe_renderers)["nuppel"].append("nullvaapi");
20 
21  opts.priorities->insert("nullvaapi", 20);
22 }
23 
25  : m_ctx(nullptr), m_lock(QMutex::Recursive), m_shadowBuffers(nullptr)
26 {
27 }
28 
30 {
31  TearDown();
32 }
33 
35 {
36  QMutexLocker lock(&m_lock);
37  DeleteBuffers();
39 }
40 
42 {
43  QMutexLocker lock(&m_lock);
44  if (m_ctx)
46 
48  return m_ctx && m_ctx->CreateDisplay(size, true);
49 }
50 
52 {
53  QMutexLocker lock(&m_lock);
54  delete m_ctx;
55  m_ctx = nullptr;
56 }
57 
59 {
60  QMutexLocker lock(&m_lock);
62  !m_ctx->CreateBuffers())
63  {
64  return false;
65  }
66 
67  // create VAAPI buffers
68  vbuffers.Init(24, true, 2, 1, 4, 1);
69  int num_buffers = m_ctx->GetNumBuffers();
70  const QSize video_dim = window.GetActualVideoDim();
71  bool ok = true;
72  for (int i = 0; i < num_buffers; i++)
73  {
74  ok &= vbuffers.CreateBuffer(video_dim.width(),
75  video_dim.height(), i,
77  FMT_VAAPI);
78  }
79 
80  // create CPU buffers
82  if (!m_shadowBuffers)
83  return false;
84  m_shadowBuffers->Init(24, true, 2, 1, 4, 1);
86  video_dim.width(),
87  video_dim.height());
88 }
89 
91 {
92  QMutexLocker lock(&m_lock);
93  DiscardFrames(true);
94  vbuffers.Reset();
96  if (m_shadowBuffers)
97  {
100  }
101  delete m_shadowBuffers;
102  m_shadowBuffers = nullptr;
103 }
104 
106 {
107  QStringList list;
108  if ((codec_is_vaapi_hw(myth_codec_id)) && !getenv("NO_VAAPI"))
109  list += "nullvaapi";
110  return list;
111 }
112 
113 bool VideoOutputNullVAAPI::Init(const QSize &video_dim_buf,
114  const QSize &video_dim_disp,
115  float aspect,
116  WId winid, const QRect &win_rect,
117  MythCodecID codec_id)
118 {
119  QMutexLocker locker(&m_lock);
120  bool ok = VideoOutput::Init(video_dim_buf, video_dim_disp,
121  aspect, winid, win_rect, codec_id);
123  return false;
124 
125  if (db_vdisp_profile)
126  db_vdisp_profile->SetVideoRenderer("nullvaapi");
128  if (ok) ok = InitBuffers();
129  if (!ok)
130  return false;
131 
132  LOG(VB_PLAYBACK, LOG_INFO, LOC +
133  "Created VAAPI context with GPU decoding");
134  return ok;
135 }
136 
137 bool VideoOutputNullVAAPI::InputChanged(const QSize &video_dim_buf,
138  const QSize &video_dim_disp,
139  float aspect,
140  MythCodecID av_codec_id,
141  void */*codec_private*/,
142  bool &aspect_only)
143 {
144  LOG(VB_PLAYBACK, LOG_INFO, LOC +
145  QString("InputChanged(%1,%2,%3) '%4'->'%5'")
146  .arg(video_dim_disp.width()).arg(video_dim_disp.height())
147  .arg(aspect)
148  .arg(toString(video_codec_id)).arg(toString(av_codec_id)));
149 
150  QMutexLocker locker(&m_lock);
151 
152  bool cid_changed = (video_codec_id != av_codec_id);
153  bool res_changed = video_dim_disp != window.GetActualVideoDim();
154  if (!res_changed && !cid_changed)
155  {
156  aspect_only = true;
157  return true;
158  }
159 
160  TearDown();
161  QRect disp = window.GetDisplayVisibleRect();
162  if (Init(video_dim_buf, video_dim_disp,
163  aspect, 0, disp, av_codec_id))
164  {
165  return true;
166  }
167 
168  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
170  return false;
171 }
172 
173 void* VideoOutputNullVAAPI::GetDecoderContext(unsigned char* buf, uint8_t*& id)
174 {
175  if (m_ctx)
176  {
177  id = m_ctx->GetSurfaceIDPointer(buf);
178  return &m_ctx->m_ctx;
179  }
180  return nullptr;
181 }
182 
183 // Always returns the CPU version of a frame
185 {
187  for (uint i = 0; i < vbuffers.Size(); i++)
188  if (vbuffers.At(i) == gpu)
189  return m_shadowBuffers->At(i);
190  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find frame.");
191  return nullptr;
192 }
193 
194 // Always returns the CPU version of a frame
196 {
198  for (uint i = 0; i < vbuffers.Size(); i++)
199  if (vbuffers.At(i) == gpu)
200  return m_shadowBuffers->At(i);
201  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find frame.");
202  return nullptr;
203 }
204 
205 // Should work with either the CPU or GPU version of a frame
207 {
208  // is this a CPU frame
209  for (uint i = 0; i < m_shadowBuffers->Size(); i++)
210  {
211  if (m_shadowBuffers->At(i) == frame)
212  {
213  frame = vbuffers.At(i);
214  break;
215  }
216  }
217 
218  // is this a GPU frame
219  for (uint i = 0; i < vbuffers.Size(); i++)
220  {
221  if (vbuffers.At(i) == frame)
222  {
223  m_lock.lock();
224  vbuffers.DiscardFrame(frame);
225  m_lock.unlock();
226  return;
227  }
228  }
229 }
230 
231 // Should work with either the CPU or GPU version of a frame
233 {
234  // is this a CPU frame
235  for (uint i = 0; i < m_shadowBuffers->Size(); i++)
236  {
237  if (m_shadowBuffers->At(i) == frame)
238  {
239  frame = vbuffers.At(i);
240  break;
241  }
242  }
243 
244  // is this a GPU frame
245  for (uint i = 0; i < vbuffers.Size(); i++)
246  {
247  if (vbuffers.At(i) == frame)
248  {
249  m_lock.lock();
251  m_lock.unlock();
252  return;
253  }
254  }
255 }
256 
258 {
259  if (!frame)
260  return;
261 
262  if ((frame->codec != FMT_VAAPI) || !m_ctx)
263  {
265  return;
266  }
267 
268  QMutexLocker lock(&m_lock);
269  for (uint i = 0; i < vbuffers.Size() && m_ctx; i++)
270  {
271  if (vbuffers.At(i)->buf == frame->buf)
272  {
273  VideoFrame *vf = m_shadowBuffers->At(i);
274  vf->aspect = frame->aspect;
275  vf->disp_timecode = frame->disp_timecode;
276  vf->dummy = frame->dummy;
277  vf->frameNumber = frame->frameNumber;
278  vf->interlaced_frame = frame->interlaced_frame;
279  vf->timecode = frame->timecode;
280  vf->repeat_pict = frame->repeat_pict;
281  vf->top_field_first = frame->top_field_first;
283  }
284  }
286 }
virtual void ReleaseFrame(VideoFrame *frame)
Releases a frame from the ready for decoding queue onto the queue of frames ready for display.
Definition: videooutbase.h:212
void Reset(void)
Resets the class so that Init may be called again.
void SetVideoRenderer(const QString &video_renderer)
bool CreateVAAPIContext(QSize size)
VideoFrame * GetLastShownFrame(void)
Definition: videobuffers.h:106
QString toString(MarkTypes type)
virtual void DiscardFrames(bool kf)
Releases all frames not being actively displayed from any queue onto the queue of frames ready for de...
Definition: videooutbase.h:227
MythCodecID
Definition: mythcodecid.h:10
int repeat_pict
Definition: mythframe.h:59
virtual bool Init(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, WId winid, const QRect &win_rect, MythCodecID codec_id)
Performs most of the initialization for VideoOutput.
VideoFrame * At(uint i)
Definition: videobuffers.h:90
unsigned int uint
Definition: compat.h:140
long long timecode
Definition: mythframe.h:49
VideoDisplayProfile * db_vdisp_profile
Definition: videooutbase.h:330
uint Size(BufferType type) const
void DoneDisplayingFrame(VideoFrame *frame) override
Releases frame returned from GetLastShownFrame() onto the queue of frames ready for decoding onto.
bool CreateDisplay(QSize size, bool noreuse=false)
vaapi_context m_ctx
Definition: vaapicontext.h:62
bool CreateBuffers(VideoFrameType type, int width, int height, vector< unsigned char * > bufs, vector< YUVInfo > yuvinfo)
bool Init(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, WId winid, const QRect &win_rect, MythCodecID codec_id) override
Performs most of the initialization for VideoOutput.
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id)
float aspect
Definition: mythframe.h:43
VideoBuffers vbuffers
VideoBuffers instance used to track video output buffers.
Definition: videooutbase.h:357
VideoBuffers * m_shadowBuffers
static void GetRenderOptions(render_opts &opts)
MythCodecID video_codec_id
Definition: videooutbase.h:329
VideoErrorState errorState
Definition: videooutbase.h:360
VideoFrame * GetLastShownFrame(void) override
Returns frame from the head of the ready to be displayed queue, if StartDisplayingFrame has been call...
bool CreateBuffers(void)
uint8_t * GetSurfaceIDPointer(void *buf)
bool CreateBuffer(int width, int height, uint num, void *data, VideoFrameType fmt)
void * GetDecoderContext(unsigned char *buf, uint8_t *&id) override
long long frameNumber
Definition: mythframe.h:48
int top_field_first
1 if top field is first.
Definition: mythframe.h:58
QSize GetActualVideoDim(void) const
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
int64_t disp_timecode
Definition: mythframe.h:50
void DiscardFrame(VideoFrame *frame)
Frame is ready to be reused by decoder.
VideoFrame * GetLastDecodedFrame(void) override
bool InputChanged(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, MythCodecID av_codec_id, void *codec_private, bool &aspect_only) override
Tells video output to discard decoded frames and wait for new ones.
void ReleaseFrame(VideoFrame *frame) override
Releases a frame from the ready for decoding queue onto the queue of frames ready for display.
#define LOC
VideoFrame * GetLastDecodedFrame(void)
Definition: videobuffers.h:105
QRect GetDisplayVisibleRect(void) const
#define codec_is_vaapi_hw(id)
Definition: mythcodecid.h:136
VideoOutWindow window
Definition: videooutbase.h:320
int interlaced_frame
1 if interlaced.
Definition: mythframe.h:57
void DiscardFrame(VideoFrame *) override
Releases frame from any queue onto the queue of frames ready for decoding onto.
This class creates tracks the state of the buffers used by various VideoOutput derived classes.
Definition: videobuffers.h:61
void Init(uint numdecode, bool extra_for_pause, uint need_free, uint needprebuffer_normal, uint needprebuffer_small, uint keepprebuffer)
Creates buffers and sets various buffer management parameters.
void * GetVideoSurface(int i)
unsigned char * buf
Definition: mythframe.h:39
int GetNumBuffers(void) const
Definition: vaapicontext.h:42
void DeleteBuffers(void)
bool CopySurfaceToFrame(VideoFrame *frame, const void *buf)
virtual void DiscardFrame(VideoFrame *frame)
Releases frame from any queue onto the queue of frames ready for decoding onto.
Definition: videooutbase.h:224
VideoFrameType codec
Definition: mythframe.h:38