mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-21 22:57:31 +09:00
Issue #2357 - WebM demuxer can't tell when a video wants to be transparent.
Required to have an alpha channel (which in the strange world of graphics seems to refer to transparency, and not experimental code) in WebM videos. Straight port of Firefox 53 implementation, adapted slightly for a couple of patches previously taken without this. Ref: BZ 1320829
This commit is contained in:
parent
ef54fc458c
commit
71cc0ef940
5 changed files with 66 additions and 6 deletions
|
|
@ -340,6 +340,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 +365,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -622,15 +622,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 +668,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 {
|
||||||
|
|
|
||||||
|
|
@ -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,11 +729,20 @@ 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 (mInfo.mVideo.HasAlpha() && alphaLength != 0) {
|
||||||
|
sample = new MediaRawData(data, length, alphaData, alphaLength);
|
||||||
|
if (length && !sample->Data() || (alphaLength && !sample->AlphaData())) {
|
||||||
|
// OOM.
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sample = new MediaRawData(data, length);
|
||||||
if (length && !sample->Data()) {
|
if (length && !sample->Data()) {
|
||||||
// OOM.
|
// OOM.
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sample->mTimecode = tstamp;
|
sample->mTimecode = tstamp;
|
||||||
sample->mTime = tstamp;
|
sample->mTime = tstamp;
|
||||||
sample->mDuration = next_tstamp - tstamp;
|
sample->mDuration = next_tstamp - tstamp;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue