1 /*
2  * Copyright 2016, 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 <algorithm>
18 
19 #include <media/omx/1.0/WOmxNode.h>
20 #include <media/omx/1.0/WOmxBufferSource.h>
21 #include <media/omx/1.0/Conversion.h>
22 
23 namespace android {
24 namespace hardware {
25 namespace media {
26 namespace omx {
27 namespace V1_0 {
28 namespace utils {
29 
30 using ::android::hardware::Void;
31 
32 // LWOmxNode
freeNode()33 status_t LWOmxNode::freeNode() {
34     return toStatusT(mBase->freeNode());
35 }
36 
sendCommand(OMX_COMMANDTYPE cmd,OMX_S32 param)37 status_t LWOmxNode::sendCommand(
38         OMX_COMMANDTYPE cmd, OMX_S32 param) {
39     return toStatusT(mBase->sendCommand(
40             toRawCommandType(cmd), param));
41 }
42 
getParameter(OMX_INDEXTYPE index,void * params,size_t size)43 status_t LWOmxNode::getParameter(
44         OMX_INDEXTYPE index, void *params, size_t size) {
45     hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
46     status_t fnStatus;
47     status_t transStatus = toStatusT(mBase->getParameter(
48             toRawIndexType(index),
49             tParams,
50             [&fnStatus, params](
51                     Status status, hidl_vec<uint8_t> const& outParams) {
52                 fnStatus = toStatusT(status);
53                 std::copy(
54                         outParams.data(),
55                         outParams.data() + outParams.size(),
56                         static_cast<uint8_t*>(params));
57             }));
58     return transStatus == NO_ERROR ? fnStatus : transStatus;
59 }
60 
setParameter(OMX_INDEXTYPE index,const void * params,size_t size)61 status_t LWOmxNode::setParameter(
62         OMX_INDEXTYPE index, const void *params, size_t size) {
63     hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
64     return toStatusT(mBase->setParameter(
65             toRawIndexType(index), tParams));
66 }
67 
getConfig(OMX_INDEXTYPE index,void * params,size_t size)68 status_t LWOmxNode::getConfig(
69         OMX_INDEXTYPE index, void *params, size_t size) {
70     hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
71     status_t fnStatus;
72     status_t transStatus = toStatusT(mBase->getConfig(
73             toRawIndexType(index),
74             tParams,
75             [&fnStatus, params, size](
76                     Status status, hidl_vec<uint8_t> const& outParams) {
77                 fnStatus = toStatusT(status);
78                 std::copy(
79                         outParams.data(),
80                         outParams.data() + size,
81                         static_cast<uint8_t*>(params));
82             }));
83     return transStatus == NO_ERROR ? fnStatus : transStatus;
84 }
85 
setConfig(OMX_INDEXTYPE index,const void * params,size_t size)86 status_t LWOmxNode::setConfig(
87         OMX_INDEXTYPE index, const void *params, size_t size) {
88     hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
89     return toStatusT(mBase->setConfig(toRawIndexType(index), tParams));
90 }
91 
setPortMode(OMX_U32 port_index,IOMX::PortMode mode)92 status_t LWOmxNode::setPortMode(
93         OMX_U32 port_index, IOMX::PortMode mode) {
94     return toStatusT(mBase->setPortMode(port_index, toHardwarePortMode(mode)));
95 }
96 
prepareForAdaptivePlayback(OMX_U32 portIndex,OMX_BOOL enable,OMX_U32 maxFrameWidth,OMX_U32 maxFrameHeight)97 status_t LWOmxNode::prepareForAdaptivePlayback(
98         OMX_U32 portIndex, OMX_BOOL enable,
99         OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
100     return toStatusT(mBase->prepareForAdaptivePlayback(
101             portIndex, toRawBool(enable), maxFrameWidth, maxFrameHeight));
102 }
103 
configureVideoTunnelMode(OMX_U32 portIndex,OMX_BOOL tunneled,OMX_U32 audioHwSync,native_handle_t ** sidebandHandle)104 status_t LWOmxNode::configureVideoTunnelMode(
105         OMX_U32 portIndex, OMX_BOOL tunneled,
106         OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
107     status_t fnStatus;
108     status_t transStatus = toStatusT(mBase->configureVideoTunnelMode(
109             portIndex,
110             toRawBool(tunneled),
111             audioHwSync,
112             [&fnStatus, sidebandHandle](
113                     Status status, hidl_handle const& outSidebandHandle) {
114                 fnStatus = toStatusT(status);
115                 *sidebandHandle = outSidebandHandle == nullptr ?
116                         nullptr : native_handle_clone(outSidebandHandle);
117             }));
118     return transStatus == NO_ERROR ? fnStatus : transStatus;
119 }
120 
getGraphicBufferUsage(OMX_U32 portIndex,OMX_U32 * usage)121 status_t LWOmxNode::getGraphicBufferUsage(
122         OMX_U32 portIndex, OMX_U32* usage) {
123     status_t fnStatus;
124     status_t transStatus = toStatusT(mBase->getGraphicBufferUsage(
125             portIndex,
126             [&fnStatus, usage](
127                     Status status, uint32_t outUsage) {
128                 fnStatus = toStatusT(status);
129                 *usage = outUsage;
130             }));
131     return transStatus == NO_ERROR ? fnStatus : transStatus;
132 }
133 
setInputSurface(const sp<IOMXBufferSource> & bufferSource)134 status_t LWOmxNode::setInputSurface(
135         const sp<IOMXBufferSource> &bufferSource) {
136     return toStatusT(mBase->setInputSurface(
137             new TWOmxBufferSource(bufferSource)));
138 }
139 
allocateSecureBuffer(OMX_U32 portIndex,size_t size,buffer_id * buffer,void ** buffer_data,sp<NativeHandle> * native_handle)140 status_t LWOmxNode::allocateSecureBuffer(
141         OMX_U32 portIndex, size_t size, buffer_id *buffer,
142         void **buffer_data, sp<NativeHandle> *native_handle) {
143     *buffer_data = nullptr;
144     status_t fnStatus;
145     status_t transStatus = toStatusT(mBase->allocateSecureBuffer(
146             portIndex,
147             static_cast<uint64_t>(size),
148             [&fnStatus, buffer, native_handle](
149                     Status status,
150                     uint32_t outBuffer,
151                     hidl_handle const& outNativeHandle) {
152                 fnStatus = toStatusT(status);
153                 *buffer = outBuffer;
154                 *native_handle = outNativeHandle.getNativeHandle() == nullptr ?
155                         nullptr : NativeHandle::create(
156                         native_handle_clone(outNativeHandle), true);
157             }));
158     return transStatus == NO_ERROR ? fnStatus : transStatus;
159 }
160 
useBuffer(OMX_U32 portIndex,const OMXBuffer & omxBuffer,buffer_id * buffer)161 status_t LWOmxNode::useBuffer(
162         OMX_U32 portIndex, const OMXBuffer &omxBuffer, buffer_id *buffer) {
163     CodecBuffer codecBuffer;
164     if (!wrapAs(&codecBuffer, omxBuffer)) {
165         return BAD_VALUE;
166     }
167     status_t fnStatus;
168     status_t transStatus = toStatusT(mBase->useBuffer(
169             portIndex,
170             codecBuffer,
171             [&fnStatus, buffer](Status status, uint32_t outBuffer) {
172                 fnStatus = toStatusT(status);
173                 *buffer = outBuffer;
174             }));
175     return transStatus == NO_ERROR ? fnStatus : transStatus;
176 }
177 
freeBuffer(OMX_U32 portIndex,buffer_id buffer)178 status_t LWOmxNode::freeBuffer(
179         OMX_U32 portIndex, buffer_id buffer) {
180     return toStatusT(mBase->freeBuffer(portIndex, buffer));
181 }
182 
fillBuffer(buffer_id buffer,const OMXBuffer & omxBuffer,int fenceFd)183 status_t LWOmxNode::fillBuffer(
184         buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) {
185     CodecBuffer codecBuffer;
186     if (!wrapAs(&codecBuffer, omxBuffer)) {
187         return BAD_VALUE;
188     }
189     native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd);
190     if (!fenceNh) {
191         return NO_MEMORY;
192     }
193     status_t status = toStatusT(mBase->fillBuffer(
194             buffer, codecBuffer, fenceNh));
195     native_handle_close(fenceNh);
196     native_handle_delete(fenceNh);
197     return status;
198 }
199 
emptyBuffer(buffer_id buffer,const OMXBuffer & omxBuffer,OMX_U32 flags,OMX_TICKS timestamp,int fenceFd)200 status_t LWOmxNode::emptyBuffer(
201         buffer_id buffer, const OMXBuffer &omxBuffer,
202         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
203     CodecBuffer codecBuffer;
204     if (!wrapAs(&codecBuffer, omxBuffer)) {
205         return BAD_VALUE;
206     }
207     native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd);
208     if (!fenceNh) {
209         return NO_MEMORY;
210     }
211     status_t status = toStatusT(mBase->emptyBuffer(
212             buffer,
213             codecBuffer,
214             flags,
215             toRawTicks(timestamp),
216             fenceNh));
217     native_handle_close(fenceNh);
218     native_handle_delete(fenceNh);
219     return status;
220 }
getExtensionIndex(const char * parameter_name,OMX_INDEXTYPE * index)221 status_t LWOmxNode::getExtensionIndex(
222         const char *parameter_name,
223         OMX_INDEXTYPE *index) {
224     status_t fnStatus;
225     status_t transStatus = toStatusT(mBase->getExtensionIndex(
226             hidl_string(parameter_name),
227             [&fnStatus, index](Status status, uint32_t outIndex) {
228                 fnStatus = toStatusT(status);
229                 *index = toEnumIndexType(outIndex);
230             }));
231     return transStatus == NO_ERROR ? fnStatus : transStatus;
232 }
233 
dispatchMessage(const omx_message & lMsg)234 status_t LWOmxNode::dispatchMessage(const omx_message &lMsg) {
235     Message tMsg;
236     native_handle_t* nh;
237     if (!wrapAs(&tMsg, &nh, lMsg)) {
238         return NO_MEMORY;
239     }
240     status_t status = toStatusT(mBase->dispatchMessage(tMsg));
241     native_handle_close(nh);
242     native_handle_delete(nh);
243     return status;
244 }
245 
246 // TWOmxNode
TWOmxNode(sp<IOMXNode> const & base)247 TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) {
248 }
249 
freeNode()250 Return<Status> TWOmxNode::freeNode() {
251     return toStatus(mBase->freeNode());
252 }
253 
sendCommand(uint32_t cmd,int32_t param)254 Return<Status> TWOmxNode::sendCommand(uint32_t cmd, int32_t param) {
255     return toStatus(mBase->sendCommand(toEnumCommandType(cmd), param));
256 }
257 
getParameter(uint32_t index,hidl_vec<uint8_t> const & inParams,getParameter_cb _hidl_cb)258 Return<void> TWOmxNode::getParameter(
259         uint32_t index, hidl_vec<uint8_t> const& inParams,
260         getParameter_cb _hidl_cb) {
261     hidl_vec<uint8_t> params(inParams);
262     Status status = toStatus(mBase->getParameter(
263             toEnumIndexType(index),
264             static_cast<void*>(params.data()),
265             params.size()));
266     _hidl_cb(status, params);
267     return Void();
268 }
269 
setParameter(uint32_t index,hidl_vec<uint8_t> const & inParams)270 Return<Status> TWOmxNode::setParameter(
271         uint32_t index, hidl_vec<uint8_t> const& inParams) {
272     hidl_vec<uint8_t> params(inParams);
273     return toStatus(mBase->setParameter(
274             toEnumIndexType(index),
275             static_cast<void const*>(params.data()),
276             params.size()));
277 }
278 
getConfig(uint32_t index,const hidl_vec<uint8_t> & inConfig,getConfig_cb _hidl_cb)279 Return<void> TWOmxNode::getConfig(
280         uint32_t index, const hidl_vec<uint8_t>& inConfig,
281         getConfig_cb _hidl_cb) {
282     hidl_vec<uint8_t> config(inConfig);
283     Status status = toStatus(mBase->getConfig(
284             toEnumIndexType(index),
285             static_cast<void*>(config.data()),
286             config.size()));
287     _hidl_cb(status, config);
288     return Void();
289 }
290 
setConfig(uint32_t index,const hidl_vec<uint8_t> & inConfig)291 Return<Status> TWOmxNode::setConfig(
292         uint32_t index, const hidl_vec<uint8_t>& inConfig) {
293     hidl_vec<uint8_t> config(inConfig);
294     return toStatus(mBase->setConfig(
295             toEnumIndexType(index),
296             static_cast<void const*>(config.data()),
297             config.size()));
298 }
299 
setPortMode(uint32_t portIndex,PortMode mode)300 Return<Status> TWOmxNode::setPortMode(uint32_t portIndex, PortMode mode) {
301     return toStatus(mBase->setPortMode(portIndex, toIOMXPortMode(mode)));
302 }
303 
prepareForAdaptivePlayback(uint32_t portIndex,bool enable,uint32_t maxFrameWidth,uint32_t maxFrameHeight)304 Return<Status> TWOmxNode::prepareForAdaptivePlayback(
305         uint32_t portIndex, bool enable,
306         uint32_t maxFrameWidth, uint32_t maxFrameHeight) {
307     return toStatus(mBase->prepareForAdaptivePlayback(
308             portIndex,
309             toEnumBool(enable),
310             maxFrameWidth,
311             maxFrameHeight));
312 }
313 
configureVideoTunnelMode(uint32_t portIndex,bool tunneled,uint32_t audioHwSync,configureVideoTunnelMode_cb _hidl_cb)314 Return<void> TWOmxNode::configureVideoTunnelMode(
315         uint32_t portIndex, bool tunneled, uint32_t audioHwSync,
316         configureVideoTunnelMode_cb _hidl_cb) {
317     native_handle_t* sidebandHandle = nullptr;
318     Status status = toStatus(mBase->configureVideoTunnelMode(
319             portIndex,
320             toEnumBool(tunneled),
321             audioHwSync,
322             &sidebandHandle));
323     _hidl_cb(status, hidl_handle(sidebandHandle));
324     return Void();
325 }
326 
getGraphicBufferUsage(uint32_t portIndex,getGraphicBufferUsage_cb _hidl_cb)327 Return<void> TWOmxNode::getGraphicBufferUsage(
328         uint32_t portIndex, getGraphicBufferUsage_cb _hidl_cb) {
329     OMX_U32 usage;
330     Status status = toStatus(mBase->getGraphicBufferUsage(
331             portIndex, &usage));
332     _hidl_cb(status, usage);
333     return Void();
334 }
335 
setInputSurface(const sp<IOmxBufferSource> & bufferSource)336 Return<Status> TWOmxNode::setInputSurface(
337         const sp<IOmxBufferSource>& bufferSource) {
338     return toStatus(mBase->setInputSurface(new LWOmxBufferSource(
339             bufferSource)));
340 }
341 
allocateSecureBuffer(uint32_t portIndex,uint64_t size,allocateSecureBuffer_cb _hidl_cb)342 Return<void> TWOmxNode::allocateSecureBuffer(
343         uint32_t portIndex, uint64_t size,
344         allocateSecureBuffer_cb _hidl_cb) {
345     IOMX::buffer_id buffer;
346     void* bufferData;
347     sp<NativeHandle> nativeHandle;
348     Status status = toStatus(mBase->allocateSecureBuffer(
349             portIndex,
350             static_cast<size_t>(size),
351             &buffer,
352             &bufferData,
353             &nativeHandle));
354     _hidl_cb(status, buffer, nativeHandle == nullptr ?
355             nullptr : nativeHandle->handle());
356     return Void();
357 }
358 
useBuffer(uint32_t portIndex,const CodecBuffer & codecBuffer,useBuffer_cb _hidl_cb)359 Return<void> TWOmxNode::useBuffer(
360         uint32_t portIndex, const CodecBuffer& codecBuffer,
361         useBuffer_cb _hidl_cb) {
362     IOMX::buffer_id buffer;
363     OMXBuffer omxBuffer;
364     if (!convertTo(&omxBuffer, codecBuffer)) {
365         _hidl_cb(Status::BAD_VALUE, 0);
366         return Void();
367     }
368     Status status = toStatus(mBase->useBuffer(
369             portIndex, omxBuffer, &buffer));
370     _hidl_cb(status, buffer);
371     return Void();
372 }
373 
freeBuffer(uint32_t portIndex,uint32_t buffer)374 Return<Status> TWOmxNode::freeBuffer(uint32_t portIndex, uint32_t buffer) {
375     return toStatus(mBase->freeBuffer(portIndex, buffer));
376 }
377 
fillBuffer(uint32_t buffer,const CodecBuffer & codecBuffer,const hidl_handle & fence)378 Return<Status> TWOmxNode::fillBuffer(
379         uint32_t buffer, const CodecBuffer& codecBuffer,
380         const hidl_handle& fence) {
381     OMXBuffer omxBuffer;
382     if (!convertTo(&omxBuffer, codecBuffer)) {
383         return Status::BAD_VALUE;
384     }
385     return toStatus(mBase->fillBuffer(
386             buffer,
387             omxBuffer,
388             dup(native_handle_read_fd(fence))));
389 }
390 
emptyBuffer(uint32_t buffer,const CodecBuffer & codecBuffer,uint32_t flags,uint64_t timestampUs,const hidl_handle & fence)391 Return<Status> TWOmxNode::emptyBuffer(
392         uint32_t buffer, const CodecBuffer& codecBuffer, uint32_t flags,
393         uint64_t timestampUs, const hidl_handle& fence) {
394     OMXBuffer omxBuffer;
395     if (!convertTo(&omxBuffer, codecBuffer)) {
396         return Status::BAD_VALUE;
397     }
398     return toStatus(mBase->emptyBuffer(
399             buffer,
400             omxBuffer,
401             flags,
402             toOMXTicks(timestampUs),
403             dup(native_handle_read_fd(fence))));
404 }
405 
getExtensionIndex(const hidl_string & parameterName,getExtensionIndex_cb _hidl_cb)406 Return<void> TWOmxNode::getExtensionIndex(
407         const hidl_string& parameterName,
408         getExtensionIndex_cb _hidl_cb) {
409     OMX_INDEXTYPE index;
410     Status status = toStatus(mBase->getExtensionIndex(
411             parameterName.c_str(), &index));
412     _hidl_cb(status, toRawIndexType(index));
413     return Void();
414 }
415 
dispatchMessage(const Message & tMsg)416 Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) {
417     omx_message lMsg;
418     if (!convertTo(&lMsg, tMsg)) {
419         return Status::BAD_VALUE;
420     }
421     return toStatus(mBase->dispatchMessage(lMsg));
422 }
423 
424 }  // namespace utils
425 }  // namespace V1_0
426 }  // namespace omx
427 }  // namespace media
428 }  // namespace hardware
429 }  // namespace android
430