1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2014 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 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <string> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/codec_factory.h" 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/decode_test_driver.h" 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/ivf_video_source.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/md5_helper.h" 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/test_vectors.h" 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/util.h" 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "test/webm_video_source.h" 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan 21233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace { 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan 23233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst int kVideoNameParam = 1; 24233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm"; 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan 26233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ExternalFrameBuffer { 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t *data; 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t size; 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan int in_use; 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Class to manipulate a list of external frame buffers. 33233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass ExternalFrameBufferList { 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan public: 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList() 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan : num_buffers_(0), 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_(NULL) {} 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual ~ExternalFrameBufferList() { 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (int i = 0; i < num_buffers_; ++i) { 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete [] ext_fb_list_[i].data; 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete [] ext_fb_list_; 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Creates the list to hold the external buffers. Returns true on success. 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan bool CreateBufferList(int num_buffers) { 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (num_buffers < 0) 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan return false; 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers_ = num_buffers; 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_ = new ExternalFrameBuffer[num_buffers_]; 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(ext_fb_list_ != NULL); 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_); 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan return true; 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Searches the frame buffer list for a free frame buffer. Makes sure 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan // that the frame buffer is at least |min_size| in bytes. Marks that the 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan // frame buffer is in use by libvpx. Finally sets |fb| to point to the 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan // external frame buffer. Returns < 0 on an error. 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) { 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(fb != NULL); 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx = FindFreeBufferIndex(); 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (idx == num_buffers_) 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ext_fb_list_[idx].size < min_size) { 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete [] ext_fb_list_[idx].data; 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_[idx].data = new uint8_t[min_size]; 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_[idx].size = min_size; 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBuffer(idx, fb); 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Test function that will not allocate any data for the frame buffer. 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Returns < 0 on an error. 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) { 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(fb != NULL); 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx = FindFreeBufferIndex(); 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (idx == num_buffers_) 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ext_fb_list_[idx].size < min_size) { 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete [] ext_fb_list_[idx].data; 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_[idx].data = NULL; 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_[idx].size = min_size; 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBuffer(idx, fb); 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Marks the external frame buffer that |fb| is pointing too as free. 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Returns < 0 on an error. 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) { 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(fb != NULL); 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBuffer *const ext_fb = 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBuffer*>(fb->priv); 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(ext_fb != NULL); 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_EQ(1, ext_fb->in_use); 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb->in_use = 0; 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Checks that the ximage data is contained within the external frame buffer 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan // private data passed back in the ximage. 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan void CheckXImageFrameBuffer(const vpx_image_t *img) { 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (img->fb_priv != NULL) { 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct ExternalFrameBuffer *const ext_fb = 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBuffer*>(img->fb_priv); 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(img->planes[0] >= ext_fb->data && 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan img->planes[0] < (ext_fb->data + ext_fb->size)); 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan private: 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Returns the index of the first free frame buffer. Returns |num_buffers_| 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan // if there are no free frame buffers. 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan int FindFreeBufferIndex() { 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find a free frame buffer. 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < num_buffers_; ++i) { 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!ext_fb_list_[i].in_use) 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan return i; 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Sets |fb| to an external frame buffer. idx is the index into the frame 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan // buffer list. 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan void SetFrameBuffer(int idx, vpx_codec_frame_buffer_t *fb) { 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(fb != NULL); 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan fb->data = ext_fb_list_[idx].data; 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan fb->size = ext_fb_list_[idx].size; 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(0, ext_fb_list_[idx].in_use); 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan ext_fb_list_[idx].in_use = 1; 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan fb->priv = &ext_fb_list_[idx]; 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan int num_buffers_; 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBuffer *ext_fb_list_; 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Callback used by libvpx to request the application to return a frame 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan// buffer of at least |min_size| in bytes. 150233d2500723e5594f3e7c70896ffeeef32b9c950ywanint get_vp9_frame_buffer(void *user_priv, size_t min_size, 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList *const fb_list = 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBufferList*>(user_priv); 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan return fb_list->GetFreeFrameBuffer(min_size, fb); 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Callback used by libvpx to tell the application that |fb| is not needed 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan// anymore. 159233d2500723e5594f3e7c70896ffeeef32b9c950ywanint release_vp9_frame_buffer(void *user_priv, 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList *const fb_list = 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBufferList*>(user_priv); 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan return fb_list->ReturnFrameBuffer(fb); 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Callback will not allocate data for frame buffer. 167233d2500723e5594f3e7c70896ffeeef32b9c950ywanint get_vp9_zero_frame_buffer(void *user_priv, size_t min_size, 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList *const fb_list = 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBufferList*>(user_priv); 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan return fb_list->GetZeroFrameBuffer(min_size, fb); 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Callback will allocate one less byte than |min_size|. 175233d2500723e5594f3e7c70896ffeeef32b9c950ywanint get_vp9_one_less_byte_frame_buffer(void *user_priv, size_t min_size, 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList *const fb_list = 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBufferList*>(user_priv); 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan return fb_list->GetFreeFrameBuffer(min_size - 1, fb); 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Callback will not release the external frame buffer. 183233d2500723e5594f3e7c70896ffeeef32b9c950ywanint do_not_release_vp9_frame_buffer(void *user_priv, 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)user_priv; 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)fb; 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Class for testing passing in external frame buffers to libvpx. 191233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass ExternalFrameBufferMD5Test 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan : public ::libvpx_test::DecoderTest, 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan public ::libvpx_test::CodecTestWithParam<const char*> { 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected: 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferMD5Test() 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)), 197233d2500723e5594f3e7c70896ffeeef32b9c950ywan md5_file_(NULL), 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers_(0) {} 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual ~ExternalFrameBufferMD5Test() { 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (md5_file_ != NULL) 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(md5_file_); 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void PreDecodeFrameHook( 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan const libvpx_test::CompressedVideoSource &video, 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::Decoder *decoder) { 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (num_buffers_ > 0 && video.frame_number() == 0) { 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Have libvpx use frame buffers we create. 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_)); 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder->SetFrameBufferFunctions( 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan GetVP9FrameBuffer, ReleaseVP9FrameBuffer, this)); 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan void OpenMD5File(const std::string &md5_file_name_) { 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: " 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan << md5_file_name_; 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void DecompressedFrameHook(const vpx_image_t &img, 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int frame_number) { 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(md5_file_ != NULL); 226233d2500723e5594f3e7c70896ffeeef32b9c950ywan char expected_md5[33]; 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan char junk[128]; 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Read correct md5 checksums. 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int res = fscanf(md5_file_, "%s %s", expected_md5, junk); 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_NE(EOF, res) << "Read md5 data failed"; 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan expected_md5[32] = '\0'; 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan ::libvpx_test::MD5 md5_res; 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan md5_res.Add(&img); 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan const char *const actual_md5 = md5_res.Get(); 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check md5 match. 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_STREQ(expected_md5, actual_md5) 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan << "Md5 checksums don't match: frame number = " << frame_number; 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan 243233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Callback to get a free external frame buffer. Return value < 0 is an 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan // error. 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan static int GetVP9FrameBuffer(void *user_priv, size_t min_size, 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 247233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferMD5Test *const md5Test = 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBufferMD5Test*>(user_priv); 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb); 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Callback to release an external frame buffer. Return value < 0 is an 253233d2500723e5594f3e7c70896ffeeef32b9c950ywan // error. 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan static int ReleaseVP9FrameBuffer(void *user_priv, 255233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_frame_buffer_t *fb) { 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferMD5Test *const md5Test = 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan reinterpret_cast<ExternalFrameBufferMD5Test*>(user_priv); 258233d2500723e5594f3e7c70896ffeeef32b9c950ywan return md5Test->fb_list_.ReturnFrameBuffer(fb); 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 260233d2500723e5594f3e7c70896ffeeef32b9c950ywan 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; } 262233d2500723e5594f3e7c70896ffeeef32b9c950ywan int num_buffers() const { return num_buffers_; } 263233d2500723e5594f3e7c70896ffeeef32b9c950ywan 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan private: 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan FILE *md5_file_; 266233d2500723e5594f3e7c70896ffeeef32b9c950ywan int num_buffers_; 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList fb_list_; 268233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Class for testing passing in external frame buffers to libvpx. 271233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass ExternalFrameBufferTest : public ::testing::Test { 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected: 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferTest() 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan : video_(NULL), 275233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder_(NULL), 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers_(0) {} 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void SetUp() { 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan video_ = new libvpx_test::WebMVideoSource(kVP9TestFile); 280233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(video_ != NULL); 281233d2500723e5594f3e7c70896ffeeef32b9c950ywan video_->Init(); 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan video_->Begin(); 283233d2500723e5594f3e7c70896ffeeef32b9c950ywan 284233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_dec_cfg_t cfg = {0}; 285233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder_ = new libvpx_test::VP9Decoder(cfg, 0); 286233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(decoder_ != NULL); 287233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 288233d2500723e5594f3e7c70896ffeeef32b9c950ywan 289233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void TearDown() { 290233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete decoder_; 291233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete video_; 292233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 293233d2500723e5594f3e7c70896ffeeef32b9c950ywan 294233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Passes the external frame buffer information to libvpx. 295233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t SetFrameBufferFunctions( 296233d2500723e5594f3e7c70896ffeeef32b9c950ywan int num_buffers, 297233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_get_frame_buffer_cb_fn_t cb_get, 298233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_release_frame_buffer_cb_fn_t cb_release) { 299233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (num_buffers > 0) { 300233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers_ = num_buffers; 301233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_)); 302233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 303233d2500723e5594f3e7c70896ffeeef32b9c950ywan 304233d2500723e5594f3e7c70896ffeeef32b9c950ywan return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_); 305233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 306233d2500723e5594f3e7c70896ffeeef32b9c950ywan 307233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t DecodeOneFrame() { 308233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_err_t res = 309233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); 310233d2500723e5594f3e7c70896ffeeef32b9c950ywan CheckDecodedFrames(); 311233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res == VPX_CODEC_OK) 312233d2500723e5594f3e7c70896ffeeef32b9c950ywan video_->Next(); 313233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 314233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 315233d2500723e5594f3e7c70896ffeeef32b9c950ywan 316233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t DecodeRemainingFrames() { 317233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (; video_->cxdata() != NULL; video_->Next()) { 318233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_err_t res = 319233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); 320233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res != VPX_CODEC_OK) 321233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 322233d2500723e5594f3e7c70896ffeeef32b9c950ywan CheckDecodedFrames(); 323233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 324233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 325233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 326233d2500723e5594f3e7c70896ffeeef32b9c950ywan 327233d2500723e5594f3e7c70896ffeeef32b9c950ywan private: 328233d2500723e5594f3e7c70896ffeeef32b9c950ywan void CheckDecodedFrames() { 329233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData(); 330233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_image_t *img = NULL; 331233d2500723e5594f3e7c70896ffeeef32b9c950ywan 332233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Get decompressed data 333233d2500723e5594f3e7c70896ffeeef32b9c950ywan while ((img = dec_iter.Next()) != NULL) { 334233d2500723e5594f3e7c70896ffeeef32b9c950ywan fb_list_.CheckXImageFrameBuffer(img); 335233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 336233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 337233d2500723e5594f3e7c70896ffeeef32b9c950ywan 338233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::WebMVideoSource *video_; 339233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::VP9Decoder *decoder_; 340233d2500723e5594f3e7c70896ffeeef32b9c950ywan int num_buffers_; 341233d2500723e5594f3e7c70896ffeeef32b9c950ywan ExternalFrameBufferList fb_list_; 342233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 343233d2500723e5594f3e7c70896ffeeef32b9c950ywan 344233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This test runs through the set of test vectors, and decodes them. 345233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Libvpx will call into the application to allocate a frame buffer when 346233d2500723e5594f3e7c70896ffeeef32b9c950ywan// needed. The md5 checksums are computed for each frame in the video file. 347233d2500723e5594f3e7c70896ffeeef32b9c950ywan// If md5 checksums match the correct md5 data, then the test is passed. 348233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Otherwise, the test failed. 349233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) { 350233d2500723e5594f3e7c70896ffeeef32b9c950ywan const std::string filename = GET_PARAM(kVideoNameParam); 351233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::CompressedVideoSource *video = NULL; 352233d2500723e5594f3e7c70896ffeeef32b9c950ywan 353233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS + 354233d2500723e5594f3e7c70896ffeeef32b9c950ywan // #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers. 355233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int jitter_buffers = 4; 356233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = 357233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers; 358233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_num_buffers(num_buffers); 359233d2500723e5594f3e7c70896ffeeef32b9c950ywan 360233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_VP8_DECODER 361233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Tell compiler we are not using kVP8TestVectors. 362233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)libvpx_test::kVP8TestVectors; 363233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 364233d2500723e5594f3e7c70896ffeeef32b9c950ywan 365233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Open compressed video file. 366233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (filename.substr(filename.length() - 3, 3) == "ivf") { 367233d2500723e5594f3e7c70896ffeeef32b9c950ywan video = new libvpx_test::IVFVideoSource(filename); 368233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 369233d2500723e5594f3e7c70896ffeeef32b9c950ywan video = new libvpx_test::WebMVideoSource(filename); 370233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 371233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_TRUE(video != NULL); 372233d2500723e5594f3e7c70896ffeeef32b9c950ywan video->Init(); 373233d2500723e5594f3e7c70896ffeeef32b9c950ywan 374233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Construct md5 file name. 375233d2500723e5594f3e7c70896ffeeef32b9c950ywan const std::string md5_filename = filename + ".md5"; 376233d2500723e5594f3e7c70896ffeeef32b9c950ywan OpenMD5File(md5_filename); 377233d2500723e5594f3e7c70896ffeeef32b9c950ywan 378233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Decode frame, and check the md5 matching. 379233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_NO_FATAL_FAILURE(RunLoop(video)); 380233d2500723e5594f3e7c70896ffeeef32b9c950ywan delete video; 381233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 382233d2500723e5594f3e7c70896ffeeef32b9c950ywan 383233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, MinFrameBuffers) { 384233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Minimum number of external frame buffers for VP9 is 385233d2500723e5594f3e7c70896ffeeef32b9c950ywan // #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. 386233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 387233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 388233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions( 389233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer)); 390233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames()); 391233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 392233d2500723e5594f3e7c70896ffeeef32b9c950ywan 393233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, EightJitterBuffers) { 394233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS + 395233d2500723e5594f3e7c70896ffeeef32b9c950ywan // #VPX_MAXIMUM_WORK_BUFFERS + eight jitter buffers. 396233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int jitter_buffers = 8; 397233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = 398233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers; 399233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 400233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions( 401233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer)); 402233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames()); 403233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 404233d2500723e5594f3e7c70896ffeeef32b9c950ywan 405233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, NotEnoughBuffers) { 406233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Minimum number of external frame buffers for VP9 is 407233d2500723e5594f3e7c70896ffeeef32b9c950ywan // #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. Most files will 408233d2500723e5594f3e7c70896ffeeef32b9c950ywan // only use 5 frame buffers at one time. 409233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = 2; 410233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 411233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions( 412233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer)); 413233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame()); 414233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames()); 415233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 416233d2500723e5594f3e7c70896ffeeef32b9c950ywan 417233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, NoRelease) { 418233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 419233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 420233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, 421233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_not_release_vp9_frame_buffer)); 422233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame()); 423233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames()); 424233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 425233d2500723e5594f3e7c70896ffeeef32b9c950ywan 426233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, NullRealloc) { 427233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 428233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 429233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions(num_buffers, get_vp9_zero_frame_buffer, 430233d2500723e5594f3e7c70896ffeeef32b9c950ywan release_vp9_frame_buffer)); 431233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame()); 432233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 433233d2500723e5594f3e7c70896ffeeef32b9c950ywan 434233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, ReallocOneLessByte) { 435233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 436233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, 437233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions( 438233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers, get_vp9_one_less_byte_frame_buffer, 439233d2500723e5594f3e7c70896ffeeef32b9c950ywan release_vp9_frame_buffer)); 440233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame()); 441233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 442233d2500723e5594f3e7c70896ffeeef32b9c950ywan 443233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, NullGetFunction) { 444233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 445233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_INVALID_PARAM, 446233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions(num_buffers, NULL, 447233d2500723e5594f3e7c70896ffeeef32b9c950ywan release_vp9_frame_buffer)); 448233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 449233d2500723e5594f3e7c70896ffeeef32b9c950ywan 450233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, NullReleaseFunction) { 451233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 452233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_INVALID_PARAM, 453233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, NULL)); 454233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 455233d2500723e5594f3e7c70896ffeeef32b9c950ywan 456233d2500723e5594f3e7c70896ffeeef32b9c950ywanTEST_F(ExternalFrameBufferTest, SetAfterDecode) { 457233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; 458233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame()); 459233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_ERROR, 460233d2500723e5594f3e7c70896ffeeef32b9c950ywan SetFrameBufferFunctions( 461233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer)); 462233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 463233d2500723e5594f3e7c70896ffeeef32b9c950ywan 464233d2500723e5594f3e7c70896ffeeef32b9c950ywanVP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test, 465233d2500723e5594f3e7c70896ffeeef32b9c950ywan ::testing::ValuesIn(libvpx_test::kVP9TestVectors, 466233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::kVP9TestVectors + 467233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::kNumVP9TestVectors)); 468233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace 469