MythTV  0.28pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
videoout_openglvaapi.cpp
Go to the documentation of this file.
1 #include "videoout_openglvaapi.h"
2 #include "vaapicontext.h"
3 
4 #define LOC QString("VidOutGLVAAPI: ")
5 #define ERR QString("VidOutGLVAAPI Error: ")
6 
8 {
9  opts.renderers->append("openglvaapi");
10 
11  (*opts.deints)["openglvaapi"].append("vaapionefield");
12  (*opts.deints)["openglvaapi"].append("vaapibobdeint");
13  (*opts.deints)["openglvaapi"].append("none");
14  (*opts.osds)["openglvaapi"].append("opengl2");
15 
16  if (opts.decoders->contains("vaapi"))
17  (*opts.safe_renderers)["vaapi"].append("openglvaapi");
18 
19  if (opts.decoders->contains("ffmpeg"))
20  (*opts.safe_renderers)["ffmpeg"].append("openglvaapi");
21 
22  (*opts.safe_renderers)["dummy"].append("openglvaapi");
23  (*opts.safe_renderers)["nuppel"].append("openglvaapi");
24 
25  opts.priorities->insert("openglvaapi", 110);
26 }
27 
29  : VideoOutputOpenGL(), m_ctx(NULL), m_pauseBuffer(NULL)
30 {
31 }
32 
34 {
35  TearDown();
36 }
37 
39 {
41 }
42 
43 bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &video_dim_buf,
44  const QSize &video_dim_disp,
45  float aspect,
46  MythCodecID av_codec_id, void *codec_private,
47  bool &aspect_only)
48 {
49  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
50  .arg(video_dim_disp.width()).arg(video_dim_disp.height())
51  .arg(aspect)
52  .arg(toString(video_codec_id)).arg(toString(av_codec_id)));
53 
54  if (!codec_is_vaapi(av_codec_id))
55  return VideoOutputOpenGL::InputChanged(video_dim_buf, video_dim_disp,
56  aspect, av_codec_id,
57  codec_private, aspect_only);
58 
59  QMutexLocker locker(&gl_context_lock);
60 
61  bool wasembedding = window.IsEmbedding();
62  QRect oldrect;
63  if (wasembedding)
64  {
65  oldrect = window.GetEmbeddingRect();
66  StopEmbedding();
67  }
68 
69  bool cid_changed = (video_codec_id != av_codec_id);
70  bool res_changed = video_dim_disp != window.GetActualVideoDim();
71  bool asp_changed = aspect != window.GetVideoAspect();
72 
73  if (!res_changed && !cid_changed)
74  {
75  if (asp_changed)
76  {
77  aspect_only = true;
79  MoveResize();
80  if (wasembedding)
81  EmbedInWidget(oldrect);
82  }
83  return true;
84  }
85 
86  if (gCoreContext->IsUIThread())
87  TearDown();
88  else
90 
91  QRect disp = window.GetDisplayVisibleRect();
92  if (Init(video_dim_buf, video_dim_disp,
93  aspect, gl_parent_win, disp, av_codec_id))
94  {
95  if (wasembedding)
96  EmbedInWidget(oldrect);
97  if (gCoreContext->IsUIThread())
98  BestDeint();
99  return true;
100  }
101 
102  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
104 
105  return false;
106 }
107 
108 bool VideoOutputOpenGLVAAPI::Init(const QSize &video_dim_buf,
109  const QSize &video_dim_disp,
110  float aspect,
111  WId winid, const QRect &win_rect,
112  MythCodecID codec_id)
113 {
114  bool ok = VideoOutputOpenGL::Init(video_dim_buf, video_dim_disp,
115  aspect, winid,
116  win_rect, codec_id);
117  if (ok && codec_is_vaapi(video_codec_id))
119  return ok;
120 }
121 
123 {
124  // FIXME During a video stream change this is called from the decoder
125  // thread - which breaks all other efforts to remove non-UI thread
126  // access to the OpenGL context. There is no obvious fix however - if we
127  // don't delete and re-create the VAAPI decoder context immediately then
128  // the decoder fails and playback exits.
129  OpenGLLocker ctx_lock(gl_context);
130 
131  if (m_ctx)
133 
135  if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers())
136  {
137  int num_buffers = m_ctx->GetNumBuffers();
138  const QSize video_dim = window.GetActualVideoDim();
139 
140  bool ok = true;
141  for (int i = 0; i < num_buffers; i++)
142  {
143  ok &= vbuffers.CreateBuffer(video_dim.width(),
144  video_dim.height(), i,
146  FMT_VAAPI);
147  }
149  return ok;
150  }
151 
152  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VAAPI context.");
154  return false;
155 }
156 
158 {
159  QMutexLocker locker(&gl_context_lock);
160  delete m_ctx;
161  m_ctx = NULL;
162 }
163 
165 {
166  QMutexLocker locker(&gl_context_lock);
167  if (codec_is_vaapi(video_codec_id))
168  {
169  vbuffers.Init(24, true, 2, 1, 4, 1);
170  return true;
171  }
173 }
174 
175 void* VideoOutputOpenGLVAAPI::GetDecoderContext(unsigned char* buf, uint8_t*& id)
176 {
177  if (m_ctx)
178  {
179  id = GetSurfaceIDPointer(buf);
180  return &m_ctx->m_ctx;
181  }
182  return NULL;
183 }
184 
186 {
187  if (m_ctx)
188  return m_ctx->GetSurfaceIDPointer(buf);
189  return NULL;
190 }
191 
193 {
194  if (db_vdisp_profile)
195  db_vdisp_profile->SetVideoRenderer("openglvaapi");
196 }
197 
198 bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const
199 {
200  return filtername.contains("vaapi");
201 }
202 
204 {
205  m_deinterlacing = enable;
206  SetupDeinterlace(enable);
207  return m_deinterlacing;
208 }
209 
210 bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf)
211 {
212  //m_deintfiltername = !db_vdisp_profile ? "" :
213  // db_vdisp_profile->GetFilteredDeint(ovrf);
214  m_deinterlacing = i;
215  return m_deinterlacing;
216 }
217 
219 {
220  if (codec_is_vaapi(video_codec_id))
221  {
222  if (m_ctx)
224  return;
225  }
227 }
228 
230  int newValue)
231 {
232  int val = newValue;
233  if (codec_is_vaapi(video_codec_id) && m_ctx)
234  val = m_ctx->SetPictureAttribute(attribute, newValue);
235  return VideoOutput::SetPictureAttribute(attribute, val);
236 }
237 
238 void VideoOutputOpenGLVAAPI::UpdatePauseFrame(int64_t &disp_timecode)
239 {
240  if (codec_is_std(video_codec_id))
241  {
243  return;
244  }
245 
248  {
250  CopyFrame(&av_pause_frame, frame);
251  m_pauseBuffer = frame->buf;
252  disp_timecode = frame->disp_timecode;
253  }
254  else
255  LOG(VB_PLAYBACK, LOG_WARNING, LOC +
256  "Could not update pause frame - no used frames.");
257 
258  vbuffers.end_lock();
259 }
260 
262  FilterChain *filterList,
263  const PIPMap &pipPlayers,
265 {
266  QMutexLocker locker(&gl_context_lock);
267  VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan);
268 
269  if (codec_is_vaapi(video_codec_id) && m_ctx && gl_videochain)
270  {
272  m_ctx->CopySurfaceToTexture(frame ? frame->buf : m_pauseBuffer,
277  }
278 }
279 
281  MythCodecID myth_codec_id, const QSize &video_dim)
282 {
283  (void) video_dim;
284  QStringList list;
285  if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) &&
286  !getenv("NO_VAAPI"))
287  {
288  list += "openglvaapi";
289  }
290  return list;
291 }
292 
294  uint width, uint height, const QString &decoder,
295  uint stream_type, bool no_acceleration,
296  PixelFormat &pix_fmt)
297 {
298  QSize size(width, height);
299  bool use_cpu = no_acceleration;
300  PixelFormat fmt = PIX_FMT_YUV420P;
301  MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type - 1));
302  if (codec_is_vaapi(test_cid) && decoder == "vaapi" && !getenv("NO_VAAPI"))
303  use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, fmt);
304  else
305  use_cpu = true;
306 
307  if (use_cpu)
308  return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1));
309 
310  pix_fmt = fmt;
311  return test_cid;
312 }
bool CopySurfaceToTexture(const void *buf, uint texture, uint texture_type, FrameScanType scan)
void StopEmbedding(void)
Tells video output to stop embedding video in an existing window.
virtual int SetPictureAttribute(PictureAttribute, int newValue)
Sets a specified picture attribute.
int GetNumBuffers(void) const
Definition: vaapicontext.h:42
void SetVideoRenderer(const QString &video_renderer)
virtual void InitPictureAttributes(void)
typedef void(__LZO_CDECL *lzo_free_func_t)(lzo_callback_p self
QMap< MythPlayer *, PIPLocation > PIPMap
Definition: videooutbase.h:36
priority_map_t * priorities
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.
QString toString(MarkTypes type)
bool m_deinterlacing
Definition: videooutbase.h:333
MythCodecID
Definition: mythcodecid.h:10
VideoColourSpace videoColourSpace
Definition: videooutbase.h:305
void DestroyCPUResources(void)
safe_list_t * renderers
uint8_t * GetSurfaceIDPointer(void *buf)
QRect GetDisplayVisibleRect(void) const
safe_map_t * deints
virtual void * GetDecoderContext(unsigned char *buf, uint8_t *&id)
bool CreateVAAPIContext(QSize size)
QSize GetActualVideoDim(void) const
FrameScanType
Definition: videoouttypes.h:76
unsigned int uint
Definition: compat.h:135
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
virtual void InitPictureAttributes(void)
bool InputChanged(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, MythCodecID av_codec_id, void *codec_private, bool &aspect_only)
Tells video output to discard decoded frames and wait for new ones.
VideoDisplayProfile * db_vdisp_profile
Definition: videooutbase.h:313
virtual void doneCurrent()
uint GetInputTexture(void) const
voidpf void * buf
Definition: ioapi.h:136
bool CreateDisplay(QSize size, bool noreuse=false)
vaapi_context m_ctx
Definition: vaapicontext.h:62
bool ApproveDeintFilter(const QString &filtername) const
Approves bobdeint filter for XVideo and otherwise defers to VideoOutput::ApproveDeintFilter(const QSt...
safe_list_t * decoders
QRect GetEmbeddingRect(void) const
safe_map_t * osds
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.
bool SetupDeinterlace(bool i, const QString &ovrf="")
Attempts to enable or disable deinterlacing.
virtual int SetPictureAttribute(PictureAttribute attribute, int newValue)
Sets a specified picture attribute.
static void CopyFrame(VideoFrame *to, const VideoFrame *from)
Copies frame data from one VideoFrame to another.
virtual bool CreateBuffers(void)
static void GetRenderOptions(render_opts &opts)
VideoBuffers vbuffers
VideoBuffers instance used to track video output buffers.
Definition: videooutbase.h:340
MythCodecID video_codec_id
Definition: videooutbase.h:312
VideoErrorState errorState
Definition: videooutbase.h:343
virtual void BestDeint(void)
Change to the best deinterlacing method.
void MoveResize(void)
performs all the calculations for video framing and any resizing.
bool CreateBuffers(void)
uint8_t * GetSurfaceIDPointer(void *buf)
bool CreateBuffer(int width, int height, uint num, void *data, VideoFrameType fmt)
void end_lock()
Definition: videobuffers.h:100
OpenGLVideo * gl_videochain
PictureAttribute
Definition: videoouttypes.h:85
float GetVideoAspect(void) const
MythRenderOpenGL * gl_context
void InitPictureAttributes(VideoColourSpace &colourspace)
void EmbedInWidget(const QRect &rect)
Tells video output to embed video in an existing window.
line height
Definition: MythXMLTest.css:26
GLint GLenum GLsizei width
void ProcessFrame(VideoFrame *frame, OSD *osd, FilterChain *filterList, const PIPMap &pipPlayers, FrameScanType scan)
virtual void ProcessFrame(VideoFrame *frame, OSD *osd, FilterChain *filterList, const PIPMap &pipPlayers, FrameScanType scan)
int64_t disp_timecode
Definition: frame.h:44
uint Size(BufferType type) const
safe_map_t * safe_renderers
void SetInputUpdated(void)
bool SetDeinterlacingEnabled(bool enable)
Attempts to enable/disable deinterlacing using existing deinterlace method when enabling.
VideoFrame * Head(BufferType)
virtual void VideoAspectRatioChanged(float aspect)
Calls SetVideoAspectRatio(float aspect), then calls MoveResize() to apply changes.
virtual void makeCurrent()
virtual bool InputChanged(const QSize &video_dim_buf, const QSize &video_dim_disp, float aspect, MythCodecID av_codec_id, void *codec_private, bool &aspect_only)
Tells video output to discard decoded frames and wait for new ones.
Definition: osd.h:131
virtual void UpdatePauseFrame(int64_t &disp_timecode)
Updates frame displayed when video is paused.
static const QString LOC
static QStringList GetAllowedRenderers(MythCodecID myth_codec_id, const QSize &video_dim)
virtual void UpdatePauseFrame(int64_t &disp_timecode)
Updates frame displayed when video is paused.
VideoOutWindow window
Definition: videooutbase.h:303
static MythCodecID GetBestSupportedCodec(uint width, uint height, const QString &decoder, uint stream_type, bool no_acceleration, PixelFormat &pix_fmt)
uint GetTextureType(void) const
int SetPictureAttribute(PictureAttribute attribute, int newValue)
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.
lzo_uint lzo_uint size
Definition: lzoconf.h:273
void * GetVideoSurface(int i)
frame_queue_t::iterator begin_lock(BufferType)
unsigned char * buf
Definition: frame.h:33
bool IsEmbedding(void) const
Returns if videooutput is embedding.
static bool IsFormatAccelerated(QSize size, MythCodecID codec, PixelFormat &pix_fmt)
VideoFrame av_pause_frame