mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-30 02:57:29 +09:00
Issue #2393 - Part 3 - Remove extra copy of YUV buffer on Windows
This commit is contained in:
parent
74a22e5c00
commit
b09b3771c6
9 changed files with 70 additions and 20 deletions
|
|
@ -9,9 +9,16 @@
|
||||||
#include "ImageContainer.h"
|
#include "ImageContainer.h"
|
||||||
#include "mozilla/layers/SharedRGBImage.h"
|
#include "mozilla/layers/SharedRGBImage.h"
|
||||||
#include "YCbCrUtils.h"
|
#include "YCbCrUtils.h"
|
||||||
|
#include "mozilla/layers/ImageBridgeChild.h"
|
||||||
|
#include "mozilla/layers/KnowsCompositor.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
#include "mozilla/WindowsVersion.h"
|
||||||
|
#include "mozilla/layers/D3D11YCbCrImage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
|
@ -218,19 +225,14 @@ VideoData::ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther,
|
||||||
return v.forget();
|
return v.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
PlanarYCbCrData
|
||||||
bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
ConstructPlanarYCbCrData(const VideoInfo& aInfo,
|
||||||
const VideoInfo& aInfo,
|
const VideoData::YCbCrBuffer& aBuffer,
|
||||||
const YCbCrBuffer &aBuffer,
|
const IntRect& aPicture)
|
||||||
const IntRect& aPicture,
|
|
||||||
bool aCopyData)
|
|
||||||
{
|
{
|
||||||
if (!aVideoImage) {
|
const VideoData::YCbCrBuffer::Plane& Y = aBuffer.mPlanes[0];
|
||||||
return false;
|
const VideoData::YCbCrBuffer::Plane& Cb = aBuffer.mPlanes[1];
|
||||||
}
|
const VideoData::YCbCrBuffer::Plane& Cr = aBuffer.mPlanes[2];
|
||||||
const YCbCrBuffer::Plane &Y = aBuffer.mPlanes[0];
|
|
||||||
const YCbCrBuffer::Plane &Cb = aBuffer.mPlanes[1];
|
|
||||||
const YCbCrBuffer::Plane &Cr = aBuffer.mPlanes[2];
|
|
||||||
|
|
||||||
PlanarYCbCrData data;
|
PlanarYCbCrData data;
|
||||||
data.mYChannel = Y.mData + Y.mOffset;
|
data.mYChannel = Y.mData + Y.mOffset;
|
||||||
|
|
@ -249,6 +251,21 @@ bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||||
data.mStereoMode = aInfo.mStereoMode;
|
data.mStereoMode = aInfo.mStereoMode;
|
||||||
data.mYUVColorSpace = aBuffer.mYUVColorSpace;
|
data.mYUVColorSpace = aBuffer.mYUVColorSpace;
|
||||||
data.mColorRange = aBuffer.mColorRange;
|
data.mColorRange = aBuffer.mColorRange;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ bool
|
||||||
|
VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||||
|
const VideoInfo& aInfo,
|
||||||
|
const YCbCrBuffer &aBuffer,
|
||||||
|
const IntRect& aPicture,
|
||||||
|
bool aCopyData)
|
||||||
|
{
|
||||||
|
if (!aVideoImage) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||||
|
|
||||||
aVideoImage->SetDelayedConversion(true);
|
aVideoImage->SetDelayedConversion(true);
|
||||||
if (aCopyData) {
|
if (aCopyData) {
|
||||||
|
|
@ -268,7 +285,8 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
const YCbCrBuffer& aBuffer,
|
const YCbCrBuffer& aBuffer,
|
||||||
bool aKeyframe,
|
bool aKeyframe,
|
||||||
int64_t aTimecode,
|
int64_t aTimecode,
|
||||||
const IntRect& aPicture)
|
const IntRect& aPicture,
|
||||||
|
layers::KnowsCompositor* aAllocator)
|
||||||
{
|
{
|
||||||
if (!aContainer) {
|
if (!aContainer) {
|
||||||
// Create a dummy VideoData with no image. This gives us something to
|
// Create a dummy VideoData with no image. This gives us something to
|
||||||
|
|
@ -296,6 +314,23 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
0));
|
0));
|
||||||
// Currently our decoder only knows how to output to ImageFormat::PLANAR_YCBCR
|
// Currently our decoder only knows how to output to ImageFormat::PLANAR_YCBCR
|
||||||
// format.
|
// format.
|
||||||
|
#if XP_WIN
|
||||||
|
// We disable this code path on Windows 7 due to intermittent crashes with old drivers.
|
||||||
|
// See Mozilla bug 1405110.
|
||||||
|
if (IsWin8OrLater() && !XRE_IsParentProcess() &&
|
||||||
|
aAllocator && aAllocator->GetCompositorBackendType()
|
||||||
|
== layers::LayersBackend::LAYERS_D3D11) {
|
||||||
|
RefPtr<layers::D3D11YCbCrImage> d3d11Image = new layers::D3D11YCbCrImage();
|
||||||
|
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||||
|
if (d3d11Image->SetData(layers::ImageBridgeChild::GetSingleton()
|
||||||
|
? layers::ImageBridgeChild::GetSingleton().get()
|
||||||
|
: aAllocator,
|
||||||
|
aContainer, data)) {
|
||||||
|
v->mImage = d3d11Image;
|
||||||
|
return v.forget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!v->mImage) {
|
if (!v->mImage) {
|
||||||
v->mImage = aContainer->CreatePlanarYCbCrImage();
|
v->mImage = aContainer->CreatePlanarYCbCrImage();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
class Image;
|
class Image;
|
||||||
class ImageContainer;
|
class ImageContainer;
|
||||||
|
class KnowsCompositor;
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|
||||||
class MediaByteBuffer;
|
class MediaByteBuffer;
|
||||||
|
|
@ -472,7 +473,8 @@ public:
|
||||||
const YCbCrBuffer &aBuffer,
|
const YCbCrBuffer &aBuffer,
|
||||||
bool aKeyframe,
|
bool aKeyframe,
|
||||||
int64_t aTimecode,
|
int64_t aTimecode,
|
||||||
const IntRect& aPicture);
|
const IntRect& aPicture,
|
||||||
|
layers::KnowsCompositor* aAllocator = nullptr);
|
||||||
|
|
||||||
static already_AddRefed<VideoData> CreateAndCopyData(const VideoInfo& aInfo,
|
static already_AddRefed<VideoData> CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
ImageContainer* aContainer,
|
ImageContainer* aContainer,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ ogg_packet InitTheoraPacket(const unsigned char* aData, size_t aLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
TheoraDecoder::TheoraDecoder(const CreateDecoderParams& aParams)
|
TheoraDecoder::TheoraDecoder(const CreateDecoderParams& aParams)
|
||||||
: mImageContainer(aParams.mImageContainer)
|
: mImageAllocator(aParams.mKnowsCompositor)
|
||||||
|
, mImageContainer(aParams.mImageContainer)
|
||||||
, mTaskQueue(aParams.mTaskQueue)
|
, mTaskQueue(aParams.mTaskQueue)
|
||||||
, mCallback(aParams.mCallback)
|
, mCallback(aParams.mCallback)
|
||||||
, mIsFlushing(false)
|
, mIsFlushing(false)
|
||||||
|
|
@ -176,7 +177,8 @@ TheoraDecoder::DoDecode(MediaRawData* aSample)
|
||||||
aSample->mKeyframe,
|
aSample->mKeyframe,
|
||||||
aSample->mTimecode,
|
aSample->mTimecode,
|
||||||
mInfo.ScaledImageRect(mTheoraInfo.frame_width,
|
mInfo.ScaledImageRect(mTheoraInfo.frame_width,
|
||||||
mTheoraInfo.frame_height));
|
mTheoraInfo.frame_height),
|
||||||
|
mImageAllocator);
|
||||||
if (!v) {
|
if (!v) {
|
||||||
LOG("Image allocation error source %ldx%ld display %ldx%ld picture %ldx%ld",
|
LOG("Image allocation error source %ldx%ld display %ldx%ld picture %ldx%ld",
|
||||||
mTheoraInfo.frame_width, mTheoraInfo.frame_height, mInfo.mDisplay.width, mInfo.mDisplay.height,
|
mTheoraInfo.frame_width, mTheoraInfo.frame_height, mInfo.mDisplay.width, mInfo.mDisplay.height,
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ private:
|
||||||
MediaResult DoDecode(MediaRawData* aSample);
|
MediaResult DoDecode(MediaRawData* aSample);
|
||||||
void ProcessDrain();
|
void ProcessDrain();
|
||||||
|
|
||||||
|
RefPtr<KnowsCompositor> mImageAllocator;
|
||||||
RefPtr<ImageContainer> mImageContainer;
|
RefPtr<ImageContainer> mImageContainer;
|
||||||
RefPtr<TaskQueue> mTaskQueue;
|
RefPtr<TaskQueue> mTaskQueue;
|
||||||
MediaDataDecoderCallback* mCallback;
|
MediaDataDecoderCallback* mCallback;
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ InitContext(vpx_codec_ctx_t* aCtx,
|
||||||
|
|
||||||
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
|
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
|
||||||
: mImageContainer(aParams.mImageContainer)
|
: mImageContainer(aParams.mImageContainer)
|
||||||
|
, mImageAllocator(aParams.mKnowsCompositor)
|
||||||
, mTaskQueue(aParams.mTaskQueue)
|
, mTaskQueue(aParams.mTaskQueue)
|
||||||
, mCallback(aParams.mCallback)
|
, mCallback(aParams.mCallback)
|
||||||
, mIsFlushing(false)
|
, mIsFlushing(false)
|
||||||
|
|
@ -149,7 +150,7 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
||||||
"WebM image format not I420 or I444");
|
"WebM image format not I420 or I444");
|
||||||
NS_ASSERTION(!alpha_decoded,
|
NS_ASSERTION(!alpha_decoded,
|
||||||
"Multiple frames per packet that contains alpha");
|
"Multiple frames per packet that contains alpha");
|
||||||
|
|
||||||
if (aSample->AlphaSize() > 0) {
|
if (aSample->AlphaSize() > 0) {
|
||||||
if(!alpha_decoded){
|
if(!alpha_decoded){
|
||||||
MediaResult rv = DecodeAlpha(&img_alpha, aSample);
|
MediaResult rv = DecodeAlpha(&img_alpha, aSample);
|
||||||
|
|
@ -221,7 +222,8 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
||||||
aSample->mKeyframe,
|
aSample->mKeyframe,
|
||||||
aSample->mTimecode,
|
aSample->mTimecode,
|
||||||
mInfo.ScaledImageRect(img->d_w,
|
mInfo.ScaledImageRect(img->d_w,
|
||||||
img->d_h));
|
img->d_h),
|
||||||
|
mImageAllocator);
|
||||||
} else {
|
} else {
|
||||||
VideoData::YCbCrBuffer::Plane alpha_plane;
|
VideoData::YCbCrBuffer::Plane alpha_plane;
|
||||||
alpha_plane.mData = img_alpha->planes[0];
|
alpha_plane.mData = img_alpha->planes[0];
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ private:
|
||||||
MediaRawData* aSample);
|
MediaRawData* aSample);
|
||||||
|
|
||||||
const RefPtr<ImageContainer> mImageContainer;
|
const RefPtr<ImageContainer> mImageContainer;
|
||||||
|
RefPtr<layers::KnowsCompositor> mImageAllocator;
|
||||||
const RefPtr<TaskQueue> mTaskQueue;
|
const RefPtr<TaskQueue> mTaskQueue;
|
||||||
MediaDataDecoderCallback* mCallback;
|
MediaDataDecoderCallback* mCallback;
|
||||||
Atomic<bool> mIsFlushing;
|
Atomic<bool> mIsFlushing;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ public:
|
||||||
aParams.mTaskQueue,
|
aParams.mTaskQueue,
|
||||||
aParams.mCallback,
|
aParams.mCallback,
|
||||||
aParams.VideoConfig(),
|
aParams.VideoConfig(),
|
||||||
|
aParams.mKnowsCompositor,
|
||||||
aParams.mImageContainer);
|
aParams.mImageContainer);
|
||||||
return decoder.forget();
|
return decoder.forget();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "MediaInfo.h"
|
#include "MediaInfo.h"
|
||||||
#include "VPXDecoder.h"
|
#include "VPXDecoder.h"
|
||||||
#include "MP4Decoder.h"
|
#include "MP4Decoder.h"
|
||||||
|
#include "mozilla/layers/KnowsCompositor.h"
|
||||||
|
|
||||||
#include "FFmpegVideoDecoder.h"
|
#include "FFmpegVideoDecoder.h"
|
||||||
#include "FFmpegLog.h"
|
#include "FFmpegLog.h"
|
||||||
|
|
@ -108,8 +109,9 @@ FFmpegVideoDecoder<LIBAV_VER>::PtsCorrectionContext::Reset()
|
||||||
FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(FFmpegLibWrapper* aLib,
|
FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(FFmpegLibWrapper* aLib,
|
||||||
TaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
|
TaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
|
||||||
const VideoInfo& aConfig,
|
const VideoInfo& aConfig,
|
||||||
ImageContainer* aImageContainer)
|
KnowsCompositor* aAllocator, ImageContainer* aImageContainer)
|
||||||
: FFmpegDataDecoder(aLib, aTaskQueue, aCallback, GetCodecId(aConfig.mMimeType))
|
: FFmpegDataDecoder(aLib, aTaskQueue, aCallback, GetCodecId(aConfig.mMimeType))
|
||||||
|
, mImageAllocator(aAllocator)
|
||||||
, mImageContainer(aImageContainer)
|
, mImageContainer(aImageContainer)
|
||||||
, mInfo(aConfig)
|
, mInfo(aConfig)
|
||||||
, mCodecParser(nullptr)
|
, mCodecParser(nullptr)
|
||||||
|
|
@ -395,7 +397,8 @@ FFmpegVideoDecoder<LIBAV_VER>::CreateImage(int64_t aOffset, int64_t aPts,
|
||||||
!!mFrame->key_frame,
|
!!mFrame->key_frame,
|
||||||
-1,
|
-1,
|
||||||
mInfo.ScaledImageRect(mFrame->width,
|
mInfo.ScaledImageRect(mFrame->width,
|
||||||
mFrame->height));
|
mFrame->height),
|
||||||
|
mImageAllocator);
|
||||||
|
|
||||||
if (!v) {
|
if (!v) {
|
||||||
return MediaResult(NS_ERROR_OUT_OF_MEMORY,
|
return MediaResult(NS_ERROR_OUT_OF_MEMORY,
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,13 @@ class FFmpegVideoDecoder<LIBAV_VER> : public FFmpegDataDecoder<LIBAV_VER>
|
||||||
{
|
{
|
||||||
typedef mozilla::layers::Image Image;
|
typedef mozilla::layers::Image Image;
|
||||||
typedef mozilla::layers::ImageContainer ImageContainer;
|
typedef mozilla::layers::ImageContainer ImageContainer;
|
||||||
|
typedef mozilla::layers::KnowsCompositor KnowsCompositor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FFmpegVideoDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
|
FFmpegVideoDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
|
||||||
MediaDataDecoderCallback* aCallback,
|
MediaDataDecoderCallback* aCallback,
|
||||||
const VideoInfo& aConfig,
|
const VideoInfo& aConfig,
|
||||||
|
KnowsCompositor* aAllocator,
|
||||||
ImageContainer* aImageContainer);
|
ImageContainer* aImageContainer);
|
||||||
virtual ~FFmpegVideoDecoder();
|
virtual ~FFmpegVideoDecoder();
|
||||||
|
|
||||||
|
|
@ -62,6 +64,7 @@ private:
|
||||||
int AllocateYUV420PVideoBuffer(AVCodecContext* aCodecContext,
|
int AllocateYUV420PVideoBuffer(AVCodecContext* aCodecContext,
|
||||||
AVFrame* aFrame);
|
AVFrame* aFrame);
|
||||||
|
|
||||||
|
RefPtr<KnowsCompositor> mImageAllocator;
|
||||||
RefPtr<ImageContainer> mImageContainer;
|
RefPtr<ImageContainer> mImageContainer;
|
||||||
VideoInfo mInfo;
|
VideoInfo mInfo;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue