Bug 1812290 [Linux] Check if dmabuf surface copy works and don't use it on broken systems r=alwu,emilio,jgilbert

Differential Revision: https://phabricator.services.mozilla.com/D167917
This commit is contained in:
stransky 2023-02-08 13:35:08 +00:00
parent 6384797392
commit ccdefe634b
5 changed files with 48 additions and 10 deletions

View File

@ -1311,6 +1311,8 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("Unable to get frame by vaExportSurfaceHandle()"));
}
auto releaseSurfaceDescriptor = MakeScopeExit(
[&] { DMABufSurfaceYUV::ReleaseVADRMPRIMESurfaceDescriptor(vaDesc); });
MOZ_ASSERT(mTaskQueue->IsOnCurrentThread());
if (!mVideoFramePool) {

View File

@ -21,7 +21,7 @@ extern mozilla::LazyLogModule gDmabufLog;
// Start copying surfaces when free ffmpeg surface count is below 1/4 of all
// available surfaces.
#define SURFACE_COPY_TRESHOLD (1.0f / 4.0f);
#define SURFACE_COPY_THRESHOLD (1.0f / 4.0f)
namespace mozilla {
@ -140,7 +140,9 @@ bool VideoFramePool<LIBAV_VER>::ShouldCopySurface() {
"%f",
(int)mDMABufSurfaces.Length(), surfacesUsed - surfacesUsedFFmpeg,
surfacesUsedFFmpeg, mFFMPEGPoolSize, freeRatio);
return freeRatio < SURFACE_COPY_TRESHOLD;
MOZ_DIAGNOSTIC_ASSERT(mTextureCopyWorks.isSome());
return mTextureCopyWorks.value() && freeRatio < SURFACE_COPY_THRESHOLD;
}
RefPtr<VideoFrameSurface<LIBAV_VER>>
@ -155,6 +157,15 @@ VideoFramePool<LIBAV_VER>::GetVideoFrameSurface(
}
MutexAutoLock lock(mSurfaceLock);
if (MOZ_UNLIKELY(mTextureCopyWorks.isNothing())) {
RefPtr<DMABufSurfaceYUV> surface =
DMABufSurfaceYUV::CopyYUVSurface(aVaDesc, aWidth, aHeight);
mTextureCopyWorks = Some(surface != nullptr);
if (!mTextureCopyWorks.value()) {
DMABUF_LOG(" DMABuf texture copy is broken");
}
}
RefPtr<DMABufSurfaceYUV> surface;
RefPtr<VideoFrameSurface<LIBAV_VER>> videoSurface =
GetFreeVideoFrameSurface();

View File

@ -136,6 +136,9 @@ class VideoFramePool<LIBAV_VER> {
// We may fail to create texture over DMABuf memory due to driver bugs so
// check that before we export first DMABuf video frame.
Maybe<bool> mTextureCreationWorks;
// We may fail to copy DMABuf memory on NVIDIA drivers.
// Check that before we try to copy any video frame.
Maybe<bool> mTextureCopyWorks;
};
} // namespace mozilla

View File

@ -909,7 +909,18 @@ already_AddRefed<DMABufSurfaceYUV> DMABufSurfaceYUV::CreateYUVSurface(
RefPtr<DMABufSurfaceYUV> surf = new DMABufSurfaceYUV();
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurface() UID %d from desc\n",
surf->GetUID()));
if (!surf->UpdateYUVData(aDesc, aWidth, aHeight, false)) {
if (!surf->UpdateYUVData(aDesc, aWidth, aHeight, /* aCopy */ false)) {
return nullptr;
}
return surf.forget();
}
already_AddRefed<DMABufSurfaceYUV> DMABufSurfaceYUV::CopyYUVSurface(
const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) {
RefPtr<DMABufSurfaceYUV> surf = new DMABufSurfaceYUV();
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurfaceCopy() UID %d from desc\n",
surf->GetUID()));
if (!surf->UpdateYUVData(aDesc, aWidth, aHeight, /* aCopy */ true)) {
return nullptr;
}
return surf.forget();
@ -1021,15 +1032,24 @@ bool DMABufSurfaceYUV::MoveYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc,
}
for (unsigned int i = 0; i < aDesc.num_layers; i++) {
unsigned int object = aDesc.layers[i].object_index[0];
// Intel exports VA-API surfaces in one object,planes have the same FD.
// AMD exports surfaces in two objects with different FDs.
int fd = aDesc.objects[object].fd;
bool dupFD = (object != i);
mDmabufFds[i] = dupFD ? dup(fd) : fd;
// Keep VADRMPRIMESurfaceDescriptor untouched and dup() dmabuf
// file descriptors.
mDmabufFds[i] = dup(aDesc.objects[object].fd);
}
return true;
}
void DMABufSurfaceYUV::ReleaseVADRMPRIMESurfaceDescriptor(
VADRMPRIMESurfaceDescriptor& aDesc) {
for (unsigned int i = 0; i < aDesc.num_layers; i++) {
unsigned int object = aDesc.layers[i].object_index[0];
if (aDesc.objects[object].fd != -1) {
close(aDesc.objects[object].fd);
aDesc.objects[object].fd = -1;
}
}
}
bool DMABufSurfaceYUV::CreateYUVPlane(int aPlane) {
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVPlane() UID %d size %d x %d", mUID,
mWidth[aPlane], mHeight[aPlane]));

View File

@ -290,9 +290,12 @@ class DMABufSurfaceYUV : public DMABufSurface {
static already_AddRefed<DMABufSurfaceYUV> CreateYUVSurface(
int aWidth, int aHeight, void** aPixelData = nullptr,
int* aLineSizes = nullptr);
static already_AddRefed<DMABufSurfaceYUV> CreateYUVSurface(
const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight);
static already_AddRefed<DMABufSurfaceYUV> CopyYUVSurface(
const VADRMPRIMESurfaceDescriptor& aVaDesc, int aWidth, int aHeight);
static void ReleaseVADRMPRIMESurfaceDescriptor(
VADRMPRIMESurfaceDescriptor& aDesc);
bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor);
@ -324,7 +327,6 @@ class DMABufSurfaceYUV : public DMABufSurface {
bool UpdateYUVData(void** aPixelData, int* aLineSizes);
bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
int aHeight, bool aCopy);
bool VerifyTextureCreation();
private: