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

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

Issue 1365063002: Wire up QualityScaler for H.264 on Android. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: feedback Created 5 years, 3 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 a74044600a754a2fb8ee1c74dcade55b9d557f66..f6a3b650a6b8aaf481fa941e3bbb777a09dc84b6 100644
--- a/talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
+++ b/talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
@@ -33,6 +33,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/thread.h"
+#include "webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h"
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/modules/video_coding/utility/include/quality_scaler.h"
#include "webrtc/modules/video_coding/utility/include/vp8_header_parser.h"
@@ -199,10 +200,12 @@ class MediaCodecVideoEncoder : public webrtc::VideoEncoder,
bool drop_next_input_frame_;
// Global references; must be deleted in Release().
std::vector<jobject> input_buffers_;
- scoped_ptr<webrtc::QualityScaler> quality_scaler_;
+ webrtc::QualityScaler quality_scaler_;
// Dynamic resolution change, off by default.
bool scale_;
- int updated_framerate_;
+
+ // H264 bitstream parser, used to extract QP from encoded bitstreams.
+ webrtc::H264BitstreamParser h264_bitstream_parser_;
};
MediaCodecVideoEncoder::~MediaCodecVideoEncoder() {
@@ -217,7 +220,6 @@ MediaCodecVideoEncoder::MediaCodecVideoEncoder(
inited_(false),
picture_id_(0),
codec_thread_(new Thread()),
- quality_scaler_(new webrtc::QualityScaler()),
j_media_codec_video_encoder_class_(
jni,
FindClass(jni, "org/webrtc/MediaCodecVideoEncoder")),
@@ -283,10 +285,6 @@ int32_t MediaCodecVideoEncoder::InitEncode(
size_t /* max_payload_size */) {
const int kMinWidth = 320;
const int kMinHeight = 180;
- // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the
- // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is
- // always = 127. Note that in SW, QP is that of the user-level range [0, 63].
- const int kMaxQP = 127;
const int kLowQpThresholdDenominator = 3;
if (codec_settings == NULL) {
ALOGE("NULL VideoCodec instance");
@@ -298,18 +296,28 @@ int32_t MediaCodecVideoEncoder::InitEncode(
<< codecType_;
ALOGD("InitEncode request");
-
scale_ = webrtc::field_trial::FindFullName(
"WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled";
ALOGD("Automatic resize: %s", scale_ ? "enabled" : "disabled");
-
- if (scale_ && codecType_ == kVideoCodecVP8) {
- quality_scaler_->Init(kMaxQP / kLowQpThresholdDenominator, true);
- quality_scaler_->SetMinResolution(kMinWidth, kMinHeight);
- quality_scaler_->ReportFramerate(codec_settings->maxFramerate);
- updated_framerate_ = codec_settings->maxFramerate;
- } else {
- updated_framerate_ = -1;
+ if (scale_) {
+ if (codecType_ == kVideoCodecVP8) {
+ // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the
+ // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is
+ // always = 127. Note that in SW, QP is that of the user-level range [0,
+ // 63].
+ const int kMaxQp = 127;
+ quality_scaler_.Init(kMaxQp / kLowQpThresholdDenominator, true);
+ } else if (codecType_ == kVideoCodecH264) {
+ // H264 QP is in the range [0, 51].
+ const int kMaxQp = 51;
+ quality_scaler_.Init(kMaxQp / kLowQpThresholdDenominator, true);
+ } else {
+ // When adding codec support to additional hardware codecs, also configure
+ // their QP thresholds for scaling.
+ RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds.";
+ }
+ quality_scaler_.SetMinResolution(kMinWidth, kMinHeight);
+ quality_scaler_.ReportFramerate(codec_settings->maxFramerate);
}
return codec_thread_->Invoke<int32_t>(
Bind(&MediaCodecVideoEncoder::InitEncodeOnCodecThread,
@@ -349,9 +357,9 @@ int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */,
int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate,
uint32_t frame_rate) {
- if (scale_ && codecType_ == kVideoCodecVP8) {
- quality_scaler_->ReportFramerate(frame_rate);
- }
+ if (scale_)
+ quality_scaler_.ReportFramerate(frame_rate);
+
return codec_thread_->Invoke<int32_t>(
Bind(&MediaCodecVideoEncoder::SetRatesOnCodecThread,
this,
@@ -507,12 +515,11 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread(
RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";
// Check framerate before spatial resolution change.
- if (scale_ && codecType_ == kVideoCodecVP8) {
- quality_scaler_->OnEncodeFrame(frame);
- updated_framerate_ = quality_scaler_->GetTargetFramerate();
- }
- const VideoFrame& input_frame = (scale_ && codecType_ == kVideoCodecVP8) ?
- quality_scaler_->GetScaledFrame(frame) : frame;
+ if (scale_)
+ quality_scaler_.OnEncodeFrame(frame);
+
+ const VideoFrame& input_frame =
+ scale_ ? quality_scaler_.GetScaledFrame(frame) : frame;
if (input_frame.width() != width_ || input_frame.height() != height_) {
ALOGD("Frame resolution change from %d x %d to %d x %d",
@@ -723,9 +730,6 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
last_input_timestamp_ms_ - last_output_timestamp_ms_,
frame_encoding_time_ms);
- if (payload_size && scale_ && codecType_ == kVideoCodecVP8)
- quality_scaler_->ReportQP(webrtc::vp8::GetQP(payload));
-
// Calculate and print encoding statistics - every 3 seconds.
frames_encoded_++;
current_frames_++;
@@ -781,7 +785,15 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
header.fragmentationLength[0] = image->_length;
header.fragmentationPlType[0] = 0;
header.fragmentationTimeDiff[0] = 0;
+ if (scale_)
+ quality_scaler_.ReportQP(webrtc::vp8::GetQP(payload));
} else if (codecType_ == kVideoCodecH264) {
+ if (scale_) {
+ h264_bitstream_parser_.ParseBitstream(payload, payload_size);
+ int qp;
+ if (h264_bitstream_parser_.GetLastSliceQp(&qp))
+ quality_scaler_.ReportQP(qp);
+ }
// For H.264 search for start codes.
int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {};
int32_t scPositionsLength = 0;
@@ -871,12 +883,12 @@ int32_t MediaCodecVideoEncoder::NextNaluPosition(
}
void MediaCodecVideoEncoder::OnDroppedFrame() {
- if (scale_ && codecType_ == kVideoCodecVP8)
- quality_scaler_->ReportDroppedFrame();
+ if (scale_)
+ quality_scaler_.ReportDroppedFrame();
}
int MediaCodecVideoEncoder::GetTargetFramerate() {
- return updated_framerate_;
+ return scale_ ? quality_scaler_.GetTargetFramerate() : -1;
}
MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() {
« 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