1 /**
2  * Copyright (C) 2019 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 #include <SharedMemoryBuffer.h>
18 #include <binder/MemoryDealer.h>
19 #include <media/OMXBuffer.h>
20 #include <media/stagefright/OMXClient.h>
21 #include <media/stagefright/foundation/AMessage.h>
22 
23 #include "OMX_Component.h"
24 
25 using namespace android;
26 
27 struct DummyOMXObserver : public BnOMXObserver {
28  public:
DummyOMXObserverDummyOMXObserver29   DummyOMXObserver() {}
onMessagesDummyOMXObserver30   virtual void onMessages(const std::list<omx_message> &) {}
31 
32  protected:
~DummyOMXObserverDummyOMXObserver33   virtual ~DummyOMXObserver() {}
34 };
35 
fuzzIOMXQcomVpx()36 bool fuzzIOMXQcomVpx() {
37   const char *name = "OMX.qcom.video.decoder.vp8";
38   int fenceFd = -1;
39 
40   int inSize = 6230016 * 4;
41   int outSize = 159744 * 4;
42 
43   sp<IMemory> memory;
44   sp<IOMXNode> mOMXNode;
45   sp<IOMX> mOmx;
46 
47   OMXClient client;
48   if (client.connect() != OK) {
49     ALOGE("OMXClient connect == NULL");
50     return false;
51   }
52 
53   mOmx = client.interface();
54   if (mOmx == NULL) {
55     ALOGE("OMXClient interface mOmx == NULL");
56     client.disconnect();
57     return false;
58   }
59 
60   sp<DummyOMXObserver> observerDec = new DummyOMXObserver();
61 
62   ALOGI("-----------decode------------");
63   status_t err = mOmx->allocateNode(name, observerDec, &mOMXNode);
64   if (err != OK) {
65     ALOGE("%s node allocation failed", name);
66     client.disconnect();
67     return false;
68   }
69 
70   // change state from loaded to idle
71   err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
72   if (err != OK) {
73     ALOGE("sendCommand is failed in OMX_StateIdle, err: %d", err);
74     mOMXNode->freeNode();
75     client.disconnect();
76     return false;
77   }
78 
79   // Input
80   sp<MemoryDealer> dealerIn = new MemoryDealer(inSize);
81   IOMX::buffer_id inBufferId = 0;
82   memory = dealerIn->allocate(inSize);
83   if (memory.get() == nullptr || memory->pointer() == nullptr) {
84     ALOGE("memory allocate failed for port index 0, err: %d", err);
85     mOMXNode->freeNode();
86     client.disconnect();
87     return false;
88   }
89 
90   /*
91    * keep running to check whether mediaserver crashes
92    * Error conditions are not checked for usebuffer/emptybuffer/fillbuffer
93    */
94 
95   OMXBuffer omxInBuf(memory);
96   memset(memory->pointer(), 0xCF, inSize);
97   err = mOMXNode->useBuffer(0, omxInBuf, &inBufferId);
98   ALOGI("useBuffer, port index 0, err: %d", err);
99 
100   sp<AMessage> inputFormat = new AMessage;
101   sp<MediaCodecBuffer> codecDataIn;
102   codecDataIn = new SharedMemoryBuffer(inputFormat, memory);
103   OMXBuffer omxInBufShared(codecDataIn);
104 
105   // Output
106   sp<MemoryDealer> dealerOut = new MemoryDealer(outSize);
107   IOMX::buffer_id outBufferId = 0;
108   memory = dealerOut->allocate(outSize);
109   if (memory.get() == nullptr || memory->pointer() == nullptr) {
110     ALOGE("memory allocate failed for port index 1, err: %d", err);
111     mOMXNode->freeNode();
112     client.disconnect();
113     return false;
114   }
115   OMXBuffer omxOutBuf(memory);
116   err = mOMXNode->useBuffer(1, omxOutBuf, &outBufferId);
117   ALOGI("useBuffer, port index 1, err: %d", err);
118 
119   sp<AMessage> outputFormat = new AMessage;
120   sp<MediaCodecBuffer> codecDataOut;
121   codecDataOut = new SharedMemoryBuffer(outputFormat, memory);
122   OMXBuffer omxOutBufShared(codecDataOut);
123 
124   // change state from idle to executing
125   err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateExecuting);
126   if (err != OK) {
127     ALOGE("sendCommand is failed in OMX_StateExecuting, err: %d", err);
128     mOMXNode->freeNode();
129     client.disconnect();
130     return false;
131   }
132 
133   // keep running to check whether mediaserver crashes
134   err = mOMXNode->emptyBuffer(inBufferId, omxInBufShared, 0, 0, fenceFd);
135   ALOGI("emptyBuffer, err: %d", err);
136 
137   err = mOMXNode->fillBuffer(outBufferId, omxOutBufShared, fenceFd);
138   ALOGI("fillBuffer, err: %d", err);
139 
140   // free node
141   err = mOMXNode->freeNode();
142   ALOGI("freeNode, err: %d", err);
143 
144   client.disconnect();
145   return true;
146 }
147 
main()148 int main() { return (int)(!fuzzIOMXQcomVpx()); }
149