xref: /aosp_15_r20/external/webrtc/api/video/test/nv12_buffer_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2020 The WebRTC 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 "api/video/nv12_buffer.h"
12 
13 #include "api/video/i420_buffer.h"
14 #include "test/frame_utils.h"
15 #include "test/gmock.h"
16 #include "test/gtest.h"
17 
18 namespace webrtc {
19 
20 namespace {
GetY(rtc::scoped_refptr<NV12BufferInterface> buf,int col,int row)21 int GetY(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
22   return buf->DataY()[row * buf->StrideY() + col];
23 }
24 
GetU(rtc::scoped_refptr<NV12BufferInterface> buf,int col,int row)25 int GetU(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
26   return buf->DataUV()[(row / 2) * buf->StrideUV() + (col / 2) * 2];
27 }
28 
GetV(rtc::scoped_refptr<NV12BufferInterface> buf,int col,int row)29 int GetV(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
30   return buf->DataUV()[(row / 2) * buf->StrideUV() + (col / 2) * 2 + 1];
31 }
32 
FillNV12Buffer(rtc::scoped_refptr<NV12Buffer> buf)33 void FillNV12Buffer(rtc::scoped_refptr<NV12Buffer> buf) {
34   const uint8_t Y = 1;
35   const uint8_t U = 2;
36   const uint8_t V = 3;
37   for (int row = 0; row < buf->height(); ++row) {
38     for (int col = 0; col < buf->width(); ++col) {
39       buf->MutableDataY()[row * buf->StrideY() + col] = Y;
40     }
41   }
42   // Fill interleaving UV values.
43   for (int row = 0; row < buf->ChromaHeight(); row++) {
44     for (int col = 0; col < buf->StrideUV(); col += 2) {
45       int uv_index = row * buf->StrideUV() + col;
46       buf->MutableDataUV()[uv_index] = U;
47       buf->MutableDataUV()[uv_index + 1] = V;
48     }
49   }
50 }
51 
52 }  // namespace
53 
TEST(NV12BufferTest,InitialData)54 TEST(NV12BufferTest, InitialData) {
55   constexpr int stride_y = 3;
56   constexpr int stride_uv = 4;
57   constexpr int width = 3;
58   constexpr int height = 3;
59 
60   rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
61   EXPECT_EQ(width, nv12_buffer->width());
62   EXPECT_EQ(height, nv12_buffer->height());
63   EXPECT_EQ(stride_y, nv12_buffer->StrideY());
64   EXPECT_EQ(stride_uv, nv12_buffer->StrideUV());
65   EXPECT_EQ(2, nv12_buffer->ChromaWidth());
66   EXPECT_EQ(2, nv12_buffer->ChromaHeight());
67 }
68 
TEST(NV12BufferTest,ReadPixels)69 TEST(NV12BufferTest, ReadPixels) {
70   constexpr int width = 3;
71   constexpr int height = 3;
72 
73   rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
74   // Y = 1, U = 2, V = 3.
75   FillNV12Buffer(nv12_buffer);
76   for (int row = 0; row < height; row++) {
77     for (int col = 0; col < width; col++) {
78       EXPECT_EQ(1, GetY(nv12_buffer, col, row));
79       EXPECT_EQ(2, GetU(nv12_buffer, col, row));
80       EXPECT_EQ(3, GetV(nv12_buffer, col, row));
81     }
82   }
83 }
84 
TEST(NV12BufferTest,ToI420)85 TEST(NV12BufferTest, ToI420) {
86   constexpr int width = 3;
87   constexpr int height = 3;
88   constexpr int size_y = width * height;
89   constexpr int size_u = (width + 1) / 2 * (height + 1) / 2;
90   constexpr int size_v = (width + 1) / 2 * (height + 1) / 2;
91   rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
92   memset(reference->MutableDataY(), 8, size_y);
93   memset(reference->MutableDataU(), 4, size_u);
94   memset(reference->MutableDataV(), 2, size_v);
95 
96   rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
97   // Convert the reference buffer to NV12.
98   memset(nv12_buffer->MutableDataY(), 8, size_y);
99   // Interleaving u/v values.
100   for (int i = 0; i < size_u + size_v; i += 2) {
101     nv12_buffer->MutableDataUV()[i] = 4;
102     nv12_buffer->MutableDataUV()[i + 1] = 2;
103   }
104   // Confirm YUV values are as expected.
105   for (int row = 0; row < height; row++) {
106     for (int col = 0; col < width; col++) {
107       EXPECT_EQ(8, GetY(nv12_buffer, col, row));
108       EXPECT_EQ(4, GetU(nv12_buffer, col, row));
109       EXPECT_EQ(2, GetV(nv12_buffer, col, row));
110     }
111   }
112 
113   rtc::scoped_refptr<I420BufferInterface> i420_buffer(nv12_buffer->ToI420());
114   EXPECT_EQ(height, i420_buffer->height());
115   EXPECT_EQ(width, i420_buffer->width());
116   EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
117 }
118 
119 }  // namespace webrtc
120