mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-02 21:37:32 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
bac9ec9a84
39 changed files with 541 additions and 108 deletions
|
|
@ -115,6 +115,27 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
|
||||||
aRetval.set(view);
|
aRetval.set(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Crypto::RandomUUID(nsAString& aRetVal)
|
||||||
|
{
|
||||||
|
// NSID_LENGTH == 39 == 36 UUID chars + 2 curly braces + 1 NUL byte
|
||||||
|
static_assert(NSID_LENGTH == 39);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||||
|
do_GetService("@mozilla.org/uuid-generator;1");
|
||||||
|
|
||||||
|
nsID uuid;
|
||||||
|
|
||||||
|
nsresult rv = uuidgen->GenerateUUIDInPlace(&uuid);
|
||||||
|
|
||||||
|
char uuidBuffer[NSID_LENGTH];
|
||||||
|
uuid.ToProvidedString(uuidBuffer);
|
||||||
|
|
||||||
|
nsCString asciiString(uuidBuffer);
|
||||||
|
|
||||||
|
// Convert UUID chars to UTF-16 retval, omitting the curly braces and NUL
|
||||||
|
CopyASCIItoUTF16(Substring(asciiString, 1, NSID_LENGTH - 3), aRetVal);
|
||||||
|
}
|
||||||
|
|
||||||
SubtleCrypto*
|
SubtleCrypto*
|
||||||
Crypto::Subtle()
|
Crypto::Subtle()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "mozilla/dom/SubtleCrypto.h"
|
#include "mozilla/dom/SubtleCrypto.h"
|
||||||
#include "nsIGlobalObject.h"
|
#include "nsIGlobalObject.h"
|
||||||
|
|
||||||
|
#include "nsString.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "mozilla/dom/TypedArray.h"
|
#include "mozilla/dom/TypedArray.h"
|
||||||
#define NS_DOMCRYPTO_CID \
|
#define NS_DOMCRYPTO_CID \
|
||||||
|
|
@ -39,6 +40,8 @@ public:
|
||||||
JS::MutableHandle<JSObject*> aRetval,
|
JS::MutableHandle<JSObject*> aRetval,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void RandomUUID(nsAString& aRetVal);
|
||||||
|
|
||||||
SubtleCrypto*
|
SubtleCrypto*
|
||||||
Subtle();
|
Subtle();
|
||||||
|
|
||||||
|
|
|
||||||
2
dom/cache/TypeUtils.cpp
vendored
2
dom/cache/TypeUtils.cpp
vendored
|
|
@ -190,7 +190,7 @@ TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
|
||||||
aOut.statusText() = aIn.GetUnfilteredStatusText();
|
aOut.statusText() = aIn.GetUnfilteredStatusText();
|
||||||
RefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
|
RefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
|
||||||
MOZ_DIAGNOSTIC_ASSERT(headers);
|
MOZ_DIAGNOSTIC_ASSERT(headers);
|
||||||
if (HasVaryStar(headers)) {
|
if (aIn.Type() != ResponseType::Opaque && HasVaryStar(headers)) {
|
||||||
aRv.ThrowTypeError<MSG_RESPONSE_HAS_VARY_STAR>();
|
aRv.ThrowTypeError<MSG_RESPONSE_HAS_VARY_STAR>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "gfxPrefs.h"
|
||||||
#include "GLContextTypes.h"
|
#include "GLContextTypes.h"
|
||||||
#include "GLDefs.h"
|
#include "GLDefs.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
@ -1397,6 +1398,7 @@ protected:
|
||||||
CheckedUint32 mGeneration;
|
CheckedUint32 mGeneration;
|
||||||
|
|
||||||
WebGLContextOptions mOptions;
|
WebGLContextOptions mOptions;
|
||||||
|
const uint32_t mMaxVertIdsPerDraw = gfxPrefs::WebglMaxVertIDsPerDraw();
|
||||||
|
|
||||||
bool mInvalidated;
|
bool mInvalidated;
|
||||||
bool mCapturedFrameInvalidated;
|
bool mCapturedFrameInvalidated;
|
||||||
|
|
|
||||||
|
|
@ -608,6 +608,12 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
|
if (vertCount > mMaxVertIdsPerDraw) {
|
||||||
|
ErrorOutOfMemory(
|
||||||
|
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
|
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
@ -850,6 +856,12 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type,
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
|
if (vertCount > mMaxVertIdsPerDraw) {
|
||||||
|
ErrorOutOfMemory(
|
||||||
|
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
|
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include "MediaInfo.h"
|
#include "MediaInfo.h"
|
||||||
#include "VideoUtils.h"
|
#include "VideoUtils.h"
|
||||||
#include "ImageContainer.h"
|
#include "ImageContainer.h"
|
||||||
|
#include "mozilla/layers/SharedRGBImage.h"
|
||||||
|
#include "YCbCrUtils.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
@ -89,6 +91,45 @@ ValidatePlane(const VideoData::YCbCrBuffer::Plane& aPlane)
|
||||||
aPlane.mStride > 0 && aPlane.mWidth <= aPlane.mStride;
|
aPlane.mStride > 0 && aPlane.mWidth <= aPlane.mStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ValidateBufferAndPicture(const VideoData::YCbCrBuffer& aBuffer,
|
||||||
|
const IntRect& aPicture)
|
||||||
|
{
|
||||||
|
// The following situation should never happen unless there is a bug
|
||||||
|
// in the decoder
|
||||||
|
if (aBuffer.mPlanes[1].mWidth != aBuffer.mPlanes[2].mWidth ||
|
||||||
|
aBuffer.mPlanes[1].mHeight != aBuffer.mPlanes[2].mHeight) {
|
||||||
|
NS_ERROR("C planes with different sizes");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following situations could be triggered by invalid input
|
||||||
|
if (aPicture.width <= 0 || aPicture.height <= 0) {
|
||||||
|
// In debug mode, makes the error more noticeable
|
||||||
|
MOZ_ASSERT(false, "Empty picture rect");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ValidatePlane(aBuffer.mPlanes[0]) ||
|
||||||
|
!ValidatePlane(aBuffer.mPlanes[1]) ||
|
||||||
|
!ValidatePlane(aBuffer.mPlanes[2])) {
|
||||||
|
NS_WARNING("Invalid plane size");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the picture size specified in the headers can be extracted out of
|
||||||
|
// the frame we've been supplied without indexing out of bounds.
|
||||||
|
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
|
||||||
|
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
|
||||||
|
if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
|
||||||
|
!yLimit.isValid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
|
||||||
|
{
|
||||||
|
// The specified picture dimensions can't be contained inside the video
|
||||||
|
// frame, we'll stomp memory if we try to copy it. Fail.
|
||||||
|
NS_WARNING("Overflowing picture rect");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
VideoData::VideoData(int64_t aOffset,
|
VideoData::VideoData(int64_t aOffset,
|
||||||
int64_t aTime,
|
int64_t aTime,
|
||||||
int64_t aDuration,
|
int64_t aDuration,
|
||||||
|
|
@ -242,36 +283,7 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
return v.forget();
|
return v.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following situation should never happen unless there is a bug
|
if (!ValidateBufferAndPicture(aBuffer, aPicture)) {
|
||||||
// in the decoder
|
|
||||||
if (aBuffer.mPlanes[1].mWidth != aBuffer.mPlanes[2].mWidth ||
|
|
||||||
aBuffer.mPlanes[1].mHeight != aBuffer.mPlanes[2].mHeight) {
|
|
||||||
NS_ERROR("C planes with different sizes");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following situations could be triggered by invalid input
|
|
||||||
if (aPicture.width <= 0 || aPicture.height <= 0) {
|
|
||||||
// In debug mode, makes the error more noticeable
|
|
||||||
MOZ_ASSERT(false, "Empty picture rect");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (!ValidatePlane(aBuffer.mPlanes[0]) || !ValidatePlane(aBuffer.mPlanes[1]) ||
|
|
||||||
!ValidatePlane(aBuffer.mPlanes[2])) {
|
|
||||||
NS_WARNING("Invalid plane size");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the picture size specified in the headers can be extracted out of
|
|
||||||
// the frame we've been supplied without indexing out of bounds.
|
|
||||||
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
|
|
||||||
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
|
|
||||||
if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
|
|
||||||
!yLimit.isValid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
|
|
||||||
{
|
|
||||||
// The specified picture dimensions can't be contained inside the video
|
|
||||||
// frame, we'll stomp memory if we try to copy it. Fail.
|
|
||||||
NS_WARNING("Overflowing picture rect");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,6 +317,73 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
return v.forget();
|
return v.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
already_AddRefed<VideoData>
|
||||||
|
VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
|
ImageContainer* aContainer,
|
||||||
|
int64_t aOffset,
|
||||||
|
int64_t aTime,
|
||||||
|
int64_t aDuration,
|
||||||
|
const YCbCrBuffer& aBuffer,
|
||||||
|
const YCbCrBuffer::Plane &aAlphaPlane,
|
||||||
|
bool aKeyframe,
|
||||||
|
int64_t aTimecode,
|
||||||
|
const IntRect& aPicture)
|
||||||
|
{
|
||||||
|
if (!aContainer) {
|
||||||
|
// Create a dummy VideoData with no image. This gives us something to
|
||||||
|
// send to media streams if necessary.
|
||||||
|
RefPtr<VideoData> v(new VideoData(aOffset,
|
||||||
|
aTime,
|
||||||
|
aDuration,
|
||||||
|
aKeyframe,
|
||||||
|
aTimecode,
|
||||||
|
aInfo.mDisplay,
|
||||||
|
0));
|
||||||
|
return v.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidateBufferAndPicture(aBuffer, aPicture)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<VideoData> v(new VideoData(aOffset,
|
||||||
|
aTime,
|
||||||
|
aDuration,
|
||||||
|
aKeyframe,
|
||||||
|
aTimecode,
|
||||||
|
aInfo.mDisplay,
|
||||||
|
0));
|
||||||
|
|
||||||
|
// Convert from YUVA to BGRA format on the software side.
|
||||||
|
RefPtr<layers::SharedRGBImage> videoImage =
|
||||||
|
aContainer->CreateSharedRGBImage();
|
||||||
|
v->mImage = videoImage;
|
||||||
|
|
||||||
|
if (!v->mImage) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (!videoImage->Allocate(IntSize(aBuffer.mPlanes[0].mWidth,
|
||||||
|
aBuffer.mPlanes[0].mHeight),
|
||||||
|
SurfaceFormat::B8G8R8A8)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
uint8_t* argb_buffer = videoImage->GetBuffer();
|
||||||
|
IntSize size = videoImage->GetSize();
|
||||||
|
|
||||||
|
// The naming convention for libyuv and associated utils is word-order.
|
||||||
|
// The naming convention in the gfx stack is byte-order.
|
||||||
|
ConvertYCbCrAToARGB(aBuffer.mPlanes[0].mData,
|
||||||
|
aBuffer.mPlanes[1].mData,
|
||||||
|
aBuffer.mPlanes[2].mData,
|
||||||
|
aAlphaPlane.mData,
|
||||||
|
aBuffer.mPlanes[0].mStride, aBuffer.mPlanes[1].mStride,
|
||||||
|
argb_buffer, size.width * 4,
|
||||||
|
size.width, size.height);
|
||||||
|
|
||||||
|
return v.forget();
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
already_AddRefed<VideoData>
|
already_AddRefed<VideoData>
|
||||||
VideoData::CreateFromImage(const VideoInfo& aInfo,
|
VideoData::CreateFromImage(const VideoInfo& aInfo,
|
||||||
|
|
@ -340,6 +419,15 @@ MediaRawData::MediaRawData(const uint8_t* aData, size_t aSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaRawData::MediaRawData(const uint8_t* aData, size_t aSize,
|
||||||
|
const uint8_t* aAlphaData, size_t aAlphaSize)
|
||||||
|
: MediaData(RAW_DATA, 0)
|
||||||
|
, mCrypto(mCryptoInternal)
|
||||||
|
, mBuffer(aData, aSize)
|
||||||
|
, mAlphaBuffer(aAlphaData, aAlphaSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<MediaRawData>
|
already_AddRefed<MediaRawData>
|
||||||
MediaRawData::Clone() const
|
MediaRawData::Clone() const
|
||||||
{
|
{
|
||||||
|
|
@ -356,6 +444,9 @@ MediaRawData::Clone() const
|
||||||
if (!s->mBuffer.Append(mBuffer.Data(), mBuffer.Length())) {
|
if (!s->mBuffer.Append(mBuffer.Data(), mBuffer.Length())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (!s->mAlphaBuffer.Append(mAlphaBuffer.Data(), mAlphaBuffer.Length())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
return s.forget();
|
return s.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,17 @@ public:
|
||||||
int64_t aTimecode,
|
int64_t aTimecode,
|
||||||
const IntRect& aPicture);
|
const IntRect& aPicture);
|
||||||
|
|
||||||
|
static already_AddRefed<VideoData> CreateAndCopyData(const VideoInfo& aInfo,
|
||||||
|
ImageContainer* aContainer,
|
||||||
|
int64_t aOffset,
|
||||||
|
int64_t aTime,
|
||||||
|
int64_t aDuration,
|
||||||
|
const YCbCrBuffer &aBuffer,
|
||||||
|
const YCbCrBuffer::Plane &aAlphaPlane,
|
||||||
|
bool aKeyframe,
|
||||||
|
int64_t aTimecode,
|
||||||
|
const IntRect& aPicture);
|
||||||
|
|
||||||
static already_AddRefed<VideoData> CreateAndCopyIntoTextureClient(const VideoInfo& aInfo,
|
static already_AddRefed<VideoData> CreateAndCopyIntoTextureClient(const VideoInfo& aInfo,
|
||||||
int64_t aOffset,
|
int64_t aOffset,
|
||||||
int64_t aTime,
|
int64_t aTime,
|
||||||
|
|
@ -622,15 +633,22 @@ private:
|
||||||
class MediaRawData : public MediaData {
|
class MediaRawData : public MediaData {
|
||||||
public:
|
public:
|
||||||
MediaRawData();
|
MediaRawData();
|
||||||
MediaRawData(const uint8_t* aData, size_t mSize);
|
MediaRawData(const uint8_t* aData, size_t aSize);
|
||||||
|
MediaRawData(const uint8_t* aData, size_t aSize,
|
||||||
|
const uint8_t* aAlphaData, size_t aAlphaSize);
|
||||||
|
|
||||||
// Pointer to data or null if not-yet allocated
|
// Pointer to data or null if not-yet allocated
|
||||||
const uint8_t* Data() const { return mBuffer.Data(); }
|
const uint8_t* Data() const { return mBuffer.Data(); }
|
||||||
|
// Pointer to alpha data or null if not-yet allocated
|
||||||
|
const uint8_t* AlphaData() const { return mAlphaBuffer.Data(); }
|
||||||
// Size of buffer.
|
// Size of buffer.
|
||||||
size_t Size() const { return mBuffer.Length(); }
|
size_t Size() const { return mBuffer.Length(); }
|
||||||
|
size_t AlphaSize() const { return mAlphaBuffer.Length(); }
|
||||||
size_t ComputedSizeOfIncludingThis() const
|
size_t ComputedSizeOfIncludingThis() const
|
||||||
{
|
{
|
||||||
return sizeof(*this) + mBuffer.ComputedSizeOfExcludingThis();
|
return sizeof(*this)
|
||||||
|
+ mBuffer.ComputedSizeOfExcludingThis()
|
||||||
|
+ mAlphaBuffer.ComputedSizeOfExcludingThis();
|
||||||
}
|
}
|
||||||
// Access the buffer as a Span.
|
// Access the buffer as a Span.
|
||||||
operator Span<const uint8_t>() { return MakeSpan(Data(), Size()); }
|
operator Span<const uint8_t>() { return MakeSpan(Data(), Size()); }
|
||||||
|
|
@ -661,6 +679,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
friend class MediaRawDataWriter;
|
friend class MediaRawDataWriter;
|
||||||
AlignedByteBuffer mBuffer;
|
AlignedByteBuffer mBuffer;
|
||||||
|
AlignedByteBuffer mAlphaBuffer;
|
||||||
CryptoSample mCryptoInternal;
|
CryptoSample mCryptoInternal;
|
||||||
MediaRawData(const MediaRawData&); // Not implemented
|
MediaRawData(const MediaRawData&); // Not implemented
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,7 @@ public:
|
||||||
, mRotation(aOther.mRotation)
|
, mRotation(aOther.mRotation)
|
||||||
, mBitDepth(aOther.mBitDepth)
|
, mBitDepth(aOther.mBitDepth)
|
||||||
, mImageRect(aOther.mImageRect)
|
, mImageRect(aOther.mImageRect)
|
||||||
|
, mAlphaPresent(aOther.mAlphaPresent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,6 +239,16 @@ public:
|
||||||
return MakeUnique<VideoInfo>(*this);
|
return MakeUnique<VideoInfo>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAlpha(bool aAlphaPresent)
|
||||||
|
{
|
||||||
|
mAlphaPresent = aAlphaPresent;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasAlpha() const
|
||||||
|
{
|
||||||
|
return mAlphaPresent;
|
||||||
|
}
|
||||||
|
|
||||||
nsIntRect ImageRect() const
|
nsIntRect ImageRect() const
|
||||||
{
|
{
|
||||||
if (mImageRect.width < 0 || mImageRect.height < 0) {
|
if (mImageRect.width < 0 || mImageRect.height < 0) {
|
||||||
|
|
@ -312,6 +323,9 @@ private:
|
||||||
// mImage may be cropped; currently only used with the WebM container.
|
// mImage may be cropped; currently only used with the WebM container.
|
||||||
// A negative width or height indicate that no cropping is to occur.
|
// A negative width or height indicate that no cropping is to occur.
|
||||||
nsIntRect mImageRect;
|
nsIntRect mImageRect;
|
||||||
|
|
||||||
|
// Indicates whether or not frames may contain alpha information.
|
||||||
|
bool mAlphaPresent = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioInfo : public TrackInfo {
|
class AudioInfo : public TrackInfo {
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ MediaSourceDemuxer::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes
|
||||||
RefPtr<MediaSourceDecoder::ResourceSizes> sizes = aSizes;
|
RefPtr<MediaSourceDecoder::ResourceSizes> sizes = aSizes;
|
||||||
nsCOMPtr<nsIRunnable> task =
|
nsCOMPtr<nsIRunnable> task =
|
||||||
NS_NewRunnableFunction([self, sizes] () {
|
NS_NewRunnableFunction([self, sizes] () {
|
||||||
for (TrackBuffersManager* manager : self->mSourceBuffers) {
|
for (const RefPtr<TrackBuffersManager>& manager : self->mSourceBuffers) {
|
||||||
manager->AddSizeOfResources(sizes);
|
manager->AddSizeOfResources(sizes);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -171,42 +171,45 @@ MediaSourceDemuxer::GetCrypto()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaSourceDemuxer::AttachSourceBuffer(TrackBuffersManager* aSourceBuffer)
|
MediaSourceDemuxer::AttachSourceBuffer(
|
||||||
|
RefPtr<TrackBuffersManager>& aSourceBuffer)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIRunnable> task =
|
nsCOMPtr<nsIRunnable> task = NewRunnableMethod<RefPtr<TrackBuffersManager>&&>(
|
||||||
NewRunnableMethod<TrackBuffersManager*>(
|
|
||||||
this, &MediaSourceDemuxer::DoAttachSourceBuffer,
|
this, &MediaSourceDemuxer::DoAttachSourceBuffer,
|
||||||
aSourceBuffer);
|
aSourceBuffer);
|
||||||
GetTaskQueue()->Dispatch(task.forget());
|
GetTaskQueue()->Dispatch(task.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaSourceDemuxer::DoAttachSourceBuffer(mozilla::TrackBuffersManager* aSourceBuffer)
|
MediaSourceDemuxer::DoAttachSourceBuffer(
|
||||||
|
RefPtr<mozilla::TrackBuffersManager>&& aSourceBuffer)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
mSourceBuffers.AppendElement(aSourceBuffer);
|
mSourceBuffers.AppendElement(Move(aSourceBuffer));
|
||||||
ScanSourceBuffersForContent();
|
ScanSourceBuffersForContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaSourceDemuxer::DetachSourceBuffer(TrackBuffersManager* aSourceBuffer)
|
MediaSourceDemuxer::DetachSourceBuffer(
|
||||||
|
RefPtr<TrackBuffersManager>& aSourceBuffer)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIRunnable> task =
|
RefPtr<MediaSourceDemuxer> self = this;
|
||||||
NewRunnableMethod<TrackBuffersManager*>(
|
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction(
|
||||||
this, &MediaSourceDemuxer::DoDetachSourceBuffer,
|
[self, aSourceBuffer]() {
|
||||||
aSourceBuffer);
|
self->DoDetachSourceBuffer(aSourceBuffer);
|
||||||
|
});
|
||||||
GetTaskQueue()->Dispatch(task.forget());
|
GetTaskQueue()->Dispatch(task.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaSourceDemuxer::DoDetachSourceBuffer(TrackBuffersManager* aSourceBuffer)
|
MediaSourceDemuxer::DoDetachSourceBuffer(
|
||||||
|
const RefPtr<TrackBuffersManager>& aSourceBuffer)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
for (uint32_t i = 0; i < mSourceBuffers.Length(); i++) {
|
mSourceBuffers.RemoveElementsBy(
|
||||||
if (mSourceBuffers[i].get() == aSourceBuffer) {
|
[&aSourceBuffer](const RefPtr<TrackBuffersManager> aLinkedSourceBuffer) {
|
||||||
mSourceBuffers.RemoveElementAt(i);
|
return aLinkedSourceBuffer == aSourceBuffer;
|
||||||
}
|
});
|
||||||
}
|
|
||||||
if (aSourceBuffer == mAudioTrack) {
|
if (aSourceBuffer == mAudioTrack) {
|
||||||
mAudioTrack = nullptr;
|
mAudioTrack = nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +233,7 @@ MediaSourceDemuxer::GetTrackInfo(TrackType aTrack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackBuffersManager*
|
RefPtr<TrackBuffersManager>
|
||||||
MediaSourceDemuxer::GetManager(TrackType aTrack)
|
MediaSourceDemuxer::GetManager(TrackType aTrack)
|
||||||
{
|
{
|
||||||
MonitorAutoLock mon(mMonitor);
|
MonitorAutoLock mon(mMonitor);
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ public:
|
||||||
void NotifyDataArrived() override;
|
void NotifyDataArrived() override;
|
||||||
|
|
||||||
/* interface for TrackBuffersManager */
|
/* interface for TrackBuffersManager */
|
||||||
void AttachSourceBuffer(TrackBuffersManager* aSourceBuffer);
|
void AttachSourceBuffer(RefPtr<TrackBuffersManager>& aSourceBuffer);
|
||||||
void DetachSourceBuffer(TrackBuffersManager* aSourceBuffer);
|
void DetachSourceBuffer(RefPtr<TrackBuffersManager>& aSourceBuffer);
|
||||||
AutoTaskQueue* GetTaskQueue() { return mTaskQueue; }
|
AutoTaskQueue* GetTaskQueue() { return mTaskQueue; }
|
||||||
|
|
||||||
// Returns a string describing the state of the MediaSource internal
|
// Returns a string describing the state of the MediaSource internal
|
||||||
|
|
@ -64,10 +64,10 @@ private:
|
||||||
// Scan source buffers and update information.
|
// Scan source buffers and update information.
|
||||||
bool ScanSourceBuffersForContent();
|
bool ScanSourceBuffersForContent();
|
||||||
RefPtr<InitPromise> AttemptInit();
|
RefPtr<InitPromise> AttemptInit();
|
||||||
TrackBuffersManager* GetManager(TrackInfo::TrackType aType);
|
RefPtr<TrackBuffersManager> GetManager(TrackInfo::TrackType aType);
|
||||||
TrackInfo* GetTrackInfo(TrackInfo::TrackType);
|
TrackInfo* GetTrackInfo(TrackInfo::TrackType);
|
||||||
void DoAttachSourceBuffer(TrackBuffersManager* aSourceBuffer);
|
void DoAttachSourceBuffer(RefPtr<TrackBuffersManager>&& aSourceBuffer);
|
||||||
void DoDetachSourceBuffer(TrackBuffersManager* aSourceBuffer);
|
void DoDetachSourceBuffer(const RefPtr<TrackBuffersManager>& aSourceBuffer);
|
||||||
bool OnTaskQueue()
|
bool OnTaskQueue()
|
||||||
{
|
{
|
||||||
return !GetTaskQueue() || GetTaskQueue()->IsCurrentThreadIn();
|
return !GetTaskQueue() || GetTaskQueue()->IsCurrentThreadIn();
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ SourceBuffer::Detach()
|
||||||
if (mTrackBuffersManager) {
|
if (mTrackBuffersManager) {
|
||||||
mTrackBuffersManager->Detach();
|
mTrackBuffersManager->Detach();
|
||||||
mMediaSource->GetDecoder()->GetDemuxer()->DetachSourceBuffer(
|
mMediaSource->GetDecoder()->GetDemuxer()->DetachSourceBuffer(
|
||||||
mTrackBuffersManager.get());
|
mTrackBuffersManager);
|
||||||
}
|
}
|
||||||
mTrackBuffersManager = nullptr;
|
mTrackBuffersManager = nullptr;
|
||||||
mMediaSource = nullptr;
|
mMediaSource = nullptr;
|
||||||
|
|
@ -321,7 +321,7 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
|
||||||
SetMode(SourceBufferAppendMode::Segments, dummy);
|
SetMode(SourceBufferAppendMode::Segments, dummy);
|
||||||
}
|
}
|
||||||
mMediaSource->GetDecoder()->GetDemuxer()->AttachSourceBuffer(
|
mMediaSource->GetDecoder()->GetDemuxer()->AttachSourceBuffer(
|
||||||
mTrackBuffersManager.get());
|
mTrackBuffersManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceBuffer::~SourceBuffer()
|
SourceBuffer::~SourceBuffer()
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,38 @@ static VPXDecoder::Codec MimeTypeToCodec(const nsACString& aMimeType)
|
||||||
return VPXDecoder::Codec::Unknown;
|
return VPXDecoder::Codec::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
InitContext(vpx_codec_ctx_t* aCtx,
|
||||||
|
const VideoInfo& aInfo,
|
||||||
|
const VPXDecoder::Codec aCodec)
|
||||||
|
{
|
||||||
|
int decode_threads = 2;
|
||||||
|
|
||||||
|
vpx_codec_iface_t* dx = nullptr;
|
||||||
|
if (aCodec == VPXDecoder::Codec::VP8) {
|
||||||
|
dx = vpx_codec_vp8_dx();
|
||||||
|
}
|
||||||
|
else if (aCodec == VPXDecoder::Codec::VP9) {
|
||||||
|
dx = vpx_codec_vp9_dx();
|
||||||
|
if (aInfo.mDisplay.width >= 2048) {
|
||||||
|
decode_threads = 8;
|
||||||
|
}
|
||||||
|
else if (aInfo.mDisplay.width >= 1024) {
|
||||||
|
decode_threads = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors());
|
||||||
|
|
||||||
|
vpx_codec_dec_cfg_t config;
|
||||||
|
config.threads = decode_threads;
|
||||||
|
config.w = config.h = 0; // set after decode
|
||||||
|
|
||||||
|
if (!dx || vpx_codec_dec_init(aCtx, dx, &config, 0)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
|
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
|
||||||
: mImageContainer(aParams.mImageContainer)
|
: mImageContainer(aParams.mImageContainer)
|
||||||
, mTaskQueue(aParams.mTaskQueue)
|
, mTaskQueue(aParams.mTaskQueue)
|
||||||
|
|
@ -45,6 +77,7 @@ VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(VPXDecoder);
|
MOZ_COUNT_CTOR(VPXDecoder);
|
||||||
PodZero(&mVPX);
|
PodZero(&mVPX);
|
||||||
|
PodZero(&mVPXAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
VPXDecoder::~VPXDecoder()
|
VPXDecoder::~VPXDecoder()
|
||||||
|
|
@ -56,34 +89,24 @@ void
|
||||||
VPXDecoder::Shutdown()
|
VPXDecoder::Shutdown()
|
||||||
{
|
{
|
||||||
vpx_codec_destroy(&mVPX);
|
vpx_codec_destroy(&mVPX);
|
||||||
|
vpx_codec_destroy(&mVPXAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<MediaDataDecoder::InitPromise>
|
RefPtr<MediaDataDecoder::InitPromise>
|
||||||
VPXDecoder::Init()
|
VPXDecoder::Init()
|
||||||
{
|
{
|
||||||
int decode_threads = 2;
|
if (NS_FAILED(InitContext(&mVPX, mInfo, mCodec))) {
|
||||||
|
return VPXDecoder::InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||||
vpx_codec_iface_t* dx = nullptr;
|
__func__);
|
||||||
if (mCodec == Codec::VP8) {
|
}
|
||||||
dx = vpx_codec_vp8_dx();
|
if (mInfo.HasAlpha()) {
|
||||||
} else if (mCodec == Codec::VP9) {
|
if (NS_FAILED(InitContext(&mVPXAlpha, mInfo, mCodec))) {
|
||||||
dx = vpx_codec_vp9_dx();
|
return VPXDecoder::InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||||
if (mInfo.mDisplay.width >= 2048) {
|
__func__);
|
||||||
decode_threads = 8;
|
|
||||||
} else if (mInfo.mDisplay.width >= 1024) {
|
|
||||||
decode_threads = 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors());
|
return VPXDecoder::InitPromise::CreateAndResolve(TrackInfo::kVideoTrack,
|
||||||
|
__func__);
|
||||||
vpx_codec_dec_cfg_t config;
|
|
||||||
config.threads = decode_threads;
|
|
||||||
config.w = config.h = 0; // set after decode
|
|
||||||
|
|
||||||
if (!dx || vpx_codec_dec_init(&mVPX, dx, &config, 0)) {
|
|
||||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
|
||||||
}
|
|
||||||
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -115,14 +138,27 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
||||||
RESULT_DETAIL("VPX error: %s", vpx_codec_err_to_string(r)));
|
RESULT_DETAIL("VPX error: %s", vpx_codec_err_to_string(r)));
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_codec_iter_t iter = nullptr;
|
vpx_codec_iter_t iter = nullptr;
|
||||||
vpx_image_t *img;
|
vpx_image_t *img;
|
||||||
|
vpx_image_t *img_alpha = nullptr;
|
||||||
|
bool alpha_decoded = false;
|
||||||
|
|
||||||
while ((img = vpx_codec_get_frame(&mVPX, &iter))) {
|
while ((img = vpx_codec_get_frame(&mVPX, &iter))) {
|
||||||
NS_ASSERTION(img->fmt == VPX_IMG_FMT_I420 ||
|
NS_ASSERTION(img->fmt == VPX_IMG_FMT_I420 ||
|
||||||
img->fmt == VPX_IMG_FMT_I444,
|
img->fmt == VPX_IMG_FMT_I444,
|
||||||
"WebM image format not I420 or I444");
|
"WebM image format not I420 or I444");
|
||||||
|
NS_ASSERTION(!alpha_decoded,
|
||||||
|
"Multiple frames per packet that contains alpha");
|
||||||
|
|
||||||
|
if (aSample->AlphaSize() > 0) {
|
||||||
|
if(!alpha_decoded){
|
||||||
|
MediaResult rv = DecodeAlpha(&img_alpha, aSample);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return(rv);
|
||||||
|
}
|
||||||
|
alpha_decoded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Chroma shifts are rounded down as per the decoding examples in the SDK
|
// Chroma shifts are rounded down as per the decoding examples in the SDK
|
||||||
VideoData::YCbCrBuffer b;
|
VideoData::YCbCrBuffer b;
|
||||||
b.mPlanes[0].mData = img->planes[0];
|
b.mPlanes[0].mData = img->planes[0];
|
||||||
|
|
@ -174,17 +210,38 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
||||||
}();
|
}();
|
||||||
// TODO: need a newer libvpx to support full color range
|
// TODO: need a newer libvpx to support full color range
|
||||||
|
|
||||||
RefPtr<VideoData> v =
|
RefPtr<VideoData> v;
|
||||||
VideoData::CreateAndCopyData(mInfo,
|
if (!img_alpha) {
|
||||||
mImageContainer,
|
v = VideoData::CreateAndCopyData(mInfo,
|
||||||
aSample->mOffset,
|
mImageContainer,
|
||||||
aSample->mTime,
|
aSample->mOffset,
|
||||||
aSample->mDuration,
|
aSample->mTime,
|
||||||
b,
|
aSample->mDuration,
|
||||||
aSample->mKeyframe,
|
b,
|
||||||
aSample->mTimecode,
|
aSample->mKeyframe,
|
||||||
mInfo.ScaledImageRect(img->d_w,
|
aSample->mTimecode,
|
||||||
img->d_h));
|
mInfo.ScaledImageRect(img->d_w,
|
||||||
|
img->d_h));
|
||||||
|
} else {
|
||||||
|
VideoData::YCbCrBuffer::Plane alpha_plane;
|
||||||
|
alpha_plane.mData = img_alpha->planes[0];
|
||||||
|
alpha_plane.mStride = img_alpha->stride[0];
|
||||||
|
alpha_plane.mHeight = img_alpha->d_h;
|
||||||
|
alpha_plane.mWidth = img_alpha->d_w;
|
||||||
|
alpha_plane.mOffset = alpha_plane.mSkip = 0;
|
||||||
|
v = VideoData::CreateAndCopyData(mInfo,
|
||||||
|
mImageContainer,
|
||||||
|
aSample->mOffset,
|
||||||
|
aSample->mTime,
|
||||||
|
aSample->mDuration,
|
||||||
|
b,
|
||||||
|
alpha_plane,
|
||||||
|
aSample->mKeyframe,
|
||||||
|
aSample->mTimecode,
|
||||||
|
mInfo.ScaledImageRect(img->d_w,
|
||||||
|
img->d_h));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
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",
|
||||||
|
|
@ -234,6 +291,32 @@ VPXDecoder::Drain()
|
||||||
mTaskQueue->Dispatch(NewRunnableMethod(this, &VPXDecoder::ProcessDrain));
|
mTaskQueue->Dispatch(NewRunnableMethod(this, &VPXDecoder::ProcessDrain));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaResult
|
||||||
|
VPXDecoder::DecodeAlpha(vpx_image_t** aImgAlpha,
|
||||||
|
MediaRawData* aSample)
|
||||||
|
{
|
||||||
|
vpx_codec_err_t r = vpx_codec_decode(&mVPXAlpha,
|
||||||
|
aSample->AlphaData(),
|
||||||
|
aSample->AlphaSize(),
|
||||||
|
nullptr,
|
||||||
|
0);
|
||||||
|
if (r) {
|
||||||
|
LOG("VPX decode alpha error: %s", vpx_codec_err_to_string(r));
|
||||||
|
return MediaResult(
|
||||||
|
NS_ERROR_DOM_MEDIA_DECODE_ERR,
|
||||||
|
RESULT_DETAIL("VPX decode alpha error: %s", vpx_codec_err_to_string(r)));
|
||||||
|
}
|
||||||
|
|
||||||
|
vpx_codec_iter_t iter = nullptr;
|
||||||
|
|
||||||
|
*aImgAlpha = vpx_codec_get_frame(&mVPXAlpha, &iter);
|
||||||
|
NS_ASSERTION((*aImgAlpha)->fmt == VPX_IMG_FMT_I420 ||
|
||||||
|
(*aImgAlpha)->fmt == VPX_IMG_FMT_I444,
|
||||||
|
"WebM image format not I420 or I444");
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
bool
|
bool
|
||||||
VPXDecoder::IsVPX(const nsACString& aMimeType, uint8_t aCodecMask)
|
VPXDecoder::IsVPX(const nsACString& aMimeType, uint8_t aCodecMask)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ private:
|
||||||
void ProcessDecode(MediaRawData* aSample);
|
void ProcessDecode(MediaRawData* aSample);
|
||||||
MediaResult DoDecode(MediaRawData* aSample);
|
MediaResult DoDecode(MediaRawData* aSample);
|
||||||
void ProcessDrain();
|
void ProcessDrain();
|
||||||
|
MediaResult DecodeAlpha(vpx_image_t** aImgAlpha,
|
||||||
|
MediaRawData* aSample);
|
||||||
|
|
||||||
const RefPtr<ImageContainer> mImageContainer;
|
const RefPtr<ImageContainer> mImageContainer;
|
||||||
const RefPtr<TaskQueue> mTaskQueue;
|
const RefPtr<TaskQueue> mTaskQueue;
|
||||||
|
|
@ -66,6 +68,9 @@ private:
|
||||||
// VPx decoder state
|
// VPx decoder state
|
||||||
vpx_codec_ctx_t mVPX;
|
vpx_codec_ctx_t mVPX;
|
||||||
|
|
||||||
|
// VPx alpha decoder state
|
||||||
|
vpx_codec_ctx_t mVPXAlpha;
|
||||||
|
|
||||||
const VideoInfo& mInfo;
|
const VideoInfo& mInfo;
|
||||||
|
|
||||||
const Codec mCodec;
|
const Codec mCodec;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,13 @@ public:
|
||||||
already_AddRefed<MediaDataDecoder>
|
already_AddRefed<MediaDataDecoder>
|
||||||
CreateVideoDecoder(const CreateDecoderParams& aParams) override
|
CreateVideoDecoder(const CreateDecoderParams& aParams) override
|
||||||
{
|
{
|
||||||
|
// Temporary - forces use of VPXDecoder when alpha is present.
|
||||||
|
// Bug 1263836 will handle alpha scenario once implemented. It will shift
|
||||||
|
// the check for alpha to PDMFactory but not itself remove the need for a
|
||||||
|
// check.
|
||||||
|
if (aParams.VideoConfig().HasAlpha()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
RefPtr<MediaDataDecoder> decoder =
|
RefPtr<MediaDataDecoder> decoder =
|
||||||
new FFmpegVideoDecoder<V>(mLib,
|
new FFmpegVideoDecoder<V>(mLib,
|
||||||
aParams.mTaskQueue,
|
aParams.mTaskQueue,
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,14 @@ WMFDecoderModule::Startup()
|
||||||
already_AddRefed<MediaDataDecoder>
|
already_AddRefed<MediaDataDecoder>
|
||||||
WMFDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
|
WMFDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
|
||||||
{
|
{
|
||||||
|
// Temporary - forces use of VPXDecoder when alpha is present.
|
||||||
|
// Bug 1263836 will handle alpha scenario once implemented. It will shift
|
||||||
|
// the check for alpha to PDMFactory but not itself remove the need for a
|
||||||
|
// check.
|
||||||
|
if (aParams.VideoConfig().HasAlpha()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsAutoPtr<WMFVideoMFTManager> manager(
|
nsAutoPtr<WMFVideoMFTManager> manager(
|
||||||
new WMFVideoMFTManager(aParams.VideoConfig(),
|
new WMFVideoMFTManager(aParams.VideoConfig(),
|
||||||
aParams.mKnowsCompositor,
|
aParams.mKnowsCompositor,
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,7 @@ WebMDemuxer::ReadMetadata()
|
||||||
mInfo.mVideo.mDisplay = displaySize;
|
mInfo.mVideo.mDisplay = displaySize;
|
||||||
mInfo.mVideo.mImage = frameSize;
|
mInfo.mVideo.mImage = frameSize;
|
||||||
mInfo.mVideo.SetImageRect(pictureRect);
|
mInfo.mVideo.SetImageRect(pictureRect);
|
||||||
|
mInfo.mVideo.SetAlpha(params.alpha_mode);
|
||||||
|
|
||||||
switch (params.stereo_mode) {
|
switch (params.stereo_mode) {
|
||||||
case NESTEGG_VIDEO_MONO:
|
case NESTEGG_VIDEO_MONO:
|
||||||
|
|
@ -656,6 +657,21 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
|
||||||
WEBM_DEBUG("nestegg_packet_data failed r=%d", r);
|
WEBM_DEBUG("nestegg_packet_data failed r=%d", r);
|
||||||
return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
|
return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
|
||||||
}
|
}
|
||||||
|
unsigned char* alphaData;
|
||||||
|
size_t alphaLength = 0;
|
||||||
|
// Check packets for alpha information if file has declared alpha frames
|
||||||
|
// may be present.
|
||||||
|
if (mInfo.mVideo.HasAlpha()) {
|
||||||
|
r = nestegg_packet_additional_data(holder->Packet(),
|
||||||
|
1,
|
||||||
|
&alphaData,
|
||||||
|
&alphaLength);
|
||||||
|
if (r == -1) {
|
||||||
|
WEBM_DEBUG(
|
||||||
|
"nestegg_packet_additional_data failed to retrieve alpha data r=%d",
|
||||||
|
r);
|
||||||
|
}
|
||||||
|
}
|
||||||
bool isKeyframe = false;
|
bool isKeyframe = false;
|
||||||
if (aType == TrackInfo::kAudioTrack) {
|
if (aType == TrackInfo::kAudioTrack) {
|
||||||
isKeyframe = true;
|
isKeyframe = true;
|
||||||
|
|
@ -713,10 +729,19 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
|
||||||
|
|
||||||
WEBM_DEBUG("push sample tstamp: %ld next_tstamp: %ld length: %ld kf: %d",
|
WEBM_DEBUG("push sample tstamp: %ld next_tstamp: %ld length: %ld kf: %d",
|
||||||
tstamp, next_tstamp, length, isKeyframe);
|
tstamp, next_tstamp, length, isKeyframe);
|
||||||
RefPtr<MediaRawData> sample = new MediaRawData(data, length);
|
RefPtr<MediaRawData> sample;
|
||||||
if (length && !sample->Data()) {
|
if (mInfo.mVideo.HasAlpha() && alphaLength != 0) {
|
||||||
// OOM.
|
sample = new MediaRawData(data, length, alphaData, alphaLength);
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
if (length && !sample->Data() || (alphaLength && !sample->AlphaData())) {
|
||||||
|
// OOM.
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sample = new MediaRawData(data, length);
|
||||||
|
if (length && !sample->Data()) {
|
||||||
|
// OOM.
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sample->mTimecode = tstamp;
|
sample->mTimecode = tstamp;
|
||||||
sample->mTime = tstamp;
|
sample->mTime = tstamp;
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,7 @@ interface Crypto {
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
ArrayBufferView getRandomValues(ArrayBufferView array);
|
ArrayBufferView getRandomValues(ArrayBufferView array);
|
||||||
|
|
||||||
|
[SecureContext]
|
||||||
|
DOMString randomUUID();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@ private:
|
||||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||||
{
|
{
|
||||||
nsresult rv = mWrappedRunnable->Run();
|
nsresult rv = mWrappedRunnable->Run();
|
||||||
|
mWrappedRunnable = nullptr;
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
if (!JS_IsExceptionPending(aCx)) {
|
if (!JS_IsExceptionPending(aCx)) {
|
||||||
Throw(aCx, rv);
|
Throw(aCx, rv);
|
||||||
|
|
@ -259,6 +260,7 @@ private:
|
||||||
MOZ_ASSERT(cancelable); // We checked this earlier!
|
MOZ_ASSERT(cancelable); // We checked this earlier!
|
||||||
rv = cancelable->Cancel();
|
rv = cancelable->Cancel();
|
||||||
nsresult rv2 = WorkerRunnable::Cancel();
|
nsresult rv2 = WorkerRunnable::Cancel();
|
||||||
|
mWrappedRunnable = nullptr;
|
||||||
return NS_FAILED(rv) ? rv : rv2;
|
return NS_FAILED(rv) ? rv : rv2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,32 @@ SharedRGBImage::GetTextureClient(KnowsCompositor* aForwarder)
|
||||||
already_AddRefed<gfx::SourceSurface>
|
already_AddRefed<gfx::SourceSurface>
|
||||||
SharedRGBImage::GetAsSourceSurface()
|
SharedRGBImage::GetAsSourceSurface()
|
||||||
{
|
{
|
||||||
return nullptr;
|
NS_ASSERTION(NS_IsMainThread(), "Must be main thread");
|
||||||
|
|
||||||
|
if (mSourceSurface) {
|
||||||
|
RefPtr<gfx::SourceSurface> surface(mSourceSurface);
|
||||||
|
return surface.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<gfx::SourceSurface> surface;
|
||||||
|
{
|
||||||
|
// We are 'borrowing' the DrawTarget and retaining a permanent reference to
|
||||||
|
// the underlying data (via the surface). It is in this instance since we
|
||||||
|
// know that the TextureClient is always wrapping a BufferTextureData and
|
||||||
|
// therefore it won't go away underneath us.
|
||||||
|
BufferTextureData* decoded_buffer =
|
||||||
|
mTextureClient->GetInternalData()->AsBufferTextureData();
|
||||||
|
RefPtr<gfx::DrawTarget> drawTarget = decoded_buffer->BorrowDrawTarget();
|
||||||
|
|
||||||
|
if (!drawTarget) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface = drawTarget->Snapshot();
|
||||||
|
}
|
||||||
|
|
||||||
|
mSourceSurface = surface;
|
||||||
|
return surface.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ private:
|
||||||
gfx::IntSize mSize;
|
gfx::IntSize mSize;
|
||||||
RefPtr<ImageClient> mCompositable;
|
RefPtr<ImageClient> mCompositable;
|
||||||
RefPtr<TextureClient> mTextureClient;
|
RefPtr<TextureClient> mTextureClient;
|
||||||
|
nsCountedRef<nsMainThreadSourceSurfaceRef> mSourceSurface;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|
|
||||||
|
|
@ -601,6 +601,7 @@ private:
|
||||||
DECL_GFX_PREF(Live, "webgl.lose-context-on-memory-pressure", WebGLLoseContextOnMemoryPressure, bool, false);
|
DECL_GFX_PREF(Live, "webgl.lose-context-on-memory-pressure", WebGLLoseContextOnMemoryPressure, bool, false);
|
||||||
DECL_GFX_PREF(Live, "webgl.max-warnings-per-context", WebGLMaxWarningsPerContext, uint32_t, 32);
|
DECL_GFX_PREF(Live, "webgl.max-warnings-per-context", WebGLMaxWarningsPerContext, uint32_t, 32);
|
||||||
DECL_GFX_PREF(Live, "webgl.max-size-per-texture-mb", WebGLMaxSizePerTextureMB, uint32_t, 1024);
|
DECL_GFX_PREF(Live, "webgl.max-size-per-texture-mb", WebGLMaxSizePerTextureMB, uint32_t, 1024);
|
||||||
|
DECL_GFX_PREF(Live, "webgl.max-vert-ids-per-draw", WebglMaxVertIDsPerDraw, uint32_t, 30*1000*1000);
|
||||||
DECL_GFX_PREF(Live, "webgl.min_capability_mode", WebGLMinCapabilityMode, bool, false);
|
DECL_GFX_PREF(Live, "webgl.min_capability_mode", WebGLMinCapabilityMode, bool, false);
|
||||||
DECL_GFX_PREF(Live, "webgl.msaa-force", WebGLForceMSAA, bool, false);
|
DECL_GFX_PREF(Live, "webgl.msaa-force", WebGLForceMSAA, bool, false);
|
||||||
DECL_GFX_PREF(Live, "webgl.prefer-16bpp", WebGLPrefer16bpp, bool, false);
|
DECL_GFX_PREF(Live, "webgl.prefer-16bpp", WebGLPrefer16bpp, bool, false);
|
||||||
|
|
|
||||||
|
|
@ -155,5 +155,26 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConvertYCbCrAToARGB(const uint8_t* aSrcY,
|
||||||
|
const uint8_t* aSrcU,
|
||||||
|
const uint8_t* aSrcV,
|
||||||
|
const uint8_t* aSrcA,
|
||||||
|
int aSrcStrideYA, int aSrcStrideUV,
|
||||||
|
uint8_t* aDstARGB, int aDstStrideARGB,
|
||||||
|
int aWidth, int aHeight) {
|
||||||
|
|
||||||
|
ConvertYCbCrAToARGB32(aSrcY,
|
||||||
|
aSrcU,
|
||||||
|
aSrcV,
|
||||||
|
aSrcA,
|
||||||
|
aDstARGB,
|
||||||
|
aWidth,
|
||||||
|
aHeight,
|
||||||
|
aSrcStrideYA,
|
||||||
|
aSrcStrideUV,
|
||||||
|
aDstStrideARGB);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,17 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
|
||||||
unsigned char* aDestBuffer,
|
unsigned char* aDestBuffer,
|
||||||
int32_t aStride);
|
int32_t aStride);
|
||||||
|
|
||||||
|
// Currently this function only has support for I420 type.
|
||||||
|
void
|
||||||
|
ConvertYCbCrAToARGB(const uint8_t* aSrcY,
|
||||||
|
const uint8_t* aSrcU,
|
||||||
|
const uint8_t* aSrcV,
|
||||||
|
const uint8_t* aSrcA,
|
||||||
|
int aSrcStrideYA, int aSrcStrideUV,
|
||||||
|
uint8_t* aDstARGB, int aDstStrideARGB,
|
||||||
|
int aWidth, int aHeight);
|
||||||
|
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,27 @@ void ScaleYCbCrToRGB32_deprecated(const uint8_t* y_buf,
|
||||||
if (has_mmx)
|
if (has_mmx)
|
||||||
EMMS();
|
EMMS();
|
||||||
}
|
}
|
||||||
|
void ConvertYCbCrAToARGB32(const uint8_t* y_buf,
|
||||||
|
const uint8_t* u_buf,
|
||||||
|
const uint8_t* v_buf,
|
||||||
|
const uint8_t* a_buf,
|
||||||
|
uint8_t* argb_buf,
|
||||||
|
int pic_width,
|
||||||
|
int pic_height,
|
||||||
|
int ya_pitch,
|
||||||
|
int uv_pitch,
|
||||||
|
int argb_pitch) {
|
||||||
|
|
||||||
|
// The downstream graphics stack expects an attenuated input, hence why the
|
||||||
|
// attenuation parameter is set.
|
||||||
|
DebugOnly<int> err = libyuv::I420AlphaToARGB(y_buf, ya_pitch,
|
||||||
|
u_buf, uv_pitch,
|
||||||
|
v_buf, uv_pitch,
|
||||||
|
a_buf, ya_pitch,
|
||||||
|
argb_buf, argb_pitch,
|
||||||
|
pic_width, pic_height, 1);
|
||||||
|
MOZ_ASSERT(!err);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,18 @@ void ScaleYCbCrToRGB32_deprecated(const uint8_t* yplane,
|
||||||
Rotate view_rotate,
|
Rotate view_rotate,
|
||||||
ScaleFilter filter);
|
ScaleFilter filter);
|
||||||
|
|
||||||
|
void ConvertYCbCrAToARGB32(const uint8_t* yplane,
|
||||||
|
const uint8_t* uplane,
|
||||||
|
const uint8_t* vplane,
|
||||||
|
const uint8_t* aplane,
|
||||||
|
uint8_t* argbframe,
|
||||||
|
int pic_width,
|
||||||
|
int pic_height,
|
||||||
|
int yastride,
|
||||||
|
int uvstride,
|
||||||
|
int argbstride);
|
||||||
|
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ nestegg_duration
|
||||||
nestegg_free_packet
|
nestegg_free_packet
|
||||||
nestegg_init
|
nestegg_init
|
||||||
nestegg_offset_seek
|
nestegg_offset_seek
|
||||||
|
nestegg_packet_additional_data
|
||||||
nestegg_packet_count
|
nestegg_packet_count
|
||||||
nestegg_packet_discard_padding
|
nestegg_packet_discard_padding
|
||||||
nestegg_packet_data
|
nestegg_packet_data
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ random == poster-12.html poster-ref-blue140x100.html
|
||||||
== poster-13.html poster-ref-blue400x300.html
|
== poster-13.html poster-ref-blue400x300.html
|
||||||
== poster-15.html poster-ref-green70x30.html
|
== poster-15.html poster-ref-green70x30.html
|
||||||
random-if(winWidget) random-if(cocoaWidget) == bug686957.html bug686957-ref.html # bug 922951 for OS X
|
random-if(winWidget) random-if(cocoaWidget) == bug686957.html bug686957-ref.html # bug 922951 for OS X
|
||||||
|
== webm-alpha.html webm-alpha-ref.html
|
||||||
|
|
||||||
# Tests for <video src> with 'object-fit' & 'object-position':
|
# Tests for <video src> with 'object-fit' & 'object-position':
|
||||||
# These tests should be very similar to tests in our w3c-css/submitted/images3
|
# These tests should be very similar to tests in our w3c-css/submitted/images3
|
||||||
|
|
|
||||||
5
layout/reftests/webm-video/webm-alpha-ref.html
Normal file
5
layout/reftests/webm-video/webm-alpha-ref.html
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<body style="background:black;">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
10
layout/reftests/webm-video/webm-alpha.html
Normal file
10
layout/reftests/webm-video/webm-alpha.html
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<body style="background:black;">
|
||||||
|
<!--
|
||||||
|
Test that if a WebM video has an alpha channel, it is displayed correctly.
|
||||||
|
-->
|
||||||
|
<video src="webm-alpha.webm">
|
||||||
|
</video>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
layout/reftests/webm-video/webm-alpha.webm
Normal file
BIN
layout/reftests/webm-video/webm-alpha.webm
Normal file
Binary file not shown.
|
|
@ -513,10 +513,16 @@ WebrtcGmpVideoEncoder::Terminated()
|
||||||
{
|
{
|
||||||
LOGD(("GMP Encoder Terminated: %p", (void *)this));
|
LOGD(("GMP Encoder Terminated: %p", (void *)this));
|
||||||
|
|
||||||
mGMP->Close();
|
GMPVideoEncoderProxy* gmp(mGMP);
|
||||||
mGMP = nullptr;
|
mGMP = nullptr;
|
||||||
mHost = nullptr;
|
mHost = nullptr;
|
||||||
mInitting = false;
|
mInitting = false;
|
||||||
|
|
||||||
|
if (gmp) {
|
||||||
|
// Do this last, since this could cause us to be destroyed
|
||||||
|
gmp->Close();
|
||||||
|
}
|
||||||
|
|
||||||
// Could now notify that it's dead
|
// Could now notify that it's dead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4320,6 +4320,7 @@ pref("webgl.can-lose-context-in-foreground", true);
|
||||||
pref("webgl.restore-context-when-visible", true);
|
pref("webgl.restore-context-when-visible", true);
|
||||||
pref("webgl.max-warnings-per-context", 32);
|
pref("webgl.max-warnings-per-context", 32);
|
||||||
pref("webgl.max-size-per-texture-mb", 1024);
|
pref("webgl.max-size-per-texture-mb", 1024);
|
||||||
|
pref("webgl.max-vert-ids-per-draw", 30000000);
|
||||||
pref("webgl.enable-draft-extensions", false);
|
pref("webgl.enable-draft-extensions", false);
|
||||||
pref("webgl.enable-privileged-extensions", false);
|
pref("webgl.enable-privileged-extensions", false);
|
||||||
pref("webgl.bypass-shader-validation", false);
|
pref("webgl.bypass-shader-validation", false);
|
||||||
|
|
|
||||||
|
|
@ -3329,7 +3329,8 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI,
|
||||||
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
|
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
|
||||||
0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||||
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
|
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
|
||||||
0x1F, /* 0x20, */ 0x00 };
|
0x1F, /* 0x20, */ 0x3B, 0x3D, 0x7F,
|
||||||
|
0x00 };
|
||||||
if (cookieAttributes.name.FindCharInSet(illegalNameCharacters, 0) != -1) {
|
if (cookieAttributes.name.FindCharInSet(illegalNameCharacters, 0) != -1) {
|
||||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "invalid name character");
|
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "invalid name character");
|
||||||
return newCookie;
|
return newCookie;
|
||||||
|
|
|
||||||
|
|
@ -695,7 +695,10 @@ nsresult nsView::AttachToTopLevelWidget(nsIWidget* aWidget)
|
||||||
mWindow = aWidget;
|
mWindow = aWidget;
|
||||||
|
|
||||||
mWindow->SetAttachedWidgetListener(this);
|
mWindow->SetAttachedWidgetListener(this);
|
||||||
mWindow->EnableDragDrop(true);
|
if (mWindow->WindowType() != eWindowType_invisible) {
|
||||||
|
nsresult rv = mWindow->AsyncEnableDragDrop(true);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
mWidgetIsTopLevel = true;
|
mWidgetIsTopLevel = true;
|
||||||
|
|
||||||
// Refresh the view bounds
|
// Refresh the view bounds
|
||||||
|
|
|
||||||
|
|
@ -2133,6 +2133,16 @@ nsBaseWidget::UpdateSynthesizedTouchState(MultiTouchInput* aState,
|
||||||
return inputToDispatch;
|
return inputToDispatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsBaseWidget::AsyncEnableDragDrop(bool aEnable)
|
||||||
|
{
|
||||||
|
RefPtr<nsBaseWidget> kungFuDeathGrip = this;
|
||||||
|
return NS_IdleDispatchToCurrentThread(
|
||||||
|
NS_NewRunnableFunction([this, aEnable, kungFuDeathGrip]() {
|
||||||
|
EnableDragDrop(aEnable);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsBaseWidget::RegisterPluginWindowForRemoteUpdates()
|
nsBaseWidget::RegisterPluginWindowForRemoteUpdates()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ public:
|
||||||
NS_IMETHOD SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
|
NS_IMETHOD SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
|
||||||
virtual LayoutDeviceIntPoint GetClientOffset() override;
|
virtual LayoutDeviceIntPoint GetClientOffset() override;
|
||||||
virtual void EnableDragDrop(bool aEnable) override {};
|
virtual void EnableDragDrop(bool aEnable) override {};
|
||||||
|
virtual nsresult AsyncEnableDragDrop(bool aEnable) override;
|
||||||
NS_IMETHOD GetAttention(int32_t aCycleCount) override;
|
NS_IMETHOD GetAttention(int32_t aCycleCount) override;
|
||||||
virtual bool HasPendingInputEvent() override;
|
virtual bool HasPendingInputEvent() override;
|
||||||
NS_IMETHOD SetIcon(const nsAString &anIconSpec) override;
|
NS_IMETHOD SetIcon(const nsAString &anIconSpec) override;
|
||||||
|
|
|
||||||
|
|
@ -1378,6 +1378,7 @@ class nsIWidget : public nsISupports
|
||||||
* Enables the dropping of files to a widget.
|
* Enables the dropping of files to a widget.
|
||||||
*/
|
*/
|
||||||
virtual void EnableDragDrop(bool aEnable) = 0;
|
virtual void EnableDragDrop(bool aEnable) = 0;
|
||||||
|
virtual nsresult AsyncEnableDragDrop(bool aEnable) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables/Disables system mouse capture.
|
* Enables/Disables system mouse capture.
|
||||||
|
|
|
||||||
|
|
@ -3734,22 +3734,21 @@ nsWindow::ClientToWindowSize(const LayoutDeviceIntSize& aClientSize)
|
||||||
void
|
void
|
||||||
nsWindow::EnableDragDrop(bool aEnable)
|
nsWindow::EnableDragDrop(bool aEnable)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mWnd, "nsWindow::EnableDragDrop() called after Destroy()");
|
if (!mWnd) {
|
||||||
|
// Return early if the window already closed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = NS_ERROR_FAILURE;
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
if (aEnable) {
|
if (aEnable) {
|
||||||
if (!mNativeDragTarget) {
|
if (!mNativeDragTarget) {
|
||||||
mNativeDragTarget = new nsNativeDragTarget(this);
|
mNativeDragTarget = new nsNativeDragTarget(this);
|
||||||
mNativeDragTarget->AddRef();
|
mNativeDragTarget->AddRef();
|
||||||
if (SUCCEEDED(::CoLockObjectExternal((LPUNKNOWN)mNativeDragTarget,
|
::RegisterDragDrop(mWnd, (LPDROPTARGET)mNativeDragTarget);
|
||||||
TRUE, FALSE))) {
|
|
||||||
::RegisterDragDrop(mWnd, (LPDROPTARGET)mNativeDragTarget);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mWnd && mNativeDragTarget) {
|
if (mWnd && mNativeDragTarget) {
|
||||||
::RevokeDragDrop(mWnd);
|
::RevokeDragDrop(mWnd);
|
||||||
::CoLockObjectExternal((LPUNKNOWN)mNativeDragTarget, FALSE, TRUE);
|
|
||||||
mNativeDragTarget->DragCancel();
|
mNativeDragTarget->DragCancel();
|
||||||
NS_RELEASE(mNativeDragTarget);
|
NS_RELEASE(mNativeDragTarget);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3020,6 +3020,8 @@ nsLocalFile::IsExecutable(bool* aResult)
|
||||||
"air", // Adobe AIR installer
|
"air", // Adobe AIR installer
|
||||||
"app", // executable application
|
"app", // executable application
|
||||||
"application", // from bug 348763
|
"application", // from bug 348763
|
||||||
|
"appx",
|
||||||
|
"appxbundle",
|
||||||
"asp",
|
"asp",
|
||||||
"bas",
|
"bas",
|
||||||
"bat",
|
"bat",
|
||||||
|
|
@ -3062,6 +3064,8 @@ nsLocalFile::IsExecutable(bool* aResult)
|
||||||
"msh", // Microsoft Shell
|
"msh", // Microsoft Shell
|
||||||
"mshxml", // Microsoft Shell
|
"mshxml", // Microsoft Shell
|
||||||
"msi",
|
"msi",
|
||||||
|
"msix",
|
||||||
|
"msixbundle",
|
||||||
"msp",
|
"msp",
|
||||||
"mst",
|
"mst",
|
||||||
"ops", // Office Profile Settings
|
"ops", // Office Profile Settings
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue