1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdlib.h>
18 
19 #include <algorithm>
20 
21 #include <binder/ProcessState.h>
22 #include <gtest/gtest.h>
23 #include <gui/Surface.h>
24 #include <media/MediaCodecBuffer.h>
25 #include <media/hardware/VideoAPI.h>
26 #include <media/stagefright/MediaCodec.h>
27 #include <media/stagefright/MediaCodecConstants.h>
28 #include <media/stagefright/foundation/ABuffer.h>
29 #include <media/stagefright/foundation/ALooper.h>
30 #include <media/stagefright/foundation/AMessage.h>
31 #include <mediadrm/ICrypto.h>
32 
33 namespace android {
34 
35 class MediaCodecSanityTest : public ::testing::Test {
36 public:
MediaCodecSanityTest()37     MediaCodecSanityTest()
38         : looper(new ALooper),
39           cfg(new AMessage),
40           ifmt(new AMessage),
41           ofmt(new AMessage) {
42         ProcessState::self()->startThreadPool();
43         looper->start();
44     }
45 
~MediaCodecSanityTest()46     ~MediaCodecSanityTest() {
47         if (codec != nullptr) {
48             codec->release();
49         }
50         looper->stop();
51     }
52 
53     sp<ALooper> looper;
54     sp<MediaCodec> codec;
55     sp<AMessage> cfg;
56     sp<AMessage> ifmt;
57     sp<AMessage> ofmt;
58 };
59 
60 const static size_t kLinearBufferSize = 1048576;
61 
62 // data for a codec input frame
63 struct FrameData {
64     const uint8_t *data;
65     size_t size;
66     template<size_t N>
FrameDataandroid::FrameData67     constexpr FrameData(const uint8_t(&data_)[N]) : data(data_), size(N) { }
68 };
69 
70 // one yellow frame of 240x180 (albeit 4:4:4)
71 const uint8_t avcStream_A1[] = { // IDR frame
72     0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0d, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
73     0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x20, 0xf1, 0x42, 0x99, 0x60,
74 
75     0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
76 
77     0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x2b, 0xff, 0xfe, 0xd8, 0xe7, 0xf3, 0x2c, 0xa5, 0x60,
78     0xca, 0xbb, 0xf1, 0x5c, 0x44, 0x7c, 0x9a, 0xa5, 0xc3, 0xab, 0x2f, 0x77, 0x0a, 0x94, 0x0d, 0x19,
79     0x43, 0x3b, 0x4f, 0x25, 0xea, 0x66, 0x00, 0x01, 0x24, 0xcd, 0x35, 0x5f, 0xc2, 0x34, 0x89, 0xd1,
80     0xa5, 0x60, 0x09, 0x98, 0x00, 0x01, 0x1b, 0x0e, 0xcb, 0x0d, 0x04, 0x86, 0x94, 0xe2, 0x32, 0x3c,
81     0xdd, 0x0f,
82 };
83 
84 FrameData avcStream_A[] __unused = { avcStream_A1 };
85 
86 // AVC stream of 2 yellow frames (240x180)
87 const uint8_t avcStream_B1[] = { // IDR frame
88     0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0c, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
89     0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x02, 0x80, 0xf1, 0x42, 0x99, 0x60,
90 
91     0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
92 
93     0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x33, 0xff, 0xfe, 0xdf, 0x32, 0xf8, 0x14, 0xd6, 0x25,
94     0xd0, 0x74, 0x42, 0x50, 0x84, 0x6f, 0xf4, 0xc2, 0x5c, 0x76, 0x37, 0x17, 0x72, 0xac, 0x52, 0xfc,
95     0xd6, 0x1f, 0xd2, 0xd0, 0x60, 0xb2, 0x20, 0x00, 0x10, 0x3d, 0x2a, 0xc0, 0xe4, 0x27, 0xcb, 0xce,
96     0xea, 0x25, 0x00, 0x81, 0x00, 0x00, 0x0f, 0x40, 0xbc, 0x81, 0x15, 0xc1, 0x65, 0x20, 0x80, 0x81,
97     0x7a, 0x57, 0x51,
98 };
99 
100 const uint8_t avcStream_B2[] = { // P frame
101     0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0xbf, 0xfe, 0x38, 0x40, 0x00, 0x0d, 0x48,
102 };
103 
104 FrameData avcStream_B[] = { avcStream_B1, avcStream_B2 };
105 
106 class MediaCodecInputBufferSizeTest : public MediaCodecSanityTest,
107         public ::testing::WithParamInterface<int32_t> {
108 };
109 
TEST_P(MediaCodecInputBufferSizeTest,TestAvcDecoder)110 TEST_P(MediaCodecInputBufferSizeTest, TestAvcDecoder) {
111     codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
112     cfg->setInt32("width", 320);
113     cfg->setInt32("height", 240);
114     cfg->setString("mime", MIMETYPE_VIDEO_AVC);
115 
116     const int32_t InputSize = GetParam();
117     if (InputSize >= 0) {
118         cfg->setInt32("max-input-size", InputSize);
119     }
120 
121     EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
122     EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
123     int32_t maxInputSize;
124     ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
125     if (InputSize > 0) {
126         EXPECT_EQ(maxInputSize, InputSize);
127     } else {
128         EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
129     }
130     EXPECT_EQ(codec->start(),  OK);
131     size_t ix;
132     EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
133     sp<MediaCodecBuffer> buf;
134     EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
135     EXPECT_GE(buf->size(), (size_t)maxInputSize);
136     EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
137 }
138 
TEST_P(MediaCodecInputBufferSizeTest,TestVideoDecoder)139 TEST_P(MediaCodecInputBufferSizeTest, TestVideoDecoder) {
140     codec = MediaCodec::CreateByComponentName(looper, "c2.android.vp8.decoder");
141     cfg->setInt32("width", 320);
142     cfg->setInt32("height", 240);
143     cfg->setString("mime", MIMETYPE_VIDEO_VP8);
144 
145     const int32_t InputSize = GetParam();
146     if (InputSize >= 0) {
147         cfg->setInt32("max-input-size", InputSize);
148     }
149 
150     EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
151     EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
152     int32_t maxInputSize;
153     ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
154     if (InputSize > 0) {
155         EXPECT_EQ(maxInputSize, InputSize);
156     } else {
157         EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
158     }
159     EXPECT_EQ(codec->start(),  OK);
160     size_t ix;
161     EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
162     sp<MediaCodecBuffer> buf;
163     EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
164     EXPECT_GE(buf->size(), (size_t)maxInputSize);
165     EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
166 }
167 
TEST_P(MediaCodecInputBufferSizeTest,TestAudioDecoder)168 TEST_P(MediaCodecInputBufferSizeTest, TestAudioDecoder) {
169     codec = MediaCodec::CreateByComponentName(looper, "c2.android.aac.decoder");
170     cfg->setInt32("sample-rate", 44100);
171     cfg->setInt32("channel-count", 2);
172     cfg->setString("mime", MIMETYPE_AUDIO_AAC);
173 
174     const int32_t InputSize = GetParam();
175     if (InputSize >= 0) {
176         cfg->setInt32("max-input-size", InputSize);
177     }
178 
179     EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
180     EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
181     int32_t maxInputSize;
182     if (InputSize > 0) {
183         ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
184         EXPECT_EQ(maxInputSize, InputSize);
185     } else {
186         if (ifmt->findInt32("max-input-size", &maxInputSize)) {
187             EXPECT_EQ(maxInputSize, 1 << 19); // 512 KB
188         }
189         maxInputSize = kLinearBufferSize; // input size is set by channel
190     }
191 
192     EXPECT_EQ(codec->start(),  OK);
193     size_t ix;
194     EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
195     sp<MediaCodecBuffer> buf;
196     EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
197     EXPECT_GE(buf->size(), (size_t)maxInputSize);
198     EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
199 }
200 
201 INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecInputBufferSizeTest, ::testing::Values(-1, 1234, 12345678));
202 
TEST_F(MediaCodecSanityTest,TestAvcDecoderHdrStaticInfo)203 TEST_F(MediaCodecSanityTest, TestAvcDecoderHdrStaticInfo) {
204     codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
205     cfg->setInt32("width", 320);
206     cfg->setInt32("height", 240);
207     cfg->setString("mime", MIMETYPE_VIDEO_AVC);
208     HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
209         .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500,  .y = 39850 },
210         .mB = { .x = 6550,  .y =  2300 }, .mW = { .x = 15635, .y = 16450 },
211         .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
212         .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
213     };
214     cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
215 
216     EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
217     EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
218     sp<ABuffer> oinfo;
219     ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
220     ASSERT_EQ(oinfo->size(), sizeof(info));
221     EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
222 
223     EXPECT_EQ(codec->start(),  OK);
224     // assume we can submit all input before dequeuing output
225     size_t frameIx = 0;
226     size_t ix;
227     sp<MediaCodecBuffer> buf;
228     for (const FrameData &frame : avcStream_B) {
229         EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
230         EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
231         ASSERT_GE(buf->capacity(), frame.size);
232         memcpy(buf->base(), frame.data, frame.size);
233         EXPECT_EQ(buf->setRange(0, frame.size), OK);
234         bool eos = ++frameIx == NELEM(avcStream_B);
235         EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
236                                           eos ? BUFFER_FLAG_END_OF_STREAM : 0),  OK);
237     }
238 
239     size_t offset, size;
240     int64_t ts;
241     uint32_t flags;
242     bool mInfoFormatChangedOk = true;
243     bool mInfoBuffersChangedOk = true;
244     while (true) {
245         status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
246         if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
247             mInfoFormatChangedOk = false;
248         } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
249             mInfoBuffersChangedOk = false;
250         } else {
251             ASSERT_EQ(err, OK);
252             break;
253         }
254     }
255     EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
256     EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
257     ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
258     ASSERT_EQ(oinfo->size(), sizeof(info));
259     EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
260 }
261 
TEST_F(MediaCodecSanityTest,TestVideoDecoderHdrStaticInfo)262 TEST_F(MediaCodecSanityTest, TestVideoDecoderHdrStaticInfo) {
263     codec = MediaCodec::CreateByComponentName(looper, "c2.android.mpeg4.decoder");
264     cfg->setInt32("width", 320);
265     cfg->setInt32("height", 240);
266     cfg->setString("mime", MIMETYPE_VIDEO_MPEG4);
267     HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
268         .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500,  .y = 39850 },
269         .mB = { .x = 6550,  .y =  2300 }, .mW = { .x = 15635, .y = 16450 },
270         .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
271         .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
272     };
273     cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
274 
275     EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
276     EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
277     sp<ABuffer> oinfo;
278     ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
279     ASSERT_EQ(oinfo->size(), sizeof(info));
280     EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
281 }
282 
283 class MediaCodecByteBufferTest : public MediaCodecSanityTest,
284         public ::testing::WithParamInterface<int32_t> {
285 };
286 
TEST_P(MediaCodecByteBufferTest,TestVideoDecoder420Planar)287 TEST_P(MediaCodecByteBufferTest, TestVideoDecoder420Planar) {
288     codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
289 //    codec = MediaCodec::CreateByComponentName(looper, "OMX.google.h264.decoder");
290     cfg->setInt32("width", 320);
291     cfg->setInt32("height", 240);
292     cfg->setString("mime", MIMETYPE_VIDEO_AVC);
293     const int32_t Color = GetParam();
294     if (Color >= 0) {
295         cfg->setInt32("color-format", Color);
296     }
297     int32_t xcolor = Color == -1 ? COLOR_FormatYUV420Planar : Color;
298 
299     EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
300     EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
301     int32_t ocolor = -1;
302     EXPECT_TRUE(ofmt->findInt32("color-format", &ocolor));
303     EXPECT_EQ(ocolor, xcolor);
304 
305     EXPECT_EQ(codec->start(),  OK);
306     // assume we can submit all input before dequeuing output
307     size_t frameIx = 0;
308     size_t ix;
309     sp<MediaCodecBuffer> buf;
310     for (const FrameData &frame : avcStream_A) {
311         EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
312         EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
313         ASSERT_GE(buf->capacity(), frame.size);
314         memcpy(buf->base(), frame.data, frame.size);
315         EXPECT_EQ(buf->setRange(0, frame.size), OK);
316         bool eos = ++frameIx == NELEM(avcStream_A);
317         EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
318                                           eos ? BUFFER_FLAG_END_OF_STREAM : 0),  OK);
319     }
320 
321     size_t offset, size;
322     int64_t ts;
323     uint32_t flags;
324     bool mInfoFormatChangedOk = true;
325     bool mInfoBuffersChangedOk = true;
326     while (true) {
327         status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
328         if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
329             mInfoFormatChangedOk = false;
330         } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
331             mInfoBuffersChangedOk = false;
332         } else {
333             ASSERT_EQ(err, OK);
334             break;
335         }
336     }
337     EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
338     EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
339     ASSERT_TRUE(ofmt->findInt32("color-format", &ocolor));
340     EXPECT_EQ(ocolor, xcolor) << ofmt->debugString(8).c_str() << buf->meta()->debugString(8).c_str();
341     // expect an image-data in both format and meta
342     sp<ABuffer> imgBuf, imgBuf2;
343     ASSERT_TRUE(ofmt->findBuffer("image-data", &imgBuf));
344     ASSERT_TRUE(buf->meta()->findBuffer("image-data", &imgBuf2));
345     EXPECT_EQ(imgBuf->size(), sizeof(MediaImage2));
346     ASSERT_EQ(imgBuf->size(), imgBuf2->size());
347     EXPECT_EQ(0, memcmp(imgBuf->data(), imgBuf2->data(), imgBuf->size()));
348     MediaImage2 *img = (MediaImage2*)imgBuf->data();
349     EXPECT_EQ(img->mType, img->MEDIA_IMAGE_TYPE_YUV);
350     EXPECT_EQ(img->mNumPlanes, 3u);
351     EXPECT_EQ(img->mWidth, 320u);
352     EXPECT_EQ(img->mHeight, 240u);
353     EXPECT_EQ(img->mBitDepth, 8u);
354     EXPECT_EQ(img->mBitDepthAllocated, 8u);
355 
356     // read strides from format
357     int32_t stride, vstride;
358     ofmt->findInt32("stride", &stride)          || ofmt->findInt32("width", &stride);
359     ofmt->findInt32("slice-height", &vstride)   || ofmt->findInt32("height", &vstride);
360 
361     EXPECT_EQ(img->mPlane[img->Y].mHorizSubsampling, 1u);
362     EXPECT_EQ(img->mPlane[img->Y].mVertSubsampling, 1u);
363     EXPECT_EQ(img->mPlane[img->U].mHorizSubsampling, 2u);
364     EXPECT_EQ(img->mPlane[img->U].mVertSubsampling, 2u);
365     EXPECT_EQ(img->mPlane[img->V].mHorizSubsampling, 2u);
366     EXPECT_EQ(img->mPlane[img->V].mVertSubsampling, 2u);
367 
368     switch (xcolor) {
369         // defined formats
370         case COLOR_FormatYUV420Planar:
371         case COLOR_FormatYUV420PackedPlanar:
372             EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
373             EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
374             EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
375 
376             EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
377             EXPECT_EQ(img->mPlane[img->U].mColInc, 1);
378             EXPECT_EQ(img->mPlane[img->U].mRowInc, stride / 2);
379 
380             EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride * 5 / 4));
381             EXPECT_EQ(img->mPlane[img->V].mColInc, 1);
382             EXPECT_EQ(img->mPlane[img->V].mRowInc, stride / 2);
383 
384             EXPECT_GE(size, (size_t)(stride * vstride * 5 / 4 + stride / 2 * 119 + 160));
385             EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
386             break;
387 
388         case COLOR_FormatYUV420SemiPlanar:
389         case COLOR_FormatYUV420PackedSemiPlanar:
390             EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
391             EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
392             EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
393 
394             EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
395             EXPECT_EQ(img->mPlane[img->U].mColInc, 2);
396             EXPECT_EQ(img->mPlane[img->U].mRowInc, stride);
397 
398             EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride + 1));
399             EXPECT_EQ(img->mPlane[img->V].mColInc, 2);
400             EXPECT_EQ(img->mPlane[img->V].mRowInc, stride);
401 
402             EXPECT_GE(size, (size_t)(stride * vstride + stride * 119 + 320));
403             EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
404             break;
405 
406         case COLOR_FormatYUV420Flexible:
407             // anything goes, but stride should match Y plane
408             EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
409 
410             EXPECT_GE(size,
411                       std::max({
412                             img->mPlane[img->Y].mOffset + 239 * img->mPlane[img->Y].mRowInc
413                                     + 319 * img->mPlane[img->Y].mColInc + 1,
414                             img->mPlane[img->U].mOffset + 119 * img->mPlane[img->U].mRowInc
415                                     + 159 * img->mPlane[img->U].mColInc + 1,
416                             img->mPlane[img->V].mOffset + 119 * img->mPlane[img->V].mRowInc
417                                     + 159 * img->mPlane[img->V].mColInc + 1 }));
418             break;
419 
420         default:
421             break;
422     }
423 
424     // validate all pixels
425 #if 0
426     fprintf(stderr, "MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }\n",
427             img->mWidth, img->mHeight,
428             img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
429             img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
430             img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
431 #endif
432     for (ix = 0; ix < 3; ++ix) {
433         const static uint8_t expected[] = { 210, 16, 146 };
434         for (uint32_t y = 0; y < img->mHeight / img->mPlane[ix].mVertSubsampling ; ++y) {
435             for (uint32_t x = 0; x < img->mWidth / img->mPlane[ix].mHorizSubsampling; ++x) {
436                 uint8_t val = buf->data()[img->mPlane[ix].mOffset + img->mPlane[ix].mColInc * x
437                         + img->mPlane[ix].mRowInc * y];
438                 ASSERT_EQ(val, expected[ix]) << "incorrect value for plane "
439                         << ix << " at x=" << x << ", y=" << y;
440             }
441         }
442     }
443 }
444 
445 INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecByteBufferTest, ::testing::Values(
446         -1,
447         COLOR_FormatYUV420Planar,
448         COLOR_FormatYUV420SemiPlanar,
449         COLOR_FormatYUV420PackedPlanar,
450         COLOR_FormatYUV420PackedSemiPlanar,
451         COLOR_FormatYUV420Flexible));
452 
453 } // namespace android
454