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
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef TEST_DECODE_TEST_DRIVER_H_
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TEST_DECODE_TEST_DRIVER_H_
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <cstring>
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "third_party/googletest/src/include/gtest/gtest.h"
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_config.h"
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_decoder.h"
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan
18233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace libvpx_test {
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan
20233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass CodecFactory;
21233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass CompressedVideoSource;
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Provides an object to handle decoding output
24233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass DxDataIterator {
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan public:
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan  explicit DxDataIterator(vpx_codec_ctx_t *decoder)
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan      : decoder_(decoder), iter_(NULL) {}
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const vpx_image_t *Next() {
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return vpx_codec_get_frame(decoder_, &iter_);
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan private:
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_codec_ctx_t  *decoder_;
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_codec_iter_t  iter_;
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Provides a simplified interface to manage one video decoding.
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Similar to Encoder class, the exact services should be added
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan// as more tests are added.
41233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Decoder {
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan public:
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan  Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan      : cfg_(cfg), deadline_(deadline), init_done_(false) {
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memset(&decoder_, 0, sizeof(decoder_));
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan  virtual ~Decoder() {
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_codec_destroy(&decoder_);
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size);
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan  DxDataIterator GetDxData() {
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return DxDataIterator(&decoder_);
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan  void set_deadline(unsigned long deadline) {
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan    deadline_ = deadline;
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan  void Control(int ctrl_id, int arg) {
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan    InitOnce();
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg);
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan  void Control(int ctrl_id, const void *arg) {
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan    InitOnce();
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg);
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const char* DecodeError() {
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char *detail = vpx_codec_error_detail(&decoder_);
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return detail ? detail : vpx_codec_error(&decoder_);
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Passes the external frame buffer information to libvpx.
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_codec_err_t SetFrameBufferFunctions(
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_get_frame_buffer_cb_fn_t cb_get,
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan    InitOnce();
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return vpx_codec_set_frame_buffer_functions(
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan        &decoder_, cb_get, cb_release, user_priv);
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected:
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan  virtual vpx_codec_iface_t* CodecInterface() const = 0;
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan  void InitOnce() {
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!init_done_) {
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                     CodecInterface(),
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                     &cfg_, 0);
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan      init_done_ = true;
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_codec_ctx_t     decoder_;
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_codec_dec_cfg_t cfg_;
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned int        deadline_;
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bool                init_done_;
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Common test functionality for all Decoder tests.
108233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass DecoderTest {
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan public:
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Main decoding loop
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan  virtual void RunLoop(CompressedVideoSource *video);
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan
113233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Hook to be called before decompressing every frame.
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan  virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  Decoder *decoder) {}
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Hook to be called on every decompressed frame.
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan  virtual void DecompressedFrameHook(const vpx_image_t& img,
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     const unsigned int frame_number) {}
120233d2500723e5594f3e7c70896ffeeef32b9c950ywan
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected:
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan  explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {}
123233d2500723e5594f3e7c70896ffeeef32b9c950ywan
124233d2500723e5594f3e7c70896ffeeef32b9c950ywan  virtual ~DecoderTest() {}
125233d2500723e5594f3e7c70896ffeeef32b9c950ywan
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const CodecFactory *codec_;
127233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan
129233d2500723e5594f3e7c70896ffeeef32b9c950ywan}  // namespace libvpx_test
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif  // TEST_DECODE_TEST_DRIVER_H_
132