Index: content/renderer/media/media_recorder_handler.cc |
diff --git a/content/renderer/media/media_recorder_handler.cc b/content/renderer/media/media_recorder_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e592d8cc97172188b6f27b7f4a1af9d79d6847cc |
--- /dev/null |
+++ b/content/renderer/media/media_recorder_handler.cc |
@@ -0,0 +1,132 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/renderer/media/media_recorder_handler.h" |
+ |
+#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/logging.h" |
+#include "content/renderer/media/video_track_recorder.h" |
+#include "media/base/bind_to_current_loop.h" |
+#include "media/capture/webm_muxer.h" |
+#include "third_party/WebKit/public/platform/WebString.h" |
+ |
+namespace content { |
+ |
+MediaRecorderHandler::MediaRecorderHandler() |
+ : recording_(false), client_(nullptr), weak_factory_(this) { |
+ DVLOG(3) << __FUNCTION__; |
+} |
+ |
+MediaRecorderHandler::~MediaRecorderHandler() { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ // Send a |last_in_slice| to our |client_|. |
+ if (client_) |
+ client_->writeData(nullptr, 0u, true); |
+} |
+ |
+bool MediaRecorderHandler::canSupportMimeType( |
+ const blink::WebString& mimeType) { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ // TODO(mcasas): For the time being only "video/vp8" is supported. |
+ return mimeType.utf8().compare("video/vp8") == 0; |
+} |
+ |
+bool MediaRecorderHandler::initialize( |
+ blink::WebMediaRecorderHandlerClient* client, |
+ const blink::WebMediaStream& media_stream, |
+ const blink::WebString& mimeType) { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ if (!canSupportMimeType(mimeType)) { |
+ DLOG(ERROR) << "Can't support type " << mimeType.utf8(); |
+ return false; |
+ } |
+ media_stream_ = media_stream; |
+ DCHECK(client); |
+ client_ = client; |
+ |
+ return true; |
+} |
+ |
+bool MediaRecorderHandler::start() { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ DCHECK(!recording_); |
+ return start(0); |
+} |
+ |
+bool MediaRecorderHandler::start(int timeslice) { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ DCHECK(!recording_); |
+ DCHECK(!media_stream_.isNull()); |
+ |
+ webm_muxer_.reset(new media::WebmMuxer(media::BindToCurrentLoop(base::Bind( |
+ &MediaRecorderHandler::WriteData, weak_factory_.GetWeakPtr())))); |
+ DCHECK(webm_muxer_); |
+ |
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks; |
+ media_stream_.videoTracks(video_tracks); |
+ |
+ if (video_tracks.size() != 1u) { |
+ // TODO(mcasas): Add audio_tracks and update this DCHECK() correspondingly, |
miu
2015/09/08 20:24:40
Comment refers to a DCHECK that is now gone.
mcasas
2015/09/08 23:36:14
Done.
|
+ // see http://crbug.com/528519. As of now only video tracks are supported. |
+ LOG_IF(WARNING, video_tracks.isEmpty()) |
+ << "Recording audio tracks is not implemented"; |
+ // TODO(mcasas): The muxer API supports only one video track. Extend it to |
+ // several video tracks, see http://crbug.com/528523. |
+ LOG_IF(WARNING, video_tracks.size() > 1u) << "Recording multiple video" |
+ << " tracks is not implemented. Only recording first video track."; |
+ return false; |
miu
2015/09/08 20:24:40
You should only return false if video_tracks.IsEmp
mcasas
2015/09/08 23:36:14
Done.
|
+ } |
+ |
+ const blink::WebMediaStreamTrack& video_track = video_tracks[0]; |
+ if (video_track.isNull()) |
+ return false; |
+ |
+ const VideoTrackRecorder::OnEncodedVideoCB on_encoded_video_cb = |
+ base::Bind(&media::WebmMuxer::OnEncodedVideo, |
+ base::Unretained(webm_muxer_.get())); |
+ |
+ video_recorders_.push_back(new VideoTrackRecorder(video_track, |
+ on_encoded_video_cb)); |
+ |
+ recording_ = true; |
+ return true; |
+} |
+ |
+void MediaRecorderHandler::stop() { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ DCHECK(recording_); |
+ |
+ recording_ = false; |
+ video_recorders_.clear(); |
+ webm_muxer_.reset(NULL); |
+} |
+ |
+void MediaRecorderHandler::pause() { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ DCHECK(recording_); |
+ recording_ = false; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void MediaRecorderHandler::resume() { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ DCHECK(!recording_); |
+ recording_ = true; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void MediaRecorderHandler::WriteData(const base::StringPiece& data) { |
+ DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
+ client_->writeData(data.data(), data.size(), false /* lastInSlice */); |
+} |
+ |
+void MediaRecorderHandler::OnVideoFrameForTesting( |
+ const scoped_refptr<media::VideoFrame>& frame, |
+ const base::TimeTicks& timestamp) { |
+ for (auto* recorder : video_recorders_) |
+ recorder->OnVideoFrameForTesting(frame, timestamp); |
+} |
+ |
+} // namespace content |