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