portbase.cpp revision cd27ef4881e3b8c9b1ff51a320d84ef71f522e90
1/* 2 * Copyright (C) 2009 Wind River Systems. 3 */ 4 5#include <stdlib.h> 6#include <string.h> 7 8#include <OMX_Core.h> 9#include <OMX_Component.h> 10 11#include <portbase.h> 12#include <componentbase.h> 13 14#define LOG_TAG "portbase" 15#include <log.h> 16 17/* 18 * constructor & destructor 19 */ 20void PortBase::__PortBase(void) 21{ 22 buffer_hdrs = NULL; 23 nr_buffer_hdrs = 0; 24 buffer_hdrs_completion = false; 25 26 pthread_mutex_init(&hdrs_lock, NULL); 27 pthread_cond_init(&hdrs_wait, NULL); 28 29 __queue_init(&bufferq); 30 pthread_mutex_init(&bufferq_lock, NULL); 31 32 memset(&portparam, 0, sizeof(portparam)); 33 memset(&audioparam, 0, sizeof(audioparam)); 34 35 owner = NULL; 36 appdata = NULL; 37 callbacks = NULL; 38} 39 40PortBase::PortBase() 41{ 42 __PortBase(); 43} 44 45PortBase::~PortBase() 46{ 47 struct list *entry, *temp; 48 49 /* should've been already freed at FreeBuffer() */ 50 list_foreach_safe(buffer_hdrs, entry, temp) { 51 free(entry->data); /* OMX_BUFFERHEADERTYPE */ 52 __list_delete(buffer_hdrs, entry); 53 } 54 55 pthread_cond_destroy(&hdrs_wait); 56 pthread_mutex_destroy(&hdrs_lock); 57 58 /* should've been already freed at buffer processing */ 59 queue_free_all(&bufferq); 60 pthread_mutex_destroy(&bufferq_lock); 61} 62 63/* end of constructor & destructor */ 64 65/* 66 * accessor 67 */ 68/* owner */ 69void PortBase::SetOwner(OMX_COMPONENTTYPE *handle) 70{ 71 owner = handle; 72} 73 74OMX_COMPONENTTYPE *PortBase::GetOwner(void) 75{ 76 return owner; 77} 78 79OMX_ERRORTYPE PortBase::SetCallbacks(OMX_HANDLETYPE hComponent, 80 OMX_CALLBACKTYPE *pCallbacks, 81 OMX_PTR pAppData) 82{ 83 if (owner != hComponent) 84 return OMX_ErrorBadParameter; 85 86 appdata = pAppData; 87 callbacks = pCallbacks; 88 89 return OMX_ErrorNone; 90} 91 92/* end of accessor */ 93 94/* 95 * component methods & helpers 96 */ 97/* Get/SetParameter */ 98void PortBase::SetPortParam( 99 const OMX_PARAM_PORTDEFINITIONTYPE *pComponentParameterStructure) 100{ 101 memcpy(&portparam, pComponentParameterStructure, sizeof(portparam)); 102} 103 104const OMX_PARAM_PORTDEFINITIONTYPE *PortBase::GetPortParam(void) 105{ 106 return &portparam; 107} 108 109/* audio parameter */ 110void PortBase::SetAudioPortParam( 111 const OMX_AUDIO_PARAM_PORTFORMATTYPE *pComponentParameterStructure) 112{ 113 memcpy(&audioparam, pComponentParameterStructure, sizeof(audioparam)); 114} 115 116const OMX_AUDIO_PARAM_PORTFORMATTYPE *PortBase::GetAudioPortParam(void) 117{ 118 return &audioparam; 119} 120 121/* Use/Allocate/FreeBuffer */ 122OMX_ERRORTYPE PortBase::UseBuffer(OMX_BUFFERHEADERTYPE **ppBufferHdr, 123 OMX_U32 nPortIndex, 124 OMX_PTR pAppPrivate, 125 OMX_U32 nSizeBytes, 126 OMX_U8 *pBuffer) 127{ 128 OMX_BUFFERHEADERTYPE *buffer_hdr; 129 struct list *entry; 130 OMX_STATETYPE state; 131 132 state = GetOwnerState(); 133 if (state != OMX_StateLoaded) 134 return OMX_ErrorIncorrectStateOperation; 135 136 pthread_mutex_lock(&hdrs_lock); 137 138 if (portparam.bPopulated == OMX_TRUE) { 139 pthread_mutex_unlock(&hdrs_lock); 140 return OMX_ErrorNone; 141 } 142 143 buffer_hdr = (OMX_BUFFERHEADERTYPE *)calloc(1, sizeof(*buffer_hdr)); 144 if (!buffer_hdr) { 145 pthread_mutex_unlock(&hdrs_lock); 146 return OMX_ErrorInsufficientResources; 147 } 148 149 entry = list_alloc(buffer_hdr); 150 if (!entry) { 151 free(buffer_hdr); 152 pthread_mutex_unlock(&hdrs_lock); 153 return OMX_ErrorInsufficientResources; 154 } 155 156 ComponentBase::SetTypeHeader(buffer_hdr, sizeof(*buffer_hdr)); 157 buffer_hdr->pBuffer = pBuffer; 158 buffer_hdr->nAllocLen = nSizeBytes; 159 buffer_hdr->pAppPrivate = pAppPrivate; 160 if (portparam.eDir == OMX_DirInput) { 161 buffer_hdr->nInputPortIndex = nPortIndex; 162 buffer_hdr->nOutputPortIndex = 0x7fffffff; 163 buffer_hdr->pInputPortPrivate = this; 164 buffer_hdr->pOutputPortPrivate = NULL; 165 } 166 else { 167 buffer_hdr->nOutputPortIndex = nPortIndex; 168 buffer_hdr->nInputPortIndex = 0x7fffffff; 169 buffer_hdr->pOutputPortPrivate = this; 170 buffer_hdr->pInputPortPrivate = NULL; 171 } 172 173 buffer_hdrs = __list_add_tail(buffer_hdrs, entry); 174 nr_buffer_hdrs++; 175 176 if (nr_buffer_hdrs >= portparam.nBufferCountActual) { 177 portparam.bPopulated = OMX_TRUE; 178 buffer_hdrs_completion = true; 179 pthread_cond_signal(&hdrs_wait); 180 } 181 182 *ppBufferHdr = buffer_hdr; 183 184 pthread_mutex_unlock(&hdrs_lock); 185 return OMX_ErrorNone; 186} 187 188OMX_ERRORTYPE PortBase::AllocateBuffer(OMX_BUFFERHEADERTYPE **ppBuffer, 189 OMX_U32 nPortIndex, 190 OMX_PTR pAppPrivate, 191 OMX_U32 nSizeBytes) 192{ 193 OMX_BUFFERHEADERTYPE *buffer_hdr; 194 struct list *entry; 195 OMX_STATETYPE state; 196 197 state = GetOwnerState(); 198 if (state != OMX_StateLoaded) 199 return OMX_ErrorIncorrectStateOperation; 200 201 pthread_mutex_lock(&hdrs_lock); 202 if (portparam.bPopulated == OMX_TRUE) { 203 pthread_mutex_unlock(&hdrs_lock); 204 return OMX_ErrorNone; 205 } 206 207 buffer_hdr = (OMX_BUFFERHEADERTYPE *) 208 calloc(1, sizeof(*buffer_hdr) + nSizeBytes); 209 if (!buffer_hdr) { 210 pthread_mutex_unlock(&hdrs_lock); 211 return OMX_ErrorInsufficientResources; 212 } 213 214 entry = list_alloc(buffer_hdr); 215 if (!entry) { 216 free(buffer_hdr); 217 pthread_mutex_unlock(&hdrs_lock); 218 return OMX_ErrorInsufficientResources; 219 } 220 221 ComponentBase::SetTypeHeader(buffer_hdr, sizeof(*buffer_hdr)); 222 buffer_hdr->pBuffer = (OMX_U8 *)buffer_hdr + sizeof(*buffer_hdr); 223 buffer_hdr->nAllocLen = nSizeBytes; 224 buffer_hdr->pAppPrivate = pAppPrivate; 225 if (portparam.eDir == OMX_DirInput) { 226 buffer_hdr->nInputPortIndex = nPortIndex; 227 buffer_hdr->nOutputPortIndex = (OMX_U32)-1; 228 buffer_hdr->pInputPortPrivate = this; 229 buffer_hdr->pOutputPortPrivate = NULL; 230 } 231 else { 232 buffer_hdr->nOutputPortIndex = nPortIndex; 233 buffer_hdr->nInputPortIndex = (OMX_U32)-1; 234 buffer_hdr->pOutputPortPrivate = this; 235 buffer_hdr->pInputPortPrivate = NULL; 236 } 237 238 buffer_hdrs = __list_add_tail(buffer_hdrs, entry); 239 nr_buffer_hdrs++; 240 241 if (nr_buffer_hdrs == portparam.nBufferCountActual) { 242 portparam.bPopulated = OMX_TRUE; 243 buffer_hdrs_completion = true; 244 pthread_cond_signal(&hdrs_wait); 245 } 246 247 *ppBuffer = buffer_hdr; 248 249 pthread_mutex_unlock(&hdrs_lock); 250 return OMX_ErrorNone; 251} 252 253OMX_ERRORTYPE PortBase::FreeBuffer(OMX_U32 nPortIndex, 254 OMX_BUFFERHEADERTYPE *pBuffer) 255{ 256 struct list *entry; 257 OMX_STATETYPE state; 258 OMX_ERRORTYPE ret; 259 260 state = GetOwnerState(); 261 if (state != OMX_StateLoaded) 262 return OMX_ErrorIncorrectStateOperation; 263 264 pthread_mutex_lock(&hdrs_lock); 265 entry = list_find(buffer_hdrs, pBuffer); 266 267 if (!entry) { 268 pthread_mutex_unlock(&hdrs_lock); 269 return OMX_ErrorNone; 270 } 271 272 if (entry->data != pBuffer) { 273 pthread_mutex_unlock(&hdrs_lock); 274 return OMX_ErrorBadParameter; 275 } 276 277 ret = ComponentBase::CheckTypeHeader(pBuffer, sizeof(*pBuffer)); 278 if (ret != OMX_ErrorNone) { 279 pthread_mutex_unlock(&hdrs_lock); 280 return ret; 281 } 282 283 buffer_hdrs = __list_delete(buffer_hdrs, entry); 284 nr_buffer_hdrs--; 285 286 portparam.bPopulated = OMX_FALSE; 287 if (!nr_buffer_hdrs) { 288 buffer_hdrs_completion = true; 289 pthread_cond_signal(&hdrs_wait); 290 } 291 292 free(pBuffer); 293 294 pthread_mutex_unlock(&hdrs_lock); 295 return OMX_ErrorNone; 296} 297 298void PortBase::WaitPortBufferCompletion(void) 299{ 300 pthread_mutex_lock(&hdrs_lock); 301 if (!buffer_hdrs_completion) 302 pthread_cond_wait(&hdrs_wait, &hdrs_lock); 303 buffer_hdrs_completion = !buffer_hdrs_completion; 304 pthread_mutex_unlock(&hdrs_lock); 305} 306 307 /* Empty/FillThisBuffer */ 308OMX_ERRORTYPE PortBase::PushThisBuffer(OMX_BUFFERHEADERTYPE *pBuffer) 309{ 310 int ret; 311 312 pthread_mutex_lock(&bufferq_lock); 313 ret = queue_push_tail(&bufferq, pBuffer); 314 pthread_mutex_unlock(&bufferq_lock); 315 316 if (ret) 317 return OMX_ErrorInsufficientResources; 318 319 return OMX_ErrorNone; 320} 321 322OMX_BUFFERHEADERTYPE *PortBase::PopBuffer(void) 323{ 324 OMX_BUFFERHEADERTYPE *buffer; 325 326 pthread_mutex_lock(&bufferq_lock); 327 buffer = (OMX_BUFFERHEADERTYPE *)queue_pop_head(&bufferq); 328 pthread_mutex_unlock(&bufferq_lock); 329 330 return buffer; 331} 332 333OMX_U32 PortBase::BufferQueueLength(void) 334{ 335 OMX_U32 length; 336 337 pthread_mutex_lock(&bufferq_lock); 338 length = queue_length(&bufferq); 339 pthread_mutex_unlock(&bufferq_lock); 340 341 return length; 342} 343 344OMX_ERRORTYPE PortBase::ReturnThisBuffer(OMX_BUFFERHEADERTYPE *pBuffer) 345{ 346 /* 347 * Todo 348 * Empty/FillThisBufferDone event 349 */ 350 351 return OMX_ErrorNone; 352} 353 354OMX_STATETYPE PortBase::GetOwnerState(void) 355{ 356 OMX_STATETYPE state = OMX_StateInvalid; 357 358 if (owner) { 359 ComponentBase *cbase; 360 cbase = static_cast<ComponentBase *>(owner->pComponentPrivate); 361 if (!cbase) 362 return state; 363 364 cbase->CBaseGetState((void *)owner, &state); 365 } 366 367 return state; 368} 369 370/* end of component methods & helpers */ 371 372/* end of PortBase */ 373