| 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 |