diff options
author | mcasas <mcasas@chromium.org> | 2015-10-26 19:36:05 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-27 02:37:22 +0000 |
commit | d718fafe1a14502a17a477d32df035acb07beeb5 (patch) | |
tree | b97454ac20400ebfc084a10165310c0d3d45bc1f /content | |
parent | a1cba16e4d9de5ba97b988e79899bb6d03cd2bdb (diff) | |
download | chromium_src-d718fafe1a14502a17a477d32df035acb07beeb5.zip chromium_src-d718fafe1a14502a17a477d32df035acb07beeb5.tar.gz chromium_src-d718fafe1a14502a17a477d32df035acb07beeb5.tar.bz2 |
MediaStreamRecorder: implement requestData() and start(timeslice)
This CL implements requestData() [1] and a fast LayoutTest.
requestData() forces sending the gathered data so-far to JS.
Until now there's no buffering, so this part just resends the
last gathered Blob, so there will be more patches dealing
with the behaviour for buffered MSRs.
This CL also implements the start(timeslice) [2], essentially
Chrome uses the |lastInSlice| parameter to instruct Blink to
finish buffering data and send to JS.
[1] http://w3c.github.io/mediacapture-record/MediaRecorder.html#widl-MediaRecorder-requestData-void
[2] http://w3c.github.io/mediacapture-record/MediaRecorder.html#widl-MediaRecorder-start-void-long-timeslice
BUG=543838, 543828
TBR=dalecurtis@chromium.org for media/capture/webm_muxer.cc
where I indented one line (no need for review, no new code).
Review URL: https://codereview.chromium.org/1420133003
Cr-Commit-Position: refs/heads/master@{#356207}
Diffstat (limited to 'content')
-rw-r--r-- | content/renderer/media/media_recorder_handler.cc | 39 | ||||
-rw-r--r-- | content/renderer/media/media_recorder_handler.h | 6 | ||||
-rw-r--r-- | content/renderer/media/media_recorder_handler_unittest.cc | 8 |
3 files changed, 41 insertions, 12 deletions
diff --git a/content/renderer/media/media_recorder_handler.cc b/content/renderer/media/media_recorder_handler.cc index 8029dea..e5c8ccf 100644 --- a/content/renderer/media/media_recorder_handler.cc +++ b/content/renderer/media/media_recorder_handler.cc @@ -15,10 +15,16 @@ #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" #include "third_party/WebKit/public/platform/WebString.h" +using base::TimeDelta; +using base::TimeTicks; + namespace content { MediaRecorderHandler::MediaRecorderHandler() - : recording_(false), client_(nullptr), weak_factory_(this) { + : use_vp9_(false), + recording_(false), + client_(nullptr), + weak_factory_(this) { DVLOG(3) << __FUNCTION__; } @@ -69,6 +75,10 @@ bool MediaRecorderHandler::start(int timeslice) { DCHECK(!recording_); DCHECK(!media_stream_.isNull()); DCHECK(!webm_muxer_); + DCHECK(timeslice_.is_zero()); + + timeslice_ = TimeDelta::FromMilliseconds(timeslice); + slice_origin_timestamp_ = TimeTicks::Now(); webm_muxer_.reset( new media::WebmMuxer(use_vp9_ ? media::kCodecVP9 : media::kCodecVP8, @@ -110,6 +120,7 @@ void MediaRecorderHandler::stop() { DCHECK(recording_); recording_ = false; + timeslice_ = TimeDelta::FromMilliseconds(0); video_recorders_.clear(); webm_muxer_.reset(); } @@ -133,23 +144,35 @@ void MediaRecorderHandler::resume() { void MediaRecorderHandler::OnEncodedVideo( const scoped_refptr<media::VideoFrame>& video_frame, scoped_ptr<std::string> encoded_data, - base::TimeTicks timestamp, + TimeTicks timestamp, bool is_key_frame) { DCHECK(main_render_thread_checker_.CalledOnValidThread()); - if (webm_muxer_) { - webm_muxer_->OnEncodedVideo(video_frame, encoded_data.Pass(), timestamp, - is_key_frame); - } + if (!webm_muxer_) + return; + webm_muxer_->OnEncodedVideo(video_frame, encoded_data.Pass(), timestamp, + is_key_frame); } void MediaRecorderHandler::WriteData(base::StringPiece data) { DCHECK(main_render_thread_checker_.CalledOnValidThread()); - client_->writeData(data.data(), data.length(), false /* lastInSlice */); + + // Non-buffered mode does not need to check timestamps. + if (timeslice_.is_zero()) { + client_->writeData(data.data(), data.length(), true /* lastInSlice */); + return; + } + + const TimeTicks now = TimeTicks::Now(); + const bool last_in_slice = now > slice_origin_timestamp_ + timeslice_; + DVLOG_IF(1, last_in_slice) << "Slice finished @ " << now; + if (last_in_slice) + slice_origin_timestamp_ = now; + client_->writeData(data.data(), data.length(), last_in_slice); } void MediaRecorderHandler::OnVideoFrameForTesting( const scoped_refptr<media::VideoFrame>& frame, - const base::TimeTicks& timestamp) { + const TimeTicks& timestamp) { for (auto* recorder : video_recorders_) recorder->OnVideoFrameForTesting(frame, timestamp); } diff --git a/content/renderer/media/media_recorder_handler.h b/content/renderer/media/media_recorder_handler.h index 4d1e519..8d9d7ee 100644 --- a/content/renderer/media/media_recorder_handler.h +++ b/content/renderer/media/media_recorder_handler.h @@ -73,6 +73,12 @@ class CONTENT_EXPORT MediaRecorderHandler final // Force using VP9 for video encoding, otherwise VP8 will be used by default. bool use_vp9_; + // |client_| has no notion of time, thus may configure us via start(timeslice) + // to notify it after a certain |timeslice_| has passed. We use a moving + // |slice_origin_timestamp_| to track those time chunks. + base::TimeDelta timeslice_; + base::TimeTicks slice_origin_timestamp_; + bool recording_; blink::WebMediaStream media_stream_; // The MediaStream being recorded. diff --git a/content/renderer/media/media_recorder_handler_unittest.cc b/content/renderer/media/media_recorder_handler_unittest.cc index b3ac9d1..208542f 100644 --- a/content/renderer/media/media_recorder_handler_unittest.cc +++ b/content/renderer/media/media_recorder_handler_unittest.cc @@ -142,9 +142,9 @@ TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) { // writeData() is pinged a number of times as the WebM header is written; // the last time it is called it has the encoded data. const size_t encoded_data_size = GetParam().first_encoded_frame_size; - EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), false)) + EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _)) .Times(AtLeast(1)); - EXPECT_CALL(*this, writeData(_, encoded_data_size, false)) + EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) .Times(1) .WillOnce(RunClosure(quit_closure)); @@ -158,9 +158,9 @@ TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) { // The second time around writeData() is called a number of times to write // the WebM frame header, and then is pinged with the encoded data. const size_t encoded_data_size = GetParam().second_encoded_frame_size; - EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), false)) + EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _)) .Times(AtLeast(1)); - EXPECT_CALL(*this, writeData(_, encoded_data_size, false)) + EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) .Times(1) .WillOnce(RunClosure(quit_closure)); |