19dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org/*
29dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
39dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *
49dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *  Use of this source code is governed by a BSD-style license
59dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *  that can be found in the LICENSE file in the root of the source
69dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *  tree. An additional intellectual property rights grant can be found
79dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *  in the file PATENTS.  All contributing project authors may
89dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
99dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org */
109dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
11a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
12076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org#include "webrtc/modules/video_coding/codecs/test_framework/unit_test.h"
13a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
14a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
159dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
169dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h"
179dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org#include "webrtc/test/testsupport/fileutils.h"
18acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h"
199dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
209dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgnamespace webrtc {
219dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
229dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgenum { kMaxWaitEncTimeMs = 100 };
239dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgenum { kMaxWaitDecTimeMs = 25 };
249dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
259d10769e109601915022fea44ec392645c3b0704wu@webrtc.orgstatic const uint32_t kTestTimestamp = 123;
269d10769e109601915022fea44ec392645c3b0704wu@webrtc.orgstatic const int64_t kTestNtpTimeMs = 456;
279dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
289dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org// TODO(mikhal): Replace these with mocks.
299dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgclass Vp8UnitTestEncodeCompleteCallback : public webrtc::EncodedImageCallback {
309dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org public:
319dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  Vp8UnitTestEncodeCompleteCallback(VideoFrame* frame,
329dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org                                    unsigned int decoderSpecificSize,
339dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org                                    void* decoderSpecificInfo)
349dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org     : encoded_video_frame_(frame),
359dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org       encode_complete_(false) {}
369dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  int Encoded(EncodedImage& encodedImage,
379dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org              const CodecSpecificInfo* codecSpecificInfo,
389dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org              const RTPFragmentationHeader*);
399dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  bool EncodeComplete();
409dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  // Note that this only makes sense if an encode has been completed
419dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  VideoFrameType EncodedFrameType() const {return  encoded_frame_type_;}
429dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
439dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org private:
449dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  VideoFrame* encoded_video_frame_;
459dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  bool encode_complete_;
469dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  VideoFrameType encoded_frame_type_;
479dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org};
489dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
499dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgint Vp8UnitTestEncodeCompleteCallback::Encoded(EncodedImage& encodedImage,
509dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    const CodecSpecificInfo* codecSpecificInfo,
519dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    const RTPFragmentationHeader* fragmentation) {
529dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_video_frame_->VerifyAndAllocate(encodedImage._size);
539dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_video_frame_->CopyFrame(encodedImage._size, encodedImage._buffer);
549dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_video_frame_->SetLength(encodedImage._length);
559dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  // TODO(mikhal): Update frame type API.
569dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  // encoded_video_frame_->SetFrameType(encodedImage._frameType);
579dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_video_frame_->SetWidth(encodedImage._encodedWidth);
589dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_video_frame_->SetHeight(encodedImage._encodedHeight);
599dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_video_frame_->SetTimeStamp(encodedImage._timeStamp);
609dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encode_complete_ = true;
619dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  encoded_frame_type_ = encodedImage._frameType;
629dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  return 0;
639dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org}
649dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
659dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgbool Vp8UnitTestEncodeCompleteCallback::EncodeComplete() {
669dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  if (encode_complete_) {
679dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    encode_complete_ = false;
689dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    return true;
699dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  }
709dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  return false;
719dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org}
729dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
739dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgclass Vp8UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback {
749dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org public:
759dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  explicit Vp8UnitTestDecodeCompleteCallback(I420VideoFrame* frame)
769dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org      : decoded_video_frame_(frame),
779dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org        decode_complete(false) {}
789dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  int Decoded(webrtc::I420VideoFrame& frame);
799dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  bool DecodeComplete();
809dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org private:
819dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  I420VideoFrame* decoded_video_frame_;
829dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  bool decode_complete;
839dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org};
849dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
859dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgbool Vp8UnitTestDecodeCompleteCallback::DecodeComplete() {
869dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  if (decode_complete) {
879dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    decode_complete = false;
889dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    return true;
899dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  }
909dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  return false;
919dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org}
929dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
939dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgint Vp8UnitTestDecodeCompleteCallback::Decoded(I420VideoFrame& image) {
949dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  decoded_video_frame_->CopyFrame(image);
959dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  decode_complete = true;
969dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  return 0;
979dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org}
989dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
999dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.orgclass TestVp8Impl : public ::testing::Test {
1009dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org protected:
1019dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  virtual void SetUp() {
10207d98c828ba8e9386c2a34e1568d7543f5708479mikhal@webrtc.org    encoder_.reset(VP8Encoder::Create());
10307d98c828ba8e9386c2a34e1568d7543f5708479mikhal@webrtc.org    decoder_.reset(VP8Decoder::Create());
1049dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    memset(&codec_inst_, 0, sizeof(codec_inst_));
1059dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    encode_complete_callback_.reset(new
1069dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org        Vp8UnitTestEncodeCompleteCallback(&encoded_video_frame_, 0, NULL));
1079dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    decode_complete_callback_.reset(new
1089dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org        Vp8UnitTestDecodeCompleteCallback(&decoded_video_frame_));
1099dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get());
1109dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get());
111e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    // Using a QCIF image (aligned stride (u,v planes) > width).
112e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    // Processing only one frame.
113e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    const VideoSource source(test::ResourcePath("paris_qcif", "yuv"), kQCIF);
114e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    length_source_frame_ = source.GetFrameLength();
115e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    source_buffer_.reset(new uint8_t[length_source_frame_]);
116e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    source_file_ = fopen(source.GetFileName().c_str(), "rb");
117e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    ASSERT_TRUE(source_file_ != NULL);
118e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    // Set input frame.
119e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    ASSERT_EQ(fread(source_buffer_.get(), 1, length_source_frame_,
120e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org        source_file_), length_source_frame_);
121e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.width = source.GetWidth();
122e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.height = source.GetHeight();
123e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.maxFramerate = source.GetFrameRate();
124e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    // Setting aligned stride values.
125e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    int stride_uv = 0;
126e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    int stride_y = 0;
127e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    Calc16ByteAlignedStride(codec_inst_.width, &stride_y, &stride_uv);
128e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    EXPECT_EQ(stride_y, 176);
129e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    EXPECT_EQ(stride_uv, 96);
130e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org
131e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    input_frame_.CreateEmptyFrame(codec_inst_.width, codec_inst_.height,
132e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org                                  stride_y, stride_uv, stride_uv);
1339d10769e109601915022fea44ec392645c3b0704wu@webrtc.org    input_frame_.set_timestamp(kTestTimestamp);
134e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    // Using ConvertToI420 to add stride to the image.
135e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    EXPECT_EQ(0, ConvertToI420(kI420, source_buffer_.get(), 0, 0,
136e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org                               codec_inst_.width, codec_inst_.height,
137e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org                               0, kRotateNone, &input_frame_));
138e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  }
139e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org
140e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  void SetUpEncodeDecode() {
141e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.startBitrate = 300;
142e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.maxBitrate = 4000;
143e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.qpMax = 56;
144e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    codec_inst_.codecSpecific.VP8.denoisingOn = true;
145e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org
146e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
147e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org        encoder_->InitEncode(&codec_inst_, 1, 1440));
148e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_inst_, 1));
1499dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  }
1509dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
1519dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  int WaitForEncodedFrame() const {
1529dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    int64_t startTime = TickTime::MillisecondTimestamp();
1539dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitEncTimeMs) {
1549dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org      if (encode_complete_callback_->EncodeComplete()) {
1559dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org        return encoded_video_frame_.Length();
1569dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org      }
1579dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    }
1589dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    return 0;
1599dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  }
1609dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
1619dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  int WaitForDecodedFrame() const {
1629dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    int64_t startTime = TickTime::MillisecondTimestamp();
1639dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitDecTimeMs) {
1649dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org      if (decode_complete_callback_->DecodeComplete()) {
1659dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org        return CalcBufferSize(kI420, decoded_video_frame_.width(),
1669dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org                              decoded_video_frame_.height());
1679dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org      }
1689dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    }
1699dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    return 0;
1709dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  }
1719dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
1729dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  void VideoFrameToEncodedImage(VideoFrame& frame, EncodedImage &image) {
1739dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._buffer = frame.Buffer();
1749dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._length = frame.Length();
1759dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._size = frame.Size();
1769dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._timeStamp = frame.TimeStamp();
1779dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._encodedWidth = frame.Width();
1789dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._encodedHeight = frame.Height();
1799dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org    image._completeFrame = true;
1809dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  }
1819dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
1829dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  scoped_ptr<Vp8UnitTestEncodeCompleteCallback> encode_complete_callback_;
1839dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  scoped_ptr<Vp8UnitTestDecodeCompleteCallback> decode_complete_callback_;
184ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org  scoped_ptr<uint8_t[]> source_buffer_;
1859dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  FILE* source_file_;
186e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  I420VideoFrame input_frame_;
1879dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  scoped_ptr<VideoEncoder> encoder_;
1889dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  scoped_ptr<VideoDecoder> decoder_;
1899dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  VideoFrame encoded_video_frame_;
1909dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  I420VideoFrame decoded_video_frame_;
1919dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  unsigned int length_source_frame_;
1929dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  VideoCodec codec_inst_;
1939dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org};
1949dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
195acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.orgTEST_F(TestVp8Impl, DISABLED_ON_ANDROID(BaseUnitTest)) {
196076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  // TODO(mikhal): Remove dependency. Move all test code here.
197076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
198076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  UnitTest unittest;
199076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  unittest.SetEncoder(encoder_.get());
200076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  unittest.SetDecoder(decoder_.get());
201076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  unittest.Setup();
202076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  unittest.Perform();
203076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  unittest.Print();
204076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org}
205076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org
206076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.orgTEST_F(TestVp8Impl, EncoderParameterTest) {
207076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  strncpy(codec_inst_.plName, "VP8", 31);
208076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.plType = 126;
209076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.maxBitrate = 0;
210076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.minBitrate = 0;
211076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.width = 1440;
212076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.height = 1080;
213076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.maxFramerate = 30;
214076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.startBitrate = 300;
215210c1455495c9cac6c4ef4ea7621094b1449b450stefan@webrtc.org  codec_inst_.qpMax = 56;
216076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.codecSpecific.VP8.complexity = kComplexityNormal;
217076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  codec_inst_.codecSpecific.VP8.numberOfTemporalLayers = 1;
218076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  // Calls before InitEncode().
219076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
220076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  int bit_rate = 300;
221076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
222076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org            encoder_->SetRates(bit_rate, codec_inst_.maxFramerate));
223076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org
224076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
225076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org            encoder_->InitEncode(&codec_inst_, 1, 1440));
226076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org
227076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  // Decoder parameter tests.
228076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  // Calls before InitDecode().
229076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
230076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_inst_, 1));
231076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org}
232076aa8444d4b002fb083bc08f9dfa6e4ecaf2043mikhal@webrtc.org
233acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.orgTEST_F(TestVp8Impl, DISABLED_ON_ANDROID(AlignedStrideEncodeDecode)) {
234e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  SetUpEncodeDecode();
235e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encoder_->Encode(input_frame_, NULL, NULL);
2369dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  EXPECT_GT(WaitForEncodedFrame(), 0);
2379dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  EncodedImage encodedImage;
2389dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  VideoFrameToEncodedImage(encoded_video_frame_, encodedImage);
239e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  // First frame should be a key frame.
240e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encodedImage._frameType = kKeyFrame;
2419d10769e109601915022fea44ec392645c3b0704wu@webrtc.org  encodedImage.ntp_time_ms_ = kTestNtpTimeMs;
2429dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encodedImage, false, NULL));
2439dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  EXPECT_GT(WaitForDecodedFrame(), 0);
2449dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org  // Compute PSNR on all planes (faster than SSIM).
245e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EXPECT_GT(I420PSNR(&input_frame_, &decoded_video_frame_), 36);
2469d10769e109601915022fea44ec392645c3b0704wu@webrtc.org  EXPECT_EQ(kTestTimestamp, decoded_video_frame_.timestamp());
2479d10769e109601915022fea44ec392645c3b0704wu@webrtc.org  EXPECT_EQ(kTestNtpTimeMs, decoded_video_frame_.ntp_time_ms());
248e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org}
249e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org
2504b067da35c8e0b771cc59e759c9ebbf2ccdbfb97andrew@webrtc.orgTEST_F(TestVp8Impl, DISABLED_ON_ANDROID(DecodeWithACompleteKeyFrame)) {
251e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  SetUpEncodeDecode();
252e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encoder_->Encode(input_frame_, NULL, NULL);
253e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EXPECT_GT(WaitForEncodedFrame(), 0);
254e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EncodedImage encodedImage;
255e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  VideoFrameToEncodedImage(encoded_video_frame_, encodedImage);
256e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  // Setting complete to false -> should return an error.
257e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encodedImage._completeFrame = false;
258e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
259e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org      decoder_->Decode(encodedImage, false, NULL));
260e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  // Setting complete back to true. Forcing a delta frame.
261e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encodedImage._frameType = kDeltaFrame;
262e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encodedImage._completeFrame = true;
263e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
264e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org      decoder_->Decode(encodedImage, false, NULL));
265e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  // Now setting a key frame.
266e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  encodedImage._frameType = kKeyFrame;
267e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
268e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org      decoder_->Decode(encodedImage, false, NULL));
269e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org  EXPECT_GT(I420PSNR(&input_frame_, &decoded_video_frame_), 36);
2709dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org}
2719dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org
2729dda8f5e03471d164b50758b327469f452a88fcemikhal@webrtc.org}  // namespace webrtc
273