Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: webrtc/modules/video_coding/video_receiver.cc

Issue 2744013002: Updates to VCMDecodedFrameCallback, VideoReceiver and a few related classes/tests. (Closed)
Patch Set: Format + assert->DCHECK and require callback in decode Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 23 matching lines...) Expand all
34 _receiver(_timing, 34 _receiver(_timing,
35 clock_, 35 clock_,
36 event_factory, 36 event_factory,
37 nack_sender, 37 nack_sender,
38 keyframe_request_sender), 38 keyframe_request_sender),
39 _decodedFrameCallback(_timing, clock_), 39 _decodedFrameCallback(_timing, clock_),
40 _frameTypeCallback(nullptr), 40 _frameTypeCallback(nullptr),
41 _receiveStatsCallback(nullptr), 41 _receiveStatsCallback(nullptr),
42 _decoderTimingCallback(nullptr), 42 _decoderTimingCallback(nullptr),
43 _packetRequestCallback(nullptr), 43 _packetRequestCallback(nullptr),
44 _decoder(nullptr),
45 _frameFromFile(), 44 _frameFromFile(),
46 _scheduleKeyRequest(false), 45 _scheduleKeyRequest(false),
47 drop_frames_until_keyframe_(false), 46 drop_frames_until_keyframe_(false),
48 max_nack_list_size_(0), 47 max_nack_list_size_(0),
49 _codecDataBase(nullptr), 48 _codecDataBase(nullptr),
50 pre_decode_image_callback_(pre_decode_image_callback), 49 pre_decode_image_callback_(pre_decode_image_callback),
51 _receiveStatsTimer(1000, clock_), 50 _receiveStatsTimer(1000, clock_),
52 _retransmissionTimer(10, clock_), 51 _retransmissionTimer(10, clock_),
53 _keyRequestTimer(500, clock_) {} 52 _keyRequestTimer(500, clock_) {}
54 53
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 _receiver.SetDecodeErrorMode(kWithErrors); 160 _receiver.SetDecodeErrorMode(kWithErrors);
162 break; 161 break;
163 } 162 }
164 return VCM_OK; 163 return VCM_OK;
165 } 164 }
166 165
167 // Register a receive callback. Will be called whenever there is a new frame 166 // Register a receive callback. Will be called whenever there is a new frame
168 // ready for rendering. 167 // ready for rendering.
169 int32_t VideoReceiver::RegisterReceiveCallback( 168 int32_t VideoReceiver::RegisterReceiveCallback(
170 VCMReceiveCallback* receiveCallback) { 169 VCMReceiveCallback* receiveCallback) {
170 RTC_DCHECK(construction_thread_.CalledOnValidThread());
171 // TODO(tommi): Callback may be null, but only after the decoder thread has
172 // been stopped.
stefan-webrtc 2017/03/11 12:57:37 Clarify what is to be done to remove this TODO
tommi 2017/03/11 15:24:03 Done.
171 rtc::CritScope cs(&receive_crit_); 173 rtc::CritScope cs(&receive_crit_);
172 _decodedFrameCallback.SetUserReceiveCallback(receiveCallback); 174 _decodedFrameCallback.SetUserReceiveCallback(receiveCallback);
173 return VCM_OK; 175 return VCM_OK;
174 } 176 }
175 177
176 int32_t VideoReceiver::RegisterReceiveStatisticsCallback( 178 int32_t VideoReceiver::RegisterReceiveStatisticsCallback(
177 VCMReceiveStatisticsCallback* receiveStats) { 179 VCMReceiveStatisticsCallback* receiveStats) {
180 RTC_DCHECK(construction_thread_.CalledOnValidThread());
178 rtc::CritScope cs(&process_crit_); 181 rtc::CritScope cs(&process_crit_);
179 _receiver.RegisterStatsCallback(receiveStats); 182 _receiver.RegisterStatsCallback(receiveStats);
180 _receiveStatsCallback = receiveStats; 183 _receiveStatsCallback = receiveStats;
181 return VCM_OK; 184 return VCM_OK;
182 } 185 }
183 186
184 int32_t VideoReceiver::RegisterDecoderTimingCallback( 187 int32_t VideoReceiver::RegisterDecoderTimingCallback(
185 VCMDecoderTimingCallback* decoderTiming) { 188 VCMDecoderTimingCallback* decoderTiming) {
189 RTC_DCHECK(construction_thread_.CalledOnValidThread());
186 rtc::CritScope cs(&process_crit_); 190 rtc::CritScope cs(&process_crit_);
187 _decoderTimingCallback = decoderTiming; 191 _decoderTimingCallback = decoderTiming;
188 return VCM_OK; 192 return VCM_OK;
189 } 193 }
190 194
191 // Register an externally defined decoder object. 195 // Register an externally defined decoder object.
192 void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder, 196 void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder,
193 uint8_t payloadType) { 197 uint8_t payloadType) {
198 RTC_DCHECK(construction_thread_.CalledOnValidThread());
199 // TODO(tommi): This method must be called when the decoder thread is not
200 // running. Do we need a lock in that case?
stefan-webrtc 2017/03/11 12:57:37 I think the answer is no as _codecDataBase only se
tommi 2017/03/11 15:24:03 Yes, this is more of a rhetorical question/TODO fr
194 rtc::CritScope cs(&receive_crit_); 201 rtc::CritScope cs(&receive_crit_);
195 if (externalDecoder == nullptr) { 202 if (externalDecoder == nullptr) {
196 // Make sure the VCM updates the decoder next time it decodes.
197 _decoder = nullptr;
198 RTC_CHECK(_codecDataBase.DeregisterExternalDecoder(payloadType)); 203 RTC_CHECK(_codecDataBase.DeregisterExternalDecoder(payloadType));
199 return; 204 return;
200 } 205 }
201 _codecDataBase.RegisterExternalDecoder(externalDecoder, payloadType); 206 _codecDataBase.RegisterExternalDecoder(externalDecoder, payloadType);
202 } 207 }
203 208
204 // Register a frame type request callback. 209 // Register a frame type request callback.
205 int32_t VideoReceiver::RegisterFrameTypeCallback( 210 int32_t VideoReceiver::RegisterFrameTypeCallback(
206 VCMFrameTypeCallback* frameTypeCallback) { 211 VCMFrameTypeCallback* frameTypeCallback) {
207 rtc::CritScope cs(&process_crit_); 212 rtc::CritScope cs(&process_crit_);
208 _frameTypeCallback = frameTypeCallback; 213 _frameTypeCallback = frameTypeCallback;
209 return VCM_OK; 214 return VCM_OK;
210 } 215 }
211 216
212 int32_t VideoReceiver::RegisterPacketRequestCallback( 217 int32_t VideoReceiver::RegisterPacketRequestCallback(
213 VCMPacketRequestCallback* callback) { 218 VCMPacketRequestCallback* callback) {
214 rtc::CritScope cs(&process_crit_); 219 rtc::CritScope cs(&process_crit_);
215 _packetRequestCallback = callback; 220 _packetRequestCallback = callback;
216 return VCM_OK; 221 return VCM_OK;
217 } 222 }
218 223
219 void VideoReceiver::TriggerDecoderShutdown() { 224 void VideoReceiver::TriggerDecoderShutdown() {
225 RTC_DCHECK(construction_thread_.CalledOnValidThread());
220 _receiver.TriggerDecoderShutdown(); 226 _receiver.TriggerDecoderShutdown();
221 } 227 }
222 228
223 // Decode next frame, blocking. 229 // Decode next frame, blocking.
224 // Should be called as often as possible to get the most out of the decoder. 230 // Should be called as often as possible to get the most out of the decoder.
225 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { 231 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
226 bool prefer_late_decoding = false; 232 bool prefer_late_decoding = false;
227 { 233 {
234 // TODO(tommi): Chances are that this lock isn't required.
228 rtc::CritScope cs(&receive_crit_); 235 rtc::CritScope cs(&receive_crit_);
229 prefer_late_decoding = _codecDataBase.PrefersLateDecoding(); 236 prefer_late_decoding = _codecDataBase.PrefersLateDecoding();
230 } 237 }
231 238
232 VCMEncodedFrame* frame = 239 VCMEncodedFrame* frame =
233 _receiver.FrameForDecoding(maxWaitTimeMs, prefer_late_decoding); 240 _receiver.FrameForDecoding(maxWaitTimeMs, prefer_late_decoding);
234 241
235 if (!frame) 242 if (!frame)
236 return VCM_FRAME_NOT_READY; 243 return VCM_FRAME_NOT_READY;
237 244
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 int qp = -1; 292 int qp = -1;
286 if (qp_parser_.GetQp(*frame, &qp)) { 293 if (qp_parser_.GetQp(*frame, &qp)) {
287 encoded_image.qp_ = qp; 294 encoded_image.qp_ = qp;
288 } 295 }
289 pre_decode_image_callback_->OnEncodedImage(encoded_image, 296 pre_decode_image_callback_->OnEncodedImage(encoded_image,
290 frame->CodecSpecific(), nullptr); 297 frame->CodecSpecific(), nullptr);
291 } 298 }
292 return Decode(*frame); 299 return Decode(*frame);
293 } 300 }
294 301
302 void VideoReceiver::DecodingStopped() {
303 // No further calls to Decode() will be made after this point.
304 // TODO(tommi): Make use of this to clarify and check threading model.
305 }
306
295 int32_t VideoReceiver::RequestSliceLossIndication( 307 int32_t VideoReceiver::RequestSliceLossIndication(
296 const uint64_t pictureID) const { 308 const uint64_t pictureID) const {
297 TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID); 309 TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID);
298 rtc::CritScope cs(&process_crit_); 310 rtc::CritScope cs(&process_crit_);
299 if (_frameTypeCallback != nullptr) { 311 if (_frameTypeCallback != nullptr) {
300 const int32_t ret = 312 const int32_t ret =
301 _frameTypeCallback->SliceLossIndicationRequest(pictureID); 313 _frameTypeCallback->SliceLossIndicationRequest(pictureID);
302 if (ret < 0) { 314 if (ret < 0) {
303 return ret; 315 return ret;
304 } 316 }
(...skipping 15 matching lines...) Expand all
320 } else { 332 } else {
321 return VCM_MISSING_CALLBACK; 333 return VCM_MISSING_CALLBACK;
322 } 334 }
323 return VCM_OK; 335 return VCM_OK;
324 } 336 }
325 337
326 // Must be called from inside the receive side critical section. 338 // Must be called from inside the receive side critical section.
327 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) { 339 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
328 TRACE_EVENT0("webrtc", "VideoReceiver::Decode"); 340 TRACE_EVENT0("webrtc", "VideoReceiver::Decode");
329 // Change decoder if payload type has changed 341 // Change decoder if payload type has changed
330 _decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback); 342 VCMGenericDecoder* decoder =
331 if (_decoder == nullptr) { 343 _codecDataBase.GetDecoder(frame, &_decodedFrameCallback);
344 if (decoder == nullptr) {
332 return VCM_NO_CODEC_REGISTERED; 345 return VCM_NO_CODEC_REGISTERED;
333 } 346 }
334 // Decode a frame 347 // Decode a frame
335 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); 348 int32_t ret = decoder->Decode(frame, clock_->TimeInMilliseconds());
336 349
337 // Check for failed decoding, run frame type request callback if needed. 350 // Check for failed decoding, run frame type request callback if needed.
338 bool request_key_frame = false; 351 bool request_key_frame = false;
339 if (ret < 0) { 352 if (ret < 0) {
340 if (ret == VCM_ERROR_REQUEST_SLI) { 353 if (ret == VCM_ERROR_REQUEST_SLI) {
341 return RequestSliceLossIndication( 354 return RequestSliceLossIndication(
342 _decodedFrameCallback.LastReceivedPictureID() + 1); 355 _decodedFrameCallback.LastReceivedPictureID() + 1);
343 } else { 356 } else {
344 request_key_frame = true; 357 request_key_frame = true;
345 } 358 }
346 } else if (ret == VCM_REQUEST_SLI) { 359 } else if (ret == VCM_REQUEST_SLI) {
347 ret = RequestSliceLossIndication( 360 ret = RequestSliceLossIndication(
348 _decodedFrameCallback.LastReceivedPictureID() + 1); 361 _decodedFrameCallback.LastReceivedPictureID() + 1);
349 } 362 }
350 if (!frame.Complete() || frame.MissingFrame()) { 363 if (!frame.Complete() || frame.MissingFrame()) {
351 request_key_frame = true; 364 request_key_frame = true;
352 ret = VCM_OK; 365 ret = VCM_OK;
353 } 366 }
354 if (request_key_frame) { 367 if (request_key_frame) {
355 rtc::CritScope cs(&process_crit_); 368 rtc::CritScope cs(&process_crit_);
356 _scheduleKeyRequest = true; 369 _scheduleKeyRequest = true;
357 } 370 }
358 return ret; 371 return ret;
359 } 372 }
360 373
361 // Register possible receive codecs, can be called multiple times 374 // Register possible receive codecs, can be called multiple times
362 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec, 375 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
363 int32_t numberOfCores, 376 int32_t numberOfCores,
364 bool requireKeyFrame) { 377 bool requireKeyFrame) {
378 RTC_DCHECK(construction_thread_.CalledOnValidThread());
379 // TODO(tommi): This method must only be called when the decoder thread
380 // is not running. Do we need a lock? If not, it looks like we might not need
381 // a lock at all for |_codecDataBase|.
365 rtc::CritScope cs(&receive_crit_); 382 rtc::CritScope cs(&receive_crit_);
366 if (receiveCodec == nullptr) { 383 if (receiveCodec == nullptr) {
367 return VCM_PARAMETER_ERROR; 384 return VCM_PARAMETER_ERROR;
368 } 385 }
369 if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores, 386 if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores,
370 requireKeyFrame)) { 387 requireKeyFrame)) {
371 return -1; 388 return -1;
372 } 389 }
373 return 0; 390 return 0;
374 } 391 }
375 392
376 // Get current received codec 393 // Get current received codec
394 // TODO(tommi): See if there are any actual callers to this method.
395 // If not, it will make threading simpler.
stefan-webrtc 2017/03/11 12:57:37 No calls that I can find.
tommi 2017/03/11 15:24:03 Thanks for looking. I didn't find any either. I'l
377 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const { 396 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const {
378 rtc::CritScope cs(&receive_crit_); 397 rtc::CritScope cs(&receive_crit_);
379 if (currentReceiveCodec == nullptr) { 398 if (currentReceiveCodec == nullptr) {
380 return VCM_PARAMETER_ERROR; 399 return VCM_PARAMETER_ERROR;
381 } 400 }
382 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1; 401 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1;
383 } 402 }
384 403
385 // Get current received codec 404 // Get current received codec
405 // TODO(tommi): See if there are any actual callers to this method.
406 // If not, it will make threading simpler.
386 VideoCodecType VideoReceiver::ReceiveCodec() const { 407 VideoCodecType VideoReceiver::ReceiveCodec() const {
387 rtc::CritScope cs(&receive_crit_); 408 rtc::CritScope cs(&receive_crit_);
388 return _codecDataBase.ReceiveCodec(); 409 return _codecDataBase.ReceiveCodec();
389 } 410 }
390 411
391 // Incoming packet from network parsed and ready for decode, non blocking. 412 // Incoming packet from network parsed and ready for decode, non blocking.
392 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload, 413 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
393 size_t payloadLength, 414 size_t payloadLength,
394 const WebRtcRTPHeader& rtpInfo) { 415 const WebRtcRTPHeader& rtpInfo) {
395 if (rtpInfo.frameType == kVideoFrameKey) { 416 if (rtpInfo.frameType == kVideoFrameKey) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 _receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack, 517 _receiver.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
497 max_incomplete_time_ms); 518 max_incomplete_time_ms);
498 } 519 }
499 520
500 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) { 521 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) {
501 return _receiver.SetMinReceiverDelay(desired_delay_ms); 522 return _receiver.SetMinReceiverDelay(desired_delay_ms);
502 } 523 }
503 524
504 } // namespace vcm 525 } // namespace vcm
505 } // namespace webrtc 526 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698