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