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#include "test/codec_factory.h" 11#include "test/decode_test_driver.h" 12#include "third_party/googletest/src/include/gtest/gtest.h" 13#include "test/register_state_check.h" 14#include "test/video_source.h" 15 16namespace libvpx_test { 17 18const char kVP8Name[] = "WebM Project VP8"; 19 20vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size, 21 vpx_codec_stream_info_t *stream_info) { 22 return vpx_codec_peek_stream_info(CodecInterface(), 23 cxdata, static_cast<unsigned int>(size), 24 stream_info); 25} 26 27vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) { 28 return DecodeFrame(cxdata, size, NULL); 29} 30 31vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size, 32 void *user_priv) { 33 vpx_codec_err_t res_dec; 34 InitOnce(); 35 API_REGISTER_STATE_CHECK( 36 res_dec = vpx_codec_decode(&decoder_, 37 cxdata, static_cast<unsigned int>(size), 38 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) << "Peek return failed: " 57 << 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) << "Peek return failed: " 62 << 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, 0); 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(video->cxdata(), 82 video->frame_size(), 83 &stream_info); 84 HandlePeekResult(decoder, video, res_peek); 85 ASSERT_FALSE(::testing::Test::HasFailure()); 86 87 vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(), 88 video->frame_size()); 89 if (!HandleDecodeResult(res_dec, *video, decoder)) 90 break; 91 } else { 92 // Signal end of the file to the decoder. 93 const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0); 94 ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); 95 end_of_file = true; 96 } 97 98 DxDataIterator dec_iter = decoder->GetDxData(); 99 const vpx_image_t *img = NULL; 100 101 // Get decompressed data 102 while ((img = dec_iter.Next())) 103 DecompressedFrameHook(*img, video->frame_number()); 104 } 105 delete decoder; 106} 107 108void DecoderTest::RunLoop(CompressedVideoSource *video) { 109 vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); 110 RunLoop(video, dec_cfg); 111} 112 113} // namespace libvpx_test 114