Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 #include <climits>
     11 #include "third_party/googletest/src/include/gtest/gtest.h"
     12 #include "test/codec_factory.h"
     13 #include "test/encode_test_driver.h"
     14 #include "test/i420_video_source.h"
     15 #include "test/util.h"
     16 
     17 namespace {
     18 
     19 const int kTestMode = 0;
     20 
     21 typedef std::tr1::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
     22 
     23 class SuperframeTest
     24     : public ::libvpx_test::EncoderTest,
     25       public ::libvpx_test::CodecTestWithParam<SuperframeTestParam> {
     26  protected:
     27   SuperframeTest()
     28       : EncoderTest(GET_PARAM(0)), modified_buf_(NULL), last_sf_pts_(0) {}
     29   virtual ~SuperframeTest() {}
     30 
     31   virtual void SetUp() {
     32     InitializeConfig();
     33     const SuperframeTestParam input = GET_PARAM(1);
     34     const libvpx_test::TestMode mode = std::tr1::get<kTestMode>(input);
     35     SetMode(mode);
     36     sf_count_ = 0;
     37     sf_count_max_ = INT_MAX;
     38   }
     39 
     40   virtual void TearDown() { delete[] modified_buf_; }
     41 
     42   virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
     43                                   libvpx_test::Encoder *encoder) {
     44     if (video->frame() == 1) {
     45       encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
     46     }
     47   }
     48 
     49   virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook(
     50       const vpx_codec_cx_pkt_t *pkt) {
     51     if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt;
     52 
     53     const uint8_t *buffer = reinterpret_cast<uint8_t *>(pkt->data.frame.buf);
     54     const uint8_t marker = buffer[pkt->data.frame.sz - 1];
     55     const int frames = (marker & 0x7) + 1;
     56     const int mag = ((marker >> 3) & 3) + 1;
     57     const unsigned int index_sz = 2 + mag * frames;
     58     if ((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz &&
     59         buffer[pkt->data.frame.sz - index_sz] == marker) {
     60       // frame is a superframe. strip off the index.
     61       if (modified_buf_) delete[] modified_buf_;
     62       modified_buf_ = new uint8_t[pkt->data.frame.sz - index_sz];
     63       memcpy(modified_buf_, pkt->data.frame.buf, pkt->data.frame.sz - index_sz);
     64       modified_pkt_ = *pkt;
     65       modified_pkt_.data.frame.buf = modified_buf_;
     66       modified_pkt_.data.frame.sz -= index_sz;
     67 
     68       sf_count_++;
     69       last_sf_pts_ = pkt->data.frame.pts;
     70       return &modified_pkt_;
     71     }
     72 
     73     // Make sure we do a few frames after the last SF
     74     abort_ |=
     75         sf_count_ > sf_count_max_ && pkt->data.frame.pts - last_sf_pts_ >= 5;
     76     return pkt;
     77   }
     78 
     79   int sf_count_;
     80   int sf_count_max_;
     81   vpx_codec_cx_pkt_t modified_pkt_;
     82   uint8_t *modified_buf_;
     83   vpx_codec_pts_t last_sf_pts_;
     84 };
     85 
     86 TEST_P(SuperframeTest, TestSuperframeIndexIsOptional) {
     87   sf_count_max_ = 0;  // early exit on successful test.
     88   cfg_.g_lag_in_frames = 25;
     89 
     90   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
     91                                        30, 1, 0, 40);
     92   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
     93   EXPECT_EQ(sf_count_, 1);
     94 }
     95 
     96 VP9_INSTANTIATE_TEST_CASE(
     97     SuperframeTest,
     98     ::testing::Combine(::testing::Values(::libvpx_test::kTwoPassGood),
     99                        ::testing::Values(0)));
    100 }  // namespace
    101