1 /*
2 * Copyright (C) 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "codec2_hidl_hal_video_enc_test"
19
20 #include <android-base/logging.h>
21 #include <gtest/gtest.h>
22 #include <stdio.h>
23 #include <fstream>
24
25 #include <codec2/hidl/client.h>
26 #include <C2AllocatorIon.h>
27 #include <C2Config.h>
28 #include <C2Debug.h>
29 #include <C2Buffer.h>
30 #include <C2BufferPriv.h>
31
32 using android::C2AllocatorIon;
33
34 #include <VtsHalHidlTargetTestBase.h>
35 #include "media_c2_video_hidl_test_common.h"
36 #include "media_c2_hidl_test_common.h"
37
38 class GraphicBuffer : public C2Buffer {
39 public:
GraphicBuffer(const std::shared_ptr<C2GraphicBlock> & block)40 explicit GraphicBuffer(const std::shared_ptr<C2GraphicBlock> &block)
41 : C2Buffer({block->share(C2Rect(block->width(), block->height()),
42 ::C2Fence())}) {}
43 };
44
45 static ComponentTestEnvironment* gEnv = nullptr;
46
47 namespace {
48
49 class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
50 private:
51 typedef ::testing::VtsHalHidlTargetTestBase Super;
52
53 public:
getTestCaseInfo() const54 ::std::string getTestCaseInfo() const override {
55 return ::std::string() +
56 "Component: " + gEnv->getComponent().c_str() + " | " +
57 "Instance: " + gEnv->getInstance().c_str() + " | " +
58 "Res: " + gEnv->getRes().c_str();
59 }
60
61 // google.codec2 Video test setup
SetUp()62 virtual void SetUp() override {
63 Super::SetUp();
64 mDisableTest = false;
65 ALOGV("Codec2VideoEncHidlTest SetUp");
66 mClient = android::Codec2Client::CreateFromService(
67 gEnv->getInstance().c_str());
68 ASSERT_NE(mClient, nullptr);
69 mListener.reset(new CodecListener(
70 [this](std::list<std::unique_ptr<C2Work>>& workItems) {
71 handleWorkDone(workItems);
72 }));
73 ASSERT_NE(mListener, nullptr);
74 for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
75 mWorkQueue.emplace_back(new C2Work);
76 }
77 mClient->createComponent(gEnv->getComponent().c_str(), mListener,
78 &mComponent);
79 ASSERT_NE(mComponent, nullptr);
80
81 std::shared_ptr<C2AllocatorStore> store =
82 android::GetCodec2PlatformAllocatorStore();
83 CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC,
84 &mGraphicAllocator),
85 C2_OK);
86 mGraphicPool = std::make_shared<C2PooledBlockPool>(mGraphicAllocator,
87 mBlockPoolId++);
88 ASSERT_NE(mGraphicPool, nullptr);
89
90 mCompName = unknown_comp;
91 struct StringToName {
92 const char* Name;
93 standardComp CompName;
94 };
95
96 const StringToName kStringToName[] = {
97 {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4},
98 {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
99 };
100
101 const size_t kNumStringToName =
102 sizeof(kStringToName) / sizeof(kStringToName[0]);
103
104 std::string substring;
105 std::string comp;
106 substring = std::string(gEnv->getComponent());
107 /* TODO: better approach to find the component */
108 /* "c2.android." => 11th position */
109 size_t pos = 11;
110 size_t len = substring.find(".encoder", pos);
111 comp = substring.substr(pos, len - pos);
112
113 for (size_t i = 0; i < kNumStringToName; ++i) {
114 if (!strcasecmp(comp.c_str(), kStringToName[i].Name)) {
115 mCompName = kStringToName[i].CompName;
116 break;
117 }
118 }
119 mEos = false;
120 mCsd = false;
121 mConfig = false;
122 mFramesReceived = 0;
123 mFailedWorkReceived = 0;
124 if (mCompName == unknown_comp) mDisableTest = true;
125 if (mDisableTest) std::cout << "[ WARN ] Test Disabled \n";
126 }
127
TearDown()128 virtual void TearDown() override {
129 if (mComponent != nullptr) {
130 if (::testing::Test::HasFatalFailure()) return;
131 mComponent->release();
132 mComponent = nullptr;
133 }
134 Super::TearDown();
135 }
136
137 void setupConfigParam(int32_t nWidth, int32_t nHeight);
138
139 // callback function to process onWorkDone received by Listener
handleWorkDone(std::list<std::unique_ptr<C2Work>> & workItems)140 void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
141 for (std::unique_ptr<C2Work>& work : workItems) {
142 if (!work->worklets.empty()) {
143 if (work->result != C2_OK) mFailedWorkReceived++;
144 workDone(mComponent, work, mFlushedIndices, mQueueLock,
145 mQueueCondition, mWorkQueue, mEos, mCsd,
146 mFramesReceived);
147 }
148 }
149 }
150
151 enum standardComp {
152 h263,
153 avc,
154 mpeg4,
155 hevc,
156 vp8,
157 vp9,
158 unknown_comp,
159 };
160
161 bool mEos;
162 bool mCsd;
163 bool mDisableTest;
164 bool mConfig;
165 standardComp mCompName;
166 uint32_t mFramesReceived;
167 uint32_t mFailedWorkReceived;
168
169 std::list<uint64_t> mFlushedIndices;
170
171 C2BlockPool::local_id_t mBlockPoolId;
172 std::shared_ptr<C2BlockPool> mGraphicPool;
173 std::shared_ptr<C2Allocator> mGraphicAllocator;
174
175 std::mutex mQueueLock;
176 std::condition_variable mQueueCondition;
177 std::list<std::unique_ptr<C2Work>> mWorkQueue;
178
179 std::shared_ptr<android::Codec2Client> mClient;
180 std::shared_ptr<android::Codec2Client::Listener> mListener;
181 std::shared_ptr<android::Codec2Client::Component> mComponent;
182
183 protected:
description(const std::string & description)184 static void description(const std::string& description) {
185 RecordProperty("description", description);
186 }
187 };
188
validateComponent(const std::shared_ptr<android::Codec2Client::Component> & component,Codec2VideoEncHidlTest::standardComp compName,bool & disableTest)189 void validateComponent(
190 const std::shared_ptr<android::Codec2Client::Component>& component,
191 Codec2VideoEncHidlTest::standardComp compName, bool& disableTest) {
192 // Validate its a C2 Component
193 if (component->getName().find("c2") == std::string::npos) {
194 ALOGE("Not a c2 component");
195 disableTest = true;
196 return;
197 }
198
199 // Validate its not an encoder and the component to be tested is video
200 if (component->getName().find("decoder") != std::string::npos) {
201 ALOGE("Expected Encoder, given Decoder");
202 disableTest = true;
203 return;
204 }
205 std::vector<std::unique_ptr<C2Param>> queried;
206 c2_status_t c2err =
207 component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
208 C2_DONT_BLOCK, &queried);
209 if (c2err != C2_OK && queried.size() == 0) {
210 ALOGE("Query media type failed => %d", c2err);
211 } else {
212 std::string inputDomain =
213 ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
214 if (inputDomain.find("video/") == std::string::npos) {
215 ALOGE("Expected Video Component");
216 disableTest = true;
217 return;
218 }
219 }
220
221 // Validates component name
222 if (compName == Codec2VideoEncHidlTest::unknown_comp) {
223 ALOGE("Component InValid");
224 disableTest = true;
225 return;
226 }
227 ALOGV("Component Valid");
228 }
229
230 // Set Default config param.
setupConfigParam(int32_t nWidth,int32_t nHeight)231 void Codec2VideoEncHidlTest::setupConfigParam(int32_t nWidth, int32_t nHeight) {
232 std::vector<std::unique_ptr<C2SettingResult>> failures;
233 C2VideoSizeStreamTuning::input inputSize(0u, nWidth, nHeight);
234 std::vector<C2Param*> configParam{&inputSize};
235 c2_status_t status =
236 mComponent->config(configParam, C2_DONT_BLOCK, &failures);
237 if (failures.size() == 0u ) mConfig = true;
238 ASSERT_EQ(status, C2_OK);
239 }
240
241 // LookUpTable of clips for component testing
GetURLForComponent(char * URL)242 void GetURLForComponent(char* URL) {
243 strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
244 }
245
encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> & component,std::mutex & queueLock,std::condition_variable & queueCondition,std::list<std::unique_ptr<C2Work>> & workQueue,std::list<uint64_t> & flushedIndices,std::shared_ptr<C2BlockPool> & graphicPool,std::ifstream & eleStream,uint32_t frameID,uint32_t nFrames,uint32_t nWidth,int32_t nHeight,bool flushed=false,bool signalEOS=true)246 void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
247 std::mutex &queueLock, std::condition_variable& queueCondition,
248 std::list<std::unique_ptr<C2Work>>& workQueue,
249 std::list<uint64_t>& flushedIndices,
250 std::shared_ptr<C2BlockPool>& graphicPool,
251 std::ifstream& eleStream, uint32_t frameID,
252 uint32_t nFrames, uint32_t nWidth, int32_t nHeight,
253 bool flushed = false,bool signalEOS = true) {
254 typedef std::unique_lock<std::mutex> ULock;
255
256 uint32_t maxRetry = 0;
257 int bytesCount = nWidth * nHeight * 3 >> 1;
258 int32_t timestampIncr = ENCODER_TIMESTAMP_INCREMENT;
259 uint64_t timestamp = 0;
260 while (1) {
261 if (nFrames == 0) break;
262 uint32_t flags = 0;
263 std::unique_ptr<C2Work> work;
264 // Prepare C2Work
265 while (!work && (maxRetry < MAX_RETRY)) {
266 ULock l(queueLock);
267 if (!workQueue.empty()) {
268 work.swap(workQueue.front());
269 workQueue.pop_front();
270 } else {
271 queueCondition.wait_for(l, TIME_OUT);
272 maxRetry++;
273 }
274 }
275 if (!work && (maxRetry >= MAX_RETRY)) {
276 ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
277 }
278 if (signalEOS && (nFrames == 1))
279 flags |= C2FrameData::FLAG_END_OF_STREAM;
280 if (flushed) {
281 flags |= SYNC_FRAME;
282 flushed = false;
283 }
284
285 work->input.flags = (C2FrameData::flags_t)flags;
286 work->input.ordinal.timestamp = timestamp;
287 work->input.ordinal.frameIndex = frameID;
288 {
289 ULock l(queueLock);
290 flushedIndices.emplace_back(frameID);
291 }
292 char* data = (char*)malloc(bytesCount);
293 ASSERT_NE(data, nullptr);
294 memset(data, 0, bytesCount);
295 if (eleStream.is_open()) {
296 eleStream.read(data, bytesCount);
297 ASSERT_EQ(eleStream.gcount(), bytesCount);
298 }
299 std::shared_ptr<C2GraphicBlock> block;
300 ASSERT_EQ(
301 C2_OK,
302 graphicPool->fetchGraphicBlock(
303 nWidth, nHeight, HAL_PIXEL_FORMAT_YV12,
304 {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block));
305 ASSERT_TRUE(block);
306 // Graphic View
307 C2GraphicView view = block->map().get();
308 if (view.error() != C2_OK) {
309 fprintf(stderr, "C2GraphicBlock::map() failed : %d", view.error());
310 break;
311 }
312
313 uint8_t* pY = view.data()[C2PlanarLayout::PLANE_Y];
314 uint8_t* pU = view.data()[C2PlanarLayout::PLANE_U];
315 uint8_t* pV = view.data()[C2PlanarLayout::PLANE_V];
316
317 memcpy(pY, data, nWidth * nHeight);
318 memcpy(pU, data + nWidth * nHeight, (nWidth * nHeight >> 2));
319 memcpy(pV, data + (nWidth * nHeight * 5 >> 2), nWidth * nHeight >> 2);
320
321 work->input.buffers.clear();
322 work->input.buffers.emplace_back(new GraphicBuffer(block));
323 work->worklets.clear();
324 work->worklets.emplace_back(new C2Worklet);
325 free(data);
326
327 std::list<std::unique_ptr<C2Work>> items;
328 items.push_back(std::move(work));
329
330 // DO THE ENCODING
331 ASSERT_EQ(component->queue(&items), C2_OK);
332 ALOGV("Frame #%d size = %d queued", frameID, bytesCount);
333 nFrames--;
334 timestamp += timestampIncr;
335 frameID++;
336 maxRetry = 0;
337 }
338 }
339
TEST_F(Codec2VideoEncHidlTest,validateCompName)340 TEST_F(Codec2VideoEncHidlTest, validateCompName) {
341 if (mDisableTest) return;
342 ALOGV("Checks if the given component is a valid video component");
343 validateComponent(mComponent, mCompName, mDisableTest);
344 ASSERT_EQ(mDisableTest, false);
345 }
346
TEST_F(Codec2VideoEncHidlTest,EncodeTest)347 TEST_F(Codec2VideoEncHidlTest, EncodeTest) {
348 description("Encodes input file");
349 if (mDisableTest) return;
350
351 char mURL[512];
352 int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
353 int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
354
355 strcpy(mURL, gEnv->getRes().c_str());
356 GetURLForComponent(mURL);
357
358 std::ifstream eleStream;
359 eleStream.open(mURL, std::ifstream::binary);
360 ASSERT_EQ(eleStream.is_open(), true) << mURL << " file not found";
361 ALOGV("mURL : %s", mURL);
362
363 setupConfigParam(nWidth, nHeight);
364 if (!mConfig) {
365 std::cout << "[ WARN ] Test Skipped \n";
366 return;
367 }
368 ASSERT_EQ(mComponent->start(), C2_OK);
369 ASSERT_NO_FATAL_FAILURE(
370 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
371 mFlushedIndices, mGraphicPool, eleStream,
372 0, ENC_NUM_FRAMES, nWidth, nHeight));
373
374 // blocking call to ensures application to Wait till all the inputs are
375 // consumed
376 ALOGD("Waiting for input consumption");
377 ASSERT_NO_FATAL_FAILURE(
378 waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
379
380 eleStream.close();
381 if (mFramesReceived != ENC_NUM_FRAMES) {
382 ALOGE("Input buffer count and Output buffer count mismatch");
383 ALOGE("framesReceived : %d inputFrames : %d", mFramesReceived,
384 ENC_NUM_FRAMES);
385 ASSERT_TRUE(false);
386 }
387
388 if (!mCsd && (mCompName != vp8 && mCompName != vp9)) {
389 ASSERT_TRUE(false) << "CSD Buffer not received";
390 }
391
392 if (mCsd && (mCompName == vp8 || mCompName == vp9)) {
393 ASSERT_TRUE(false) << "CSD Buffer not expected";
394 }
395
396 ASSERT_EQ(mComponent->stop(), C2_OK);
397 }
398
TEST_F(Codec2VideoEncHidlTest,EOSTest)399 TEST_F(Codec2VideoEncHidlTest, EOSTest) {
400 description("Test empty input buffer with EOS flag");
401 if (mDisableTest) return;
402 ASSERT_EQ(mComponent->start(), C2_OK);
403
404 typedef std::unique_lock<std::mutex> ULock;
405 std::unique_ptr<C2Work> work;
406 {
407 ULock l(mQueueLock);
408 if (!mWorkQueue.empty()) {
409 work.swap(mWorkQueue.front());
410 mWorkQueue.pop_front();
411 } else {
412 ALOGE("mWorkQueue Empty is not expected at the start of the test");
413 ASSERT_TRUE(false);
414 }
415 }
416 ASSERT_NE(work, nullptr);
417 work->input.flags = (C2FrameData::flags_t)C2FrameData::FLAG_END_OF_STREAM;
418 work->input.ordinal.timestamp = 0;
419 work->input.ordinal.frameIndex = 0;
420 work->input.buffers.clear();
421 work->worklets.clear();
422 work->worklets.emplace_back(new C2Worklet);
423
424 std::list<std::unique_ptr<C2Work>> items;
425 items.push_back(std::move(work));
426 ASSERT_EQ(mComponent->queue(&items), C2_OK);
427 uint32_t queueSize;
428 {
429 ULock l(mQueueLock);
430 queueSize = mWorkQueue.size();
431 if (queueSize < MAX_INPUT_BUFFERS) {
432 mQueueCondition.wait_for(l, TIME_OUT);
433 }
434 }
435 ASSERT_EQ(mEos, true);
436 ASSERT_EQ(mComponent->stop(), C2_OK);
437 }
438
TEST_F(Codec2VideoEncHidlTest,FlushTest)439 TEST_F(Codec2VideoEncHidlTest, FlushTest) {
440 description("Test Request for flush");
441 if (mDisableTest) return;
442 ASSERT_EQ(mComponent->start(), C2_OK);
443
444 typedef std::unique_lock<std::mutex> ULock;
445 char mURL[512];
446 int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
447 int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
448 strcpy(mURL, gEnv->getRes().c_str());
449 GetURLForComponent(mURL);
450 setupConfigParam(nWidth, nHeight);
451
452 // Setting default configuration
453 mFlushedIndices.clear();
454 std::ifstream eleStream;
455 uint32_t numFramesFlushed = 10;
456 uint32_t numFrames = ENC_NUM_FRAMES;
457 eleStream.open(mURL, std::ifstream::binary);
458 ASSERT_EQ(eleStream.is_open(), true);
459 ALOGV("mURL : %s", mURL);
460 ASSERT_NO_FATAL_FAILURE(
461 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
462 mFlushedIndices, mGraphicPool, eleStream,
463 0, numFramesFlushed, nWidth, nHeight));
464 std::list<std::unique_ptr<C2Work>> flushedWork;
465 c2_status_t err =
466 mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
467 ASSERT_EQ(err, C2_OK);
468 ASSERT_NO_FATAL_FAILURE(
469 waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
470 (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
471 uint64_t frameIndex;
472 {
473 //Update mFlushedIndices based on the index received from flush()
474 ULock l(mQueueLock);
475 for (std::unique_ptr<C2Work>& work : flushedWork) {
476 ASSERT_NE(work, nullptr);
477 frameIndex = work->input.ordinal.frameIndex.peeku();
478 std::list<uint64_t>::iterator frameIndexIt = std::find(
479 mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
480 if (!mFlushedIndices.empty() &&
481 (frameIndexIt != mFlushedIndices.end())) {
482 mFlushedIndices.erase(frameIndexIt);
483 work->input.buffers.clear();
484 work->worklets.clear();
485 mWorkQueue.push_back(std::move(work));
486 }
487 }
488 }
489 mFlushedIndices.clear();
490 ASSERT_NO_FATAL_FAILURE(
491 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
492 mFlushedIndices, mGraphicPool, eleStream,
493 numFramesFlushed, numFrames - numFramesFlushed,
494 nWidth, nHeight, true));
495 eleStream.close();
496 err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
497 ASSERT_EQ(err, C2_OK);
498 ASSERT_NO_FATAL_FAILURE(
499 waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
500 (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
501 {
502 //Update mFlushedIndices based on the index received from flush()
503 ULock l(mQueueLock);
504 for (std::unique_ptr<C2Work>& work : flushedWork) {
505 ASSERT_NE(work, nullptr);
506 frameIndex = work->input.ordinal.frameIndex.peeku();
507 std::list<uint64_t>::iterator frameIndexIt = std::find(
508 mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
509 if (!mFlushedIndices.empty() &&
510 (frameIndexIt != mFlushedIndices.end())) {
511 mFlushedIndices.erase(frameIndexIt);
512 work->input.buffers.clear();
513 work->worklets.clear();
514 mWorkQueue.push_back(std::move(work));
515 }
516 }
517 }
518 ASSERT_EQ(mFlushedIndices.empty(), true);
519 ASSERT_EQ(mComponent->stop(), C2_OK);
520 }
521
TEST_F(Codec2VideoEncHidlTest,InvalidBufferTest)522 TEST_F(Codec2VideoEncHidlTest, InvalidBufferTest) {
523 description("Tests feeding larger/smaller input buffer");
524 if (mDisableTest) return;
525 ASSERT_EQ(mComponent->start(), C2_OK);
526
527 std::ifstream eleStream;
528 int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH / 2;
529 int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT / 2;
530 setupConfigParam(nWidth, nHeight);
531
532 ASSERT_NO_FATAL_FAILURE(
533 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
534 mFlushedIndices, mGraphicPool, eleStream,
535 0, 1, nWidth, nHeight, false, false));
536
537 // Feed larger input buffer.
538 ASSERT_NO_FATAL_FAILURE(
539 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
540 mFlushedIndices, mGraphicPool, eleStream,
541 1, 1, nWidth*2, nHeight*2, false, false));
542
543 // Feed smaller input buffer.
544 ASSERT_NO_FATAL_FAILURE(
545 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
546 mFlushedIndices, mGraphicPool, eleStream,
547 2, 1, nWidth/2, nHeight/2, false, true));
548
549 // blocking call to ensures application to Wait till all the inputs are
550 // consumed
551 ALOGD("Waiting for input consumption");
552 ASSERT_NO_FATAL_FAILURE(
553 waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
554
555 if (mFramesReceived != 3) {
556 ALOGE("Input buffer count and Output buffer count mismatch");
557 ALOGE("framesReceived : %d inputFrames : 3", mFramesReceived);
558 ASSERT_TRUE(false);
559 }
560
561 if (mFailedWorkReceived == 0) {
562 ALOGE("Expected failed frame count mismatch");
563 ALOGE("failedFramesReceived : %d", mFailedWorkReceived);
564 ASSERT_TRUE(false);
565 }
566
567 ASSERT_EQ(mComponent->stop(), C2_OK);
568 }
569
570 class Codec2VideoEncResolutionTest : public Codec2VideoEncHidlTest,
571 public ::testing::WithParamInterface<std::pair<int32_t, int32_t> > {
572 };
573
TEST_P(Codec2VideoEncResolutionTest,ResolutionTest)574 TEST_P(Codec2VideoEncResolutionTest, ResolutionTest) {
575 description("Tests encoding at different resolutions");
576 if (mDisableTest) return;
577
578 std::ifstream eleStream;
579 int32_t nWidth = GetParam().first;
580 int32_t nHeight = GetParam().second;
581 ALOGD("Trying encode for width %d height %d", nWidth, nHeight);
582 mConfig = false;
583 mEos = false;
584 setupConfigParam(nWidth, nHeight);
585 if (!mConfig) return;
586 ASSERT_EQ(mComponent->start(), C2_OK);
587
588 ASSERT_NO_FATAL_FAILURE(
589 encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
590 mFlushedIndices, mGraphicPool, eleStream, 0,
591 MAX_INPUT_BUFFERS, nWidth, nHeight));
592
593 ALOGD("Waiting for input consumption");
594 ASSERT_NO_FATAL_FAILURE(
595 waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
596
597 ASSERT_EQ(mEos, true);
598 ASSERT_EQ(mComponent->stop(), C2_OK);
599 ASSERT_EQ(mComponent->reset(), C2_OK);
600 }
601 INSTANTIATE_TEST_CASE_P(NonStdSizes, Codec2VideoEncResolutionTest, ::testing::Values(
602 std::make_pair(52, 18),
603 std::make_pair(365, 365),
604 std::make_pair(484, 362),
605 std::make_pair(244, 488)));
606
607 } // anonymous namespace
608
main(int argc,char ** argv)609 int main(int argc, char** argv) {
610 gEnv = new ComponentTestEnvironment();
611 ::testing::AddGlobalTestEnvironment(gEnv);
612 ::testing::InitGoogleTest(&argc, argv);
613 gEnv->init(&argc, argv);
614 int status = gEnv->initFromOptions(argc, argv);
615 if (status == 0) {
616 int status = RUN_ALL_TESTS();
617 LOG(INFO) << "C2 Test result = " << status;
618 }
619 return status;
620 }
621