John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| 10 | */ |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 11 | |
Frank Galligan | 89df6d1 | 2015-03-09 15:52:29 -0700 | [diff] [blame] | 12 | #include <string> |
| 13 | |
Jingning Han | 097d59c | 2015-07-29 14:51:36 -0700 | [diff] [blame] | 14 | #include "third_party/googletest/src/include/gtest/gtest.h" |
| 15 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 16 | #include "./aom_config.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | #include "aom_ports/mem.h" |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 18 | #include "test/codec_factory.h" |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 19 | #include "test/decode_test_driver.h" |
Jingning Han | 097d59c | 2015-07-29 14:51:36 -0700 | [diff] [blame] | 20 | #include "test/encode_test_driver.h" |
James Zern | eebb648 | 2012-11-27 13:08:05 -0800 | [diff] [blame] | 21 | #include "test/register_state_check.h" |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 22 | #include "test/video_source.h" |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 23 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 24 | namespace libaom_test { |
Yunqing Wang | 3666478 | 2014-12-12 14:34:30 -0800 | [diff] [blame] | 25 | void Encoder::InitEncoder(VideoSource *video) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 26 | aom_codec_err_t res; |
| 27 | const aom_image_t *img = video->img(); |
Yunqing Wang | 3666478 | 2014-12-12 14:34:30 -0800 | [diff] [blame] | 28 | |
| 29 | if (video->img() && !encoder_.priv) { |
| 30 | cfg_.g_w = img->d_w; |
| 31 | cfg_.g_h = img->d_h; |
| 32 | cfg_.g_timebase = video->timebase(); |
| 33 | cfg_.rc_twopass_stats_in = stats_->buf(); |
Frank Galligan | 89df6d1 | 2015-03-09 15:52:29 -0700 | [diff] [blame] | 34 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 35 | res = aom_codec_enc_init(&encoder_, CodecInterface(), &cfg_, init_flags_); |
| 36 | ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); |
Frank Galligan | 89df6d1 | 2015-03-09 15:52:29 -0700 | [diff] [blame] | 37 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 38 | #if CONFIG_AV1_ENCODER |
| 39 | if (CodecInterface() == &aom_codec_av1_cx_algo) { |
| 40 | // Default to 1 tile column for AV1. With CONFIG_EXT_TILE, the |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 41 | // default is already the largest possible tile size |
Geza Lore | 67a2ff7 | 2016-05-03 11:53:55 +0100 | [diff] [blame] | 42 | #if !CONFIG_EXT_TILE |
Jingning Han | 41be09a | 2015-08-19 14:13:18 -0700 | [diff] [blame] | 43 | const int log2_tile_columns = 0; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 44 | res = aom_codec_control_(&encoder_, AV1E_SET_TILE_COLUMNS, |
Jingning Han | 41be09a | 2015-08-19 14:13:18 -0700 | [diff] [blame] | 45 | log2_tile_columns); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 46 | ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); |
Geza Lore | 67a2ff7 | 2016-05-03 11:53:55 +0100 | [diff] [blame] | 47 | #endif // !CONFIG_EXT_TILE |
Jingning Han | 41be09a | 2015-08-19 14:13:18 -0700 | [diff] [blame] | 48 | } else |
| 49 | #endif |
Yaowu Xu | 0924bcd | 2016-05-20 11:33:07 -0700 | [diff] [blame] | 50 | { |
Frank Galligan | 89df6d1 | 2015-03-09 15:52:29 -0700 | [diff] [blame] | 51 | } |
Yunqing Wang | 3666478 | 2014-12-12 14:34:30 -0800 | [diff] [blame] | 52 | } |
| 53 | } |
| 54 | |
Adrian Grange | 4206c6d | 2012-10-02 11:03:09 -0700 | [diff] [blame] | 55 | void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) { |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 56 | if (video->img()) |
Adrian Grange | 4206c6d | 2012-10-02 11:03:09 -0700 | [diff] [blame] | 57 | EncodeFrameInternal(*video, frame_flags); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 58 | else |
| 59 | Flush(); |
| 60 | |
| 61 | // Handle twopass stats |
| 62 | CxDataIterator iter = GetCxData(); |
| 63 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 64 | while (const aom_codec_cx_pkt_t *pkt = iter.Next()) { |
| 65 | if (pkt->kind != AOM_CODEC_STATS_PKT) continue; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 66 | |
| 67 | stats_->Append(*pkt); |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | void Encoder::EncodeFrameInternal(const VideoSource &video, |
Adrian Grange | 4206c6d | 2012-10-02 11:03:09 -0700 | [diff] [blame] | 72 | const unsigned long frame_flags) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 73 | aom_codec_err_t res; |
| 74 | const aom_image_t *img = video.img(); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 75 | |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 76 | // Handle frame resizing |
| 77 | if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) { |
| 78 | cfg_.g_w = img->d_w; |
| 79 | cfg_.g_h = img->d_h; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 80 | res = aom_codec_enc_config_set(&encoder_, &cfg_); |
| 81 | ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | // Encode the frame |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 85 | API_REGISTER_STATE_CHECK(res = aom_codec_encode(&encoder_, img, video.pts(), |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 86 | video.duration(), frame_flags, |
| 87 | deadline_)); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 88 | ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | void Encoder::Flush() { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 92 | const aom_codec_err_t res = |
| 93 | aom_codec_encode(&encoder_, NULL, 0, 0, 0, deadline_); |
Deb Mukherjee | bdbaa5b | 2014-07-18 03:06:07 -0700 | [diff] [blame] | 94 | if (!encoder_.priv) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 95 | ASSERT_EQ(AOM_CODEC_ERROR, res) << EncoderError(); |
Deb Mukherjee | bdbaa5b | 2014-07-18 03:06:07 -0700 | [diff] [blame] | 96 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 97 | ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError(); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 98 | } |
| 99 | |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 100 | void EncoderTest::InitializeConfig() { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 101 | const aom_codec_err_t res = codec_->DefaultEncoderConfig(&cfg_, 0); |
| 102 | dec_cfg_ = aom_codec_dec_cfg_t(); |
| 103 | ASSERT_EQ(AOM_CODEC_OK, res); |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 104 | } |
| 105 | |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 106 | void EncoderTest::SetMode(TestMode mode) { |
| 107 | switch (mode) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 108 | case kRealTime: deadline_ = AOM_DL_REALTIME; break; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 109 | |
| 110 | case kOnePassGood: |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 111 | case kTwoPassGood: deadline_ = AOM_DL_GOOD_QUALITY; break; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 112 | |
| 113 | case kOnePassBest: |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 114 | case kTwoPassBest: deadline_ = AOM_DL_BEST_QUALITY; break; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 115 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 116 | default: ASSERT_TRUE(false) << "Unexpected mode " << mode; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | if (mode == kTwoPassGood || mode == kTwoPassBest) |
| 120 | passes_ = 2; |
| 121 | else |
| 122 | passes_ = 1; |
| 123 | } |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 124 | |
| 125 | static bool compare_plane(const uint8_t *const buf1, const int stride1, |
| 126 | const uint8_t *const buf2, const int stride2, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 127 | const int w, const int h, int *const mismatch_row, |
| 128 | int *const mismatch_col, int *const mismatch_pix1, |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 129 | int *const mismatch_pix2) { |
| 130 | int r, c; |
| 131 | |
| 132 | for (r = 0; r < h; ++r) { |
| 133 | for (c = 0; c < w; ++c) { |
| 134 | const int pix1 = buf1[r * stride1 + c]; |
| 135 | const int pix2 = buf2[r * stride2 + c]; |
| 136 | |
| 137 | if (pix1 != pix2) { |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 138 | if (mismatch_row != NULL) *mismatch_row = r; |
| 139 | if (mismatch_col != NULL) *mismatch_col = c; |
| 140 | if (mismatch_pix1 != NULL) *mismatch_pix1 = pix1; |
| 141 | if (mismatch_pix2 != NULL) *mismatch_pix2 = pix2; |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 142 | return false; |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | return true; |
| 148 | } |
| 149 | |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 150 | // The function should return "true" most of the time, therefore no early |
| 151 | // break-out is implemented within the match checking process. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 152 | static bool compare_img(const aom_image_t *img1, const aom_image_t *img2, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 153 | int *const mismatch_row, int *const mismatch_col, |
| 154 | int *const mismatch_plane, int *const mismatch_pix1, |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 155 | int *const mismatch_pix2) { |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 156 | const unsigned int w_y = img1->d_w; |
| 157 | const unsigned int h_y = img1->d_h; |
Pascal Massimino | e5fb2d4 | 2016-07-11 06:17:17 -0700 | [diff] [blame] | 158 | const unsigned int w_uv = ROUND_POWER_OF_TWO(w_y, img1->x_chroma_shift); |
| 159 | const unsigned int h_uv = ROUND_POWER_OF_TWO(h_y, img1->y_chroma_shift); |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 160 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 161 | if (img1->fmt != img2->fmt || img1->cs != img2->cs || |
| 162 | img1->d_w != img2->d_w || img1->d_h != img2->d_h) { |
| 163 | if (mismatch_row != NULL) *mismatch_row = -1; |
| 164 | if (mismatch_col != NULL) *mismatch_col = -1; |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 165 | return false; |
| 166 | } |
| 167 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 168 | if (!compare_plane(img1->planes[AOM_PLANE_Y], img1->stride[AOM_PLANE_Y], |
| 169 | img2->planes[AOM_PLANE_Y], img2->stride[AOM_PLANE_Y], w_y, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 170 | h_y, mismatch_row, mismatch_col, mismatch_pix1, |
| 171 | mismatch_pix2)) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 172 | if (mismatch_plane != NULL) *mismatch_plane = AOM_PLANE_Y; |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 173 | return false; |
| 174 | } |
| 175 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 176 | if (!compare_plane(img1->planes[AOM_PLANE_U], img1->stride[AOM_PLANE_U], |
| 177 | img2->planes[AOM_PLANE_U], img2->stride[AOM_PLANE_U], w_uv, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 178 | h_uv, mismatch_row, mismatch_col, mismatch_pix1, |
| 179 | mismatch_pix2)) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 180 | if (mismatch_plane != NULL) *mismatch_plane = AOM_PLANE_U; |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 181 | return false; |
| 182 | } |
| 183 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 184 | if (!compare_plane(img1->planes[AOM_PLANE_V], img1->stride[AOM_PLANE_V], |
| 185 | img2->planes[AOM_PLANE_V], img2->stride[AOM_PLANE_V], w_uv, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 186 | h_uv, mismatch_row, mismatch_col, mismatch_pix1, |
| 187 | mismatch_pix2)) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 188 | if (mismatch_plane != NULL) *mismatch_plane = AOM_PLANE_U; |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 189 | return false; |
| 190 | } |
| 191 | |
| 192 | return true; |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 193 | } |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 194 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 195 | void EncoderTest::MismatchHook(const aom_image_t *img_enc, |
| 196 | const aom_image_t *img_dec) { |
Geza Lore | 7de2ba3 | 2016-06-19 21:35:01 +0100 | [diff] [blame] | 197 | int mismatch_row = 0; |
| 198 | int mismatch_col = 0; |
| 199 | int mismatch_plane = 0; |
| 200 | int mismatch_pix_enc = 0; |
| 201 | int mismatch_pix_dec = 0; |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 202 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 203 | ASSERT_FALSE(compare_img(img_enc, img_dec, &mismatch_row, &mismatch_col, |
| 204 | &mismatch_plane, &mismatch_pix_enc, |
Geza Lore | e0dcab9 | 2016-05-09 13:19:34 +0100 | [diff] [blame] | 205 | &mismatch_pix_dec)); |
| 206 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 207 | GTEST_FAIL() << "Encode/Decode mismatch found:" << std::endl |
| 208 | << " pixel value enc/dec: " << mismatch_pix_enc << "/" |
| 209 | << mismatch_pix_dec << std::endl |
| 210 | << " plane: " << mismatch_plane << std::endl |
| 211 | << " row/col: " << mismatch_row << "/" |
| 212 | << mismatch_col << std::endl; |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 213 | } |
| 214 | |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 215 | void EncoderTest::RunLoop(VideoSource *video) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 216 | aom_codec_dec_cfg_t dec_cfg = aom_codec_dec_cfg_t(); |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 217 | |
Adrian Grange | 30f58b5 | 2012-10-02 09:36:41 -0700 | [diff] [blame] | 218 | stats_.Reset(); |
| 219 | |
Ronald S. Bultje | e189edf | 2013-03-01 12:43:10 -0800 | [diff] [blame] | 220 | ASSERT_TRUE(passes_ == 1 || passes_ == 2); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 221 | for (unsigned int pass = 0; pass < passes_; pass++) { |
James Zern | 51ebb9a | 2012-08-08 14:16:08 -0700 | [diff] [blame] | 222 | last_pts_ = 0; |
| 223 | |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 224 | if (passes_ == 1) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 225 | cfg_.g_pass = AOM_RC_ONE_PASS; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 226 | else if (pass == 0) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 227 | cfg_.g_pass = AOM_RC_FIRST_PASS; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 228 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 229 | cfg_.g_pass = AOM_RC_LAST_PASS; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 230 | |
| 231 | BeginPassHook(pass); |
Alex Converse | 1c1bc94 | 2016-07-21 11:36:41 -0700 | [diff] [blame] | 232 | testing::internal::scoped_ptr<Encoder> encoder( |
| 233 | codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_)); |
| 234 | ASSERT_TRUE(encoder.get() != NULL); |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 235 | |
Alex Converse | 1c1bc94 | 2016-07-21 11:36:41 -0700 | [diff] [blame] | 236 | ASSERT_NO_FATAL_FAILURE(video->Begin()); |
Yunqing Wang | 3666478 | 2014-12-12 14:34:30 -0800 | [diff] [blame] | 237 | encoder->InitEncoder(video); |
James Zern | d1ff1e9 | 2015-08-27 16:05:52 -0700 | [diff] [blame] | 238 | ASSERT_FALSE(::testing::Test::HasFatalFailure()); |
Yunqing Wang | 3666478 | 2014-12-12 14:34:30 -0800 | [diff] [blame] | 239 | |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 240 | unsigned long dec_init_flags = 0; // NOLINT |
| 241 | // Use fragment decoder if encoder outputs partitions. |
| 242 | // NOTE: fragment decoder and partition encoder are only supported by VP8. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 243 | if (init_flags_ & AOM_CODEC_USE_OUTPUT_PARTITION) |
| 244 | dec_init_flags |= AOM_CODEC_USE_INPUT_FRAGMENTS; |
Alex Converse | 1c1bc94 | 2016-07-21 11:36:41 -0700 | [diff] [blame] | 245 | testing::internal::scoped_ptr<Decoder> decoder( |
| 246 | codec_->CreateDecoder(dec_cfg, dec_init_flags, 0)); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 247 | #if CONFIG_AV1 && CONFIG_EXT_TILE |
| 248 | if (decoder->IsAV1()) { |
Yunqing Wang | 8e5e338 | 2016-05-05 16:42:57 -0700 | [diff] [blame] | 249 | // Set dec_cfg.tile_row = -1 and dec_cfg.tile_col = -1 so that the whole |
| 250 | // frame is decoded. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 251 | decoder->Control(AV1_SET_DECODE_TILE_ROW, -1); |
| 252 | decoder->Control(AV1_SET_DECODE_TILE_COL, -1); |
Yunqing Wang | 8e5e338 | 2016-05-05 16:42:57 -0700 | [diff] [blame] | 253 | } |
| 254 | #endif |
| 255 | |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 256 | bool again; |
Yunqing Wang | 3666478 | 2014-12-12 14:34:30 -0800 | [diff] [blame] | 257 | for (again = true; again; video->Next()) { |
Deb Mukherjee | 0d8723f | 2013-08-19 14:16:26 -0700 | [diff] [blame] | 258 | again = (video->img() != NULL); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 259 | |
| 260 | PreEncodeFrameHook(video); |
Alex Converse | 1c1bc94 | 2016-07-21 11:36:41 -0700 | [diff] [blame] | 261 | PreEncodeFrameHook(video, encoder.get()); |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 262 | encoder->EncodeFrame(video, frame_flags_); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 263 | |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 264 | CxDataIterator iter = encoder->GetCxData(); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 265 | |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 266 | bool has_cxdata = false; |
| 267 | bool has_dxdata = false; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 268 | while (const aom_codec_cx_pkt_t *pkt = iter.Next()) { |
John Koleszar | 522d4bf | 2013-03-05 12:23:34 -0800 | [diff] [blame] | 269 | pkt = MutateEncoderOutputHook(pkt); |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 270 | again = true; |
Adrian Grange | e6109db | 2012-10-02 11:27:29 -0700 | [diff] [blame] | 271 | switch (pkt->kind) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 272 | case AOM_CODEC_CX_FRAME_PKT: |
Adrian Grange | e6109db | 2012-10-02 11:27:29 -0700 | [diff] [blame] | 273 | has_cxdata = true; |
Alex Converse | 1c1bc94 | 2016-07-21 11:36:41 -0700 | [diff] [blame] | 274 | if (decoder.get() != NULL && DoDecode()) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 275 | aom_codec_err_t res_dec = decoder->DecodeFrame( |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 276 | (const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz); |
Jim Bankoski | 943e432 | 2014-07-17 06:31:50 -0700 | [diff] [blame] | 277 | |
Urvang Joshi | d71a231 | 2016-07-14 12:33:48 -0700 | [diff] [blame] | 278 | if (!HandleDecodeResult(res_dec, decoder.get())) break; |
Jim Bankoski | 943e432 | 2014-07-17 06:31:50 -0700 | [diff] [blame] | 279 | |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 280 | has_dxdata = true; |
| 281 | } |
Adrian Grange | e6109db | 2012-10-02 11:27:29 -0700 | [diff] [blame] | 282 | ASSERT_GE(pkt->data.frame.pts, last_pts_); |
| 283 | last_pts_ = pkt->data.frame.pts; |
| 284 | FramePktHook(pkt); |
| 285 | break; |
| 286 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 287 | case AOM_CODEC_PSNR_PKT: PSNRPktHook(pkt); break; |
Adrian Grange | e6109db | 2012-10-02 11:27:29 -0700 | [diff] [blame] | 288 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 289 | default: break; |
Adrian Grange | e6109db | 2012-10-02 11:27:29 -0700 | [diff] [blame] | 290 | } |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 291 | } |
| 292 | |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 293 | // Flush the decoder when there are no more fragments. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 294 | if ((init_flags_ & AOM_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) { |
| 295 | const aom_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0); |
Urvang Joshi | d71a231 | 2016-07-14 12:33:48 -0700 | [diff] [blame] | 296 | if (!HandleDecodeResult(res_dec, decoder.get())) break; |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 297 | } |
| 298 | |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 299 | if (has_dxdata && has_cxdata) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 300 | const aom_image_t *img_enc = encoder->GetPreviewFrame(); |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 301 | DxDataIterator dec_iter = decoder->GetDxData(); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 302 | const aom_image_t *img_dec = dec_iter.Next(); |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 303 | if (img_enc && img_dec) { |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 304 | const bool res = |
| 305 | compare_img(img_enc, img_dec, NULL, NULL, NULL, NULL, NULL); |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 306 | if (!res) { // Mismatch |
| 307 | MismatchHook(img_enc, img_dec); |
| 308 | } |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 309 | } |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 310 | if (img_dec) DecompressedFrameHook(*img_dec, video->pts()); |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 311 | } |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 312 | if (!Continue()) break; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 313 | } |
| 314 | |
| 315 | EndPassHook(); |
| 316 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 317 | if (!Continue()) break; |
John Koleszar | b9180fc | 2012-05-16 15:27:00 -0700 | [diff] [blame] | 318 | } |
| 319 | } |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 320 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 321 | } // namespace libaom_test |