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 |
11 // NOTICE: androidmediaencoder_jni.h must be included before | 11 // NOTICE: androidmediaencoder_jni.h must be included before |
12 // androidmediacodeccommon.h to avoid build errors. | 12 // androidmediacodeccommon.h to avoid build errors. |
13 #include "webrtc/api/java/jni/androidmediaencoder_jni.h" | 13 #include "webrtc/api/java/jni/androidmediaencoder_jni.h" |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <memory> | 16 #include <memory> |
17 #include <list> | 17 #include <list> |
18 | 18 |
19 #include "third_party/libyuv/include/libyuv/convert.h" | 19 #include "third_party/libyuv/include/libyuv/convert.h" |
20 #include "third_party/libyuv/include/libyuv/convert_from.h" | 20 #include "third_party/libyuv/include/libyuv/convert_from.h" |
21 #include "third_party/libyuv/include/libyuv/video_common.h" | 21 #include "third_party/libyuv/include/libyuv/video_common.h" |
22 #include "webrtc/api/java/jni/androidmediacodeccommon.h" | 22 #include "webrtc/api/java/jni/androidmediacodeccommon.h" |
23 #include "webrtc/api/java/jni/classreferenceholder.h" | 23 #include "webrtc/api/java/jni/classreferenceholder.h" |
24 #include "webrtc/api/java/jni/native_handle_impl.h" | 24 #include "webrtc/api/java/jni/native_handle_impl.h" |
25 #include "webrtc/base/bind.h" | 25 #include "webrtc/base/bind.h" |
26 #include "webrtc/base/checks.h" | 26 #include "webrtc/base/checks.h" |
27 #include "webrtc/base/logging.h" | 27 #include "webrtc/base/logging.h" |
28 #include "webrtc/base/thread.h" | 28 #include "webrtc/base/thread.h" |
29 #include "webrtc/base/thread_checker.h" | 29 #include "webrtc/base/thread_checker.h" |
| 30 #include "webrtc/base/timeutils.h" |
30 #include "webrtc/common_types.h" | 31 #include "webrtc/common_types.h" |
31 #include "webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h" | 32 #include "webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h" |
32 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 33 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
33 #include "webrtc/modules/video_coding/utility/quality_scaler.h" | 34 #include "webrtc/modules/video_coding/utility/quality_scaler.h" |
34 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" | 35 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" |
35 #include "webrtc/system_wrappers/include/field_trial.h" | 36 #include "webrtc/system_wrappers/include/field_trial.h" |
36 #include "webrtc/system_wrappers/include/logcat_trace_context.h" | 37 #include "webrtc/system_wrappers/include/logcat_trace_context.h" |
37 | 38 |
38 using rtc::Bind; | 39 using rtc::Bind; |
39 using rtc::Thread; | 40 using rtc::Thread; |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 width_ = width; | 518 width_ = width; |
518 height_ = height; | 519 height_ = height; |
519 last_set_bitrate_kbps_ = kbps; | 520 last_set_bitrate_kbps_ = kbps; |
520 last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS; | 521 last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS; |
521 yuv_size_ = width_ * height_ * 3 / 2; | 522 yuv_size_ = width_ * height_ * 3 / 2; |
522 frames_received_ = 0; | 523 frames_received_ = 0; |
523 frames_encoded_ = 0; | 524 frames_encoded_ = 0; |
524 frames_dropped_media_encoder_ = 0; | 525 frames_dropped_media_encoder_ = 0; |
525 consecutive_full_queue_frame_drops_ = 0; | 526 consecutive_full_queue_frame_drops_ = 0; |
526 current_timestamp_us_ = 0; | 527 current_timestamp_us_ = 0; |
527 stat_start_time_ms_ = GetCurrentTimeMs(); | 528 stat_start_time_ms_ = rtc::TimeMillis(); |
528 current_frames_ = 0; | 529 current_frames_ = 0; |
529 current_bytes_ = 0; | 530 current_bytes_ = 0; |
530 current_acc_qp_ = 0; | 531 current_acc_qp_ = 0; |
531 current_encoding_time_ms_ = 0; | 532 current_encoding_time_ms_ = 0; |
532 last_input_timestamp_ms_ = -1; | 533 last_input_timestamp_ms_ = -1; |
533 last_output_timestamp_ms_ = -1; | 534 last_output_timestamp_ms_ = -1; |
534 output_timestamp_ = 0; | 535 output_timestamp_ = 0; |
535 output_render_time_ms_ = 0; | 536 output_render_time_ms_ = 0; |
536 input_frame_infos_.clear(); | 537 input_frame_infos_.clear(); |
537 drop_next_input_frame_ = false; | 538 drop_next_input_frame_ = false; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 606 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
606 ScopedLocalRefFrame local_ref_frame(jni); | 607 ScopedLocalRefFrame local_ref_frame(jni); |
607 | 608 |
608 if (!inited_) { | 609 if (!inited_) { |
609 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 610 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
610 } | 611 } |
611 | 612 |
612 bool send_key_frame = false; | 613 bool send_key_frame = false; |
613 if (codec_mode_ == webrtc::kRealtimeVideo) { | 614 if (codec_mode_ == webrtc::kRealtimeVideo) { |
614 ++frames_received_since_last_key_; | 615 ++frames_received_since_last_key_; |
615 int64_t now_ms = GetCurrentTimeMs(); | 616 int64_t now_ms = rtc::TimeMillis(); |
616 if (last_frame_received_ms_ != -1 && | 617 if (last_frame_received_ms_ != -1 && |
617 (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) { | 618 (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) { |
618 // Add limit to prevent triggering a key for every frame for very low | 619 // Add limit to prevent triggering a key for every frame for very low |
619 // framerates (e.g. if frame diff > kFrameDiffThresholdMs). | 620 // framerates (e.g. if frame diff > kFrameDiffThresholdMs). |
620 if (frames_received_since_last_key_ > kMinKeyFrameInterval) { | 621 if (frames_received_since_last_key_ > kMinKeyFrameInterval) { |
621 ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_); | 622 ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_); |
622 send_key_frame = true; | 623 send_key_frame = true; |
623 } | 624 } |
624 frames_received_since_last_key_ = 0; | 625 frames_received_since_last_key_ = 0; |
625 } | 626 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 input_frame = quality_scaler_.GetScaledFrame(frame); | 692 input_frame = quality_scaler_.GetScaledFrame(frame); |
692 } | 693 } |
693 } | 694 } |
694 } | 695 } |
695 | 696 |
696 if (!MaybeReconfigureEncoderOnCodecThread(input_frame)) { | 697 if (!MaybeReconfigureEncoderOnCodecThread(input_frame)) { |
697 ALOGE << "Failed to reconfigure encoder."; | 698 ALOGE << "Failed to reconfigure encoder."; |
698 return WEBRTC_VIDEO_CODEC_ERROR; | 699 return WEBRTC_VIDEO_CODEC_ERROR; |
699 } | 700 } |
700 | 701 |
701 const int64_t time_before_calling_encode = GetCurrentTimeMs(); | 702 const int64_t time_before_calling_encode = rtc::TimeMillis(); |
702 const bool key_frame = | 703 const bool key_frame = |
703 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame; | 704 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame; |
704 bool encode_status = true; | 705 bool encode_status = true; |
705 if (!input_frame.video_frame_buffer()->native_handle()) { | 706 if (!input_frame.video_frame_buffer()->native_handle()) { |
706 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, | 707 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, |
707 j_dequeue_input_buffer_method_); | 708 j_dequeue_input_buffer_method_); |
708 CHECK_EXCEPTION(jni); | 709 CHECK_EXCEPTION(jni); |
709 if (j_input_buffer_index == -1) { | 710 if (j_input_buffer_index == -1) { |
710 // Video codec falls behind - no input buffer available. | 711 // Video codec falls behind - no input buffer available. |
711 ALOGW << "Encoder drop frame - no input buffers available"; | 712 ALOGW << "Encoder drop frame - no input buffers available"; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 int64_t frame_encoding_time_ms = 0; | 944 int64_t frame_encoding_time_ms = 0; |
944 last_output_timestamp_ms_ = | 945 last_output_timestamp_ms_ = |
945 GetOutputBufferInfoPresentationTimestampUs(jni, j_output_buffer_info) / | 946 GetOutputBufferInfoPresentationTimestampUs(jni, j_output_buffer_info) / |
946 1000; | 947 1000; |
947 if (!input_frame_infos_.empty()) { | 948 if (!input_frame_infos_.empty()) { |
948 const InputFrameInfo& frame_info = input_frame_infos_.front(); | 949 const InputFrameInfo& frame_info = input_frame_infos_.front(); |
949 output_timestamp_ = frame_info.frame_timestamp; | 950 output_timestamp_ = frame_info.frame_timestamp; |
950 output_render_time_ms_ = frame_info.frame_render_time_ms; | 951 output_render_time_ms_ = frame_info.frame_render_time_ms; |
951 output_rotation_ = frame_info.rotation; | 952 output_rotation_ = frame_info.rotation; |
952 frame_encoding_time_ms = | 953 frame_encoding_time_ms = |
953 GetCurrentTimeMs() - frame_info.encode_start_time; | 954 rtc::TimeMillis() - frame_info.encode_start_time; |
954 input_frame_infos_.pop_front(); | 955 input_frame_infos_.pop_front(); |
955 } | 956 } |
956 | 957 |
957 // Extract payload. | 958 // Extract payload. |
958 size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer); | 959 size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer); |
959 uint8_t* payload = reinterpret_cast<uint8_t*>( | 960 uint8_t* payload = reinterpret_cast<uint8_t*>( |
960 jni->GetDirectBufferAddress(j_output_buffer)); | 961 jni->GetDirectBufferAddress(j_output_buffer)); |
961 CHECK_EXCEPTION(jni); | 962 CHECK_EXCEPTION(jni); |
962 | 963 |
963 if (frames_encoded_ < kMaxEncodedLogFrames) { | 964 if (frames_encoded_ < kMaxEncodedLogFrames) { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 if (callback_status > 0) { | 1107 if (callback_status > 0) { |
1107 drop_next_input_frame_ = true; | 1108 drop_next_input_frame_ = true; |
1108 // Theoretically could handle callback_status<0 here, but unclear what | 1109 // Theoretically could handle callback_status<0 here, but unclear what |
1109 // that would mean for us. | 1110 // that would mean for us. |
1110 } | 1111 } |
1111 } | 1112 } |
1112 return true; | 1113 return true; |
1113 } | 1114 } |
1114 | 1115 |
1115 void MediaCodecVideoEncoder::LogStatistics(bool force_log) { | 1116 void MediaCodecVideoEncoder::LogStatistics(bool force_log) { |
1116 int statistic_time_ms = GetCurrentTimeMs() - stat_start_time_ms_; | 1117 int statistic_time_ms = rtc::TimeMillis() - stat_start_time_ms_; |
1117 if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log) && | 1118 if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log) && |
1118 current_frames_ > 0 && statistic_time_ms > 0) { | 1119 current_frames_ > 0 && statistic_time_ms > 0) { |
1119 int current_bitrate = current_bytes_ * 8 / statistic_time_ms; | 1120 int current_bitrate = current_bytes_ * 8 / statistic_time_ms; |
1120 int current_fps = | 1121 int current_fps = |
1121 (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms; | 1122 (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms; |
1122 ALOGD << "Encoded frames: " << frames_encoded_ << | 1123 ALOGD << "Encoded frames: " << frames_encoded_ << |
1123 ". Bitrate: " << current_bitrate << | 1124 ". Bitrate: " << current_bitrate << |
1124 ", target: " << last_set_bitrate_kbps_ << " kbps" << | 1125 ", target: " << last_set_bitrate_kbps_ << " kbps" << |
1125 ", fps: " << current_fps << | 1126 ", fps: " << current_fps << |
1126 ", encTime: " << (current_encoding_time_ms_ / current_frames_) << | 1127 ", encTime: " << (current_encoding_time_ms_ / current_frames_) << |
1127 ". QP: " << (current_acc_qp_ / current_frames_) << | 1128 ". QP: " << (current_acc_qp_ / current_frames_) << |
1128 " for last " << statistic_time_ms << " ms."; | 1129 " for last " << statistic_time_ms << " ms."; |
1129 stat_start_time_ms_ = GetCurrentTimeMs(); | 1130 stat_start_time_ms_ = rtc::TimeMillis(); |
1130 current_frames_ = 0; | 1131 current_frames_ = 0; |
1131 current_bytes_ = 0; | 1132 current_bytes_ = 0; |
1132 current_acc_qp_ = 0; | 1133 current_acc_qp_ = 0; |
1133 current_encoding_time_ms_ = 0; | 1134 current_encoding_time_ms_ = 0; |
1134 } | 1135 } |
1135 } | 1136 } |
1136 | 1137 |
1137 int32_t MediaCodecVideoEncoder::NextNaluPosition( | 1138 int32_t MediaCodecVideoEncoder::NextNaluPosition( |
1138 uint8_t *buffer, size_t buffer_size) { | 1139 uint8_t *buffer, size_t buffer_size) { |
1139 if (buffer_size < H264_SC_LENGTH) { | 1140 if (buffer_size < H264_SC_LENGTH) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 return supported_codecs_; | 1269 return supported_codecs_; |
1269 } | 1270 } |
1270 | 1271 |
1271 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 1272 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( |
1272 webrtc::VideoEncoder* encoder) { | 1273 webrtc::VideoEncoder* encoder) { |
1273 ALOGD << "Destroy video encoder."; | 1274 ALOGD << "Destroy video encoder."; |
1274 delete encoder; | 1275 delete encoder; |
1275 } | 1276 } |
1276 | 1277 |
1277 } // namespace webrtc_jni | 1278 } // namespace webrtc_jni |
OLD | NEW |