1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#include <string.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdarg.h>
32#include <ctype.h>
33
34#include "interface/vmcs_host/khronos/IL/OMX_Component.h"
35
36#include "interface/vmcs_host/vc_ilcs_defs.h"
37#include "interface/vmcs_host/vcilcs.h"
38#include "interface/vmcs_host/vcilcs_common.h"
39
40#ifndef NDEBUG
41static int is_valid_hostside_buffer(OMX_BUFFERHEADERTYPE *pBuf)
42{
43 if (!pBuf->pBuffer)
44 return 0;
45 if ((unsigned long)pBuf->pBuffer < 0x100)
46 return 0; // not believable
47 return 1;
48}
49#endif
50
51void vcil_in_get_state(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
52{
53 IL_EXECUTE_HEADER_T *exe = call;
54 IL_GET_STATE_RESPONSE_T *ret = resp;
55 OMX_COMPONENTTYPE *pComp = exe->reference;
56
57 *rlen = sizeof(IL_GET_STATE_RESPONSE_T);
58 ret->func = IL_GET_STATE;
59 ret->err = pComp->GetState(pComp, &ret->state);
60}
61
62void vcil_in_get_parameter(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
63{
64 IL_GET_EXECUTE_T *exe = call;
65 IL_GET_RESPONSE_T *ret = resp;
66 OMX_COMPONENTTYPE *pComp = exe->reference;
67 OMX_U32 size = *((OMX_U32 *) (&exe->param));
68
69 ret->func = IL_GET_PARAMETER;
70
71 if(size > VC_ILCS_MAX_PARAM_SIZE)
72 {
73 *rlen = IL_GET_RESPONSE_HEADER_SIZE;
74 ret->err = OMX_ErrorHardware;
75 }
76 else
77 {
78 *rlen = size + IL_GET_RESPONSE_HEADER_SIZE;
79 ret->err = pComp->GetParameter(pComp, exe->index, exe->param);
80 memcpy(ret->param, exe->param, size);
81 }
82}
83
84void vcil_in_set_parameter(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
85{
86 IL_SET_EXECUTE_T *exe = call;
87 IL_RESPONSE_HEADER_T *ret = resp;
88 OMX_COMPONENTTYPE *pComp = exe->reference;
89
90 *rlen = sizeof(IL_RESPONSE_HEADER_T);
91 ret->func = IL_SET_PARAMETER;
92 ret->err = pComp->SetParameter(pComp, exe->index, exe->param);
93}
94
95void vcil_in_get_config(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
96{
97 IL_GET_EXECUTE_T *exe = call;
98 IL_GET_RESPONSE_T *ret = resp;
99 OMX_COMPONENTTYPE *pComp = exe->reference;
100 OMX_U32 size = *((OMX_U32 *) (&exe->param));
101
102 ret->func = IL_GET_CONFIG;
103
104 if(size > VC_ILCS_MAX_PARAM_SIZE)
105 {
106 *rlen = IL_GET_RESPONSE_HEADER_SIZE;
107 ret->err = OMX_ErrorHardware;
108 }
109 else
110 {
111 *rlen = size + IL_GET_RESPONSE_HEADER_SIZE;
112 ret->func = IL_GET_CONFIG;
113 ret->err = pComp->GetConfig(pComp, exe->index, exe->param);
114 memcpy(ret->param, exe->param, size);
115 }
116}
117
118void vcil_in_set_config(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
119{
120 IL_SET_EXECUTE_T *exe = call;
121 IL_RESPONSE_HEADER_T *ret = resp;
122 OMX_COMPONENTTYPE *pComp = exe->reference;
123
124 *rlen = sizeof(IL_RESPONSE_HEADER_T);
125 ret->func = IL_SET_CONFIG;
126 ret->err = pComp->SetConfig(pComp, exe->index, exe->param);
127}
128
129void vcil_in_use_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
130{
131 IL_ADD_BUFFER_EXECUTE_T *exe = call;
132 IL_ADD_BUFFER_RESPONSE_T *ret = resp;
133 OMX_COMPONENTTYPE *pComp = exe->reference;
134 OMX_U8 *buffer;
135 OMX_BUFFERHEADERTYPE *bufferHeader;
136
137 *rlen = sizeof(IL_ADD_BUFFER_RESPONSE_T);
138
139 buffer = vcos_malloc_aligned(exe->size, 32, "vcin mapping buffer"); // 32-byte aligned
140 if (!buffer)
141 {
142 ret->err = OMX_ErrorInsufficientResources;
143 return;
144 }
145
146 //OMX_OSAL_Trace(OMX_OSAL_TRACE_COMPONENT, "hostcomp: use buffer(%p)\n", buffer);
147 ret->func = IL_USE_BUFFER;
148 ret->err = pComp->UseBuffer(pComp, &bufferHeader, exe->port, exe->bufferReference, exe->size, buffer);
149
150 if (ret->err == OMX_ErrorNone)
151 {
152 // we're going to pass this buffer to VC
153 // initialise our private field in their copy with the host buffer reference
154 OMX_PARAM_PORTDEFINITIONTYPE def;
155 OMX_ERRORTYPE error;
156 def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
157 def.nVersion.nVersion = OMX_VERSION;
158 def.nPortIndex = exe->port;
159 error = pComp->GetParameter(pComp, OMX_IndexParamPortDefinition, &def);
160 vc_assert(error == OMX_ErrorNone);
161
162 ret->reference = bufferHeader;
163 memcpy(&ret->bufferHeader, bufferHeader, sizeof(OMX_BUFFERHEADERTYPE));
164
165 if (def.eDir == OMX_DirInput)
166 ret->bufferHeader.pInputPortPrivate = bufferHeader;
167 else
168 ret->bufferHeader.pOutputPortPrivate = bufferHeader;
169 }
170 else
171 vcos_free(buffer);
172}
173
174void vcil_in_free_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
175{
176 IL_FREE_BUFFER_EXECUTE_T *exe = call;
177 IL_RESPONSE_HEADER_T *ret = resp;
178 OMX_COMPONENTTYPE *pComp = exe->reference;
179 OMX_BUFFERHEADERTYPE *pHeader;
180 OMX_U8 *buffer;
181 OMX_PARAM_PORTDEFINITIONTYPE def;
182 OMX_ERRORTYPE error;
183
184 def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
185 def.nVersion.nVersion = OMX_VERSION;
186 def.nPortIndex = exe->port;
187 error = pComp->GetParameter(pComp, OMX_IndexParamPortDefinition, &def);
188 vc_assert(error == OMX_ErrorNone);
189 if (def.eDir == OMX_DirInput)
190 pHeader = exe->inputPrivate;
191 else
192 pHeader = exe->outputPrivate;
193
194 buffer = pHeader->pBuffer;
195
196 *rlen = sizeof(IL_RESPONSE_HEADER_T);
197 ret->func = IL_FREE_BUFFER;
198 ret->err = pComp->FreeBuffer(pComp, exe->port, pHeader);
199 if (ret->err == OMX_ErrorNone)
200 vcos_free(buffer);
201}
202
203void vcil_in_empty_this_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
204{
205 IL_RESPONSE_HEADER_T *ret = resp;
206 OMX_COMPONENTTYPE *pComp;
207 OMX_BUFFERHEADERTYPE *pHeader;
208
209 pHeader = ilcs_receive_buffer(st->ilcs, call, clen, &pComp);
210
211 *rlen = sizeof(IL_RESPONSE_HEADER_T);
212 ret->func = IL_EMPTY_THIS_BUFFER;
213
214 if(pHeader)
215 {
216 vc_assert(is_valid_hostside_buffer(pHeader));
217 ret->err = pComp->EmptyThisBuffer(pComp, pHeader);
218 }
219 else
220 ret->err = OMX_ErrorHardware;
221}
222
223void vcil_in_fill_this_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
224{
225 IL_PASS_BUFFER_EXECUTE_T *exe = call;
226 IL_RESPONSE_HEADER_T *ret = resp;
227 OMX_COMPONENTTYPE *pComp = exe->reference;
228 OMX_BUFFERHEADERTYPE *pHeader = exe->bufferHeader.pOutputPortPrivate;
229 OMX_U8 *pBuffer = pHeader->pBuffer;
230 OMX_PTR *pAppPrivate = pHeader->pAppPrivate;
231 OMX_PTR *pPlatformPrivate = pHeader->pPlatformPrivate;
232 OMX_PTR *pInputPortPrivate = pHeader->pInputPortPrivate;
233 OMX_PTR *pOutputPortPrivate = pHeader->pOutputPortPrivate;
234
235 vc_assert(pHeader);
236 memcpy(pHeader, &exe->bufferHeader, sizeof(OMX_BUFFERHEADERTYPE));
237
238 pHeader->pBuffer = pBuffer;
239 pHeader->pAppPrivate = pAppPrivate;
240 pHeader->pPlatformPrivate = pPlatformPrivate;
241 pHeader->pInputPortPrivate = pInputPortPrivate;
242 pHeader->pOutputPortPrivate = pOutputPortPrivate;
243
244 vc_assert(is_valid_hostside_buffer(pHeader));
245
246 *rlen = sizeof(IL_RESPONSE_HEADER_T);
247 ret->func = IL_FILL_THIS_BUFFER;
248 ret->err = pComp->FillThisBuffer(pComp, pHeader);
249}
250
251void vcil_in_get_component_version(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
252{
253 IL_EXECUTE_HEADER_T *exe = call;
254 IL_GET_VERSION_RESPONSE_T *ret = resp;
255 OMX_COMPONENTTYPE *pComp = exe->reference;
256
257 *rlen = sizeof(IL_GET_VERSION_RESPONSE_T);
258 ret->func = IL_GET_COMPONENT_VERSION;
259 ret->err = pComp->GetComponentVersion(pComp, ret->name, &ret->component_version, &ret->spec_version, &ret->uuid);
260}
261
262void vcil_in_get_extension_index(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen)
263{
264 IL_GET_EXTENSION_EXECUTE_T *exe = call;
265 IL_GET_EXTENSION_RESPONSE_T *ret = resp;
266 OMX_COMPONENTTYPE *pComp = exe->reference;
267
268 *rlen = sizeof(IL_GET_EXTENSION_RESPONSE_T);
269 ret->func = IL_GET_EXTENSION_INDEX;
270 ret->err = pComp->GetExtensionIndex(pComp, exe->name, &ret->index);
271}
272