Implement QP parsing in VideoDecoderWrapper.

BUG=webrtc:7760
NOTRY=True

Review-Url: https://codereview.webrtc.org/3000993002
Cr-Commit-Position: refs/heads/master@{#19378}
This commit is contained in:
sakal
2017-08-17 02:18:04 -07:00
committed by Commit Bot
parent 7441827b61
commit 4dee344493
2 changed files with 64 additions and 2 deletions

View File

@ -12,6 +12,8 @@
#include "webrtc/api/video/video_frame.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/modules/video_coding/utility/vp8_header_parser.h"
#include "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/sdk/android/src/jni/classreferenceholder.h"
@ -70,6 +72,8 @@ VideoDecoderWrapper::VideoDecoderWrapper(JNIEnv* jni, jobject decoder)
int_value_method_ = jni->GetMethodID(*integer_class_, "intValue", "()I");
initialized_ = false;
// QP parsing starts enabled and we disable it if the decoder provides frames.
qp_parsing_enabled_ = true;
}
int32_t VideoDecoderWrapper::InitDecode(
@ -100,6 +104,11 @@ int32_t VideoDecoderWrapper::InitDecodeInternal(JNIEnv* jni) {
if (jni->CallIntMethod(ret, get_number_method_) == WEBRTC_VIDEO_CODEC_OK) {
initialized_ = true;
}
// The decoder was reinitialized so re-enable the QP parsing in case it stops
// providing QP values.
qp_parsing_enabled_ = true;
return HandleReturnCode(jni, ret);
}
@ -120,6 +129,8 @@ int32_t VideoDecoderWrapper::Decode(
FrameExtraInfo frame_extra_info;
frame_extra_info.capture_time_ms = input_image.capture_time_ms_;
frame_extra_info.timestamp_rtp = input_image._timeStamp;
frame_extra_info.qp =
qp_parsing_enabled_ ? ParseQP(input_image) : rtc::Optional<uint8_t>();
frame_extra_infos_.push_back(frame_extra_info);
jobject jinput_image =
@ -189,9 +200,16 @@ void VideoDecoderWrapper::OnDecodedFrame(JNIEnv* jni,
rtc::Optional<uint8_t> qp;
if (jqp != nullptr) {
qp = rtc::Optional<uint8_t>(jni->CallIntMethod(jqp, int_value_method_));
// The decoder provides QP values itself, no need to parse the bitstream.
qp_parsing_enabled_ = false;
} else {
qp = frame_extra_info.qp;
// The decoder doesn't provide QP values, ensure bitstream parsing is
// enabled.
qp_parsing_enabled_ = true;
}
callback_->Decoded(frame, decoding_time_ms, rtc::Optional<uint8_t>());
callback_->Decoded(frame, decoding_time_ms, qp);
}
jobject VideoDecoderWrapper::ConvertEncodedImageToJavaEncodedImage(
@ -242,6 +260,45 @@ int32_t VideoDecoderWrapper::HandleReturnCode(JNIEnv* jni, jobject code) {
}
}
rtc::Optional<uint8_t> VideoDecoderWrapper::ParseQP(
const webrtc::EncodedImage& input_image) {
if (input_image.qp_ != -1) {
return rtc::Optional<uint8_t>(input_image.qp_);
}
rtc::Optional<uint8_t> qp;
switch (codec_settings_.codecType) {
case webrtc::kVideoCodecVP8: {
int qp_int;
if (webrtc::vp8::GetQp(input_image._buffer, input_image._length,
&qp_int)) {
qp = rtc::Optional<uint8_t>(qp_int);
}
break;
}
case webrtc::kVideoCodecVP9: {
int qp_int;
if (webrtc::vp9::GetQp(input_image._buffer, input_image._length,
&qp_int)) {
qp = rtc::Optional<uint8_t>(qp_int);
}
break;
}
case webrtc::kVideoCodecH264: {
h264_bitstream_parser_.ParseBitstream(input_image._buffer,
input_image._length);
int qp_int;
if (h264_bitstream_parser_.GetLastSliceQp(&qp_int)) {
qp = rtc::Optional<uint8_t>(qp_int);
}
break;
}
default:
break; // Default is to not provide QP.
}
return qp;
}
JOW(void, VideoDecoderWrapperCallback_nativeOnDecodedFrame)
(JNIEnv* jni,
jclass,

View File

@ -12,10 +12,10 @@
#define WEBRTC_SDK_ANDROID_SRC_JNI_VIDEODECODERWRAPPER_H_
#include <jni.h>
#include <deque>
#include "webrtc/api/video_codecs/video_decoder.h"
#include "webrtc/common_video/h264/h264_bitstream_parser.h"
#include "webrtc/sdk/android/src/jni/jni_helpers.h"
#include "webrtc/sdk/android/src/jni/native_handle_impl.h"
@ -60,6 +60,7 @@ class VideoDecoderWrapper : public webrtc::VideoDecoder {
uint32_t capture_time_ms; // Used as an identifier of the frame.
uint32_t timestamp_rtp;
rtc::Optional<uint8_t> qp;
};
int32_t InitDecodeInternal(JNIEnv* jni);
@ -68,12 +69,16 @@ class VideoDecoderWrapper : public webrtc::VideoDecoder {
// status code.
int32_t HandleReturnCode(JNIEnv* jni, jobject code);
rtc::Optional<uint8_t> ParseQP(const webrtc::EncodedImage& input_image);
webrtc::VideoCodec codec_settings_;
int32_t number_of_cores_;
bool initialized_;
AndroidVideoBufferFactory android_video_buffer_factory_;
std::deque<FrameExtraInfo> frame_extra_infos_;
bool qp_parsing_enabled_;
webrtc::H264BitstreamParser h264_bitstream_parser_;
webrtc::DecodedImageCallback* callback_;