OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 return vp9_settings; | 59 return vp9_settings; |
60 } | 60 } |
61 | 61 |
62 VideoCodecH264 VideoEncoder::GetDefaultH264Settings() { | 62 VideoCodecH264 VideoEncoder::GetDefaultH264Settings() { |
63 VideoCodecH264 h264_settings; | 63 VideoCodecH264 h264_settings; |
64 memset(&h264_settings, 0, sizeof(h264_settings)); | 64 memset(&h264_settings, 0, sizeof(h264_settings)); |
65 | 65 |
66 h264_settings.profile = kProfileBase; | 66 h264_settings.profile = kProfileBase; |
67 h264_settings.frameDroppingOn = true; | 67 h264_settings.frameDroppingOn = true; |
68 h264_settings.keyFrameInterval = 3000; | 68 h264_settings.keyFrameInterval = 3000; |
69 h264_settings.spsData = NULL; | 69 h264_settings.spsData = nullptr; |
70 h264_settings.spsLen = 0; | 70 h264_settings.spsLen = 0; |
71 h264_settings.ppsData = NULL; | 71 h264_settings.ppsData = nullptr; |
72 h264_settings.ppsLen = 0; | 72 h264_settings.ppsLen = 0; |
73 | 73 |
74 return h264_settings; | 74 return h264_settings; |
75 } | 75 } |
76 | 76 |
77 VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, | 77 VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, |
78 int number_of_cores, | 78 int number_of_cores, |
79 bool require_key_frame) | 79 bool require_key_frame) |
80 : settings(settings), | 80 : settings(settings), |
81 number_of_cores(number_of_cores), | 81 number_of_cores(number_of_cores), |
(...skipping 13 matching lines...) Expand all Loading... |
95 VCMCodecDataBase::VCMCodecDataBase( | 95 VCMCodecDataBase::VCMCodecDataBase( |
96 VideoEncoderRateObserver* encoder_rate_observer, | 96 VideoEncoderRateObserver* encoder_rate_observer, |
97 VCMEncodedFrameCallback* encoded_frame_callback) | 97 VCMEncodedFrameCallback* encoded_frame_callback) |
98 : number_of_cores_(0), | 98 : number_of_cores_(0), |
99 max_payload_size_(kDefaultPayloadSize), | 99 max_payload_size_(kDefaultPayloadSize), |
100 periodic_key_frames_(false), | 100 periodic_key_frames_(false), |
101 pending_encoder_reset_(true), | 101 pending_encoder_reset_(true), |
102 send_codec_(), | 102 send_codec_(), |
103 receive_codec_(), | 103 receive_codec_(), |
104 encoder_payload_type_(0), | 104 encoder_payload_type_(0), |
105 external_encoder_(NULL), | 105 external_encoder_(nullptr), |
106 internal_source_(false), | 106 internal_source_(false), |
107 encoder_rate_observer_(encoder_rate_observer), | 107 encoder_rate_observer_(encoder_rate_observer), |
108 encoded_frame_callback_(encoded_frame_callback), | 108 encoded_frame_callback_(encoded_frame_callback), |
109 ptr_decoder_(NULL), | 109 ptr_decoder_(nullptr), |
110 dec_map_(), | 110 dec_map_(), |
111 dec_external_map_() {} | 111 dec_external_map_() {} |
112 | 112 |
113 VCMCodecDataBase::~VCMCodecDataBase() { | 113 VCMCodecDataBase::~VCMCodecDataBase() { |
114 ResetSender(); | 114 ResetSender(); |
115 ResetReceiver(); | 115 ResetReceiver(); |
116 } | 116 } |
117 | 117 |
118 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) { | 118 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) { |
119 memset(settings, 0, sizeof(VideoCodec)); | 119 memset(settings, 0, sizeof(VideoCodec)); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 if (encoder_payload_type_ != payload_type) { | 293 if (encoder_payload_type_ != payload_type) { |
294 return false; | 294 return false; |
295 } | 295 } |
296 if (send_codec_.plType == payload_type) { | 296 if (send_codec_.plType == payload_type) { |
297 // De-register as send codec if needed. | 297 // De-register as send codec if needed. |
298 DeleteEncoder(); | 298 DeleteEncoder(); |
299 memset(&send_codec_, 0, sizeof(VideoCodec)); | 299 memset(&send_codec_, 0, sizeof(VideoCodec)); |
300 *was_send_codec = true; | 300 *was_send_codec = true; |
301 } | 301 } |
302 encoder_payload_type_ = 0; | 302 encoder_payload_type_ = 0; |
303 external_encoder_ = NULL; | 303 external_encoder_ = nullptr; |
304 internal_source_ = false; | 304 internal_source_ = false; |
305 return true; | 305 return true; |
306 } | 306 } |
307 | 307 |
308 void VCMCodecDataBase::RegisterExternalEncoder( | 308 void VCMCodecDataBase::RegisterExternalEncoder( |
309 VideoEncoder* external_encoder, | 309 VideoEncoder* external_encoder, |
310 uint8_t payload_type, | 310 uint8_t payload_type, |
311 bool internal_source) { | 311 bool internal_source) { |
312 // Since only one encoder can be used at a given time, only one external | 312 // Since only one encoder can be used at a given time, only one external |
313 // encoder can be registered/used. | 313 // encoder can be registered/used. |
314 external_encoder_ = external_encoder; | 314 external_encoder_ = external_encoder; |
315 encoder_payload_type_ = payload_type; | 315 encoder_payload_type_ = payload_type; |
316 internal_source_ = internal_source; | 316 internal_source_ = internal_source; |
317 pending_encoder_reset_ = true; | 317 pending_encoder_reset_ = true; |
318 } | 318 } |
319 | 319 |
320 bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) { | 320 bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) { |
321 if (ptr_encoder_ == NULL) { | 321 if (!ptr_encoder_) |
322 return true; | 322 return true; |
323 } | |
324 | 323 |
325 // Does not check startBitrate or maxFramerate | 324 // Does not check startBitrate or maxFramerate |
326 if (new_send_codec.codecType != send_codec_.codecType || | 325 if (new_send_codec.codecType != send_codec_.codecType || |
327 strcmp(new_send_codec.plName, send_codec_.plName) != 0 || | 326 strcmp(new_send_codec.plName, send_codec_.plName) != 0 || |
328 new_send_codec.plType != send_codec_.plType || | 327 new_send_codec.plType != send_codec_.plType || |
329 new_send_codec.width != send_codec_.width || | 328 new_send_codec.width != send_codec_.width || |
330 new_send_codec.height != send_codec_.height || | 329 new_send_codec.height != send_codec_.height || |
331 new_send_codec.maxBitrate != send_codec_.maxBitrate || | 330 new_send_codec.maxBitrate != send_codec_.maxBitrate || |
332 new_send_codec.minBitrate != send_codec_.minBitrate || | 331 new_send_codec.minBitrate != send_codec_.minBitrate || |
333 new_send_codec.qpMax != send_codec_.qpMax || | 332 new_send_codec.qpMax != send_codec_.qpMax || |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) { | 392 bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) { |
394 periodic_key_frames_ = enable; | 393 periodic_key_frames_ = enable; |
395 if (ptr_encoder_) { | 394 if (ptr_encoder_) { |
396 return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0); | 395 return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0); |
397 } | 396 } |
398 return true; | 397 return true; |
399 } | 398 } |
400 | 399 |
401 void VCMCodecDataBase::ResetReceiver() { | 400 void VCMCodecDataBase::ResetReceiver() { |
402 ReleaseDecoder(ptr_decoder_); | 401 ReleaseDecoder(ptr_decoder_); |
403 ptr_decoder_ = NULL; | 402 ptr_decoder_ = nullptr; |
404 memset(&receive_codec_, 0, sizeof(VideoCodec)); | 403 memset(&receive_codec_, 0, sizeof(VideoCodec)); |
405 while (!dec_map_.empty()) { | 404 while (!dec_map_.empty()) { |
406 DecoderMap::iterator it = dec_map_.begin(); | 405 DecoderMap::iterator it = dec_map_.begin(); |
407 delete (*it).second; | 406 delete (*it).second; |
408 dec_map_.erase(it); | 407 dec_map_.erase(it); |
409 } | 408 } |
410 while (!dec_external_map_.empty()) { | 409 while (!dec_external_map_.empty()) { |
411 ExternalDecoderMap::iterator external_it = dec_external_map_.begin(); | 410 ExternalDecoderMap::iterator external_it = dec_external_map_.begin(); |
412 delete (*external_it).second; | 411 delete (*external_it).second; |
413 dec_external_map_.erase(external_it); | 412 dec_external_map_.erase(external_it); |
414 } | 413 } |
415 } | 414 } |
416 | 415 |
417 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { | 416 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { |
418 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); | 417 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); |
419 if (it == dec_external_map_.end()) { | 418 if (it == dec_external_map_.end()) { |
420 // Not found | 419 // Not found |
421 return false; | 420 return false; |
422 } | 421 } |
423 // We can't use payload_type to check if the decoder is currently in use, | 422 // We can't use payload_type to check if the decoder is currently in use, |
424 // because payload type may be out of date (e.g. before we decode the first | 423 // because payload type may be out of date (e.g. before we decode the first |
425 // frame after RegisterReceiveCodec) | 424 // frame after RegisterReceiveCodec) |
426 if (ptr_decoder_ != NULL && | 425 if (ptr_decoder_ != nullptr && |
427 &ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { | 426 &ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { |
428 // Release it if it was registered and in use. | 427 // Release it if it was registered and in use. |
429 ReleaseDecoder(ptr_decoder_); | 428 ReleaseDecoder(ptr_decoder_); |
430 ptr_decoder_ = NULL; | 429 ptr_decoder_ = nullptr; |
431 } | 430 } |
432 DeregisterReceiveCodec(payload_type); | 431 DeregisterReceiveCodec(payload_type); |
433 delete (*it).second; | 432 delete (*it).second; |
434 dec_external_map_.erase(it); | 433 dec_external_map_.erase(it); |
435 return true; | 434 return true; |
436 } | 435 } |
437 | 436 |
438 // Add the external encoder object to the list of external decoders. | 437 // Add the external encoder object to the list of external decoders. |
439 // Won't be registered as a receive codec until RegisterReceiveCodec is called. | 438 // Won't be registered as a receive codec until RegisterReceiveCodec is called. |
440 bool VCMCodecDataBase::RegisterExternalDecoder( | 439 bool VCMCodecDataBase::RegisterExternalDecoder( |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 } | 500 } |
502 | 501 |
503 VideoCodecType VCMCodecDataBase::ReceiveCodec() const { | 502 VideoCodecType VCMCodecDataBase::ReceiveCodec() const { |
504 if (!ptr_decoder_) { | 503 if (!ptr_decoder_) { |
505 return kVideoCodecUnknown; | 504 return kVideoCodecUnknown; |
506 } | 505 } |
507 return receive_codec_.codecType; | 506 return receive_codec_.codecType; |
508 } | 507 } |
509 | 508 |
510 VCMGenericDecoder* VCMCodecDataBase::GetDecoder( | 509 VCMGenericDecoder* VCMCodecDataBase::GetDecoder( |
511 uint8_t payload_type, VCMDecodedFrameCallback* decoded_frame_callback) { | 510 const VCMEncodedFrame& frame, |
| 511 VCMDecodedFrameCallback* decoded_frame_callback) { |
| 512 uint8_t payload_type = frame.PayloadType(); |
512 if (payload_type == receive_codec_.plType || payload_type == 0) { | 513 if (payload_type == receive_codec_.plType || payload_type == 0) { |
513 return ptr_decoder_; | 514 return ptr_decoder_; |
514 } | 515 } |
515 // Check for exisitng decoder, if exists - delete. | 516 // Check for exisitng decoder, if exists - delete. |
516 if (ptr_decoder_) { | 517 if (ptr_decoder_) { |
517 ReleaseDecoder(ptr_decoder_); | 518 ReleaseDecoder(ptr_decoder_); |
518 ptr_decoder_ = NULL; | 519 ptr_decoder_ = nullptr; |
519 memset(&receive_codec_, 0, sizeof(VideoCodec)); | 520 memset(&receive_codec_, 0, sizeof(VideoCodec)); |
520 } | 521 } |
521 ptr_decoder_ = CreateAndInitDecoder(payload_type, &receive_codec_); | 522 ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_); |
522 if (!ptr_decoder_) { | 523 if (!ptr_decoder_) { |
523 return NULL; | 524 return nullptr; |
524 } | 525 } |
525 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback(); | 526 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback(); |
526 if (callback) callback->OnIncomingPayloadType(receive_codec_.plType); | 527 if (callback) callback->OnIncomingPayloadType(receive_codec_.plType); |
527 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) | 528 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) |
528 < 0) { | 529 < 0) { |
529 ReleaseDecoder(ptr_decoder_); | 530 ReleaseDecoder(ptr_decoder_); |
530 ptr_decoder_ = NULL; | 531 ptr_decoder_ = nullptr; |
531 memset(&receive_codec_, 0, sizeof(VideoCodec)); | 532 memset(&receive_codec_, 0, sizeof(VideoCodec)); |
532 return NULL; | 533 return nullptr; |
533 } | 534 } |
534 return ptr_decoder_; | 535 return ptr_decoder_; |
535 } | 536 } |
536 | 537 |
537 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { | 538 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { |
538 if (decoder) { | 539 if (decoder) { |
539 assert(&decoder->_decoder); | 540 assert(&decoder->_decoder); |
540 decoder->Release(); | 541 decoder->Release(); |
541 if (!decoder->External()) { | 542 if (!decoder->External()) { |
542 delete &decoder->_decoder; | 543 delete &decoder->_decoder; |
543 } | 544 } |
544 delete decoder; | 545 delete decoder; |
545 } | 546 } |
546 } | 547 } |
547 | 548 |
548 bool VCMCodecDataBase::SupportsRenderScheduling() const { | 549 bool VCMCodecDataBase::SupportsRenderScheduling() const { |
549 const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem( | 550 const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem( |
550 receive_codec_.plType); | 551 receive_codec_.plType); |
551 if (ext_item == nullptr) | 552 if (!ext_item) |
552 return true; | 553 return true; |
553 return ext_item->internal_render_timing; | 554 return ext_item->internal_render_timing; |
554 } | 555 } |
555 | 556 |
556 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { | 557 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { |
557 return send_codec_.width == width && send_codec_.height == height; | 558 return send_codec_.width == width && send_codec_.height == height; |
558 } | 559 } |
559 | 560 |
560 VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder( | 561 VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder( |
561 uint8_t payload_type, | 562 const VCMEncodedFrame& frame, |
562 VideoCodec* new_codec) const { | 563 VideoCodec* new_codec) const { |
| 564 uint8_t payload_type = frame.PayloadType(); |
563 assert(new_codec); | 565 assert(new_codec); |
564 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type); | 566 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type); |
565 if (!decoder_item) { | 567 if (!decoder_item) { |
566 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " | 568 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " |
567 << static_cast<int>(payload_type); | 569 << static_cast<int>(payload_type); |
568 return NULL; | 570 return nullptr; |
569 } | 571 } |
570 VCMGenericDecoder* ptr_decoder = NULL; | 572 VCMGenericDecoder* ptr_decoder = nullptr; |
571 const VCMExtDecoderMapItem* external_dec_item = | 573 const VCMExtDecoderMapItem* external_dec_item = |
572 FindExternalDecoderItem(payload_type); | 574 FindExternalDecoderItem(payload_type); |
573 if (external_dec_item) { | 575 if (external_dec_item) { |
574 // External codec. | 576 // External codec. |
575 ptr_decoder = new VCMGenericDecoder( | 577 ptr_decoder = new VCMGenericDecoder( |
576 *external_dec_item->external_decoder_instance, true); | 578 *external_dec_item->external_decoder_instance, true); |
577 } else { | 579 } else { |
578 // Create decoder. | 580 // Create decoder. |
579 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); | 581 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); |
580 } | 582 } |
581 if (!ptr_decoder) | 583 if (!ptr_decoder) |
582 return NULL; | 584 return nullptr; |
583 | 585 |
| 586 // Copy over input resolutions to prevent codec reinitialization due to |
| 587 // the first frame being of a different resolution than the database values. |
| 588 // This is best effort, since there's no guarantee that width/height have been |
| 589 // parsed yet (and may be zero). |
| 590 if (frame.EncodedImage()._encodedWidth > 0 && |
| 591 frame.EncodedImage()._encodedHeight > 0) { |
| 592 decoder_item->settings->width = frame.EncodedImage()._encodedWidth; |
| 593 decoder_item->settings->height = frame.EncodedImage()._encodedHeight; |
| 594 } |
584 if (ptr_decoder->InitDecode(decoder_item->settings.get(), | 595 if (ptr_decoder->InitDecode(decoder_item->settings.get(), |
585 decoder_item->number_of_cores) < 0) { | 596 decoder_item->number_of_cores) < 0) { |
586 ReleaseDecoder(ptr_decoder); | 597 ReleaseDecoder(ptr_decoder); |
587 return NULL; | 598 return nullptr; |
588 } | 599 } |
589 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); | 600 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); |
590 return ptr_decoder; | 601 return ptr_decoder; |
591 } | 602 } |
592 | 603 |
593 void VCMCodecDataBase::DeleteEncoder() { | 604 void VCMCodecDataBase::DeleteEncoder() { |
594 if (!ptr_encoder_) | 605 if (!ptr_encoder_) |
595 return; | 606 return; |
596 ptr_encoder_->Release(); | 607 ptr_encoder_->Release(); |
597 ptr_encoder_.reset(); | 608 ptr_encoder_.reset(); |
598 } | 609 } |
599 | 610 |
600 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const { | 611 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const { |
601 switch (type) { | 612 switch (type) { |
602 case kVideoCodecVP8: | 613 case kVideoCodecVP8: |
603 return new VCMGenericDecoder(*(VP8Decoder::Create())); | 614 return new VCMGenericDecoder(*(VP8Decoder::Create())); |
604 case kVideoCodecVP9: | 615 case kVideoCodecVP9: |
605 return new VCMGenericDecoder(*(VP9Decoder::Create())); | 616 return new VCMGenericDecoder(*(VP9Decoder::Create())); |
606 case kVideoCodecI420: | 617 case kVideoCodecI420: |
607 return new VCMGenericDecoder(*(new I420Decoder)); | 618 return new VCMGenericDecoder(*(new I420Decoder)); |
608 case kVideoCodecH264: | 619 case kVideoCodecH264: |
609 if (H264Decoder::IsSupported()) { | 620 if (H264Decoder::IsSupported()) { |
610 return new VCMGenericDecoder(*(H264Decoder::Create())); | 621 return new VCMGenericDecoder(*(H264Decoder::Create())); |
611 } | 622 } |
612 break; | 623 break; |
613 default: | 624 default: |
614 break; | 625 break; |
615 } | 626 } |
616 LOG(LS_WARNING) << "No internal decoder of this type exists."; | 627 LOG(LS_WARNING) << "No internal decoder of this type exists."; |
617 return NULL; | 628 return nullptr; |
618 } | 629 } |
619 | 630 |
620 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( | 631 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( |
621 uint8_t payload_type) const { | 632 uint8_t payload_type) const { |
622 DecoderMap::const_iterator it = dec_map_.find(payload_type); | 633 DecoderMap::const_iterator it = dec_map_.find(payload_type); |
623 if (it != dec_map_.end()) { | 634 if (it != dec_map_.end()) { |
624 return (*it).second; | 635 return (*it).second; |
625 } | 636 } |
626 return NULL; | 637 return nullptr; |
627 } | 638 } |
628 | 639 |
629 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( | 640 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( |
630 uint8_t payload_type) const { | 641 uint8_t payload_type) const { |
631 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); | 642 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); |
632 if (it != dec_external_map_.end()) { | 643 if (it != dec_external_map_.end()) { |
633 return (*it).second; | 644 return (*it).second; |
634 } | 645 } |
635 return NULL; | 646 return nullptr; |
636 } | 647 } |
637 } // namespace webrtc | 648 } // namespace webrtc |
OLD | NEW |