y4m_test.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 <string>
  11. #include "third_party/googletest/src/include/gtest/gtest.h"
  12. #include "./vpx_config.h"
  13. #include "./y4menc.h"
  14. #include "test/md5_helper.h"
  15. #include "test/util.h"
  16. #include "test/y4m_video_source.h"
  17. namespace {
  18. using std::string;
  19. static const unsigned int kWidth = 160;
  20. static const unsigned int kHeight = 90;
  21. static const unsigned int kFrames = 10;
  22. struct Y4mTestParam {
  23. const char *filename;
  24. unsigned int bit_depth;
  25. vpx_img_fmt format;
  26. const char *md5raw;
  27. };
  28. const Y4mTestParam kY4mTestVectors[] = {
  29. { "park_joy_90p_8_420.y4m", 8, VPX_IMG_FMT_I420,
  30. "e5406275b9fc6bb3436c31d4a05c1cab" },
  31. { "park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422,
  32. "284a47a47133b12884ec3a14e959a0b6" },
  33. { "park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444,
  34. "90517ff33843d85de712fd4fe60dbed0" },
  35. { "park_joy_90p_10_420_20f.y4m", 10, VPX_IMG_FMT_I42016,
  36. "2f56ab9809269f074df7e3daf1ce0be6" },
  37. { "park_joy_90p_10_422_20f.y4m", 10, VPX_IMG_FMT_I42216,
  38. "1b5c73d2e8e8c4e02dc4889ecac41c83" },
  39. { "park_joy_90p_10_444_20f.y4m", 10, VPX_IMG_FMT_I44416,
  40. "ec4ab5be53195c5b838d1d19e1bc2674" },
  41. { "park_joy_90p_12_420_20f.y4m", 12, VPX_IMG_FMT_I42016,
  42. "3370856c8ddebbd1f9bb2e66f97677f4" },
  43. { "park_joy_90p_12_422_20f.y4m", 12, VPX_IMG_FMT_I42216,
  44. "4eab364318dd8201acbb182e43bd4966" },
  45. { "park_joy_90p_12_444_20f.y4m", 12, VPX_IMG_FMT_I44416,
  46. "f189dfbbd92119fc8e5f211a550166be" },
  47. };
  48. static void write_image_file(const vpx_image_t *img, FILE *file) {
  49. int plane, y;
  50. for (plane = 0; plane < 3; ++plane) {
  51. const unsigned char *buf = img->planes[plane];
  52. const int stride = img->stride[plane];
  53. const int bytes_per_sample = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
  54. const int h =
  55. (plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift
  56. : img->d_h);
  57. const int w =
  58. (plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift
  59. : img->d_w);
  60. for (y = 0; y < h; ++y) {
  61. fwrite(buf, bytes_per_sample, w, file);
  62. buf += stride;
  63. }
  64. }
  65. }
  66. class Y4mVideoSourceTest : public ::testing::TestWithParam<Y4mTestParam>,
  67. public ::libvpx_test::Y4mVideoSource {
  68. protected:
  69. Y4mVideoSourceTest() : Y4mVideoSource("", 0, 0) {}
  70. virtual ~Y4mVideoSourceTest() { CloseSource(); }
  71. virtual void Init(const std::string &file_name, int limit) {
  72. file_name_ = file_name;
  73. start_ = 0;
  74. limit_ = limit;
  75. frame_ = 0;
  76. Begin();
  77. }
  78. // Checks y4m header information
  79. void HeaderChecks(unsigned int bit_depth, vpx_img_fmt_t fmt) {
  80. ASSERT_TRUE(input_file_ != NULL);
  81. ASSERT_EQ(y4m_.pic_w, (int)kWidth);
  82. ASSERT_EQ(y4m_.pic_h, (int)kHeight);
  83. ASSERT_EQ(img()->d_w, kWidth);
  84. ASSERT_EQ(img()->d_h, kHeight);
  85. ASSERT_EQ(y4m_.bit_depth, bit_depth);
  86. ASSERT_EQ(y4m_.vpx_fmt, fmt);
  87. if (fmt == VPX_IMG_FMT_I420 || fmt == VPX_IMG_FMT_I42016) {
  88. ASSERT_EQ(y4m_.bps, (int)y4m_.bit_depth * 3 / 2);
  89. ASSERT_EQ(img()->x_chroma_shift, 1U);
  90. ASSERT_EQ(img()->y_chroma_shift, 1U);
  91. }
  92. if (fmt == VPX_IMG_FMT_I422 || fmt == VPX_IMG_FMT_I42216) {
  93. ASSERT_EQ(y4m_.bps, (int)y4m_.bit_depth * 2);
  94. ASSERT_EQ(img()->x_chroma_shift, 1U);
  95. ASSERT_EQ(img()->y_chroma_shift, 0U);
  96. }
  97. if (fmt == VPX_IMG_FMT_I444 || fmt == VPX_IMG_FMT_I44416) {
  98. ASSERT_EQ(y4m_.bps, (int)y4m_.bit_depth * 3);
  99. ASSERT_EQ(img()->x_chroma_shift, 0U);
  100. ASSERT_EQ(img()->y_chroma_shift, 0U);
  101. }
  102. }
  103. // Checks MD5 of the raw frame data
  104. void Md5Check(const string &expected_md5) {
  105. ASSERT_TRUE(input_file_ != NULL);
  106. libvpx_test::MD5 md5;
  107. for (unsigned int i = start_; i < limit_; i++) {
  108. md5.Add(img());
  109. Next();
  110. }
  111. ASSERT_EQ(string(md5.Get()), expected_md5);
  112. }
  113. };
  114. TEST_P(Y4mVideoSourceTest, SourceTest) {
  115. const Y4mTestParam t = GetParam();
  116. Init(t.filename, kFrames);
  117. HeaderChecks(t.bit_depth, t.format);
  118. Md5Check(t.md5raw);
  119. }
  120. INSTANTIATE_TEST_CASE_P(C, Y4mVideoSourceTest,
  121. ::testing::ValuesIn(kY4mTestVectors));
  122. class Y4mVideoWriteTest : public Y4mVideoSourceTest {
  123. protected:
  124. Y4mVideoWriteTest() : tmpfile_(NULL) {}
  125. virtual ~Y4mVideoWriteTest() {
  126. delete tmpfile_;
  127. input_file_ = NULL;
  128. }
  129. void ReplaceInputFile(FILE *input_file) {
  130. CloseSource();
  131. frame_ = 0;
  132. input_file_ = input_file;
  133. rewind(input_file_);
  134. ReadSourceToStart();
  135. }
  136. // Writes out a y4m file and then reads it back
  137. void WriteY4mAndReadBack() {
  138. ASSERT_TRUE(input_file_ != NULL);
  139. char buf[Y4M_BUFFER_SIZE] = { 0 };
  140. const struct VpxRational framerate = { y4m_.fps_n, y4m_.fps_d };
  141. tmpfile_ = new libvpx_test::TempOutFile;
  142. ASSERT_TRUE(tmpfile_->file() != NULL);
  143. y4m_write_file_header(buf, sizeof(buf), kWidth, kHeight, &framerate,
  144. y4m_.vpx_fmt, y4m_.bit_depth);
  145. fputs(buf, tmpfile_->file());
  146. for (unsigned int i = start_; i < limit_; i++) {
  147. y4m_write_frame_header(buf, sizeof(buf));
  148. fputs(buf, tmpfile_->file());
  149. write_image_file(img(), tmpfile_->file());
  150. Next();
  151. }
  152. ReplaceInputFile(tmpfile_->file());
  153. }
  154. virtual void Init(const std::string &file_name, int limit) {
  155. Y4mVideoSourceTest::Init(file_name, limit);
  156. WriteY4mAndReadBack();
  157. }
  158. libvpx_test::TempOutFile *tmpfile_;
  159. };
  160. TEST_P(Y4mVideoWriteTest, WriteTest) {
  161. const Y4mTestParam t = GetParam();
  162. Init(t.filename, kFrames);
  163. HeaderChecks(t.bit_depth, t.format);
  164. Md5Check(t.md5raw);
  165. }
  166. INSTANTIATE_TEST_CASE_P(C, Y4mVideoWriteTest,
  167. ::testing::ValuesIn(kY4mTestVectors));
  168. } // namespace