Advertisement
Guest User

Untitled

a guest
Jan 6th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.83 KB | None | 0 0
  1. diff --git a/mythtv/libs/libmythtv/videoout_opengl.h b/mythtv/libs/libmythtv/videoout_opengl.h
  2. index 412024cc09..14e8892e65 100644
  3. --- a/mythtv/libs/libmythtv/videoout_opengl.h
  4. +++ b/mythtv/libs/libmythtv/videoout_opengl.h
  5. @@ -27,7 +27,7 @@ class VideoOutputOpenGL : public VideoOutput
  6. FilterChain *filterList,
  7. const PIPMap &pipPlayers,
  8. FrameScanType scan) override; // VideoOutput
  9. - void Show(FrameScanType ) override; // VideoOutput
  10. + virtual void Show(FrameScanType ) override; // VideoOutput
  11. bool InputChanged(const QSize &video_dim_buf,
  12. const QSize &video_dim_disp,
  13. float aspect,
  14. diff --git a/mythtv/libs/libmythtv/videoout_openglvaapi.cpp b/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
  15. index 8fd4565ab7..1f75796225 100644
  16. --- a/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
  17. +++ b/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
  18. @@ -34,13 +34,24 @@ void VideoOutputOpenGLVAAPI::GetRenderOptions(render_opts &opts)
  19. }
  20.  
  21. VideoOutputOpenGLVAAPI::VideoOutputOpenGLVAAPI()
  22. - : VideoOutputOpenGL(), m_ctx(nullptr), m_pauseBuffer(nullptr)
  23. + : VideoOutputOpenGL(),
  24. + m_ctx(nullptr),
  25. + m_pauseBuffer(nullptr),
  26. + m_videoChangedLock(QMutex::NonRecursive),
  27. + m_videoChangedWait(),
  28. + m_videoChanged(0),
  29. + m_videoChangedOK(true),
  30. + m_newVideoBufferSize(),
  31. + m_newVideoDisplaySize(),
  32. + m_newVideoAspect(1.0),
  33. + m_newVideoCodec(kCodec_NONE)
  34. {
  35. }
  36.  
  37. VideoOutputOpenGLVAAPI::~VideoOutputOpenGLVAAPI()
  38. {
  39. TearDown();
  40. + m_videoChangedWait.wakeAll();
  41. }
  42.  
  43. void VideoOutputOpenGLVAAPI::TearDown(void)
  44. @@ -48,23 +59,93 @@ void VideoOutputOpenGLVAAPI::TearDown(void)
  45. DeleteVAAPIContext();
  46. }
  47.  
  48. +bool VideoOutputOpenGLVAAPI::InputChangedIsThreadSafe()
  49. +{
  50. + return gCoreContext->IsUIThread();
  51. +}
  52. +
  53. bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &video_dim_buf,
  54. const QSize &video_dim_disp,
  55. float aspect,
  56. MythCodecID av_codec_id, void *codec_private,
  57. bool &aspect_only)
  58. {
  59. - LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
  60. - .arg(video_dim_disp.width()).arg(video_dim_disp.height())
  61. - .arg(aspect)
  62. - .arg(toString(video_codec_id)).arg(toString(av_codec_id)));
  63. + (void)codec_private;
  64. +
  65. + QSize currentbuf = window.GetVideoDim();
  66. + QSize currentres = window.GetActualVideoDim();
  67. + float currentasp = window.GetVideoAspect();
  68. +
  69. + LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Video changed: %1x%2 (%3x%4) '%5' (Aspect %6)"
  70. + "-> %7x%8 (%9x%10) '%11' (Aspect %12)")
  71. + .arg(currentres.width()).arg(currentres.height())
  72. + .arg(currentbuf.width()).arg(currentbuf.height())
  73. + .arg(toString(video_codec_id)).arg(currentasp)
  74. + .arg(video_dim_disp.width()).arg(video_dim_disp.height())
  75. + .arg(video_dim_buf.width()).arg(video_dim_buf.height())
  76. + .arg(toString(av_codec_id)).arg(aspect));
  77. +
  78. + // aspect ratio changes are a no-op as changes are handled at display time
  79. + if ((video_codec_id == av_codec_id) && (currentres == video_dim_disp))
  80. + {
  81. + aspect_only = true;
  82. + return true;
  83. + }
  84.  
  85. - if (!codec_is_vaapi(av_codec_id))
  86. - return VideoOutputOpenGL::InputChanged(video_dim_buf, video_dim_disp,
  87. - aspect, av_codec_id,
  88. - codec_private, aspect_only);
  89. + // if this has been called from the decoder thread and either the old or new
  90. + // codec is VAAPI, then store the new video metadata and wait until video has
  91. + // been re-initialised. This ensures thread safe VAAPI calls and allows the
  92. + // video buffers to play out before re-creating
  93. + if (!(codec_sw_copy(video_codec_id) && codec_sw_copy(av_codec_id)) && !gCoreContext->IsUIThread())
  94. + {
  95. + LOG(VB_PLAYBACK, LOG_INFO, "Video change signalled from decoder thread");
  96. + m_videoChangedLock.lock();
  97. + m_videoChanged = 1;
  98. + m_newVideoCodec = av_codec_id;
  99. + m_newVideoAspect = aspect;
  100. + m_newVideoBufferSize = video_dim_buf;
  101. + m_newVideoDisplaySize = video_dim_disp;
  102. + m_videoChangedWait.wait(&m_videoChangedLock);
  103. + bool result = m_videoChangedOK;
  104. + m_videoChangedOK = true;
  105. + m_videoChangedLock.unlock();
  106. + LOG(VB_PLAYBACK, LOG_INFO, "Video change complete");
  107. + return result;
  108. + }
  109.  
  110. - QMutexLocker locker(&gl_context_lock);
  111. + return InputChangedPriv(video_dim_buf, video_dim_disp, aspect, av_codec_id);
  112. +}
  113. +
  114. +void VideoOutputOpenGLVAAPI::Show(FrameScanType Scan)
  115. +{
  116. + VideoOutputOpenGL::Show(Scan);
  117. + InputChangedCheck();
  118. +}
  119. +
  120. +void VideoOutputOpenGLVAAPI::InputChangedCheck()
  121. +{
  122. + if (m_videoChanged.testAndSetAcquire(1, 0))
  123. + {
  124. + LOG(VB_PLAYBACK, LOG_INFO, "Recreating video resources in UI thread");
  125. + m_videoChangedOK = InputChangedPriv(m_newVideoBufferSize, m_newVideoDisplaySize,
  126. + m_newVideoAspect, m_newVideoCodec);
  127. + m_videoChangedWait.wakeAll();
  128. + }
  129. +}
  130. +
  131. +bool VideoOutputOpenGLVAAPI::InputChangedPriv(const QSize &VideoBufferSize,
  132. + const QSize &VideoDisplaySize,
  133. + float VideoAspect,
  134. + MythCodecID MythAVCodecID)
  135. +{
  136. + if (!gCoreContext->IsUIThread())
  137. + {
  138. + LOG(VB_GENERAL, LOG_ERR, "Cannot change video codec from this thread");
  139. + return false;
  140. + }
  141. +
  142. + QMutexLocker lock1(&gl_context_lock);
  143. + OpenGLLocker lock2(gl_context);
  144.  
  145. bool wasembedding = window.IsEmbedding();
  146. QRect oldrect;
  147. @@ -74,42 +155,23 @@ bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &video_dim_buf,
  148. StopEmbedding();
  149. }
  150.  
  151. - bool cid_changed = (video_codec_id != av_codec_id);
  152. - bool res_changed = video_dim_disp != window.GetActualVideoDim();
  153. - bool asp_changed = aspect != window.GetVideoAspect();
  154.  
  155. - if (!res_changed && !cid_changed)
  156. - {
  157. - if (asp_changed)
  158. - {
  159. - aspect_only = true;
  160. - VideoAspectRatioChanged(aspect);
  161. - MoveResize();
  162. - if (wasembedding)
  163. - EmbedInWidget(oldrect);
  164. - }
  165. - return true;
  166. - }
  167. -
  168. - if (gCoreContext->IsUIThread())
  169. - TearDown();
  170. - else
  171. - DestroyCPUResources();
  172. + TearDown();
  173. + DestroyCPUResources();
  174. + DestroyVideoResources();
  175. + DestroyGPUResources();
  176.  
  177. - QRect disp = window.GetDisplayVisibleRect();
  178. - if (Init(video_dim_buf, video_dim_disp,
  179. - aspect, gl_parent_win, disp, av_codec_id))
  180. + QRect display = window.GetDisplayVisibleRect();
  181. + if (Init(VideoBufferSize, VideoDisplaySize, VideoAspect, gl_parent_win, display, MythAVCodecID))
  182. {
  183. if (wasembedding)
  184. EmbedInWidget(oldrect);
  185. - if (gCoreContext->IsUIThread())
  186. - BestDeint();
  187. + BestDeint();
  188. return true;
  189. }
  190.  
  191. LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
  192. errorState = kError_Unknown;
  193. -
  194. return false;
  195. }
  196.  
  197. @@ -129,16 +191,6 @@ bool VideoOutputOpenGLVAAPI::Init(const QSize &video_dim_buf,
  198.  
  199. bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size)
  200. {
  201. - // FIXME During a video stream change this is called from the decoder
  202. - // thread - which breaks all other efforts to remove non-UI thread
  203. - // access to the OpenGL context. There is no obvious fix however - if we
  204. - // don't delete and re-create the VAAPI decoder context immediately then
  205. - // the decoder fails and playback exits.
  206. -
  207. - // lvr 27-oct-13
  208. - // in 0.27 if m_ctx->CreateDisplay is called outside of the UI thread then
  209. - // it fails, which then causes subsequent unbalanced calls to doneCurrent
  210. - // which results in Qt aborting. So just fail if non-UI.
  211. if (!gCoreContext->IsUIThread())
  212. {
  213. LOG(VB_GENERAL, LOG_ERR, LOC +
  214. @@ -284,10 +336,15 @@ void VideoOutputOpenGLVAAPI::PrepareFrame(VideoFrame *frame, FrameScanType scan,
  215. QMutexLocker locker(&gl_context_lock);
  216. if (codec_is_vaapi(video_codec_id) && m_ctx && gl_videochain)
  217. {
  218. + FrameScanType newscan = kScan_Progressive;
  219. + if (frame && (scan == kScan_Interlaced))
  220. + newscan = frame->top_field_first ? kScan_Intr2ndField : kScan_Interlaced;
  221. + else if (frame && (scan == kScan_Intr2ndField))
  222. + newscan = frame->top_field_first ? kScan_Interlaced : kScan_Intr2ndField;
  223. gl_context->makeCurrent();
  224. m_ctx->CopySurfaceToTexture(frame ? frame->buf : m_pauseBuffer,
  225. gl_videochain->GetInputTexture(),
  226. - gl_videochain->GetTextureType(), scan);
  227. + gl_videochain->GetTextureType(), newscan);
  228. gl_videochain->SetInputUpdated();
  229. gl_context->doneCurrent();
  230. }
  231. diff --git a/mythtv/libs/libmythtv/videoout_openglvaapi.h b/mythtv/libs/libmythtv/videoout_openglvaapi.h
  232. index f0ccea1217..47e153cd50 100644
  233. --- a/mythtv/libs/libmythtv/videoout_openglvaapi.h
  234. +++ b/mythtv/libs/libmythtv/videoout_openglvaapi.h
  235. @@ -30,8 +30,10 @@ class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL
  236. float aspect,
  237. MythCodecID av_codec_id, void *codec_private,
  238. bool &aspect_only) override; // VideoOutputOpenGL
  239. + bool InputChangedIsThreadSafe() override;
  240. void UpdatePauseFrame(int64_t &disp_timecode) override; // VideoOutputOpenGL
  241. void PrepareFrame(VideoFrame *frame, FrameScanType scan, OSD *osd) override; // VideoOutputOpenGL
  242. + void Show(FrameScanType) override; // VideoOutputOpenGL
  243. bool ApproveDeintFilter(const QString& filtername) const override; // VideoOutputOpenGL
  244. bool SetDeinterlacingEnabled(bool enable) override; // VideoOutputOpenGL
  245. bool SetupDeinterlace(bool interlaced, const QString& overridefilter="") override; // VideoOutputOpenGL
  246. @@ -47,8 +49,25 @@ class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL
  247. AVPixelFormat &pix_fmt);
  248.  
  249. private:
  250. - VAAPIContext *m_ctx;
  251. - void *m_pauseBuffer;
  252. + bool InputChangedPriv(const QSize &VideoBufferSize,
  253. + const QSize &VideoDisplaySize,
  254. + float VideoAspect,
  255. + MythCodecID MythAVCodecID);
  256. + void InputChangedCheck();
  257. +
  258. + private:
  259. + VAAPIContext *m_ctx;
  260. + void *m_pauseBuffer;
  261. +
  262. + // Video codec changes
  263. + QMutex m_videoChangedLock;
  264. + QWaitCondition m_videoChangedWait;
  265. + QAtomicInt m_videoChanged;
  266. + bool m_videoChangedOK;
  267. + QSize m_newVideoBufferSize;
  268. + QSize m_newVideoDisplaySize;
  269. + float m_newVideoAspect;
  270. + MythCodecID m_newVideoCodec;
  271. };
  272. #endif // VIDEOOUTPUTOPENGLVAAPI_H
  273.  
  274. diff --git a/mythtv/libs/libmythtv/videooutbase.h b/mythtv/libs/libmythtv/videooutbase.h
  275. index 0d1bca5b49..37b51ca60f 100644
  276. --- a/mythtv/libs/libmythtv/videooutbase.h
  277. +++ b/mythtv/libs/libmythtv/videooutbase.h
  278. @@ -99,6 +99,7 @@ class VideoOutput
  279. MythCodecID myth_codec_id,
  280. void *codec_private,
  281. bool &aspect_changed);
  282. + virtual bool InputChangedIsThreadSafe() { return true; }
  283.  
  284. virtual void VideoAspectRatioChanged(float aspect);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement