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 11#include "third_party/googletest/src/include/gtest/gtest.h" 12 13#include "test/codec_factory.h" 14#include "test/decode_test_driver.h" 15#include "test/register_state_check.h" 16#include "test/video_source.h" 17 18namespace libvpx_test { 19 20const char kVP8Name[] = "WebM Project VP8"; 21 22vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size, 23 vpx_codec_stream_info_t *stream_info) { 24 return vpx_codec_peek_stream_info( 25 CodecInterface(), cxdata, static_cast<unsigned int>(size), stream_info); 26} 27 28vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) { 29 return DecodeFrame(cxdata, size, NULL); 30} 31 32vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size, 33 void *user_priv) { 34 vpx_codec_err_t res_dec; 35 InitOnce(); 36 API_REGISTER_STATE_CHECK( 37 res_dec = vpx_codec_decode( 38 &decoder_, cxdata, static_cast<unsigned int>(size), user_priv, 0)); 39 return res_dec; 40} 41 42bool Decoder::IsVP8() const { 43 const char *codec_name = GetDecoderName(); 44 return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0; 45} 46 47void DecoderTest::HandlePeekResult(Decoder *const decoder, 48 CompressedVideoSource *video, 49 const vpx_codec_err_t res_peek) { 50 const bool is_vp8 = decoder->IsVP8(); 51 if (is_vp8) { 52 /* Vp8's implementation of PeekStream returns an error if the frame you 53 * pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first 54 * frame, which must be a keyframe. */ 55 if (video->frame_number() == 0) 56 ASSERT_EQ(VPX_CODEC_OK, res_peek) 57 << "Peek return failed: " << vpx_codec_err_to_string(res_peek); 58 } else { 59 /* The Vp9 implementation of PeekStream returns an error only if the 60 * data passed to it isn't a valid Vp9 chunk. */ 61 ASSERT_EQ(VPX_CODEC_OK, res_peek) 62 << "Peek return failed: " << vpx_codec_err_to_string(res_peek); 63 } 64} 65 66void DecoderTest::RunLoop(CompressedVideoSource *video, 67 const vpx_codec_dec_cfg_t &dec_cfg) { 68 Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_); 69 ASSERT_TRUE(decoder != NULL); 70 bool end_of_file = false; 71 72 // Decode frames. 73 for (video->Begin(); !::testing::Test::HasFailure() && !end_of_file; 74 video->Next()) { 75 PreDecodeFrameHook(*video, decoder); 76 77 vpx_codec_stream_info_t stream_info; 78 stream_info.sz = sizeof(stream_info); 79 80 if (video->cxdata() != NULL) { 81 const vpx_codec_err_t res_peek = decoder->PeekStream( 82 video->cxdata(), video->frame_size(), &stream_info); 83 HandlePeekResult(decoder, video, res_peek); 84 ASSERT_FALSE(::testing::Test::HasFailure()); 85 86 vpx_codec_err_t res_dec = 87 decoder->DecodeFrame(video->cxdata(), video->frame_size()); 88 if (!HandleDecodeResult(res_dec, *video, decoder)) break; 89 } else { 90 // Signal end of the file to the decoder. 91 const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0); 92 ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); 93 end_of_file = true; 94 } 95 96 DxDataIterator dec_iter = decoder->GetDxData(); 97 const vpx_image_t *img = NULL; 98 99 // Get decompressed data 100 while ((img = dec_iter.Next())) { 101 DecompressedFrameHook(*img, video->frame_number()); 102 } 103 } 104 delete decoder; 105} 106 107void DecoderTest::RunLoop(CompressedVideoSource *video) { 108 vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); 109 RunLoop(video, dec_cfg); 110} 111 112void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) { 113 memcpy(&cfg_, &dec_cfg, sizeof(cfg_)); 114} 115 116void DecoderTest::set_flags(const vpx_codec_flags_t flags) { flags_ = flags; } 117 118} // namespace libvpx_test 119