OSDN Git Service

bug fix: during fatal fails bypass freeNode() calls
[android-x86/hardware-interfaces.git] / media / omx / 1.0 / vts / functional / video / VtsHalMediaOmxV1_0TargetVideoEncTest.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_enc_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/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
25 #include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
26 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
27 #include <android/hardware/graphics/mapper/2.0/types.h>
28 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
29 #include <android/hardware/media/omx/1.0/IOmx.h>
30 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
31 #include <android/hardware/media/omx/1.0/IOmxNode.h>
32 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
33 #include <android/hardware/media/omx/1.0/types.h>
34 #include <android/hidl/allocator/1.0/IAllocator.h>
35 #include <android/hidl/memory/1.0/IMapper.h>
36 #include <android/hidl/memory/1.0/IMemory.h>
37
38 using ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer;
39 using ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener;
40 using ::android::hardware::graphics::common::V1_0::BufferUsage;
41 using ::android::hardware::graphics::common::V1_0::PixelFormat;
42 using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
43 using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
44 using ::android::hardware::media::omx::V1_0::IOmx;
45 using ::android::hardware::media::omx::V1_0::IOmxObserver;
46 using ::android::hardware::media::omx::V1_0::IOmxNode;
47 using ::android::hardware::media::omx::V1_0::Message;
48 using ::android::hardware::media::omx::V1_0::CodecBuffer;
49 using ::android::hardware::media::omx::V1_0::PortMode;
50 using ::android::hidl::allocator::V1_0::IAllocator;
51 using ::android::hidl::memory::V1_0::IMemory;
52 using ::android::hidl::memory::V1_0::IMapper;
53 using ::android::hardware::Return;
54 using ::android::hardware::Void;
55 using ::android::hardware::hidl_vec;
56 using ::android::hardware::hidl_string;
57 using ::android::sp;
58
59 #include <VtsHalHidlTargetTestBase.h>
60 #include <getopt.h>
61 #include <media/hardware/HardwareAPI.h>
62 #include <media_hidl_test_common.h>
63 #include <media_video_hidl_test_common.h>
64 #include <system/window.h>
65 #include <fstream>
66
67 // A class for test environment setup
68 class ComponentTestEnvironment : public ::testing::Environment {
69    public:
70     virtual void SetUp() {}
71     virtual void TearDown() {}
72
73     ComponentTestEnvironment() : instance("default"), res("/sdcard/media/") {}
74
75     void setInstance(const char* _instance) { instance = _instance; }
76
77     void setComponent(const char* _component) { component = _component; }
78
79     void setRole(const char* _role) { role = _role; }
80
81     void setRes(const char* _res) { res = _res; }
82
83     const hidl_string getInstance() const { return instance; }
84
85     const hidl_string getComponent() const { return component; }
86
87     const hidl_string getRole() const { return role; }
88
89     const hidl_string getRes() const { return res; }
90
91     int initFromOptions(int argc, char** argv) {
92         static struct option options[] = {
93             {"instance", required_argument, 0, 'I'},
94             {"component", required_argument, 0, 'C'},
95             {"role", required_argument, 0, 'R'},
96             {"res", required_argument, 0, 'P'},
97             {0, 0, 0, 0}};
98
99         while (true) {
100             int index = 0;
101             int c = getopt_long(argc, argv, "I:C:R:P:", options, &index);
102             if (c == -1) {
103                 break;
104             }
105
106             switch (c) {
107                 case 'I':
108                     setInstance(optarg);
109                     break;
110                 case 'C':
111                     setComponent(optarg);
112                     break;
113                 case 'R':
114                     setRole(optarg);
115                     break;
116                 case 'P':
117                     setRes(optarg);
118                     break;
119                 case '?':
120                     break;
121             }
122         }
123
124         if (optind < argc) {
125             fprintf(stderr,
126                     "unrecognized option: %s\n\n"
127                     "usage: %s <gtest options> <test options>\n\n"
128                     "test options are:\n\n"
129                     "-I, --instance: HAL instance to test\n"
130                     "-C, --component: OMX component to test\n"
131                     "-R, --role: OMX component Role\n"
132                     "-P, --res: Resource files directory location\n",
133                     argv[optind ?: 1], argv[0]);
134             return 2;
135         }
136         return 0;
137     }
138
139    private:
140     hidl_string instance;
141     hidl_string component;
142     hidl_string role;
143     hidl_string res;
144 };
145
146 static ComponentTestEnvironment* gEnv = nullptr;
147
148 // video encoder test fixture class
149 class VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
150    private:
151     typedef ::testing::VtsHalHidlTargetTestBase Super;
152    public:
153     ::std::string getTestCaseInfo() const override {
154         return ::std::string() +
155                 "Component: " + gEnv->getComponent().c_str() + " | " +
156                 "Role: " + gEnv->getRole().c_str() + " | " +
157                 "Instance: " + gEnv->getInstance().c_str() + " | " +
158                 "Res: " + gEnv->getRes().c_str();
159     }
160
161     virtual void SetUp() override {
162         Super::SetUp();
163         disableTest = false;
164         android::hardware::media::omx::V1_0::Status status;
165         omx = Super::getService<IOmx>(gEnv->getInstance());
166         ASSERT_NE(omx, nullptr);
167         observer =
168             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
169                 handleMessage(msg, buffer);
170             });
171         ASSERT_NE(observer, nullptr);
172         if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
173             disableTest = true;
174         EXPECT_TRUE(omx->allocateNode(
175                            gEnv->getComponent(), observer,
176                            [&](android::hardware::media::omx::V1_0::Status _s,
177                                sp<IOmxNode> const& _nl) {
178                                status = _s;
179                                this->omxNode = _nl;
180                            })
181                         .isOk());
182         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
183         ASSERT_NE(omxNode, nullptr);
184         ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
185         struct StringToName {
186             const char* Name;
187             standardComp CompName;
188         };
189         const StringToName kStringToName[] = {
190             {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4},
191             {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
192         };
193         const size_t kNumStringToName =
194             sizeof(kStringToName) / sizeof(kStringToName[0]);
195         const char* pch;
196         char substring[OMX_MAX_STRINGNAME_SIZE];
197         strcpy(substring, gEnv->getRole().c_str());
198         pch = strchr(substring, '.');
199         ASSERT_NE(pch, nullptr);
200         compName = unknown_comp;
201         for (size_t i = 0; i < kNumStringToName; ++i) {
202             if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
203                 compName = kStringToName[i].CompName;
204                 break;
205             }
206         }
207         if (compName == unknown_comp) disableTest = true;
208         struct CompToCompression {
209             standardComp CompName;
210             OMX_VIDEO_CODINGTYPE eCompressionFormat;
211         };
212         static const CompToCompression kCompToCompression[] = {
213             {h263, OMX_VIDEO_CodingH263},   {avc, OMX_VIDEO_CodingAVC},
214             {mpeg4, OMX_VIDEO_CodingMPEG4}, {hevc, OMX_VIDEO_CodingHEVC},
215             {vp8, OMX_VIDEO_CodingVP8},     {vp9, OMX_VIDEO_CodingVP9},
216         };
217         static const size_t kNumCompToCompression =
218             sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
219         size_t i;
220         for (i = 0; i < kNumCompToCompression; ++i) {
221             if (kCompToCompression[i].CompName == compName) {
222                 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
223                 break;
224             }
225         }
226         if (i == kNumCompToCompression) disableTest = true;
227         eosFlag = false;
228         prependSPSPPS = false;
229         timestampDevTest = false;
230         producer = nullptr;
231         source = nullptr;
232         isSecure = false;
233         size_t suffixLen = strlen(".secure");
234         if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
235             isSecure =
236                 !strcmp(gEnv->getComponent().c_str() +
237                             strlen(gEnv->getComponent().c_str()) - suffixLen,
238                         ".secure");
239         }
240         if (isSecure) disableTest = true;
241         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
242     }
243
244     virtual void TearDown() override {
245         if (omxNode != nullptr) {
246             // If you have encountered a fatal failure, it is possible that
247             // freeNode() will not go through. Instead of hanging the app.
248             // let it pass through and report errors
249             if (::testing::Test::HasFatalFailure()) return;
250             EXPECT_TRUE((omxNode->freeNode()).isOk());
251             omxNode = nullptr;
252         }
253         Super::TearDown();
254     }
255
256     // callback function to process messages received by onMessages() from IL
257     // client.
258     void handleMessage(Message msg, const BufferInfo* buffer) {
259         (void)buffer;
260
261         if (msg.type == Message::Type::FILL_BUFFER_DONE) {
262             if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
263                 eosFlag = true;
264             }
265             if (msg.data.extendedBufferData.rangeLength != 0) {
266                 // Test if current timestamp is among the list of queued
267                 // timestamps
268                 if (timestampDevTest && ((msg.data.extendedBufferData.flags &
269                                           OMX_BUFFERFLAG_CODECCONFIG) == 0)) {
270                     bool tsHit = false;
271                     android::List<uint64_t>::iterator it =
272                         timestampUslist.begin();
273                     while (it != timestampUslist.end()) {
274                         if (*it == msg.data.extendedBufferData.timestampUs) {
275                             timestampUslist.erase(it);
276                             tsHit = true;
277                             break;
278                         }
279                         it++;
280                     }
281                     if (tsHit == false) {
282                         if (timestampUslist.empty() == false) {
283                             EXPECT_EQ(tsHit, true)
284                                 << "TimeStamp not recognized";
285                         } else {
286                             std::cout << "[   INFO   ] Received non-zero "
287                                          "output / TimeStamp not recognized \n";
288                         }
289                     }
290                 }
291 #define WRITE_OUTPUT 0
292 #if WRITE_OUTPUT
293                 static int count = 0;
294                 FILE* ofp = nullptr;
295                 if (count)
296                     ofp = fopen("out.bin", "ab");
297                 else
298                     ofp = fopen("out.bin", "wb");
299                 if (ofp != nullptr) {
300                     fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
301                            sizeof(char),
302                            msg.data.extendedBufferData.rangeLength, ofp);
303                     fclose(ofp);
304                     count++;
305                 }
306 #endif
307             }
308         }
309     }
310
311     enum standardComp {
312         h263,
313         avc,
314         mpeg4,
315         hevc,
316         vp8,
317         vp9,
318         unknown_comp,
319     };
320
321     sp<IOmx> omx;
322     sp<CodecObserver> observer;
323     sp<IOmxNode> omxNode;
324     standardComp compName;
325     OMX_VIDEO_CODINGTYPE eCompressionFormat;
326     bool disableTest;
327     bool eosFlag;
328     bool prependSPSPPS;
329     ::android::List<uint64_t> timestampUslist;
330     bool timestampDevTest;
331     bool isSecure;
332     sp<IGraphicBufferProducer> producer;
333     sp<IGraphicBufferSource> source;
334
335    protected:
336     static void description(const std::string& description) {
337         RecordProperty("description", description);
338     }
339 };
340
341 // CodecProducerListener class
342 struct CodecProducerListener : public IProducerListener {
343    public:
344     CodecProducerListener(int a, int b)
345         : freeBuffers(a), minUnDequeuedCount(b) {}
346     virtual ::android::hardware::Return<void> onBufferReleased() override {
347         android::Mutex::Autolock autoLock(bufferLock);
348         freeBuffers += 1;
349         return Void();
350     }
351     virtual ::android::hardware::Return<bool> needsReleaseNotify() override {
352         return true;
353     }
354     void reduceCount() {
355         android::Mutex::Autolock autoLock(bufferLock);
356         freeBuffers -= 1;
357         EXPECT_GE(freeBuffers, minUnDequeuedCount);
358     }
359
360     size_t freeBuffers;
361     size_t minUnDequeuedCount;
362     android::Mutex bufferLock;
363 };
364
365 // Mock IOmxBufferSource class. GraphicBufferSource.cpp in libstagefright/omx/
366 // implements this class. Below is dummy class introduced to test if callback
367 // functions are actually being called or not
368 struct DummyBufferSource : public IOmxBufferSource {
369    public:
370     DummyBufferSource(sp<IOmxNode> node) {
371         callback = 0;
372         executing = false;
373         omxNode = node;
374     }
375     virtual Return<void> onOmxExecuting();
376     virtual Return<void> onOmxIdle();
377     virtual Return<void> onOmxLoaded();
378     virtual Return<void> onInputBufferAdded(uint32_t buffer);
379     virtual Return<void> onInputBufferEmptied(
380         uint32_t buffer, const ::android::hardware::hidl_handle& fence);
381
382     int callback;
383     bool executing;
384     sp<IOmxNode> omxNode;
385     android::Vector<BufferInfo> iBuffer, oBuffer;
386 };
387
388 Return<void> DummyBufferSource::onOmxExecuting() {
389     executing = true;
390     callback |= 0x1;
391     size_t index;
392     // Fetch a client owned input buffer and send an EOS
393     if ((index = getEmptyBufferID(&iBuffer)) < iBuffer.size()) {
394         android::hardware::media::omx::V1_0::Status status;
395         CodecBuffer t = iBuffer[index].omxBuffer;
396         t.type = CodecBuffer::Type::ANW_BUFFER;
397         native_handle_t* fenceNh = native_handle_create(0, 0);
398         EXPECT_NE(fenceNh, nullptr);
399         status = omxNode->emptyBuffer(iBuffer[index].id, t, OMX_BUFFERFLAG_EOS,
400                                       0, fenceNh);
401         native_handle_close(fenceNh);
402         native_handle_delete(fenceNh);
403         EXPECT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
404         iBuffer.editItemAt(index).owner = component;
405     }
406     return Void();
407 };
408
409 Return<void> DummyBufferSource::onOmxIdle() {
410     callback |= 0x2;
411     executing = false;
412     return Void();
413 };
414
415 Return<void> DummyBufferSource::onOmxLoaded() {
416     callback |= 0x4;
417     return Void();
418 };
419
420 Return<void> DummyBufferSource::onInputBufferAdded(uint32_t buffer) {
421     (void)buffer;
422     EXPECT_EQ(executing, false);
423     callback |= 0x8;
424     return Void();
425 };
426
427 Return<void> DummyBufferSource::onInputBufferEmptied(
428     uint32_t buffer, const ::android::hardware::hidl_handle& fence) {
429     (void)fence;
430     callback |= 0x10;
431     size_t i;
432     for (i = 0; i < iBuffer.size(); i++) {
433         if (iBuffer[i].id == buffer) {
434             iBuffer.editItemAt(i).owner = client;
435             break;
436         }
437     }
438     return Void();
439 };
440
441 // request VOP refresh
442 void requestIDR(sp<IOmxNode> omxNode, OMX_U32 portIndex) {
443     android::hardware::media::omx::V1_0::Status status;
444     OMX_CONFIG_INTRAREFRESHVOPTYPE param;
445     param.IntraRefreshVOP = OMX_TRUE;
446     status = setPortConfig(omxNode, OMX_IndexConfigVideoIntraVOPRefresh,
447                            portIndex, &param);
448     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
449         std::cout << "[   INFO   ] unable to request IDR \n";
450 }
451
452 // modify bitrate
453 void changeBitrate(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t nBitrate) {
454     android::hardware::media::omx::V1_0::Status status;
455     OMX_VIDEO_CONFIG_BITRATETYPE param;
456     param.nEncodeBitrate = nBitrate;
457     status =
458         setPortConfig(omxNode, OMX_IndexConfigVideoBitrate, portIndex, &param);
459     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
460         std::cout << "[   INFO   ] unable to change Bitrate \n";
461 }
462
463 // modify framerate
464 Return<android::hardware::media::omx::V1_0::Status> changeFrameRate(
465     sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t xFramerate) {
466     android::hardware::media::omx::V1_0::Status status;
467     OMX_CONFIG_FRAMERATETYPE param;
468     param.xEncodeFramerate = xFramerate;
469     status = setPortConfig(omxNode, OMX_IndexConfigVideoFramerate, portIndex,
470                            &param);
471     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
472         std::cout << "[   INFO   ] unable to change Framerate \n";
473     return status;
474 }
475
476 // modify intra refresh interval
477 void changeRefreshPeriod(sp<IOmxNode> omxNode, OMX_U32 portIndex,
478                          uint32_t nRefreshPeriod) {
479     android::hardware::media::omx::V1_0::Status status;
480     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE param;
481     param.nRefreshPeriod = nRefreshPeriod;
482     status = setPortConfig(omxNode,
483                            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
484                            portIndex, &param);
485     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
486         std::cout << "[   INFO   ] unable to change Refresh Period\n";
487 }
488
489 // set intra refresh interval
490 void setRefreshPeriod(sp<IOmxNode> omxNode, OMX_U32 portIndex,
491                       uint32_t nRefreshPeriod) {
492     android::hardware::media::omx::V1_0::Status status;
493     OMX_VIDEO_PARAM_INTRAREFRESHTYPE param;
494     param.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
495     param.nCirMBs = 0;
496     if (nRefreshPeriod == 0)
497         param.nCirMBs = 0;
498     else {
499         OMX_PARAM_PORTDEFINITIONTYPE portDef;
500         status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
501                               &portDef);
502         if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
503             param.nCirMBs =
504                 ((portDef.format.video.nFrameWidth + 15) >>
505                  4 * (portDef.format.video.nFrameHeight + 15) >> 4) /
506                 nRefreshPeriod;
507         }
508     }
509     status = setPortParam(omxNode, OMX_IndexParamVideoIntraRefresh, portIndex,
510                           &param);
511     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
512         std::cout << "[   INFO   ] unable to set Refresh Period \n";
513 }
514
515 void setLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t latency) {
516     android::hardware::media::omx::V1_0::Status status;
517     OMX_PARAM_U32TYPE param;
518     param.nU32 = (OMX_U32)latency;
519     status = setPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
520                            portIndex, &param);
521     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
522         std::cout << "[   INFO   ] unable to set latency\n";
523 }
524
525 void getLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t* latency) {
526     android::hardware::media::omx::V1_0::Status status;
527     OMX_PARAM_U32TYPE param;
528     status = getPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
529                            portIndex, &param);
530     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
531         std::cout << "[   INFO   ] unable to get latency\n";
532     else
533         *latency = param.nU32;
534 }
535
536 // Set Default port param.
537 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
538                          OMX_VIDEO_CODINGTYPE eCompressionFormat,
539                          OMX_U32 nFrameWidth, OMX_U32 nFrameHeight,
540                          OMX_U32 nBitrate, OMX_U32 xFramerate) {
541     android::hardware::media::omx::V1_0::Status status;
542     OMX_PARAM_PORTDEFINITIONTYPE portDef;
543     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
544                           &portDef);
545     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
546     portDef.format.video.nFrameWidth = nFrameWidth;
547     portDef.format.video.nFrameHeight = nFrameHeight;
548     portDef.format.video.nBitrate = nBitrate;
549     portDef.format.video.xFramerate = xFramerate;
550     portDef.format.video.bFlagErrorConcealment = OMX_TRUE;
551     portDef.format.video.eCompressionFormat = eCompressionFormat;
552     portDef.format.video.eColorFormat = OMX_COLOR_FormatUnused;
553     status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
554                           &portDef);
555     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
556
557     std::vector<int32_t> arrProfile;
558     std::vector<int32_t> arrLevel;
559     enumerateProfileAndLevel(omxNode, portIndex, &arrProfile, &arrLevel);
560     if (arrProfile.empty() == true || arrLevel.empty() == true)
561         ASSERT_TRUE(false);
562     int32_t profile = arrProfile[0];
563     int32_t level = arrLevel[0];
564
565     switch ((int)eCompressionFormat) {
566         case OMX_VIDEO_CodingAVC:
567             setupAVCPort(omxNode, portIndex,
568                          static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile),
569                          static_cast<OMX_VIDEO_AVCLEVELTYPE>(level),
570                          xFramerate);
571             break;
572         case OMX_VIDEO_CodingHEVC:
573             setupHEVCPort(omxNode, portIndex,
574                           static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile),
575                           static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level));
576             break;
577         case OMX_VIDEO_CodingH263:
578             setupH263Port(omxNode, portIndex,
579                           static_cast<OMX_VIDEO_H263PROFILETYPE>(profile),
580                           static_cast<OMX_VIDEO_H263LEVELTYPE>(level),
581                           xFramerate);
582             break;
583         case OMX_VIDEO_CodingMPEG4:
584             setupMPEG4Port(omxNode, portIndex,
585                            static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile),
586                            static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level),
587                            xFramerate);
588             break;
589         case OMX_VIDEO_CodingVP8:
590             setupVPXPort(omxNode, portIndex, xFramerate);
591             setupVP8Port(omxNode, portIndex,
592                          static_cast<OMX_VIDEO_VP8PROFILETYPE>(profile),
593                          static_cast<OMX_VIDEO_VP8LEVELTYPE>(level));
594             break;
595         case OMX_VIDEO_CodingVP9:
596             setupVPXPort(omxNode, portIndex, xFramerate);
597             setupVP9Port(omxNode, portIndex,
598                          static_cast<OMX_VIDEO_VP9PROFILETYPE>(profile),
599                          static_cast<OMX_VIDEO_VP9LEVELTYPE>(level));
600             break;
601         default:
602             break;
603     }
604 }
605
606 // LookUpTable of clips and metadata for component testing
607 void GetURLForComponent(char* URL) {
608     strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
609 }
610
611 // blocking call to ensures application to Wait till all the inputs are consumed
612 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
613                             android::Vector<BufferInfo>* iBuffer,
614                             android::Vector<BufferInfo>* oBuffer,
615                             bool inputDataIsMeta = false,
616                             sp<CodecProducerListener> listener = nullptr) {
617     android::hardware::media::omx::V1_0::Status status;
618     Message msg;
619     int timeOut = TIMEOUT_COUNTER_Q;
620
621     while (timeOut--) {
622         size_t i = 0;
623         status =
624             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
625         ASSERT_EQ(status,
626                   android::hardware::media::omx::V1_0::Status::TIMED_OUT);
627         // status == TIMED_OUT, it could be due to process time being large
628         // than DEFAULT_TIMEOUT or component needs output buffers to start
629         // processing.
630         if (inputDataIsMeta) {
631             if (listener->freeBuffers == iBuffer->size()) break;
632         } else {
633             for (; i < iBuffer->size(); i++) {
634                 if ((*iBuffer)[i].owner != client) break;
635             }
636             if (i == iBuffer->size()) break;
637         }
638
639         // Dispatch an output buffer assuming outQueue.empty() is true
640         size_t index;
641         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
642             ASSERT_NO_FATAL_FAILURE(
643                 dispatchOutputBuffer(omxNode, oBuffer, index));
644             timeOut = TIMEOUT_COUNTER_Q;
645         }
646     }
647 }
648
649 int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format,
650                           std::ifstream& eleStream) {
651     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
652         android::hardware::graphics::mapper::V2_0::IMapper::getService();
653     EXPECT_NE(mapper.get(), nullptr);
654     if (mapper.get() == nullptr) return 1;
655
656     android::hardware::hidl_handle fence;
657     android::hardware::graphics::mapper::V2_0::IMapper::Rect rect;
658     android::hardware::graphics::mapper::V2_0::YCbCrLayout ycbcrLayout;
659     android::hardware::graphics::mapper::V2_0::Error error;
660     rect.left = 0;
661     rect.top = 0;
662     rect.width = buffer->omxBuffer.attr.anwBuffer.width;
663     rect.height = buffer->omxBuffer.attr.anwBuffer.height;
664
665     if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
666         format == PixelFormat::YCBCR_420_888) {
667         mapper->lockYCbCr(
668             buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
669             [&](android::hardware::graphics::mapper::V2_0::Error _e,
670                 android::hardware::graphics::mapper::V2_0::YCbCrLayout _n1) {
671                 error = _e;
672                 ycbcrLayout = _n1;
673             });
674         EXPECT_EQ(error,
675                   android::hardware::graphics::mapper::V2_0::Error::NONE);
676         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
677             return 1;
678
679         int size = ((rect.width * rect.height * 3) >> 1);
680         char* img = new char[size];
681         if (img == nullptr) return 1;
682         eleStream.read(img, size);
683         if (eleStream.gcount() != size) {
684             delete[] img;
685             return 1;
686         }
687
688         char* imgTmp = img;
689         char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
690         for (size_t y = rect.height; y > 0; --y) {
691             memcpy(ipBuffer, imgTmp, rect.width);
692             ipBuffer += ycbcrLayout.yStride;
693             imgTmp += rect.width;
694         }
695
696         if (format == PixelFormat::YV12)
697             EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
698         else if (format == PixelFormat::YCRCB_420_SP)
699             EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
700
701         ipBuffer = static_cast<char*>(ycbcrLayout.cb);
702         for (size_t y = rect.height >> 1; y > 0; --y) {
703             for (int32_t x = 0; x < (rect.width >> 1); ++x) {
704                 ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
705             }
706             ipBuffer += ycbcrLayout.cStride;
707         }
708         ipBuffer = static_cast<char*>(ycbcrLayout.cr);
709         for (size_t y = rect.height >> 1; y > 0; --y) {
710             for (int32_t x = 0; x < (rect.width >> 1); ++x) {
711                 ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
712             }
713             ipBuffer += ycbcrLayout.cStride;
714         }
715
716         delete[] img;
717
718         mapper->unlock(buff,
719                        [&](android::hardware::graphics::mapper::V2_0::Error _e,
720                            android::hardware::hidl_handle _n1) {
721                            error = _e;
722                            fence = _n1;
723                        });
724         EXPECT_EQ(error,
725                   android::hardware::graphics::mapper::V2_0::Error::NONE);
726         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
727             return 1;
728     } else {
729         void* data;
730         mapper->lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
731                      [&](android::hardware::graphics::mapper::V2_0::Error _e,
732                          void* _n1) {
733                          error = _e;
734                          data = _n1;
735                      });
736         EXPECT_EQ(error,
737                   android::hardware::graphics::mapper::V2_0::Error::NONE);
738         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
739             return 1;
740
741         if (format == PixelFormat::BGRA_8888) {
742             char* ipBuffer = static_cast<char*>(data);
743             for (size_t y = rect.height; y > 0; --y) {
744                 eleStream.read(ipBuffer, rect.width * 4);
745                 if (eleStream.gcount() != rect.width * 4) return 1;
746                 ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
747             }
748         } else {
749             EXPECT_TRUE(false) << "un expected pixel format";
750             return 1;
751         }
752
753         mapper->unlock(buff,
754                        [&](android::hardware::graphics::mapper::V2_0::Error _e,
755                            android::hardware::hidl_handle _n1) {
756                            error = _e;
757                            fence = _n1;
758                        });
759         EXPECT_EQ(error,
760                   android::hardware::graphics::mapper::V2_0::Error::NONE);
761         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
762             return 1;
763     }
764
765     return 0;
766 }
767
768 int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format,
769                       std::ifstream& eleStream) {
770     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
771         android::hardware::graphics::mapper::V2_0::IMapper::getService();
772     EXPECT_NE(mapper.get(), nullptr);
773     if (mapper.get() == nullptr) return 1;
774
775     void* buff = nullptr;
776     android::hardware::graphics::mapper::V2_0::Error error;
777     mapper->importBuffer(
778         buffer->omxBuffer.nativeHandle,
779         [&](android::hardware::graphics::mapper::V2_0::Error _e, void* _n1) {
780             error = _e;
781             buff = _n1;
782         });
783     EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
784     if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
785         return 1;
786
787     if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
788
789     error = mapper->freeBuffer(buff);
790     EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
791     if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
792         return 1;
793
794     return 0;
795 }
796
797 int dispatchGraphicBuffer(sp<IOmxNode> omxNode,
798                           sp<IGraphicBufferProducer> producer,
799                           sp<CodecProducerListener> listener,
800                           android::Vector<BufferInfo>* buffArray,
801                           OMX_U32 portIndex, std::ifstream& eleStream,
802                           uint64_t timestamp) {
803     android::hardware::media::omx::V1_0::Status status;
804     OMX_PARAM_PORTDEFINITIONTYPE portDef;
805
806     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
807                           &portDef);
808     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
809     if (status != ::android::hardware::media::omx::V1_0::Status::OK) return 1;
810
811     enum {
812         // A flag returned by dequeueBuffer when the client needs to call
813         // requestBuffer immediately thereafter.
814         BUFFER_NEEDS_REALLOCATION = 0x1,
815         // A flag returned by dequeueBuffer when all mirrored slots should be
816         // released by the client. This flag should always be processed first.
817         RELEASE_ALL_BUFFERS = 0x2,
818     };
819
820     int32_t slot;
821     int32_t result;
822     ::android::hardware::hidl_handle fence;
823     IGraphicBufferProducer::FrameEventHistoryDelta outTimestamps;
824     ::android::hardware::media::V1_0::AnwBuffer AnwBuffer;
825     PixelFormat format = PixelFormat::YCBCR_420_888;
826     producer->dequeueBuffer(
827         portDef.format.video.nFrameWidth, portDef.format.video.nFrameHeight,
828         format, BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
829         true, [&](int32_t _s, int32_t const& _n1,
830                   ::android::hardware::hidl_handle const& _n2,
831                   IGraphicBufferProducer::FrameEventHistoryDelta const& _n3) {
832             result = _s;
833             slot = _n1;
834             fence = _n2;
835             outTimestamps = _n3;
836         });
837     if (result & BUFFER_NEEDS_REALLOCATION) {
838         producer->requestBuffer(
839             slot, [&](int32_t _s,
840                       ::android::hardware::media::V1_0::AnwBuffer const& _n1) {
841                 result = _s;
842                 AnwBuffer = _n1;
843             });
844         EXPECT_EQ(result, 0);
845         if (result != 0) return 1;
846         size_t i;
847         for (i = 0; i < buffArray->size(); i++) {
848             if ((*buffArray)[i].slot == -1) {
849                 buffArray->editItemAt(i).slot = slot;
850                 buffArray->editItemAt(i).omxBuffer.nativeHandle =
851                     AnwBuffer.nativeHandle;
852                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer =
853                     AnwBuffer.attr;
854                 break;
855             }
856         }
857         EXPECT_NE(i, buffArray->size());
858         if (i == buffArray->size()) return 1;
859     }
860     EXPECT_EQ(result, 0);
861     if (result != 0) return 1;
862
863     // fill Buffer
864     BufferInfo buffer;
865     size_t i;
866     for (i = 0; i < buffArray->size(); i++) {
867         if ((*buffArray)[i].slot == slot) {
868             buffer = (*buffArray)[i];
869             break;
870         }
871     }
872     EXPECT_NE(i, buffArray->size());
873     if (i == buffArray->size()) return 1;
874     if (fillGraphicBuffer(&buffer, format, eleStream)) return 1;
875
876     // queue Buffer
877     IGraphicBufferProducer::QueueBufferOutput output;
878     IGraphicBufferProducer::QueueBufferInput input;
879     android::hardware::media::V1_0::Rect rect;
880     rect.left = 0;
881     rect.top = 0;
882     rect.right = buffer.omxBuffer.attr.anwBuffer.width;
883     rect.bottom = buffer.omxBuffer.attr.anwBuffer.height;
884     input.timestamp = timestamp;
885     input.isAutoTimestamp = false;
886     input.dataSpace =
887         android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN;
888     input.crop = rect;
889     input.scalingMode = 0;
890     input.transform = 0;
891     input.stickyTransform = 0;
892     input.fence = android::hardware::hidl_handle();
893     input.surfaceDamage =
894         android::hardware::hidl_vec<android::hardware::media::V1_0::Rect>{rect};
895     input.getFrameTimestamps = false;
896     producer->queueBuffer(
897         buffer.slot, input,
898         [&](int32_t _s, const IGraphicBufferProducer::QueueBufferOutput& _n1) {
899             result = _s;
900             output = _n1;
901         });
902     EXPECT_EQ(result, 0);
903     if (result != 0) return 1;
904
905     listener->reduceCount();
906
907     return 0;
908 }
909
910 int fillByteBuffer(sp<IOmxNode> omxNode, char* ipBuffer, OMX_U32 portIndexInput,
911                    std::ifstream& eleStream) {
912     android::hardware::media::omx::V1_0::Status status;
913     OMX_PARAM_PORTDEFINITIONTYPE portDef;
914     uint32_t i, j;
915
916     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndexInput,
917                           &portDef);
918     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
919
920     int size = ((portDef.format.video.nFrameWidth *
921                  portDef.format.video.nFrameHeight * 3) >>
922                 1);
923     char* img = new char[size];
924     if (img == nullptr) return 1;
925     eleStream.read(img, size);
926     if (eleStream.gcount() != size) {
927         delete[] img;
928         return 1;
929     }
930
931     char* Y = ipBuffer;
932     char* imgTmp = img;
933     for (j = 0; j < portDef.format.video.nFrameHeight; ++j) {
934         memcpy(Y, imgTmp, portDef.format.video.nFrameWidth);
935         Y += portDef.format.video.nStride;
936         imgTmp += portDef.format.video.nFrameWidth;
937     }
938
939     if (portDef.format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
940         char* Cb = ipBuffer + (portDef.format.video.nFrameHeight *
941                                portDef.format.video.nStride);
942         char* Cr = Cb + 1;
943         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
944             for (i = 0; i < (portDef.format.video.nFrameWidth >> 1); ++i) {
945                 Cb[2 * i] = *imgTmp++;
946             }
947             Cb += portDef.format.video.nStride;
948         }
949         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
950             for (i = 0; i < (portDef.format.video.nFrameWidth >> 1); ++i) {
951                 Cr[2 * i] = *imgTmp++;
952             }
953             Cr += portDef.format.video.nStride;
954         }
955     } else if (portDef.format.video.eColorFormat ==
956                OMX_COLOR_FormatYUV420Planar) {
957         char* Cb = ipBuffer + (portDef.format.video.nFrameHeight *
958                                portDef.format.video.nStride);
959         char* Cr = Cb + ((portDef.format.video.nFrameHeight *
960                           portDef.format.video.nStride) >>
961                          2);
962         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
963             memcpy(Cb, imgTmp, (portDef.format.video.nFrameWidth >> 1));
964             Cb += (portDef.format.video.nStride >> 1);
965             imgTmp += (portDef.format.video.nFrameWidth >> 1);
966         }
967         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
968             memcpy(Cr, imgTmp, (portDef.format.video.nFrameWidth >> 1));
969             Cr += (portDef.format.video.nStride >> 1);
970             imgTmp += (portDef.format.video.nFrameWidth >> 1);
971         }
972     }
973
974     delete[] img;
975     return 0;
976 }
977
978 // Encode N Frames
979 void encodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
980                    OMX_U32 portIndexInput, OMX_U32 portIndexOutput,
981                    android::Vector<BufferInfo>* iBuffer,
982                    android::Vector<BufferInfo>* oBuffer, uint32_t nFrames,
983                    uint32_t xFramerate, int bytesCount,
984                    std::ifstream& eleStream,
985                    ::android::List<uint64_t>* timestampUslist = nullptr,
986                    bool signalEOS = true, bool inputDataIsMeta = false,
987                    sp<IGraphicBufferProducer> producer = nullptr,
988                    sp<CodecProducerListener> listener = nullptr) {
989     android::hardware::media::omx::V1_0::Status status;
990     Message msg;
991     uint64_t timestamp = 0;
992     uint32_t flags = 0;
993     int timeOut = TIMEOUT_COUNTER_Q;
994     bool iQueued, oQueued;
995
996     uint32_t ipCount = 0;
997     if (ipCount == 0) {
998         status = changeFrameRate(omxNode, portIndexOutput, (24U << 16));
999         if (status == ::android::hardware::media::omx::V1_0::Status::OK)
1000             xFramerate = (24U << 16);
1001     }
1002     int32_t timestampIncr = (int)((float)1000000 / (xFramerate >> 16));
1003     if (inputDataIsMeta) timestampIncr *= 1000;  // timestamp scale: Nano sec
1004
1005     while (1) {
1006         iQueued = oQueued = false;
1007         status =
1008             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
1009         // Port Reconfiguration
1010         if (status == android::hardware::media::omx::V1_0::Status::OK) {
1011             ASSERT_EQ(msg.type, Message::Type::EVENT);
1012             if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
1013                 ASSERT_EQ(msg.data.eventData.data1, portIndexOutput);
1014                 ASSERT_EQ(msg.data.eventData.data2,
1015                           OMX_IndexConfigAndroidIntraRefresh);
1016             } else if (msg.data.eventData.event == OMX_EventError) {
1017                 ASSERT_TRUE(false) << "Received OMX_EventError, not sure why";
1018             } else if (msg.data.eventData.event == OMX_EventDataSpaceChanged) {
1019                 // TODO: how am i supposed to respond now?
1020                 std::cout << "[   INFO   ] OMX_EventDataSpaceChanged \n";
1021             } else {
1022                 ASSERT_TRUE(false);
1023             }
1024         }
1025
1026         if (nFrames == 0) break;
1027
1028         // Dispatch input buffer
1029         size_t index = 0;
1030         if (inputDataIsMeta) {
1031             if (listener->freeBuffers > listener->minUnDequeuedCount) {
1032                 if (dispatchGraphicBuffer(omxNode, producer, listener, iBuffer,
1033                                           portIndexInput, eleStream,
1034                                           timestamp)) {
1035                     if (::testing::Test::HasFailure())
1036                         ASSERT_TRUE(false);
1037                     else
1038                         break;
1039                 }
1040                 timestamp += timestampIncr;
1041                 nFrames--;
1042                 ipCount++;
1043                 iQueued = true;
1044             }
1045         } else {
1046             if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
1047                 char* ipBuffer = static_cast<char*>(static_cast<void*>(
1048                     (*iBuffer)[index].mMemory->getPointer()));
1049                 ASSERT_LE(
1050                     bytesCount,
1051                     static_cast<int>((*iBuffer)[index].mMemory->getSize()));
1052                 if (fillByteBuffer(omxNode, ipBuffer, portIndexInput,
1053                                    eleStream))
1054                     break;
1055                 flags = OMX_BUFFERFLAG_ENDOFFRAME;
1056                 if (signalEOS && (nFrames == 1)) flags |= OMX_BUFFERFLAG_EOS;
1057                 ASSERT_NO_FATAL_FAILURE(dispatchInputBuffer(
1058                     omxNode, iBuffer, index, bytesCount, flags, timestamp));
1059                 if (timestampUslist) timestampUslist->push_back(timestamp);
1060                 timestamp += timestampIncr;
1061                 nFrames--;
1062                 ipCount++;
1063                 iQueued = true;
1064             }
1065         }
1066         // Dispatch output buffer
1067         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
1068             ASSERT_NO_FATAL_FAILURE(
1069                 dispatchOutputBuffer(omxNode, oBuffer, index));
1070             oQueued = true;
1071         }
1072         // Reset Counters when either input or output buffer is dispatched
1073         if (iQueued || oQueued)
1074             timeOut = TIMEOUT_COUNTER_Q;
1075         else
1076             timeOut--;
1077         if (timeOut == 0) {
1078             ASSERT_TRUE(false) << "Wait on Input/Output is found indefinite";
1079         }
1080         // Runtime Param Configuration
1081         if (ipCount == 15) {
1082             changeBitrate(omxNode, portIndexOutput, 768000);
1083             requestIDR(omxNode, portIndexOutput);
1084             changeRefreshPeriod(omxNode, portIndexOutput, 15);
1085         }
1086     }
1087 }
1088
1089 // set component role
1090 TEST_F(VideoEncHidlTest, SetRole) {
1091     description("Test Set Component Role");
1092     if (disableTest) return;
1093     android::hardware::media::omx::V1_0::Status status;
1094     status = setRole(omxNode, gEnv->getRole().c_str());
1095     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1096 }
1097
1098 // port format enumeration
1099 TEST_F(VideoEncHidlTest, EnumeratePortFormat) {
1100     description("Test Component on Mandatory Port Parameters (Port Format)");
1101     if (disableTest) return;
1102     android::hardware::media::omx::V1_0::Status status;
1103     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1104     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
1105     OMX_U32 xFramerate = (30U << 16);
1106     status = setRole(omxNode, gEnv->getRole().c_str());
1107     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1108     OMX_PORT_PARAM_TYPE params;
1109     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1110     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1111         ASSERT_EQ(params.nPorts, 2U);
1112         kPortIndexInput = params.nStartPortNumber;
1113         kPortIndexOutput = kPortIndexInput + 1;
1114     }
1115     status =
1116         setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused,
1117                            eColorFormat, xFramerate);
1118     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1119
1120     status = setVideoPortFormat(omxNode, kPortIndexOutput, eCompressionFormat,
1121                                 OMX_COLOR_FormatUnused, 0U);
1122     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1123 }
1124
1125 // Test IOmxBufferSource CallBacks
1126 TEST_F(VideoEncHidlTest, BufferSourceCallBacks) {
1127     description("Test IOmxBufferSource CallBacks");
1128     if (disableTest) return;
1129     android::hardware::media::omx::V1_0::Status status;
1130     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1131     status = setRole(omxNode, gEnv->getRole().c_str());
1132     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1133     OMX_PORT_PARAM_TYPE params;
1134     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1135     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1136         ASSERT_EQ(params.nPorts, 2U);
1137         kPortIndexInput = params.nStartPortNumber;
1138         kPortIndexOutput = kPortIndexInput + 1;
1139     }
1140
1141     // Configure input port
1142     uint32_t nFrameWidth = 352;
1143     uint32_t nFrameHeight = 288;
1144     uint32_t xFramerate = (30U << 16);
1145     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
1146     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
1147                  xFramerate, eColorFormat);
1148
1149     sp<DummyBufferSource> buffersource = new DummyBufferSource(omxNode);
1150     ASSERT_NE(buffersource, nullptr);
1151     status = omxNode->setInputSurface(buffersource);
1152     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1153
1154     // set port mode
1155     PortMode portMode[2];
1156     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
1157     portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1158     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1159     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1160     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1161     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1162
1163     // set state to idle
1164     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1165         omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer,
1166         kPortIndexInput, kPortIndexOutput, portMode));
1167     // set state to executing
1168     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1169     ASSERT_NO_FATAL_FAILURE(testEOS(omxNode, observer, &buffersource->iBuffer,
1170                                     &buffersource->oBuffer, false, eosFlag));
1171     // set state to idle
1172     ASSERT_NO_FATAL_FAILURE(changeStateExecutetoIdle(
1173         omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer));
1174     // set state to executing
1175     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(
1176         omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer,
1177         kPortIndexInput, kPortIndexOutput));
1178     // test for callbacks
1179     EXPECT_EQ(buffersource->callback, 31);
1180 }
1181
1182 // test raw stream encode (input is byte buffers)
1183 TEST_F(VideoEncHidlTest, EncodeTest) {
1184     description("Test Encode");
1185     if (disableTest) return;
1186     android::hardware::media::omx::V1_0::Status status;
1187     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1188     status = setRole(omxNode, gEnv->getRole().c_str());
1189     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1190     OMX_PORT_PARAM_TYPE params;
1191     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1192     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1193         ASSERT_EQ(params.nPorts, 2U);
1194         kPortIndexInput = params.nStartPortNumber;
1195         kPortIndexOutput = kPortIndexInput + 1;
1196     }
1197     char mURL[512];
1198     strcpy(mURL, gEnv->getRes().c_str());
1199     GetURLForComponent(mURL);
1200
1201     std::ifstream eleStream;
1202
1203     timestampDevTest = true;
1204
1205     // Configure input port
1206     uint32_t nFrameWidth = 352;
1207     uint32_t nFrameHeight = 288;
1208     uint32_t xFramerate = (30U << 16);
1209     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1210     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
1211     portFormat.nIndex = 0;
1212     while (1) {
1213         status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
1214                               kPortIndexInput, &portFormat);
1215         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
1216         EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
1217         if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
1218             OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat) {
1219             eColorFormat = portFormat.eColorFormat;
1220             break;
1221         }
1222         portFormat.nIndex++;
1223         if (portFormat.nIndex == 512) break;
1224     }
1225     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1226     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
1227                  xFramerate, eColorFormat);
1228
1229     // Configure output port
1230     uint32_t nBitRate = 512000;
1231     ASSERT_NO_FATAL_FAILURE(
1232         setDefaultPortParam(omxNode, kPortIndexOutput, eCompressionFormat,
1233                             nFrameWidth, nFrameHeight, nBitRate, xFramerate));
1234     setRefreshPeriod(omxNode, kPortIndexOutput, 0);
1235
1236     unsigned int index;
1237     omxNode->getExtensionIndex(
1238         "OMX.google.android.index.prependSPSPPSToIDRFrames",
1239         [&status, &index](android::hardware::media::omx::V1_0::Status _s,
1240                           unsigned int _nl) {
1241             status = _s;
1242             index = _nl;
1243         });
1244     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1245         android::PrependSPSPPSToIDRFramesParams param;
1246         param.bEnable = OMX_TRUE;
1247         status = setParam(omxNode, static_cast<OMX_INDEXTYPE>(index), &param);
1248     }
1249     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
1250         std::cout << "[   INFO   ] unable to prependSPSPPSToIDRFrames\n";
1251     else
1252         prependSPSPPS = true;
1253
1254     // set port mode
1255     PortMode portMode[2];
1256     portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1257     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1258     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1259     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1260     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1261
1262     uint32_t latency = 0;
1263     setLatency(omxNode, kPortIndexInput, latency);
1264     getLatency(omxNode, kPortIndexInput, &latency);
1265
1266     android::Vector<BufferInfo> iBuffer, oBuffer;
1267
1268     // set state to idle
1269     ASSERT_NO_FATAL_FAILURE(
1270         changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1271                                 kPortIndexInput, kPortIndexOutput, portMode));
1272     // set state to executing
1273     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1274
1275     eleStream.open(mURL, std::ifstream::binary);
1276     ASSERT_EQ(eleStream.is_open(), true);
1277     ASSERT_NO_FATAL_FAILURE(encodeNFrames(
1278         omxNode, observer, kPortIndexInput, kPortIndexOutput, &iBuffer,
1279         &oBuffer, 32, xFramerate, (nFrameWidth * nFrameHeight * 3) >> 1,
1280         eleStream, &timestampUslist));
1281     eleStream.close();
1282     ASSERT_NO_FATAL_FAILURE(
1283         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer));
1284     ASSERT_NO_FATAL_FAILURE(
1285         testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag));
1286     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
1287
1288     // set state to idle
1289     ASSERT_NO_FATAL_FAILURE(
1290         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1291     // set state to executing
1292     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
1293                                                     &oBuffer, kPortIndexInput,
1294                                                     kPortIndexOutput));
1295 }
1296
1297 // test raw stream encode (input is ANW buffers)
1298 TEST_F(VideoEncHidlTest, EncodeTestBufferMetaModes) {
1299     description("Test Encode Input buffer metamodes");
1300     if (disableTest) return;
1301     android::hardware::media::omx::V1_0::Status status;
1302     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1303     status = setRole(omxNode, gEnv->getRole().c_str());
1304     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1305     OMX_PORT_PARAM_TYPE params;
1306     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1307     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1308         ASSERT_EQ(params.nPorts, 2U);
1309         kPortIndexInput = params.nStartPortNumber;
1310         kPortIndexOutput = kPortIndexInput + 1;
1311     }
1312
1313     // Configure input port
1314     uint32_t nFrameWidth = 352;
1315     uint32_t nFrameHeight = 288;
1316     uint32_t xFramerate = (30U << 16);
1317     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
1318     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
1319                  xFramerate, eColorFormat);
1320
1321     // Configure output port
1322     uint32_t nBitRate = 512000;
1323     ASSERT_NO_FATAL_FAILURE(
1324         setDefaultPortParam(omxNode, kPortIndexOutput, eCompressionFormat,
1325                             nFrameWidth, nFrameHeight, nBitRate, xFramerate));
1326     // CreateInputSurface
1327     EXPECT_TRUE(omx->createInputSurface(
1328                        [&](android::hardware::media::omx::V1_0::Status _s,
1329                            sp<IGraphicBufferProducer> const& _nl,
1330                            sp<IGraphicBufferSource> const& _n2) {
1331                            status = _s;
1332                            producer = _nl;
1333                            source = _n2;
1334                        })
1335                     .isOk());
1336     ASSERT_NE(producer, nullptr);
1337     ASSERT_NE(source, nullptr);
1338
1339     // setMaxDequeuedBufferCount
1340     int32_t returnval;
1341     int32_t value;
1342     producer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1343                     [&returnval, &value](int32_t _s, int32_t _n1) {
1344                         returnval = _s;
1345                         value = _n1;
1346                     });
1347     ASSERT_EQ(returnval, 0);
1348     OMX_PARAM_PORTDEFINITIONTYPE portDef;
1349     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
1350                           kPortIndexInput, &portDef);
1351     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1352     ASSERT_EQ(::android::OK,
1353               producer->setMaxDequeuedBufferCount(portDef.nBufferCountActual));
1354
1355     // Connect :: Mock Producer Listener
1356     IGraphicBufferProducer::QueueBufferOutput qbo;
1357     sp<CodecProducerListener> listener =
1358         new CodecProducerListener(portDef.nBufferCountActual + value, value);
1359     producer->connect(
1360         listener, NATIVE_WINDOW_API_CPU, false,
1361         [&](int32_t _s, IGraphicBufferProducer::QueueBufferOutput const& _n1) {
1362             returnval = _s;
1363             qbo = _n1;
1364         });
1365     ASSERT_EQ(returnval, 0);
1366
1367     portDef.nBufferCountActual = portDef.nBufferCountActual + value;
1368     status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
1369                           kPortIndexInput, &portDef);
1370     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1371
1372     // Do setInputSurface()
1373     // enable MetaMode on input port
1374     status = source->configure(
1375         omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
1376     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1377
1378     // set port mode
1379     PortMode portMode[2];
1380     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
1381     portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1382     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1383     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1384     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1385     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1386
1387     char mURL[512];
1388     strcpy(mURL, gEnv->getRes().c_str());
1389     GetURLForComponent(mURL);
1390
1391     uint32_t latency = 0;
1392     setLatency(omxNode, kPortIndexInput, latency);
1393     getLatency(omxNode, kPortIndexInput, &latency);
1394
1395     std::ifstream eleStream;
1396
1397     status = source->setSuspend(false, 0);
1398     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1399     status = source->setRepeatPreviousFrameDelayUs(100000);
1400     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1401     status = source->setMaxFps(24.0f);
1402     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1403     status = source->setTimeLapseConfig(24.0, 24.0);
1404     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1405     status = source->setTimeOffsetUs(-100);
1406     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1407     status = source->setStartTimeUs(10);
1408     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1409     status = source->setStopTimeUs(1000000);
1410     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1411     ::android::hardware::media::omx::V1_0::ColorAspects aspects;
1412     aspects.range =
1413         ::android::hardware::media::omx::V1_0::ColorAspects::Range::UNSPECIFIED;
1414     aspects.primaries = ::android::hardware::media::omx::V1_0::ColorAspects::
1415         Primaries::UNSPECIFIED;
1416     aspects.transfer = ::android::hardware::media::omx::V1_0::ColorAspects::
1417         Transfer::UNSPECIFIED;
1418     aspects.matrixCoeffs = ::android::hardware::media::omx::V1_0::ColorAspects::
1419         MatrixCoeffs::UNSPECIFIED;
1420     status = source->setColorAspects(aspects);
1421     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1422     int64_t stopTimeOffsetUs;
1423     source->getStopTimeOffsetUs(
1424         [&](android::hardware::media::omx::V1_0::Status _s, int64_t _n1) {
1425             status = _s;
1426             stopTimeOffsetUs = _n1;
1427         });
1428     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1429
1430     android::Vector<BufferInfo> iBuffer, oBuffer;
1431     // set state to idle
1432     ASSERT_NO_FATAL_FAILURE(
1433         changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1434                                 kPortIndexInput, kPortIndexOutput, portMode));
1435     // set state to executing
1436     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1437
1438     eleStream.open(mURL, std::ifstream::binary);
1439     ASSERT_EQ(eleStream.is_open(), true);
1440     ASSERT_NO_FATAL_FAILURE(encodeNFrames(
1441         omxNode, observer, kPortIndexInput, kPortIndexOutput, &iBuffer,
1442         &oBuffer, 1024, xFramerate, (nFrameWidth * nFrameHeight * 3) >> 1,
1443         eleStream, nullptr, false, true, producer, listener));
1444     eleStream.close();
1445     ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(omxNode, observer, &iBuffer,
1446                                                    &oBuffer, true, listener));
1447     ASSERT_NO_FATAL_FAILURE(
1448         testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag));
1449
1450     // set state to idle
1451     ASSERT_NO_FATAL_FAILURE(
1452         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1453     EXPECT_EQ(portDef.nBufferCountActual, listener->freeBuffers);
1454     // set state to executing
1455     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
1456                                                     &oBuffer, kPortIndexInput,
1457                                                     kPortIndexOutput));
1458
1459     returnval = producer->disconnect(
1460         NATIVE_WINDOW_API_CPU, IGraphicBufferProducer::DisconnectMode::API);
1461     ASSERT_EQ(returnval, 0);
1462 }
1463
1464 // Test end of stream
1465 TEST_F(VideoEncHidlTest, EncodeTestEOS) {
1466     description("Test EOS");
1467     if (disableTest) return;
1468     android::hardware::media::omx::V1_0::Status status;
1469     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1470     status = setRole(omxNode, gEnv->getRole().c_str());
1471     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1472     OMX_PORT_PARAM_TYPE params;
1473     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1474     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1475         ASSERT_EQ(params.nPorts, 2U);
1476         kPortIndexInput = params.nStartPortNumber;
1477         kPortIndexOutput = kPortIndexInput + 1;
1478     }
1479
1480     // Configure input port
1481     uint32_t nFrameWidth = 352;
1482     uint32_t nFrameHeight = 288;
1483     uint32_t xFramerate = (30U << 16);
1484     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
1485     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
1486                  xFramerate, eColorFormat);
1487
1488     // CreateInputSurface
1489     EXPECT_TRUE(omx->createInputSurface(
1490                        [&](android::hardware::media::omx::V1_0::Status _s,
1491                            sp<IGraphicBufferProducer> const& _nl,
1492                            sp<IGraphicBufferSource> const& _n2) {
1493                            status = _s;
1494                            producer = _nl;
1495                            source = _n2;
1496                        })
1497                     .isOk());
1498     ASSERT_NE(producer, nullptr);
1499     ASSERT_NE(source, nullptr);
1500
1501     // setMaxDequeuedBufferCount
1502     int32_t returnval;
1503     int32_t value;
1504     producer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1505                     [&returnval, &value](int32_t _s, int32_t _n1) {
1506                         returnval = _s;
1507                         value = _n1;
1508                     });
1509     ASSERT_EQ(returnval, 0);
1510     OMX_PARAM_PORTDEFINITIONTYPE portDef;
1511     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
1512                           kPortIndexInput, &portDef);
1513     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1514     ASSERT_EQ(::android::OK,
1515               producer->setMaxDequeuedBufferCount(portDef.nBufferCountActual));
1516
1517     // Connect :: Mock Producer Listener
1518     IGraphicBufferProducer::QueueBufferOutput qbo;
1519     sp<CodecProducerListener> listener =
1520         new CodecProducerListener(portDef.nBufferCountActual + value, value);
1521     producer->connect(
1522         listener, NATIVE_WINDOW_API_CPU, false,
1523         [&](int32_t _s, IGraphicBufferProducer::QueueBufferOutput const& _n1) {
1524             returnval = _s;
1525             qbo = _n1;
1526         });
1527     ASSERT_EQ(returnval, 0);
1528
1529     portDef.nBufferCountActual = portDef.nBufferCountActual + value;
1530     status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
1531                           kPortIndexInput, &portDef);
1532     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1533
1534     // Do setInputSurface()
1535     // enable MetaMode on input port
1536     status = source->configure(
1537         omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
1538     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1539
1540     // set port mode
1541     PortMode portMode[2];
1542     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
1543     portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1544     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1545     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1546     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1547     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1548
1549     android::Vector<BufferInfo> iBuffer, oBuffer;
1550     // set state to idle
1551     ASSERT_NO_FATAL_FAILURE(
1552         changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1553                                 kPortIndexInput, kPortIndexOutput, portMode));
1554     // set state to executing
1555     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1556
1557     // send EOS
1558     status = source->signalEndOfInputStream();
1559     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1560     ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(omxNode, observer, &iBuffer,
1561                                                    &oBuffer, true, listener));
1562     ASSERT_NO_FATAL_FAILURE(
1563         testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag));
1564
1565     // set state to idle
1566     ASSERT_NO_FATAL_FAILURE(
1567         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1568     EXPECT_EQ(portDef.nBufferCountActual, listener->freeBuffers);
1569     // set state to executing
1570     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
1571                                                     &oBuffer, kPortIndexInput,
1572                                                     kPortIndexOutput));
1573
1574     returnval = producer->disconnect(
1575         NATIVE_WINDOW_API_CPU, IGraphicBufferProducer::DisconnectMode::API);
1576     ASSERT_EQ(returnval, 0);
1577 }
1578
1579 int main(int argc, char** argv) {
1580     gEnv = new ComponentTestEnvironment();
1581     ::testing::AddGlobalTestEnvironment(gEnv);
1582     ::testing::InitGoogleTest(&argc, argv);
1583     int status = gEnv->initFromOptions(argc, argv);
1584     if (status == 0) {
1585         status = RUN_ALL_TESTS();
1586         ALOGI("Test result = %d", status);
1587     }
1588     return status;
1589 }