OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 if (!encoder_->inited_) { | 449 if (!encoder_->inited_) { |
450 encoder_->encode_task_ = std::unique_ptr<rtc::QueuedTask>(this); | 450 encoder_->encode_task_ = std::unique_ptr<rtc::QueuedTask>(this); |
451 return false; | 451 return false; |
452 } | 452 } |
453 | 453 |
454 // It would be nice to recover from a failure here if one happened, but it's | 454 // It would be nice to recover from a failure here if one happened, but it's |
455 // unclear how to signal such a failure to the app, so instead we stay silent | 455 // unclear how to signal such a failure to the app, so instead we stay silent |
456 // about it and let the next app-called API method reveal the borkedness. | 456 // about it and let the next app-called API method reveal the borkedness. |
457 encoder_->DeliverPendingOutputs(jni); | 457 encoder_->DeliverPendingOutputs(jni); |
458 | 458 |
| 459 if (!encoder_) { |
| 460 // Encoder can be destroyed in DeliverPendingOutputs. |
| 461 return true; |
| 462 } |
| 463 |
459 // Call log statistics here so it's called even if no frames are being | 464 // Call log statistics here so it's called even if no frames are being |
460 // delivered. | 465 // delivered. |
461 encoder_->LogStatistics(false); | 466 encoder_->LogStatistics(false); |
462 | 467 |
463 // If there aren't more frames to deliver, we can start polling at lower rate. | 468 // If there aren't more frames to deliver, we can start polling at lower rate. |
464 if (encoder_->input_frame_infos_.empty()) { | 469 if (encoder_->input_frame_infos_.empty()) { |
465 rtc::TaskQueue::Current()->PostDelayedTask( | 470 rtc::TaskQueue::Current()->PostDelayedTask( |
466 std::unique_ptr<rtc::QueuedTask>(this), kMediaCodecPollNoFramesMs); | 471 std::unique_ptr<rtc::QueuedTask>(this), kMediaCodecPollNoFramesMs); |
467 } else { | 472 } else { |
468 rtc::TaskQueue::Current()->PostDelayedTask( | 473 rtc::TaskQueue::Current()->PostDelayedTask( |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 output_render_time_ms_ = 0; | 543 output_render_time_ms_ = 0; |
539 input_frame_infos_.clear(); | 544 input_frame_infos_.clear(); |
540 drop_next_input_frame_ = false; | 545 drop_next_input_frame_ = false; |
541 use_surface_ = use_surface; | 546 use_surface_ = use_surface; |
542 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; | 547 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; |
543 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); | 548 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); |
544 tl0_pic_idx_ = static_cast<uint8_t>(rand()); | 549 tl0_pic_idx_ = static_cast<uint8_t>(rand()); |
545 gof_idx_ = 0; | 550 gof_idx_ = 0; |
546 last_frame_received_ms_ = -1; | 551 last_frame_received_ms_ = -1; |
547 frames_received_since_last_key_ = kMinKeyFrameInterval; | 552 frames_received_since_last_key_ = kMinKeyFrameInterval; |
548 weak_factory_.reset(new rtc::WeakPtrFactory<MediaCodecVideoEncoder>(this)); | |
549 encode_task_.reset(new EncodeTask(weak_factory_->GetWeakPtr())); | |
550 | 553 |
551 // We enforce no extra stride/padding in the format creation step. | 554 // We enforce no extra stride/padding in the format creation step. |
552 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( | 555 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( |
553 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); | 556 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); |
554 const bool encode_status = jni->CallBooleanMethod( | 557 const bool encode_status = jni->CallBooleanMethod( |
555 *j_media_codec_video_encoder_, j_init_encode_method_, | 558 *j_media_codec_video_encoder_, j_init_encode_method_, |
556 j_video_codec_enum, width, height, kbps, fps, | 559 j_video_codec_enum, width, height, kbps, fps, |
557 (use_surface ? egl_context_ : nullptr)); | 560 (use_surface ? egl_context_ : nullptr)); |
558 if (!encode_status) { | 561 if (!encode_status) { |
559 ALOGE << "Failed to configure encoder."; | 562 ALOGE << "Failed to configure encoder."; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 RTC_CHECK(yuv_buffer_capacity >= yuv_size_) << "Insufficient capacity"; | 616 RTC_CHECK(yuv_buffer_capacity >= yuv_size_) << "Insufficient capacity"; |
614 } | 617 } |
615 } | 618 } |
616 | 619 |
617 { | 620 { |
618 #if RTC_DCHECK_IS_ON | 621 #if RTC_DCHECK_IS_ON |
619 rtc::CritScope lock(&inited_crit_); | 622 rtc::CritScope lock(&inited_crit_); |
620 #endif | 623 #endif |
621 inited_ = true; | 624 inited_ = true; |
622 } | 625 } |
| 626 weak_factory_.reset(new rtc::WeakPtrFactory<MediaCodecVideoEncoder>(this)); |
| 627 encode_task_.reset(new EncodeTask(weak_factory_->GetWeakPtr())); |
| 628 |
623 return WEBRTC_VIDEO_CODEC_OK; | 629 return WEBRTC_VIDEO_CODEC_OK; |
624 } | 630 } |
625 | 631 |
626 int32_t MediaCodecVideoEncoder::Encode( | 632 int32_t MediaCodecVideoEncoder::Encode( |
627 const webrtc::VideoFrame& frame, | 633 const webrtc::VideoFrame& frame, |
628 const webrtc::CodecSpecificInfo* /* codec_specific_info */, | 634 const webrtc::CodecSpecificInfo* /* codec_specific_info */, |
629 const std::vector<webrtc::FrameType>* frame_types) { | 635 const std::vector<webrtc::FrameType>* frame_types) { |
630 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 636 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
631 if (sw_fallback_required_) | 637 if (sw_fallback_required_) |
632 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; | 638 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 | 883 |
878 int32_t MediaCodecVideoEncoder::Release() { | 884 int32_t MediaCodecVideoEncoder::Release() { |
879 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 885 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
880 if (!inited_) { | 886 if (!inited_) { |
881 return WEBRTC_VIDEO_CODEC_OK; | 887 return WEBRTC_VIDEO_CODEC_OK; |
882 } | 888 } |
883 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 889 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
884 ALOGD << "EncoderRelease: Frames received: " << frames_received_ | 890 ALOGD << "EncoderRelease: Frames received: " << frames_received_ |
885 << ". Encoded: " << frames_encoded_ | 891 << ". Encoded: " << frames_encoded_ |
886 << ". Dropped: " << frames_dropped_media_encoder_; | 892 << ". Dropped: " << frames_dropped_media_encoder_; |
| 893 encode_task_.reset(nullptr); |
| 894 weak_factory_.reset(nullptr); |
887 ScopedLocalRefFrame local_ref_frame(jni); | 895 ScopedLocalRefFrame local_ref_frame(jni); |
888 for (size_t i = 0; i < input_buffers_.size(); ++i) | 896 for (size_t i = 0; i < input_buffers_.size(); ++i) |
889 jni->DeleteGlobalRef(input_buffers_[i]); | 897 jni->DeleteGlobalRef(input_buffers_[i]); |
890 input_buffers_.clear(); | 898 input_buffers_.clear(); |
891 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); | 899 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); |
892 if (CheckException(jni)) { | 900 if (CheckException(jni)) { |
893 ALOGE << "Exception in release."; | 901 ALOGE << "Exception in release."; |
894 ProcessHWError(false /* reset_if_fallback_unavailable */); | 902 ProcessHWError(false /* reset_if_fallback_unavailable */); |
895 return WEBRTC_VIDEO_CODEC_ERROR; | 903 return WEBRTC_VIDEO_CODEC_ERROR; |
896 } | 904 } |
897 { | 905 { |
898 #if RTC_DCHECK_IS_ON | 906 #if RTC_DCHECK_IS_ON |
899 rtc::CritScope lock(&inited_crit_); | 907 rtc::CritScope lock(&inited_crit_); |
900 #endif | 908 #endif |
901 inited_ = false; | 909 inited_ = false; |
902 } | 910 } |
903 use_surface_ = false; | 911 use_surface_ = false; |
904 encode_task_.reset(nullptr); | |
905 weak_factory_.reset(nullptr); | |
906 ALOGD << "EncoderRelease done."; | 912 ALOGD << "EncoderRelease done."; |
907 return WEBRTC_VIDEO_CODEC_OK; | 913 return WEBRTC_VIDEO_CODEC_OK; |
908 } | 914 } |
909 | 915 |
910 int32_t MediaCodecVideoEncoder::SetRateAllocation( | 916 int32_t MediaCodecVideoEncoder::SetRateAllocation( |
911 const webrtc::BitrateAllocation& rate_allocation, | 917 const webrtc::BitrateAllocation& rate_allocation, |
912 uint32_t frame_rate) { | 918 uint32_t frame_rate) { |
913 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 919 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
914 const uint32_t new_bit_rate = rate_allocation.get_sum_kbps(); | 920 const uint32_t new_bit_rate = rate_allocation.get_sum_kbps(); |
915 if (sw_fallback_required_) | 921 if (sw_fallback_required_) |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 } | 1311 } |
1306 } | 1312 } |
1307 | 1313 |
1308 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 1314 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( |
1309 webrtc::VideoEncoder* encoder) { | 1315 webrtc::VideoEncoder* encoder) { |
1310 ALOGD << "Destroy video encoder."; | 1316 ALOGD << "Destroy video encoder."; |
1311 delete encoder; | 1317 delete encoder; |
1312 } | 1318 } |
1313 | 1319 |
1314 } // namespace webrtc_jni | 1320 } // namespace webrtc_jni |
OLD | NEW |