Add QP statistics logging to Android HW encoder.
- Similar to HW decoder log timing for first 5 frames of HW encoder input and output to track correct encoder start. - Increment input timestamp when frame is dropped. - Better calculate average encoding time. - Use different tags for encoder and decoder modules. BUG=b/26504665 Review URL: https://codereview.webrtc.org/1587943004 Cr-Commit-Position: refs/heads/master@{#11277}
This commit is contained in:
@ -41,15 +41,7 @@ namespace webrtc_jni {
|
|||||||
// video frame.
|
// video frame.
|
||||||
//#define TRACK_BUFFER_TIMING
|
//#define TRACK_BUFFER_TIMING
|
||||||
|
|
||||||
#define TAG "MediaCodecVideo"
|
#define TAG_COMMON "MediaCodecVideo"
|
||||||
#ifdef TRACK_BUFFER_TIMING
|
|
||||||
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define ALOGV(...)
|
|
||||||
#endif
|
|
||||||
#define ALOGD LOG_TAG(rtc::LS_INFO, TAG)
|
|
||||||
#define ALOGW LOG_TAG(rtc::LS_WARNING, TAG)
|
|
||||||
#define ALOGE LOG_TAG(rtc::LS_ERROR, TAG)
|
|
||||||
|
|
||||||
// Color formats supported by encoder - should mirror supportedColorList
|
// Color formats supported by encoder - should mirror supportedColorList
|
||||||
// from MediaCodecVideoEncoder.java
|
// from MediaCodecVideoEncoder.java
|
||||||
@ -78,6 +70,8 @@ enum { kMaxPendingFramesVp9 = 1 };
|
|||||||
enum { kMaxPendingFramesH264 = 30 };
|
enum { kMaxPendingFramesH264 = 30 };
|
||||||
// Maximum amount of decoded frames for which per-frame logging is enabled.
|
// Maximum amount of decoded frames for which per-frame logging is enabled.
|
||||||
enum { kMaxDecodedLogFrames = 5 };
|
enum { kMaxDecodedLogFrames = 5 };
|
||||||
|
// Maximum amount of encoded frames for which per-frame logging is enabled.
|
||||||
|
enum { kMaxEncodedLogFrames = 5 };
|
||||||
|
|
||||||
static inline int64_t GetCurrentTimeMs() {
|
static inline int64_t GetCurrentTimeMs() {
|
||||||
return webrtc::TickTime::Now().Ticks() / 1000000LL;
|
return webrtc::TickTime::Now().Ticks() / 1000000LL;
|
||||||
@ -102,7 +96,7 @@ static inline jobject JavaEnumFromIndex(
|
|||||||
// currently thrown exception.
|
// currently thrown exception.
|
||||||
static inline bool CheckException(JNIEnv* jni) {
|
static inline bool CheckException(JNIEnv* jni) {
|
||||||
if (jni->ExceptionCheck()) {
|
if (jni->ExceptionCheck()) {
|
||||||
ALOGE << "Java JNI exception.";
|
LOG_TAG(rtc::LS_ERROR, TAG_COMMON) << "Java JNI exception.";
|
||||||
jni->ExceptionDescribe();
|
jni->ExceptionDescribe();
|
||||||
jni->ExceptionClear();
|
jni->ExceptionClear();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -67,6 +67,18 @@ using webrtc::kVideoCodecVP9;
|
|||||||
|
|
||||||
namespace webrtc_jni {
|
namespace webrtc_jni {
|
||||||
|
|
||||||
|
// Logging macros.
|
||||||
|
#define TAG_DECODER "MediaCodecVideoDecoder"
|
||||||
|
#ifdef TRACK_BUFFER_TIMING
|
||||||
|
#define ALOGV(...)
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, TAG_DECODER, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define ALOGV(...)
|
||||||
|
#endif
|
||||||
|
#define ALOGD LOG_TAG(rtc::LS_INFO, TAG_DECODER)
|
||||||
|
#define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_DECODER)
|
||||||
|
#define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_DECODER)
|
||||||
|
|
||||||
class MediaCodecVideoDecoder : public webrtc::VideoDecoder,
|
class MediaCodecVideoDecoder : public webrtc::VideoDecoder,
|
||||||
public rtc::MessageHandler {
|
public rtc::MessageHandler {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -71,6 +71,25 @@ namespace webrtc_jni {
|
|||||||
#define MAX_VIDEO_HEIGHT 1280
|
#define MAX_VIDEO_HEIGHT 1280
|
||||||
// Maximum supported HW video encoder fps.
|
// Maximum supported HW video encoder fps.
|
||||||
#define MAX_VIDEO_FPS 30
|
#define MAX_VIDEO_FPS 30
|
||||||
|
// Maximum allowed fps value in SetRates() call.
|
||||||
|
#define MAX_ALLOWED_VIDEO_FPS 60
|
||||||
|
// Maximum allowed frames in encoder input queue.
|
||||||
|
#define MAX_ENCODER_Q_SIZE 2
|
||||||
|
// Maximum allowed latency in ms.
|
||||||
|
#define MAX_ENCODER_LATENCY_MS 70
|
||||||
|
|
||||||
|
|
||||||
|
// Logging macros.
|
||||||
|
#define TAG_ENCODER "MediaCodecVideoEncoder"
|
||||||
|
#ifdef TRACK_BUFFER_TIMING
|
||||||
|
#define ALOGV(...)
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, TAG_ENCODER, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define ALOGV(...)
|
||||||
|
#endif
|
||||||
|
#define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER)
|
||||||
|
#define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_ENCODER)
|
||||||
|
#define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER)
|
||||||
|
|
||||||
// MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses
|
// MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses
|
||||||
// Android's MediaCodec SDK API behind the scenes to implement (hopefully)
|
// Android's MediaCodec SDK API behind the scenes to implement (hopefully)
|
||||||
@ -206,6 +225,7 @@ class MediaCodecVideoEncoder : public webrtc::VideoEncoder,
|
|||||||
int64_t start_time_ms_; // Start time for statistics.
|
int64_t start_time_ms_; // Start time for statistics.
|
||||||
int current_frames_; // Number of frames in the current statistics interval.
|
int current_frames_; // Number of frames in the current statistics interval.
|
||||||
int current_bytes_; // Encoded bytes in the current statistics interval.
|
int current_bytes_; // Encoded bytes in the current statistics interval.
|
||||||
|
int current_acc_qp_; // Accumulated QP in the current statistics interval.
|
||||||
int current_encoding_time_ms_; // Overall encoding time in the current second
|
int current_encoding_time_ms_; // Overall encoding time in the current second
|
||||||
int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame.
|
int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame.
|
||||||
int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame.
|
int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame.
|
||||||
@ -467,13 +487,13 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread(
|
|||||||
kbps = last_set_bitrate_kbps_;
|
kbps = last_set_bitrate_kbps_;
|
||||||
}
|
}
|
||||||
if (fps == 0) {
|
if (fps == 0) {
|
||||||
fps = last_set_fps_;
|
fps = MAX_VIDEO_FPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
width_ = width;
|
width_ = width;
|
||||||
height_ = height;
|
height_ = height;
|
||||||
last_set_bitrate_kbps_ = kbps;
|
last_set_bitrate_kbps_ = kbps;
|
||||||
last_set_fps_ = fps;
|
last_set_fps_ = (fps < MAX_VIDEO_FPS) ? fps : MAX_VIDEO_FPS;
|
||||||
yuv_size_ = width_ * height_ * 3 / 2;
|
yuv_size_ = width_ * height_ * 3 / 2;
|
||||||
frames_received_ = 0;
|
frames_received_ = 0;
|
||||||
frames_encoded_ = 0;
|
frames_encoded_ = 0;
|
||||||
@ -483,6 +503,7 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread(
|
|||||||
start_time_ms_ = GetCurrentTimeMs();
|
start_time_ms_ = GetCurrentTimeMs();
|
||||||
current_frames_ = 0;
|
current_frames_ = 0;
|
||||||
current_bytes_ = 0;
|
current_bytes_ = 0;
|
||||||
|
current_acc_qp_ = 0;
|
||||||
current_encoding_time_ms_ = 0;
|
current_encoding_time_ms_ = 0;
|
||||||
last_input_timestamp_ms_ = -1;
|
last_input_timestamp_ms_ = -1;
|
||||||
last_output_timestamp_ms_ = -1;
|
last_output_timestamp_ms_ = -1;
|
||||||
@ -569,15 +590,37 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
|
|||||||
if (!ResetCodecOnCodecThread())
|
if (!ResetCodecOnCodecThread())
|
||||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
}
|
}
|
||||||
|
if (frames_encoded_ < kMaxEncodedLogFrames) {
|
||||||
|
ALOGD << "Encoder frame in # " << (frames_received_ - 1) << ". TS: " <<
|
||||||
|
(int)(current_timestamp_us_ / 1000) << ". Q: " << frames_in_queue_ <<
|
||||||
|
". Fps: " << last_set_fps_ << ". Kbps: " << last_set_bitrate_kbps_;
|
||||||
|
}
|
||||||
|
|
||||||
if (drop_next_input_frame_) {
|
if (drop_next_input_frame_) {
|
||||||
ALOGW << "Encoder drop frame - failed callback.";
|
ALOGW << "Encoder drop frame - failed callback.";
|
||||||
drop_next_input_frame_ = false;
|
drop_next_input_frame_ = false;
|
||||||
|
current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
|
||||||
|
OnDroppedFrame();
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";
|
RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";
|
||||||
|
|
||||||
|
// Check if we accumulated too many frames in encoder input buffers
|
||||||
|
// or the encoder latency exceeds 70 ms and drop frame if so.
|
||||||
|
if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) {
|
||||||
|
int encoder_latency_ms = last_input_timestamp_ms_ -
|
||||||
|
last_output_timestamp_ms_;
|
||||||
|
if (frames_in_queue_ > MAX_ENCODER_Q_SIZE ||
|
||||||
|
encoder_latency_ms > MAX_ENCODER_LATENCY_MS) {
|
||||||
|
ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms <<
|
||||||
|
" ms. Q size: " << frames_in_queue_;
|
||||||
|
current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
|
||||||
|
OnDroppedFrame();
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VideoFrame input_frame = frame;
|
VideoFrame input_frame = frame;
|
||||||
if (scale_) {
|
if (scale_) {
|
||||||
// Check framerate before spatial resolution change.
|
// Check framerate before spatial resolution change.
|
||||||
@ -605,20 +648,8 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
|
|||||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we accumulated too many frames in encoder input buffers
|
// Save time when input frame is sent to the encoder input.
|
||||||
// or the encoder latency exceeds 70 ms and drop frame if so.
|
frame_rtc_times_ms_.push_back(GetCurrentTimeMs());
|
||||||
if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) {
|
|
||||||
int encoder_latency_ms = last_input_timestamp_ms_ -
|
|
||||||
last_output_timestamp_ms_;
|
|
||||||
if (frames_in_queue_ > 2 || encoder_latency_ms > 70) {
|
|
||||||
ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms <<
|
|
||||||
" ms. Q size: " << frames_in_queue_;
|
|
||||||
frames_dropped_++;
|
|
||||||
// Report dropped frame to quality_scaler_.
|
|
||||||
OnDroppedFrame();
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool key_frame = frame_types->front() != webrtc::kVideoFrameDelta;
|
const bool key_frame = frame_types->front() != webrtc::kVideoFrameDelta;
|
||||||
bool encode_status = true;
|
bool encode_status = true;
|
||||||
@ -629,9 +660,8 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
|
|||||||
if (j_input_buffer_index == -1) {
|
if (j_input_buffer_index == -1) {
|
||||||
// Video codec falls behind - no input buffer available.
|
// Video codec falls behind - no input buffer available.
|
||||||
ALOGW << "Encoder drop frame - no input buffers available";
|
ALOGW << "Encoder drop frame - no input buffers available";
|
||||||
frames_dropped_++;
|
current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
|
||||||
// Report dropped frame to quality_scaler_.
|
frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin());
|
||||||
OnDroppedFrame();
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887.
|
return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887.
|
||||||
}
|
}
|
||||||
if (j_input_buffer_index == -2) {
|
if (j_input_buffer_index == -2) {
|
||||||
@ -657,7 +687,6 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
|
|||||||
// Save input image timestamps for later output
|
// Save input image timestamps for later output
|
||||||
timestamps_.push_back(input_frame.timestamp());
|
timestamps_.push_back(input_frame.timestamp());
|
||||||
render_times_ms_.push_back(input_frame.render_time_ms());
|
render_times_ms_.push_back(input_frame.render_time_ms());
|
||||||
frame_rtc_times_ms_.push_back(GetCurrentTimeMs());
|
|
||||||
current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
|
current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
|
||||||
|
|
||||||
if (!DeliverPendingOutputs(jni)) {
|
if (!DeliverPendingOutputs(jni)) {
|
||||||
@ -705,9 +734,6 @@ bool MediaCodecVideoEncoder::EncodeByteBufferOnCodecThread(JNIEnv* jni,
|
|||||||
RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
|
RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
|
||||||
RTC_CHECK(!use_surface_);
|
RTC_CHECK(!use_surface_);
|
||||||
|
|
||||||
ALOGV("Encoder frame in # %d. TS: %lld. Q: %d",
|
|
||||||
frames_received_ - 1, current_timestamp_us_ / 1000, frames_in_queue_);
|
|
||||||
|
|
||||||
jobject j_input_buffer = input_buffers_[input_buffer_index];
|
jobject j_input_buffer = input_buffers_[input_buffer_index];
|
||||||
uint8_t* yuv_buffer =
|
uint8_t* yuv_buffer =
|
||||||
reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer));
|
reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer));
|
||||||
@ -783,6 +809,8 @@ int32_t MediaCodecVideoEncoder::ReleaseOnCodecThread() {
|
|||||||
int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate,
|
int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate,
|
||||||
uint32_t frame_rate) {
|
uint32_t frame_rate) {
|
||||||
RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
|
RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
|
||||||
|
frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ?
|
||||||
|
frame_rate : MAX_ALLOWED_VIDEO_FPS;
|
||||||
if (last_set_bitrate_kbps_ == new_bit_rate &&
|
if (last_set_bitrate_kbps_ == new_bit_rate &&
|
||||||
last_set_fps_ == frame_rate) {
|
last_set_fps_ == frame_rate) {
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
@ -875,32 +903,12 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
|||||||
jni->GetDirectBufferAddress(j_output_buffer));
|
jni->GetDirectBufferAddress(j_output_buffer));
|
||||||
CHECK_EXCEPTION(jni);
|
CHECK_EXCEPTION(jni);
|
||||||
|
|
||||||
ALOGV("Encoder frame out # %d. Key: %d. Size: %d. TS: %lld."
|
if (frames_encoded_ < kMaxEncodedLogFrames) {
|
||||||
" Latency: %lld. EncTime: %lld",
|
ALOGD << "Encoder frame out # " << frames_encoded_ << ". Key: " <<
|
||||||
frames_encoded_, key_frame, payload_size,
|
key_frame << ". Size: " << payload_size << ". TS: " <<
|
||||||
last_output_timestamp_ms_,
|
(int)last_output_timestamp_ms_ << ". Latency: " <<
|
||||||
last_input_timestamp_ms_ - last_output_timestamp_ms_,
|
(int)(last_input_timestamp_ms_ - last_output_timestamp_ms_) <<
|
||||||
frame_encoding_time_ms);
|
". EncTime: " << frame_encoding_time_ms;
|
||||||
|
|
||||||
// Calculate and print encoding statistics - every 3 seconds.
|
|
||||||
frames_encoded_++;
|
|
||||||
current_frames_++;
|
|
||||||
current_bytes_ += payload_size;
|
|
||||||
current_encoding_time_ms_ += frame_encoding_time_ms;
|
|
||||||
int statistic_time_ms = GetCurrentTimeMs() - start_time_ms_;
|
|
||||||
if (statistic_time_ms >= kMediaCodecStatisticsIntervalMs &&
|
|
||||||
current_frames_ > 0) {
|
|
||||||
ALOGD << "Encoded frames: " << frames_encoded_ << ". Bitrate: " <<
|
|
||||||
(current_bytes_ * 8 / statistic_time_ms) <<
|
|
||||||
", target: " << last_set_bitrate_kbps_ << " kbps, fps: " <<
|
|
||||||
((current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms)
|
|
||||||
<< ", encTime: " <<
|
|
||||||
(current_encoding_time_ms_ / current_frames_) << " for last " <<
|
|
||||||
statistic_time_ms << " ms.";
|
|
||||||
start_time_ms_ = GetCurrentTimeMs();
|
|
||||||
current_frames_ = 0;
|
|
||||||
current_bytes_ = 0;
|
|
||||||
current_encoding_time_ms_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback - return encoded frame.
|
// Callback - return encoded frame.
|
||||||
@ -966,16 +974,20 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
|||||||
header.fragmentationTimeDiff[0] = 0;
|
header.fragmentationTimeDiff[0] = 0;
|
||||||
if (codecType_ == kVideoCodecVP8 && scale_) {
|
if (codecType_ == kVideoCodecVP8 && scale_) {
|
||||||
int qp;
|
int qp;
|
||||||
if (webrtc::vp8::GetQp(payload, payload_size, &qp))
|
if (webrtc::vp8::GetQp(payload, payload_size, &qp)) {
|
||||||
|
current_acc_qp_ += qp;
|
||||||
quality_scaler_.ReportQP(qp);
|
quality_scaler_.ReportQP(qp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (codecType_ == kVideoCodecH264) {
|
} else if (codecType_ == kVideoCodecH264) {
|
||||||
if (scale_) {
|
if (scale_) {
|
||||||
h264_bitstream_parser_.ParseBitstream(payload, payload_size);
|
h264_bitstream_parser_.ParseBitstream(payload, payload_size);
|
||||||
int qp;
|
int qp;
|
||||||
if (h264_bitstream_parser_.GetLastSliceQp(&qp))
|
if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
|
||||||
|
current_acc_qp_ += qp;
|
||||||
quality_scaler_.ReportQP(qp);
|
quality_scaler_.ReportQP(qp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// For H.264 search for start codes.
|
// For H.264 search for start codes.
|
||||||
int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {};
|
int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {};
|
||||||
int32_t scPositionsLength = 0;
|
int32_t scPositionsLength = 0;
|
||||||
@ -1022,6 +1034,29 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate and print encoding statistics - every 3 seconds.
|
||||||
|
frames_encoded_++;
|
||||||
|
current_frames_++;
|
||||||
|
current_bytes_ += payload_size;
|
||||||
|
current_encoding_time_ms_ += frame_encoding_time_ms;
|
||||||
|
int statistic_time_ms = GetCurrentTimeMs() - start_time_ms_;
|
||||||
|
if (statistic_time_ms >= kMediaCodecStatisticsIntervalMs &&
|
||||||
|
current_frames_ > 0) {
|
||||||
|
ALOGD << "Encoded frames: " << frames_encoded_ << ". Bitrate: " <<
|
||||||
|
(current_bytes_ * 8 / statistic_time_ms) <<
|
||||||
|
", target: " << last_set_bitrate_kbps_ << " kbps, fps: " <<
|
||||||
|
((current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms)
|
||||||
|
<< ", encTime: " <<
|
||||||
|
(current_encoding_time_ms_ / current_frames_) << ". QP: " <<
|
||||||
|
(current_acc_qp_ / current_frames_) << " for last " <<
|
||||||
|
statistic_time_ms << " ms.";
|
||||||
|
start_time_ms_ = GetCurrentTimeMs();
|
||||||
|
current_frames_ = 0;
|
||||||
|
current_bytes_ = 0;
|
||||||
|
current_acc_qp_ = 0;
|
||||||
|
current_encoding_time_ms_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (callback_status > 0) {
|
if (callback_status > 0) {
|
||||||
drop_next_input_frame_ = true;
|
drop_next_input_frame_ = true;
|
||||||
// Theoretically could handle callback_status<0 here, but unclear what
|
// Theoretically could handle callback_status<0 here, but unclear what
|
||||||
@ -1065,6 +1100,8 @@ int32_t MediaCodecVideoEncoder::NextNaluPosition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MediaCodecVideoEncoder::OnDroppedFrame() {
|
void MediaCodecVideoEncoder::OnDroppedFrame() {
|
||||||
|
frames_dropped_++;
|
||||||
|
// Report dropped frame to quality_scaler_.
|
||||||
if (scale_)
|
if (scale_)
|
||||||
quality_scaler_.ReportDroppedFrame();
|
quality_scaler_.ReportDroppedFrame();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user