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

Unified Diff: talk/app/webrtc/java/jni/androidmediaencoder_jni.cc

Issue 1510913007: Send key frame if time difference between incoming frames exceeds a certain limit. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
diff --git a/talk/app/webrtc/java/jni/androidmediaencoder_jni.cc b/talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
index 7f558c0551b07e657d2163df58167a4734ecf06d..e87abaf5a5d5a74ce6063aba938b6af6214ac9c2 100644
--- a/talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
+++ b/talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
@@ -35,6 +35,7 @@
#include "webrtc/base/logging.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/thread_checker.h"
+#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/modules/video_coding/utility/quality_scaler.h"
@@ -91,6 +92,12 @@ namespace webrtc_jni {
#define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_ENCODER)
#define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER)
+namespace {
+// Maximum time limit between incoming frames before requesting a key frame.
+const size_t kFrameDiffThresholdMs = 1100;
+const int kMinKeyFrameInterval = 2;
+} // namespace
+
// MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses
// Android's MediaCodec SDK API behind the scenes to implement (hopefully)
// HW-backed video encode. This C++ class is implemented as a very thin shim,
@@ -259,6 +266,13 @@ class MediaCodecVideoEncoder : public webrtc::VideoEncoder,
// EGL context - owned by factory, should not be allocated/destroyed
// by MediaCodecVideoEncoder.
jobject egl_context_;
+
+ // Temporary fix for VP8.
+ // Sends a key frame if frames are largely spaced apart (possibly
+ // corresponding to a large image change).
+ int64_t last_frame_received_ms_;
+ int frames_received_since_last_key_;
+ webrtc::VideoCodecMode codec_mode_;
};
MediaCodecVideoEncoder::~MediaCodecVideoEncoder() {
@@ -360,6 +374,7 @@ int32_t MediaCodecVideoEncoder::InitEncode(
<< codecType_;
ALOGD << "InitEncode request";
+ codec_mode_ = codec_settings->mode;
scale_ = (codecType_ != kVideoCodecVP9) && (webrtc::field_trial::FindFullName(
"WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled");
ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled");
@@ -518,6 +533,8 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread(
gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1);
tl0_pic_idx_ = static_cast<uint8_t>(rand());
gof_idx_ = 0;
+ last_frame_received_ms_ = -1;
+ frames_received_since_last_key_ = kMinKeyFrameInterval;
// We enforce no extra stride/padding in the format creation step.
jobject j_video_codec_enum = JavaEnumFromIndex(
@@ -585,6 +602,23 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
+ bool send_key_frame = false;
+ if (codecType_ == kVideoCodecVP8 && codec_mode_ == webrtc::kRealtimeVideo) {
+ ++frames_received_since_last_key_;
+ int64_t now_ms = GetCurrentTimeMs();
+ if (last_frame_received_ms_ != -1 &&
+ (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) {
+ // Add limit to prevent triggering a key for every frame for very low
+ // framerates (e.g. if frame diff > kFrameDiffThresholdMs).
+ if (frames_received_since_last_key_ > kMinKeyFrameInterval) {
+ ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_);
+ send_key_frame = true;
+ }
+ frames_received_since_last_key_ = 0;
+ }
+ last_frame_received_ms_ = now_ms;
+ }
+
frames_received_++;
if (!DeliverPendingOutputs(jni)) {
if (!ResetCodecOnCodecThread())
@@ -651,7 +685,8 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
// Save time when input frame is sent to the encoder input.
frame_rtc_times_ms_.push_back(GetCurrentTimeMs());
- const bool key_frame = frame_types->front() != webrtc::kVideoFrameDelta;
+ const bool key_frame =
+ frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame;
bool encode_status = true;
if (!input_frame.native_handle()) {
int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_,
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698