OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 return VCM_OK; | 228 return VCM_OK; |
229 } | 229 } |
230 | 230 |
231 int32_t VideoReceiver::RegisterDecoderTimingCallback( | 231 int32_t VideoReceiver::RegisterDecoderTimingCallback( |
232 VCMDecoderTimingCallback* decoderTiming) { | 232 VCMDecoderTimingCallback* decoderTiming) { |
233 CriticalSectionScoped cs(process_crit_sect_.get()); | 233 CriticalSectionScoped cs(process_crit_sect_.get()); |
234 _decoderTimingCallback = decoderTiming; | 234 _decoderTimingCallback = decoderTiming; |
235 return VCM_OK; | 235 return VCM_OK; |
236 } | 236 } |
237 | 237 |
238 // Register an externally defined decoder/render object. | 238 // Register an externally defined decoder object. |
239 // Can be a decoder only or a decoder coupled with a renderer. | |
240 int32_t VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder, | 239 int32_t VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder, |
241 uint8_t payloadType, | 240 uint8_t payloadType) { |
242 bool internalRenderTiming) { | |
243 CriticalSectionScoped cs(_receiveCritSect); | 241 CriticalSectionScoped cs(_receiveCritSect); |
244 if (externalDecoder == NULL) { | 242 if (externalDecoder == NULL) { |
245 // Make sure the VCM updates the decoder next time it decodes. | 243 // Make sure the VCM updates the decoder next time it decodes. |
246 _decoder = NULL; | 244 _decoder = NULL; |
247 return _codecDataBase.DeregisterExternalDecoder(payloadType) ? 0 : -1; | 245 return _codecDataBase.DeregisterExternalDecoder(payloadType) ? 0 : -1; |
248 } | 246 } |
249 return _codecDataBase.RegisterExternalDecoder( | 247 return _codecDataBase.RegisterExternalDecoder( |
250 externalDecoder, payloadType, internalRenderTiming) | 248 externalDecoder, payloadType) |
251 ? 0 | 249 ? 0 |
252 : -1; | 250 : -1; |
253 } | 251 } |
254 | 252 |
255 // Register a frame type request callback. | 253 // Register a frame type request callback. |
256 int32_t VideoReceiver::RegisterFrameTypeCallback( | 254 int32_t VideoReceiver::RegisterFrameTypeCallback( |
257 VCMFrameTypeCallback* frameTypeCallback) { | 255 VCMFrameTypeCallback* frameTypeCallback) { |
258 CriticalSectionScoped cs(process_crit_sect_.get()); | 256 CriticalSectionScoped cs(process_crit_sect_.get()); |
259 _frameTypeCallback = frameTypeCallback; | 257 _frameTypeCallback = frameTypeCallback; |
260 return VCM_OK; | 258 return VCM_OK; |
(...skipping 14 matching lines...) Expand all Loading... |
275 } | 273 } |
276 | 274 |
277 void VideoReceiver::TriggerDecoderShutdown() { | 275 void VideoReceiver::TriggerDecoderShutdown() { |
278 _receiver.TriggerDecoderShutdown(); | 276 _receiver.TriggerDecoderShutdown(); |
279 } | 277 } |
280 | 278 |
281 // Decode next frame, blocking. | 279 // Decode next frame, blocking. |
282 // Should be called as often as possible to get the most out of the decoder. | 280 // Should be called as often as possible to get the most out of the decoder. |
283 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { | 281 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { |
284 int64_t nextRenderTimeMs; | 282 int64_t nextRenderTimeMs; |
285 bool supports_render_scheduling; | 283 bool has_only_one_output_buffer = false; |
286 { | 284 { |
287 CriticalSectionScoped cs(_receiveCritSect); | 285 CriticalSectionScoped cs(_receiveCritSect); |
288 supports_render_scheduling = _codecDataBase.SupportsRenderScheduling(); | 286 has_only_one_output_buffer = _codecDataBase.HasOnlyOneOutputBuffer(); |
289 } | 287 } |
290 | 288 |
291 VCMEncodedFrame* frame = _receiver.FrameForDecoding( | 289 VCMEncodedFrame* frame = _receiver.FrameForDecoding( |
292 maxWaitTimeMs, nextRenderTimeMs, supports_render_scheduling); | 290 maxWaitTimeMs, nextRenderTimeMs, has_only_one_output_buffer); |
293 | 291 |
294 if (frame == NULL) { | 292 if (frame == NULL) { |
295 return VCM_FRAME_NOT_READY; | 293 return VCM_FRAME_NOT_READY; |
296 } else { | 294 } else { |
297 CriticalSectionScoped cs(_receiveCritSect); | 295 CriticalSectionScoped cs(_receiveCritSect); |
298 | 296 |
299 // If this frame was too late, we should adjust the delay accordingly | 297 // If this frame was too late, we should adjust the delay accordingly |
300 _timing.UpdateCurrentDelay(frame->RenderTimeMs(), | 298 _timing.UpdateCurrentDelay(frame->RenderTimeMs(), |
301 clock_->TimeInMilliseconds()); | 299 clock_->TimeInMilliseconds()); |
302 | 300 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 361 |
364 // Must be called from inside the receive side critical section. | 362 // Must be called from inside the receive side critical section. |
365 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) { | 363 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) { |
366 TRACE_EVENT_ASYNC_STEP1("webrtc", | 364 TRACE_EVENT_ASYNC_STEP1("webrtc", |
367 "Video", | 365 "Video", |
368 frame.TimeStamp(), | 366 frame.TimeStamp(), |
369 "Decode", | 367 "Decode", |
370 "type", | 368 "type", |
371 frame.FrameType()); | 369 frame.FrameType()); |
372 // Change decoder if payload type has changed | 370 // Change decoder if payload type has changed |
373 const bool renderTimingBefore = _codecDataBase.SupportsRenderScheduling(); | |
374 _decoder = | 371 _decoder = |
375 _codecDataBase.GetDecoder(frame.PayloadType(), &_decodedFrameCallback); | 372 _codecDataBase.GetDecoder(frame.PayloadType(), &_decodedFrameCallback); |
376 if (renderTimingBefore != _codecDataBase.SupportsRenderScheduling()) { | |
377 // Make sure we reset the decode time estimate since it will | |
378 // be zero for codecs without render timing. | |
379 _timing.ResetDecodeTime(); | |
380 } | |
381 if (_decoder == NULL) { | 373 if (_decoder == NULL) { |
382 return VCM_NO_CODEC_REGISTERED; | 374 return VCM_NO_CODEC_REGISTERED; |
383 } | 375 } |
384 // Decode a frame | 376 // Decode a frame |
385 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); | 377 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); |
386 | 378 |
387 // Check for failed decoding, run frame type request callback if needed. | 379 // Check for failed decoding, run frame type request callback if needed. |
388 bool request_key_frame = false; | 380 bool request_key_frame = false; |
389 if (ret < 0) { | 381 if (ret < 0) { |
390 if (ret == VCM_ERROR_REQUEST_SLI) { | 382 if (ret == VCM_ERROR_REQUEST_SLI) { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 } | 561 } |
570 | 562 |
571 void VideoReceiver::RegisterPreDecodeImageCallback( | 563 void VideoReceiver::RegisterPreDecodeImageCallback( |
572 EncodedImageCallback* observer) { | 564 EncodedImageCallback* observer) { |
573 CriticalSectionScoped cs(_receiveCritSect); | 565 CriticalSectionScoped cs(_receiveCritSect); |
574 pre_decode_image_callback_ = observer; | 566 pre_decode_image_callback_ = observer; |
575 } | 567 } |
576 | 568 |
577 } // namespace vcm | 569 } // namespace vcm |
578 } // namespace webrtc | 570 } // namespace webrtc |
OLD | NEW |