216 lines · 7.0 KB · C++
RawDownload
/* *  Copyright (c) 2014 The WebM project authors. All Rights Reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS.  All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */#include <memory> #include "third_party/googletest/src/include/gtest/gtest.h"#include "test/codec_factory.h"#include "test/register_state_check.h"#include "test/video_source.h" namespace { class EncoderWithExpectedError : public ::libvpx_test::Encoder { public:  EncoderWithExpectedError(vpx_codec_enc_cfg_t cfg,                           unsigned long deadline,          // NOLINT                           const unsigned long init_flags,  // NOLINT                           ::libvpx_test::TwopassStatsStore *stats)      : ::libvpx_test::Encoder(cfg, deadline, init_flags, stats) {}  // This overrides with expected error code.  void EncodeFrame(::libvpx_test::VideoSource *video,                   const unsigned long frame_flags,  // NOLINT                   const vpx_codec_err_t expected_err) {    if (video->img()) {      EncodeFrameInternal(*video, frame_flags, expected_err);    } else {      Flush();    }     // Handle twopass stats    ::libvpx_test::CxDataIterator iter = GetCxData();     while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {      if (pkt->kind != VPX_CODEC_STATS_PKT) continue;       stats_->Append(*pkt);    }  }  protected:  void EncodeFrameInternal(const ::libvpx_test::VideoSource &video,                           const unsigned long frame_flags,  // NOLINT                           const vpx_codec_err_t expected_err) {    vpx_codec_err_t res;    const vpx_image_t *img = video.img();     // Handle frame resizing    if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) {      cfg_.g_w = img->d_w;      cfg_.g_h = img->d_h;      res = vpx_codec_enc_config_set(&encoder_, &cfg_);      ASSERT_EQ(res, VPX_CODEC_OK) << EncoderError();    }     // Encode the frame    API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(),                                                    video.duration(),                                                    frame_flags, deadline_));    ASSERT_EQ(expected_err, res) << EncoderError();  }   virtual vpx_codec_iface_t *CodecInterface() const {#if CONFIG_VP9_ENCODER    return &vpx_codec_vp9_cx_algo;#else    return nullptr;#endif  }}; class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,                               public ::testing::Test { protected:  VP9FrameSizeTestsLarge()      : EncoderTest(&::libvpx_test::kVP9), expected_res_(VPX_CODEC_OK) {}  virtual ~VP9FrameSizeTestsLarge() {}   virtual void SetUp() {    InitializeConfig();    SetMode(::libvpx_test::kRealTime);  }   virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,                                  const libvpx_test::VideoSource & /*video*/,                                  libvpx_test::Decoder *decoder) {    EXPECT_EQ(expected_res_, res_dec) << decoder->DecodeError();    return !::testing::Test::HasFailure();  }   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,                                  ::libvpx_test::Encoder *encoder) {    if (video->frame() == 0) {      encoder->Control(VP8E_SET_CPUUSED, 7);      encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);      encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);      encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);      encoder->Control(VP8E_SET_ARNR_TYPE, 3);    }  }   using ::libvpx_test::EncoderTest::RunLoop;  virtual void RunLoop(::libvpx_test::VideoSource *video,                       const vpx_codec_err_t expected_err) {    stats_.Reset();     ASSERT_TRUE(passes_ == 1 || passes_ == 2);    for (unsigned int pass = 0; pass < passes_; pass++) {      last_pts_ = 0;       if (passes_ == 1) {        cfg_.g_pass = VPX_RC_ONE_PASS;      } else if (pass == 0) {        cfg_.g_pass = VPX_RC_FIRST_PASS;      } else {        cfg_.g_pass = VPX_RC_LAST_PASS;      }       BeginPassHook(pass);      std::unique_ptr<EncoderWithExpectedError> encoder(          new EncoderWithExpectedError(cfg_, deadline_, init_flags_, &stats_));      ASSERT_NE(encoder.get(), nullptr);       ASSERT_NO_FATAL_FAILURE(video->Begin());      encoder->InitEncoder(video);      ASSERT_FALSE(::testing::Test::HasFatalFailure());      for (bool again = true; again; video->Next()) {        again = (video->img() != nullptr);         PreEncodeFrameHook(video, encoder.get());        encoder->EncodeFrame(video, frame_flags_, expected_err);         PostEncodeFrameHook(encoder.get());         ::libvpx_test::CxDataIterator iter = encoder->GetCxData();         while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {          pkt = MutateEncoderOutputHook(pkt);          again = true;          switch (pkt->kind) {            case VPX_CODEC_CX_FRAME_PKT:              ASSERT_GE(pkt->data.frame.pts, last_pts_);              last_pts_ = pkt->data.frame.pts;              FramePktHook(pkt);              break;             case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;            case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break;            default: break;          }        }         if (!Continue()) break;      }       EndPassHook();       if (!Continue()) break;    }  }   vpx_codec_err_t expected_res_;}; TEST_F(VP9FrameSizeTestsLarge, TestInvalidSizes) {  ::libvpx_test::RandomVideoSource video; #if CONFIG_SIZE_LIMIT  video.SetSize(DECODE_WIDTH_LIMIT + 16, DECODE_HEIGHT_LIMIT + 16);  video.set_limit(2);  expected_res_ = VPX_CODEC_MEM_ERROR;  ASSERT_NO_FATAL_FAILURE(RunLoop(&video, expected_res_));#endif} TEST_F(VP9FrameSizeTestsLarge, ValidSizes) {  ::libvpx_test::RandomVideoSource video; #if CONFIG_SIZE_LIMIT  video.SetSize(DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT);  video.set_limit(2);  expected_res_ = VPX_CODEC_OK;  ASSERT_NO_FATAL_FAILURE(::libvpx_test::EncoderTest::RunLoop(&video));#else// This test produces a pretty large single frame allocation,  (roughly// 25 megabits). The encoder allocates a good number of these frames// one for each lag in frames (for 2 pass), and then one for each possible// reference buffer (8) - we can end up with up to 30 buffers of roughly this// size or almost 1 gig of memory.// In total the allocations will exceed 2GiB which may cause a failure with// mingw + wine, use a smaller size in that case.#if defined(_WIN32) && !defined(_WIN64) || defined(__OS2__)  video.SetSize(4096, 3072);#else  video.SetSize(4096, 4096);#endif  video.set_limit(2);  expected_res_ = VPX_CODEC_OK;  ASSERT_NO_FATAL_FAILURE(::libvpx_test::EncoderTest::RunLoop(&video));#endif} TEST_F(VP9FrameSizeTestsLarge, OneByOneVideo) {  ::libvpx_test::RandomVideoSource video;   video.SetSize(1, 1);  video.set_limit(2);  expected_res_ = VPX_CODEC_OK;  ASSERT_NO_FATAL_FAILURE(::libvpx_test::EncoderTest::RunLoop(&video));}}  // namespace

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t