1/*
2 * cmodule.cpp, component module interface class
3 *
4 * Copyright (c) 2009-2010 Wind River Systems, Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include <OMX_Core.h>
24
25#include <cmodule.h>
26#include <componentbase.h>
27
28#define LOG_TAG "cmodule"
29#include <log.h>
30
31/*
32 * constructor / deconstructor
33 */
34CModule::CModule(const OMX_STRING lname)
35{
36    module = NULL;
37    wrs_omxil_cmodule = NULL;
38
39    roles = NULL;
40    nr_roles = 0;
41
42    memset(cname, 0, OMX_MAX_STRINGNAME_SIZE);
43
44    memset(this->lname, 0, OMX_MAX_STRINGNAME_SIZE);
45   // strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE);
46    strncpy(this->lname, lname, (strlen(lname) < OMX_MAX_STRINGNAME_SIZE) ? strlen(lname) : (OMX_MAX_STRINGNAME_SIZE-1));
47    this->lname[OMX_MAX_STRINGNAME_SIZE-1] = '\0';
48}
49
50CModule::~CModule()
51{
52    if (module) {
53        int ref_count;
54
55        while ((ref_count = Unload()));
56    }
57
58    if (roles) {
59        if (roles[0])
60            free(roles[0]);
61        free(roles);
62    }
63}
64
65/* end of constructor / deconstructor */
66
67/*
68 * library loading / unloading
69 */
70OMX_ERRORTYPE CModule::Load(int flag)
71{
72    struct module *m;
73
74    m = module_open(lname, flag);
75    if (!m) {
76        LOGE("module not founded (%s)\n", lname);
77        return OMX_ErrorComponentNotFound;
78    }
79
80    if (m == module)
81        return OMX_ErrorNone;
82
83    wrs_omxil_cmodule = (struct wrs_omxil_cmodule_s *)
84        module_symbol(m, WRS_OMXIL_CMODULE_SYMBOL_STRING);
85    if (!wrs_omxil_cmodule) {
86        LOGE("module %s symbol not founded (%s)\n",
87             lname, WRS_OMXIL_CMODULE_SYMBOL_STRING);
88
89        module_close(m);
90        return OMX_ErrorInvalidComponent;
91    }
92
93    if (module)
94        LOGE("module %s will be overwrite",module->name);
95    module = m;
96    LOGI("module %s successfully loaded\n", lname);
97
98    return OMX_ErrorNone;
99}
100
101OMX_U32 CModule::Unload(void)
102{
103    int ref_count;
104
105    ref_count = module_close(module);
106    if (!ref_count) {
107        module = NULL;
108        wrs_omxil_cmodule = NULL;
109
110        LOGI("module %s successfully unloaded\n", lname);
111    }
112
113    return ref_count;
114}
115
116/* end of library loading / unloading */
117
118/*
119 * accessor
120 */
121OMX_STRING CModule::GetLibraryName(void)
122{
123    return lname;
124}
125
126OMX_STRING CModule::GetComponentName(void)
127{
128    return cname;
129}
130
131OMX_ERRORTYPE CModule::GetComponentRoles(OMX_U32 *nr_roles, OMX_U8 **roles)
132{
133    OMX_U32 i;
134    OMX_U32 this_nr_roles = this->nr_roles;
135
136    if (!roles) {
137        *nr_roles = this_nr_roles;
138        return OMX_ErrorNone;
139    }
140
141    if (!nr_roles || (*nr_roles != this_nr_roles))
142        return OMX_ErrorBadParameter;
143
144    for (i = 0; i < this_nr_roles; i++) {
145        if (!roles[i])
146            break;
147
148        if (roles && roles[i])
149            strncpy((OMX_STRING)&roles[i][0],
150                    (const OMX_STRING)&this->roles[i][0],
151                    OMX_MAX_STRINGNAME_SIZE);
152    }
153
154    if (i != this_nr_roles)
155        return OMX_ErrorBadParameter;
156
157    *nr_roles = this_nr_roles;
158    return OMX_ErrorNone;
159}
160
161bool CModule::QueryHavingThisRole(const OMX_STRING role)
162{
163    OMX_U32 i;
164
165    if (!roles || !role)
166        return false;
167
168    for (i = 0; i < nr_roles; i++) {
169        if (!strcmp((OMX_STRING)&roles[i][0], role))
170            return true;
171    }
172
173    return false;
174}
175
176/* end of accessor */
177
178/*
179 * library symbol method and helpers
180 */
181OMX_ERRORTYPE CModule::InstantiateComponent(ComponentBase **instance)
182{
183    ComponentBase *cbase;
184    OMX_ERRORTYPE ret;
185
186    if (!instance)
187        return OMX_ErrorBadParameter;
188    *instance = NULL;
189
190    if (!wrs_omxil_cmodule)
191        return OMX_ErrorUndefined;
192
193    ret = wrs_omxil_cmodule->ops->instantiate((void **)&cbase);
194    if (ret != OMX_ErrorNone) {
195        LOGE("%s failed to instantiate()\n", lname);
196        return ret;
197    }
198
199    cbase->SetCModule(this);
200    cbase->SetName(cname);
201    ret = cbase->SetRolesOfComponent(nr_roles, (const OMX_U8 **)roles);
202    if (ret != OMX_ErrorNone) {
203        delete cbase;
204        return ret;
205    }
206
207    *instance = cbase;
208    return OMX_ErrorNone;
209}
210
211OMX_ERRORTYPE CModule::QueryComponentNameAndRoles(void)
212{
213    const char *name;
214    OMX_U32 name_len;
215    OMX_U32 copy_name_len;
216
217    const OMX_U8 **roles;
218    OMX_U32 nr_roles;
219    OMX_U32 role_len;
220    OMX_U32 copy_role_len;
221    OMX_U8 **this_roles;
222
223    OMX_U32 i;
224
225    if (this->roles)
226        return OMX_ErrorNone;
227
228    if (!wrs_omxil_cmodule)
229        return OMX_ErrorUndefined;
230
231    roles = (const OMX_U8 **)wrs_omxil_cmodule->roles;
232    nr_roles = wrs_omxil_cmodule->nr_roles;
233
234    this_roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles);
235    if (!this_roles)
236        return OMX_ErrorInsufficientResources;
237
238    this_roles[0] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE * nr_roles);
239    if (!this_roles[0]) {
240        free(this_roles);
241        return OMX_ErrorInsufficientResources;
242    }
243
244    for (i = 0; i < nr_roles; i++) {
245        if (i < nr_roles - 1)
246            this_roles[i+1] = this_roles[i] + OMX_MAX_STRINGNAME_SIZE;
247
248        role_len = strlen((const OMX_STRING)&roles[i][0]);
249        copy_role_len = role_len > OMX_MAX_STRINGNAME_SIZE-1 ?
250            OMX_MAX_STRINGNAME_SIZE-1 : role_len;
251
252        strncpy((OMX_STRING)&this_roles[i][0],
253                (const OMX_STRING)&roles[i][0], copy_role_len);
254        this_roles[i][copy_role_len] = '\0';
255    }
256
257    this->roles = this_roles;
258    this->nr_roles = nr_roles;
259
260    name = wrs_omxil_cmodule->name;
261    name_len = strlen(name);
262    copy_name_len = name_len > OMX_MAX_STRINGNAME_SIZE-1 ?
263        OMX_MAX_STRINGNAME_SIZE-1 : name_len;
264
265    strncpy(&cname[0], name, copy_name_len);
266    cname[copy_name_len] = '\0';
267
268    return OMX_ErrorNone;
269}
270
271/* end of library symbol method and helpers */
272