Bug 1323631 - update original frame timestamp or duration rather than creating shallow copy. r?jwwang
MozReview-Commit-ID: 4oSheJwFNOE
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -172,65 +172,34 @@ VideoData::SizeOfIncludingThis(MallocSiz
const mozilla::layers::PlanarYCbCrImage* img =
static_cast<const mozilla::layers::PlanarYCbCrImage*>(mImage.get());
size += img->SizeOfIncludingThis(aMallocSizeOf);
}
return size;
}
-/* static */
-already_AddRefed<VideoData>
-VideoData::ShallowCopyUpdateDuration(const VideoData* aOther,
- int64_t aDuration)
+void
+VideoData::UpdateDuration(int64_t aDuration)
{
- RefPtr<VideoData> v = new VideoData(aOther->mOffset,
- aOther->mTime,
- aDuration,
- aOther->mKeyframe,
- aOther->mTimecode,
- aOther->mDisplay,
- aOther->mFrameID);
- v->mImage = aOther->mImage;
- return v.forget();
+ MOZ_ASSERT(aDuration >= 0);
+
+ mDuration = aDuration;
}
-/* static */
-already_AddRefed<VideoData>
-VideoData::ShallowCopyUpdateTimestamp(const VideoData* aOther,
- int64_t aTimestamp)
+void
+VideoData::UpdateTimestamp(int64_t aTimestamp)
{
- NS_ENSURE_TRUE(aOther, nullptr);
- RefPtr<VideoData> v = new VideoData(aOther->mOffset,
- aTimestamp,
- aOther->GetEndTime() - aTimestamp,
- aOther->mKeyframe,
- aOther->mTimecode,
- aOther->mDisplay,
- aOther->mFrameID);
- v->mImage = aOther->mImage;
- return v.forget();
-}
+ MOZ_ASSERT(aTimestamp >= 0);
-/* static */
-already_AddRefed<VideoData>
-VideoData::ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther,
- int64_t aTimestamp,
- int64_t aDuration)
-{
- NS_ENSURE_TRUE(aOther, nullptr);
- RefPtr<VideoData> v = new VideoData(aOther->mOffset,
- aTimestamp,
- aDuration,
- aOther->mKeyframe,
- aOther->mTimecode,
- aOther->mDisplay,
- aOther->mFrameID);
- v->mImage = aOther->mImage;
- return v.forget();
+ int64_t updatedDuration = GetEndTime() - aTimestamp;
+ MOZ_ASSERT(updatedDuration >= 0);
+
+ mTime = aTimestamp;
+ mDuration = updatedDuration;
}
/* static */
bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
bool aCopyData)
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -488,39 +488,16 @@ public:
int64_t aOffset,
int64_t aTime,
int64_t aDuration,
const RefPtr<Image>& aImage,
bool aKeyframe,
int64_t aTimecode,
const IntRect& aPicture);
- // Creates a new VideoData identical to aOther, but with a different
- // specified duration. All data from aOther is copied into the new
- // VideoData. The new VideoData's mImage field holds a reference to
- // aOther's mImage, i.e. the Image is not copied. This function is useful
- // in reader backends that can't determine the duration of a VideoData
- // until the next frame is decoded, i.e. it's a way to change the const
- // duration field on a VideoData.
- static already_AddRefed<VideoData> ShallowCopyUpdateDuration(const VideoData* aOther,
- int64_t aDuration);
-
- // Creates a new VideoData identical to aOther, but with a different
- // specified timestamp. All data from aOther is copied into the new
- // VideoData, as ShallowCopyUpdateDuration() does.
- static already_AddRefed<VideoData> ShallowCopyUpdateTimestamp(const VideoData* aOther,
- int64_t aTimestamp);
-
- // Creates a new VideoData identical to aOther, but with a different
- // specified timestamp and duration. All data from aOther is copied
- // into the new VideoData, as ShallowCopyUpdateDuration() does.
- static already_AddRefed<VideoData>
- ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther, int64_t aTimestamp,
- int64_t aDuration);
-
// Initialize PlanarYCbCrImage. Only When aCopyData is true,
// video data is copied to PlanarYCbCrImage.
static bool SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
bool aCopyData);
@@ -543,16 +520,19 @@ public:
int64_t aTimecode,
IntSize aDisplay,
uint32_t aFrameID);
void SetListener(UniquePtr<Listener> aListener);
void MarkSentToCompositor();
bool IsSentToCompositor() { return mSentToCompositor; }
+ void UpdateDuration(int64_t aDuration);
+ void UpdateTimestamp(int64_t aTimestamp);
+
protected:
~VideoData();
bool mSentToCompositor;
UniquePtr<Listener> mListener;
};
class CryptoTrack
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1237,20 +1237,18 @@ private:
// to display this frame after the seek, so discard it.
if (target >= video->GetEndTime()) {
SLOG("DropVideoUpToSeekTarget() pop video frame [%lld, %lld] target=%lld",
video->mTime, video->GetEndTime(), target);
mFirstVideoFrameAfterSeek = video;
} else {
if (target >= video->mTime && video->GetEndTime() >= target) {
// The seek target lies inside this frame's time slice. Adjust the frame's
- // start time to match the seek target. We do this by replacing the
- // first frame with a shallow copy which has the new timestamp.
- RefPtr<VideoData> temp = VideoData::ShallowCopyUpdateTimestamp(video.get(), target);
- video = temp;
+ // start time to match the seek target.
+ video->UpdateTimestamp(target);
}
mFirstVideoFrameAfterSeek = nullptr;
SLOG("DropVideoUpToSeekTarget() found video frame [%lld, %lld] containing target=%lld",
video->mTime, video->GetEndTime(), target);
MOZ_ASSERT(!mSeekedVideoData, "Should be the 1st sample after seeking");
mSeekedVideoData = video;
--- a/dom/media/android/AndroidMediaReader.cpp
+++ b/dom/media/android/AndroidMediaReader.cpp
@@ -136,19 +136,18 @@ bool AndroidMediaReader::DecodeVideoFram
if (!mPlugin->ReadVideo(mPlugin, &frame, mVideoSeekTimeUs, &bufferCallback)) {
// We reached the end of the video stream. If we have a buffered
// video frame, push it the video queue using the total duration
// of the video as the end time.
if (mLastVideoFrame) {
int64_t durationUs;
mPlugin->GetDuration(mPlugin, &durationUs);
durationUs = std::max<int64_t>(durationUs - mLastVideoFrame->mTime, 0);
- RefPtr<VideoData> data = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame,
- durationUs);
- mVideoQueue.Push(data);
+ mLastVideoFrame->UpdateDuration(durationUs);
+ mVideoQueue.Push(mLastVideoFrame);
mLastVideoFrame = nullptr;
}
return false;
}
mVideoSeekTimeUs = -1;
if (aKeyframeSkip) {
// Disable keyframe skipping for now as
@@ -256,17 +255,17 @@ bool AndroidMediaReader::DecodeVideoFram
mLastVideoFrame = v;
continue;
}
// Calculate the duration as the timestamp of the current frame minus the
// timestamp of the previous frame. We can then return the previously
// decoded frame, and it will have a valid timestamp.
int64_t duration = v->mTime - mLastVideoFrame->mTime;
- mLastVideoFrame = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame, duration);
+ mLastVideoFrame->UpdateDuration(duration);
// We have the start time of the next frame, so we can push the previous
// frame into the queue, except if the end time is below the threshold,
// in which case it wouldn't be displayed anyway.
if (mLastVideoFrame->GetEndTime() < aTimeThreshold) {
mLastVideoFrame = nullptr;
continue;
}