OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/media_recorder_handler.h" | 5 #include "content/renderer/media/media_recorder_handler.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "media/capture/webm_muxer.h" | 25 #include "media/capture/webm_muxer.h" |
26 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" | 26 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" |
27 #include "third_party/WebKit/public/platform/WebString.h" | 27 #include "third_party/WebKit/public/platform/WebString.h" |
28 | 28 |
29 using base::TimeDelta; | 29 using base::TimeDelta; |
30 using base::TimeTicks; | 30 using base::TimeTicks; |
31 | 31 |
32 namespace content { | 32 namespace content { |
33 | 33 |
34 MediaRecorderHandler::MediaRecorderHandler() | 34 MediaRecorderHandler::MediaRecorderHandler() |
35 : use_vp9_(false), | 35 : video_bits_per_second_(0), |
| 36 audio_bits_per_second_(0), |
| 37 use_vp9_(false), |
36 recording_(false), | 38 recording_(false), |
37 client_(nullptr), | 39 client_(nullptr), |
38 weak_factory_(this) {} | 40 weak_factory_(this) {} |
39 | 41 |
40 MediaRecorderHandler::~MediaRecorderHandler() { | 42 MediaRecorderHandler::~MediaRecorderHandler() { |
41 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 43 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
42 // Send a |last_in_slice| to our |client_|. | 44 // Send a |last_in_slice| to our |client_|. |
43 if (client_) | 45 if (client_) |
44 client_->writeData(nullptr, 0u, true); | 46 client_->writeData(nullptr, 0u, true); |
45 } | 47 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 if (found == &codecs[codecs_count]) | 79 if (found == &codecs[codecs_count]) |
78 return false; | 80 return false; |
79 } | 81 } |
80 return true; | 82 return true; |
81 } | 83 } |
82 | 84 |
83 bool MediaRecorderHandler::initialize( | 85 bool MediaRecorderHandler::initialize( |
84 blink::WebMediaRecorderHandlerClient* client, | 86 blink::WebMediaRecorderHandlerClient* client, |
85 const blink::WebMediaStream& media_stream, | 87 const blink::WebMediaStream& media_stream, |
86 const blink::WebString& type, | 88 const blink::WebString& type, |
87 const blink::WebString& codecs) { | 89 const blink::WebString& codecs, |
| 90 int32_t audio_bits_per_second, |
| 91 int32_t video_bits_per_second) { |
88 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 92 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
89 // Save histogram data so we can see how much MediaStream Recorder is used. | 93 // Save histogram data so we can see how much MediaStream Recorder is used. |
90 // The histogram counts the number of calls to the JS API. | 94 // The histogram counts the number of calls to the JS API. |
91 UpdateWebRTCMethodCount(WEBKIT_MEDIA_STREAM_RECORDER); | 95 UpdateWebRTCMethodCount(WEBKIT_MEDIA_STREAM_RECORDER); |
92 | 96 |
93 if (!canSupportMimeType(type, codecs)) { | 97 if (!canSupportMimeType(type, codecs)) { |
94 DLOG(ERROR) << "Can't support " << type.utf8() | 98 DLOG(ERROR) << "Can't support " << type.utf8() |
95 << ";codecs=" << codecs.utf8(); | 99 << ";codecs=" << codecs.utf8(); |
96 return false; | 100 return false; |
97 } | 101 } |
98 use_vp9_ = base::ToLowerASCII(codecs.utf8()).find("vp9") != std::string::npos; | 102 use_vp9_ = base::ToLowerASCII(codecs.utf8()).find("vp9") != std::string::npos; |
99 media_stream_ = media_stream; | 103 media_stream_ = media_stream; |
100 DCHECK(client); | 104 DCHECK(client); |
101 client_ = client; | 105 client_ = client; |
102 | 106 |
| 107 audio_bits_per_second_ = audio_bits_per_second; |
| 108 video_bits_per_second_ = video_bits_per_second; |
103 return true; | 109 return true; |
104 } | 110 } |
105 | 111 |
106 bool MediaRecorderHandler::start() { | 112 bool MediaRecorderHandler::start() { |
107 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 113 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
108 DCHECK(!recording_); | 114 DCHECK(!recording_); |
109 return start(0); | 115 return start(0); |
110 } | 116 } |
111 | 117 |
112 bool MediaRecorderHandler::start(int timeslice) { | 118 bool MediaRecorderHandler::start(int timeslice) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 << "Recording multiple video tracks is not implemented. " | 151 << "Recording multiple video tracks is not implemented. " |
146 << "Only recording first video track."; | 152 << "Only recording first video track."; |
147 const blink::WebMediaStreamTrack& video_track = video_tracks[0]; | 153 const blink::WebMediaStreamTrack& video_track = video_tracks[0]; |
148 if (video_track.isNull()) | 154 if (video_track.isNull()) |
149 return false; | 155 return false; |
150 | 156 |
151 const VideoTrackRecorder::OnEncodedVideoCB on_encoded_video_cb = | 157 const VideoTrackRecorder::OnEncodedVideoCB on_encoded_video_cb = |
152 media::BindToCurrentLoop(base::Bind( | 158 media::BindToCurrentLoop(base::Bind( |
153 &MediaRecorderHandler::OnEncodedVideo, weak_factory_.GetWeakPtr())); | 159 &MediaRecorderHandler::OnEncodedVideo, weak_factory_.GetWeakPtr())); |
154 | 160 |
155 video_recorders_.push_back( | 161 video_recorders_.push_back(new VideoTrackRecorder( |
156 new VideoTrackRecorder(use_vp9_, video_track, on_encoded_video_cb)); | 162 use_vp9_, video_track, on_encoded_video_cb, video_bits_per_second_)); |
157 } | 163 } |
158 | 164 |
159 if (use_audio_tracks) { | 165 if (use_audio_tracks) { |
160 // TODO(ajose): The muxer API supports only one audio track. Extend it to | 166 // TODO(ajose): The muxer API supports only one audio track. Extend it to |
161 // several tracks. | 167 // several tracks. |
162 LOG_IF(WARNING, audio_tracks.size() > 1u) | 168 LOG_IF(WARNING, audio_tracks.size() > 1u) |
163 << "Recording multiple audio" | 169 << "Recording multiple audio" |
164 << " tracks is not implemented. Only recording first audio track."; | 170 << " tracks is not implemented. Only recording first audio track."; |
165 const blink::WebMediaStreamTrack& audio_track = audio_tracks[0]; | 171 const blink::WebMediaStreamTrack& audio_track = audio_tracks[0]; |
166 if (audio_track.isNull()) | 172 if (audio_track.isNull()) |
167 return false; | 173 return false; |
168 | 174 |
169 const AudioTrackRecorder::OnEncodedAudioCB on_encoded_audio_cb = | 175 const AudioTrackRecorder::OnEncodedAudioCB on_encoded_audio_cb = |
170 media::BindToCurrentLoop(base::Bind( | 176 media::BindToCurrentLoop(base::Bind( |
171 &MediaRecorderHandler::OnEncodedAudio, weak_factory_.GetWeakPtr())); | 177 &MediaRecorderHandler::OnEncodedAudio, weak_factory_.GetWeakPtr())); |
172 | 178 |
173 audio_recorders_.push_back( | 179 audio_recorders_.push_back(new AudioTrackRecorder( |
174 new AudioTrackRecorder(audio_track, on_encoded_audio_cb)); | 180 audio_track, on_encoded_audio_cb, audio_bits_per_second_)); |
175 } | 181 } |
176 | 182 |
177 recording_ = true; | 183 recording_ = true; |
178 return true; | 184 return true; |
179 } | 185 } |
180 | 186 |
181 void MediaRecorderHandler::stop() { | 187 void MediaRecorderHandler::stop() { |
182 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 188 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
183 // Don't check |recording_| since we can go directly from pause() to stop(). | 189 // Don't check |recording_| since we can go directly from pause() to stop(). |
184 | 190 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 void MediaRecorderHandler::OnEncodedAudio(const media::AudioParameters& params, | 226 void MediaRecorderHandler::OnEncodedAudio(const media::AudioParameters& params, |
221 scoped_ptr<std::string> encoded_data, | 227 scoped_ptr<std::string> encoded_data, |
222 base::TimeTicks timestamp) { | 228 base::TimeTicks timestamp) { |
223 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 229 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
224 if (webm_muxer_) | 230 if (webm_muxer_) |
225 webm_muxer_->OnEncodedAudio(params, std::move(encoded_data), timestamp); | 231 webm_muxer_->OnEncodedAudio(params, std::move(encoded_data), timestamp); |
226 } | 232 } |
227 | 233 |
228 void MediaRecorderHandler::WriteData(base::StringPiece data) { | 234 void MediaRecorderHandler::WriteData(base::StringPiece data) { |
229 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 235 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
230 | |
231 // Non-buffered mode does not need to check timestamps. | 236 // Non-buffered mode does not need to check timestamps. |
232 if (timeslice_.is_zero()) { | 237 if (timeslice_.is_zero()) { |
233 client_->writeData(data.data(), data.length(), true /* lastInSlice */); | 238 client_->writeData(data.data(), data.length(), true /* lastInSlice */); |
234 return; | 239 return; |
235 } | 240 } |
236 | 241 |
237 const TimeTicks now = TimeTicks::Now(); | 242 const TimeTicks now = TimeTicks::Now(); |
238 const bool last_in_slice = now > slice_origin_timestamp_ + timeslice_; | 243 const bool last_in_slice = now > slice_origin_timestamp_ + timeslice_; |
239 DVLOG_IF(1, last_in_slice) << "Slice finished @ " << now; | 244 DVLOG_IF(1, last_in_slice) << "Slice finished @ " << now; |
240 if (last_in_slice) | 245 if (last_in_slice) |
(...skipping 15 matching lines...) Expand all Loading... |
256 recorder->OnData(audio_bus, timestamp); | 261 recorder->OnData(audio_bus, timestamp); |
257 } | 262 } |
258 | 263 |
259 void MediaRecorderHandler::SetAudioFormatForTesting( | 264 void MediaRecorderHandler::SetAudioFormatForTesting( |
260 const media::AudioParameters& params) { | 265 const media::AudioParameters& params) { |
261 for (auto* recorder : audio_recorders_) | 266 for (auto* recorder : audio_recorders_) |
262 recorder->OnSetFormat(params); | 267 recorder->OnSetFormat(params); |
263 } | 268 } |
264 | 269 |
265 } // namespace content | 270 } // namespace content |
OLD | NEW |