mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
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:
parent
6384797392
commit
ccdefe634b
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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]));
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user