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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "content/renderer/media/video_track_recorder.h" | 10 #include "content/renderer/media/video_track_recorder.h" |
11 #include "content/renderer/media/webrtc_uma_histograms.h" | 11 #include "content/renderer/media/webrtc_uma_histograms.h" |
12 #include "media/base/bind_to_current_loop.h" | 12 #include "media/base/bind_to_current_loop.h" |
13 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
14 #include "media/capture/webm_muxer.h" | |
15 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" | 14 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" |
16 #include "third_party/WebKit/public/platform/WebString.h" | 15 #include "third_party/WebKit/public/platform/WebString.h" |
17 | 16 |
| 17 #if !defined(MEDIA_DISABLE_LIBWEBM) |
| 18 #include "media/capture/webm_muxer.h" |
| 19 #endif |
| 20 |
18 using base::TimeDelta; | 21 using base::TimeDelta; |
19 using base::TimeTicks; | 22 using base::TimeTicks; |
20 | 23 |
21 namespace content { | 24 namespace content { |
22 | 25 |
23 MediaRecorderHandler::MediaRecorderHandler() | 26 MediaRecorderHandler::MediaRecorderHandler() |
24 : use_vp9_(false), | 27 : use_vp9_(false), |
25 recording_(false), | 28 recording_(false), |
26 client_(nullptr), | 29 client_(nullptr), |
27 weak_factory_(this) { | 30 weak_factory_(this) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 bool MediaRecorderHandler::start() { | 70 bool MediaRecorderHandler::start() { |
68 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 71 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
69 DCHECK(!recording_); | 72 DCHECK(!recording_); |
70 return start(0); | 73 return start(0); |
71 } | 74 } |
72 | 75 |
73 bool MediaRecorderHandler::start(int timeslice) { | 76 bool MediaRecorderHandler::start(int timeslice) { |
74 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 77 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
75 DCHECK(!recording_); | 78 DCHECK(!recording_); |
76 DCHECK(!media_stream_.isNull()); | 79 DCHECK(!media_stream_.isNull()); |
| 80 DCHECK(timeslice_.is_zero()); |
| 81 |
| 82 #if !defined(MEDIA_DISABLE_LIBWEBM) |
77 DCHECK(!webm_muxer_); | 83 DCHECK(!webm_muxer_); |
78 DCHECK(timeslice_.is_zero()); | 84 webm_muxer_.reset( |
| 85 new media::WebmMuxer(use_vp9_ ? media::kCodecVP9 : media::kCodecVP8, |
| 86 base::Bind(&MediaRecorderHandler::WriteData, |
| 87 weak_factory_.GetWeakPtr()))); |
| 88 #else |
| 89 return false; |
| 90 #endif |
79 | 91 |
80 timeslice_ = TimeDelta::FromMilliseconds(timeslice); | 92 timeslice_ = TimeDelta::FromMilliseconds(timeslice); |
81 slice_origin_timestamp_ = TimeTicks::Now(); | 93 slice_origin_timestamp_ = TimeTicks::Now(); |
82 | 94 |
83 webm_muxer_.reset( | |
84 new media::WebmMuxer(use_vp9_ ? media::kCodecVP9 : media::kCodecVP8, | |
85 base::Bind(&MediaRecorderHandler::WriteData, | |
86 weak_factory_.GetWeakPtr()))); | |
87 | |
88 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; | 95 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; |
89 media_stream_.videoTracks(video_tracks); | 96 media_stream_.videoTracks(video_tracks); |
90 | 97 |
91 if (video_tracks.isEmpty()) { | 98 if (video_tracks.isEmpty()) { |
92 // TODO(mcasas): Add audio_tracks and update the code in this function | 99 // TODO(mcasas): Add audio_tracks and update the code in this function |
93 // correspondingly, see http://crbug.com/528519. As of now, only video | 100 // correspondingly, see http://crbug.com/528519. As of now, only video |
94 // tracks are supported. | 101 // tracks are supported. |
95 LOG(WARNING) << "Recording no video tracks is not implemented"; | 102 LOG(WARNING) << "Recording no video tracks is not implemented"; |
96 return false; | 103 return false; |
97 } | 104 } |
(...skipping 17 matching lines...) Expand all Loading... |
115 return true; | 122 return true; |
116 } | 123 } |
117 | 124 |
118 void MediaRecorderHandler::stop() { | 125 void MediaRecorderHandler::stop() { |
119 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 126 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
120 DCHECK(recording_); | 127 DCHECK(recording_); |
121 | 128 |
122 recording_ = false; | 129 recording_ = false; |
123 timeslice_ = TimeDelta::FromMilliseconds(0); | 130 timeslice_ = TimeDelta::FromMilliseconds(0); |
124 video_recorders_.clear(); | 131 video_recorders_.clear(); |
| 132 #if !defined(MEDIA_DISABLE_LIBWEBM) |
125 webm_muxer_.reset(); | 133 webm_muxer_.reset(); |
| 134 #endif |
126 } | 135 } |
127 | 136 |
128 void MediaRecorderHandler::pause() { | 137 void MediaRecorderHandler::pause() { |
129 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 138 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
130 DCHECK(recording_); | 139 DCHECK(recording_); |
131 recording_ = false; | 140 recording_ = false; |
132 for (const auto& video_recorder : video_recorders_) | 141 for (const auto& video_recorder : video_recorders_) |
133 video_recorder->Pause(); | 142 video_recorder->Pause(); |
134 } | 143 } |
135 | 144 |
136 void MediaRecorderHandler::resume() { | 145 void MediaRecorderHandler::resume() { |
137 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 146 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
138 DCHECK(!recording_); | 147 DCHECK(!recording_); |
139 recording_ = true; | 148 recording_ = true; |
140 for (const auto& video_recorder : video_recorders_) | 149 for (const auto& video_recorder : video_recorders_) |
141 video_recorder->Resume(); | 150 video_recorder->Resume(); |
142 } | 151 } |
143 | 152 |
144 void MediaRecorderHandler::OnEncodedVideo( | 153 void MediaRecorderHandler::OnEncodedVideo( |
145 const scoped_refptr<media::VideoFrame>& video_frame, | 154 const scoped_refptr<media::VideoFrame>& video_frame, |
146 scoped_ptr<std::string> encoded_data, | 155 scoped_ptr<std::string> encoded_data, |
147 TimeTicks timestamp, | 156 TimeTicks timestamp, |
148 bool is_key_frame) { | 157 bool is_key_frame) { |
149 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 158 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 159 #if !defined(MEDIA_DISABLE_LIBWEBM) |
150 if (!webm_muxer_) | 160 if (!webm_muxer_) |
151 return; | 161 return; |
152 webm_muxer_->OnEncodedVideo(video_frame, encoded_data.Pass(), timestamp, | 162 webm_muxer_->OnEncodedVideo(video_frame, encoded_data.Pass(), timestamp, |
153 is_key_frame); | 163 is_key_frame); |
| 164 #endif |
154 } | 165 } |
155 | 166 |
156 void MediaRecorderHandler::WriteData(base::StringPiece data) { | 167 void MediaRecorderHandler::WriteData(base::StringPiece data) { |
157 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 168 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
158 | 169 |
159 // Non-buffered mode does not need to check timestamps. | 170 // Non-buffered mode does not need to check timestamps. |
160 if (timeslice_.is_zero()) { | 171 if (timeslice_.is_zero()) { |
161 client_->writeData(data.data(), data.length(), true /* lastInSlice */); | 172 client_->writeData(data.data(), data.length(), true /* lastInSlice */); |
162 return; | 173 return; |
163 } | 174 } |
164 | 175 |
165 const TimeTicks now = TimeTicks::Now(); | 176 const TimeTicks now = TimeTicks::Now(); |
166 const bool last_in_slice = now > slice_origin_timestamp_ + timeslice_; | 177 const bool last_in_slice = now > slice_origin_timestamp_ + timeslice_; |
167 DVLOG_IF(1, last_in_slice) << "Slice finished @ " << now; | 178 DVLOG_IF(1, last_in_slice) << "Slice finished @ " << now; |
168 if (last_in_slice) | 179 if (last_in_slice) |
169 slice_origin_timestamp_ = now; | 180 slice_origin_timestamp_ = now; |
170 client_->writeData(data.data(), data.length(), last_in_slice); | 181 client_->writeData(data.data(), data.length(), last_in_slice); |
171 } | 182 } |
172 | 183 |
173 void MediaRecorderHandler::OnVideoFrameForTesting( | 184 void MediaRecorderHandler::OnVideoFrameForTesting( |
174 const scoped_refptr<media::VideoFrame>& frame, | 185 const scoped_refptr<media::VideoFrame>& frame, |
175 const TimeTicks& timestamp) { | 186 const TimeTicks& timestamp) { |
176 for (auto* recorder : video_recorders_) | 187 for (auto* recorder : video_recorders_) |
177 recorder->OnVideoFrameForTesting(frame, timestamp); | 188 recorder->OnVideoFrameForTesting(frame, timestamp); |
178 } | 189 } |
179 | 190 |
180 } // namespace content | 191 } // namespace content |
OLD | NEW |