Bug 1261007: part1: Force to send video sample into encoder if we got the same video sample more than 1 seconds. Enable testcases. r=jolin
MozReview-Commit-ID: GXFZVqDUChM
--- a/dom/media/encoder/TrackEncoder.cpp
+++ b/dom/media/encoder/TrackEncoder.cpp
@@ -245,32 +245,36 @@ VideoTrackEncoder::AppendVideoSegment(co
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// Append all video segments from MediaStreamGraph, including null an
// non-null frames.
VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(aSegment));
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
mTotalFrameDuration += chunk.GetDuration();
- // Send only the unique video frames for encoding
- if (mLastFrame != chunk.mFrame) {
+ mLastFrameDuration += chunk.GetDuration();
+ // Send only the unique video frames for encoding.
+ // Or if we got the same video chunks more than 1 seconds,
+ // force to send into encoder.
+ if ((mLastFrame != chunk.mFrame) ||
+ (mLastFrameDuration >= mTrackRate)) {
RefPtr<layers::Image> image = chunk.mFrame.GetImage();
// Because we may get chunks with a null image (due to input blocking),
// accumulate duration and give it to the next frame that arrives.
// Canonically incorrect - the duration should go to the previous frame
// - but that would require delaying until the next frame arrives.
// Best would be to do like OMXEncoder and pass an effective timestamp
- // in with each frame (don't zero mTotalFrameDuration)
+ // in with each frame.
if (image) {
mRawSegment.AppendFrame(image.forget(),
- mTotalFrameDuration,
+ mLastFrameDuration,
chunk.mFrame.GetIntrinsicSize(),
PRINCIPAL_HANDLE_NONE,
chunk.mFrame.GetForceBlack());
- mTotalFrameDuration = 0;
+ mLastFrameDuration = 0;
}
}
mLastFrame.TakeFrom(&chunk.mFrame);
iter.Next();
}
if (mRawSegment.GetDuration() > 0) {
mReentrantMonitor.NotifyAll();
--- a/dom/media/encoder/TrackEncoder.h
+++ b/dom/media/encoder/TrackEncoder.h
@@ -256,16 +256,17 @@ public:
VideoTrackEncoder()
: TrackEncoder()
, mFrameWidth(0)
, mFrameHeight(0)
, mDisplayWidth(0)
, mDisplayHeight(0)
, mTrackRate(0)
, mTotalFrameDuration(0)
+ , mLastFrameDuration(0)
, mVideoBitrate(0)
{}
/**
* Notified by the same callback of MediaEncoder when it has received a track
* change from MediaStreamGraph. Called on the MediaStreamGraph thread.
*/
void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
@@ -332,20 +333,21 @@ protected:
/**
* The total duration of frames in encoded video in StreamTime, kept track of
* in subclasses.
*/
StreamTime mTotalFrameDuration;
/**
- * The last unique frame we've sent to track encoder, kept track of in
- * subclasses.
+ * The last unique frame and duration we've sent to track encoder,
+ * kept track of in subclasses.
*/
VideoFrame mLastFrame;
+ StreamTime mLastFrameDuration;
/**
* A segment queue of audio track data, protected by mReentrantMonitor.
*/
VideoSegment mRawSegment;
uint32_t mVideoBitrate;
};
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -697,20 +697,18 @@ tags=msg
tags=msg
[test_mediarecorder_record_audiocontext.html]
tags=msg
[test_mediarecorder_record_audiocontext_mlk.html]
tags=msg
[test_mediarecorder_record_audionode.html]
tags=msg
[test_mediarecorder_record_canvas_captureStream.html]
-skip-if = (android_version < '17' || toolkit == 'android') # Android/Gonk before SDK version 17 does not have the OMX Encoder API and Fennec does not support video recording
tags=msg
[test_mediarecorder_record_changing_video_resolution.html]
-skip-if = android_version < '17' # Android/Gonk before SDK version 17 does not have the OMX Encoder API.
tags=msg
[test_mediarecorder_record_gum_video_timeslice.html]
tags=msg
[test_mediarecorder_record_immediate_stop.html]
tags=msg capturestream
[test_mediarecorder_record_no_timeslice.html]
tags=msg capturestream
[test_mediarecorder_record_session.html]