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