summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew F. Davis2019-07-22 12:51:14 -0500
committerAndrew F. Davis2019-07-22 13:55:56 -0500
commit2e76aaed9b8570602a9819ccd0f3351e7a359cb5 (patch)
treefdc08abf9a8649a43d1fb624d6ee50752140ce83
parentfcfc15b439d45f4c30943354f57bac70cc3b6807 (diff)
downloadhardware-ti-am57x-dev/multimedia.tar.gz
hardware-ti-am57x-dev/multimedia.tar.xz
hardware-ti-am57x-dev/multimedia.zip
libstagefrighthw: Add hardware accelerated multimedia supportdev/multimedia
Signed-off-by: Andrew F. Davis <afd@ti.com>
-rw-r--r--libstagefrighthw/Android.bp24
-rw-r--r--libstagefrighthw/TIOMXPlugin.cpp148
-rw-r--r--libstagefrighthw/TIOMXPlugin.h70
-rw-r--r--libstagefrighthw/omx/Android.bp26
-rw-r--r--libstagefrighthw/omx/OMX_Core.c570
-rw-r--r--libstagefrighthw/omx/base/Android.bp32
-rw-r--r--libstagefrighthw/omx/base/OMX_Base.c1273
-rw-r--r--libstagefrighthw/omx/base/OMX_Base.h221
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseCallbacks.c136
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseDIO.c312
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseDIONonTunnel.c648
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseDIOPlugin.h181
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseDIOTable.c28
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseInternal.c1588
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseInternal.h232
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseProcess.c355
-rw-r--r--libstagefrighthw/omx/base/OMX_BaseUtils.h60
-rw-r--r--libstagefrighthw/omx/base/OMX_TI_Custom.h109
-rw-r--r--libstagefrighthw/omx/osal/Android.bp27
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_error.h83
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_events.h47
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_memory.h37
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_mutex.h36
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_pipes.h40
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_semaphores.h38
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_task.h37
-rwxr-xr-xlibstagefrighthw/omx/osal/inc/osal_trace.h37
-rwxr-xr-xlibstagefrighthw/omx/osal/src/osal_events.c275
-rwxr-xr-xlibstagefrighthw/omx/osal/src/osal_memory.c73
-rwxr-xr-xlibstagefrighthw/omx/osal/src/osal_mutex.c107
-rwxr-xr-xlibstagefrighthw/omx/osal/src/osal_pipes.c346
-rwxr-xr-xlibstagefrighthw/omx/osal/src/osal_semaphores.c141
-rwxr-xr-xlibstagefrighthw/omx/osal/src/osal_task.c146
-rw-r--r--libstagefrighthw/omx/videodecode/Android.bp35
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder.c1725
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder.h258
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_componenttable.c31
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_componenttable.h46
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_h264.c717
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_h264.h67
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c945
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_internal.h102
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_mpeg2.c451
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_mpeg2.h68
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_mpeg4.c422
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_mpeg4.h71
-rw-r--r--libstagefrighthw/omx/videoencode/Android.bp32
-rw-r--r--libstagefrighthw/omx/videoencode/omx_video_encoder_h264.c2282
-rw-r--r--libstagefrighthw/omx/videoencode/omx_video_encoder_h264.h185
-rw-r--r--libstagefrighthw/omx/videoencode/omx_video_encoder_h264_utils.c989
-rw-r--r--libstagefrighthw/omx/videoencode/omx_video_encoder_h264_utils.h1129
51 files changed, 17038 insertions, 0 deletions
diff --git a/libstagefrighthw/Android.bp b/libstagefrighthw/Android.bp
new file mode 100644
index 0000000..2460ea2
--- /dev/null
+++ b/libstagefrighthw/Android.bp
@@ -0,0 +1,24 @@
1cc_library_shared {
2
3 name: "libstagefrighthw",
4 vendor: true,
5
6 srcs: ["TIOMXPlugin.cpp"],
7
8 include_dirs: [
9 "frameworks/native/include/media/openmax",
10 "frameworks/native/include/media/hardware",
11 ],
12
13 header_libs: ["media_plugin_headers"],
14
15 shared_libs: [
16 "libbinder",
17 "libcutils",
18 "libdl",
19 "liblog",
20 "libui",
21 "libutils",
22 ],
23
24}
diff --git a/libstagefrighthw/TIOMXPlugin.cpp b/libstagefrighthw/TIOMXPlugin.cpp
new file mode 100644
index 0000000..a69bbe8
--- /dev/null
+++ b/libstagefrighthw/TIOMXPlugin.cpp
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2009 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 "TIOMXPlugin.h"
18
19#include <dlfcn.h>
20
21#include <HardwareAPI.h>
22
23namespace android {
24
25extern "C" OMXPluginBase *createOMXPlugin()
26{
27 return new TIOMXPlugin;
28}
29
30extern "C" void destroyOMXPlugin(OMXPluginBase *plugin)
31{
32 delete plugin;
33}
34
35#define LIBOMX "libOMX.ti.ducati.core.so"
36
37TIOMXPlugin::TIOMXPlugin()
38 : mLibHandle(dlopen(LIBOMX, RTLD_NOW)),
39 mInit(NULL),
40 mDeinit(NULL),
41 mComponentNameEnum(NULL),
42 mGetHandle(NULL),
43 mFreeHandle(NULL),
44 mGetRolesOfComponentHandle(NULL)
45{
46 if (mLibHandle != NULL) {
47 mInit = (InitFunc)dlsym(mLibHandle, "OMX_Init");
48 mDeinit = (DeinitFunc)dlsym(mLibHandle, "OMX_Deinit");
49 mComponentNameEnum = (ComponentNameEnumFunc)dlsym(mLibHandle, "OMX_ComponentNameEnum");
50 mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "OMX_GetHandle");
51 mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "OMX_FreeHandle");
52 mGetRolesOfComponentHandle = (GetRolesOfComponentFunc)dlsym(mLibHandle, "OMX_GetRolesOfComponent");
53
54 (*mInit)();
55 }
56 else {
57 char const *err_str = dlerror();
58 ALOGE("failed to load %s, with error[%s]", LIBOMX, err_str ? err_str : "unknown");
59 }
60}
61
62TIOMXPlugin::~TIOMXPlugin()
63{
64 if (mLibHandle != NULL) {
65 (*mDeinit)();
66
67 dlclose(mLibHandle);
68 mLibHandle = NULL;
69 }
70}
71
72OMX_ERRORTYPE TIOMXPlugin::makeComponentInstance(
73 const char *name,
74 const OMX_CALLBACKTYPE *callbacks,
75 OMX_PTR appData,
76 OMX_COMPONENTTYPE **component) {
77 if (mLibHandle == NULL) {
78 return OMX_ErrorUndefined;
79 }
80
81 return (*mGetHandle)(
82 reinterpret_cast<OMX_HANDLETYPE *>(component),
83 const_cast<char *>(name),
84 appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
85}
86
87OMX_ERRORTYPE TIOMXPlugin::destroyComponentInstance(OMX_COMPONENTTYPE *component)
88{
89 if (mLibHandle == NULL) {
90 return OMX_ErrorUndefined;
91 }
92
93 return (*mFreeHandle)(reinterpret_cast<OMX_HANDLETYPE *>(component));
94}
95
96OMX_ERRORTYPE TIOMXPlugin::enumerateComponents(OMX_STRING name, size_t size, OMX_U32 index)
97{
98 if (mLibHandle == NULL) {
99 ALOGE("mLibHandle is NULL!");
100 return OMX_ErrorUndefined;
101 }
102
103 return (*mComponentNameEnum)(name, size, index);
104}
105
106OMX_ERRORTYPE TIOMXPlugin::getRolesOfComponent(const char *name, Vector<String8> *roles)
107{
108 roles->clear();
109
110 if (mLibHandle == NULL) {
111 return OMX_ErrorUndefined;
112 }
113
114 OMX_U32 numRoles;
115 OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)(
116 const_cast<OMX_STRING>(name), &numRoles, NULL);
117
118 if (err != OMX_ErrorNone) {
119 return err;
120 }
121
122 if (numRoles > 0) {
123 OMX_U8 **array = new OMX_U8 *[numRoles];
124 for (OMX_U32 i = 0; i < numRoles; ++i) {
125 array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
126 }
127
128 err = (*mGetRolesOfComponentHandle)(
129 const_cast<OMX_STRING>(name), &numRoles, array);
130
131 for (OMX_U32 i = 0; i < numRoles; ++i) {
132 if (err == OMX_ErrorNone) {
133 String8 s((const char *)array[i]);
134 roles->push(s);
135 }
136
137 delete[] array[i];
138 array[i] = NULL;
139 }
140
141 delete[] array;
142 array = NULL;
143 }
144
145 return err;
146}
147
148} // namespace android
diff --git a/libstagefrighthw/TIOMXPlugin.h b/libstagefrighthw/TIOMXPlugin.h
new file mode 100644
index 0000000..afbfb9c
--- /dev/null
+++ b/libstagefrighthw/TIOMXPlugin.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2009 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#ifndef TI_OMX_PLUGIN_H_
18
19#define TI_OMX_PLUGIN_H_
20
21#include <OMXPluginBase.h>
22
23namespace android {
24
25struct TIOMXPlugin : public OMXPluginBase {
26 TIOMXPlugin();
27 virtual ~TIOMXPlugin();
28
29 virtual OMX_ERRORTYPE makeComponentInstance(
30 const char *name,
31 const OMX_CALLBACKTYPE *callbacks,
32 OMX_PTR appData,
33 OMX_COMPONENTTYPE **component);
34
35 virtual OMX_ERRORTYPE destroyComponentInstance(
36 OMX_COMPONENTTYPE *component);
37
38 virtual OMX_ERRORTYPE enumerateComponents(
39 OMX_STRING name,
40 size_t size,
41 OMX_U32 index);
42
43 virtual OMX_ERRORTYPE getRolesOfComponent(
44 const char *name,
45 Vector<String8> *roles);
46
47private:
48 void *mLibHandle;
49
50 typedef OMX_ERRORTYPE (*InitFunc)();
51 typedef OMX_ERRORTYPE (*DeinitFunc)();
52 typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)(OMX_STRING, OMX_U32, OMX_U32);
53 typedef OMX_ERRORTYPE (*GetHandleFunc)(OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *);
54 typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE *);
55 typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)(OMX_STRING, OMX_U32 *, OMX_U8 **);
56
57 InitFunc mInit;
58 DeinitFunc mDeinit;
59 ComponentNameEnumFunc mComponentNameEnum;
60 GetHandleFunc mGetHandle;
61 FreeHandleFunc mFreeHandle;
62 GetRolesOfComponentFunc mGetRolesOfComponentHandle;
63
64 TIOMXPlugin(const TIOMXPlugin &);
65 TIOMXPlugin &operator=(const TIOMXPlugin &);
66};
67
68} // namespace android
69
70#endif // TI_OMX_PLUGIN_H_
diff --git a/libstagefrighthw/omx/Android.bp b/libstagefrighthw/omx/Android.bp
new file mode 100644
index 0000000..798454d
--- /dev/null
+++ b/libstagefrighthw/omx/Android.bp
@@ -0,0 +1,26 @@
1// OMX Ducati Core Library
2
3cc_library_shared {
4
5 name: "libOMX.ti.ducati.core",
6 vendor: true,
7
8 srcs: ["OMX_Core.c"],
9
10 shared_libs: [
11 "libdce",
12 "libdl",
13 "liblog",
14 "libosal",
15 "libutils",
16 ],
17
18 header_libs: ["media_plugin_headers"],
19
20 cflags: [
21 "-DBUILDOS_ANDROID",
22 "-DSTATIC_TABLE",
23 "-Wno-unused",
24 ],
25
26}
diff --git a/libstagefrighthw/omx/OMX_Core.c b/libstagefrighthw/omx/OMX_Core.c
new file mode 100644
index 0000000..9c8170f
--- /dev/null
+++ b/libstagefrighthw/omx/OMX_Core.c
@@ -0,0 +1,570 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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 "OMX_CORE"
18
19#include <dlfcn.h>
20#include <stdio.h>
21#include <string.h>
22#include <stdlib.h>
23#include <pthread.h>
24
25#include <OMX_Component.h>
26#include <OMX_Core.h>
27
28#include <memplugin.h>
29
30#include "osal_error.h"
31#include "osal_trace.h"
32#include "osal_mutex.h"
33
34#define MAX_ROLES 20
35
36typedef struct _ComponentTable {
37 OMX_STRING name;
38 OMX_U16 nRoles;
39 OMX_STRING pRoleArray[MAX_ROLES];
40}ComponentTable;
41
42/** size for the array of allocated components. Sets the maximum
43* number of components that can be allocated at once
44*/
45#define MAXCOMP (50)
46#define MAXNAMESIZE (128)
47
48/** Determine the number of elements in an array */
49#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
50
51/** Array to hold the DLL pointers for each allocated component */
52static void *pModules[MAXCOMP] = { 0 };
53
54/** Array to hold the component handles for each allocated component */
55static void *pComponents[COUNTOF(pModules)] = { 0 };
56
57/* count for call OMX_Init() */
58int count = 0;
59
60pthread_mutex_t mutex;
61void *pCoreInitMutex = NULL;
62
63ComponentTable componentTable[] =
64{
65 {
66 .name = "OMX.ti.ducati.video.decoder",
67 .nRoles = 4,
68 .pRoleArray = {
69 "video_decoder.mpeg4",
70 "video_decoder.avc",
71 "video_decoder.h263",
72 "video_decoder.mpeg2",
73 },
74 },
75 {
76 .name = "OMX.ti.ducati.video.encoder",
77 .nRoles = 1,
78 .pRoleArray = {
79 "video_encoder.avc",
80 },
81 },
82};
83
84#define MAX_CONCURRENT_INSTANCES 5 // aligned with IPUMM definitions
85int concurrent_instances = 0;
86
87#define CORE_assert(C, V, S) \
88 do { \
89 if(!(C)) { \
90 eError = V; \
91 OSAL_ErrorTrace("failed check: " # C); \
92 OSAL_ErrorTrace(" - returning error: " # V); \
93 if( S ) { \
94 OSAL_ErrorTrace(" - %s", S); \
95 }\
96 goto EXIT; \
97 }\
98 } while( 0 )
99
100static void OMX_PrintComponentTable()
101{
102 OSAL_Info("--------Component Table:: %d Components found-------------", COUNTOF(componentTable));
103
104 for( size_t i = 0; i < COUNTOF(componentTable); i++ ) {
105 OSAL_Info("%i:: %s", i, componentTable[i].name);
106
107 for( int j = 0; j < componentTable[i].nRoles; j++ ) {
108 OSAL_Info("\t%s", componentTable[i].pRoleArray[j]);
109 }
110 }
111
112 OSAL_Info("-----------------End Component Table ------------------");
113}
114
115/*
116* OMX_Init()
117*
118* Description:This method will initialize the OMX Core. It is the
119* responsibility of the application to call OMX_Init to ensure the proper
120* set up of core resources.
121*
122* Returns: OMX_NOERROR Successful
123*/
124OMX_ERRORTYPE OMX_Init()
125{
126 OMX_ERRORTYPE eError = OMX_ErrorNone;
127 OSAL_ERROR eOsalError = OSAL_ErrNone;
128
129 eOsalError = OSAL_ObtainMutex(pCoreInitMutex, OSAL_SUSPEND);
130 CORE_assert(eOsalError == OSAL_ErrNone, OMX_ErrorInsufficientResources, "Mutex lock failed");
131 count++;
132 if( count == 1 ) {
133 pthread_mutex_init(&mutex, NULL);
134 memplugin_open();
135 OMX_PrintComponentTable();
136 }
137
138 eOsalError = OSAL_ReleaseMutex(pCoreInitMutex);
139 CORE_assert(eOsalError == OSAL_ErrNone, OMX_ErrorInsufficientResources, "Mutex release failed");
140EXIT:
141 return (eError);
142}
143
144/*
145* OMX_GetHandle
146*
147* Description: This method will create the handle of the COMPONENTTYPE
148* If the component is currently loaded, this method will reutrn the
149* handle of existing component or create a new instance of the component.
150* It will call the OMX_ComponentInit function and then the setcallback
151* method to initialize the callback functions
152* Parameters:
153* @param[out] pHandle Handle of the loaded components
154* @param[in] cComponentName Name of the component to load
155* @param[in] pAppData Used to identify the callbacks of component
156* @param[in] pCallBacks Application callbacks
157*
158* @retval OMX_ErrorUndefined
159* @retval OMX_ErrorInvalidComponentName
160* @retval OMX_ErrorInvalidComponent
161* @retval OMX_ErrorInsufficientResources
162* @retval OMX_NOERROR Successful
163*/
164OMX_ERRORTYPE OMX_GetHandle(OMX_HANDLETYPE *pHandle,
165 OMX_STRING cComponentName,
166 OMX_PTR pAppData,
167 OMX_CALLBACKTYPE *pCallBacks)
168{
169 static const char prefix[] = "lib";
170 static const char postfix[] = ".so";
171
172 OMX_ERRORTYPE (*pComponentInit)(OMX_HANDLETYPE *);
173 OMX_ERRORTYPE eError = OMX_ErrorNone;
174 OMX_COMPONENTTYPE *componentType;
175 int i;
176 char buf[sizeof(prefix) + MAXNAMESIZE + sizeof(postfix)];
177 const char *pErr = dlerror();
178 char *dlError = NULL;
179 if (pthread_mutex_lock(&mutex) != 0) {
180 OSAL_ErrorTrace("Core: Error in Mutex lock");
181 }
182
183 CORE_assert(NULL != cComponentName, OMX_ErrorBadParameter, NULL);
184 CORE_assert(NULL != pHandle, OMX_ErrorBadParameter, NULL);
185 CORE_assert(NULL != pCallBacks, OMX_ErrorBadParameter, NULL);
186 CORE_assert(count > 0, OMX_ErrorUndefined, "OMX_GetHandle called without calling OMX_Init first");
187 CORE_assert(concurrent_instances < MAX_CONCURRENT_INSTANCES, OMX_ErrorInsufficientResources, "Max Concurrent Instances reached");
188
189 concurrent_instances++;
190
191 /* Verify that the name is not too long and could cause a crash. Notice
192 * that the comparison is a greater than or equals. This is to make
193 * sure that there is room for the terminating NULL at the end of the
194 * name. */
195 CORE_assert(strlen(cComponentName) < MAXNAMESIZE, OMX_ErrorInvalidComponentName, NULL);
196
197 /* Locate the first empty slot for a component. If no slots
198 * are available, error out */
199 for (i = 0; i < (int) COUNTOF(pModules); i++) {
200 if (pModules[i] == NULL) {
201 break;
202 }
203 }
204
205 CORE_assert(i != COUNTOF(pModules), OMX_ErrorInsufficientResources, NULL);
206
207 strcpy(buf, prefix); /* the lengths are defined herein or have been */
208 strcat(buf, cComponentName); /* checked already, so strcpy and strcat are */
209 strcat(buf, postfix); /* are safe to use in this context. */
210
211 pModules[i] = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
212 if (pModules[i] == NULL) {
213 dlError = (char *) dlerror();
214 OSAL_ErrorTrace("Failed because %s", dlError);
215 eError = OMX_ErrorComponentNotFound;
216 goto EXIT;
217 }
218
219 pComponentInit = dlsym(pModules[i], "OMX_ComponentInit");
220 pErr = dlerror();
221 CORE_assert(((pErr == NULL) && (pComponentInit != NULL)), OMX_ErrorInvalidComponent, NULL);
222
223 /* We now can access the library. So, we need to call the "OMX_ComponentInit"
224 * method to load up the "handle" (which is just a list of functions to
225 * call) and we should be all set.
226 */
227 *pHandle = malloc(sizeof(OMX_COMPONENTTYPE));
228 CORE_assert((*pHandle != NULL), OMX_ErrorInsufficientResources, "Malloc of pHandle* failed");
229
230 pComponents[i] = *pHandle;
231 componentType = (OMX_COMPONENTTYPE *) *pHandle;
232 componentType->nSize = sizeof(OMX_COMPONENTTYPE);
233
234 componentType->nVersion.s.nVersionMajor = 1;
235 componentType->nVersion.s.nVersionMinor = 1;
236 componentType->nVersion.s.nRevision = 0;
237 componentType->nVersion.s.nStep = 0;
238
239 eError = (*pComponentInit)(*pHandle);
240 if (OMX_ErrorNone == eError) {
241 eError = (componentType->SetCallbacks)(*pHandle, pCallBacks, pAppData);
242 CORE_assert(eError == OMX_ErrorNone, eError, "Core: Error returned from component SetCallBack");
243 } else {
244 /* when the component fails to initialize, release the
245 component handle structure */
246 free(*pHandle);
247 /* mark the component handle as NULL to prevent the caller from
248 actually trying to access the component with it, should they
249 ignore the return code */
250 *pHandle = NULL;
251 pComponents[i] = NULL;
252 dlclose(pModules[i]);
253 pModules[i] = NULL;
254 goto EXIT;
255 }
256
257EXIT:
258 if (pthread_mutex_unlock(&mutex) != 0) {
259 OSAL_ErrorTrace("Core: Error in Mutex unlock");
260 }
261 return (eError);
262}
263
264/*
265* OMX_FreeHandle()
266*
267* Description:This method will unload the OMX component pointed by
268* OMX_HANDLETYPE. It is the responsibility of the calling method to ensure that
269* the Deinit method of the component has been called prior to unloading component
270*
271* Parameters:
272* @param[in] hComponent the component to unload
273*
274* Returns: OMX_NOERROR Successful
275*/
276OMX_ERRORTYPE OMX_FreeHandle(OMX_HANDLETYPE hComponent)
277{
278 OMX_ERRORTYPE eError = OMX_ErrorUndefined;
279 int i;
280
281 if (pthread_mutex_lock(&mutex) != 0) {
282 OSAL_ErrorTrace("Core: Error in Mutex lock");
283 }
284
285 CORE_assert(hComponent != NULL, OMX_ErrorBadParameter, NULL);
286 CORE_assert(count > 0, OMX_ErrorUndefined, "OMX_FreeHandle called without calling OMX_Init first");
287
288 /* Locate the component handle in the array of handles */
289 for (i = 0; i < (int) COUNTOF(pModules); i++) {
290 if (pComponents[i] == hComponent) {
291 break;
292 }
293 }
294 CORE_assert(i != COUNTOF(pModules), OMX_ErrorBadParameter, NULL);
295
296 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *) hComponent;
297 eError = pHandle->ComponentDeInit(hComponent);
298 if (eError != OMX_ErrorNone) {
299 OSAL_ErrorTrace("Error From ComponentDeInit..");
300 }
301
302 /* release the component and the component handle */
303 dlclose(pModules[i]);
304 pModules[i] = NULL;
305 free(pComponents[i]);
306
307 pComponents[i] = NULL;
308
309 concurrent_instances--;
310 eError = OMX_ErrorNone;
311
312 EXIT:
313 /* The unload is now complete, so set the error code to pass and exit */
314 if (pthread_mutex_unlock(&mutex) != 0) {
315 OSAL_ErrorTrace("Core: Error in Mutex unlock");
316 }
317
318 return (eError);
319}
320
321/*
322* OMX_DeInit()
323*
324* Description: This method will release the resources of the OMX Core. It is the
325* responsibility of the application to call OMX_DeInit to ensure the clean up of these
326* resources.
327*
328* Returns: OMX_NOERROR Successful
329*/
330OMX_ERRORTYPE OMX_Deinit()
331{
332 OMX_ERRORTYPE eError = OMX_ErrorNone;
333 OSAL_ERROR eOsalError = OSAL_ErrNone;
334
335 eOsalError = OSAL_ObtainMutex(pCoreInitMutex, OSAL_SUSPEND);
336 if (eOsalError != OSAL_ErrNone) {
337 OSAL_ErrorTrace("Mutex lock failed");
338 }
339 /*Returning error none because of OMX spec limitation on error codes that
340 can be returned by OMX_Deinit */
341 CORE_assert(count > 0, OMX_ErrorNone, "OMX_Deinit being called without a corresponding OMX_Init");
342 count--;
343
344 if (pthread_mutex_lock(&mutex) != 0) {
345 OSAL_ErrorTrace("Core: Error in Mutex lock");
346 }
347
348 if (count == 0) {
349 memplugin_close();
350 if (pthread_mutex_unlock(&mutex) != 0) {
351 OSAL_ErrorTrace("Core: Error in Mutex unlock");
352 }
353 if (pthread_mutex_destroy(&mutex) != 0) {
354 OSAL_ErrorTrace("%d :: Core: Error in Mutex destroy\n", __LINE__);
355 }
356 } else {
357 if (pthread_mutex_unlock(&mutex) != 0) {
358 OSAL_ErrorTrace("Core: Error in Mutex unlock");
359 }
360 }
361
362EXIT:
363 eOsalError = OSAL_ReleaseMutex(pCoreInitMutex);
364 if (eOsalError != OSAL_ErrNone) {
365 OSAL_ErrorTrace("Mutex release failed");
366 }
367 return (eError);
368}
369
370/*
371* OMX_SetupTunnel()
372*
373* Description: Setup the specified tunnel the two components
374*
375* Parameters:
376* @param[in] hOutput Handle of the component to be accessed
377* @param[in] nPortOutput Source port used in the tunnel
378* @param[in] hInput Component to setup the tunnel with.
379* @param[in] nPortInput Destination port used in the tunnel
380*
381* Returns: OMX_NOERROR Successful
382*/
383OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE hOutput,
384 OMX_IN OMX_U32 nPortOutput,
385 OMX_IN OMX_HANDLETYPE hInput,
386 OMX_IN OMX_U32 nPortInput)
387{
388 OMX_ERRORTYPE eError = OMX_ErrorNone;
389 OMX_COMPONENTTYPE *pCompOut = (OMX_COMPONENTTYPE *) hOutput;
390 OMX_COMPONENTTYPE *pCompIn = (OMX_COMPONENTTYPE *) hInput;
391 OMX_TUNNELSETUPTYPE oTunnelSetup;
392
393 if (hOutput == NULL && hInput == NULL) {
394 return (OMX_ErrorBadParameter);
395 }
396
397 oTunnelSetup.nTunnelFlags = 0;
398 oTunnelSetup.eSupplier = OMX_BufferSupplyUnspecified;
399
400 if (hOutput) {
401 eError = pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, hInput, nPortInput, &oTunnelSetup);
402 if (eError != OMX_ErrorNone)
403 return eError;
404 }
405
406 if (hInput) {
407 eError = pCompIn->ComponentTunnelRequest(hInput, nPortInput, hOutput, nPortOutput, &oTunnelSetup);
408 if (eError != OMX_ErrorNone && hOutput) {
409 /* cancel tunnel request on output port since input port failed */
410 pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, NULL, 0, NULL);
411 }
412 }
413 return (eError);
414}
415
416/*
417* OMX_ComponentNameEnum()
418*
419* Description: This method will provide the name of the component at the given nIndex
420*
421* Parameters:
422* @param[out] cComponentName The name of the component at nIndex
423* @param[in] nNameLength The length of the component name
424* @param[in] nIndex The index number of the component
425*
426* Returns: OMX_NOERROR Successful
427*/
428OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(OMX_OUT OMX_STRING cComponentName,
429 OMX_IN OMX_U32 nNameLength,
430 OMX_IN OMX_U32 nIndex)
431{
432 OMX_ERRORTYPE eError = OMX_ErrorNone;
433
434 CORE_assert(cComponentName != NULL, OMX_ErrorBadParameter, NULL);
435 CORE_assert(count > 0, OMX_ErrorUndefined, "OMX_GetHandle called without calling OMX_Init first");
436
437 if (nIndex >= (OMX_U32) COUNTOF(componentTable)) {
438 eError = OMX_ErrorNoMore;
439 } else if (strlen(componentTable[nIndex].name) >= nNameLength) {
440 eError = OMX_ErrorBadParameter;
441 } else {
442 strcpy(cComponentName, componentTable[nIndex].name);
443 }
444
445EXIT:
446 return (eError);
447}
448
449/*
450* OMX_GetRolesOfComponent()
451*
452* Description: This method will query the component for its supported roles
453*
454* Parameters:
455* @param[in] cComponentName The name of the component to query
456* @param[in] pNumRoles The number of roles supported by the component
457* @param[in] roles The roles of the component
458*
459* Returns: OMX_NOERROR Successful
460* OMX_ErrorBadParameter Failure due to a bad input parameter
461*/
462OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent(OMX_IN OMX_STRING cComponentName,
463 OMX_INOUT OMX_U32 *pNumRoles,
464 OMX_OUT OMX_U8 **roles)
465{
466 OMX_ERRORTYPE eError = OMX_ErrorNone;
467 OMX_BOOL bFound = OMX_FALSE;
468 OMX_U32 index = 0;
469
470 CORE_assert(cComponentName != NULL, OMX_ErrorBadParameter, NULL);
471 CORE_assert(pNumRoles != NULL, OMX_ErrorBadParameter, NULL);
472 CORE_assert(strlen(cComponentName) < MAXNAMESIZE, OMX_ErrorInvalidComponentName, NULL);
473 CORE_assert(count > 0, OMX_ErrorUndefined, "OMX_GetHandle called without calling OMX_Init first");
474
475 /* Locate the component in the component table */
476 for (index = 0; index < (OMX_U32) COUNTOF(componentTable); index++) {
477 if (strcmp(cComponentName, componentTable[index].name) == 0) {
478 break;
479 }
480 }
481 CORE_assert(index != COUNTOF(componentTable), OMX_ErrorComponentNotFound, NULL);
482
483 // just getting component's role count this call
484 if (roles == NULL) {
485 *pNumRoles = componentTable[index].nRoles;
486 goto EXIT;
487 }
488
489 // requested too many roles from this component
490 if (*pNumRoles > componentTable[index].nRoles) {
491 eError = OMX_ErrorBadParameter;
492 goto EXIT;
493 }
494
495 for (size_t j = 0; j < *pNumRoles; j++) {
496 strcpy((OMX_STRING) roles[j], componentTable[index].pRoleArray[j]);
497 }
498
499EXIT:
500 return (eError);
501}
502
503/*
504* OMX_GetComponentsOfRole()
505*
506* Description: This method will query the component for its supported roles
507*
508* Parameters:
509* @param[in] role The role name to query for
510* @param[in] pNumComps The number of components supporting the given role
511* @param[in] compNames The names of the components supporting the given role
512*
513* Returns: OMX_NOERROR Successful
514*/
515OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole(OMX_IN OMX_STRING role,
516 OMX_INOUT OMX_U32 *pNumComps,
517 OMX_INOUT OMX_U8 **compNames)
518{
519 OMX_ERRORTYPE eError = OMX_ErrorNone;
520
521 CORE_assert(role != NULL, OMX_ErrorBadParameter, NULL);
522 CORE_assert(pNumComps != NULL, OMX_ErrorBadParameter, NULL);
523 CORE_assert(count > 0, OMX_ErrorUndefined, "OMX_GetHandle called without calling OMX_Init first");
524
525 *pNumComps = 0;
526
527 for (size_t i = 0; i < (OMX_U32) COUNTOF(componentTable); i++) {
528 for (size_t j = 0; j < componentTable[i].nRoles; j++) {
529 if (strcmp(componentTable[i].pRoleArray[j], role) == 0) {
530 /* the first call to this function should only count the number
531 of roles so that for the second call compNames can be allocated
532 with the proper size for that number of roles */
533 if (compNames != NULL) {
534 strncpy((OMX_STRING) (compNames[*pNumComps]), (OMX_STRING) componentTable[i].name, MAXNAMESIZE);
535 }
536 (*pNumComps)++;
537 }
538 }
539 }
540
541 EXIT:
542 return (eError);
543}
544
545/*
546 * @fn Core_Setup : This function is called when the the OMX Core library is
547 * loaded. It creates a mutex, which is used during OMX_Init()
548 */
549void __attribute__ ((constructor)) Core_Setup(void)
550{
551 OSAL_ERROR eError = OSAL_ErrNone;
552 eError = OSAL_CreateMutex(&pCoreInitMutex);
553 if( eError != OSAL_ErrNone ) {
554 OSAL_ErrorTrace("Creation of default mutex failed");
555 }
556}
557
558/*
559 * @fn Core_Destroy : This function is called when the the OMX Core library is
560 * unloaded. It destroys the mutex which was created by
561 * Core_Setup().
562 */
563void __attribute__ ((destructor)) Core_Destroy(void)
564{
565 OSAL_ERROR eError = OSAL_ErrNone;
566 eError = OSAL_DeleteMutex(pCoreInitMutex);
567 if( eError != OSAL_ErrNone ) {
568 OSAL_ErrorTrace("Destruction of default mutex failed");
569 }
570}
diff --git a/libstagefrighthw/omx/base/Android.bp b/libstagefrighthw/omx/base/Android.bp
new file mode 100644
index 0000000..898ddde
--- /dev/null
+++ b/libstagefrighthw/omx/base/Android.bp
@@ -0,0 +1,32 @@
1// OMX Ducati Common Base Library
2
3cc_library_shared {
4
5 name: "libOMX.ti.ducati.base",
6 vendor: true,
7
8 srcs: [
9 "OMX_Base.c",
10 "OMX_BaseCallbacks.c",
11 "OMX_BaseInternal.c",
12 "OMX_BaseProcess.c",
13 "OMX_BaseDIO.c",
14 "OMX_BaseDIOTable.c",
15 "OMX_BaseDIONonTunnel.c",
16 ],
17
18 export_include_dirs: ["."],
19 header_libs: ["media_plugin_headers"],
20
21 shared_libs: [
22 "libosal",
23 "libc",
24 "liblog",
25 "libcutils",
26 "libutils",
27 "libdce",
28 ],
29
30 cflags: ["-DBUILDOS_ANDROID"],
31
32}
diff --git a/libstagefrighthw/omx/base/OMX_Base.c b/libstagefrighthw/omx/base/OMX_Base.c
new file mode 100644
index 0000000..658da36
--- /dev/null
+++ b/libstagefrighthw/omx/base/OMX_Base.c
@@ -0,0 +1,1273 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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 "OMX_BASE"
18
19#include <string.h>
20
21#include <OMX_Core.h>
22#include <OMX_Component.h>
23#include <OMX_Base.h>
24#include <OMX_TI_Custom.h>
25
26/**
27* OMX BaseComponent Init
28*/
29OMX_ERRORTYPE OMXBase_ComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
30{
31 OMX_ERRORTYPE eError = OMX_ErrorNone, eTmpError = OMX_ErrorNone;
32 OSAL_ERROR tStatus = OSAL_ErrNone;
33 OMX_COMPONENTTYPE *pComp = NULL;
34 OMXBaseComp *pBaseComp = NULL;
35
36 OMX_CHECK(hComponent != NULL, OMX_ErrorBadParameter);
37 pComp = (OMX_COMPONENTTYPE *)hComponent;
38 pBaseComp = (OMXBaseComp*)pComp->pComponentPrivate;
39 OMX_CHECK(pBaseComp != NULL, OMX_ErrorBadParameter);
40
41 /* populate component specific function pointers */
42 pComp->GetComponentVersion = OMXBase_GetComponentVersion;
43 pComp->SendCommand = OMXBase_SendCommand;
44 pComp->GetParameter = OMXBase_GetParameter;
45 pComp->SetParameter = OMXBase_SetParameter;
46 pComp->GetConfig = OMXBase_GetConfig;
47 pComp->SetConfig = OMXBase_SetConfig;
48 pComp->GetExtensionIndex = OMXBase_GetExtensionIndex;
49 pComp->GetState = OMXBase_GetState;
50 pComp->ComponentTunnelRequest = NULL;
51 pComp->UseBuffer = OMXBase_UseBuffer;
52 pComp->AllocateBuffer = OMXBase_AllocateBuffer;
53 pComp->FreeBuffer = OMXBase_FreeBuffer;
54 pComp->EmptyThisBuffer = OMXBase_EmptyThisBuffer;
55 pComp->FillThisBuffer = OMXBase_FillThisBuffer;
56 pComp->SetCallbacks = OMXBase_SetCallbacks;
57 pComp->ComponentDeInit = OMXBase_ComponentDeinit;
58 pComp->UseEGLImage = OMXBase_UseEGLImage;
59 pComp->ComponentRoleEnum = OMXBase_ComponentRoleEnum;
60
61 pBaseComp->fpReturnEventNotify = OMXBase_CB_ReturnEventNotify;
62
63 /* create a mutex to handle race conditions */
64 tStatus = OSAL_CreateMutex(&(pBaseComp->pMutex));
65 if(OSAL_ErrNone != tStatus) {
66 return OMX_ErrorInsufficientResources;
67 }
68
69 /* Allocate internal area for Base component */
70 pBaseComp->pPvtData = (OMXBaseComp_Pvt*)OSAL_Malloc(sizeof(OMXBaseComp_Pvt));
71 OMX_CHECK(pBaseComp->pPvtData != NULL, OMX_ErrorInsufficientResources);
72
73 OSAL_Memset(pBaseComp->pPvtData, 0, sizeof(OMXBaseComp_Pvt));
74 eError = OMXBase_PrivateInit(hComponent);
75 OMX_CHECK(OMX_ErrorNone == eError, eError);
76
77 /* Initialize ports */
78 eError = OMXBase_InitializePorts(hComponent);
79 OMX_CHECK(OMX_ErrorNone == eError, eError);
80
81 /* Component is initialized successfully, set the
82 * component to loaded state */
83 pBaseComp->tCurState = OMX_StateLoaded;
84 pBaseComp->tNewState = OMX_StateMax;
85
86
87EXIT:
88 /* incase of an error, deinitialize the component */
89 if((OMX_ErrorNone != eError) && (pComp != NULL)) {
90 eTmpError = eError;
91 eError = pComp->ComponentDeInit(hComponent);
92 eError = eTmpError;
93 }
94 return (eError);
95}
96
97/*
98* SetCallbacks
99*/
100OMX_ERRORTYPE OMXBase_SetCallbacks(OMX_HANDLETYPE hComponent,
101 OMX_CALLBACKTYPE *pCallbacks,
102 OMX_PTR pAppData)
103{
104 OMX_ERRORTYPE eError = OMX_ErrorNone;
105 OMX_COMPONENTTYPE *pComp = NULL;
106 OMXBaseComp *pBaseComp = NULL;
107 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
108 OMX_U32 i = 0;
109
110 OMX_CHECK((hComponent != NULL) &&
111 (pCallbacks != NULL), OMX_ErrorBadParameter);
112
113 pComp = (OMX_COMPONENTTYPE *)hComponent;
114 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
115 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
116
117 pComp->pApplicationPrivate = pAppData;
118 pBaseCompPvt->sAppCallbacks = *pCallbacks;
119
120 for( i = 0; i < pBaseComp->nNumPorts; i++ ) {
121 pBaseComp->pPorts[i]->bIsBufferAllocator = OMX_FALSE;
122 }
123
124EXIT:
125 return (eError);
126}
127
128/*
129* GetComponent Version
130*/
131OMX_ERRORTYPE OMXBase_GetComponentVersion(OMX_HANDLETYPE hComponent,
132 OMX_STRING pComponentName,
133 OMX_VERSIONTYPE *pComponentVersion,
134 OMX_VERSIONTYPE *pSpecVersion,
135 OMX_UUIDTYPE *pComponentUUID)
136{
137 OMX_ERRORTYPE eError = OMX_ErrorNone;
138 OMX_COMPONENTTYPE *pComp = NULL;
139 OMXBaseComp *pBaseComp = NULL;
140 (void)pComponentUUID;
141
142 OMX_CHECK((hComponent != NULL) &&
143 (pComponentName != NULL) &&
144 (pComponentVersion != NULL) &&
145 (pSpecVersion != NULL), OMX_ErrorBadParameter);
146
147 pComp = (OMX_COMPONENTTYPE *)hComponent;
148 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
149
150 /*Can't be invoked when the comp is in invalid state*/
151 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState, OMX_ErrorInvalidState);
152
153 OSAL_Memcpy(pComponentName, pBaseComp->cComponentName, OMX_MAX_STRINGNAME_SIZE);
154
155 *pComponentVersion = pBaseComp->nComponentVersion;
156 *pSpecVersion = pComp->nVersion;
157
158EXIT:
159 return (eError);
160}
161
162/*
163* GetState
164*/
165OMX_ERRORTYPE OMXBase_GetState(OMX_HANDLETYPE hComponent,
166 OMX_STATETYPE *pState)
167{
168 OMX_ERRORTYPE eError = OMX_ErrorNone;
169 OMX_COMPONENTTYPE *pComp = NULL;
170 OMXBaseComp *pBaseComp = NULL;
171
172 OMX_CHECK((hComponent != NULL) &&
173 (pState != NULL), OMX_ErrorBadParameter);
174
175 pComp = (OMX_COMPONENTTYPE *)hComponent;
176 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
177
178 *pState = pBaseComp->tCurState;
179
180EXIT:
181 return (eError);
182}
183
184/*
185* Base Component DeInit
186*/
187OMX_ERRORTYPE OMXBase_ComponentDeinit(OMX_HANDLETYPE hComponent)
188{
189 OMX_ERRORTYPE eError = OMX_ErrorNone, eTmpError = OMX_ErrorNone;
190 OSAL_ERROR tStatus = OSAL_ErrNone;
191 OMX_COMPONENTTYPE *pComp = NULL;
192 OMXBaseComp *pBaseComp = NULL;
193 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
194 OMXBase_Port *pPort = NULL;
195 OMX_U32 i = 0;
196
197 OMX_CHECK(hComponent != NULL, OMX_ErrorBadParameter);
198 pComp = (OMX_COMPONENTTYPE *)hComponent;
199 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
200 OMX_CHECK(pBaseComp != NULL, OMX_ErrorBadParameter);
201 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
202
203 OSAL_ObtainMutex(pBaseComp->pMutex, OSAL_SUSPEND);
204
205 /*If component transitioned to invalid state suddenly then dio close and
206 deinit might have not been called - in that case calle them now */
207 if( pBaseComp->tCurState != OMX_StateLoaded ) {
208 for( i=0; i < pBaseComp->nNumPorts; i++ ) {
209 pPort = pBaseComp->pPorts[i];
210 if( pPort != NULL ) {
211 if( pPort->hDIO != NULL ) {
212 eTmpError = OMXBase_DIO_Close(hComponent,
213 (i + pBaseComp->nMinStartPortIndex));
214 if( eTmpError != OMX_ErrorNone ) {
215 eError = eTmpError;
216 }
217 eTmpError = OMXBase_DIO_Deinit(hComponent,
218 (i + pBaseComp->nMinStartPortIndex));
219 if( eTmpError != OMX_ErrorNone ) {
220 eError = eTmpError;
221 }
222 }
223 }
224 }
225 }
226
227 /* deinitialize ports and freeup the memory */
228 eTmpError = OMXBase_DeinitializePorts(hComponent);
229 if( eTmpError != OMX_ErrorNone ) {
230 eError = eTmpError;
231 }
232
233 OSAL_ReleaseMutex(pBaseComp->pMutex);
234
235 if (pBaseCompPvt) {
236 OMXBase_PrivateDeInit(hComponent);
237 }
238
239 tStatus = OSAL_DeleteMutex(pBaseComp->pMutex);
240 if( tStatus != OSAL_ErrNone ) {
241 eError = OMX_ErrorUndefined;
242 }
243 pBaseComp->pMutex = NULL;
244
245 OSAL_Free(pBaseCompPvt);
246 pBaseCompPvt = NULL;
247
248EXIT:
249 return (eError);
250}
251
252/*
253* OMXBase SendCommand
254*/
255OMX_ERRORTYPE OMXBase_SendCommand(OMX_HANDLETYPE hComponent,
256 OMX_COMMANDTYPE Cmd,
257 OMX_U32 nParam1,
258 OMX_PTR pCmdData)
259{
260 OMX_ERRORTYPE eError = OMX_ErrorNone;
261 OSAL_ERROR tStatus = OSAL_ErrNone;
262 OMX_COMPONENTTYPE *pComp = NULL;
263 OMXBaseComp *pBaseComp = NULL;
264 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
265 OMXBase_Port *pPort = NULL;
266 OMXBase_CmdParams sCmdParams, sErrorCmdParams;
267 OMX_U32 nPorts, nStartPortNumber, nIndex;
268 OMX_PTR pLocalCmdData = NULL;
269 OMX_BOOL bFreeCmdDataIfError = OMX_TRUE;
270 OMX_U32 i = 0;
271 uint32_t nActualSize = 0, nCmdCount = 0;
272
273 OMX_CHECK(hComponent != NULL, OMX_ErrorBadParameter);
274 if( OMX_CommandMarkBuffer == Cmd ) {
275 OMX_CHECK(pCmdData != NULL, OMX_ErrorBadParameter);
276 }
277 pComp = (OMX_COMPONENTTYPE *)hComponent;
278 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
279 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
280
281 nPorts = pBaseComp->nNumPorts;
282 nStartPortNumber = pBaseComp->nMinStartPortIndex;
283
284 /*Can't be invoked when the comp is in invalid state*/
285 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState, OMX_ErrorInvalidState);
286
287 switch( Cmd ) {
288 case OMX_CommandStateSet :
289 /*Return error if unknown state is provided*/
290 OMX_CHECK(((OMX_STATETYPE)nParam1 <=
291 OMX_StateWaitForResources), OMX_ErrorBadParameter);
292
293 /*Mutex protection is for multiple SendCommands on the same
294 component parallely. This can especially happen in error handling
295 scenarios. Mutex protection ensure that the NewState variable is not
296 overwritten.*/
297 OSAL_ObtainMutex(pBaseCompPvt->pNewStateMutex,
298 OSAL_SUSPEND);
299 /*Multiple state transitions at the same time is not allowed.
300 Though it is allowed by the spec, we prohibit it in our
301 implementation*/
302 if( OMX_StateMax != pBaseComp->tNewState ) {
303 eError = OMX_ErrorIncorrectStateTransition;
304 OSAL_ReleaseMutex(pBaseCompPvt->pNewStateMutex);
305 goto EXIT;
306 }
307 pBaseComp->tNewState = (OMX_STATETYPE)nParam1;
308 OSAL_ReleaseMutex(pBaseCompPvt->pNewStateMutex);
309 break;
310
311 case OMX_CommandPortDisable :
312 /* Index of the port to disable should be less than
313 * no of ports or equal to OMX_ALL */
314 OMX_CHECK((nParam1 < (nStartPortNumber + nPorts)) ||
315 (nParam1 == OMX_ALL), OMX_ErrorBadPortIndex);
316 if( OMX_ALL == nParam1 ) {
317 /*Dont want to return same port state error if it never enters
318 the for loop*/
319 if( nPorts > 0 ) {
320 eError = (OMX_ERRORTYPE)OMX_ErrorNone;
321 }
322
323 for( nIndex = 0; nIndex < nPorts; nIndex++ ) {
324 pPort = pBaseComp->pPorts[nIndex];
325 /*Atleast 1 port is enabled - dont send same port state error*/
326 if( pPort->sPortDef.bEnabled ) {
327 pPort->sPortDef.bEnabled = OMX_FALSE;
328 pPort->bIsInTransition = OMX_TRUE;
329 eError = OMX_ErrorNone;
330 }
331 }
332 } else {
333 nIndex = nParam1 - nStartPortNumber;
334 pPort = pBaseComp->pPorts[nIndex];
335 if( pPort->sPortDef.bEnabled ) {
336 pPort->sPortDef.bEnabled = OMX_FALSE;
337 pPort->bIsInTransition = OMX_TRUE;
338 } else {
339 eError = (OMX_ERRORTYPE)OMX_ErrorNone;
340 }
341 }
342 break;
343
344 case OMX_CommandPortEnable :
345 /* Index of the port to enable should be less than
346 * no of ports or equal to OMX_ALL */
347 OMX_CHECK((nParam1 < (nStartPortNumber + nPorts)) ||
348 (nParam1 == OMX_ALL), OMX_ErrorBadPortIndex);
349 if( OMX_ALL == nParam1 ) {
350 /*Dont want to return same port state error if it never enters
351 the for loop*/
352 if( nPorts > 0 ) {
353 eError = (OMX_ERRORTYPE)OMX_ErrorNone;
354 }
355
356 for( nIndex = 0; nIndex < nPorts; nIndex++ ) {
357 pPort = pBaseComp->pPorts[nIndex];
358 /*Atleast 1 port is disabled - dont send same port state error*/
359 if( !pPort->sPortDef.bEnabled ) {
360 eError = OMX_ErrorNone;
361 pPort->sPortDef.bEnabled = OMX_TRUE;
362 pPort->bIsInTransition = OMX_TRUE;
363 }
364 }
365 } else {
366 nIndex = nParam1 - nStartPortNumber;
367 pPort = pBaseComp->pPorts[nIndex];
368 if( !pPort->sPortDef.bEnabled ) {
369 pPort->sPortDef.bEnabled = OMX_TRUE;
370 pPort->bIsInTransition = OMX_TRUE;
371 } else {
372 eError = (OMX_ERRORTYPE)OMX_ErrorNone;
373 }
374 }
375 break;
376
377 case OMX_CommandMarkBuffer :
378 /*For mark buffer pCmdData points to a structure of type OMX_MARKTYPE.
379 This may not be valid once send commmand returns so allocate memory and
380 copy this info there. This memory will be freed up during the command
381 complete callback for mark buffer.*/
382 OMX_CHECK((nParam1 < (nStartPortNumber + nPorts)) ||
383 (nParam1 == OMX_ALL), OMX_ErrorBadPortIndex);
384 pLocalCmdData = OSAL_Malloc(sizeof(OMX_MARKTYPE));
385 OMX_CHECK(pLocalCmdData != NULL, OMX_ErrorInsufficientResources);
386 OSAL_Memcpy(pLocalCmdData, pCmdData, sizeof(OMX_MARKTYPE));
387 break;
388
389 case OMX_CommandFlush :
390 OMX_CHECK((nParam1 < (nStartPortNumber + nPorts)) ||
391 (nParam1 == OMX_ALL), OMX_ErrorBadPortIndex);
392 break;
393
394 default :
395 OMX_CHECK(OMX_FALSE, OMX_ErrorBadParameter);
396 }
397
398 /*Return error if port enable/disable command is sent on an already
399 enabled/disabled port*/
400 OMX_CHECK(eError == OMX_ErrorNone, eError);
401 /*For mark buffer store pCmdData in a separate pipe - to be freed up during
402 command complete callback*/
403 if( Cmd == OMX_CommandMarkBuffer ) {
404 /*If pipe is full, return error - thus a limitation that currently
405 cannot queue up more than OMXBase_MAXCMDS mark buffer commands*/
406 tStatus = OSAL_WriteToPipe(pBaseCompPvt->pCmdDataPipe,
407 &pLocalCmdData, sizeof(OMX_PTR), OSAL_NO_SUSPEND);
408 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorInsufficientResources);
409 }
410 /*Obtain mutex for writing to command pipe*/
411 tStatus = OSAL_ObtainMutex(pBaseCompPvt->pCmdPipeMutex, OSAL_SUSPEND);
412 if((tStatus != OSAL_ErrNone) && (Cmd == OMX_CommandMarkBuffer)) {
413 bFreeCmdDataIfError = OMX_FALSE;
414 }
415 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
416
417 /* keep this info, and process later */
418 sCmdParams.eCmd = Cmd;
419 sCmdParams.unParam = nParam1;
420 if( Cmd == OMX_CommandMarkBuffer ) {
421 sCmdParams.pCmdData = pLocalCmdData;
422 } else {
423 sCmdParams.pCmdData = pCmdData;
424 }
425 tStatus = OSAL_WriteToPipe(pBaseCompPvt->pCmdPipe, &sCmdParams,
426 sizeof(sCmdParams), OSAL_SUSPEND);
427 if( tStatus != OSAL_ErrNone ) {
428 /*Do not free pLocalCmdData in this case since it has been pushed to
429 pipe and will now be freed during deinit when pipe is deleted*/
430 if( Cmd == OMX_CommandMarkBuffer ) {
431 bFreeCmdDataIfError = OMX_FALSE;
432 }
433 /*Release the locked mutex and exit with error*/
434 eError = OMX_ErrorInsufficientResources;
435 tStatus = OSAL_ReleaseMutex(pBaseCompPvt->pCmdPipeMutex);
436 goto EXIT;
437 }
438 /* This call invokes the process function directly incase if comp
439 * does process in client context, otherwise triggers compo thread */
440 eError = pBaseCompPvt->fpInvokeProcessFunction(hComponent, CMDEVENT);
441 if( eError != OMX_ErrorNone ) {
442 if( Cmd == OMX_CommandMarkBuffer ) {
443 /*Do not free pLocalCmdData in this case since it has been pushed to
444 pipe and will now be freed during deinit when pipe is deleted*/
445 bFreeCmdDataIfError = OMX_FALSE;
446 }
447 /*Get the count in cmd pipe - this is to be used for popping the
448 recently added cmd to the pipe since that is no longer valid*/
449 tStatus = OSAL_GetPipeReadyMessageCount(pBaseCompPvt->pCmdPipe,
450 &nCmdCount);
451 if( tStatus != OSAL_ErrNone ) {
452 /*Release mutex and return error*/
453 eError = OMX_ErrorUndefined;
454 tStatus = OSAL_ReleaseMutex(pBaseCompPvt->pCmdPipeMutex);
455 goto EXIT;
456 }
457
458 for( i = 0; i < nCmdCount; i++ ) {
459 /*Clear the last command from pipe since error has occured*/
460 tStatus = OSAL_ReadFromPipe(pBaseCompPvt->pCmdPipe, &sErrorCmdParams,
461 sizeof(sErrorCmdParams), &nActualSize,
462 OSAL_SUSPEND);
463 if( tStatus != OSAL_ErrNone ) {
464 eError = OMX_ErrorUndefined;
465 break;
466 }
467 if( OSAL_Memcmp(&sErrorCmdParams, &sCmdParams, sizeof(OMXBase_CmdParams)) == 0 ) {
468 OSAL_ErrorTrace("Found the command to discard");
469 break;
470 } else {
471 /* This is not the command to be discarded - write it back to pipe */
472 tStatus = OSAL_WriteToPipe(pBaseCompPvt->pCmdPipe,
473 &sErrorCmdParams, sizeof(sErrorCmdParams),
474 OSAL_SUSPEND);
475 if( tStatus != OSAL_ErrNone ) {
476 OSAL_ErrorTrace("Write to pipe failed");
477 eError = OMX_ErrorUndefined;
478 break;
479 }
480 }
481 }
482
483 if( i == nCmdCount ) {
484 /*The command to discard was not found even after going through the
485 pipe*/
486 OSAL_ErrorTrace("Command to be discarded not found in pipe");
487 eError = OMX_ErrorUndefined;
488 }
489 }
490 tStatus = OSAL_ReleaseMutex(pBaseCompPvt->pCmdPipeMutex);
491 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
492
493EXIT:
494 if( eError != OMX_ErrorNone ) {
495 if( pLocalCmdData && bFreeCmdDataIfError ) {
496 OSAL_Free(pLocalCmdData);
497 pLocalCmdData = NULL;
498 }
499 }
500 return (eError);
501}
502
503/*
504* OMX Base Get Parameter
505*/
506OMX_ERRORTYPE OMXBase_GetParameter(OMX_HANDLETYPE hComponent,
507 OMX_INDEXTYPE nParamIndex,
508 OMX_PTR pParamStruct)
509{
510 OMX_ERRORTYPE eError = OMX_ErrorNone;
511 OMX_COMPONENTTYPE *pComp = NULL;
512 OMXBaseComp *pBaseComp = NULL;
513 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
514 OMXBase_Port *pPort = NULL;
515 OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL;
516 OMX_PRIORITYMGMTTYPE *pPriorityMgmt = NULL;
517 OMX_PARAM_BUFFERSUPPLIERTYPE *pBufSupplier = NULL;
518 OMX_U32 nStartPortNumber, nPorts, nPortIndex;
519
520
521 OMX_CHECK((hComponent != NULL) && (pParamStruct != NULL), OMX_ErrorBadParameter);
522
523 pComp = (OMX_COMPONENTTYPE *)hComponent;
524 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
525 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
526
527 nPorts = pBaseComp->nNumPorts;
528 nStartPortNumber = pBaseComp->nMinStartPortIndex;
529
530 /*Can't be invoked when the comp is in invalid state*/
531 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState, OMX_ErrorInvalidState);
532
533 switch( nParamIndex ) {
534 case OMX_IndexParamAudioInit :
535 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PORT_PARAM_TYPE, eError);
536 if( pBaseComp->pAudioPortParams == NULL ) {
537 OMX_BASE_INIT_STRUCT_PTR((OMX_PORT_PARAM_TYPE *)(pParamStruct),
538 OMX_PORT_PARAM_TYPE);
539 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nPorts = 0;
540 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nStartPortNumber = 0;
541 break;
542 }
543 *(OMX_PORT_PARAM_TYPE *)pParamStruct = *(pBaseComp->pAudioPortParams);
544 break;
545
546 case OMX_IndexParamImageInit :
547 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PORT_PARAM_TYPE, eError);
548 if( pBaseComp->pImagePortParams == NULL ) {
549 OMX_BASE_INIT_STRUCT_PTR((OMX_PORT_PARAM_TYPE *)(pParamStruct),
550 OMX_PORT_PARAM_TYPE);
551 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nPorts = 0;
552 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nStartPortNumber = 0;
553 break;
554 }
555 *(OMX_PORT_PARAM_TYPE *)pParamStruct = *(pBaseComp->pImagePortParams);
556 break;
557
558 case OMX_IndexParamVideoInit :
559 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PORT_PARAM_TYPE, eError);
560 if( pBaseComp->pVideoPortParams == NULL ) {
561 OMX_BASE_INIT_STRUCT_PTR((OMX_PORT_PARAM_TYPE *)(pParamStruct),
562 OMX_PORT_PARAM_TYPE);
563 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nPorts = 0;
564 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nStartPortNumber = 0;
565 break;
566 }
567 *(OMX_PORT_PARAM_TYPE *)pParamStruct =
568 *(pBaseComp->pVideoPortParams);
569 break;
570
571 case OMX_IndexParamOtherInit :
572 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PORT_PARAM_TYPE, eError);
573 if( pBaseComp->pOtherPortParams == NULL ) {
574 OMX_BASE_INIT_STRUCT_PTR((OMX_PORT_PARAM_TYPE *)(pParamStruct),
575 OMX_PORT_PARAM_TYPE);
576 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nPorts = 0;
577 ((OMX_PORT_PARAM_TYPE *)pParamStruct)->nStartPortNumber = 0;
578 break;
579 }
580 *(OMX_PORT_PARAM_TYPE *)pParamStruct = *(pBaseComp->pOtherPortParams);
581 break;
582
583 case OMX_IndexParamPortDefinition :
584 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PARAM_PORTDEFINITIONTYPE,
585 eError);
586 pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct;
587 nPortIndex = pPortDef->nPortIndex - nStartPortNumber;
588 /* check for valid port index */
589 OMX_CHECK(nPortIndex < nPorts, OMX_ErrorBadPortIndex);
590 *pPortDef = pBaseComp->pPorts[nPortIndex]->sPortDef;
591
592 break;
593
594 case OMX_IndexParamCompBufferSupplier :
595 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PARAM_BUFFERSUPPLIERTYPE, eError);
596 pBufSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParamStruct;
597 nPortIndex = pBufSupplier->nPortIndex - nStartPortNumber;
598 /* check for valid port index */
599 OMX_CHECK(nPortIndex < nPorts, OMX_ErrorBadPortIndex);
600 pPort = pBaseComp->pPorts[nPortIndex];
601 pBufSupplier->eBufferSupplier = 0x0;
602 break;
603
604 case OMX_IndexParamPriorityMgmt :
605 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PRIORITYMGMTTYPE, eError);
606 pPriorityMgmt = (OMX_PRIORITYMGMTTYPE *)pParamStruct;
607 break;
608
609 default :
610 OSAL_ErrorTrace("Unknown Index received ");
611 eError = OMX_ErrorUnsupportedIndex;
612 break;
613 }
614
615EXIT:
616 return (eError);
617}
618
619/*
620* OMX Base SetParameter
621*/
622OMX_ERRORTYPE OMXBase_SetParameter(OMX_HANDLETYPE hComponent,
623 OMX_INDEXTYPE nIndex,
624 OMX_PTR pParamStruct)
625{
626 OMX_ERRORTYPE eError = OMX_ErrorNone;
627 OMX_COMPONENTTYPE *pComp = NULL;
628 OMXBaseComp *pBaseComp = NULL;
629 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
630 OMXBase_Port *pPort = NULL;
631 OMX_PRIORITYMGMTTYPE *pPriorityMgmt = NULL;
632 OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL;
633 OMX_PARAM_PORTDEFINITIONTYPE *pLocalPortDef;
634// OMX_PARAM_BUFFERSUPPLIERTYPE *pBufSupplier = NULL;
635 OMX_U32 nStartPortNumber, nPorts, nPortIndex;
636// OMX_PARAM_BUFFERSUPPLIERTYPE sTunBufSupplier;
637 OMX_TI_PARAMUSENATIVEBUFFER *pParamNativeBuffer = NULL;
638
639 OMX_CHECK((hComponent != NULL) &&
640 (pParamStruct != NULL), OMX_ErrorBadParameter);
641
642 pComp = (OMX_COMPONENTTYPE *)hComponent;
643 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
644 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
645 nPorts = pBaseComp->nNumPorts;
646 nStartPortNumber = pBaseComp->nMinStartPortIndex;
647
648 /*Can't be invoked when the comp is in invalid state*/
649 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState,
650 OMX_ErrorInvalidState);
651 /* This method is not allowed when the component is not in the loaded
652 * state or the the port is not disabled */
653 if((OMX_IndexParamPriorityMgmt == nIndex
654 || OMX_IndexParamAudioInit == nIndex
655 || OMX_IndexParamVideoInit == nIndex
656 || OMX_IndexParamImageInit == nIndex
657 || OMX_IndexParamOtherInit == nIndex)
658 && (pBaseComp->tCurState != OMX_StateLoaded)) {
659 eError = OMX_ErrorIncorrectStateOperation;
660 goto EXIT;
661 }
662
663 switch( (int) nIndex ) {
664 case OMX_IndexParamPriorityMgmt :
665 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PRIORITYMGMTTYPE, eError);
666 pPriorityMgmt = (OMX_PRIORITYMGMTTYPE *)pParamStruct;
667 break;
668
669 case OMX_IndexParamPortDefinition :
670 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PARAM_PORTDEFINITIONTYPE,
671 eError);
672 pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct;
673
674 nPortIndex = pPortDef->nPortIndex - nStartPortNumber;
675 /* check for valid port index */
676 OMX_CHECK(nPortIndex < nPorts, OMX_ErrorBadPortIndex);
677 pPort = pBaseComp->pPorts[nPortIndex];
678 /* successfully only when the comp is in loaded or disabled port */
679 OMX_CHECK((pBaseComp->tCurState == OMX_StateLoaded) ||
680 (pPort->sPortDef.bEnabled == OMX_FALSE),
681 OMX_ErrorIncorrectStateOperation);
682
683 pLocalPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamStruct;
684 /*Copying only the modifiabke fields. Rest are all read only fields*/
685 pBaseComp->pPorts[nPortIndex]->sPortDef.nBufferCountActual =
686 pLocalPortDef->nBufferCountActual;
687 pBaseComp->pPorts[nPortIndex]->sPortDef.format = pLocalPortDef->format;
688 break;
689
690 /*These are compulsory parameters hence being supported by base*/
691 case OMX_IndexParamAudioInit :
692 case OMX_IndexParamVideoInit :
693 case OMX_IndexParamImageInit :
694 case OMX_IndexParamOtherInit :
695 /*All fields of OMX_PORT_PARAM_TYPE are read only so SetParam will just
696 return and not overwrite anything*/
697 OMX_BASE_CHK_VERSION(pParamStruct, OMX_PORT_PARAM_TYPE, eError);
698 break;
699
700 case OMX_TI_IndexUseNativeBuffers:
701 pParamNativeBuffer = (OMX_TI_PARAMUSENATIVEBUFFER* )pParamStruct;
702 if(pParamNativeBuffer->bEnable == OMX_TRUE) {
703 pBaseComp->pPorts[pParamNativeBuffer->nPortIndex - nStartPortNumber]->sProps.eBufMemoryType = MEM_GRALLOC;
704 } else {
705 pBaseComp->pPorts[pParamNativeBuffer->nPortIndex - nStartPortNumber]->sProps.eBufMemoryType = MEM_CARVEOUT;
706 }
707 break;
708
709 default :
710 eError = OMX_ErrorUnsupportedIndex;
711 break;
712 }
713
714EXIT:
715 return (eError);
716}
717
718/*
719* OMX Base AllocatBuffer
720*/
721OMX_ERRORTYPE OMXBase_AllocateBuffer(OMX_HANDLETYPE hComponent,
722 OMX_BUFFERHEADERTYPE * *ppBufferHdr,
723 OMX_U32 nPortIndex,
724 OMX_PTR pAppPrivate,
725 OMX_U32 nSizeBytes)
726{
727 OMX_ERRORTYPE eError = OMX_ErrorNone;
728 OSAL_ERROR tStatus = OSAL_ErrNone;
729 OMX_COMPONENTTYPE *pComp = NULL;
730 OMXBaseComp *pBaseComp = NULL;
731 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
732 OMXBase_Port *pPort = NULL;
733 OMX_DIO_CreateParams sDIOCreateParams;
734 OMX_DIO_OpenParams sDIOOpenParams;
735 OMX_U32 nStartPortNumber = 0, nPorts = 0;
736
737 OMX_CHECK((hComponent != NULL) && (nSizeBytes > 0), OMX_ErrorBadParameter);
738
739 pComp = (OMX_COMPONENTTYPE *)hComponent;
740 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
741 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
742
743 OSAL_ObtainMutex(pBaseCompPvt->pPortDisableMutex, OSAL_SUSPEND);
744
745 nStartPortNumber = pBaseComp->nMinStartPortIndex;
746 nPorts = pBaseComp->nNumPorts;
747 OMX_CHECK(nPortIndex >= nStartPortNumber && nPortIndex < nPorts,
748 OMX_ErrorBadPortIndex);
749 /*Can't be invoked when the comp is in invalid state*/
750 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState,
751 OMX_ErrorInvalidState);
752
753 pPort = pBaseComp->pPorts[nPortIndex - nStartPortNumber];
754
755 /*Buffer size should be >= the minimum buffer size specified in
756 port definition*/
757 OMX_CHECK(nSizeBytes >= pPort->sPortDef.nBufferSize,
758 OMX_ErrorBadParameter);
759 if((pBaseComp->tCurState == OMX_StateLoaded ||
760 pBaseComp->tCurState == OMX_StateWaitForResources) &&
761 (pBaseComp->tNewState == OMX_StateIdle) &&
762 (pPort->sPortDef.bEnabled)) {
763 /*Allowed during loaded/waitforresources --> idle transition if port is
764 enabled*/
765 } else if((pPort->bIsInTransition) &&
766 (pBaseComp->tCurState != OMX_StateLoaded) &&
767 (pBaseComp->tCurState != OMX_StateWaitForResources)) {
768 /*Allowed when port is transitioning to enabled if current state is not
769 loaded/waitforresources*/
770 } else {
771 eError = OMX_ErrorIncorrectStateOperation;
772 goto EXIT;
773 }
774 /*Port should not be already populated*/
775 OMX_CHECK(pPort->sPortDef.bPopulated == OMX_FALSE,
776 OMX_ErrorBadParameter);
777 if( pPort->nBufferCnt == 0 ) {
778 /* Initialize DIO and open as a supplier */
779 pPort->bIsBufferAllocator = OMX_TRUE;
780 sDIOCreateParams.hComponent = hComponent;
781 sDIOCreateParams.nPortIndex = pPort->sPortDef.nPortIndex;
782 sDIOCreateParams.pAppCallbacks = &(pBaseCompPvt->sAppCallbacks);
783 if( pPort->sPortDef.eDir == OMX_DirOutput ) {
784 sDIOOpenParams.nMode = OMX_DIO_WRITER;
785 } else {
786 sDIOOpenParams.nMode = OMX_DIO_READER;
787 }
788
789 sDIOOpenParams.nBufSize = nSizeBytes;
790 eError = OMXBase_DIO_Init(hComponent, nPortIndex, "OMX.DIO.NONTUNNEL",
791 &sDIOCreateParams);
792 OMX_CHECK(eError == OMX_ErrorNone, eError);
793 eError = OMXBase_DIO_Open(hComponent, nPortIndex, &sDIOOpenParams);
794 OMX_CHECK(eError == OMX_ErrorNone, eError);
795 }
796 /*update buffer header from buffer list */
797 *ppBufferHdr = pPort->pBufferlist[pPort->nBufferCnt];
798 if( pPort->sPortDef.eDir == OMX_DirInput ) {
799 (*ppBufferHdr)->nInputPortIndex = pPort->sPortDef.nPortIndex;
800 (*ppBufferHdr)->nOutputPortIndex = OMX_NOPORT;
801 } else if( pPort->sPortDef.eDir == OMX_DirOutput ) {
802 (*ppBufferHdr)->nOutputPortIndex = pPort->sPortDef.nPortIndex;
803 (*ppBufferHdr)->nInputPortIndex = OMX_NOPORT;
804 }
805 (*ppBufferHdr)->pAppPrivate = pAppPrivate;
806 (*ppBufferHdr)->nAllocLen = nSizeBytes;
807
808 pPort->nBufferCnt++;
809 if( pPort->sPortDef.nBufferCountActual == pPort->nBufferCnt ) {
810 pPort->sPortDef.bPopulated = OMX_TRUE;
811 tStatus = OSAL_SetEvent(pPort->pBufAllocFreeEvent, BUF_ALLOC_EVENT,
812 OSAL_EVENT_OR);
813 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorInsufficientResources);
814 }
815
816EXIT:
817 if ((hComponent != NULL) && (nSizeBytes > 0)) {
818 OSAL_ReleaseMutex(pBaseCompPvt->pPortDisableMutex);
819 }
820 return (eError);
821}
822
823/*
824* OMX Base UseBuffer
825*/
826OMX_ERRORTYPE OMXBase_UseBuffer(OMX_HANDLETYPE hComponent,
827 OMX_BUFFERHEADERTYPE * *ppBufferHdr,
828 OMX_U32 nPortIndex,
829 OMX_PTR pAppPrivate,
830 OMX_U32 nSizeBytes,
831 OMX_U8 *pBuffer)
832{
833 OMX_ERRORTYPE eError = OMX_ErrorNone;
834 OSAL_ERROR tStatus = OSAL_ErrNone;
835 OMX_COMPONENTTYPE *pComp = NULL;
836 OMXBaseComp *pBaseComp = NULL;
837 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
838 OMXBase_Port *pPort = NULL;
839 OMX_DIO_CreateParams sDIOCreateParams;
840 OMX_DIO_OpenParams sDIOOpenParams;
841 OMX_U32 nStartPortNumber = 0, nPorts = 0;
842
843 OMX_CHECK((hComponent != NULL), OMX_ErrorBadParameter);
844
845 pComp = (OMX_COMPONENTTYPE *)hComponent;
846 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
847 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
848
849 OSAL_ObtainMutex(pBaseCompPvt->pPortDisableMutex, OSAL_SUSPEND);
850
851 nStartPortNumber = pBaseComp->nMinStartPortIndex;
852 nPorts = pBaseComp->nNumPorts;
853 OMX_CHECK(nPortIndex >= nStartPortNumber && nPortIndex < nPorts,
854 OMX_ErrorBadPortIndex);
855 /*Can't be invoked when the comp is in invalid state*/
856 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState,
857 OMX_ErrorInvalidState);
858
859 pPort = pBaseComp->pPorts[nPortIndex - nStartPortNumber];
860
861 if((pBaseComp->tCurState == OMX_StateLoaded ||
862 pBaseComp->tCurState == OMX_StateWaitForResources) &&
863 (pBaseComp->tNewState == OMX_StateIdle) &&
864 (pPort->sPortDef.bEnabled)) {
865 /*Allowed during loaded/waitforresources --> idle transition if port is
866 enabled*/
867 } else if((pPort->bIsInTransition) &&
868 (pBaseComp->tCurState != OMX_StateLoaded) &&
869 (pBaseComp->tCurState != OMX_StateWaitForResources)) {
870 /*Allowed when port is transitioning to enabled if current state is not
871 loaded/waitforresources*/
872 } else {
873 eError = OMX_ErrorIncorrectStateOperation;
874 goto EXIT;
875 }
876 OMX_CHECK(pPort->sPortDef.bPopulated == OMX_FALSE,
877 OMX_ErrorBadParameter);
878
879 if( pPort->nBufferCnt == 0 ) {
880 /* Initialize DIO if not initialized and open as a non supplier */
881 pPort->bIsBufferAllocator = OMX_FALSE;
882 if( pPort->hDIO == NULL) {
883 sDIOCreateParams.hComponent = hComponent;
884 sDIOCreateParams.nPortIndex = pPort->sPortDef.nPortIndex;
885 sDIOCreateParams.pAppCallbacks = &(pBaseCompPvt->sAppCallbacks);
886
887 if( pPort->sPortDef.eDir == OMX_DirOutput ) {
888 sDIOOpenParams.nMode = OMX_DIO_WRITER;
889 } else {
890 sDIOOpenParams.nMode = OMX_DIO_READER;
891 }
892
893 sDIOOpenParams.nBufSize = nSizeBytes;
894 eError = OMXBase_DIO_Init(hComponent, nPortIndex,
895 "OMX.DIO.NONTUNNEL", &sDIOCreateParams);
896 OMX_CHECK(eError == OMX_ErrorNone, eError);
897 eError = OMXBase_DIO_Open(hComponent, nPortIndex, &sDIOOpenParams);
898 OMX_CHECK(eError == OMX_ErrorNone, eError);
899 }
900 }
901 /*update buffer header from buffer list */
902 pPort->pBufferlist[pPort->nBufferCnt]->pBuffer = pBuffer;
903 *ppBufferHdr = pPort->pBufferlist[pPort->nBufferCnt];
904 if( pPort->sPortDef.eDir == OMX_DirInput ) {
905 (*ppBufferHdr)->nInputPortIndex = pPort->sPortDef.nPortIndex;
906 (*ppBufferHdr)->nOutputPortIndex = OMX_NOPORT;
907 } else if( pPort->sPortDef.eDir == OMX_DirOutput ) {
908 (*ppBufferHdr)->nOutputPortIndex = pPort->sPortDef.nPortIndex;
909 (*ppBufferHdr)->nInputPortIndex = OMX_NOPORT;
910 }
911 (*ppBufferHdr)->pAppPrivate = pAppPrivate;
912 (*ppBufferHdr)->nAllocLen = nSizeBytes;
913
914 if (pBaseComp->fpXlateBuffHandle != NULL) {
915 eError = pBaseComp->fpXlateBuffHandle(hComponent, (OMX_PTR)(*ppBufferHdr), OMX_TRUE);
916 }
917
918 pPort->nBufferCnt++;
919 if( pPort->sPortDef.nBufferCountActual == pPort->nBufferCnt ) {
920 pPort->sPortDef.bPopulated = OMX_TRUE;
921 tStatus = OSAL_SetEvent(pPort->pBufAllocFreeEvent, BUF_ALLOC_EVENT,
922 OSAL_EVENT_OR);
923 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorInsufficientResources);
924 }
925EXIT:
926 if (hComponent != NULL) {
927 OSAL_ReleaseMutex(pBaseCompPvt->pPortDisableMutex);
928 }
929 return (eError);
930}
931
932/*
933* OMX Base FreeBuffer
934*/
935OMX_ERRORTYPE OMXBase_FreeBuffer(OMX_HANDLETYPE hComponent,
936 OMX_U32 nPortIndex,
937 OMX_BUFFERHEADERTYPE *pBuffHeader)
938{
939 OMX_ERRORTYPE eError = OMX_ErrorNone, eTmpError = OMX_ErrorNone;
940 OSAL_ERROR tStatus = OSAL_ErrNone;
941 OMX_COMPONENTTYPE *pComp = NULL;
942 OMXBaseComp *pBaseComp = NULL;
943 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
944 OMXBase_Port *pPort = NULL;
945 OMX_U32 nStartPortNumber = 0, nPorts = 0;
946
947 OMX_CHECK((hComponent != NULL) &&
948 (pBuffHeader != NULL), OMX_ErrorBadParameter);
949
950 pComp = (OMX_COMPONENTTYPE *)hComponent;
951 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
952 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
953 nStartPortNumber = pBaseComp->nMinStartPortIndex;
954 nPorts = pBaseComp->nNumPorts;
955 OMX_CHECK(nPortIndex >= nStartPortNumber && nPortIndex < nPorts,
956 OMX_ErrorBadPortIndex);
957
958 pPort = pBaseComp->pPorts[nPortIndex - nStartPortNumber];
959
960 OMX_BASE_CHK_VERSION(pBuffHeader, OMX_BUFFERHEADERTYPE, eError);
961 /*Free buffer should not be called on a port after all buffers have been
962 freed*/
963 OMX_CHECK(pPort->nBufferCnt != 0, OMX_ErrorBadParameter);
964
965 /* unregister the buffer with decoder for non-allocator port*/
966 if (!pPort->bIsBufferAllocator && pBaseComp->fpXlateBuffHandle != NULL) {
967 eError = pBaseComp->fpXlateBuffHandle(hComponent, (OMX_PTR)(pBuffHeader), OMX_FALSE);
968 }
969
970 /* Just decrement the buffer count and unpopulate the port,
971 * buffer header pool is freed up once all the buffers are received */
972 pPort->nBufferCnt--;
973 pPort->sPortDef.bPopulated = OMX_FALSE;
974 if( pBaseComp->tCurState == OMX_StateIdle &&
975 pBaseComp->tNewState == OMX_StateLoaded && pPort->sPortDef.bEnabled ) {
976 /*Allowed on idle --> loaded transition if port is enabled*/
977 } else if((pPort->bIsInTransition) &&
978 (pBaseComp->tCurState != OMX_StateLoaded) &&
979 (pBaseComp->tCurState != OMX_StateWaitForResources)) {
980 /*Allowed during port disable if current state is not
981 loaded/waitforresources*/
982 } else {
983 eError = pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
984 pComp->pApplicationPrivate,
985 OMX_EventError, (OMX_U32)OMX_ErrorPortUnpopulated,
986 nPortIndex, " PortUnpopulated ");
987 /*Ideally callback should never return error*/
988 OMX_CHECK(OMX_ErrorNone == eError, eError);
989 }
990 if( pPort->nBufferCnt == 0 ) {
991 tStatus = OSAL_SetEvent(pPort->pBufAllocFreeEvent, BUF_FREE_EVENT,
992 OSAL_EVENT_OR);
993 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
994 }
995
996EXIT:
997 if((eTmpError != OMX_ErrorNone) && (eError == OMX_ErrorNone)) {
998 /*An error occured earlier but we still continued cleanup to avoid leaks.
999 Setting the return value to the error code now*/
1000 eError = eTmpError;
1001 }
1002 return (eError);
1003}
1004
1005/*
1006* Empty This Buffer
1007*/
1008OMX_ERRORTYPE OMXBase_EmptyThisBuffer(OMX_HANDLETYPE hComponent,
1009 OMX_BUFFERHEADERTYPE *pBuffer)
1010{
1011 OMX_ERRORTYPE eError = OMX_ErrorNone;
1012 OMX_COMPONENTTYPE *pComp = NULL;
1013 OMXBaseComp *pBaseComp = NULL;
1014 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
1015 OMXBase_Port *pPort = NULL;
1016 OMX_U32 nPorts, nStartPortNumber;
1017
1018 OMX_CHECK((hComponent != NULL) &&
1019 (pBuffer != NULL), OMX_ErrorBadParameter);
1020
1021 pComp = (OMX_COMPONENTTYPE *)hComponent;
1022 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
1023 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
1024 nPorts = pBaseComp->nNumPorts;
1025 nStartPortNumber = pBaseComp->nMinStartPortIndex;
1026
1027 /*Can't be invoked when the comp is in invalid state*/
1028 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState, OMX_ErrorInvalidState);
1029 /* check for valid port index */
1030 OMX_CHECK(pBuffer->nInputPortIndex < (nPorts + nStartPortNumber), OMX_ErrorBadPortIndex);
1031
1032 pPort = pBaseComp->pPorts[pBuffer->nInputPortIndex - nStartPortNumber];
1033 if( pPort->sPortDef.eDir != OMX_DirInput ) {
1034 eError = OMX_ErrorIncorrectStateOperation;
1035 goto EXIT;
1036 }
1037
1038 /* This method is allowed only when the comp is in or a transition
1039 * to executing or pause state */
1040 OMX_CHECK((pBaseComp->tCurState == OMX_StateIdle &&
1041 pBaseComp->tNewState == OMX_StateExecuting) ||
1042 (pBaseComp->tCurState == OMX_StateExecuting ||
1043 pBaseComp->tCurState == OMX_StatePause),
1044 OMX_ErrorIncorrectStateOperation);
1045
1046 /*Following two checks are based on the 1.1.2 AppNote*/
1047 /*Supplier ports can accept buffers even if current state is disabled
1048 if they are transitioning from port enable to disable*/
1049 if( pPort->sPortDef.bEnabled != OMX_TRUE ) {
1050 if((!pPort->bIsInTransition) || (!pPort->bIsBufferAllocator)) {
1051 eError = OMX_ErrorIncorrectStateOperation;
1052 goto EXIT;
1053 }
1054 }
1055 /*Non-supplier ports can't accept buffers when transitioning to Idle
1056 or when port is being transitioned to disabled*/
1057 if( !pPort->bIsBufferAllocator) {
1058 if((pBaseComp->tNewState == OMX_StateIdle) || (pPort->bIsInTransition)) {
1059 eError = OMX_ErrorIncorrectStateOperation;
1060 goto EXIT;
1061 }
1062 }
1063 eError = OMXBase_DIO_Queue(hComponent, pBuffer->nInputPortIndex, pBuffer);
1064 OMX_CHECK(eError == OMX_ErrorNone, eError);
1065 ((OMXBase_BufHdrPvtData *)(pBuffer->pPlatformPrivate))->bufSt = OWNED_BY_US;
1066
1067 /*If another buffer comes after eos then reset the variable that causes
1068 watermark to become meaningless on this port*/
1069 if( pPort->bEosRecd == OMX_TRUE ) {
1070 pPort->bEosRecd = OMX_FALSE;
1071 }
1072 /*If EOS buffer or CodecConfig buffer then force notify to derived component*/
1073 if( pBuffer->nFlags & OMX_BUFFERFLAG_EOS ) {
1074 pPort->bEosRecd = OMX_TRUE;
1075 }
1076 eError = pBaseCompPvt->fpInvokeProcessFunction(hComponent, DATAEVENT);
1077
1078EXIT:
1079 return (eError);
1080}
1081
1082/*
1083* OMX Base FillThisBuffer
1084*/
1085OMX_ERRORTYPE OMXBase_FillThisBuffer(OMX_HANDLETYPE hComponent,
1086 OMX_BUFFERHEADERTYPE *pBuffer)
1087{
1088 OMX_ERRORTYPE eError = OMX_ErrorNone;
1089 OMX_COMPONENTTYPE *pComp = NULL;
1090 OMXBaseComp *pBaseComp = NULL;
1091 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
1092 OMXBase_Port *pPort = NULL;
1093 OMX_U32 nPorts, nStartPortNumber;
1094
1095 OMX_CHECK((hComponent != NULL) && (pBuffer != NULL), OMX_ErrorBadParameter);
1096 OMX_CHECK(pBuffer->pBuffer != NULL, OMX_ErrorBadParameter);
1097
1098 pComp = (OMX_COMPONENTTYPE *)hComponent;
1099 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
1100 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
1101 nPorts = pBaseComp->nNumPorts;
1102 nStartPortNumber = pBaseComp->nMinStartPortIndex;
1103
1104 /*Can't be invoked when the comp is in invalid state*/
1105 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState,
1106 OMX_ErrorInvalidState);
1107
1108 /* check for valid port index */
1109 OMX_CHECK(pBuffer->nOutputPortIndex < (nPorts +
1110 nStartPortNumber), OMX_ErrorBadPortIndex);
1111
1112 pPort = pBaseComp->pPorts[pBuffer->nOutputPortIndex - nStartPortNumber];
1113 if( pPort->sPortDef.eDir != OMX_DirOutput ) {
1114 eError = OMX_ErrorIncorrectStateOperation;
1115 goto EXIT;
1116 }
1117
1118 /* This method is allowed only when the comp is in or a transition
1119 * to executing or pause state */
1120 OMX_CHECK((pBaseComp->tCurState == OMX_StateIdle &&
1121 pBaseComp->tNewState == OMX_StateExecuting) ||
1122 (pBaseComp->tCurState == OMX_StateExecuting ||
1123 pBaseComp->tCurState == OMX_StatePause),
1124 OMX_ErrorIncorrectStateOperation);
1125 /*Following two checks are based on the 1.1.2 AppNote*/
1126 /*Supplier ports can accept buffers even if current state is disabled
1127 if they are transitioning from port enable to disable*/
1128 if( pPort->sPortDef.bEnabled != OMX_TRUE ) {
1129 if((!pPort->bIsInTransition) || (!pPort->bIsBufferAllocator)) {
1130 eError = OMX_ErrorIncorrectStateOperation;
1131 goto EXIT;
1132 }
1133 }
1134 /*Non-supplier ports can't accept buffers when transitioning to Idle
1135 or when port is being transitioned to disabled*/
1136 if( !pPort->bIsBufferAllocator) {
1137 if((pBaseComp->tNewState == OMX_StateIdle) ||
1138 (pPort->bIsInTransition)) {
1139 eError = OMX_ErrorIncorrectStateOperation;
1140 goto EXIT;
1141 }
1142 }
1143 eError = OMXBase_DIO_Queue(hComponent, pBuffer->nOutputPortIndex, pBuffer);
1144 OMX_CHECK(eError == OMX_ErrorNone, eError);
1145 ((OMXBase_BufHdrPvtData *)(pBuffer->pPlatformPrivate))->bufSt = OWNED_BY_US;
1146 eError = pBaseCompPvt->fpInvokeProcessFunction(hComponent, DATAEVENT);
1147
1148EXIT:
1149 return (eError);
1150}
1151
1152/*
1153* OMX Base SetConfig
1154*/
1155OMX_ERRORTYPE OMXBase_SetConfig(OMX_HANDLETYPE hComponent,
1156 OMX_INDEXTYPE nIndex,
1157 OMX_PTR pComponentConfigStructure)
1158{
1159 OMX_ERRORTYPE eError = OMX_ErrorNone;
1160// OSAL_ERROR tStatus = OSAL_ErrNone;
1161 OMX_COMPONENTTYPE *pComp = NULL;
1162 OMXBaseComp *pBaseComp = NULL;
1163 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
1164// OMXBase_Port *pPort = NULL;
1165 OMX_U32 nStartPortNumber, nPorts;
1166// OMX_U32 nPortIndex;
1167
1168 OMX_CHECK((hComponent != NULL) &&
1169 (pComponentConfigStructure != NULL), OMX_ErrorBadParameter);
1170
1171 pComp = (OMX_COMPONENTTYPE *)hComponent;
1172 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
1173 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
1174 nStartPortNumber = pBaseComp->nMinStartPortIndex;
1175 nPorts = pBaseComp->nNumPorts;
1176
1177 /*Can't be invoked when the comp is in invalid state*/
1178 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState,
1179 OMX_ErrorInvalidState);
1180
1181 switch( nIndex ) {
1182 default :
1183 eError = OMX_ErrorUnsupportedIndex;
1184 break;
1185 }
1186
1187EXIT:
1188 return (eError);
1189}
1190
1191/*
1192* OMX Base GetConfig
1193*/
1194OMX_ERRORTYPE OMXBase_GetConfig(OMX_HANDLETYPE hComponent,
1195 OMX_INDEXTYPE nIndex,
1196 OMX_PTR pComponentConfigStructure)
1197{
1198 OMX_ERRORTYPE eError = OMX_ErrorNone;
1199 OMX_COMPONENTTYPE *pComp = NULL;
1200 OMXBaseComp *pBaseComp = NULL;
1201 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
1202// OMXBase_Port *pPort = NULL;
1203 OMX_U32 nStartPortNumber, nPorts;
1204// OMX_U32 nPortIndex;
1205
1206 OMX_CHECK((hComponent != NULL) &&
1207 (pComponentConfigStructure != NULL), OMX_ErrorBadParameter);
1208
1209 pComp = (OMX_COMPONENTTYPE *)hComponent;
1210 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
1211 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
1212 nStartPortNumber = pBaseComp->nMinStartPortIndex;
1213 nPorts = pBaseComp->nNumPorts;
1214
1215 /*Can't be invoked when the comp is in invalid state*/
1216 OMX_CHECK(OMX_StateInvalid != pBaseComp->tCurState, OMX_ErrorInvalidState);
1217
1218 switch( nIndex ) {
1219 default :
1220 eError = OMX_ErrorUnsupportedIndex;
1221 break;
1222 }
1223
1224EXIT:
1225 return (eError);
1226}
1227
1228/*
1229* OMX Base UseEGLImage
1230*/
1231OMX_ERRORTYPE OMXBase_UseEGLImage(OMX_HANDLETYPE hComponent,
1232 OMX_BUFFERHEADERTYPE * *ppBufferHdr,
1233 OMX_U32 nPortIndex,
1234 OMX_PTR pAppPrivate,
1235 void *eglImage)
1236{
1237 (void)hComponent;
1238 (void)ppBufferHdr;
1239 (void)nPortIndex;
1240 (void)pAppPrivate;
1241 (void)eglImage;
1242
1243 return (OMX_ErrorNotImplemented);
1244}
1245
1246/*
1247* OMX Base GetExtentionIndex
1248*/
1249OMX_ERRORTYPE OMXBase_GetExtensionIndex(OMX_HANDLETYPE hComponent,
1250 OMX_STRING cParameterName,
1251 OMX_INDEXTYPE *pIndexType)
1252{
1253 (void)hComponent;
1254 (void)cParameterName;
1255 (void)pIndexType;
1256
1257 return (OMX_ErrorNotImplemented);
1258}
1259
1260/*
1261* OMX Base ComponentRoleEnum
1262*/
1263OMX_ERRORTYPE OMXBase_ComponentRoleEnum(OMX_HANDLETYPE hComponent,
1264 OMX_U8 *cRole,
1265 OMX_U32 nIndex)
1266{
1267 (void)hComponent;
1268 (void)cRole;
1269 (void)nIndex;
1270
1271 return (OMX_ErrorNotImplemented);
1272}
1273
diff --git a/libstagefrighthw/omx/base/OMX_Base.h b/libstagefrighthw/omx/base/OMX_Base.h
new file mode 100644
index 0000000..3c7cc3e
--- /dev/null
+++ b/libstagefrighthw/omx/base/OMX_Base.h
@@ -0,0 +1,221 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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#ifndef _D_OMX_BASE_H_
18#define _D_OMX_BASE_H_
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27
28#include <OMX_Core.h>
29#include <OMX_Component.h>
30#include <OMX_BaseInternal.h>
31#include <OMX_BaseUtils.h>
32
33#include <osal_error.h>
34#include <osal_mutex.h>
35#include <osal_memory.h>
36#include <osal_pipes.h>
37#include <osal_events.h>
38#include <osal_task.h>
39
40#include <memplugin.h>
41
42#define OMX_NOPORT 0xFFFFFFFE
43#define OMX_BASE_INPUT_PORT 0
44#define OMX_BASE_OUTPUT_PORT 1
45#define OMX_BASE_NUM_OF_PORTS 2
46#define OMX_BASE_DEFAULT_START_PORT_NUM 0
47#define DEFAULT_COMPOENENT 0
48#define MAX_PLANES_PER_BUFFER 3
49
50
51/*
52* buffer life cycle
53*/
54typedef enum OMXBase_BufferStatus{
55 OWNED_BY_US,
56 OWNED_BY_CLIENT,
57 OWNED_BY_CODEC
58}OMXBase_BufStatus;
59
60/** Platform private buffer header
61 */
62typedef struct OMXBase_BufHdrPrivateData {
63 MemHeader sMemHdr[MAX_PLANES_PER_BUFFER];
64 OMXBase_BufStatus bufSt;
65 OMX_BOOL bIsLocked;
66}OMXBase_BufHdrPvtData;
67
68typedef struct OMXBase_CodecConfigBuffer {
69 MemHeader *sBuffer;
70} OMXBase_CodecConfigBuf;
71
72/** Port properties.
73 */
74typedef struct OMXBase_PortProperties {
75 OMX_U32 nWatermark;
76 BufAccessMode eDataAccessMode;
77 MemRegion eBufMemoryType;
78 OMX_U32 nNumComponentBuffers;
79 OMX_U32 nTimeoutForDequeue;
80}OMXBase_PortProps;
81
82/** Base port definition
83 */
84typedef struct OMXBase_Port{
85 OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
86 OMX_BUFFERHEADERTYPE **pBufferlist;
87 OMXBase_PortProps sProps;
88 OMX_BOOL bIsBufferAllocator;
89 OMX_BOOL bIsInTransition;
90 OMX_BOOL bIsFlushingBuffers;
91 OMX_BOOL bEosRecd;
92 OMX_U32 nBufferCnt;
93 OMX_PTR pBufAllocFreeEvent;
94 OMX_PTR pDioOpenCloseSem;
95 OMX_PTR hDIO;
96 OMX_U32 nCachedBufferCnt;
97}OMXBase_Port;
98
99/* OMX base component structure
100*/
101typedef struct OMXBaseComp
102{
103 OMX_STRING cComponentName;
104 OMX_VERSIONTYPE nComponentVersion;
105 OMX_PORT_PARAM_TYPE *pAudioPortParams;
106 OMX_PORT_PARAM_TYPE *pVideoPortParams;
107 OMX_PORT_PARAM_TYPE *pImagePortParams;
108 OMX_PORT_PARAM_TYPE *pOtherPortParams;
109 OMX_U32 nNumPorts;
110 OMX_U32 nMinStartPortIndex;
111 OMXBase_Port **pPorts;
112 OMX_BOOL bNotifyForAnyPort;
113 OMXBaseComp_Pvt *pPvtData;
114 OMX_STATETYPE tCurState;
115 OMX_STATETYPE tNewState;
116 OMX_PTR pMutex;
117
118 OMX_ERRORTYPE (*fpCommandNotify)(OMX_HANDLETYPE hComponent, OMX_COMMANDTYPE Cmd,
119 OMX_U32 nParam, OMX_PTR pCmdData);
120
121 OMX_ERRORTYPE (*fpDataNotify)(OMX_HANDLETYPE hComponent);
122
123
124 OMX_ERRORTYPE (*fpReturnEventNotify)(OMX_HANDLETYPE hComponent, OMX_EVENTTYPE eEvent,
125 OMX_U32 nEventData1, OMX_U32 nEventData2, OMX_PTR pEventData);
126
127 OMX_ERRORTYPE (*fpXlateBuffHandle)(OMX_HANDLETYPE hComponent, OMX_PTR pBufferHdr, OMX_BOOL bRegister);
128
129}OMXBaseComp;
130
131
132OMX_ERRORTYPE OMXBase_ComponentInit(OMX_IN OMX_HANDLETYPE hComponent);
133
134OMX_ERRORTYPE OMXBase_SetCallbacks(OMX_IN OMX_HANDLETYPE hComponent,
135 OMX_IN OMX_CALLBACKTYPE *pCallbacks,
136 OMX_IN OMX_PTR pAppData);
137
138OMX_ERRORTYPE OMXBase_GetComponentVersion(OMX_IN OMX_HANDLETYPE hComponent,
139 OMX_OUT OMX_STRING pComponentName,
140 OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
141 OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
142 OMX_OUT OMX_UUIDTYPE *pComponentUUID);
143
144OMX_ERRORTYPE OMXBase_SendCommand(OMX_IN OMX_HANDLETYPE hComponent,
145 OMX_IN OMX_COMMANDTYPE Cmd,
146 OMX_IN OMX_U32 nParam1,
147 OMX_IN OMX_PTR pCmdData);
148
149OMX_ERRORTYPE OMXBase_GetParameter(OMX_IN OMX_HANDLETYPE hComponent,
150 OMX_IN OMX_INDEXTYPE nParamIndex,
151 OMX_INOUT OMX_PTR pParamStruct);
152
153OMX_ERRORTYPE OMXBase_SetParameter(OMX_IN OMX_HANDLETYPE hComponent,
154 OMX_IN OMX_INDEXTYPE nIndex,
155 OMX_IN OMX_PTR pParamStruct);
156
157
158OMX_ERRORTYPE OMXBase_GetConfig(OMX_IN OMX_HANDLETYPE hComponent,
159 OMX_IN OMX_INDEXTYPE nIndex,
160 OMX_INOUT OMX_PTR pComponentConfigStructure);
161
162
163OMX_ERRORTYPE OMXBase_SetConfig(OMX_IN OMX_HANDLETYPE hComponent,
164 OMX_IN OMX_INDEXTYPE nIndex,
165 OMX_IN OMX_PTR pComponentConfigStructure);
166
167OMX_ERRORTYPE OMXBase_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent,
168 OMX_IN OMX_STRING cParameterName,
169 OMX_OUT OMX_INDEXTYPE *pIndexType);
170
171
172OMX_ERRORTYPE OMXBase_GetState(OMX_IN OMX_HANDLETYPE hComponent,
173 OMX_OUT OMX_STATETYPE *pState);
174
175
176OMX_ERRORTYPE OMXBase_UseBuffer(OMX_IN OMX_HANDLETYPE hComponent,
177 OMX_INOUT OMX_BUFFERHEADERTYPE * *ppBufferHdr,
178 OMX_IN OMX_U32 nPortIndex,
179 OMX_IN OMX_PTR pAppPrivate,
180 OMX_IN OMX_U32 nSizeBytes,
181 OMX_IN OMX_U8 *pBuffer);
182
183OMX_ERRORTYPE OMXBase_AllocateBuffer(OMX_IN OMX_HANDLETYPE hComponent,
184 OMX_INOUT OMX_BUFFERHEADERTYPE * *ppBuffer,
185 OMX_IN OMX_U32 nPortIndex,
186 OMX_IN OMX_PTR pAppPrivate,
187 OMX_IN OMX_U32 nSizeBytes);
188
189
190OMX_ERRORTYPE OMXBase_FreeBuffer(OMX_IN OMX_HANDLETYPE hComponent,
191 OMX_IN OMX_U32 nPortIndex,
192 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
193
194
195OMX_ERRORTYPE OMXBase_EmptyThisBuffer(OMX_IN OMX_HANDLETYPE hComponent,
196 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
197
198
199OMX_ERRORTYPE OMXBase_FillThisBuffer(OMX_IN OMX_HANDLETYPE hComponent,
200 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
201
202
203OMX_ERRORTYPE OMXBase_ComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent);
204
205
206OMX_ERRORTYPE OMXBase_UseEGLImage(OMX_IN OMX_HANDLETYPE hComponent,
207 OMX_INOUT OMX_BUFFERHEADERTYPE * *ppBufferHdr,
208 OMX_IN OMX_U32 nPortIndex,
209 OMX_IN OMX_PTR pAppPrivate,
210 OMX_IN void *eglImage);
211
212OMX_ERRORTYPE OMXBase_ComponentRoleEnum(OMX_IN OMX_HANDLETYPE hComponent,
213 OMX_OUT OMX_U8 *cRole,
214 OMX_IN OMX_U32 nIndex);
215
216#ifdef __cplusplus
217}
218#endif
219
220#endif /* _OMX_BASE_H_ */
221
diff --git a/libstagefrighthw/omx/base/OMX_BaseCallbacks.c b/libstagefrighthw/omx/base/OMX_BaseCallbacks.c
new file mode 100644
index 0000000..efe62b8
--- /dev/null
+++ b/libstagefrighthw/omx/base/OMX_BaseCallbacks.c
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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 "OMX_BASE_CALLBACKS"
18
19#include <OMX_Core.h>
20#include <OMX_Base.h>
21
22/*
23* OMX Base callback ReturnEventNotify
24*/
25OMX_ERRORTYPE OMXBase_CB_ReturnEventNotify(OMX_HANDLETYPE hComponent,
26 OMX_EVENTTYPE eEvent,
27 OMX_U32 nData1, OMX_U32 nData2,
28 OMX_PTR pEventData)
29{
30 OMX_ERRORTYPE eError = OMX_ErrorNone;
31 OMX_COMPONENTTYPE *pComp = NULL;
32 OMXBaseComp *pBaseComp = NULL;
33 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
34 OSAL_ERROR tStatus = OSAL_ErrNone;
35 uint32_t nActualSize = 0;
36 OMX_PTR pCmdData = NULL;
37
38 OMX_CHECK(hComponent != NULL, OMX_ErrorBadParameter);
39
40 pComp = (OMX_COMPONENTTYPE *)hComponent;
41 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
42 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
43
44 switch( eEvent ) {
45 case OMX_EventCmdComplete :
46 if((OMX_COMMANDTYPE)nData1 == OMX_CommandStateSet ) {
47 OSAL_SetEvent(pBaseCompPvt->pCmdCompleteEvent,
48 OMXBase_CmdStateSet, OSAL_EVENT_OR);
49 } else if((OMX_COMMANDTYPE)nData1 == OMX_CommandPortEnable ) {
50 OSAL_SetEvent(pBaseCompPvt->pCmdCompleteEvent,
51 OMXBase_CmdPortEnable, OSAL_EVENT_OR);
52 } else if((OMX_COMMANDTYPE)nData1 == OMX_CommandPortDisable ) {
53 OSAL_SetEvent(pBaseCompPvt->pCmdCompleteEvent,
54 OMXBase_CmdPortDisable, OSAL_EVENT_OR);
55 } else if((OMX_COMMANDTYPE)nData1 == OMX_CommandFlush ) {
56 OSAL_SetEvent(pBaseCompPvt->pCmdCompleteEvent,
57 OMXBase_CmdFlush, OSAL_EVENT_OR);
58 } else if((OMX_COMMANDTYPE)nData1 == OMX_CommandMarkBuffer ) {
59 /*The derived component has completed the mark buffer command so
60 the memory allocated for pCmdData is no longer needed - it can
61 be freed up*/
62 tStatus = OSAL_ReadFromPipe(pBaseCompPvt->pCmdDataPipe,
63 &pCmdData, sizeof(OMX_PTR), &nActualSize,
64 OSAL_NO_SUSPEND);
65 /*Read from pipe should return immediately with valid value - if
66 it does not, return error callback to the client*/
67 if( OSAL_ErrNone != tStatus ) {
68 OSAL_ErrorTrace("pCmdData not available to freed up at mark \
69 buffer command completion. Returning error event.");
70 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
71 pComp->pApplicationPrivate, OMX_EventError,
72 (OMX_U32)OMX_ErrorInsufficientResources, 0, NULL);
73 goto EXIT;
74 }
75 OSAL_Free(pCmdData);
76 /*For mark buffer cmd complete, directly send callback to the
77 client. This callback is not being handled in
78 OMXBase_EventNotifyToClient since this can happen much later
79 than the time when the mark comand was received*/
80 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
81 pComp->pApplicationPrivate, eEvent, nData1, nData2,
82 pEventData);
83 }
84 break;
85
86 case OMX_EventError :
87 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
88 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
89 break;
90
91 case OMX_EventMark :
92 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
93 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
94 break;
95
96 case OMX_EventPortSettingsChanged :
97 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
98 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
99 break;
100
101 case OMX_EventBufferFlag :
102 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
103 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
104 break;
105
106 case OMX_EventResourcesAcquired :
107 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
108 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
109 break;
110
111 case OMX_EventComponentResumed :
112 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
113 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
114 break;
115
116 case OMX_EventDynamicResourcesAvailable :
117 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
118 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
119 break;
120
121 case OMX_EventPortFormatDetected :
122 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
123 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
124 break;
125
126 default :
127 OSAL_ErrorTrace("Unknown event received - still making callback");
128 pBaseCompPvt->sAppCallbacks.EventHandler(hComponent,
129 pComp->pApplicationPrivate, eEvent, nData1, nData2, pEventData);
130 break;
131 }
132
133EXIT:
134 return (eError);
135}
136
diff --git a/libstagefrighthw/omx/base/OMX_BaseDIO.c b/libstagefrighthw/omx/base/OMX_BaseDIO.c
new file mode 100644
index 0000000..47110fe
--- /dev/null
+++ b/libstagefrighthw/omx/base/OMX_BaseDIO.c
@@ -0,0 +1,312 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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#define LOG_TAG "OMX_BASE_DIO"
17
18#include <string.h>
19
20#include <OMX_Base.h>
21
22static OMX_PTR OMXBase_DIO_GetPort(OMX_HANDLETYPE hComponent,
23 OMX_U32 nPortIndex);
24/*
25* OMXBase DIO Init
26*/
27OMX_ERRORTYPE OMXBase_DIO_Init (OMX_HANDLETYPE hComponent,
28 OMX_U32 nPortIndex,
29 OMX_STRING cChannelType,
30 OMX_PTR pCreateParams)
31{
32 OMX_ERRORTYPE eError = OMX_ErrorNone;
33 OMX_DIO_Object *hDIO = NULL;
34 OMXBase_Port *pPort = NULL;
35 OMX_BOOL bFound = OMX_FALSE;
36 OMX_U32 i = 0;
37
38// OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *)hComponent;
39// OMXBaseComp *pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
40
41 OMX_CHECK(NULL != cChannelType, OMX_ErrorBadParameter);
42
43 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
44 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
45
46 while( NULL != OMX_DIO_Registered[i].cChannelType ) {
47 if( strcmp(cChannelType, OMX_DIO_Registered[i].cChannelType) == 0 ) {
48 bFound = OMX_TRUE;
49 break;
50 }
51 i++;
52 }
53
54 if( bFound ) {
55 hDIO = (OMX_DIO_Object *) OSAL_Malloc(sizeof(OMX_DIO_Object));
56 OMX_CHECK(NULL != hDIO, OMX_ErrorInsufficientResources);
57 OSAL_Memset(hDIO, 0x0, sizeof(OMX_DIO_Object));
58
59 /* Initialize the DIO object depending on the ChannelType */
60 eError = OMX_DIO_Registered[i].pInitialize(hDIO, pCreateParams);
61 OMX_CHECK(OMX_ErrorNone == eError, eError);
62
63 /* Assign DIO handle to port */
64 pPort->hDIO = hDIO;
65 } else {
66 OMX_CHECK(OMX_FALSE, OMX_ErrorUndefined);
67 }
68
69EXIT:
70 return (eError);
71}
72
73/*
74* OMXBase DIO DeInit
75*/
76OMX_ERRORTYPE OMXBase_DIO_Deinit (OMX_HANDLETYPE hComponent,
77 OMX_U32 nPortIndex)
78{
79 OMX_ERRORTYPE eError = OMX_ErrorNone;
80 OMX_DIO_Object *hDIO = NULL;
81 OMXBase_Port *pPort = NULL;
82
83 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
84 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
85
86 hDIO = (OMX_DIO_Object *)pPort->hDIO;
87 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
88
89 eError = hDIO->deinit(hDIO);
90
91 OSAL_Free(pPort->hDIO);
92 pPort->hDIO = NULL;
93
94EXIT:
95 return (eError);
96}
97
98/*
99* OMXBase DIO Open
100*/
101OMX_ERRORTYPE OMXBase_DIO_Open (OMX_HANDLETYPE hComponent,
102 OMX_U32 nPortIndex,
103 OMX_PTR pOpenParams)
104{
105 OMX_ERRORTYPE eError = OMX_ErrorNone;
106 OMX_DIO_Object *hDIO = NULL;
107 OMXBase_Port *pPort = NULL;
108
109 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
110 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
111
112 hDIO = (OMX_DIO_Object *)pPort->hDIO;
113 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
114
115 eError = hDIO->open(hDIO, (OMX_DIO_OpenParams *)pOpenParams);
116
117EXIT:
118 if( eError == OMX_ErrorNone ) {
119 hDIO->bOpened = OMX_TRUE;
120 }
121 return (eError);
122}
123
124/*
125* OMX Base DIO close
126*/
127OMX_ERRORTYPE OMXBase_DIO_Close (OMX_HANDLETYPE hComponent,
128 OMX_U32 nPortIndex)
129{
130 OMX_ERRORTYPE eError = OMX_ErrorNone;
131 OMX_DIO_Object *hDIO = NULL;
132 OMXBase_Port *pPort = NULL;
133
134 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
135 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
136
137 hDIO = (OMX_DIO_Object *)pPort->hDIO;
138 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
139
140 hDIO->bOpened = OMX_FALSE;
141 eError = hDIO->close(hDIO);
142
143EXIT:
144 return (eError);
145}
146
147/*
148* OMX Base DIO Queue
149*/
150OMX_ERRORTYPE OMXBase_DIO_Queue (OMX_HANDLETYPE hComponent,
151 OMX_U32 nPortIndex,
152 OMX_PTR pBuffHeader)
153{
154 OMX_ERRORTYPE eError = OMX_ErrorNone;
155 OMX_DIO_Object *hDIO = NULL;
156 OMXBase_Port *pPort = NULL;
157
158 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
159 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
160
161 hDIO = (OMX_DIO_Object *)pPort->hDIO;
162 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
163
164 eError = hDIO->queue(hDIO, pBuffHeader);
165
166EXIT:
167 return (eError);
168}
169
170/*
171* OMXBase DIO Dequeue
172*/
173OMX_ERRORTYPE OMXBase_DIO_Dequeue (OMX_HANDLETYPE hComponent,
174 OMX_U32 nPortIndex,
175 OMX_PTR *pBuffHeader)
176{
177 OMX_ERRORTYPE eError = OMX_ErrorNone;
178 OMX_DIO_Object *hDIO = NULL;
179 OMXBase_Port *pPort = NULL;
180
181 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
182 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
183
184 hDIO = (OMX_DIO_Object *)pPort->hDIO;
185 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
186
187 eError = hDIO->dequeue(hDIO, pBuffHeader);
188
189EXIT:
190 return (eError);
191}
192
193/*
194* OMXBase DIO Send
195*/
196OMX_ERRORTYPE OMXBase_DIO_Send (OMX_HANDLETYPE hComponent,
197 OMX_U32 nPortIndex,
198 OMX_PTR pBuffHeader)
199{
200 OMX_ERRORTYPE eError = OMX_ErrorNone;
201 OMX_DIO_Object *hDIO = NULL;
202 OMXBase_Port *pPort = NULL;
203
204 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
205 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
206
207 hDIO = (OMX_DIO_Object *)pPort->hDIO;
208 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
209
210 eError = hDIO->send(hDIO, pBuffHeader);
211
212EXIT:
213 return (eError);
214}
215
216/*
217* OMXBase DIO Cancel
218*/
219OMX_ERRORTYPE OMXBase_DIO_Cancel (OMX_HANDLETYPE hComponent,
220 OMX_U32 nPortIndex,
221 OMX_PTR pBuffHeader)
222{
223 OMX_ERRORTYPE eError = OMX_ErrorNone;
224 OMX_DIO_Object *hDIO = NULL;
225 OMXBase_Port *pPort = NULL;
226
227 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
228 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
229
230 hDIO = (OMX_DIO_Object *)pPort->hDIO;
231 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
232
233 eError = hDIO->cancel(hDIO, pBuffHeader);
234
235EXIT:
236 return (eError);
237}
238
239/*
240* OMXBase DIO Control
241*/
242OMX_ERRORTYPE OMXBase_DIO_Control (OMX_HANDLETYPE hComponent,
243 OMX_U32 nPortIndex,
244 OMX_DIO_CtrlCmdType nCmdType,
245 OMX_PTR pParams)
246{
247 OMX_ERRORTYPE eError = OMX_ErrorNone;
248 OMX_DIO_Object *hDIO = NULL;
249 OMXBase_Port *pPort = NULL;
250
251 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
252 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
253
254 hDIO = (OMX_DIO_Object *)pPort->hDIO;
255 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
256
257 eError = hDIO->control(hDIO, nCmdType, pParams);
258
259EXIT:
260 return (eError);
261}
262
263/*
264* OMX Base DIO GetCount
265*/
266OMX_ERRORTYPE OMXBase_DIO_GetCount (OMX_HANDLETYPE hComponent,
267 OMX_U32 nPortIndex,
268 OMX_U32 *pCount)
269{
270 OMX_ERRORTYPE eError = OMX_ErrorNone;
271 OMX_DIO_Object *hDIO = NULL;
272 OMXBase_Port *pPort = NULL;
273
274 /*Resetting count to 0 initially*/
275 *pCount = 0;
276 pPort = OMXBase_DIO_GetPort(hComponent, nPortIndex);
277 OMX_CHECK(pPort != NULL, OMX_ErrorBadParameter);
278
279 hDIO = (OMX_DIO_Object *)pPort->hDIO;
280 OMX_CHECK(hDIO != NULL, OMX_ErrorBadParameter);
281
282 eError = hDIO->getcount(hDIO, pCount);
283
284EXIT:
285 return (eError);
286}
287
288
289/*
290* OMX Base DIO GetPort from the PortIndex
291*/
292static OMX_PTR OMXBase_DIO_GetPort(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex)
293{
294 OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *)hComponent;
295 OMXBaseComp *pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
296 OMXBase_Port *pPort = NULL;
297 OMX_U32 nStartPortNumber = 0;
298
299 nStartPortNumber = pBaseComp->nMinStartPortIndex;
300 if( pBaseComp->pPorts == NULL ) {
301 pPort = NULL;
302 goto EXIT;
303 }
304 pPort = (OMXBase_Port *)pBaseComp->pPorts[nPortIndex - nStartPortNumber];
305
306EXIT:
307 return (pPort);
308}
309
310
311
312
diff --git a/libstagefrighthw/omx/base/OMX_BaseDIONonTunnel.c b/libstagefrighthw/omx/base/OMX_BaseDIONonTunnel.c
new file mode 100644
index 0000000..dc61ed9
--- /dev/null
+++ b/libstagefrighthw/omx/base/OMX_BaseDIONonTunnel.c
@@ -0,0 +1,648 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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 "OMX_BASE_DIO_NONTUNNEL"
18
19#include <OMX_Base.h>
20#include <OMX_TI_Custom.h>
21
22#include <memplugin.h>
23
24typedef struct DIO_NonTunnel_Attrs {
25 OMX_DIO_CreateParams sCreateParams;
26 OMX_U32 nFlags;
27 OMX_PTR pPipeHandle;
28 OMX_PTR pHdrPool;
29 OMX_PTR pPlatformPrivatePool;
30}DIO_NonTunnel_Attrs;
31
32
33static OMX_ERRORTYPE OMX_DIO_NonTunnel_Open (OMX_HANDLETYPE handle,
34 OMX_DIO_OpenParams *pParams);
35
36static OMX_ERRORTYPE OMX_DIO_NonTunnel_Close (OMX_HANDLETYPE handle);
37
38static OMX_ERRORTYPE OMX_DIO_NonTunnel_Queue (OMX_HANDLETYPE handle,
39 OMX_PTR pBuffHeader);
40
41static OMX_ERRORTYPE OMX_DIO_NonTunnel_Dequeue (OMX_HANDLETYPE handle,
42 OMX_PTR *pBuffHeader);
43
44static OMX_ERRORTYPE OMX_DIO_NonTunnel_Send (OMX_HANDLETYPE handle,
45 OMX_PTR pBuffHeader);
46
47static OMX_ERRORTYPE OMX_DIO_NonTunnel_Cancel (OMX_HANDLETYPE handle,
48 OMX_PTR pBuffHeader);
49
50static OMX_ERRORTYPE OMX_DIO_NonTunnel_Control (OMX_HANDLETYPE handle,
51 OMX_DIO_CtrlCmdType nCmdType,
52 OMX_PTR pParams);
53
54static OMX_ERRORTYPE OMX_DIO_NonTunnel_Getcount (OMX_HANDLETYPE handle,
55 OMX_U32 *pCount);
56
57static OMX_ERRORTYPE OMX_DIO_NonTunnel_Deinit (OMX_HANDLETYPE handle);
58
59/*
60* _DIO_GetPort from Port Index
61*/
62static OMX_PTR _DIO_GetPort(OMX_HANDLETYPE handle, OMX_U32 nPortIndex)
63{
64 OMX_COMPONENTTYPE *pComp;
65 OMXBaseComp *pBaseComp;
66 OMXBase_Port *pPort = NULL;
67 OMX_U32 nStartPortNumber = 0;
68 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
69 DIO_NonTunnel_Attrs *pContext = NULL;
70 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
71
72 pComp = (OMX_COMPONENTTYPE *)(pContext->sCreateParams.hComponent);
73 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
74
75 nStartPortNumber = pBaseComp->nMinStartPortIndex;
76 if( pBaseComp->pPorts == NULL ) {
77 pPort = NULL;
78 goto EXIT;
79 }
80
81 pPort = (OMXBase_Port *)pBaseComp->pPorts[nPortIndex - nStartPortNumber];
82
83EXIT:
84 return (pPort);
85}
86
87/*
88* DIO NoneTunnel Init
89*/
90OMX_ERRORTYPE OMX_DIO_NonTunnel_Init(OMX_HANDLETYPE handle,
91 OMX_PTR pCreateParams)
92{
93 OMX_ERRORTYPE eError = OMX_ErrorNone;
94 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
95 DIO_NonTunnel_Attrs *pContext = NULL;
96
97// OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *)(((OMX_DIO_CreateParams *)(pCreateParams))->hComponent);
98// OMXBaseComp *pBaseComPvt = (OMXBaseComp *)pComp->pComponentPrivate;
99
100 /* creating memory for DIO object private area */
101 hDIO->pContext = OSAL_Malloc(sizeof(DIO_NonTunnel_Attrs));
102 OMX_CHECK(NULL != hDIO->pContext, OMX_ErrorInsufficientResources);
103
104 OSAL_Memset(hDIO->pContext, 0x0, sizeof(DIO_NonTunnel_Attrs));
105
106 hDIO->open = OMX_DIO_NonTunnel_Open;
107 hDIO->close = OMX_DIO_NonTunnel_Close;
108 hDIO->queue = OMX_DIO_NonTunnel_Queue;
109 hDIO->dequeue = OMX_DIO_NonTunnel_Dequeue;
110 hDIO->send = OMX_DIO_NonTunnel_Send;
111 hDIO->cancel = OMX_DIO_NonTunnel_Cancel;
112 hDIO->control = OMX_DIO_NonTunnel_Control;
113 hDIO->getcount = OMX_DIO_NonTunnel_Getcount;
114 hDIO->deinit = OMX_DIO_NonTunnel_Deinit;
115
116 pContext = hDIO->pContext;
117 /* Initialize private data */
118 pContext->sCreateParams = *(OMX_DIO_CreateParams *)pCreateParams;
119
120EXIT:
121 return (eError);
122}
123
124/*
125* DIO NonTunnel DeInit
126*/
127static OMX_ERRORTYPE OMX_DIO_NonTunnel_Deinit (OMX_HANDLETYPE handle)
128{
129 OMX_ERRORTYPE eError = OMX_ErrorNone;
130 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
131 DIO_NonTunnel_Attrs *pContext = NULL;
132
133 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
134 if( NULL != pContext ) {
135 OSAL_Free(pContext);
136 pContext = NULL;
137 }
138
139 return (eError);
140}
141
142/*
143* DIO NonTunnel Open
144*/
145static OMX_ERRORTYPE OMX_DIO_NonTunnel_Open (OMX_HANDLETYPE handle,
146 OMX_DIO_OpenParams *pParams)
147{
148 OMX_ERRORTYPE eError = OMX_ErrorNone;
149 OSAL_ERROR tStatus = OSAL_ErrNone;
150 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
151 DIO_NonTunnel_Attrs *pContext = NULL;
152 OMXBase_Port *pPort = NULL;
153 OMX_U32 i = 0;
154 OMX_U32 nPortIndex = 0;
155 OMX_U32 nStartPortNumber = 0;
156// OMX_U8 *pTmpBuffer = NULL;
157 OMX_U32 nLocalComBuffers = 0;
158 OMX_PTR *pBufArr = NULL;
159
160 OMX_COMPONENTTYPE *pComp = NULL;
161 OMXBaseComp *pBaseComp = NULL;
162
163 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
164 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
165 pComp = (OMX_COMPONENTTYPE *)(pContext->sCreateParams.hComponent);
166 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
167 nStartPortNumber = pBaseComp->nMinStartPortIndex;
168 nPortIndex = pContext->sCreateParams.nPortIndex;
169
170 /* supplier should allocate both the buffer and buffer headers
171 non supplier should allocate only the buffer headers */
172 pPort->pBufferlist = (OMX_BUFFERHEADERTYPE * *)OSAL_Malloc(
173 (pPort->sPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE *)));
174
175 OMX_CHECK(NULL != pPort->pBufferlist, OMX_ErrorInsufficientResources);
176 OSAL_Memset(pPort->pBufferlist, 0, (pPort->sPortDef.nBufferCountActual
177 * sizeof(OMX_BUFFERHEADERTYPE *)));
178 /* create a buffer header pool */
179 pContext->pHdrPool = (OMX_PTR)OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)
180 * (pPort->sPortDef.nBufferCountActual));
181 OMX_CHECK(NULL != pContext->pHdrPool, OMX_ErrorInsufficientResources);
182 OSAL_Memset(pContext->pHdrPool, 0, sizeof(OMX_BUFFERHEADERTYPE) *
183 (pPort->sPortDef.nBufferCountActual));
184
185 pContext->pPlatformPrivatePool = (OMX_PTR)OSAL_Malloc(pPort->sPortDef.nBufferCountActual
186 * sizeof(OMXBase_BufHdrPvtData));
187 OMX_CHECK(NULL != pContext->pPlatformPrivatePool, OMX_ErrorInsufficientResources);
188
189 /*Setting platform port pvt pool to 0*/
190 OSAL_Memset(pContext->pPlatformPrivatePool, 0,
191 pPort->sPortDef.nBufferCountActual *
192 sizeof(OMXBase_BufHdrPvtData));
193
194 if( pPort->bIsBufferAllocator) {
195 //Setting up fields for calling configure
196 nLocalComBuffers = pBaseComp->pPorts[nPortIndex - nStartPortNumber]->sProps.
197 nNumComponentBuffers;
198 if( nLocalComBuffers != 1 && pBaseComp->
199 pPorts[nPortIndex - nStartPortNumber]->sProps.eBufMemoryType !=
200 MEM_TILER8_2D ) {
201 //For non 2D buffers multiple component buffers not supported
202 OMX_CHECK(OMX_FALSE, OMX_ErrorBadParameter);
203 }
204
205 pBufArr = OSAL_Malloc(sizeof(OMX_PTR) * nLocalComBuffers);
206 OMX_CHECK(NULL != pBufArr, OMX_ErrorInsufficientResources);
207 }
208
209 /* update buffer list with buffer and buffer headers */
210 for( i = 0; i < pPort->sPortDef.nBufferCountActual; i++ ) {
211 pPort->pBufferlist[i] = (OMX_BUFFERHEADERTYPE *)(pContext->pHdrPool) + i;
212 OMX_BASE_INIT_STRUCT_PTR(pPort->pBufferlist[i], OMX_BUFFERHEADERTYPE);
213 pPort->pBufferlist[i]->pPlatformPrivate =
214 (OMXBase_BufHdrPvtData *)(pContext->pPlatformPrivatePool) + i;
215
216 ((OMXBase_BufHdrPvtData *)(pPort->pBufferlist[i]->pPlatformPrivate))->bufSt = OWNED_BY_CLIENT;
217 ((OMXBase_BufHdrPvtData *)(pPort->pBufferlist[i]->pPlatformPrivate))->bIsLocked = OMX_FALSE;
218
219 if( pPort->bIsBufferAllocator) {
220 MemHeader *h = &(((OMXBase_BufHdrPvtData *)(pPort->pBufferlist[i]->pPlatformPrivate))->sMemHdr[0]);
221 pPort->pBufferlist[i]->pBuffer = memplugin_alloc_noheader(h, pParams->nBufSize, 1, MEM_CARVEOUT, 0, 0);
222 if( nLocalComBuffers == 2 ) {
223 OMX_CHECK(OMX_FALSE, OMX_ErrorNotImplemented);
224 }
225 }
226 }
227
228 /* create a fixed size OS pipe */
229 tStatus = OSAL_CreatePipe(&pContext->pPipeHandle,
230 (sizeof(OMX_BUFFERHEADERTYPE *) *
231 pPort->sPortDef.nBufferCountActual),
232 sizeof(OMX_BUFFERHEADERTYPE *), 1);
233 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorInsufficientResources);
234 pPort->nCachedBufferCnt = pPort->sPortDef.nBufferCountActual;
235
236
237EXIT:
238 if( pBufArr != NULL ) {
239 OSAL_Free(pBufArr);
240 pBufArr = NULL;
241 }
242 if( OMX_ErrorNone != eError ) {
243 OMX_DIO_NonTunnel_Close(handle);
244 }
245 return (eError);
246}
247
248/*
249* DIO NonTunnel Close
250*/
251static OMX_ERRORTYPE OMX_DIO_NonTunnel_Close(OMX_HANDLETYPE handle)
252{
253 OMX_ERRORTYPE eError = OMX_ErrorNone;
254 OSAL_ERROR tStatus = OSAL_ErrNone;
255 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
256 DIO_NonTunnel_Attrs *pContext = NULL;
257 OMXBase_Port *pPort = NULL;
258 OMX_U32 i = 0, nPortIndex = 0, nStartPortNumber = 0, nCompBufs = 0;
259// OMX_PTR pTmpBuffer = NULL;
260 OMX_COMPONENTTYPE *pComp = NULL;
261 OMXBaseComp *pBaseComp = NULL;
262
263 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
264 OMX_CHECK(pContext != NULL, OMX_ErrorNone);
265
266 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
267 if( pPort ) {
268 pComp = (OMX_COMPONENTTYPE *)(pContext->sCreateParams.hComponent);
269 if( pComp ) {
270 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
271 }
272 if( pBaseComp ) {
273 nStartPortNumber = pBaseComp->nMinStartPortIndex;
274 nPortIndex = pPort->sPortDef.nPortIndex;
275 nCompBufs = pBaseComp->pPorts[nPortIndex - nStartPortNumber]->sProps.nNumComponentBuffers;
276 }
277 if( pPort->pBufferlist ) {
278 for( i = 0; i < pPort->nCachedBufferCnt; i++ ) {
279 if( pPort->pBufferlist[i] ) {
280 if( pPort->bIsBufferAllocator) {
281 MemHeader *h = &(((OMXBase_BufHdrPvtData *)(pPort->pBufferlist[i]->pPlatformPrivate))->sMemHdr[0]);
282 memplugin_free_noheader(h);
283 if( nCompBufs == 2 ) {
284 OMX_CHECK(OMX_FALSE, OMX_ErrorNotImplemented);
285 }
286 }
287 }
288 }
289 /* freeup the buffer list */
290 OSAL_Free(pPort->pBufferlist);
291 pPort->pBufferlist = NULL;
292 pPort->nCachedBufferCnt = 0;
293 }
294 }
295
296 if( pContext->pPlatformPrivatePool ) {
297 OSAL_Free(pContext->pPlatformPrivatePool);
298 }
299 pContext->pPlatformPrivatePool = NULL;
300 if( pContext->pHdrPool ) {
301 OSAL_Free(pContext->pHdrPool);
302 }
303 pContext->pHdrPool = NULL;
304 /* delete a OS pipe */
305 if( pContext->pPipeHandle != NULL ) {
306 tStatus = OSAL_DeletePipe(pContext->pPipeHandle);
307 if( tStatus != OSAL_ErrNone ) {
308 eError = OMX_ErrorUndefined;
309 }
310 pContext->pPipeHandle = NULL;
311 }
312
313EXIT:
314 return (eError);
315}
316
317/*
318* DIO NonTunnel Queue
319*/
320static OMX_ERRORTYPE OMX_DIO_NonTunnel_Queue (OMX_HANDLETYPE handle,
321 OMX_PTR pBuffHeader)
322{
323 OMX_ERRORTYPE eError = OMX_ErrorNone;
324 OSAL_ERROR tStatus = OSAL_ErrNone;
325 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
326 DIO_NonTunnel_Attrs *pContext = NULL;
327 OMX_BUFFERHEADERTYPE *pOMXBufHeader;
328 OMXBase_Port *pPort;
329
330 pOMXBufHeader = (OMX_BUFFERHEADERTYPE *) pBuffHeader;
331 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
332
333 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
334 tStatus = OSAL_WriteToPipe(pContext->pPipeHandle, &pOMXBufHeader,
335 sizeof(pOMXBufHeader), OSAL_SUSPEND);
336 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
337
338EXIT:
339 return (eError);
340}
341
342/*
343* DIO NonTunnel Dequeue
344*/
345static OMX_ERRORTYPE OMX_DIO_NonTunnel_Dequeue (OMX_HANDLETYPE handle,
346 OMX_PTR *pBuffHeader)
347{
348 OMX_ERRORTYPE eError = OMX_ErrorNone;
349 OSAL_ERROR tStatus = OSAL_ErrNone;
350 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
351 DIO_NonTunnel_Attrs *pContext = NULL;
352 OMXBase_Port *pPort;
353 uint32_t actualSize = 0;
354 OMX_BUFFERHEADERTYPE *pOrigOMXBufHeader = NULL;
355 OMX_COMPONENTTYPE *pComp = NULL;
356 OMXBaseComp *pBaseComp = NULL;
357 OMX_U32 nPortIndex, nTimeout;
358
359 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
360 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
361 pComp = (OMX_COMPONENTTYPE *)pContext->sCreateParams.hComponent;
362 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
363 nPortIndex = pPort->sPortDef.nPortIndex;
364 nTimeout = pBaseComp->pPorts[nPortIndex]->sProps.nTimeoutForDequeue;
365 /* dequeue the buffer from the data pipe */
366 tStatus = OSAL_ReadFromPipe(pContext->pPipeHandle, &pOrigOMXBufHeader,
367 sizeof(pOrigOMXBufHeader), &actualSize, nTimeout);
368 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
369
370 /*Cancel the buffer and return warning so that derived component may call
371 GetAttribute*/
372 if( pOrigOMXBufHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG ) {
373 /*Reset codec config flag on o/p port*/
374 if( OMX_DirOutput == pPort->sPortDef.eDir ) {
375 pOrigOMXBufHeader->nFlags &= (~OMX_BUFFERFLAG_CODECCONFIG);
376 } else {
377 tStatus = OSAL_WriteToFrontOfPipe(pContext->pPipeHandle, &pOrigOMXBufHeader,
378 sizeof(pOrigOMXBufHeader), OSAL_NO_SUSPEND);
379 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
380 eError = (OMX_ERRORTYPE)OMX_TI_WarningAttributePending;
381 goto EXIT;
382 }
383 }
384 *pBuffHeader = (OMX_PTR)pOrigOMXBufHeader;
385
386EXIT:
387 return (eError);
388}
389
390/*
391* DIO NonTunnel Send
392*/
393static OMX_ERRORTYPE OMX_DIO_NonTunnel_Send (OMX_HANDLETYPE handle,
394 OMX_PTR pBuffHeader)
395{
396 OMX_ERRORTYPE eError = OMX_ErrorNone;
397 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
398 DIO_NonTunnel_Attrs *pContext = NULL;
399 OMXBase_Port *pPort = NULL;
400 OMX_COMPONENTTYPE *pComp = NULL;
401 OMXBaseComp *pBaseComp = NULL;
402 OMX_CALLBACKTYPE *pAppCallbacks = NULL;
403 OMX_BUFFERHEADERTYPE *pOMXBufHeader;
404
405 pOMXBufHeader = (OMX_BUFFERHEADERTYPE *) pBuffHeader;
406
407 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
408 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
409 pComp = (OMX_COMPONENTTYPE *)pContext->sCreateParams.hComponent;
410 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
411 pAppCallbacks = (OMX_CALLBACKTYPE *)pContext->sCreateParams.pAppCallbacks;
412
413 /* return the buffer back to the Application using EBD or FBD
414 * depending on the direction of the port (input or output) */
415 if (((OMXBase_BufHdrPvtData *)(pOMXBufHeader->pPlatformPrivate))->bufSt != OWNED_BY_CLIENT) {
416 ((OMXBase_BufHdrPvtData *)(pOMXBufHeader->pPlatformPrivate))->bufSt = OWNED_BY_CLIENT;
417 if( OMX_DirInput == pPort->sPortDef.eDir ) {
418 eError = pAppCallbacks->EmptyBufferDone(pComp,
419 pComp->pApplicationPrivate, pOMXBufHeader);
420 } else if( OMX_DirOutput == pPort->sPortDef.eDir ) {
421 eError = pAppCallbacks->FillBufferDone(pComp,
422 pComp->pApplicationPrivate, pOMXBufHeader);
423 }
424 }
425
426 return (eError);
427}
428
429/*
430* DIO NonTunnel Cancel
431*/
432static OMX_ERRORTYPE OMX_DIO_NonTunnel_Cancel (OMX_HANDLETYPE handle,
433 OMX_PTR pBuffHeader)
434{
435 OMX_ERRORTYPE eError = OMX_ErrorNone;
436 OSAL_ERROR tStatus = OSAL_ErrNone;
437 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
438 DIO_NonTunnel_Attrs *pContext = NULL;
439 OMXBase_Port *pPort = NULL;
440 OMX_BUFFERHEADERTYPE *pOMXBufHeader;
441 OMX_COMPONENTTYPE *pComp;
442 OMXBaseComp *pBaseComp;
443 OMXBaseComp_Pvt *pBaseCompPvt;
444 OMX_BOOL bCallProcess = OMX_FALSE;
445
446 pOMXBufHeader = (OMX_BUFFERHEADERTYPE *) pBuffHeader;
447
448 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
449 pPort = (OMXBase_Port*)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
450
451 pComp = (OMX_COMPONENTTYPE *)pContext->sCreateParams.hComponent;
452 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
453 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
454
455 tStatus = OSAL_WriteToFrontOfPipe(pContext->pPipeHandle, &pOMXBufHeader,
456 sizeof(pOMXBufHeader), OSAL_NO_SUSPEND);
457 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
458
459 if( bCallProcess ) {
460 /*Calling process fn so that event to process the buffer can be generated*/
461 pBaseCompPvt->fpInvokeProcessFunction(pComp, DATAEVENT);
462 }
463
464EXIT:
465 return (eError);
466}
467
468
469/*
470* DIO NonTunnel Control
471*/
472static OMX_ERRORTYPE OMX_DIO_NonTunnel_Control (OMX_HANDLETYPE handle,
473 OMX_DIO_CtrlCmdType nCmdType,
474 OMX_PTR pParams)
475{
476 OMX_ERRORTYPE eError = OMX_ErrorNone;
477 OSAL_ERROR tStatus = OSAL_ErrNone;
478 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
479 DIO_NonTunnel_Attrs *pContext = NULL;
480 OMXBase_Port *pPort = NULL;
481 OMX_COMPONENTTYPE *pComp = NULL;
482 OMXBaseComp *pBaseComp = NULL;
483 OMXBaseComp_Pvt *pBaseCompPvt = NULL;
484 OMX_CALLBACKTYPE *pAppCallbacks = NULL;
485 OMX_BUFFERHEADERTYPE *pBuffHeader = NULL;
486 MemHeader *pAttrDesc = NULL;
487 uint32_t elementsInpipe = 0;
488 uint32_t actualSize = 0;
489
490 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
491 pComp = (OMX_COMPONENTTYPE *)pContext->sCreateParams.hComponent;
492 pBaseComp = (OMXBaseComp *)pComp->pComponentPrivate;
493 pBaseCompPvt = (OMXBaseComp_Pvt *)pBaseComp->pPvtData;
494 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
495 pAppCallbacks = (OMX_CALLBACKTYPE *)pContext->sCreateParams.pAppCallbacks;
496
497 switch( nCmdType ) {
498 /* Flush the queues or buffers on a port. Both Flush and Stop perform
499 the same operation i.e. send all the buffers back to the client */
500 case OMX_DIO_CtrlCmd_Stop :
501 case OMX_DIO_CtrlCmd_Flush :
502 /* return all buffers to the IL client using EBD/FBD depending
503 * on the direction(input or output) of port */
504
505 OSAL_GetPipeReadyMessageCount(pContext->pPipeHandle, &elementsInpipe);
506
507 while( elementsInpipe ) {
508 OSAL_ReadFromPipe(pContext->pPipeHandle, &pBuffHeader,
509 sizeof(pBuffHeader), &actualSize, OSAL_NO_SUSPEND);
510 elementsInpipe--;
511 if (((OMXBase_BufHdrPvtData *)(pBuffHeader->pPlatformPrivate))->bufSt != OWNED_BY_CLIENT) {
512 ((OMXBase_BufHdrPvtData *)(pBuffHeader->pPlatformPrivate))->bufSt = OWNED_BY_CLIENT;
513 if( OMX_DirInput == pPort->sPortDef.eDir ) {
514 eError = pAppCallbacks->EmptyBufferDone(pComp,
515 pComp->pApplicationPrivate, pBuffHeader);
516 } else if( OMX_DirOutput == pPort->sPortDef.eDir ) {
517 pBuffHeader->nFilledLen = 0;
518 eError = pAppCallbacks->FillBufferDone(pComp,
519 pComp->pApplicationPrivate, pBuffHeader);
520 }
521 }
522 }
523 break;
524
525 case OMX_DIO_CtrlCmd_Start :
526 /*If there are buffers in the pipe in case of pause to executing
527 then start processing them*/
528 OSAL_GetPipeReadyMessageCount(pContext->pPipeHandle, &elementsInpipe);
529 if( elementsInpipe ) {
530 pBaseCompPvt->fpInvokeProcessFunction(pComp, DATAEVENT);
531 } else {
532 OSAL_ErrorTrace(" Nothing to do ");
533 }
534 break;
535
536 case OMX_DIO_CtrlCmd_GetCtrlAttribute :
537 /*Buffer should be available when calling GetAttribute*/
538 tStatus = OSAL_IsPipeReady(pContext->pPipeHandle);
539 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
540
541 tStatus = OSAL_ReadFromPipe(pContext->pPipeHandle, &pBuffHeader,
542 sizeof(pBuffHeader), &actualSize, OSAL_NO_SUSPEND);
543 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
544 if( !(pBuffHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
545 /*This buffer does not contain codec config*/
546 eError = OMX_ErrorUndefined;
547 /*Write the buffer back to front of pipe*/
548 OSAL_WriteToFrontOfPipe(pContext->pPipeHandle, &pBuffHeader,
549 sizeof(pBuffHeader), OSAL_SUSPEND);
550 goto EXIT;
551 }
552 pAttrDesc = ((OMXBase_CodecConfigBuf*)pParams)->sBuffer;
553 if( pAttrDesc->size < pBuffHeader->nFilledLen ) {
554 tStatus = OSAL_WriteToFrontOfPipe(pContext->pPipeHandle,
555 &pBuffHeader, sizeof(pBuffHeader), OSAL_SUSPEND);
556 pAttrDesc->size = pBuffHeader->nFilledLen;
557
558 eError = (OMX_ERRORTYPE)OMX_TI_WarningInsufficientAttributeSize;
559 goto EXIT;
560 }
561 pAttrDesc->size = pBuffHeader->nFilledLen;
562 OSAL_Memcpy(H2P(pAttrDesc), pBuffHeader->pBuffer + pBuffHeader->nOffset,
563 pAttrDesc->size);
564
565 /*Send the buffer back*/
566 pBuffHeader->nFlags &= (~OMX_BUFFERFLAG_CODECCONFIG);
567 if (((OMXBase_BufHdrPvtData *)(pBuffHeader->pPlatformPrivate))->bufSt != OWNED_BY_CLIENT) {
568 ((OMXBase_BufHdrPvtData *)(pBuffHeader->pPlatformPrivate))->bufSt = OWNED_BY_CLIENT;
569 if( OMX_DirInput == pPort->sPortDef.eDir ) {
570 eError = pAppCallbacks->EmptyBufferDone(pComp,
571 pComp->pApplicationPrivate, pBuffHeader);
572 } else if( OMX_DirOutput == pPort->sPortDef.eDir ) {
573 /*So that the other port does not try to interpret any garbage
574 data that may be present*/
575 pBuffHeader->nFilledLen = 0;
576 eError = pAppCallbacks->FillBufferDone(pComp,
577 pComp->pApplicationPrivate, pBuffHeader);
578 }
579 }
580 break;
581
582 case OMX_DIO_CtrlCmd_SetCtrlAttribute :
583 /*Buffer should be available when calling SetAttribute*/
584 tStatus = OSAL_IsPipeReady(pContext->pPipeHandle);
585 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
586
587 tStatus = OSAL_ReadFromPipe(pContext->pPipeHandle, &pBuffHeader,
588 sizeof(pBuffHeader), &actualSize, OSAL_NO_SUSPEND);
589 OMX_CHECK(OSAL_ErrNone == tStatus, OMX_ErrorUndefined);
590
591 pBuffHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
592 pAttrDesc = ((OMXBase_CodecConfigBuf *)pParams)->sBuffer;
593 if( pBuffHeader->nAllocLen < pAttrDesc->size ) {
594 OSAL_ErrorTrace("Cannot send attribute data, size is too large");
595 tStatus = OSAL_WriteToFrontOfPipe(pContext->pPipeHandle,
596 &pBuffHeader, sizeof(pBuffHeader), OSAL_SUSPEND);
597 eError = OMX_ErrorInsufficientResources;
598 goto EXIT;
599 }
600 pBuffHeader->nFilledLen = pAttrDesc->size;
601 OSAL_Memcpy(pBuffHeader->pBuffer, pAttrDesc->ptr, pAttrDesc->size);
602 if (((OMXBase_BufHdrPvtData *)(pBuffHeader->pPlatformPrivate))->bufSt != OWNED_BY_CLIENT) {
603 ((OMXBase_BufHdrPvtData *)(pBuffHeader->pPlatformPrivate))->bufSt = OWNED_BY_CLIENT;
604 /*Send the buffer*/
605 if( OMX_DirInput == pPort->sPortDef.eDir ) {
606 eError = pAppCallbacks->EmptyBufferDone(pComp,
607 pComp->pApplicationPrivate, pBuffHeader);
608 } else if( OMX_DirOutput == pPort->sPortDef.eDir ) {
609 eError = pAppCallbacks->FillBufferDone(pComp,
610 pComp->pApplicationPrivate, pBuffHeader);
611 }
612 }
613 break;
614
615 default :
616 OSAL_ErrorTrace(" Invalid Command received \n");
617 eError = OMX_ErrorUnsupportedIndex;
618 break;
619 }
620
621EXIT:
622 return (eError);
623}
624
625
626/*
627* DIO Non Tunnel GEtCount
628*/
629static OMX_ERRORTYPE OMX_DIO_NonTunnel_Getcount (OMX_HANDLETYPE handle,
630 OMX_U32 *pCount)
631{
632 OMX_ERRORTYPE eError = OMX_ErrorNone;
633 OMX_DIO_Object *hDIO = (OMX_DIO_Object *)handle;
634 DIO_NonTunnel_Attrs *pContext = NULL;
635 OMXBase_Port *pPort = NULL;
636
637 pContext = (DIO_NonTunnel_Attrs *)hDIO->pContext;
638 pPort = (OMXBase_Port *)_DIO_GetPort(handle, pContext->sCreateParams.nPortIndex);
639 if( pPort->bEosRecd && pPort->sPortDef.eDir == OMX_DirInput ) {
640 eError = (OMX_ERRORTYPE)OMX_TI_WarningEosReceived;
641 }
642
643 OSAL_GetPipeReadyMessageCount(pContext->pPipeHandle, (uint32_t*)pCount);
644
645 return (eError);
646}
647
648
diff --git a/libstagefrighthw/omx/base/OMX_BaseDIOPlugin.h b/libstagefrighthw/omx/base/OMX_BaseDIOPlugin.h
new file mode 100644
index 0000000..3059afe
--- /dev/null
+++ b/libstagefrighthw/omx/base/OMX_BaseDIOPlugin.h
@@ -0,0 +1,181 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
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#ifndef _OMX_BASE_DIO_PLUGIN_H
18#define _OMX_BASE_DIO_PLUGIN_H
19
20#ifdef _cplusplus
21extern "C" {
22#endif
23
24#include <OMX_Core.h>
25#include <OMX_Component.h>
26
27#define OMX_BASE_MAXNAMELEN OMX_MAX_STRINGNAME_SIZE
28
29/* The OMX_DIO_OpenMode enumeration is used to
30 * sepcify the open mode type i.e reader or writer
31 */
32typedef enum OMX_DIO_OpenMode {
33 OMX_DIO_READER = 0x0,
34 OMX_DIO_WRITER = 0x1
35}OMX_DIO_OpenMode;
36
37/** OMX_DIO_CreateParams :
38 * This structure contains the parameters required to
39 * create DIO object
40 *
41 * @param cChannelName : channel name
42 * @param hComponent : Handle of Component
43 * @param nPortIndex : Index of the port
44 * @param pAppCallbacks : Application callbacks
45 */
46typedef struct OMX_DIO_CreateParams {
47 char cChannelName[OMX_BASE_MAXNAMELEN];
48 OMX_HANDLETYPE hComponent;
49 OMX_U8 nPortIndex;
50 OMX_CALLBACKTYPE *pAppCallbacks;
51}OMX_DIO_CreateParams;
52
53
54/** OMX_DIO_OpenParams :
55 * This structure contains the open parameters for DIO object
56 * @param nMode : open mode reader or writer
57 * @param bCacheFlag : cache access flag - true if buffer is accessed via
58 * processor/cache
59 * @param nBufSize : used by non-tunnel open as allocate buffer call
60 * can specify a different size
61 */
62typedef struct OMX_DIO_OpenParams {
63 OMX_U32 nMode;
64 OMX_BOOL bCacheFlag;
65 OMX_U32 nBufSize;
66}OMX_DIO_OpenParams;
67
68typedef OMX_ERRORTYPE (*OMX_DIO_Init)(OMX_IN OMX_HANDLETYPE hComponent,
69 OMX_IN OMX_PTR pCreateParams);
70
71/* OMX_DIO_Register :
72 * This structure contains the params used to register the DIO object
73 * @param pChannelName : Channel Name
74 * @param pInitialize : DIO instace initialization function
75 */
76typedef struct OMX_DIO_Register {
77 const char *cChannelType;
78 OMX_DIO_Init pInitialize;
79}OMX_DIO_Register;
80
81extern OMX_DIO_Register OMX_DIO_Registered[2];
82/*
83 * The OMX_DIO_CtrlCmd_TYPE : This enumeration is used to
84 * specify the action in the
85 * OMX_DIO_Control Macro.
86 *
87 * @ param OMX_DIO_CtrlCmd_Flush : Flush the buffers on this port.
88 * This command is used only by
89 * omx_base for now.
90 * @ param OMX_DIO_CtrlCmd_Start : Start buffer processing on this
91 * port. This command is used only by
92 * omx_base for now.
93 * @ param OMX_DIO_CtrlCmd_Stop : Stop buffer processing on this
94 * port. This command is used only by
95 * omx_base for now.
96 * @ param OMX_DIO_CtrlCmd_GetCtrlAttribute : To get the attribute pending
97 * on this port. A pointer to structure
98 * of type
99 * OMXBase_CodecConfig is
100 * passed as the parameter to the
101 * control command. This should be used
102 * if dio_dequeue returns