Add QP for libvpx VP8 decoder.
BUG=webrtc:6541, webrtc:7065 TBR=hta@webrtc.org Review-Url: https://codereview.webrtc.org/2656603002 Cr-Commit-Position: refs/heads/master@{#16722}
This commit is contained in:
@ -148,7 +148,7 @@ class Vp8TestDecodedImageCallback : public DecodedImageCallback {
|
||||
void Decoded(VideoFrame& decoded_image,
|
||||
rtc::Optional<int32_t> decode_time_ms,
|
||||
rtc::Optional<uint8_t> qp) override {
|
||||
RTC_NOTREACHED();
|
||||
Decoded(decoded_image);
|
||||
}
|
||||
int DecodedFrames() { return decoded_frames_; }
|
||||
|
||||
|
||||
@ -76,6 +76,7 @@ Vp8UnitTestEncodeCompleteCallback::OnEncodedImage(
|
||||
encoded_frame_->_timeStamp = encoded_frame._timeStamp;
|
||||
encoded_frame_->_frameType = encoded_frame._frameType;
|
||||
encoded_frame_->_completeFrame = encoded_frame._completeFrame;
|
||||
encoded_frame_->qp_ = encoded_frame.qp_;
|
||||
encode_complete_ = true;
|
||||
return Result(Result::OK, 0);
|
||||
}
|
||||
@ -90,22 +91,25 @@ bool Vp8UnitTestEncodeCompleteCallback::EncodeComplete() {
|
||||
|
||||
class Vp8UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback {
|
||||
public:
|
||||
explicit Vp8UnitTestDecodeCompleteCallback(rtc::Optional<VideoFrame>* frame)
|
||||
: decoded_frame_(frame), decode_complete(false) {}
|
||||
int32_t Decoded(VideoFrame& frame) override;
|
||||
explicit Vp8UnitTestDecodeCompleteCallback(rtc::Optional<VideoFrame>* frame,
|
||||
rtc::Optional<uint8_t>* qp)
|
||||
: decoded_frame_(frame), decoded_qp_(qp), decode_complete(false) {}
|
||||
int32_t Decoded(VideoFrame& frame) override {
|
||||
RTC_NOTREACHED();
|
||||
return -1;
|
||||
}
|
||||
int32_t Decoded(VideoFrame& frame, int64_t decode_time_ms) override {
|
||||
RTC_NOTREACHED();
|
||||
return -1;
|
||||
}
|
||||
void Decoded(VideoFrame& frame,
|
||||
rtc::Optional<int32_t> decode_time_ms,
|
||||
rtc::Optional<uint8_t> qp) override {
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
rtc::Optional<uint8_t> qp) override;
|
||||
bool DecodeComplete();
|
||||
|
||||
private:
|
||||
rtc::Optional<VideoFrame>* decoded_frame_;
|
||||
rtc::Optional<uint8_t>* decoded_qp_;
|
||||
bool decode_complete;
|
||||
};
|
||||
|
||||
@ -117,10 +121,13 @@ bool Vp8UnitTestDecodeCompleteCallback::DecodeComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int Vp8UnitTestDecodeCompleteCallback::Decoded(VideoFrame& image) {
|
||||
*decoded_frame_ = rtc::Optional<VideoFrame>(image);
|
||||
void Vp8UnitTestDecodeCompleteCallback::Decoded(
|
||||
VideoFrame& frame,
|
||||
rtc::Optional<int32_t> decode_time_ms,
|
||||
rtc::Optional<uint8_t> qp) {
|
||||
*decoded_frame_ = rtc::Optional<VideoFrame>(frame);
|
||||
*decoded_qp_ = qp;
|
||||
decode_complete = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
class TestVp8Impl : public ::testing::Test {
|
||||
@ -132,7 +139,7 @@ class TestVp8Impl : public ::testing::Test {
|
||||
encode_complete_callback_.reset(
|
||||
new Vp8UnitTestEncodeCompleteCallback(&encoded_frame_, 0, NULL));
|
||||
decode_complete_callback_.reset(
|
||||
new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_));
|
||||
new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_, &decoded_qp_));
|
||||
encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get());
|
||||
decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get());
|
||||
// Using a QCIF image (aligned stride (u,v planes) > width).
|
||||
@ -210,6 +217,7 @@ class TestVp8Impl : public ::testing::Test {
|
||||
std::unique_ptr<VideoDecoder> decoder_;
|
||||
EncodedImage encoded_frame_;
|
||||
rtc::Optional<VideoFrame> decoded_frame_;
|
||||
rtc::Optional<uint8_t> decoded_qp_;
|
||||
VideoCodec codec_inst_;
|
||||
TemporalLayersFactory tl_factory_;
|
||||
};
|
||||
@ -244,6 +252,21 @@ TEST_F(TestVp8Impl, EncoderParameterTest) {
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_inst_, 1));
|
||||
}
|
||||
|
||||
TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) {
|
||||
SetUpEncodeDecode();
|
||||
encoder_->Encode(*input_frame_, nullptr, nullptr);
|
||||
EXPECT_GT(WaitForEncodedFrame(), 0u);
|
||||
// First frame should be a key frame.
|
||||
encoded_frame_._frameType = kVideoFrameKey;
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
decoder_->Decode(encoded_frame_, false, nullptr));
|
||||
EXPECT_GT(WaitForDecodedFrame(), 0u);
|
||||
ASSERT_TRUE(decoded_frame_);
|
||||
EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36);
|
||||
ASSERT_TRUE(decoded_qp_);
|
||||
EXPECT_EQ(encoded_frame_.qp_, *decoded_qp_);
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
#define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode
|
||||
#else
|
||||
|
||||
@ -1145,7 +1145,11 @@ int VP8DecoderImpl::Decode(const EncodedImage& input_image,
|
||||
}
|
||||
|
||||
img = vpx_codec_get_frame(decoder_, &iter);
|
||||
ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_);
|
||||
int qp;
|
||||
vpx_codec_err_t vpx_ret =
|
||||
vpx_codec_control(decoder_, VPXD_GET_LAST_QUANTIZER, &qp);
|
||||
RTC_DCHECK_EQ(vpx_ret, VPX_CODEC_OK);
|
||||
ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_, qp);
|
||||
if (ret != 0) {
|
||||
// Reset to avoid requesting key frames too often.
|
||||
if (ret < 0 && propagation_cnt_ > 0)
|
||||
@ -1205,7 +1209,8 @@ int VP8DecoderImpl::Decode(const EncodedImage& input_image,
|
||||
|
||||
int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img,
|
||||
uint32_t timestamp,
|
||||
int64_t ntp_time_ms) {
|
||||
int64_t ntp_time_ms,
|
||||
int qp) {
|
||||
if (img == NULL) {
|
||||
// Decoder OK and NULL image => No show frame
|
||||
return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
|
||||
@ -1232,9 +1237,8 @@ int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img,
|
||||
|
||||
VideoFrame decoded_image(buffer, timestamp, 0, kVideoRotation_0);
|
||||
decoded_image.set_ntp_time_ms(ntp_time_ms);
|
||||
int ret = decode_complete_callback_->Decoded(decoded_image);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
decode_complete_callback_->Decoded(decoded_image, rtc::Optional<int32_t>(),
|
||||
rtc::Optional<uint8_t>(qp));
|
||||
|
||||
// Remember image format for later
|
||||
image_format_ = img->fmt;
|
||||
|
||||
@ -149,7 +149,8 @@ class VP8DecoderImpl : public VP8Decoder {
|
||||
|
||||
int ReturnFrame(const vpx_image_t* img,
|
||||
uint32_t timeStamp,
|
||||
int64_t ntp_time_ms);
|
||||
int64_t ntp_time_ms,
|
||||
int qp);
|
||||
|
||||
I420BufferPool buffer_pool_;
|
||||
DecodedImageCallback* decode_complete_callback_;
|
||||
|
||||
Reference in New Issue
Block a user