1 /*
2  * Copyright (C) 2017 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_TAG "media_omx_hidl_video_dec_test"
18 #ifdef __LP64__
19 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
20 #endif
21 
22 #include <android-base/logging.h>
23 
24 #include <android/hardware/media/omx/1.0/IOmx.h>
25 #include <android/hardware/media/omx/1.0/IOmxNode.h>
26 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
27 #include <android/hardware/media/omx/1.0/types.h>
28 #include <android/hidl/allocator/1.0/IAllocator.h>
29 #include <android/hidl/memory/1.0/IMapper.h>
30 #include <android/hidl/memory/1.0/IMemory.h>
31 #include <gtest/gtest.h>
32 #include <hidl/GtestPrinter.h>
33 
34 using ::android::hardware::media::omx::V1_0::IOmx;
35 using ::android::hardware::media::omx::V1_0::IOmxObserver;
36 using ::android::hardware::media::omx::V1_0::IOmxNode;
37 using ::android::hardware::media::omx::V1_0::Message;
38 using ::android::hardware::media::omx::V1_0::CodecBuffer;
39 using ::android::hardware::media::omx::V1_0::PortMode;
40 using ::android::hidl::allocator::V1_0::IAllocator;
41 using ::android::hidl::memory::V1_0::IMemory;
42 using ::android::hidl::memory::V1_0::IMapper;
43 using ::android::hardware::Return;
44 using ::android::hardware::Void;
45 using ::android::hardware::hidl_vec;
46 using ::android::hardware::hidl_string;
47 using ::android::sp;
48 
49 #include <getopt.h>
50 #include <media/hardware/HardwareAPI.h>
51 #include <media_video_hidl_test_common.h>
52 #include <fstream>
53 
54 // Resource directory
55 std::string sResourceDir = "";
56 
57 // video decoder test fixture class
58 class VideoDecHidlTest
59     : public ::testing::TestWithParam<std::tuple<std::string, std::string, std::string>> {
60   public:
getTestCaseInfo() const61     ::std::string getTestCaseInfo() const {
62         return ::std::string() + "Component: " + component_ + " | " + "Role: " + role_ + " | " +
63                "Instance: " + instance_ + " | " + "Res: " + sResourceDir;
64     }
65 
SetUp()66     virtual void SetUp() override {
67         instance_ = std::get<0>(GetParam());
68         component_ = std::get<1>(GetParam());
69         role_ = std::get<2>(GetParam());
70         ASSERT_NE(sResourceDir.empty(), true);
71 
72         disableTest = false;
73         android::hardware::media::omx::V1_0::Status status;
74         omx = IOmx::getService(instance_);
75         ASSERT_NE(omx, nullptr);
76         observer =
77             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
78                 handleMessage(msg, buffer);
79             });
80         ASSERT_NE(observer, nullptr);
81         if (component_.find("OMX.") != 0) disableTest = true;
82         EXPECT_TRUE(omx->allocateNode(component_, observer,
83                                       [&](android::hardware::media::omx::V1_0::Status _s,
84                                           sp<IOmxNode> const& _nl) {
85                                           status = _s;
86                                           this->omxNode = _nl;
87                                       })
88                             .isOk());
89         if (status == android::hardware::media::omx::V1_0::Status::NAME_NOT_FOUND) {
90             disableTest = true;
91             std::cout << "[   WARN   ] Test Disabled, component not present\n";
92             return;
93         }
94         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
95         ASSERT_NE(omxNode, nullptr);
96         ASSERT_NE(role_.empty(), true) << "Invalid Component Role";
97         struct StringToName {
98             const char* Name;
99             standardComp CompName;
100         };
101         const StringToName kStringToName[] = {
102             {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
103             {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
104         };
105         const size_t kNumStringToName =
106             sizeof(kStringToName) / sizeof(kStringToName[0]);
107         const char* pch;
108         char substring[OMX_MAX_STRINGNAME_SIZE];
109         strcpy(substring, role_.c_str());
110         pch = strchr(substring, '.');
111         ASSERT_NE(pch, nullptr);
112         compName = unknown_comp;
113         for (size_t i = 0; i < kNumStringToName; ++i) {
114             if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
115                 compName = kStringToName[i].CompName;
116                 break;
117             }
118         }
119         if (compName == unknown_comp) disableTest = true;
120         struct CompToCompression {
121             standardComp CompName;
122             OMX_VIDEO_CODINGTYPE eCompressionFormat;
123         };
124         static const CompToCompression kCompToCompression[] = {
125             {h263, OMX_VIDEO_CodingH263},   {avc, OMX_VIDEO_CodingAVC},
126             {mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
127             {hevc, OMX_VIDEO_CodingHEVC},   {vp8, OMX_VIDEO_CodingVP8},
128             {vp9, OMX_VIDEO_CodingVP9},
129         };
130         static const size_t kNumCompToCompression =
131             sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
132         size_t i;
133         for (i = 0; i < kNumCompToCompression; ++i) {
134             if (kCompToCompression[i].CompName == compName) {
135                 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
136                 break;
137             }
138         }
139         if (i == kNumCompToCompression) disableTest = true;
140         portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
141         eosFlag = false;
142         framesReceived = 0;
143         timestampUs = 0;
144         timestampDevTest = false;
145         isSecure = false;
146         portSettingsChange = false;
147         size_t suffixLen = strlen(".secure");
148         if (component_.rfind(".secure") == component_.length() - suffixLen) {
149             isSecure = true;
150         }
151         if (isSecure) disableTest = true;
152         omxNode->configureVideoTunnelMode(
153             1, OMX_TRUE, 0,
154             [&](android::hardware::media::omx::V1_0::Status _s,
155                 const ::android::hardware::hidl_handle& sidebandHandle) {
156                 (void)sidebandHandle;
157                 if (_s == android::hardware::media::omx::V1_0::Status::OK)
158                     this->disableTest = true;
159             });
160         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
161         // NOTES: secure and tunneled components are not covered in these tests.
162         // we are disabling tests for them
163     }
164 
TearDown()165     virtual void TearDown() override {
166         if (omxNode != nullptr) {
167             // If you have encountered a fatal failure, it is possible that
168             // freeNode() will not go through. Instead of hanging the app.
169             // let it pass through and report errors
170             if (::testing::Test::HasFatalFailure()) return;
171             EXPECT_TRUE((omxNode->freeNode()).isOk());
172             omxNode = nullptr;
173         }
174     }
175 
176     // callback function to process messages received by onMessages() from IL
177     // client.
handleMessage(Message msg,const BufferInfo * buffer)178     void handleMessage(Message msg, const BufferInfo* buffer) {
179         (void)buffer;
180         if (msg.type == Message::Type::FILL_BUFFER_DONE) {
181             if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
182                 eosFlag = true;
183             }
184             if (msg.data.extendedBufferData.rangeLength != 0) {
185                 framesReceived += 1;
186                 // For decoder components current timestamp always exceeds
187                 // previous timestamp
188                 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
189                 timestampUs = msg.data.extendedBufferData.timestampUs;
190                 // Test if current timestamp is among the list of queued
191                 // timestamps
192                 if (timestampDevTest) {
193                     bool tsHit = false;
194                     android::List<uint64_t>::iterator it =
195                         timestampUslist.begin();
196                     while (it != timestampUslist.end()) {
197                         if (*it == timestampUs) {
198                             timestampUslist.erase(it);
199                             tsHit = true;
200                             break;
201                         }
202                         it++;
203                     }
204                     if (tsHit == false) {
205                         if (timestampUslist.empty() == false) {
206                             EXPECT_EQ(tsHit, true)
207                                 << "TimeStamp not recognized";
208                         } else {
209                             std::cout << "[   INFO   ] Received non-zero "
210                                          "output / TimeStamp not recognized \n";
211                         }
212                     }
213                 }
214 #define WRITE_OUTPUT 0
215 #if WRITE_OUTPUT
216                 static int count = 0;
217                 FILE* ofp = nullptr;
218                 if (count)
219                     ofp = fopen("out.bin", "ab");
220                 else
221                     ofp = fopen("out.bin", "wb");
222                 if (ofp != nullptr &&
223                     portMode[1] == PortMode::PRESET_BYTE_BUFFER) {
224                     fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
225                            sizeof(char),
226                            msg.data.extendedBufferData.rangeLength, ofp);
227                     fclose(ofp);
228                     count++;
229                 }
230 #endif
231             }
232         } else if (msg.type == Message::Type::EVENT) {
233             if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
234                 if ((msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
235                      msg.data.eventData.data2 == 0)) {
236                     portSettingsChange = true;
237                 }
238             }
239         }
240     }
241 
242     enum standardComp {
243         h263,
244         avc,
245         mpeg2,
246         mpeg4,
247         hevc,
248         vp8,
249         vp9,
250         unknown_comp,
251     };
252 
253     std::string component_;
254     std::string role_;
255     std::string instance_;
256 
257     sp<IOmx> omx;
258     sp<CodecObserver> observer;
259     sp<IOmxNode> omxNode;
260     standardComp compName;
261     OMX_VIDEO_CODINGTYPE eCompressionFormat;
262     bool disableTest;
263     PortMode portMode[2];
264     bool eosFlag;
265     uint32_t framesReceived;
266     uint64_t timestampUs;
267     ::android::List<uint64_t> timestampUslist;
268     bool timestampDevTest;
269     bool isSecure;
270     bool portSettingsChange;
271 
272    protected:
description(const std::string & description)273     static void description(const std::string& description) {
274         RecordProperty("description", description);
275     }
276 };
277 
278 // Set Default port param.
setDefaultPortParam(sp<IOmxNode> omxNode,OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE eCompressionFormat,OMX_COLOR_FORMATTYPE eColorFormat,OMX_U32 nFrameWidth=352,OMX_U32 nFrameHeight=288,OMX_U32 nBitrate=0,OMX_U32 xFramerate=(24U<<16))279 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
280                          OMX_VIDEO_CODINGTYPE eCompressionFormat,
281                          OMX_COLOR_FORMATTYPE eColorFormat,
282                          OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
283                          OMX_U32 nBitrate = 0,
284                          OMX_U32 xFramerate = (24U << 16)) {
285     switch ((int)eCompressionFormat) {
286         case OMX_VIDEO_CodingUnused:
287             setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
288                          nBitrate, xFramerate, eColorFormat);
289             break;
290         default:
291             break;
292     }
293 }
294 
295 // In decoder components, often the input port parameters get updated upon
296 // parsing the header of elementary stream. Client needs to collect this
297 // information to reconfigure other ports that share data with this input
298 // port.
getInputChannelInfo(sp<IOmxNode> omxNode,OMX_U32 kPortIndexInput,uint32_t * nFrameWidth,uint32_t * nFrameHeight,uint32_t * xFramerate)299 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
300                          uint32_t* nFrameWidth, uint32_t* nFrameHeight,
301                          uint32_t* xFramerate) {
302     android::hardware::media::omx::V1_0::Status status;
303     *nFrameWidth = 352;
304     *nFrameHeight = 288;
305     *xFramerate = (24U << 16);
306 
307     OMX_PARAM_PORTDEFINITIONTYPE portDef;
308     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
309                           kPortIndexInput, &portDef);
310     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
311     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
312         *nFrameWidth = portDef.format.video.nFrameWidth;
313         *nFrameHeight = portDef.format.video.nFrameHeight;
314         *xFramerate = portDef.format.video.xFramerate;
315     }
316 }
317 
318 // number of elementary streams per component
319 #define STREAM_COUNT 2
320 // LookUpTable of clips and metadata for component testing
GetURLForComponent(VideoDecHidlTest::standardComp comp,char * mURL,char * info,size_t streamIndex=1)321 void GetURLForComponent(VideoDecHidlTest::standardComp comp, char* mURL,
322                         char* info, size_t streamIndex = 1) {
323     struct CompToURL {
324         VideoDecHidlTest::standardComp comp;
325         const char mURL[STREAM_COUNT][512];
326         const char info[STREAM_COUNT][512];
327     };
328     ASSERT_TRUE(streamIndex < STREAM_COUNT);
329 
330     static const CompToURL kCompToURL[] = {
331         {VideoDecHidlTest::standardComp::avc,
332          {"bbb_avc_176x144_300kbps_60fps.h264",
333           "bbb_avc_640x360_768kbps_30fps.h264"},
334          {"bbb_avc_176x144_300kbps_60fps.info",
335           "bbb_avc_640x360_768kbps_30fps.info"}},
336         {VideoDecHidlTest::standardComp::hevc,
337          {"bbb_hevc_176x144_176kbps_60fps.hevc",
338           "bbb_hevc_640x360_1600kbps_30fps.hevc"},
339          {"bbb_hevc_176x144_176kbps_60fps.info",
340           "bbb_hevc_640x360_1600kbps_30fps.info"}},
341         {VideoDecHidlTest::standardComp::mpeg2,
342          {"bbb_mpeg2_176x144_105kbps_25fps.m2v",
343           "bbb_mpeg2_352x288_1mbps_60fps.m2v"},
344          {"bbb_mpeg2_176x144_105kbps_25fps.info",
345           "bbb_mpeg2_352x288_1mbps_60fps.info"}},
346         {VideoDecHidlTest::standardComp::h263,
347          {"", "bbb_h263_352x288_300kbps_12fps.h263"},
348          {"", "bbb_h263_352x288_300kbps_12fps.info"}},
349         {VideoDecHidlTest::standardComp::mpeg4,
350          {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"},
351          {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}},
352         {VideoDecHidlTest::standardComp::vp8,
353          {"bbb_vp8_176x144_240kbps_60fps.vp8",
354           "bbb_vp8_640x360_2mbps_30fps.vp8"},
355          {"bbb_vp8_176x144_240kbps_60fps.info",
356           "bbb_vp8_640x360_2mbps_30fps.info"}},
357         {VideoDecHidlTest::standardComp::vp9,
358          {"bbb_vp9_176x144_285kbps_60fps.vp9",
359           "bbb_vp9_640x360_1600kbps_30fps.vp9"},
360          {"bbb_vp9_176x144_285kbps_60fps.info",
361           "bbb_vp9_640x360_1600kbps_30fps.info"}},
362     };
363 
364     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
365         if (kCompToURL[i].comp == comp) {
366             strcat(mURL, kCompToURL[i].mURL[streamIndex]);
367             strcat(info, kCompToURL[i].info[streamIndex]);
368             return;
369         }
370     }
371 }
372 
373 // port settings reconfiguration during runtime. reconfigures frame dimensions
portReconfiguration(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,Message msg,PortMode oPortMode,void * args)374 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
375                          android::Vector<BufferInfo>* iBuffer,
376                          android::Vector<BufferInfo>* oBuffer,
377                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
378                          Message msg, PortMode oPortMode, void* args) {
379     android::hardware::media::omx::V1_0::Status status;
380     (void)args;
381 
382     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
383         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
384         if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
385             msg.data.eventData.data2 == 0) {
386             // Components can send various kinds of port settings changed events
387             // all at once. Before committing to a full port reconfiguration,
388             // defer any events waiting in the queue to be addressed to a later
389             // point.
390             android::List<Message> msgQueueDefer;
391             while (1) {
392                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
393                                                   iBuffer, oBuffer);
394                 if (status !=
395                     android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
396                     msgQueueDefer.push_back(msg);
397                     continue;
398                 } else
399                     break;
400             }
401             status = omxNode->sendCommand(
402                 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
403             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
404 
405             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
406                                               oBuffer);
407             if (status ==
408                 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
409                 for (size_t i = 0; i < oBuffer->size(); ++i) {
410                     // test if client got all its buffers back
411                     EXPECT_EQ((*oBuffer)[i].owner, client);
412                     // free the buffers
413                     status =
414                         omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
415                     ASSERT_EQ(status,
416                               android::hardware::media::omx::V1_0::Status::OK);
417                 }
418                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
419                                                   iBuffer, oBuffer);
420                 ASSERT_EQ(status,
421                           android::hardware::media::omx::V1_0::Status::OK);
422                 ASSERT_EQ(msg.type, Message::Type::EVENT);
423                 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
424                 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
425                 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
426 
427                 // set Port Params
428                 uint32_t nFrameWidth, nFrameHeight, xFramerate;
429                 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
430                                     &nFrameHeight, &xFramerate);
431                 // get configured color format
432                 OMX_PARAM_PORTDEFINITIONTYPE portDef;
433                 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
434                                       kPortIndexOutput, &portDef);
435                 setDefaultPortParam(omxNode, kPortIndexOutput,
436                                     OMX_VIDEO_CodingUnused,
437                                     portDef.format.video.eColorFormat,
438                                     nFrameWidth, nFrameHeight, 0, xFramerate);
439 
440                 // If you can disable a port, then you should be able to
441                 // enable it as well
442                 status = omxNode->sendCommand(
443                     toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
444                 ASSERT_EQ(status,
445                           android::hardware::media::omx::V1_0::Status::OK);
446 
447                 // do not enable the port until all the buffers are supplied
448                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
449                                                   iBuffer, oBuffer);
450                 ASSERT_EQ(
451                     status,
452                     android::hardware::media::omx::V1_0::Status::TIMED_OUT);
453 
454                 ASSERT_NO_FATAL_FAILURE(freePortBuffers(oBuffer, oPortMode, true));
455                 ASSERT_NO_FATAL_FAILURE(allocatePortBuffers(
456                     omxNode, oBuffer, kPortIndexOutput, oPortMode, true));
457                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
458                                                   iBuffer, oBuffer);
459                 ASSERT_EQ(status,
460                           android::hardware::media::omx::V1_0::Status::OK);
461                 ASSERT_EQ(msg.type, Message::Type::EVENT);
462                 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
463                 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
464 
465                 // Push back deferred messages to the list
466                 android::List<Message>::iterator it = msgQueueDefer.begin();
467                 while (it != msgQueueDefer.end()) {
468                     status = omxNode->dispatchMessage(*it);
469                     ASSERT_EQ(
470                         status,
471                         ::android::hardware::media::omx::V1_0::Status::OK);
472                     it++;
473                 }
474 
475                 // dispatch output buffers
476                 for (size_t i = 0; i < oBuffer->size(); i++) {
477                     ASSERT_NO_FATAL_FAILURE(
478                         dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode));
479                 }
480             } else {
481                 ASSERT_TRUE(false);
482             }
483         } else if (msg.data.eventData.data2 ==
484                    OMX_IndexConfigCommonOutputCrop) {
485             std::cout << "[   INFO   ] OMX_EventPortSettingsChanged/ "
486                          "OMX_IndexConfigCommonOutputCrop not handled \n";
487         } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
488             std::cout << "[   INFO   ] OMX_EventPortSettingsChanged/ "
489                          "kDescribeColorAspectsIndex not handled \n";
490         }
491     } else if (msg.data.eventData.event == OMX_EventError) {
492         std::cerr << "[   ERROR   ] OMX_EventError/ "
493                      "Decode Frame Call might be failed \n";
494         ASSERT_TRUE(false);
495     } else {
496         // something unexpected happened
497         ASSERT_TRUE(false);
498     }
499 }
500 
501 // blocking call to ensures application to Wait till all the inputs are consumed
waitOnInputConsumption(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,PortMode oPortMode)502 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
503                             android::Vector<BufferInfo>* iBuffer,
504                             android::Vector<BufferInfo>* oBuffer,
505                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
506                             PortMode oPortMode) {
507     android::hardware::media::omx::V1_0::Status status;
508     Message msg;
509     int timeOut = TIMEOUT_COUNTER_Q;
510 
511     while (timeOut--) {
512         size_t i = 0;
513         status =
514             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
515         if (status == android::hardware::media::omx::V1_0::Status::OK) {
516             ASSERT_EQ(msg.type, Message::Type::EVENT);
517             ASSERT_NO_FATAL_FAILURE(portReconfiguration(
518                 omxNode, observer, iBuffer, oBuffer, kPortIndexInput,
519                 kPortIndexOutput, msg, oPortMode, nullptr));
520         }
521         // status == TIMED_OUT, it could be due to process time being large
522         // than DEFAULT_TIMEOUT or component needs output buffers to start
523         // processing.
524         for (; i < iBuffer->size(); i++) {
525             if ((*iBuffer)[i].owner != client) break;
526         }
527         if (i == iBuffer->size()) break;
528 
529         // Dispatch an output buffer assuming outQueue.empty() is true
530         size_t index;
531         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
532             ASSERT_NO_FATAL_FAILURE(
533                 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode));
534             timeOut = TIMEOUT_COUNTER_Q;
535         }
536     }
537 }
538 
539 // Decode N Frames
decodeNFrames(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,std::ifstream & eleStream,android::Vector<FrameData> * Info,int offset,int range,PortMode oPortMode,bool signalEOS=true)540 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
541                    android::Vector<BufferInfo>* iBuffer,
542                    android::Vector<BufferInfo>* oBuffer,
543                    OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
544                    std::ifstream& eleStream, android::Vector<FrameData>* Info,
545                    int offset, int range, PortMode oPortMode,
546                    bool signalEOS = true) {
547     android::hardware::media::omx::V1_0::Status status;
548     Message msg;
549     size_t index;
550     uint32_t flags = 0;
551     int frameID = offset;
552     int timeOut = TIMEOUT_COUNTER_Q;
553     bool iQueued, oQueued;
554 
555     while (1) {
556         iQueued = oQueued = false;
557         status =
558             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
559         // Port Reconfiguration
560         if (status == android::hardware::media::omx::V1_0::Status::OK &&
561             msg.type == Message::Type::EVENT) {
562             ASSERT_NO_FATAL_FAILURE(portReconfiguration(
563                 omxNode, observer, iBuffer, oBuffer, kPortIndexInput,
564                 kPortIndexOutput, msg, oPortMode, nullptr));
565         }
566 
567         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
568 
569         // Dispatch input buffer
570         if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
571             char* ipBuffer = static_cast<char*>(
572                 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
573             ASSERT_LE((*Info)[frameID].bytesCount,
574                       static_cast<int>((*iBuffer)[index].mMemory->getSize()));
575             eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
576             ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
577             flags = (*Info)[frameID].flags;
578             // Indicate to omx core that the buffer contains a full frame worth
579             // of data
580             flags |= OMX_BUFFERFLAG_ENDOFFRAME;
581             // Indicate the omx core that this is the last buffer it needs to
582             // process
583             if (signalEOS && ((frameID == (int)Info->size() - 1) ||
584                               (frameID == (offset + range - 1))))
585                 flags |= OMX_BUFFERFLAG_EOS;
586             ASSERT_NO_FATAL_FAILURE(dispatchInputBuffer(
587                 omxNode, iBuffer, index, (*Info)[frameID].bytesCount, flags,
588                 (*Info)[frameID].timestamp));
589             frameID++;
590             iQueued = true;
591         }
592         // Dispatch output buffer
593         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
594             ASSERT_NO_FATAL_FAILURE(
595                 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode));
596             oQueued = true;
597         }
598         // Reset Counters when either input or output buffer is dispatched
599         if (iQueued || oQueued)
600             timeOut = TIMEOUT_COUNTER_Q;
601         else
602             timeOut--;
603         if (timeOut == 0) {
604             ASSERT_TRUE(false) << "Wait on Input/Output is found indefinite";
605         }
606     }
607 }
608 
609 // DescribeColorFormatParams Copy Constructor (Borrowed from OMXUtils.cpp)
DescribeColorFormatParams(const android::DescribeColorFormat2Params & params)610 android::DescribeColorFormatParams::DescribeColorFormatParams(
611     const android::DescribeColorFormat2Params& params) {
612     eColorFormat = params.eColorFormat;
613     nFrameWidth = params.nFrameWidth;
614     nFrameHeight = params.nFrameHeight;
615     nStride = params.nStride;
616     nSliceHeight = params.nSliceHeight;
617     bUsingNativeBuffers = params.bUsingNativeBuffers;
618 };
619 
isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,OMX_COLOR_FORMATTYPE eColorFormat)620 bool isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,
621                               OMX_COLOR_FORMATTYPE eColorFormat) {
622     android::hardware::media::omx::V1_0::Status status;
623     unsigned int index = OMX_IndexMax, index2 = OMX_IndexMax;
624     omxNode->getExtensionIndex(
625         "OMX.google.android.index.describeColorFormat",
626         [&index](android::hardware::media::omx::V1_0::Status _s,
627                           unsigned int _nl) {
628             if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
629                 index = _nl;
630         });
631     omxNode->getExtensionIndex(
632         "OMX.google.android.index.describeColorFormat2",
633         [&index2](android::hardware::media::omx::V1_0::Status _s,
634                            unsigned int _nl) {
635             if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
636                 index2 = _nl;
637         });
638 
639     android::DescribeColorFormat2Params describeParams;
640     describeParams.eColorFormat = eColorFormat;
641     describeParams.nFrameWidth = 128;
642     describeParams.nFrameHeight = 128;
643     describeParams.nStride = 128;
644     describeParams.nSliceHeight = 128;
645     describeParams.bUsingNativeBuffers = OMX_FALSE;
646     if (index != OMX_IndexMax) {
647         android::DescribeColorFormatParams describeParamsV1(describeParams);
648         status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index),
649                           &describeParamsV1);
650         if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
651             android::MediaImage& img = describeParamsV1.sMediaImage;
652             if (img.mType == android::MediaImage::MEDIA_IMAGE_TYPE_YUV) {
653                 if (img.mNumPlanes == 3 &&
654                     img.mPlane[img.Y].mHorizSubsampling == 1 &&
655                     img.mPlane[img.Y].mVertSubsampling == 1) {
656                     if (img.mPlane[img.U].mHorizSubsampling == 2 &&
657                         img.mPlane[img.U].mVertSubsampling == 2 &&
658                         img.mPlane[img.V].mHorizSubsampling == 2 &&
659                         img.mPlane[img.V].mVertSubsampling == 2) {
660                         if (img.mBitDepth <= 8) {
661                             return true;
662                         }
663                     }
664                 }
665             }
666         }
667     } else if (index2 != OMX_IndexMax) {
668         status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index2),
669                           &describeParams);
670         android::MediaImage2& img = describeParams.sMediaImage;
671         if (img.mType == android::MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
672             if (img.mNumPlanes == 3 &&
673                 img.mPlane[img.Y].mHorizSubsampling == 1 &&
674                 img.mPlane[img.Y].mVertSubsampling == 1) {
675                 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
676                     img.mPlane[img.U].mVertSubsampling == 2 &&
677                     img.mPlane[img.V].mHorizSubsampling == 2 &&
678                     img.mPlane[img.V].mVertSubsampling == 2) {
679                     if (img.mBitDepth <= 8) {
680                         return true;
681                     }
682                 }
683             }
684         }
685     }
686     return false;
687 }
688 
689 // get default color format for output port
getDefaultColorFormat(sp<IOmxNode> omxNode,OMX_U32 kPortIndexOutput,PortMode oPortMode,OMX_COLOR_FORMATTYPE * eColorFormat)690 void getDefaultColorFormat(sp<IOmxNode> omxNode, OMX_U32 kPortIndexOutput,
691                            PortMode oPortMode,
692                            OMX_COLOR_FORMATTYPE* eColorFormat) {
693     android::hardware::media::omx::V1_0::Status status;
694     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
695     *eColorFormat = OMX_COLOR_FormatUnused;
696     portFormat.nIndex = 0;
697     while (portFormat.nIndex < 512) {
698         status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
699                               kPortIndexOutput, &portFormat);
700         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
701         EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
702         if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
703             *eColorFormat = portFormat.eColorFormat;
704             break;
705         }
706         if (isColorFormatFlexibleYUV(omxNode, portFormat.eColorFormat)) {
707             *eColorFormat = portFormat.eColorFormat;
708             break;
709         }
710         if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
711             OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat ||
712             OMX_COLOR_FormatYUV420PackedPlanar == portFormat.eColorFormat ||
713             OMX_COLOR_FormatYUV420PackedSemiPlanar == portFormat.eColorFormat) {
714             *eColorFormat = portFormat.eColorFormat;
715             break;
716         }
717         portFormat.nIndex++;
718     }
719 }
720 
721 // set component role
TEST_P(VideoDecHidlTest,SetRole)722 TEST_P(VideoDecHidlTest, SetRole) {
723     description("Test Set Component Role");
724     if (disableTest) return;
725     android::hardware::media::omx::V1_0::Status status;
726     status = setRole(omxNode, role_);
727     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
728 }
729 
730 // port format enumeration
TEST_P(VideoDecHidlTest,EnumeratePortFormat)731 TEST_P(VideoDecHidlTest, EnumeratePortFormat) {
732     description("Test Component on Mandatory Port Parameters (Port Format)");
733     if (disableTest) return;
734     android::hardware::media::omx::V1_0::Status status;
735     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
736     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
737     OMX_U32 xFramerate = (24U << 16);
738     status = setRole(omxNode, role_);
739     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
740     OMX_PORT_PARAM_TYPE params;
741     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
742     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
743         ASSERT_EQ(params.nPorts, 2U);
744         kPortIndexInput = params.nStartPortNumber;
745         kPortIndexOutput = kPortIndexInput + 1;
746     }
747     status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
748                                 OMX_COLOR_FormatUnused, 0U);
749     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
750     status =
751         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
752                            eColorFormat, xFramerate);
753     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
754 }
755 
756 // test port settings reconfiguration, elementary stream decode and timestamp
757 // deviation
TEST_P(VideoDecHidlTest,DecodeTest)758 TEST_P(VideoDecHidlTest, DecodeTest) {
759     description("Tests Port Reconfiguration, Decode and timestamp deviation");
760     if (disableTest) return;
761     android::hardware::media::omx::V1_0::Status status;
762     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
763     status = setRole(omxNode, role_);
764     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
765     OMX_PORT_PARAM_TYPE params;
766     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
767     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
768         ASSERT_EQ(params.nPorts, 2U);
769         kPortIndexInput = params.nStartPortNumber;
770         kPortIndexOutput = kPortIndexInput + 1;
771     }
772     char mURL[512], info[512];
773     strcpy(mURL, sResourceDir.c_str());
774     strcpy(info, sResourceDir.c_str());
775     GetURLForComponent(compName, mURL, info);
776 
777     std::ifstream eleStream, eleInfo;
778 
779     eleInfo.open(info);
780     ASSERT_EQ(eleInfo.is_open(), true);
781     android::Vector<FrameData> Info;
782     int bytesCount = 0, maxBytesCount = 0;
783     uint32_t flags = 0;
784     uint32_t timestamp = 0;
785     timestampDevTest = true;
786     while (1) {
787         if (!(eleInfo >> bytesCount)) break;
788         eleInfo >> flags;
789         eleInfo >> timestamp;
790         Info.push_back({bytesCount, flags, timestamp});
791         if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
792             timestampUslist.push_back(timestamp);
793         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
794     }
795     eleInfo.close();
796 
797     // As the frame sizes are known ahead, use it to configure i/p buffer size
798     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
799     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
800     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
801 
802     // set port mode
803     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
804     portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
805     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
806     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
807     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
808     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
809         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
810         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
811         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
812     }
813 
814     // set Port Params
815     uint32_t nFrameWidth, nFrameHeight, xFramerate;
816     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
817                         &xFramerate);
818     // get default color format
819     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
820     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
821                           &eColorFormat);
822     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
823     status =
824         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
825                            eColorFormat, xFramerate);
826     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
827     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
828                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
829 
830     android::Vector<BufferInfo> iBuffer, oBuffer;
831 
832     // set state to idle
833     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
834         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
835         kPortIndexOutput, portMode, true));
836     // set state to executing
837     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
838 
839     // Port Reconfiguration
840     eleStream.open(mURL, std::ifstream::binary);
841     ASSERT_EQ(eleStream.is_open(), true);
842     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
843         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
844         kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(), portMode[1]));
845     eleStream.close();
846     ASSERT_NO_FATAL_FAILURE(
847         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
848                                kPortIndexInput, kPortIndexOutput, portMode[1]));
849     ASSERT_NO_FATAL_FAILURE(testEOS(
850         omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
851         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
852     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
853     // set state to idle
854     ASSERT_NO_FATAL_FAILURE(
855         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
856     // set state to executing
857     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
858                                                     kPortIndexInput, kPortIndexOutput, portMode,
859                                                     true));
860 }
861 
862 // Test for adaptive playback support
TEST_P(VideoDecHidlTest,AdaptivePlaybackTest)863 TEST_P(VideoDecHidlTest, AdaptivePlaybackTest) {
864     description("Tests for Adaptive Playback support");
865     if (disableTest) return;
866     if (!(compName == avc || compName == hevc || compName == vp8 ||
867           compName == vp9 || compName == mpeg2))
868         return;
869     android::hardware::media::omx::V1_0::Status status;
870     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
871     status = setRole(omxNode, role_);
872     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
873     OMX_PORT_PARAM_TYPE params;
874     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
875     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
876         ASSERT_EQ(params.nPorts, 2U);
877         kPortIndexInput = params.nStartPortNumber;
878         kPortIndexOutput = kPortIndexInput + 1;
879     }
880 
881     // set port mode
882     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
883     portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
884     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
885     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
886     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
887     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
888         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
889         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
890         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
891     }
892 
893     // prepare for adaptive playback
894     uint32_t adaptiveMaxWidth = 320;
895     uint32_t adaptiveMaxHeight = 240;
896     status = omxNode->prepareForAdaptivePlayback(
897         kPortIndexOutput, true, adaptiveMaxWidth, adaptiveMaxHeight);
898     if (component_.find("OMX.google.") == 0) {
899         // SoftOMX Decoders donot support graphic buffer modes. So for them
900         // support for adaptive play back is mandatory in Byte Buffer mode
901         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
902     } else {
903         // for vendor codecs, support for adaptive play back is optional
904         // in byte buffer mode.
905         if (portMode[1] == PortMode::PRESET_BYTE_BUFFER) return;
906         if (status != ::android::hardware::media::omx::V1_0::Status::OK) return;
907     }
908 
909     // TODO: Handle this better !!!
910     // Without the knowledge of the maximum resolution of the frame to be
911     // decoded it is not possible to choose the size of the input buffer.
912     // The value below is based on the info. files of clips in res folder.
913     status = setPortBufferSize(omxNode, kPortIndexInput, 482304);
914     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
915 
916     // set Port Params
917     uint32_t nFrameWidth, nFrameHeight, xFramerate;
918     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
919                         &xFramerate);
920     // get default color format
921     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
922     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
923                           &eColorFormat);
924     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
925     status =
926         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
927                            eColorFormat, xFramerate);
928     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
929     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
930                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
931 
932     android::Vector<BufferInfo> iBuffer, oBuffer;
933 
934     // set state to idle
935     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
936         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
937         kPortIndexOutput, portMode, true));
938     // set state to executing
939     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
940 
941     timestampDevTest = true;
942     uint32_t timestampOffset = 0;
943     for (uint32_t i = 0; i < STREAM_COUNT * 2; i++) {
944         std::ifstream eleStream, eleInfo;
945         char mURL[512], info[512];
946         android::Vector<FrameData> Info;
947         strcpy(mURL, sResourceDir.c_str());
948         strcpy(info, sResourceDir.c_str());
949         GetURLForComponent(compName, mURL, info, i % STREAM_COUNT);
950         eleInfo.open(info);
951         ASSERT_EQ(eleInfo.is_open(), true);
952         int bytesCount = 0;
953         uint32_t flags = 0;
954         uint32_t timestamp = 0;
955         uint32_t timestampMax = 0;
956         while (1) {
957             if (!(eleInfo >> bytesCount)) break;
958             eleInfo >> flags;
959             eleInfo >> timestamp;
960             timestamp += timestampOffset;
961             Info.push_back({bytesCount, flags, timestamp});
962             if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
963                 timestampUslist.push_back(timestamp);
964             if (timestampMax < timestamp) timestampMax = timestamp;
965         }
966         timestampOffset = timestampMax;
967         eleInfo.close();
968 
969         // Port Reconfiguration
970         eleStream.open(mURL, std::ifstream::binary);
971         ASSERT_EQ(eleStream.is_open(), true);
972         ASSERT_NO_FATAL_FAILURE(
973             decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
974                           kPortIndexInput, kPortIndexOutput, eleStream, &Info,
975                           0, (int)Info.size(), portMode[1], false));
976         eleStream.close();
977 
978         getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
979                             &nFrameHeight, &xFramerate);
980         if ((nFrameWidth > adaptiveMaxWidth) ||
981             (nFrameHeight > adaptiveMaxHeight)) {
982             if (nFrameWidth > adaptiveMaxWidth) adaptiveMaxWidth = nFrameWidth;
983             if (nFrameHeight > adaptiveMaxHeight)
984                 adaptiveMaxHeight = nFrameHeight;
985             EXPECT_TRUE(portSettingsChange);
986         } else {
987             // In DynamicANW Buffer mode, its ok to do a complete
988             // reconfiguration even if a partial reconfiguration is sufficient.
989             if (portMode[1] != PortMode::DYNAMIC_ANW_BUFFER)
990                 EXPECT_FALSE(portSettingsChange);
991         }
992         portSettingsChange = false;
993     }
994     ASSERT_NO_FATAL_FAILURE(
995         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
996                                kPortIndexInput, kPortIndexOutput, portMode[1]));
997     ASSERT_NO_FATAL_FAILURE(testEOS(
998         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
999         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1000     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
1001     // set state to idle
1002     ASSERT_NO_FATAL_FAILURE(
1003         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1004     // set state to executing
1005     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1006                                                     kPortIndexInput, kPortIndexOutput, portMode,
1007                                                     true));
1008 }
1009 
1010 // end of sequence test
TEST_P(VideoDecHidlTest,EOSTest_M)1011 TEST_P(VideoDecHidlTest, EOSTest_M) {
1012     description("Test End of stream monkeying");
1013     if (disableTest) return;
1014     android::hardware::media::omx::V1_0::Status status;
1015     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1016     status = setRole(omxNode, role_);
1017     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1018     OMX_PORT_PARAM_TYPE params;
1019     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1020     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1021         ASSERT_EQ(params.nPorts, 2U);
1022         kPortIndexInput = params.nStartPortNumber;
1023         kPortIndexOutput = kPortIndexInput + 1;
1024     }
1025 
1026     // set port mode
1027     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1028     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1029     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1030     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1031 
1032     // set Port Params
1033     uint32_t nFrameWidth, nFrameHeight, xFramerate;
1034     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1035                         &xFramerate);
1036     // get default color format
1037     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1038     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1039                           &eColorFormat);
1040     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1041     status =
1042         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1043                            eColorFormat, xFramerate);
1044     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1045     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1046                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1047 
1048     android::Vector<BufferInfo> iBuffer, oBuffer;
1049 
1050     // set state to idle
1051     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1052         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1053         kPortIndexOutput, portMode, true));
1054     // set state to executing
1055     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1056 
1057     // request EOS at the start
1058     ASSERT_NO_FATAL_FAILURE(testEOS(
1059         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1060         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1061     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1062                                        kPortIndexInput, kPortIndexOutput));
1063     EXPECT_GE(framesReceived, 0U);
1064     framesReceived = 0;
1065     timestampUs = 0;
1066 
1067     // set state to idle
1068     ASSERT_NO_FATAL_FAILURE(
1069         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1070     // set state to executing
1071     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1072                                                     kPortIndexInput, kPortIndexOutput, portMode,
1073                                                     true));
1074 }
1075 
1076 // end of sequence test
TEST_P(VideoDecHidlTest,ThumbnailTest)1077 TEST_P(VideoDecHidlTest, ThumbnailTest) {
1078     description("Test Request for thumbnail");
1079     if (disableTest) return;
1080     android::hardware::media::omx::V1_0::Status status;
1081     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1082     status = setRole(omxNode, role_);
1083     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1084     OMX_PORT_PARAM_TYPE params;
1085     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1086     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1087         ASSERT_EQ(params.nPorts, 2U);
1088         kPortIndexInput = params.nStartPortNumber;
1089         kPortIndexOutput = kPortIndexInput + 1;
1090     }
1091     char mURL[512], info[512];
1092     strcpy(mURL, sResourceDir.c_str());
1093     strcpy(info, sResourceDir.c_str());
1094     GetURLForComponent(compName, mURL, info);
1095 
1096     std::ifstream eleStream, eleInfo;
1097 
1098     eleInfo.open(info);
1099     ASSERT_EQ(eleInfo.is_open(), true);
1100     android::Vector<FrameData> Info;
1101     int bytesCount = 0, maxBytesCount = 0;
1102     uint32_t flags = 0;
1103     uint32_t timestamp = 0;
1104     while (1) {
1105         if (!(eleInfo >> bytesCount)) break;
1106         eleInfo >> flags;
1107         eleInfo >> timestamp;
1108         Info.push_back({bytesCount, flags, timestamp});
1109         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1110     }
1111     eleInfo.close();
1112 
1113     // As the frame sizes are known ahead, use it to configure i/p buffer size
1114     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1115     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1116     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1117 
1118     // set port mode
1119     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1120     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1121     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1122     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1123 
1124     // set Port Params
1125     uint32_t nFrameWidth, nFrameHeight, xFramerate;
1126     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1127                         &xFramerate);
1128     // get default color format
1129     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1130     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1131                           &eColorFormat);
1132     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1133     status =
1134         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1135                            eColorFormat, xFramerate);
1136     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1137     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1138                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1139 
1140     android::Vector<BufferInfo> iBuffer, oBuffer;
1141 
1142     // set state to idle
1143     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1144         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1145         kPortIndexOutput, portMode, true));
1146     // set state to executing
1147     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1148 
1149     // request EOS for thumbnail
1150     size_t i = 0;
1151     while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
1152     eleStream.open(mURL, std::ifstream::binary);
1153     ASSERT_EQ(eleStream.is_open(), true);
1154     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
1155         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1156         kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1]));
1157     eleStream.close();
1158     ASSERT_NO_FATAL_FAILURE(
1159         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1160                                kPortIndexInput, kPortIndexOutput, portMode[1]));
1161     ASSERT_NO_FATAL_FAILURE(testEOS(
1162         omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
1163         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1164     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1165                                        kPortIndexInput, kPortIndexOutput));
1166     EXPECT_GE(framesReceived, 1U);
1167     framesReceived = 0;
1168     timestampUs = 0;
1169 
1170     eleStream.open(mURL, std::ifstream::binary);
1171     ASSERT_EQ(eleStream.is_open(), true);
1172     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
1173         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1174         kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1], false));
1175     eleStream.close();
1176     ASSERT_NO_FATAL_FAILURE(
1177         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1178                                kPortIndexInput, kPortIndexOutput, portMode[1]));
1179     ASSERT_NO_FATAL_FAILURE(testEOS(
1180         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1181         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1182     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1183                                        kPortIndexInput, kPortIndexOutput));
1184     EXPECT_GE(framesReceived, 1U);
1185     framesReceived = 0;
1186     timestampUs = 0;
1187 
1188     // set state to idle
1189     ASSERT_NO_FATAL_FAILURE(
1190         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1191     // set state to executing
1192     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1193                                                     kPortIndexInput, kPortIndexOutput, portMode,
1194                                                     true));
1195 }
1196 
1197 // end of sequence test
TEST_P(VideoDecHidlTest,SimpleEOSTest)1198 TEST_P(VideoDecHidlTest, SimpleEOSTest) {
1199     description("Test End of stream");
1200     if (disableTest) return;
1201     android::hardware::media::omx::V1_0::Status status;
1202     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1203     status = setRole(omxNode, role_);
1204     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1205     OMX_PORT_PARAM_TYPE params;
1206     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1207     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1208         ASSERT_EQ(params.nPorts, 2U);
1209         kPortIndexInput = params.nStartPortNumber;
1210         kPortIndexOutput = kPortIndexInput + 1;
1211     }
1212     char mURL[512], info[512];
1213     strcpy(mURL, sResourceDir.c_str());
1214     strcpy(info, sResourceDir.c_str());
1215     GetURLForComponent(compName, mURL, info);
1216 
1217     std::ifstream eleStream, eleInfo;
1218 
1219     eleInfo.open(info);
1220     ASSERT_EQ(eleInfo.is_open(), true);
1221     android::Vector<FrameData> Info;
1222     int bytesCount = 0, maxBytesCount = 0;
1223     uint32_t flags = 0;
1224     uint32_t timestamp = 0;
1225     while (1) {
1226         if (!(eleInfo >> bytesCount)) break;
1227         eleInfo >> flags;
1228         eleInfo >> timestamp;
1229         Info.push_back({bytesCount, flags, timestamp});
1230         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1231     }
1232     eleInfo.close();
1233 
1234     // As the frame sizes are known ahead, use it to configure i/p buffer size
1235     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1236     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1237     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1238 
1239     // set port mode
1240     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
1241     portMode[1] = PortMode::PRESET_ANW_BUFFER;
1242     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1243     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1244     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1245     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
1246         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1247         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1248         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1249     }
1250 
1251     // set Port Params
1252     uint32_t nFrameWidth, nFrameHeight, xFramerate;
1253     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1254                         &xFramerate);
1255     // get default color format
1256     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1257     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1258                           &eColorFormat);
1259     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1260     status =
1261         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1262                            eColorFormat, xFramerate);
1263     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1264     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1265                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1266 
1267     android::Vector<BufferInfo> iBuffer, oBuffer;
1268 
1269     // set state to idle
1270     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1271         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1272         kPortIndexOutput, portMode, true));
1273     // set state to executing
1274     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1275 
1276     // request EOS at the end
1277     eleStream.open(mURL, std::ifstream::binary);
1278     ASSERT_EQ(eleStream.is_open(), true);
1279     ASSERT_NO_FATAL_FAILURE(decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
1280                                           kPortIndexInput, kPortIndexOutput,
1281                                           eleStream, &Info, 0, (int)Info.size(),
1282                                           portMode[1], false));
1283     eleStream.close();
1284     ASSERT_NO_FATAL_FAILURE(
1285         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1286                                kPortIndexInput, kPortIndexOutput, portMode[1]));
1287     ASSERT_NO_FATAL_FAILURE(testEOS(
1288         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1289         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1290     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1291                                        kPortIndexInput, kPortIndexOutput));
1292     framesReceived = 0;
1293     timestampUs = 0;
1294 
1295     // set state to idle
1296     ASSERT_NO_FATAL_FAILURE(
1297         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1298     // set state to executing
1299     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1300                                                     kPortIndexInput, kPortIndexOutput, portMode,
1301                                                     true));
1302 }
1303 
1304 // test input/output port flush
TEST_P(VideoDecHidlTest,FlushTest)1305 TEST_P(VideoDecHidlTest, FlushTest) {
1306     description("Test Flush");
1307     if (disableTest) return;
1308     android::hardware::media::omx::V1_0::Status status;
1309     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1310     status = setRole(omxNode, role_);
1311     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1312     OMX_PORT_PARAM_TYPE params;
1313     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1314     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1315         ASSERT_EQ(params.nPorts, 2U);
1316         kPortIndexInput = params.nStartPortNumber;
1317         kPortIndexOutput = kPortIndexInput + 1;
1318     }
1319     char mURL[512], info[512];
1320     strcpy(mURL, sResourceDir.c_str());
1321     strcpy(info, sResourceDir.c_str());
1322     GetURLForComponent(compName, mURL, info);
1323 
1324     std::ifstream eleStream, eleInfo;
1325 
1326     eleInfo.open(info);
1327     ASSERT_EQ(eleInfo.is_open(), true);
1328     android::Vector<FrameData> Info;
1329     int bytesCount = 0, maxBytesCount = 0;
1330     uint32_t flags = 0;
1331     uint32_t timestamp = 0;
1332     while (1) {
1333         if (!(eleInfo >> bytesCount)) break;
1334         eleInfo >> flags;
1335         eleInfo >> timestamp;
1336         Info.push_back({bytesCount, flags, timestamp});
1337         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1338     }
1339     eleInfo.close();
1340 
1341     // As the frame sizes are known ahead, use it to configure i/p buffer size
1342     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1343     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1344     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1345 
1346     // set port mode
1347     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1348     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1349     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1350     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1351 
1352     // set Port Params
1353     uint32_t nFrameWidth, nFrameHeight, xFramerate;
1354     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1355                         &xFramerate);
1356     // get default color format
1357     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1358     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1359                           &eColorFormat);
1360     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1361     status =
1362         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1363                            eColorFormat, xFramerate);
1364     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1365     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1366                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1367 
1368     android::Vector<BufferInfo> iBuffer, oBuffer;
1369 
1370     // set state to idle
1371     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1372         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1373         kPortIndexOutput, portMode, true));
1374     // set state to executing
1375     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1376 
1377     // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
1378     // frame after this so that the below section can be convered for all
1379     // components
1380     int nFrames = 128;
1381     eleStream.open(mURL, std::ifstream::binary);
1382     ASSERT_EQ(eleStream.is_open(), true);
1383     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
1384         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1385         kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1], false));
1386     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1387                                        kPortIndexInput, kPortIndexOutput));
1388     framesReceived = 0;
1389 
1390     // Seek to next key frame and start decoding till the end
1391     int index = nFrames;
1392     bool keyFrame = false;
1393     while (index < (int)Info.size()) {
1394         if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
1395             OMX_BUFFERFLAG_SYNCFRAME) {
1396             timestampUs = Info[index - 1].timestamp;
1397             keyFrame = true;
1398             break;
1399         }
1400         eleStream.ignore(Info[index].bytesCount);
1401         index++;
1402     }
1403     if (keyFrame) {
1404         ASSERT_NO_FATAL_FAILURE(
1405             decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
1406                           kPortIndexInput, kPortIndexOutput, eleStream, &Info,
1407                           index, Info.size() - index, portMode[1], false));
1408     }
1409     eleStream.close();
1410     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1411                                        kPortIndexInput, kPortIndexOutput));
1412     framesReceived = 0;
1413 
1414     // set state to idle
1415     ASSERT_NO_FATAL_FAILURE(
1416         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1417     // set state to executing
1418     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1419                                                     kPortIndexInput, kPortIndexOutput, portMode,
1420                                                     true));
1421 }
1422 
1423 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VideoDecHidlTest);
1424 INSTANTIATE_TEST_SUITE_P(PerInstance, VideoDecHidlTest, testing::ValuesIn(kTestParameters),
1425                          android::hardware::PrintInstanceTupleNameToString<>);
1426 
main(int argc,char ** argv)1427 int main(int argc, char** argv) {
1428     kTestParameters = getTestParameters("video_decoder");
1429     ::testing::InitGoogleTest(&argc, argv);
1430 
1431     // Set the resource directory based on command line args.
1432     // Test will fail to set up if the argument is not set.
1433     for (int i = 1; i < argc; i++) {
1434         if (strcmp(argv[i], "-P") == 0 && i < argc - 1) {
1435             sResourceDir = argv[i + 1];
1436             break;
1437         }
1438     }
1439 
1440     return RUN_ALL_TESTS();
1441 }