portbase.cpp revision 7b94bb78335b52b812d8b4137ce80799bb6b9125
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 memset(&portparam, 0, sizeof(portparam)); 30 memset(&audioparam, 0, sizeof(audioparam)); 31} 32 33PortBase::PortBase() 34{ 35 __PortBase(); 36} 37 38PortBase::~PortBase() 39{ 40 struct list *entry, *temp; 41 42 /* should've been already freed at FreeBuffer() */ 43 list_foreach_safe(buffer_hdrs, entry, temp) { 44 free(entry->data); /* OMX_BUFFERHEADERTYPE */ 45 __list_delete(buffer_hdrs, entry); 46 } 47 48 pthread_cond_destroy(&hdrs_wait); 49 pthread_mutex_destroy(&hdrs_lock); 50} 51 52/* end of constructor & destructor */ 53 54/* 55 * accessor 56 */ 57/* owner */ 58void PortBase::SetOwner(OMX_COMPONENTTYPE *handle) 59{ 60 owner = handle; 61} 62 63OMX_COMPONENTTYPE *PortBase::GetOwner(void) 64{ 65 return owner; 66} 67 68/* 69 * component methods & helpers 70 */ 71/* Get/SetParameter */ 72void PortBase::SetPortParam( 73 const OMX_PARAM_PORTDEFINITIONTYPE *pComponentParameterStructure) 74{ 75 memcpy(&portparam, pComponentParameterStructure, sizeof(portparam)); 76} 77 78const OMX_PARAM_PORTDEFINITIONTYPE *PortBase::GetPortParam(void) 79{ 80 return &portparam; 81} 82 83/* audio parameter */ 84void PortBase::SetAudioPortParam( 85 const OMX_AUDIO_PARAM_PORTFORMATTYPE *pComponentParameterStructure) 86{ 87 memcpy(&audioparam, pComponentParameterStructure, sizeof(audioparam)); 88} 89 90const OMX_AUDIO_PARAM_PORTFORMATTYPE *PortBase::GetAudioPortParam(void) 91{ 92 return &audioparam; 93} 94 95/* Use/Allocate/FreeBuffer */ 96OMX_ERRORTYPE PortBase::UseBuffer(OMX_BUFFERHEADERTYPE **ppBufferHdr, 97 OMX_U32 nPortIndex, 98 OMX_PTR pAppPrivate, 99 OMX_U32 nSizeBytes, 100 OMX_U8 *pBuffer) 101{ 102 OMX_BUFFERHEADERTYPE *buffer_hdr; 103 struct list *entry; 104 105 pthread_mutex_lock(&hdrs_lock); 106 107 if (portparam.bPopulated == OMX_TRUE) { 108 pthread_mutex_unlock(&hdrs_lock); 109 return OMX_ErrorNone; 110 } 111 112 buffer_hdr = (OMX_BUFFERHEADERTYPE *)calloc(1, sizeof(*buffer_hdr)); 113 if (!buffer_hdr) { 114 pthread_mutex_unlock(&hdrs_lock); 115 return OMX_ErrorInsufficientResources; 116 } 117 118 entry = list_alloc(buffer_hdr); 119 if (!entry) { 120 free(buffer_hdr); 121 pthread_mutex_unlock(&hdrs_lock); 122 return OMX_ErrorInsufficientResources; 123 } 124 125 ComponentBase::SetTypeHeader(buffer_hdr, sizeof(*buffer_hdr)); 126 buffer_hdr->pBuffer = pBuffer; 127 buffer_hdr->nAllocLen = nSizeBytes; 128 buffer_hdr->pAppPrivate = pAppPrivate; 129 if (portparam.eDir == OMX_DirInput) { 130 buffer_hdr->nInputPortIndex = nPortIndex; 131 buffer_hdr->nOutputPortIndex = 0x7fffffff; 132 buffer_hdr->pInputPortPrivate = this; 133 buffer_hdr->pOutputPortPrivate = NULL; 134 } 135 else { 136 buffer_hdr->nOutputPortIndex = nPortIndex; 137 buffer_hdr->nInputPortIndex = 0x7fffffff; 138 buffer_hdr->pOutputPortPrivate = this; 139 buffer_hdr->pInputPortPrivate = NULL; 140 } 141 142 buffer_hdrs = __list_add_tail(buffer_hdrs, entry); 143 nr_buffer_hdrs++; 144 145 if (nr_buffer_hdrs >= portparam.nBufferCountActual) { 146 portparam.bPopulated = OMX_TRUE; 147 buffer_hdrs_completion = true; 148 pthread_cond_signal(&hdrs_wait); 149 } 150 151 *ppBufferHdr = buffer_hdr; 152 153 pthread_mutex_unlock(&hdrs_lock); 154 return OMX_ErrorNone; 155} 156 157OMX_ERRORTYPE PortBase::AllocateBuffer(OMX_BUFFERHEADERTYPE **ppBuffer, 158 OMX_U32 nPortIndex, 159 OMX_PTR pAppPrivate, 160 OMX_U32 nSizeBytes) 161{ 162 OMX_BUFFERHEADERTYPE *buffer_hdr; 163 struct list *entry; 164 165 pthread_mutex_lock(&hdrs_lock); 166 if (portparam.bPopulated == OMX_TRUE) { 167 pthread_mutex_unlock(&hdrs_lock); 168 return OMX_ErrorNone; 169 } 170 171 buffer_hdr = (OMX_BUFFERHEADERTYPE *) 172 calloc(1, sizeof(*buffer_hdr) + nSizeBytes); 173 if (!buffer_hdr) { 174 pthread_mutex_unlock(&hdrs_lock); 175 return OMX_ErrorInsufficientResources; 176 } 177 178 entry = list_alloc(buffer_hdr); 179 if (!entry) { 180 free(buffer_hdr); 181 pthread_mutex_unlock(&hdrs_lock); 182 return OMX_ErrorInsufficientResources; 183 } 184 185 ComponentBase::SetTypeHeader(buffer_hdr, sizeof(*buffer_hdr)); 186 buffer_hdr->pBuffer = (OMX_U8 *)buffer_hdr + sizeof(*buffer_hdr); 187 buffer_hdr->nAllocLen = nSizeBytes; 188 buffer_hdr->pAppPrivate = pAppPrivate; 189 if (portparam.eDir == OMX_DirInput) { 190 buffer_hdr->nInputPortIndex = nPortIndex; 191 buffer_hdr->nOutputPortIndex = (OMX_U32)-1; 192 buffer_hdr->pInputPortPrivate = this; 193 buffer_hdr->pOutputPortPrivate = NULL; 194 } 195 else { 196 buffer_hdr->nOutputPortIndex = nPortIndex; 197 buffer_hdr->nInputPortIndex = (OMX_U32)-1; 198 buffer_hdr->pOutputPortPrivate = this; 199 buffer_hdr->pInputPortPrivate = NULL; 200 } 201 202 buffer_hdrs = __list_add_tail(buffer_hdrs, entry); 203 nr_buffer_hdrs++; 204 205 if (nr_buffer_hdrs == portparam.nBufferCountActual) { 206 portparam.bPopulated = OMX_TRUE; 207 buffer_hdrs_completion = true; 208 pthread_cond_signal(&hdrs_wait); 209 } 210 211 *ppBuffer = buffer_hdr; 212 213 pthread_mutex_unlock(&hdrs_lock); 214 return OMX_ErrorNone; 215} 216 217OMX_ERRORTYPE PortBase::FreeBuffer(OMX_U32 nPortIndex, 218 OMX_BUFFERHEADERTYPE *pBuffer) 219{ 220 struct list *entry; 221 OMX_ERRORTYPE ret; 222 223 pthread_mutex_lock(&hdrs_lock); 224 entry = list_find(buffer_hdrs, pBuffer); 225 226 if (!entry) { 227 pthread_mutex_unlock(&hdrs_lock); 228 return OMX_ErrorNone; 229 } 230 231 if (entry->data != pBuffer) { 232 pthread_mutex_unlock(&hdrs_lock); 233 return OMX_ErrorBadParameter; 234 } 235 236 ret = ComponentBase::CheckTypeHeader(pBuffer, sizeof(*pBuffer)); 237 if (ret != OMX_ErrorNone) { 238 pthread_mutex_unlock(&hdrs_lock); 239 return ret; 240 } 241 242 buffer_hdrs = __list_delete(buffer_hdrs, entry); 243 nr_buffer_hdrs--; 244 245 portparam.bPopulated = OMX_FALSE; 246 if (!nr_buffer_hdrs) { 247 buffer_hdrs_completion = true; 248 pthread_cond_signal(&hdrs_wait); 249 } 250 251 free(pBuffer); 252 253 pthread_mutex_unlock(&hdrs_lock); 254 return OMX_ErrorNone; 255} 256 257void PortBase::WaitPortBufferCompletion(void) 258{ 259 pthread_mutex_lock(&hdrs_lock); 260 if (!buffer_hdrs_completion) 261 pthread_cond_wait(&hdrs_wait, &hdrs_lock); 262 buffer_hdrs_completion = !buffer_hdrs_completion; 263 pthread_mutex_unlock(&hdrs_lock); 264} 265 266/* end of component methods & helpers */ 267 268/* end of PortBase */ 269