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