Bug 944117 - updated WebM demuxer to surface alpha information. f?jya
MozReview-Commit-ID: 8XQyUs0KXl0
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -388,32 +388,46 @@ MediaRawData::MediaRawData()
MediaRawData::MediaRawData(const uint8_t* aData, size_t aSize)
: MediaData(RAW_DATA, 0)
, mCrypto(mCryptoInternal)
, mBuffer(aData, 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>
MediaRawData::Clone() const
{
RefPtr<MediaRawData> s = new MediaRawData;
s->mTimecode = mTimecode;
s->mTime = mTime;
s->mDuration = mDuration;
s->mOffset = mOffset;
s->mKeyframe = mKeyframe;
s->mExtraData = mExtraData;
s->mCryptoInternal = mCryptoInternal;
s->mTrackInfo = mTrackInfo;
s->mEOS = mEOS;
if (!s->mBuffer.Append(mBuffer.Data(), mBuffer.Length())) {
return nullptr;
}
+ if (!s->mAlphaBuffer.Append(mAlphaBuffer.Data(), mAlphaBuffer.Length())) {
+ return nullptr;
+ }
return s.forget();
}
MediaRawData::~MediaRawData()
{
}
size_t
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -613,24 +613,33 @@ private:
bool EnsureSize(size_t aSize);
MediaRawData* mTarget;
};
class MediaRawData : public MediaData {
public:
MediaRawData();
MediaRawData(const uint8_t* aData, size_t mSize);
+ MediaRawData(const uint8_t* aData,
+ size_t mSize,
+ const uint8_t* aAlphaData,
+ size_t mAlphaSize);
// Pointer to data or null if not-yet allocated
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_t Size() const { return mBuffer.Length(); }
+ size_t AlphaSize() const { return mAlphaBuffer.Length(); }
size_t ComputedSizeOfIncludingThis() const
{
- return sizeof(*this) + mBuffer.ComputedSizeOfExcludingThis();
+ return sizeof(*this)
+ + mBuffer.ComputedSizeOfExcludingThis()
+ + mAlphaBuffer.ComputedSizeOfExcludingThis();
}
const CryptoSample& mCrypto;
RefPtr<MediaByteBuffer> mExtraData;
// Used by the Vorbis decoder and Ogg demuxer.
// Indicates that this is the last packet of the stream.
bool mEOS = false;
@@ -645,16 +654,17 @@ public:
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
protected:
~MediaRawData();
private:
friend class MediaRawDataWriter;
AlignedByteBuffer mBuffer;
+ AlignedByteBuffer mAlphaBuffer;
CryptoSample mCryptoInternal;
MediaRawData(const MediaRawData&); // Not implemented
};
// MediaByteBuffer is a ref counted infallible TArray.
class MediaByteBuffer : public nsTArray<uint8_t> {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaByteBuffer);
MediaByteBuffer() = default;
--- a/dom/media/MediaInfo.h
+++ b/dom/media/MediaInfo.h
@@ -198,28 +198,30 @@ public:
EmptyString(), EmptyString(), true, 2)
, mDisplay(aSize)
, mStereoMode(StereoMode::MONO)
, mImage(aSize)
, mCodecSpecificConfig(new MediaByteBuffer)
, mExtraData(new MediaByteBuffer)
, mRotation(kDegree_0)
, mImageRect(nsIntRect(nsIntPoint(), aSize))
+ , mAlphaPresent(false)
{
}
VideoInfo(const VideoInfo& aOther)
: TrackInfo(aOther)
, mDisplay(aOther.mDisplay)
, mStereoMode(aOther.mStereoMode)
, mImage(aOther.mImage)
, mCodecSpecificConfig(aOther.mCodecSpecificConfig)
, mExtraData(aOther.mExtraData)
, mRotation(aOther.mRotation)
, mImageRect(aOther.mImageRect)
+ , mAlphaPresent(aOther.mAlphaPresent)
{
}
bool IsValid() const override
{
return mDisplay.width > 0 && mDisplay.height > 0;
}
@@ -233,16 +235,26 @@ public:
return this;
}
UniquePtr<TrackInfo> Clone() const override
{
return MakeUnique<VideoInfo>(*this);
}
+ void SetAlpha(bool aAlphaPresent)
+ {
+ mAlphaPresent = aAlphaPresent;
+ }
+
+ bool HasAlpha() const
+ {
+ return mAlphaPresent;
+ }
+
nsIntRect ImageRect() const
{
if (mImageRect.width < 0 || mImageRect.height < 0) {
return nsIntRect(0, 0, mImage.width, mImage.height);
}
return mImageRect;
}
@@ -304,16 +316,19 @@ public:
// Describing how many degrees video frames should be rotated in clock-wise to
// get correct view.
Rotation mRotation;
private:
// mImage may be cropped; currently only used with the WebM container.
// A negative width or height indicate that no cropping is to occur.
nsIntRect mImageRect;
+
+ // Indicates whether or not frames may contain alpha information.
+ bool mAlphaPresent;
};
class AudioInfo : public TrackInfo {
public:
AudioInfo()
: TrackInfo(kAudioTrack, NS_LITERAL_STRING("1"), NS_LITERAL_STRING("main"),
EmptyString(), EmptyString(), true, 1)
, mRate(0)
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -356,16 +356,17 @@ WebMDemuxer::ReadMetadata()
}
mVideoTrack = track;
mHasVideo = true;
mInfo.mVideo.mDisplay = displaySize;
mInfo.mVideo.mImage = frameSize;
mInfo.mVideo.SetImageRect(pictureRect);
+ mInfo.mVideo.SetAlpha(params.alpha_mode);
switch (params.stereo_mode) {
case NESTEGG_VIDEO_MONO:
mInfo.mVideo.mStereoMode = StereoMode::MONO;
break;
case NESTEGG_VIDEO_STEREO_LEFT_RIGHT:
mInfo.mVideo.mStereoMode = StereoMode::LEFT_RIGHT;
break;
@@ -621,16 +622,31 @@ WebMDemuxer::GetNextPacket(TrackInfo::Tr
for (uint32_t i = 0; i < count; ++i) {
unsigned char* data;
size_t length;
r = nestegg_packet_data(holder->Packet(), i, &data, &length);
if (r == -1) {
WEBM_DEBUG("nestegg_packet_data failed r=%d", r);
return false;
}
+ 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;
if (aType == TrackInfo::kAudioTrack) {
isKeyframe = true;
} else if (aType == TrackInfo::kVideoTrack) {
if (packetEncryption == NESTEGG_PACKET_HAS_SIGNAL_BYTE_ENCRYPTED) {
// Packet is encrypted, can't peek, use packet info
isKeyframe = nestegg_packet_has_keyframe(holder->Packet()) == NESTEGG_PACKET_HAS_KEYFRAME_TRUE;
} else {
@@ -658,17 +674,22 @@ WebMDemuxer::GetNextPacket(TrackInfo::Tr
mLastSeenFrameWidth = Some(si.w);
mLastSeenFrameHeight = Some(si.h);
}
}
}
WEBM_DEBUG("push sample tstamp: %ld next_tstamp: %ld length: %ld kf: %d",
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);
+ } else {
+ sample = new MediaRawData(data, length);
+ }
sample->mTimecode = tstamp;
sample->mTime = tstamp;
sample->mDuration = next_tstamp - tstamp;
sample->mOffset = holder->Offset();
sample->mKeyframe = isKeyframe;
if (discardPadding && i == count - 1) {
uint8_t c[8];
BigEndian::writeInt64(&c[0], discardPadding);