зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1809162) for causing bustages on FFmpegVideoFramePool.cpp.
Backed out changeset 0034c0451d9b (bug 1809162) Backed out changeset bb0ff84365ad (bug 1809162) Backed out changeset 2d88d3f5c01f (bug 1809162) Backed out changeset 84503cda04f3 (bug 1809162) Backed out changeset 4692e64be33b (bug 1809162)
This commit is contained in:
Родитель
f844c09af0
Коммит
11e26bc546
|
@ -87,10 +87,7 @@ VideoFrameSurface<LIBAV_VER>::~VideoFrameSurface() {
|
|||
}
|
||||
|
||||
VideoFramePool<LIBAV_VER>::VideoFramePool()
|
||||
: mSurfaceLock("VideoFramePoolSurfaceLock"),
|
||||
mSurfaceCopy(StaticPrefs::media_ffmpeg_vaapi_surface_copy_enabled()) {
|
||||
DMABUF_LOG("VideoFramePool::VideoFramePool() surface copy %d", mSurfaceCopy);
|
||||
}
|
||||
: mSurfaceLock("VideoFramePoolSurfaceLock") {}
|
||||
|
||||
VideoFramePool<LIBAV_VER>::~VideoFramePool() {
|
||||
MutexAutoLock lock(mSurfaceLock);
|
||||
|
@ -132,31 +129,32 @@ VideoFramePool<LIBAV_VER>::GetVideoFrameSurface(
|
|||
MutexAutoLock lock(mSurfaceLock);
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>> videoSurface =
|
||||
GetFreeVideoFrameSurface();
|
||||
RefPtr<DMABufSurfaceYUV> surface =
|
||||
videoSurface ? videoSurface->GetDMABufSurface() : new DMABufSurfaceYUV();
|
||||
if (!videoSurface) {
|
||||
RefPtr<DMABufSurfaceYUV> surface =
|
||||
DMABufSurfaceYUV::CreateYUVSurface(aVaDesc, aWidth, aHeight);
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
DMABUF_LOG("Created new VA-API DMABufSurface UID %d", surface->GetUID());
|
||||
videoSurface = new VideoFrameSurface<LIBAV_VER>(surface);
|
||||
mDMABufSurfaces.AppendElement(videoSurface);
|
||||
} else {
|
||||
DMABUF_LOG("Reusing VA-API DMABufSurface UID %d", surface->GetUID());
|
||||
}
|
||||
|
||||
if (!surface->UpdateYUVData(aVaDesc, aWidth, aHeight, mSurfaceCopy)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(!mTextureCreationWorks)) {
|
||||
mTextureCreationWorks = Some(surface->VerifyTextureCreation());
|
||||
RefPtr<VideoFrameSurface<LIBAV_VER>> surf =
|
||||
new VideoFrameSurface<LIBAV_VER>(surface);
|
||||
if (!mTextureCreationWorks) {
|
||||
mTextureCreationWorks = Some(surface->VerifyTextureCreation());
|
||||
}
|
||||
if (!*mTextureCreationWorks) {
|
||||
DMABUF_LOG(" failed to create texture over DMABuf memory!");
|
||||
return nullptr;
|
||||
}
|
||||
videoSurface = surf;
|
||||
mDMABufSurfaces.AppendElement(std::move(surf));
|
||||
} else {
|
||||
RefPtr<DMABufSurfaceYUV> surface = videoSurface->GetDMABufSurface();
|
||||
DMABUF_LOG("Reusing VA-API DMABufSurface UID %d", surface->GetUID());
|
||||
if (!surface->UpdateYUVData(aVaDesc, aWidth, aHeight)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mSurfaceCopy) {
|
||||
videoSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib);
|
||||
}
|
||||
videoSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib);
|
||||
videoSurface->MarkAsUsed();
|
||||
return videoSurface;
|
||||
}
|
||||
|
|
|
@ -129,8 +129,6 @@ 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;
|
||||
// Copy decoded dmabuf surfaces so we can return them to ffmpeg immediately.
|
||||
const bool mSurfaceCopy;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -9871,12 +9871,6 @@
|
|||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
# Copy decoded VA-API frames and return them to ffmpeg.
|
||||
# It may fix rendering/decoding bugs on some drivers.
|
||||
- name: media.ffmpeg.vaapi.surface-copy.enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
#endif # MOZ_WIDGET_GTK
|
||||
#endif # MOZ_FFMPEG
|
||||
|
||||
|
|
|
@ -12,17 +12,12 @@
|
|||
#include "mozilla/StaticPrefs_media.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "WidgetUtilsGtk.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#include "mozilla/Components.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
|
@ -229,13 +224,24 @@ nsDMABufDevice::~nsDMABufDevice() {
|
|||
int nsDMABufDevice::GetDRMFd() { return mDRMFd; }
|
||||
|
||||
bool nsDMABufDevice::Configure(nsACString& aFailureId) {
|
||||
if (mInitialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGDMABUF(("nsDMABufDevice::Configure()"));
|
||||
|
||||
MOZ_ASSERT(!mInitialized);
|
||||
mInitialized = true;
|
||||
|
||||
bool isDMABufUsed = (
|
||||
#ifdef NIGHTLY_BUILD
|
||||
StaticPrefs::widget_dmabuf_textures_enabled() ||
|
||||
#endif
|
||||
StaticPrefs::widget_dmabuf_webgl_enabled());
|
||||
|
||||
if (!isDMABufUsed) {
|
||||
// Disabled by user, just quit.
|
||||
LOGDMABUF(("IsDMABufEnabled(): Disabled by preferences."));
|
||||
aFailureId = "FEATURE_FAILURE_NO_PREFS_ENABLED";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nsGbmLib::IsAvailable()) {
|
||||
LOGDMABUF(("nsGbmLib is not available!"));
|
||||
aFailureId = "FEATURE_FAILURE_NO_LIBGBM";
|
||||
|
@ -321,13 +327,5 @@ nsDMABufDevice* GetDMABufDevice() {
|
|||
return &dmaBufDevice;
|
||||
}
|
||||
|
||||
nsDMABufDevice* GetAndConfigureDMABufDevice() {
|
||||
nsCString failureId;
|
||||
if (GetDMABufDevice()->Configure(failureId)) {
|
||||
return GetDMABufDevice();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -215,7 +215,6 @@ class nsDMABufDevice {
|
|||
};
|
||||
|
||||
nsDMABufDevice* GetDMABufDevice();
|
||||
nsDMABufDevice* GetAndConfigureDMABufDevice();
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -67,14 +67,13 @@ RefPtr<GLContext> ClaimSnapshotGLContext() {
|
|||
nsCString discardFailureId;
|
||||
sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId);
|
||||
if (!sSnapshotContext) {
|
||||
LOGDMABUF(
|
||||
("ClaimSnapshotGLContext: Failed to create snapshot GLContext."));
|
||||
LOGDMABUF(("GetAsSourceSurface: Failed to create snapshot GLContext."));
|
||||
return nullptr;
|
||||
}
|
||||
sSnapshotContext->mOwningThreadId = Nothing(); // No singular owner.
|
||||
}
|
||||
if (!sSnapshotContext->MakeCurrent()) {
|
||||
LOGDMABUF(("ClaimSnapshotGLContext: Failed to make GLContext current."));
|
||||
LOGDMABUF(("GetAsSourceSurface: Failed to make GLContext current."));
|
||||
return nullptr;
|
||||
}
|
||||
return sSnapshotContext;
|
||||
|
@ -85,7 +84,6 @@ void ReturnSnapshotGLContext(RefPtr<GLContext> aGLContext) {
|
|||
// it's not used.
|
||||
MOZ_ASSERT(!aGLContext->mUseTLSIsCurrent);
|
||||
if (!aGLContext->IsCurrent()) {
|
||||
LOGDMABUF(("ReturnSnapshotGLContext() failed, is not current!"));
|
||||
return;
|
||||
}
|
||||
const auto& gle = gl::GLContextEGL::Cast(aGLContext);
|
||||
|
@ -913,7 +911,7 @@ 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)) {
|
||||
return nullptr;
|
||||
}
|
||||
return surf.forget();
|
||||
|
@ -977,16 +975,16 @@ void DMABufSurfaceYUV::CloseFileDescriptorForPlane(
|
|||
}
|
||||
}
|
||||
|
||||
bool DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor(
|
||||
const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) {
|
||||
LOGDMABUF(("DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor() UID %d", mUID));
|
||||
// Already exists?
|
||||
MOZ_DIAGNOSTIC_ASSERT(mDmabufFds[0] < 0);
|
||||
|
||||
bool DMABufSurfaceYUV::UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc,
|
||||
int aWidth, int aHeight) {
|
||||
if (aDesc.num_layers > DMABUF_BUFFER_PLANES ||
|
||||
aDesc.num_objects > DMABUF_BUFFER_PLANES) {
|
||||
LOGDMABUF((" Can't import, wrong layers/objects number (%d, %d)",
|
||||
aDesc.num_layers, aDesc.num_objects));
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGDMABUF(("DMABufSurfaceYUV::UpdateYUVData() UID %d", mUID));
|
||||
if (mDmabufFds[0] >= 0) {
|
||||
LOGDMABUF((" Already created!"));
|
||||
return false;
|
||||
}
|
||||
if (aDesc.fourcc == VA_FOURCC_NV12) {
|
||||
|
@ -996,7 +994,8 @@ bool DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor(
|
|||
} else if (aDesc.fourcc == VA_FOURCC_YV12) {
|
||||
mSurfaceType = SURFACE_YUV420;
|
||||
} else {
|
||||
LOGDMABUF((" Can't import surface data of 0x%x format", aDesc.fourcc));
|
||||
LOGDMABUF(("UpdateYUVData(): Can't import surface data of 0x%x format",
|
||||
aDesc.fourcc));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1004,6 +1003,12 @@ bool DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor(
|
|||
|
||||
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;
|
||||
|
||||
mBufferModifiers[i] = aDesc.objects[object].drm_format_modifier;
|
||||
mDrmFormats[i] = aDesc.layers[i].drm_format;
|
||||
mOffsets[i] = aDesc.layers[i].offset[0];
|
||||
|
@ -1012,104 +1017,18 @@ bool DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor(
|
|||
mHeightAligned[i] = aDesc.height >> i;
|
||||
mWidth[i] = aWidth >> i;
|
||||
mHeight[i] = aHeight >> i;
|
||||
|
||||
LOGDMABUF((" plane %d size %d x %d format %x", i, mWidth[i], mHeight[i],
|
||||
mDrmFormats[i]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DMABufSurfaceYUV::MoveYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc,
|
||||
int aWidth, int aHeight) {
|
||||
if (!ImportPRIMESurfaceDescriptor(aDesc, aWidth, aHeight)) {
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DMABufSurfaceYUV::CreateYUVPlane(int aPlane) {
|
||||
bool DMABufSurfaceYUV::CreateYUVPlane(int aPlane, int aWidth, int aHeight,
|
||||
int aDrmFormat) {
|
||||
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVPlane() UID %d size %d x %d", mUID,
|
||||
mWidth[aPlane], mHeight[aPlane]));
|
||||
|
||||
if (!GetAndConfigureDMABufDevice()->GetGbmDevice()) {
|
||||
LOGDMABUF((" Missing GbmDevice!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useModifiers = (mBufferModifiers[aPlane] != DRM_FORMAT_MOD_INVALID);
|
||||
if (useModifiers) {
|
||||
mGbmBufferObject[aPlane] = nsGbmLib::CreateWithModifiers(
|
||||
GetDMABufDevice()->GetGbmDevice(), mWidth[aPlane], mHeight[aPlane],
|
||||
mDrmFormats[aPlane], mBufferModifiers + aPlane, 1);
|
||||
} else {
|
||||
mGbmBufferObject[aPlane] = nsGbmLib::Create(
|
||||
GetDMABufDevice()->GetGbmDevice(), mWidth[aPlane], mHeight[aPlane],
|
||||
mDrmFormats[aPlane], GBM_BO_USE_RENDERING);
|
||||
}
|
||||
if (!mGbmBufferObject[aPlane]) {
|
||||
LOGDMABUF((" Failed to create GbmBufferObject: %s", strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
|
||||
mStrides[aPlane] = nsGbmLib::GetStride(mGbmBufferObject[aPlane]);
|
||||
mOffsets[aPlane] = nsGbmLib::GetOffset(mGbmBufferObject[aPlane], 0);
|
||||
mWidthAligned[aPlane] = mWidth[aPlane];
|
||||
mHeightAligned[aPlane] = mHeight[aPlane];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DMABufSurfaceYUV::CopyYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc,
|
||||
int aWidth, int aHeight) {
|
||||
RefPtr<DMABufSurfaceYUV> tmpSurf = CreateYUVSurface(aDesc, aWidth, aHeight);
|
||||
if (!tmpSurf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ImportPRIMESurfaceDescriptor(aDesc, aWidth, aHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(sSnapshotContextMutex);
|
||||
RefPtr<GLContext> context = ClaimSnapshotGLContext();
|
||||
auto releaseTextures = MakeScopeExit([&] {
|
||||
tmpSurf->ReleaseTextures();
|
||||
ReleaseTextures();
|
||||
ReturnSnapshotGLContext(context);
|
||||
});
|
||||
|
||||
for (int i = 0; i < mBufferPlaneCount; i++) {
|
||||
if (!tmpSurf->CreateTexture(context, i)) {
|
||||
return false;
|
||||
}
|
||||
if (!CreateYUVPlane(i) || !CreateTexture(context, i)) {
|
||||
return false;
|
||||
}
|
||||
gfx::IntSize size(GetWidth(i), GetHeight(i));
|
||||
context->BlitHelper()->BlitTextureToTexture(
|
||||
tmpSurf->GetTexture(i), GetTexture(i), size, size, LOCAL_GL_TEXTURE_2D,
|
||||
LOCAL_GL_TEXTURE_2D);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DMABufSurfaceYUV::UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc,
|
||||
int aWidth, int aHeight, bool aCopy) {
|
||||
LOGDMABUF(("DMABufSurfaceYUV::UpdateYUVData() UID %d copy %d", mUID, aCopy));
|
||||
return aCopy ? CopyYUVDataImpl(aDesc, aWidth, aHeight)
|
||||
: MoveYUVDataImpl(aDesc, aWidth, aHeight);
|
||||
}
|
||||
|
||||
bool DMABufSurfaceYUV::CreateLinearYUVPlane(int aPlane, int aWidth, int aHeight,
|
||||
int aDrmFormat) {
|
||||
LOGDMABUF(("DMABufSurfaceYUV::CreateLinearYUVPlane() UID %d size %d x %d",
|
||||
mUID, aWidth, aHeight));
|
||||
aWidth, aHeight));
|
||||
|
||||
if (!GetDMABufDevice()->GetGbmDevice()) {
|
||||
LOGDMABUF((" Missing GbmDevice!"));
|
||||
|
@ -1199,13 +1118,13 @@ bool DMABufSurfaceYUV::Create(int aWidth, int aHeight, void** aPixelData,
|
|||
mSurfaceType = SURFACE_YUV420;
|
||||
mBufferPlaneCount = 3;
|
||||
|
||||
if (!CreateLinearYUVPlane(0, aWidth, aHeight, GBM_FORMAT_R8)) {
|
||||
if (!CreateYUVPlane(0, aWidth, aHeight, GBM_FORMAT_R8)) {
|
||||
return false;
|
||||
}
|
||||
if (!CreateLinearYUVPlane(1, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
|
||||
if (!CreateYUVPlane(1, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
|
||||
return false;
|
||||
}
|
||||
if (!CreateLinearYUVPlane(2, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
|
||||
if (!CreateYUVPlane(2, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
|
||||
return false;
|
||||
}
|
||||
if (!aPixelData || !aLineSizes) {
|
||||
|
|
|
@ -323,7 +323,7 @@ class DMABufSurfaceYUV : public DMABufSurface {
|
|||
|
||||
bool UpdateYUVData(void** aPixelData, int* aLineSizes);
|
||||
bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
|
||||
int aHeight, bool aCopy);
|
||||
int aHeight);
|
||||
|
||||
bool VerifyTextureCreation();
|
||||
|
||||
|
@ -332,18 +332,9 @@ class DMABufSurfaceYUV : public DMABufSurface {
|
|||
|
||||
bool Create(const mozilla::layers::SurfaceDescriptor& aDesc);
|
||||
bool Create(int aWidth, int aHeight, void** aPixelData, int* aLineSizes);
|
||||
bool CreateYUVPlane(int aPlane);
|
||||
bool CreateLinearYUVPlane(int aPlane, int aWidth, int aHeight,
|
||||
int aDrmFormat);
|
||||
bool CreateYUVPlane(int aPlane, int aWidth, int aHeight, int aDrmFormat);
|
||||
void UpdateYUVPlane(int aPlane, void* aPixelData, int aLineSize);
|
||||
|
||||
bool MoveYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
|
||||
int aHeight);
|
||||
bool CopyYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
|
||||
int aHeight);
|
||||
|
||||
bool ImportPRIMESurfaceDescriptor(const VADRMPRIMESurfaceDescriptor& aDesc,
|
||||
int aWidth, int aHeight);
|
||||
bool ImportSurfaceDescriptor(
|
||||
const mozilla::layers::SurfaceDescriptorDMABuf& aDesc);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче