1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <climits> 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "third_party/googletest/src/include/gtest/gtest.h" 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/codec_factory.h" 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/encode_test_driver.h" 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/i420_video_source.h" 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/util.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan 17233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace { 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan 19233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass SuperframeTest : public ::libvpx_test::EncoderTest, 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> { 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected: 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan SuperframeTest() : EncoderTest(GET_PARAM(0)), modified_buf_(NULL), 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_sf_pts_(0) {} 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual ~SuperframeTest() {} 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void SetUp() { 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan InitializeConfig(); 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetMode(GET_PARAM(1)); 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan sf_count_ = 0; 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan sf_count_max_ = INT_MAX; 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void TearDown() { 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete[] modified_buf_; 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::Encoder *encoder) { 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (video->frame() == 1) { 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual const vpx_codec_cx_pkt_t * MutateEncoderOutputHook( 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_cx_pkt_t *pkt) { 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan return pkt; 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *buffer = reinterpret_cast<uint8_t*>(pkt->data.frame.buf); 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t marker = buffer[pkt->data.frame.sz - 1]; 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int frames = (marker & 0x7) + 1; 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mag = ((marker >> 3) & 3) + 1; 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int index_sz = 2 + mag * frames; 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((marker & 0xe0) == 0xc0 && 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->data.frame.sz >= index_sz && 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan buffer[pkt->data.frame.sz - index_sz] == marker) { 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan // frame is a superframe. strip off the index. 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (modified_buf_) 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete[] modified_buf_; 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan modified_buf_ = new uint8_t[pkt->data.frame.sz - index_sz]; 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan memcpy(modified_buf_, pkt->data.frame.buf, 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->data.frame.sz - index_sz); 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan modified_pkt_ = *pkt; 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan modified_pkt_.data.frame.buf = modified_buf_; 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan modified_pkt_.data.frame.sz -= index_sz; 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan sf_count_++; 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_sf_pts_ = pkt->data.frame.pts; 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &modified_pkt_; 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Make sure we do a few frames after the last SF 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan abort_ |= sf_count_ > sf_count_max_ && 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->data.frame.pts - last_sf_pts_ >= 5; 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan return pkt; 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sf_count_; 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sf_count_max_; 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_cx_pkt_t modified_pkt_; 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t *modified_buf_; 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_pts_t last_sf_pts_; 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan 85233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_P(SuperframeTest, TestSuperframeIndexIsOptional) { 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan sf_count_max_ = 0; // early exit on successful test. 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg_.g_lag_in_frames = 25; 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan 30, 1, 0, 40); 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_EQ(sf_count_, 1); 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan 95233d2500723e5594f3e7c70896ffeeef32b9c950ywanVP9_INSTANTIATE_TEST_CASE(SuperframeTest, ::testing::Values( 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan ::libvpx_test::kTwoPassGood)); 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace 98