Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/mythtv/libs/libmythtv/videoout_opengl.h b/mythtv/libs/libmythtv/videoout_opengl.h
- index 412024cc09..14e8892e65 100644
- --- a/mythtv/libs/libmythtv/videoout_opengl.h
- +++ b/mythtv/libs/libmythtv/videoout_opengl.h
- @@ -27,7 +27,7 @@ class VideoOutputOpenGL : public VideoOutput
- FilterChain *filterList,
- const PIPMap &pipPlayers,
- FrameScanType scan) override; // VideoOutput
- - void Show(FrameScanType ) override; // VideoOutput
- + virtual void Show(FrameScanType ) override; // VideoOutput
- bool InputChanged(const QSize &video_dim_buf,
- const QSize &video_dim_disp,
- float aspect,
- diff --git a/mythtv/libs/libmythtv/videoout_openglvaapi.cpp b/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
- index 8fd4565ab7..1f75796225 100644
- --- a/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
- +++ b/mythtv/libs/libmythtv/videoout_openglvaapi.cpp
- @@ -34,13 +34,24 @@ void VideoOutputOpenGLVAAPI::GetRenderOptions(render_opts &opts)
- }
- VideoOutputOpenGLVAAPI::VideoOutputOpenGLVAAPI()
- - : VideoOutputOpenGL(), m_ctx(nullptr), m_pauseBuffer(nullptr)
- + : VideoOutputOpenGL(),
- + m_ctx(nullptr),
- + m_pauseBuffer(nullptr),
- + m_videoChangedLock(QMutex::NonRecursive),
- + m_videoChangedWait(),
- + m_videoChanged(0),
- + m_videoChangedOK(true),
- + m_newVideoBufferSize(),
- + m_newVideoDisplaySize(),
- + m_newVideoAspect(1.0),
- + m_newVideoCodec(kCodec_NONE)
- {
- }
- VideoOutputOpenGLVAAPI::~VideoOutputOpenGLVAAPI()
- {
- TearDown();
- + m_videoChangedWait.wakeAll();
- }
- void VideoOutputOpenGLVAAPI::TearDown(void)
- @@ -48,23 +59,93 @@ void VideoOutputOpenGLVAAPI::TearDown(void)
- DeleteVAAPIContext();
- }
- +bool VideoOutputOpenGLVAAPI::InputChangedIsThreadSafe()
- +{
- + return gCoreContext->IsUIThread();
- +}
- +
- bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &video_dim_buf,
- const QSize &video_dim_disp,
- float aspect,
- MythCodecID av_codec_id, void *codec_private,
- bool &aspect_only)
- {
- - LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
- - .arg(video_dim_disp.width()).arg(video_dim_disp.height())
- - .arg(aspect)
- - .arg(toString(video_codec_id)).arg(toString(av_codec_id)));
- + (void)codec_private;
- +
- + QSize currentbuf = window.GetVideoDim();
- + QSize currentres = window.GetActualVideoDim();
- + float currentasp = window.GetVideoAspect();
- +
- + LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Video changed: %1x%2 (%3x%4) '%5' (Aspect %6)"
- + "-> %7x%8 (%9x%10) '%11' (Aspect %12)")
- + .arg(currentres.width()).arg(currentres.height())
- + .arg(currentbuf.width()).arg(currentbuf.height())
- + .arg(toString(video_codec_id)).arg(currentasp)
- + .arg(video_dim_disp.width()).arg(video_dim_disp.height())
- + .arg(video_dim_buf.width()).arg(video_dim_buf.height())
- + .arg(toString(av_codec_id)).arg(aspect));
- +
- + // aspect ratio changes are a no-op as changes are handled at display time
- + if ((video_codec_id == av_codec_id) && (currentres == video_dim_disp))
- + {
- + aspect_only = true;
- + return true;
- + }
- - if (!codec_is_vaapi(av_codec_id))
- - return VideoOutputOpenGL::InputChanged(video_dim_buf, video_dim_disp,
- - aspect, av_codec_id,
- - codec_private, aspect_only);
- + // if this has been called from the decoder thread and either the old or new
- + // codec is VAAPI, then store the new video metadata and wait until video has
- + // been re-initialised. This ensures thread safe VAAPI calls and allows the
- + // video buffers to play out before re-creating
- + if (!(codec_sw_copy(video_codec_id) && codec_sw_copy(av_codec_id)) && !gCoreContext->IsUIThread())
- + {
- + LOG(VB_PLAYBACK, LOG_INFO, "Video change signalled from decoder thread");
- + m_videoChangedLock.lock();
- + m_videoChanged = 1;
- + m_newVideoCodec = av_codec_id;
- + m_newVideoAspect = aspect;
- + m_newVideoBufferSize = video_dim_buf;
- + m_newVideoDisplaySize = video_dim_disp;
- + m_videoChangedWait.wait(&m_videoChangedLock);
- + bool result = m_videoChangedOK;
- + m_videoChangedOK = true;
- + m_videoChangedLock.unlock();
- + LOG(VB_PLAYBACK, LOG_INFO, "Video change complete");
- + return result;
- + }
- - QMutexLocker locker(&gl_context_lock);
- + return InputChangedPriv(video_dim_buf, video_dim_disp, aspect, av_codec_id);
- +}
- +
- +void VideoOutputOpenGLVAAPI::Show(FrameScanType Scan)
- +{
- + VideoOutputOpenGL::Show(Scan);
- + InputChangedCheck();
- +}
- +
- +void VideoOutputOpenGLVAAPI::InputChangedCheck()
- +{
- + if (m_videoChanged.testAndSetAcquire(1, 0))
- + {
- + LOG(VB_PLAYBACK, LOG_INFO, "Recreating video resources in UI thread");
- + m_videoChangedOK = InputChangedPriv(m_newVideoBufferSize, m_newVideoDisplaySize,
- + m_newVideoAspect, m_newVideoCodec);
- + m_videoChangedWait.wakeAll();
- + }
- +}
- +
- +bool VideoOutputOpenGLVAAPI::InputChangedPriv(const QSize &VideoBufferSize,
- + const QSize &VideoDisplaySize,
- + float VideoAspect,
- + MythCodecID MythAVCodecID)
- +{
- + if (!gCoreContext->IsUIThread())
- + {
- + LOG(VB_GENERAL, LOG_ERR, "Cannot change video codec from this thread");
- + return false;
- + }
- +
- + QMutexLocker lock1(&gl_context_lock);
- + OpenGLLocker lock2(gl_context);
- bool wasembedding = window.IsEmbedding();
- QRect oldrect;
- @@ -74,42 +155,23 @@ bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &video_dim_buf,
- StopEmbedding();
- }
- - bool cid_changed = (video_codec_id != av_codec_id);
- - bool res_changed = video_dim_disp != window.GetActualVideoDim();
- - bool asp_changed = aspect != window.GetVideoAspect();
- - if (!res_changed && !cid_changed)
- - {
- - if (asp_changed)
- - {
- - aspect_only = true;
- - VideoAspectRatioChanged(aspect);
- - MoveResize();
- - if (wasembedding)
- - EmbedInWidget(oldrect);
- - }
- - return true;
- - }
- -
- - if (gCoreContext->IsUIThread())
- - TearDown();
- - else
- - DestroyCPUResources();
- + TearDown();
- + DestroyCPUResources();
- + DestroyVideoResources();
- + DestroyGPUResources();
- - QRect disp = window.GetDisplayVisibleRect();
- - if (Init(video_dim_buf, video_dim_disp,
- - aspect, gl_parent_win, disp, av_codec_id))
- + QRect display = window.GetDisplayVisibleRect();
- + if (Init(VideoBufferSize, VideoDisplaySize, VideoAspect, gl_parent_win, display, MythAVCodecID))
- {
- if (wasembedding)
- EmbedInWidget(oldrect);
- - if (gCoreContext->IsUIThread())
- - BestDeint();
- + BestDeint();
- return true;
- }
- LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output.");
- errorState = kError_Unknown;
- -
- return false;
- }
- @@ -129,16 +191,6 @@ bool VideoOutputOpenGLVAAPI::Init(const QSize &video_dim_buf,
- bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size)
- {
- - // FIXME During a video stream change this is called from the decoder
- - // thread - which breaks all other efforts to remove non-UI thread
- - // access to the OpenGL context. There is no obvious fix however - if we
- - // don't delete and re-create the VAAPI decoder context immediately then
- - // the decoder fails and playback exits.
- -
- - // lvr 27-oct-13
- - // in 0.27 if m_ctx->CreateDisplay is called outside of the UI thread then
- - // it fails, which then causes subsequent unbalanced calls to doneCurrent
- - // which results in Qt aborting. So just fail if non-UI.
- if (!gCoreContext->IsUIThread())
- {
- LOG(VB_GENERAL, LOG_ERR, LOC +
- @@ -284,10 +336,15 @@ void VideoOutputOpenGLVAAPI::PrepareFrame(VideoFrame *frame, FrameScanType scan,
- QMutexLocker locker(&gl_context_lock);
- if (codec_is_vaapi(video_codec_id) && m_ctx && gl_videochain)
- {
- + FrameScanType newscan = kScan_Progressive;
- + if (frame && (scan == kScan_Interlaced))
- + newscan = frame->top_field_first ? kScan_Intr2ndField : kScan_Interlaced;
- + else if (frame && (scan == kScan_Intr2ndField))
- + newscan = frame->top_field_first ? kScan_Interlaced : kScan_Intr2ndField;
- gl_context->makeCurrent();
- m_ctx->CopySurfaceToTexture(frame ? frame->buf : m_pauseBuffer,
- gl_videochain->GetInputTexture(),
- - gl_videochain->GetTextureType(), scan);
- + gl_videochain->GetTextureType(), newscan);
- gl_videochain->SetInputUpdated();
- gl_context->doneCurrent();
- }
- diff --git a/mythtv/libs/libmythtv/videoout_openglvaapi.h b/mythtv/libs/libmythtv/videoout_openglvaapi.h
- index f0ccea1217..47e153cd50 100644
- --- a/mythtv/libs/libmythtv/videoout_openglvaapi.h
- +++ b/mythtv/libs/libmythtv/videoout_openglvaapi.h
- @@ -30,8 +30,10 @@ class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL
- float aspect,
- MythCodecID av_codec_id, void *codec_private,
- bool &aspect_only) override; // VideoOutputOpenGL
- + bool InputChangedIsThreadSafe() override;
- void UpdatePauseFrame(int64_t &disp_timecode) override; // VideoOutputOpenGL
- void PrepareFrame(VideoFrame *frame, FrameScanType scan, OSD *osd) override; // VideoOutputOpenGL
- + void Show(FrameScanType) override; // VideoOutputOpenGL
- bool ApproveDeintFilter(const QString& filtername) const override; // VideoOutputOpenGL
- bool SetDeinterlacingEnabled(bool enable) override; // VideoOutputOpenGL
- bool SetupDeinterlace(bool interlaced, const QString& overridefilter="") override; // VideoOutputOpenGL
- @@ -47,8 +49,25 @@ class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL
- AVPixelFormat &pix_fmt);
- private:
- - VAAPIContext *m_ctx;
- - void *m_pauseBuffer;
- + bool InputChangedPriv(const QSize &VideoBufferSize,
- + const QSize &VideoDisplaySize,
- + float VideoAspect,
- + MythCodecID MythAVCodecID);
- + void InputChangedCheck();
- +
- + private:
- + VAAPIContext *m_ctx;
- + void *m_pauseBuffer;
- +
- + // Video codec changes
- + QMutex m_videoChangedLock;
- + QWaitCondition m_videoChangedWait;
- + QAtomicInt m_videoChanged;
- + bool m_videoChangedOK;
- + QSize m_newVideoBufferSize;
- + QSize m_newVideoDisplaySize;
- + float m_newVideoAspect;
- + MythCodecID m_newVideoCodec;
- };
- #endif // VIDEOOUTPUTOPENGLVAAPI_H
- diff --git a/mythtv/libs/libmythtv/videooutbase.h b/mythtv/libs/libmythtv/videooutbase.h
- index 0d1bca5b49..37b51ca60f 100644
- --- a/mythtv/libs/libmythtv/videooutbase.h
- +++ b/mythtv/libs/libmythtv/videooutbase.h
- @@ -99,6 +99,7 @@ class VideoOutput
- MythCodecID myth_codec_id,
- void *codec_private,
- bool &aspect_changed);
- + virtual bool InputChangedIsThreadSafe() { return true; }
- virtual void VideoAspectRatioChanged(float aspect);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement