OSDN Git Service

Merge "graphics: sideband streams are not buffers" into oc-dr1-dev am: 9071cc5bbc
[android-x86/hardware-interfaces.git] / media / omx / 1.0 / vts / functional / video / VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
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 #include <android-base/logging.h>
19
20 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
21 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
22 #include <android/hardware/graphics/mapper/2.0/types.h>
23 #include <android/hardware/media/omx/1.0/IOmx.h>
24 #include <android/hardware/media/omx/1.0/IOmxNode.h>
25 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
26 #include <android/hardware/media/omx/1.0/types.h>
27 #include <android/hidl/allocator/1.0/IAllocator.h>
28 #include <android/hidl/memory/1.0/IMapper.h>
29 #include <android/hidl/memory/1.0/IMemory.h>
30
31 using ::android::hardware::graphics::common::V1_0::BufferUsage;
32 using ::android::hardware::graphics::common::V1_0::PixelFormat;
33 using ::android::hardware::media::omx::V1_0::IOmx;
34 using ::android::hardware::media::omx::V1_0::IOmxObserver;
35 using ::android::hardware::media::omx::V1_0::IOmxNode;
36 using ::android::hardware::media::omx::V1_0::Message;
37 using ::android::hardware::media::omx::V1_0::CodecBuffer;
38 using ::android::hardware::media::omx::V1_0::PortMode;
39 using ::android::hidl::allocator::V1_0::IAllocator;
40 using ::android::hidl::memory::V1_0::IMemory;
41 using ::android::hidl::memory::V1_0::IMapper;
42 using ::android::hardware::Return;
43 using ::android::hardware::Void;
44 using ::android::hardware::hidl_vec;
45 using ::android::hardware::hidl_string;
46 using ::android::sp;
47
48 #include <VtsHalHidlTargetTestBase.h>
49 #include <getopt.h>
50 #include <media_hidl_test_common.h>
51 #include <media_video_hidl_test_common.h>
52 #include <fstream>
53
54 // A class for test environment setup
55 class ComponentTestEnvironment : public ::testing::Environment {
56    public:
57     virtual void SetUp() {}
58     virtual void TearDown() {}
59
60     ComponentTestEnvironment() : instance("default"), res("/sdcard/media/") {}
61
62     void setInstance(const char* _instance) { instance = _instance; }
63
64     void setComponent(const char* _component) { component = _component; }
65
66     void setRole(const char* _role) { role = _role; }
67
68     void setRes(const char* _res) { res = _res; }
69
70     const hidl_string getInstance() const { return instance; }
71
72     const hidl_string getComponent() const { return component; }
73
74     const hidl_string getRole() const { return role; }
75
76     const hidl_string getRes() const { return res; }
77
78     int initFromOptions(int argc, char** argv) {
79         static struct option options[] = {
80             {"instance", required_argument, 0, 'I'},
81             {"component", required_argument, 0, 'C'},
82             {"role", required_argument, 0, 'R'},
83             {"res", required_argument, 0, 'P'},
84             {0, 0, 0, 0}};
85
86         while (true) {
87             int index = 0;
88             int c = getopt_long(argc, argv, "I:C:R:P:", options, &index);
89             if (c == -1) {
90                 break;
91             }
92
93             switch (c) {
94                 case 'I':
95                     setInstance(optarg);
96                     break;
97                 case 'C':
98                     setComponent(optarg);
99                     break;
100                 case 'R':
101                     setRole(optarg);
102                     break;
103                 case 'P':
104                     setRes(optarg);
105                     break;
106                 case '?':
107                     break;
108             }
109         }
110
111         if (optind < argc) {
112             fprintf(stderr,
113                     "unrecognized option: %s\n\n"
114                     "usage: %s <gtest options> <test options>\n\n"
115                     "test options are:\n\n"
116                     "-I, --instance: HAL instance to test\n"
117                     "-C, --component: OMX component to test\n"
118                     "-R, --role: OMX component Role\n"
119                     "-P, --res: Resource files directory location\n",
120                     argv[optind ?: 1], argv[0]);
121             return 2;
122         }
123         return 0;
124     }
125
126    private:
127     hidl_string instance;
128     hidl_string component;
129     hidl_string role;
130     hidl_string res;
131 };
132
133 static ComponentTestEnvironment* gEnv = nullptr;
134
135 // video decoder test fixture class
136 class VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
137    private:
138     typedef ::testing::VtsHalHidlTargetTestBase Super;
139    public:
140     ::std::string getTestCaseInfo() const override {
141         return ::std::string() +
142                 "Component: " + gEnv->getComponent().c_str() + " | " +
143                 "Role: " + gEnv->getRole().c_str() + " | " +
144                 "Instance: " + gEnv->getInstance().c_str() + " | " +
145                 "Res: " + gEnv->getRes().c_str();
146     }
147
148     virtual void SetUp() override {
149         Super::SetUp();
150         disableTest = false;
151         android::hardware::media::omx::V1_0::Status status;
152         omx = Super::getService<IOmx>(gEnv->getInstance());
153         ASSERT_NE(omx, nullptr);
154         observer =
155             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
156                 handleMessage(msg, buffer);
157             });
158         ASSERT_NE(observer, nullptr);
159         if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
160             disableTest = true;
161         EXPECT_TRUE(omx->allocateNode(
162                            gEnv->getComponent(), observer,
163                            [&](android::hardware::media::omx::V1_0::Status _s,
164                                sp<IOmxNode> const& _nl) {
165                                status = _s;
166                                this->omxNode = _nl;
167                            })
168                         .isOk());
169         ASSERT_NE(omxNode, nullptr);
170         ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
171         struct StringToName {
172             const char* Name;
173             standardComp CompName;
174         };
175         const StringToName kStringToName[] = {
176             {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
177             {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
178         };
179         const size_t kNumStringToName =
180             sizeof(kStringToName) / sizeof(kStringToName[0]);
181         const char* pch;
182         char substring[OMX_MAX_STRINGNAME_SIZE];
183         strcpy(substring, gEnv->getRole().c_str());
184         pch = strchr(substring, '.');
185         ASSERT_NE(pch, nullptr);
186         compName = unknown_comp;
187         for (size_t i = 0; i < kNumStringToName; ++i) {
188             if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
189                 compName = kStringToName[i].CompName;
190                 break;
191             }
192         }
193         if (compName == unknown_comp) disableTest = true;
194         struct CompToCompression {
195             standardComp CompName;
196             OMX_VIDEO_CODINGTYPE eCompressionFormat;
197         };
198         static const CompToCompression kCompToCompression[] = {
199             {h263, OMX_VIDEO_CodingH263},   {avc, OMX_VIDEO_CodingAVC},
200             {mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
201             {hevc, OMX_VIDEO_CodingHEVC},   {vp8, OMX_VIDEO_CodingVP8},
202             {vp9, OMX_VIDEO_CodingVP9},
203         };
204         static const size_t kNumCompToCompression =
205             sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
206         size_t i;
207         for (i = 0; i < kNumCompToCompression; ++i) {
208             if (kCompToCompression[i].CompName == compName) {
209                 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
210                 break;
211             }
212         }
213         if (i == kNumCompToCompression) disableTest = true;
214         portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
215         eosFlag = false;
216         framesReceived = 0;
217         timestampUs = 0;
218         timestampDevTest = false;
219         isSecure = false;
220         size_t suffixLen = strlen(".secure");
221         if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
222             isSecure =
223                 !strcmp(gEnv->getComponent().c_str() +
224                             strlen(gEnv->getComponent().c_str()) - suffixLen,
225                         ".secure");
226         }
227         if (isSecure) disableTest = true;
228         if (disableTest) std::cout << "[          ] Warning !  Test Disabled\n";
229     }
230
231     virtual void TearDown() override {
232         if (omxNode != nullptr) {
233             EXPECT_TRUE((omxNode->freeNode()).isOk());
234             omxNode = nullptr;
235         }
236         Super::TearDown();
237     }
238
239     // callback function to process messages received by onMessages() from IL
240     // client.
241     void handleMessage(Message msg, const BufferInfo* buffer) {
242         (void)buffer;
243         if (msg.type == Message::Type::FILL_BUFFER_DONE) {
244             if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
245                 eosFlag = true;
246             }
247             if (msg.data.extendedBufferData.rangeLength != 0) {
248                 framesReceived += 1;
249                 // For decoder components current timestamp always exceeds
250                 // previous timestamp
251                 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
252                 timestampUs = msg.data.extendedBufferData.timestampUs;
253                 // Test if current timestamp is among the list of queued
254                 // timestamps
255                 if (timestampDevTest) {
256                     bool tsHit = false;
257                     android::List<uint64_t>::iterator it =
258                         timestampUslist.begin();
259                     while (it != timestampUslist.end()) {
260                         if (*it == timestampUs) {
261                             timestampUslist.erase(it);
262                             tsHit = true;
263                             break;
264                         }
265                         it++;
266                     }
267                     if (tsHit == false) {
268                         if (timestampUslist.empty() == false) {
269                             EXPECT_EQ(tsHit, true)
270                                 << "TimeStamp not recognized";
271                         } else {
272                             std::cout
273                                 << "[          ] Warning ! Received non-zero "
274                                    "output / TimeStamp not recognized \n";
275                         }
276                     }
277                 }
278 #define WRITE_OUTPUT 0
279 #if WRITE_OUTPUT
280                 static int count = 0;
281                 FILE* ofp = nullptr;
282                 if (count)
283                     ofp = fopen("out.bin", "ab");
284                 else
285                     ofp = fopen("out.bin", "wb");
286                 if (ofp != nullptr &&
287                     portMode[1] == PortMode::PRESET_BYTE_BUFFER) {
288                     fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
289                            sizeof(char),
290                            msg.data.extendedBufferData.rangeLength, ofp);
291                     fclose(ofp);
292                     count++;
293                 }
294 #endif
295             }
296         }
297     }
298
299     enum standardComp {
300         h263,
301         avc,
302         mpeg2,
303         mpeg4,
304         hevc,
305         vp8,
306         vp9,
307         unknown_comp,
308     };
309
310     sp<IOmx> omx;
311     sp<CodecObserver> observer;
312     sp<IOmxNode> omxNode;
313     standardComp compName;
314     OMX_VIDEO_CODINGTYPE eCompressionFormat;
315     bool disableTest;
316     PortMode portMode[2];
317     bool eosFlag;
318     uint32_t framesReceived;
319     uint64_t timestampUs;
320     ::android::List<uint64_t> timestampUslist;
321     bool timestampDevTest;
322     bool isSecure;
323
324    protected:
325     static void description(const std::string& description) {
326         RecordProperty("description", description);
327     }
328 };
329
330 // Set Default port param.
331 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
332                          OMX_VIDEO_CODINGTYPE eCompressionFormat,
333                          OMX_COLOR_FORMATTYPE eColorFormat,
334                          OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
335                          OMX_U32 nBitrate = 0,
336                          OMX_U32 xFramerate = (24U << 16)) {
337     switch ((int)eCompressionFormat) {
338         case OMX_VIDEO_CodingUnused:
339             setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
340                          nBitrate, xFramerate, eColorFormat);
341             break;
342         default:
343             break;
344     }
345 }
346
347 // In decoder components, often the input port parameters get updated upon
348 // parsing the header of elementary stream. Client needs to collect this
349 // information to reconfigure other ports that share data with this input
350 // port.
351 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
352                          uint32_t* nFrameWidth, uint32_t* nFrameHeight,
353                          uint32_t* xFramerate) {
354     android::hardware::media::omx::V1_0::Status status;
355     *nFrameWidth = 352;
356     *nFrameHeight = 288;
357     *xFramerate = (24U << 16);
358
359     OMX_PARAM_PORTDEFINITIONTYPE portDef;
360     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
361                           kPortIndexInput, &portDef);
362     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
363     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
364         *nFrameWidth = portDef.format.video.nFrameWidth;
365         *nFrameHeight = portDef.format.video.nFrameHeight;
366         *xFramerate = portDef.format.video.xFramerate;
367     }
368 }
369
370 // LookUpTable of clips and metadata for component testing
371 void GetURLForComponent(VideoDecHidlTest::standardComp comp, char* mURL,
372                         char* info) {
373     struct CompToURL {
374         VideoDecHidlTest::standardComp comp;
375         const char* mURL;
376         const char* info;
377     };
378     static const CompToURL kCompToURL[] = {
379         {VideoDecHidlTest::standardComp::avc,
380          "bbb_avc_1920x1080_5000kbps_30fps.h264",
381          "bbb_avc_1920x1080_5000kbps_30fps.info"},
382         {VideoDecHidlTest::standardComp::hevc,
383          "bbb_hevc_640x360_1600kbps_30fps.hevc",
384          "bbb_hevc_640x360_1600kbps_30fps.info"},
385         {VideoDecHidlTest::standardComp::mpeg2,
386          "bbb_mpeg2_176x144_105kbps_25fps.m2v",
387          "bbb_mpeg2_176x144_105kbps_25fps.info"},
388         {VideoDecHidlTest::standardComp::h263,
389          "bbb_h263_352x288_300kbps_12fps.h263",
390          "bbb_h263_352x288_300kbps_12fps.info"},
391         {VideoDecHidlTest::standardComp::mpeg4,
392          "bbb_mpeg4_1280x720_1000kbps_25fps.m4v",
393          "bbb_mpeg4_1280x720_1000kbps_25fps.info"},
394         {VideoDecHidlTest::standardComp::vp8, "bbb_vp8_640x360_2mbps_30fps.vp8",
395          "bbb_vp8_640x360_2mbps_30fps.info"},
396         {VideoDecHidlTest::standardComp::vp9,
397          "bbb_vp9_640x360_1600kbps_30fps.vp9",
398          "bbb_vp9_640x360_1600kbps_30fps.info"},
399     };
400
401     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
402         if (kCompToURL[i].comp == comp) {
403             strcat(mURL, kCompToURL[i].mURL);
404             strcat(info, kCompToURL[i].info);
405             return;
406         }
407     }
408 }
409
410 void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
411                             android::Vector<BufferInfo>* buffArray,
412                             uint32_t nFrameWidth, uint32_t nFrameHeight,
413                             int32_t* nStride, uint32_t count) {
414     android::hardware::media::omx::V1_0::Status status;
415     sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
416         android::hardware::graphics::allocator::V2_0::IAllocator::getService();
417     ASSERT_NE(nullptr, allocator.get());
418
419     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
420         android::hardware::graphics::mapper::V2_0::IMapper::getService();
421     ASSERT_NE(mapper.get(), nullptr);
422
423     android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
424         descriptorInfo;
425     uint32_t usage;
426
427     descriptorInfo.width = nFrameWidth;
428     descriptorInfo.height = nFrameHeight;
429     descriptorInfo.layerCount = 1;
430     descriptorInfo.format = PixelFormat::RGBA_8888;
431     descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
432     omxNode->getGraphicBufferUsage(
433         portIndex,
434         [&status, &usage](android::hardware::media::omx::V1_0::Status _s,
435                           uint32_t _n1) {
436             status = _s;
437             usage = _n1;
438         });
439     if (status == android::hardware::media::omx::V1_0::Status::OK) {
440         descriptorInfo.usage |= usage;
441     }
442
443     ::android::hardware::hidl_vec<uint32_t> descriptor;
444     android::hardware::graphics::mapper::V2_0::Error error;
445     mapper->createDescriptor(
446         descriptorInfo, [&error, &descriptor](
447                             android::hardware::graphics::mapper::V2_0::Error _s,
448                             ::android::hardware::hidl_vec<uint32_t> _n1) {
449             error = _s;
450             descriptor = _n1;
451         });
452     EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
453
454     EXPECT_EQ(buffArray->size(), count);
455     allocator->allocate(
456         descriptor, count,
457         [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
458             const ::android::hardware::hidl_vec<
459                 ::android::hardware::hidl_handle>& _n2) {
460             ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
461                       _s);
462             *nStride = _n1;
463             ASSERT_EQ(count, _n2.size());
464             for (uint32_t i = 0; i < count; i++) {
465                 buffArray->editItemAt(i).omxBuffer.nativeHandle = _n2[i];
466                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.width =
467                     nFrameWidth;
468                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.height =
469                     nFrameHeight;
470                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.stride = _n1;
471                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.format =
472                     descriptorInfo.format;
473                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.usage =
474                     descriptorInfo.usage;
475                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.layerCount =
476                     descriptorInfo.layerCount;
477                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.id =
478                     (*buffArray)[i].id;
479             }
480         });
481 }
482
483 // port settings reconfiguration during runtime. reconfigures frame dimensions
484 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
485                          android::Vector<BufferInfo>* iBuffer,
486                          android::Vector<BufferInfo>* oBuffer,
487                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
488                          Message msg, PortMode oPortMode, void* args) {
489     android::hardware::media::omx::V1_0::Status status;
490     (void)args;
491
492     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
493         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
494         if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
495             msg.data.eventData.data2 == 0) {
496             status = omxNode->sendCommand(
497                 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
498             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
499
500             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
501                                               oBuffer);
502             if (status ==
503                 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
504                 for (size_t i = 0; i < oBuffer->size(); ++i) {
505                     // test if client got all its buffers back
506                     EXPECT_EQ((*oBuffer)[i].owner, client);
507                     // free the buffers
508                     status =
509                         omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
510                     ASSERT_EQ(status,
511                               android::hardware::media::omx::V1_0::Status::OK);
512                 }
513                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
514                                                   iBuffer, oBuffer);
515                 ASSERT_EQ(status,
516                           android::hardware::media::omx::V1_0::Status::OK);
517                 ASSERT_EQ(msg.type, Message::Type::EVENT);
518                 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
519                 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
520                 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
521
522                 // set Port Params
523                 uint32_t nFrameWidth, nFrameHeight, xFramerate;
524                 OMX_COLOR_FORMATTYPE eColorFormat =
525                     OMX_COLOR_FormatYUV420Planar;
526                 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
527                                     &nFrameHeight, &xFramerate);
528                 setDefaultPortParam(omxNode, kPortIndexOutput,
529                                     OMX_VIDEO_CodingUnused, eColorFormat,
530                                     nFrameWidth, nFrameHeight, 0, xFramerate);
531
532                 // If you can disable a port, then you should be able to
533                 // enable
534                 // it as well
535                 status = omxNode->sendCommand(
536                     toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
537                 ASSERT_EQ(status,
538                           android::hardware::media::omx::V1_0::Status::OK);
539
540                 // do not enable the port until all the buffers are supplied
541                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
542                                                   iBuffer, oBuffer);
543                 ASSERT_EQ(
544                     status,
545                     android::hardware::media::omx::V1_0::Status::TIMED_OUT);
546
547                 allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput,
548                                     oPortMode);
549                 if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
550                     OMX_PARAM_PORTDEFINITIONTYPE portDef;
551
552                     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
553                                           kPortIndexOutput, &portDef);
554                     ASSERT_EQ(
555                         status,
556                         ::android::hardware::media::omx::V1_0::Status::OK);
557                     allocateGraphicBuffers(omxNode, kPortIndexOutput, oBuffer,
558                                            portDef.format.video.nFrameWidth,
559                                            portDef.format.video.nFrameHeight,
560                                            &portDef.format.video.nStride,
561                                            portDef.nBufferCountActual);
562                 }
563                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
564                                                   iBuffer, oBuffer);
565                 ASSERT_EQ(status,
566                           android::hardware::media::omx::V1_0::Status::OK);
567                 ASSERT_EQ(msg.type, Message::Type::EVENT);
568                 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
569                 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
570
571                 // dispatch output buffers
572                 for (size_t i = 0; i < oBuffer->size(); i++) {
573                     dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
574                 }
575             } else {
576                 ASSERT_TRUE(false);
577             }
578         } else if (msg.data.eventData.data2 ==
579                    OMX_IndexConfigCommonOutputCrop) {
580             std::cout << "[          ] Warning ! OMX_EventPortSettingsChanged/ "
581                          "OMX_IndexConfigCommonOutputCrop not handled \n";
582         } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
583             std::cout << "[          ] Warning ! OMX_EventPortSettingsChanged/ "
584                          "kDescribeColorAspectsIndex not handled \n";
585         }
586     } else if (msg.data.eventData.event == OMX_EventError) {
587         std::cout << "[          ] Warning ! OMX_EventError/ "
588                      "Decode Frame Call might be failed \n";
589         return;
590     } else if (msg.data.eventData.event == OMX_EventBufferFlag) {
591         // soft omx components donot send this, we will just ignore it
592         // for now
593     } else {
594         // something unexpected happened
595         ASSERT_TRUE(false);
596     }
597 }
598
599 // blocking call to ensures application to Wait till all the inputs are consumed
600 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
601                             android::Vector<BufferInfo>* iBuffer,
602                             android::Vector<BufferInfo>* oBuffer,
603                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
604                             PortMode oPortMode) {
605     android::hardware::media::omx::V1_0::Status status;
606     Message msg;
607     int timeOut = TIMEOUT_COUNTER_Q;
608
609     while (timeOut--) {
610         size_t i = 0;
611         status =
612             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
613         if (status == android::hardware::media::omx::V1_0::Status::OK) {
614             EXPECT_EQ(msg.type, Message::Type::EVENT);
615             portReconfiguration(omxNode, observer, iBuffer, oBuffer,
616                                 kPortIndexInput, kPortIndexOutput, msg,
617                                 oPortMode, nullptr);
618         }
619         // status == TIMED_OUT, it could be due to process time being large
620         // than DEFAULT_TIMEOUT or component needs output buffers to start
621         // processing.
622         for (; i < iBuffer->size(); i++) {
623             if ((*iBuffer)[i].owner != client) break;
624         }
625         if (i == iBuffer->size()) break;
626
627         // Dispatch an output buffer assuming outQueue.empty() is true
628         size_t index;
629         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
630             dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
631             timeOut = TIMEOUT_COUNTER_Q;
632         }
633     }
634 }
635
636 // Decode N Frames
637 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
638                    android::Vector<BufferInfo>* iBuffer,
639                    android::Vector<BufferInfo>* oBuffer,
640                    OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
641                    std::ifstream& eleStream, android::Vector<FrameData>* Info,
642                    int offset, int range, PortMode oPortMode,
643                    bool signalEOS = true) {
644     android::hardware::media::omx::V1_0::Status status;
645     Message msg;
646
647     // dispatch output buffers
648     for (size_t i = 0; i < oBuffer->size(); i++) {
649         dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
650     }
651     // dispatch input buffers
652     uint32_t flags = 0;
653     int frameID = offset;
654     for (size_t i = 0; (i < iBuffer->size()) && (frameID < (int)Info->size()) &&
655                        (frameID < (offset + range));
656          i++) {
657         char* ipBuffer = static_cast<char*>(
658             static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
659         ASSERT_LE((*Info)[frameID].bytesCount,
660                   static_cast<int>((*iBuffer)[i].mMemory->getSize()));
661         eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
662         ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
663         flags = (*Info)[frameID].flags;
664         if (signalEOS && ((frameID == (int)Info->size() - 1) ||
665                           (frameID == (offset + range - 1))))
666             flags |= OMX_BUFFERFLAG_EOS;
667         dispatchInputBuffer(omxNode, iBuffer, i, (*Info)[frameID].bytesCount,
668                             flags, (*Info)[frameID].timestamp);
669         frameID++;
670     }
671
672     int timeOut = TIMEOUT_COUNTER_Q;
673     bool iQueued, oQueued;
674     while (1) {
675         iQueued = oQueued = false;
676         status =
677             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
678
679         // Port Reconfiguration
680         if (status == android::hardware::media::omx::V1_0::Status::OK &&
681             msg.type == Message::Type::EVENT) {
682             portReconfiguration(omxNode, observer, iBuffer, oBuffer,
683                                 kPortIndexInput, kPortIndexOutput, msg,
684                                 oPortMode, nullptr);
685         }
686
687         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
688
689         // Dispatch input buffer
690         size_t index = 0;
691         if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
692             char* ipBuffer = static_cast<char*>(
693                 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
694             ASSERT_LE((*Info)[frameID].bytesCount,
695                       static_cast<int>((*iBuffer)[index].mMemory->getSize()));
696             eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
697             ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
698             flags = (*Info)[frameID].flags;
699             if (signalEOS && ((frameID == (int)Info->size() - 1) ||
700                               (frameID == (offset + range - 1))))
701                 flags |= OMX_BUFFERFLAG_EOS;
702             dispatchInputBuffer(omxNode, iBuffer, index,
703                                 (*Info)[frameID].bytesCount, flags,
704                                 (*Info)[frameID].timestamp);
705             frameID++;
706             iQueued = true;
707         }
708         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
709             dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
710             oQueued = true;
711         }
712         if (iQueued || oQueued)
713             timeOut = TIMEOUT_COUNTER_Q;
714         else
715             timeOut--;
716         if (timeOut == 0) {
717             EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
718             break;
719         }
720     }
721 }
722
723 // set component role
724 TEST_F(VideoDecHidlTest, SetRole) {
725     description("Test Set Component Role");
726     if (disableTest) return;
727     android::hardware::media::omx::V1_0::Status status;
728     status = setRole(omxNode, gEnv->getRole().c_str());
729     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
730 }
731
732 // port format enumeration
733 TEST_F(VideoDecHidlTest, EnumeratePortFormat) {
734     description("Test Component on Mandatory Port Parameters (Port Format)");
735     if (disableTest) return;
736     android::hardware::media::omx::V1_0::Status status;
737     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
738     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
739     OMX_U32 xFramerate = (24U << 16);
740     status = setRole(omxNode, gEnv->getRole().c_str());
741     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
742     OMX_PORT_PARAM_TYPE params;
743     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
744     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
745         ASSERT_EQ(params.nPorts, 2U);
746         kPortIndexInput = params.nStartPortNumber;
747         kPortIndexOutput = kPortIndexInput + 1;
748     }
749     status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
750                                 OMX_COLOR_FormatUnused, 0U);
751     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
752     status =
753         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
754                            eColorFormat, xFramerate);
755     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
756 }
757
758 // test port settings reconfiguration, elementary stream decode and timestamp
759 // deviation
760 TEST_F(VideoDecHidlTest, DecodeTest) {
761     description("Tests Port Reconfiguration, Decode and timestamp deviation");
762     if (disableTest) return;
763     android::hardware::media::omx::V1_0::Status status;
764     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
765     status = setRole(omxNode, gEnv->getRole().c_str());
766     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
767     OMX_PORT_PARAM_TYPE params;
768     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
769     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
770         ASSERT_EQ(params.nPorts, 2U);
771         kPortIndexInput = params.nStartPortNumber;
772         kPortIndexOutput = kPortIndexInput + 1;
773     }
774     char mURL[512], info[512];
775     strcpy(mURL, gEnv->getRes().c_str());
776     strcpy(info, gEnv->getRes().c_str());
777     GetURLForComponent(compName, mURL, info);
778
779     std::ifstream eleStream, eleInfo;
780
781     eleInfo.open(info);
782     ASSERT_EQ(eleInfo.is_open(), true);
783     android::Vector<FrameData> Info;
784     int bytesCount = 0;
785     uint32_t flags = 0;
786     uint32_t timestamp = 0;
787     timestampDevTest = true;
788     while (1) {
789         if (!(eleInfo >> bytesCount)) break;
790         eleInfo >> flags;
791         eleInfo >> timestamp;
792         Info.push_back({bytesCount, flags, timestamp});
793         if (flags != OMX_BUFFERFLAG_CODECCONFIG)
794             timestampUslist.push_back(timestamp);
795     }
796     eleInfo.close();
797
798     // set port mode
799     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
800     portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
801     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
802     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
803     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
804     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
805         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
806         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
807         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
808     }
809
810     // set Port Params
811     uint32_t nFrameWidth, nFrameHeight, xFramerate;
812     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
813     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
814                         &xFramerate);
815     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
816                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
817     omxNode->prepareForAdaptivePlayback(kPortIndexOutput, false, 1920, 1080);
818
819     android::Vector<BufferInfo> iBuffer, oBuffer;
820
821     // set state to idle
822     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
823                             kPortIndexInput, kPortIndexOutput, portMode);
824     // set state to executing
825     changeStateIdletoExecute(omxNode, observer);
826
827     if (portMode[1] != PortMode::PRESET_BYTE_BUFFER) {
828         OMX_PARAM_PORTDEFINITIONTYPE portDef;
829
830         status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
831                               kPortIndexOutput, &portDef);
832         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
833         allocateGraphicBuffers(
834             omxNode, kPortIndexOutput, &oBuffer,
835             portDef.format.video.nFrameWidth, portDef.format.video.nFrameHeight,
836             &portDef.format.video.nStride, portDef.nBufferCountActual);
837     }
838
839     // Port Reconfiguration
840     eleStream.open(mURL, std::ifstream::binary);
841     ASSERT_EQ(eleStream.is_open(), true);
842     decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
843                   kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(),
844                   portMode[1]);
845     eleStream.close();
846     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
847                            kPortIndexInput, kPortIndexOutput, portMode[1]);
848     testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
849             portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
850     EXPECT_EQ(timestampUslist.empty(), true);
851     // set state to idle
852     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
853     // set state to executing
854     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
855                             kPortIndexInput, kPortIndexOutput);
856 }
857
858 // end of sequence test
859 TEST_F(VideoDecHidlTest, EOSTest_M) {
860     description("Test End of stream monkeying");
861     if (disableTest) return;
862     android::hardware::media::omx::V1_0::Status status;
863     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
864     status = setRole(omxNode, gEnv->getRole().c_str());
865     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
866     OMX_PORT_PARAM_TYPE params;
867     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
868     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
869         ASSERT_EQ(params.nPorts, 2U);
870         kPortIndexInput = params.nStartPortNumber;
871         kPortIndexOutput = kPortIndexInput + 1;
872     }
873
874     // set Port Params
875     uint32_t nFrameWidth, nFrameHeight, xFramerate;
876     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
877     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
878                         &xFramerate);
879     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
880                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
881
882     // set port mode
883     PortMode portMode[2];
884     portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
885     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
886     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
887     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
888     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
889
890     android::Vector<BufferInfo> iBuffer, oBuffer;
891
892     // set state to idle
893     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
894                             kPortIndexInput, kPortIndexOutput, portMode);
895     // set state to executing
896     changeStateIdletoExecute(omxNode, observer);
897
898     // request EOS at the start
899     testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
900             portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
901     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
902                kPortIndexOutput);
903     EXPECT_GE(framesReceived, 0U);
904     framesReceived = 0;
905     timestampUs = 0;
906
907     // set state to idle
908     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
909     // set state to executing
910     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
911                             kPortIndexInput, kPortIndexOutput);
912 }
913
914 // end of sequence test
915 TEST_F(VideoDecHidlTest, ThumbnailTest) {
916     description("Test Request for thumbnail");
917     if (disableTest) return;
918     android::hardware::media::omx::V1_0::Status status;
919     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
920     status = setRole(omxNode, gEnv->getRole().c_str());
921     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
922     OMX_PORT_PARAM_TYPE params;
923     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
924     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
925         ASSERT_EQ(params.nPorts, 2U);
926         kPortIndexInput = params.nStartPortNumber;
927         kPortIndexOutput = kPortIndexInput + 1;
928     }
929     char mURL[512], info[512];
930     strcpy(mURL, gEnv->getRes().c_str());
931     strcpy(info, gEnv->getRes().c_str());
932     GetURLForComponent(compName, mURL, info);
933
934     std::ifstream eleStream, eleInfo;
935
936     eleInfo.open(info);
937     ASSERT_EQ(eleInfo.is_open(), true);
938     android::Vector<FrameData> Info;
939     int bytesCount = 0;
940     uint32_t flags = 0;
941     uint32_t timestamp = 0;
942     while (1) {
943         if (!(eleInfo >> bytesCount)) break;
944         eleInfo >> flags;
945         eleInfo >> timestamp;
946         Info.push_back({bytesCount, flags, timestamp});
947     }
948     eleInfo.close();
949
950     // set Port Params
951     uint32_t nFrameWidth, nFrameHeight, xFramerate;
952     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
953     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
954                         &xFramerate);
955     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
956                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
957
958     // set port mode
959     PortMode portMode[2];
960     portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
961     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
962     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
963     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
964     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
965
966     android::Vector<BufferInfo> iBuffer, oBuffer;
967
968     // set state to idle
969     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
970                             kPortIndexInput, kPortIndexOutput, portMode);
971     // set state to executing
972     changeStateIdletoExecute(omxNode, observer);
973
974     // request EOS for thumbnail
975     size_t i = 0;
976     while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
977     eleStream.open(mURL, std::ifstream::binary);
978     ASSERT_EQ(eleStream.is_open(), true);
979     decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
980                   kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1]);
981     eleStream.close();
982     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
983                            kPortIndexInput, kPortIndexOutput, portMode[1]);
984     testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
985             portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
986     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
987                kPortIndexOutput);
988     EXPECT_GE(framesReceived, 1U);
989     framesReceived = 0;
990     timestampUs = 0;
991
992     eleStream.open(mURL, std::ifstream::binary);
993     ASSERT_EQ(eleStream.is_open(), true);
994     decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
995                   kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1],
996                   false);
997     eleStream.close();
998     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
999                            kPortIndexInput, kPortIndexOutput, portMode[1]);
1000     testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1001             portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1002     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1003                kPortIndexOutput);
1004     EXPECT_GE(framesReceived, 1U);
1005     framesReceived = 0;
1006     timestampUs = 0;
1007
1008     // set state to idle
1009     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1010     // set state to executing
1011     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1012                             kPortIndexInput, kPortIndexOutput);
1013 }
1014
1015 // end of sequence test
1016 TEST_F(VideoDecHidlTest, SimpleEOSTest) {
1017     description("Test End of stream");
1018     if (disableTest) return;
1019     android::hardware::media::omx::V1_0::Status status;
1020     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1021     status = setRole(omxNode, gEnv->getRole().c_str());
1022     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1023     OMX_PORT_PARAM_TYPE params;
1024     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1025     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1026         ASSERT_EQ(params.nPorts, 2U);
1027         kPortIndexInput = params.nStartPortNumber;
1028         kPortIndexOutput = kPortIndexInput + 1;
1029     }
1030     char mURL[512], info[512];
1031     strcpy(mURL, gEnv->getRes().c_str());
1032     strcpy(info, gEnv->getRes().c_str());
1033     GetURLForComponent(compName, mURL, info);
1034
1035     std::ifstream eleStream, eleInfo;
1036
1037     eleInfo.open(info);
1038     ASSERT_EQ(eleInfo.is_open(), true);
1039     android::Vector<FrameData> Info;
1040     int bytesCount = 0;
1041     uint32_t flags = 0;
1042     uint32_t timestamp = 0;
1043     while (1) {
1044         if (!(eleInfo >> bytesCount)) break;
1045         eleInfo >> flags;
1046         eleInfo >> timestamp;
1047         Info.push_back({bytesCount, flags, timestamp});
1048     }
1049     eleInfo.close();
1050
1051     // set Port Params
1052     uint32_t nFrameWidth, nFrameHeight, xFramerate;
1053     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
1054     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1055                         &xFramerate);
1056     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1057                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1058
1059     // set port mode
1060     PortMode portMode[2];
1061     portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1062     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1063     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1064     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1065     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1066
1067     android::Vector<BufferInfo> iBuffer, oBuffer;
1068
1069     // set state to idle
1070     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1071                             kPortIndexInput, kPortIndexOutput, portMode);
1072     // set state to executing
1073     changeStateIdletoExecute(omxNode, observer);
1074
1075     // request EOS at the end
1076     eleStream.open(mURL, std::ifstream::binary);
1077     ASSERT_EQ(eleStream.is_open(), true);
1078     decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1079                   kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(),
1080                   portMode[1], false);
1081     eleStream.close();
1082     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1083                            kPortIndexInput, kPortIndexOutput, portMode[1]);
1084     testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1085             portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1086     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1087                kPortIndexOutput);
1088     framesReceived = 0;
1089     timestampUs = 0;
1090
1091     // set state to idle
1092     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1093     // set state to executing
1094     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1095                             kPortIndexInput, kPortIndexOutput);
1096 }
1097
1098 // test input/output port flush
1099 TEST_F(VideoDecHidlTest, FlushTest) {
1100     description("Test Flush");
1101     if (disableTest) return;
1102     android::hardware::media::omx::V1_0::Status status;
1103     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1104     status = setRole(omxNode, gEnv->getRole().c_str());
1105     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1106     OMX_PORT_PARAM_TYPE params;
1107     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1108     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1109         ASSERT_EQ(params.nPorts, 2U);
1110         kPortIndexInput = params.nStartPortNumber;
1111         kPortIndexOutput = kPortIndexInput + 1;
1112     }
1113     char mURL[512], info[512];
1114     strcpy(mURL, gEnv->getRes().c_str());
1115     strcpy(info, gEnv->getRes().c_str());
1116     GetURLForComponent(compName, mURL, info);
1117
1118     std::ifstream eleStream, eleInfo;
1119
1120     eleInfo.open(info);
1121     ASSERT_EQ(eleInfo.is_open(), true);
1122     android::Vector<FrameData> Info;
1123     int bytesCount = 0;
1124     uint32_t flags = 0;
1125     uint32_t timestamp = 0;
1126     while (1) {
1127         if (!(eleInfo >> bytesCount)) break;
1128         eleInfo >> flags;
1129         eleInfo >> timestamp;
1130         Info.push_back({bytesCount, flags, timestamp});
1131     }
1132     eleInfo.close();
1133
1134     // set Port Params
1135     uint32_t nFrameWidth, nFrameHeight, xFramerate;
1136     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
1137     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1138                         &xFramerate);
1139     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1140                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1141
1142     // set port mode
1143     PortMode portMode[2];
1144     portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1145     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1146     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1147     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1148     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1149
1150     android::Vector<BufferInfo> iBuffer, oBuffer;
1151
1152     // set state to idle
1153     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1154                             kPortIndexInput, kPortIndexOutput, portMode);
1155     // set state to executing
1156     changeStateIdletoExecute(omxNode, observer);
1157
1158     // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
1159     // frame after this so that the below section can be convered for all
1160     // components
1161     int nFrames = 128;
1162     eleStream.open(mURL, std::ifstream::binary);
1163     ASSERT_EQ(eleStream.is_open(), true);
1164     decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1165                   kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1],
1166                   false);
1167     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1168                kPortIndexOutput);
1169     framesReceived = 0;
1170
1171     // Seek to next key frame and start decoding till the end
1172     int index = nFrames;
1173     bool keyFrame = false;
1174     while (index < (int)Info.size()) {
1175         if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
1176             OMX_BUFFERFLAG_SYNCFRAME) {
1177             timestampUs = Info[index - 1].timestamp;
1178             keyFrame = true;
1179             break;
1180         }
1181         eleStream.ignore(Info[index].bytesCount);
1182         index++;
1183     }
1184     if (keyFrame) {
1185         decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1186                       kPortIndexOutput, eleStream, &Info, index,
1187                       Info.size() - index, portMode[1], false);
1188     }
1189     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1190                kPortIndexOutput);
1191     framesReceived = 0;
1192
1193     // set state to idle
1194     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1195     // set state to executing
1196     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1197                             kPortIndexInput, kPortIndexOutput);
1198 }
1199
1200 int main(int argc, char** argv) {
1201     gEnv = new ComponentTestEnvironment();
1202     ::testing::AddGlobalTestEnvironment(gEnv);
1203     ::testing::InitGoogleTest(&argc, argv);
1204     int status = gEnv->initFromOptions(argc, argv);
1205     if (status == 0) {
1206         status = RUN_ALL_TESTS();
1207         ALOGI("Test result = %d", status);
1208     }
1209     return status;
1210 }