OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/cast/video_receiver/video_receiver.h" | 5 #include "media/cast/video_receiver/video_receiver.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 void VideoReceiver::GetRawVideoFrame( | 152 void VideoReceiver::GetRawVideoFrame( |
153 const VideoFrameDecodedCallback& callback) { | 153 const VideoFrameDecodedCallback& callback) { |
154 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 154 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
155 GetEncodedVideoFrame(base::Bind(&VideoReceiver::DecodeVideoFrame, | 155 GetEncodedVideoFrame(base::Bind(&VideoReceiver::DecodeVideoFrame, |
156 base::Unretained(this), callback)); | 156 base::Unretained(this), callback)); |
157 } | 157 } |
158 | 158 |
159 // Called when we have a frame to decode. | 159 // Called when we have a frame to decode. |
160 void VideoReceiver::DecodeVideoFrame( | 160 void VideoReceiver::DecodeVideoFrame( |
161 const VideoFrameDecodedCallback& callback, | 161 const VideoFrameDecodedCallback& callback, |
162 scoped_ptr<EncodedVideoFrame> encoded_frame, | 162 scoped_ptr<transport::EncodedVideoFrame> encoded_frame, |
163 const base::TimeTicks& render_time) { | 163 const base::TimeTicks& render_time) { |
164 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 164 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
165 // Hand the ownership of the encoded frame to the decode thread. | 165 // Hand the ownership of the encoded frame to the decode thread. |
166 cast_environment_->PostTask(CastEnvironment::VIDEO_DECODER, FROM_HERE, | 166 cast_environment_->PostTask(CastEnvironment::VIDEO_DECODER, FROM_HERE, |
167 base::Bind(&VideoReceiver::DecodeVideoFrameThread, base::Unretained(this), | 167 base::Bind(&VideoReceiver::DecodeVideoFrameThread, base::Unretained(this), |
168 base::Passed(&encoded_frame), render_time, callback)); | 168 base::Passed(&encoded_frame), render_time, callback)); |
169 } | 169 } |
170 | 170 |
171 // Utility function to run the decoder on a designated decoding thread. | 171 // Utility function to run the decoder on a designated decoding thread. |
172 void VideoReceiver::DecodeVideoFrameThread( | 172 void VideoReceiver::DecodeVideoFrameThread( |
173 scoped_ptr<EncodedVideoFrame> encoded_frame, | 173 scoped_ptr<transport::EncodedVideoFrame> encoded_frame, |
174 const base::TimeTicks render_time, | 174 const base::TimeTicks render_time, |
175 const VideoFrameDecodedCallback& frame_decoded_callback) { | 175 const VideoFrameDecodedCallback& frame_decoded_callback) { |
176 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::VIDEO_DECODER)); | 176 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::VIDEO_DECODER)); |
177 DCHECK(video_decoder_); | 177 DCHECK(video_decoder_); |
178 | 178 |
179 if (!(video_decoder_->DecodeVideoFrame(encoded_frame.get(), render_time, | 179 if (!(video_decoder_->DecodeVideoFrame(encoded_frame.get(), render_time, |
180 frame_decoded_callback))) { | 180 frame_decoded_callback))) { |
181 // This will happen if we decide to decode but not show a frame. | 181 // This will happen if we decide to decode but not show a frame. |
182 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, | 182 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, |
183 base::Bind(&VideoReceiver::GetRawVideoFrame, base::Unretained(this), | 183 base::Bind(&VideoReceiver::GetRawVideoFrame, base::Unretained(this), |
184 frame_decoded_callback)); | 184 frame_decoded_callback)); |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 bool VideoReceiver::DecryptVideoFrame( | 188 bool VideoReceiver::DecryptVideoFrame( |
189 scoped_ptr<EncodedVideoFrame>* video_frame) { | 189 scoped_ptr<transport::EncodedVideoFrame>* video_frame) { |
190 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 190 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
191 DCHECK(decryptor_) << "Invalid state"; | 191 DCHECK(decryptor_) << "Invalid state"; |
192 | 192 |
193 if (!decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id, | 193 if (!decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id, |
194 iv_mask_))) { | 194 iv_mask_))) { |
195 NOTREACHED() << "Failed to set counter"; | 195 NOTREACHED() << "Failed to set counter"; |
196 return false; | 196 return false; |
197 } | 197 } |
198 std::string decrypted_video_data; | 198 std::string decrypted_video_data; |
199 if (!decryptor_->Decrypt((*video_frame)->data, &decrypted_video_data)) { | 199 if (!decryptor_->Decrypt((*video_frame)->data, &decrypted_video_data)) { |
200 VLOG(1) << "Decryption error"; | 200 VLOG(1) << "Decryption error"; |
201 // Give up on this frame, release it from jitter buffer. | 201 // Give up on this frame, release it from jitter buffer. |
202 framer_->ReleaseFrame((*video_frame)->frame_id); | 202 framer_->ReleaseFrame((*video_frame)->frame_id); |
203 return false; | 203 return false; |
204 } | 204 } |
205 (*video_frame)->data.swap(decrypted_video_data); | 205 (*video_frame)->data.swap(decrypted_video_data); |
206 return true; | 206 return true; |
207 } | 207 } |
208 | 208 |
209 // Called from the main cast thread. | 209 // Called from the main cast thread. |
210 void VideoReceiver::GetEncodedVideoFrame( | 210 void VideoReceiver::GetEncodedVideoFrame( |
211 const VideoFrameEncodedCallback& callback) { | 211 const VideoFrameEncodedCallback& callback) { |
212 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 212 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
213 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); | 213 scoped_ptr<transport::EncodedVideoFrame> encoded_frame( |
| 214 new transport::EncodedVideoFrame()); |
214 uint32 rtp_timestamp = 0; | 215 uint32 rtp_timestamp = 0; |
215 bool next_frame = false; | 216 bool next_frame = false; |
216 | 217 |
217 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, | 218 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, |
218 &next_frame)) { | 219 &next_frame)) { |
219 // We have no video frames. Wait for new packet(s). | 220 // We have no video frames. Wait for new packet(s). |
220 queued_encoded_callbacks_.push_back(callback); | 221 queued_encoded_callbacks_.push_back(callback); |
221 return; | 222 return; |
222 } | 223 } |
223 | 224 |
(...skipping 14 matching lines...) Expand all Loading... |
238 queued_encoded_callbacks_.push_back(callback); | 239 queued_encoded_callbacks_.push_back(callback); |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 // Should we pull the encoded video frame from the framer? decided by if this is | 243 // Should we pull the encoded video frame from the framer? decided by if this is |
243 // the next frame or we are running out of time and have to pull the following | 244 // the next frame or we are running out of time and have to pull the following |
244 // frame. | 245 // frame. |
245 // If the frame is too old to be rendered we set the don't show flag in the | 246 // If the frame is too old to be rendered we set the don't show flag in the |
246 // video bitstream where possible. | 247 // video bitstream where possible. |
247 bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp, | 248 bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp, |
248 bool next_frame, scoped_ptr<EncodedVideoFrame>* encoded_frame, | 249 bool next_frame, scoped_ptr<transport::EncodedVideoFrame>* encoded_frame, |
249 base::TimeTicks* render_time) { | 250 base::TimeTicks* render_time) { |
250 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 251 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
251 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 252 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
252 *render_time = GetRenderTime(now, rtp_timestamp); | 253 *render_time = GetRenderTime(now, rtp_timestamp); |
253 | 254 |
254 // TODO(mikhal): Store actual render time and not diff. | 255 // TODO(mikhal): Store actual render time and not diff. |
255 cast_environment_->Logging()->InsertFrameEventWithDelay(now, | 256 cast_environment_->Logging()->InsertFrameEventWithDelay(now, |
256 kVideoRenderDelay, rtp_timestamp, (*encoded_frame)->frame_id, | 257 kVideoRenderDelay, rtp_timestamp, (*encoded_frame)->frame_id, |
257 now - *render_time); | 258 now - *render_time); |
258 | 259 |
(...skipping 12 matching lines...) Expand all Loading... |
271 base::Bind(&VideoReceiver::PlayoutTimeout, weak_factory_.GetWeakPtr()), | 272 base::Bind(&VideoReceiver::PlayoutTimeout, weak_factory_.GetWeakPtr()), |
272 time_until_release); | 273 time_until_release); |
273 VLOG(1) << "Wait before releasing frame " | 274 VLOG(1) << "Wait before releasing frame " |
274 << static_cast<int>((*encoded_frame)->frame_id) | 275 << static_cast<int>((*encoded_frame)->frame_id) |
275 << " time " << time_until_release.InMilliseconds(); | 276 << " time " << time_until_release.InMilliseconds(); |
276 return false; | 277 return false; |
277 } | 278 } |
278 | 279 |
279 base::TimeDelta dont_show_timeout_delta = | 280 base::TimeDelta dont_show_timeout_delta = |
280 base::TimeDelta::FromMilliseconds(-kDontShowTimeoutMs); | 281 base::TimeDelta::FromMilliseconds(-kDontShowTimeoutMs); |
281 if (codec_ == kVp8 && time_until_render < dont_show_timeout_delta) { | 282 if (codec_ == transport::kVp8 && |
| 283 time_until_render < dont_show_timeout_delta) { |
282 (*encoded_frame)->data[0] &= 0xef; | 284 (*encoded_frame)->data[0] &= 0xef; |
283 VLOG(1) << "Don't show frame " | 285 VLOG(1) << "Don't show frame " |
284 << static_cast<int>((*encoded_frame)->frame_id) | 286 << static_cast<int>((*encoded_frame)->frame_id) |
285 << " time_until_render:" << time_until_render.InMilliseconds(); | 287 << " time_until_render:" << time_until_render.InMilliseconds(); |
286 } else { | 288 } else { |
287 VLOG(1) << "Show frame " | 289 VLOG(1) << "Show frame " |
288 << static_cast<int>((*encoded_frame)->frame_id) | 290 << static_cast<int>((*encoded_frame)->frame_id) |
289 << " time_until_render:" << time_until_render.InMilliseconds(); | 291 << " time_until_render:" << time_until_render.InMilliseconds(); |
290 } | 292 } |
291 // We have a copy of the frame, release this one. | 293 // We have a copy of the frame, release this one. |
292 framer_->ReleaseFrame((*encoded_frame)->frame_id); | 294 framer_->ReleaseFrame((*encoded_frame)->frame_id); |
293 (*encoded_frame)->codec = codec_; | 295 (*encoded_frame)->codec = codec_; |
294 return true; | 296 return true; |
295 } | 297 } |
296 | 298 |
297 void VideoReceiver::PlayoutTimeout() { | 299 void VideoReceiver::PlayoutTimeout() { |
298 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 300 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
299 if (queued_encoded_callbacks_.empty()) return; | 301 if (queued_encoded_callbacks_.empty()) return; |
300 | 302 |
301 uint32 rtp_timestamp = 0; | 303 uint32 rtp_timestamp = 0; |
302 bool next_frame = false; | 304 bool next_frame = false; |
303 scoped_ptr<EncodedVideoFrame> encoded_frame(new EncodedVideoFrame()); | 305 scoped_ptr<transport::EncodedVideoFrame> encoded_frame( |
| 306 new transport::EncodedVideoFrame()); |
304 | 307 |
305 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, | 308 if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp, |
306 &next_frame)) { | 309 &next_frame)) { |
307 // We have no video frames. Wait for new packet(s). | 310 // We have no video frames. Wait for new packet(s). |
308 // Since the application can post multiple VideoFrameEncodedCallback and | 311 // Since the application can post multiple VideoFrameEncodedCallback and |
309 // we only check the next frame to play out we might have multiple timeout | 312 // we only check the next frame to play out we might have multiple timeout |
310 // events firing after each other; however this should be a rare event. | 313 // events firing after each other; however this should be a rare event. |
311 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; | 314 VLOG(1) << "Failed to retrieved a complete frame at this point in time"; |
312 return; | 315 return; |
313 } | 316 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 } | 477 } |
475 | 478 |
476 void VideoReceiver::SendNextRtcpReport() { | 479 void VideoReceiver::SendNextRtcpReport() { |
477 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 480 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
478 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL); | 481 rtcp_->SendRtcpFromRtpReceiver(NULL, NULL); |
479 ScheduleNextRtcpReport(); | 482 ScheduleNextRtcpReport(); |
480 } | 483 } |
481 | 484 |
482 } // namespace cast | 485 } // namespace cast |
483 } // namespace media | 486 } // namespace media |
OLD | NEW |