changeset: 544864:a8603f131703 tag: tip parent: 544861:161920b70ae4 user: Martin Stransky date: Fri Jul 31 13:39:48 2020 +0200 files: dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h description: Bug 1645671 [Linux/VA-API] Create DMABufSurfaceWrapper directly at nsTAttay and disable DMABufSurfaceWrapper class copy and assignment constructors, r?jya When DMABufSurfaceWrapper is added to nsTArray, a temporary local DMABufSurfaceWrapper object is created. When the temporary object is deleted after the adding, associated dmabuf data is released which leads to rendering artifact during VA-API video playback. As a fix in this patch we create DMABufSurfaceWrapper 'in-place' at nsTAttay. We also disable DMABufSurfaceWrapper class copy and assignment constructors to avoid similar potential issues. Differential Revision: https://phabricator.services.mozilla.com/D85152 diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp --- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp @@ -777,17 +777,17 @@ MediaResult FFmpegVideoDecoderSetUID(++uid); FFMPEG_LOG("Created new DMABufSurface UID = %d", uid); # endif - mDMABufSurfaces.AppendElement(DMABufSurfaceWrapper(surface, mLib)); + mDMABufSurfaces.EmplaceBack(surface, mLib); surfaceWrapper = &(mDMABufSurfaces[mDMABufSurfaces.Length() - 1]); } else { surface = surfaceWrapper->GetDMABufSurface(); bool ret; if (mVAAPIDeviceContext) { ret = surface->UpdateYUVData(vaDesc); } else { diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h --- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h +++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h @@ -70,16 +70,22 @@ class DMABufSurfaceWrapper final { // Check if DMABufSurface is used by any gecko rendering process // (WebRender or GL compositor) or by DMABUFSurfaceImage/VideoData. bool IsUsed() const { return mSurface->IsGlobalRefSet(); } RefPtr GetDMABufSurface() const { return mSurface->GetAsDMABufSurfaceYUV(); } + // Don't allow DMABufSurfaceWrapper plain copy as it leads to + // enexpected DMABufSurface/HW buffer releases and we don't want to + // deep copy them. + DMABufSurfaceWrapper(const DMABufSurfaceWrapper&) = delete; + const DMABufSurfaceWrapper& operator=(DMABufSurfaceWrapper const&) = delete; + private: const RefPtr mSurface; const FFmpegLibWrapper* mLib; AVBufferRef* mAVHWFramesContext; AVBufferRef* mHWAVBuffer; }; #endif