/******************************Public*Routine******************************\ * OMX_Init() * * Description:This method will initialize the OMX Core. It is the * responsibility of the application to call OMX_Init to ensure the proper * set up of core resources. * * Returns: OMX_NOERROR Successful * * Note * \************************************************************************/ OMX_ERRORTYPE OMX_Init() { OMX_ERRORTYPE eError = OMX_ErrorNone; DEBUG_PRINT("%s :: enter!\n", __func__); if(pthread_mutex_lock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex lock\n",__func__); return OMX_ErrorUndefined; } g_InitCount++; if (g_InitCount == 1) { eError = OMX_BuildComponentTable(); } if(pthread_mutex_unlock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex unlock\n",__func__); return OMX_ErrorUndefined; } DEBUG_PRINT("%s :: exit!\n", __func__); return eError; }
/************************************************************************* * OMX_GetRolesOfComponent() * * Description: This method will query the component for its supported roles * *Parameters: * @param[in] cComponentName The name of the component to query * @param[in] pNumRoles The number of roles supported by the component * @param[in] roles The roles of the component * * Returns: OMX_NOERROR Successful * OMX_ErrorBadParameter Faliure due to a bad input parameter * * Note * **************************************************************************/ OMX_ERRORTYPE OMX_GetRolesOfComponent ( OMX_IN OMX_STRING cComponentName, OMX_INOUT OMX_U32 *pNumRoles, OMX_OUT OMX_U8 **roles) { OMX_U32 i = 0; OMX_U32 j = 0; OMX_BOOL bFound = OMX_FALSE; OMX_ERRORTYPE eError = OMX_ErrorNone; if (cComponentName == NULL || pNumRoles == NULL) { eError = OMX_ErrorBadParameter; goto EXIT; } while (i < g_TableCount) { if (strcmp(cComponentName, g_ComponentTable[i].name) == 0) { bFound = OMX_TRUE; break; } i++; } if (!bFound) { eError = OMX_ErrorComponentNotFound; DEBUG_PRINT_ERROR("%s :: component %s not found\n",__func__, cComponentName); goto EXIT; } if (roles == NULL) { *pNumRoles = g_ComponentTable[i].nRoles; } else { /* must be second of two calls, pNumRoles is input in this context. If pNumRoles is < actual number of roles than we return an error */ if (*pNumRoles >= g_ComponentTable[i].nRoles) { for (j = 0; j<g_ComponentTable[i].nRoles; j++) { strncpy((OMX_STRING)roles[j], g_ComponentTable[i].pRoleArray[j], OMX_MAX_STRINGNAME_SIZE); } *pNumRoles = g_ComponentTable[i].nRoles; } else { eError = OMX_ErrorBadParameter; DEBUG_PRINT_ERROR("%s :: pNumRoles (%ld) is less than actual number (%d) of roles for this component %s\n",__func__, *pNumRoles, g_ComponentTable[i].nRoles,cComponentName); } } EXIT: return eError; }
OMX_ERRORTYPE omx_vdec::set_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { ALOGI("set_vendor_extension_config"); if (ext->nIndex >= mVendorExtensionStore.size()) { DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)", ext->nIndex, mVendorExtensionStore.size()); return OMX_ErrorBadParameter; } const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name()); OMX_ERRORTYPE err = OMX_ErrorNone; err = vExt.isConfigValid(ext); if (err != OMX_ErrorNone) { return err; } // mark this as set, regardless of set_config succeeding/failing. // App will know by inconsistent values in output-format vExt.set(); bool valueSet = false; switch ((OMX_U32)vExt.extensionIndex()) { case OMX_QcomIndexParamVideoDecoderPictureOrder: { OMX_S32 pic_order_enable = 0; valueSet |= vExt.readParamInt32(ext, "enable", &pic_order_enable); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_QcomIndexParamVideoDecoderPictureOrder : %d", pic_order_enable); QOMX_VIDEO_DECODER_PICTURE_ORDER decParam; OMX_INIT_STRUCT(&decParam, QOMX_VIDEO_DECODER_PICTURE_ORDER); decParam.eOutputPictureOrder = pic_order_enable ? QOMX_VIDEO_DECODE_ORDER : QOMX_VIDEO_DISPLAY_ORDER; err = set_parameter( NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDecoderPictureOrder, &decParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexParamVideoDecoderPictureOrder failed !"); } break; } default: { return OMX_ErrorNotImplemented; } } return err; }
/* puts a message into the outgoing queue, returns 1 if successful, * 0 otherwise */ uint8_t lwb_send_pkt(uint16_t recipient, uint8_t stream_id, const uint8_t * const data, uint8_t len) { /* data has the max. length LWB_DATA_PKT_PAYLOAD_LEN, lwb header needs * to be added before the data is inserted into the queue */ if(len > LWB_DATA_PKT_PAYLOAD_LEN || !data) { DEBUG_PRINT_ERROR("invalid payload length"); return 0; } uint32_t pkt_addr = fifo_put(&out_buffer); if(FIFO_ERROR != pkt_addr) { #if !LWB_CONF_USE_XMEM /* assume pointers are 16-bit */ uint8_t* next_msg = (uint8_t*)(uint16_t)pkt_addr; *(next_msg) = (uint8_t)recipient; /* recipient L */ *(next_msg + 1) = recipient >> 8; /* recipient H */ *(next_msg + 2) = stream_id; *(next_msg + LWB_CONF_MAX_DATA_PKT_LEN) = len + LWB_CONF_HEADER_LEN; memcpy(next_msg + LWB_CONF_HEADER_LEN, data, len); #else /* LWB_CONF_USE_XMEM */ *(data_buffer) = (uint8_t)recipient; /* recipient L */ *(data_buffer + 1) = recipient >> 8; /* recipient H */ *(data_buffer + 2) = stream_id; *(data_buffer + LWB_CONF_MAX_DATA_PKT_LEN) = len + LWB_CONF_HEADER_LEN; memcpy(data_buffer + LWB_CONF_HEADER_LEN, data, len); /* always read the max length since we don't know how long the packet is */ xmem_write(pkt_addr, LWB_CONF_MAX_DATA_PKT_LEN + 1, data_buffer); #endif /* LWB_CONF_USE_XMEM */ return 1; }
static int get_adie_codec_file_names(void) { DIR *dir; int i; struct dirent *dirent; char *file_names[NUMBER_OF_SUBSTRING] = {"-snd-card", "_codec", "reg"}; for(i = 0; i < NUMBER_OF_SUBSTRING; i++) { dir = opendir(MsmAdieCodecPeek); if (dir == NULL) { #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("%d (%s) opendir %s failed\n", errno, strerror(errno), MsmAdieCodecPeek); #endif return 2; } while (NULL != (dirent = readdir(dir))) { if (strstr (dirent->d_name,file_names[i])) { strlcat(MsmAdieCodecPeek, "/", sizeof(MsmAdieCodecPeek)); strlcat(MsmAdieCodecPeek, dirent->d_name, sizeof(MsmAdieCodecPeek)); strlcat(MsmAdieCodecPoke, "/", sizeof(MsmAdieCodecPoke)); strlcat(MsmAdieCodecPoke, dirent->d_name, sizeof(MsmAdieCodecPoke)); /* If "reg" found don't search anymore */ if (i == (NUMBER_OF_SUBSTRING - 1)) found_codec_path = 1; } } closedir(dir); } return 0; }
bool omx_c2d_conv::init() { bool status = true; if(mLibHandle || mConvertOpen || mConvertClose) { DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); status = false; } if(status) { mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); if(mLibHandle){ mConvertOpen = (createC2DColorConverter_t *) dlsym(mLibHandle,"createC2DColorConverter"); mConvertClose = (destroyC2DColorConverter_t *) dlsym(mLibHandle,"destroyC2DColorConverter"); if(!mConvertOpen || !mConvertClose) status = false; } else status = false; } if(!status && mLibHandle){ dlclose(mLibHandle); mLibHandle = NULL; mConvertOpen = NULL; mConvertClose = NULL; } return status; }
/******************************Public*Routine******************************\ * OMX_DeInit() * * Description:This method will release the resources of the OMX Core. It is the * responsibility of the application to call OMX_DeInit to ensure the clean up of these * resources. * * Returns: OMX_NOERROR Successful * * Note * \**************************************************************************/ OMX_ERRORTYPE OMX_Deinit() { if(pthread_mutex_lock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex lock\n", __func__); return OMX_ErrorUndefined; } if (g_InitCount) { g_InitCount--; } if(pthread_mutex_unlock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex unlock\n", __func__); return OMX_ErrorUndefined; } return OMX_ErrorNone; }
bool omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, int dest_fd, void *dest_base, void *dest_viraddr) { int result; if(!src_viraddr || !dest_viraddr || !c2dcc){ DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); return false; } result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, dest_fd, dest_base, dest_viraddr); DEBUG_PRINT_LOW("\n Color convert status %d",result); return ((result < 0)?false:true); }
void omx_c2d_conv::destroy() { DEBUG_PRINT_ERROR("\n Destroy C2D instance"); if(mLibHandle) { if(mConvertClose && c2dcc) mConvertClose(c2dcc); dlclose(mLibHandle); } c2dcc = NULL; mLibHandle = NULL; mConvertOpen = NULL; mConvertClose = NULL; }
void free_contigous_buffer(venc_user_buf *puser_buf) { HI_MMZ_BUF_S stBuf; OMX_S32 ret; if (!puser_buf) { DEBUG_PRINT_ERROR("%s() invalid param\n", __func__); return; } stBuf.user_viraddr = puser_buf->bufferaddr; stBuf.phyaddr = puser_buf->bufferaddr_Phy; stBuf.bufsize = puser_buf->buffer_size; ret = HI_MMZ_Free(&stBuf); if( 0 != ret) { DEBUG_PRINT_ERROR("~~~~~~ERROR: HI_MMZ_Free (%s) Failed!! Ret:%ld\n",stBuf.bufname,ret); } return ; }
bool omx_c2d_conv::open(unsigned int height,unsigned int width, ColorConvertFormat src, ColorConvertFormat dest) { bool status = false; size_t srcStride = 0; if(!c2dcc) { c2dcc = mConvertOpen(width, height, width, height, src, dest, 0, srcStride); if(c2dcc) { src_format = src; status = true; } else DEBUG_PRINT_ERROR("\n mConvertOpen failed"); } return status; }
/** @brief This function starts command server @param cb pointer to callback function from the client @param client_data reference client wants to get back through callback @return handle to msging thread */ struct amr_ipc_info *omx_amr_thread_create( message_func cb, void* client_data, char* th_name) { int r; int fds[2]; struct amr_ipc_info *amr_info; amr_info = calloc(1, sizeof(struct amr_ipc_info)); if (!amr_info) { return 0; } amr_info->client_data = client_data; amr_info->process_msg_cb = cb; strlcpy(amr_info->thread_name, th_name, sizeof(amr_info->thread_name)); if (pipe(fds)) { DEBUG_PRINT_ERROR("\n%s: pipe creation failed\n", __FUNCTION__); goto fail_pipe; } amr_info->pipe_in = fds[0]; amr_info->pipe_out = fds[1]; r = pthread_create(&amr_info->thr, 0, omx_amr_msg, amr_info); if (r < 0) goto fail_thread; DEBUG_DETAIL("Created thread for %s \n", amr_info->thread_name); return amr_info; fail_thread: close(amr_info->pipe_in); close(amr_info->pipe_out); fail_pipe: free(amr_info); return 0; }
OMX_S32 alloc_contigous_buffer(OMX_U32 buf_size, OMX_U32 align,venc_user_buf *pvenc_buf) { HI_MMZ_BUF_S stBuf = {0}; OMX_S32 ret; venc_user_buf *puser_buf = pvenc_buf; if (!puser_buf) { DEBUG_PRINT_ERROR("%s() invalid param\n", __func__); return -1; } buf_size = (buf_size + align - 1) & ~(align - 1); if ( PORT_DIR_INPUT == puser_buf->dir ) { snprintf(stBuf.bufname,16,"%s",ETB_MMZ_name_table[etb_mmz_cnt++]); } else { snprintf(stBuf.bufname,16,"%s",FTB_MMZ_name_table[ftb_mmz_cnt++]); } stBuf.bufsize = buf_size; ret = HI_MMZ_Malloc(&stBuf); if(0 != ret) { DEBUG_PRINT("~~~~~~ERROR: HI_MMZ_Malloc Failed!! Ret:%ld\n",ret); return -1; } puser_buf->ion_handle = NULL; puser_buf->bufferaddr = stBuf.user_viraddr; puser_buf->bufferaddr_Phy = stBuf.phyaddr; puser_buf->buffer_size = stBuf.bufsize; puser_buf->data_len = 0; puser_buf->offset = 0; puser_buf->pmem_fd = 0; puser_buf->mmaped_size = stBuf.bufsize; /*DEBUG_PRINT("%s() , PHYaddr: %p, bufsize: %d\n", __func__, puser_buf->bufferaddr_Phy, puser_buf->buffer_size);*/ return 0; }
/*---------------------------------------------------------------------------*/ void rtimer_schedule(rtimer_id_t timer, rtimer_clock_t start, rtimer_clock_t period, rtimer_callback_t func) { if((timer < NUM_OF_RTIMERS) && (rt[timer].state != RTIMER_SCHEDULED)) { rt[timer].func = func; rt[timer].period = period; rt[timer].time = start + period; rt[timer].state = RTIMER_SCHEDULED; if(timer >= RTIMER_LF_0) { *(&TA1CCR0 + (timer - RTIMER_LF_0)) = (uint16_t)(start + period); *(&TA1CCTL0 + (timer - RTIMER_LF_0)) = CCIE | OUTMOD_4; } else { *(&TA0CCR0 + timer) = (uint16_t)(start + period); *(&TA0CCTL0 + timer) = CCIE | OUTMOD_4; /* enable interrupt */ } } else { DEBUG_PRINT_ERROR("invalid rtimer ID %u", timer); } }
/*---------------------------------------------------------------------------*/ uint8_t lwb_stream_add(const lwb_stream_req_t* const stream_info) { uint8_t i = 0, idx = 0xff; if(LWB_INVALID_STREAM_ID == stream_info->stream_id) { return 0; } for(; i < LWB_CONF_MAX_N_STREAMS_PER_NODE; i++) { if(streams[i].id == stream_info->stream_id) { /* exists already -> update steam data */ memcpy((uint8_t*)&streams[i] + 2, /* skip the first 2 bytes */ (uint8_t*)stream_info + 4, /* skip the first 4 bytes */ LWB_STREAM_REQ_HEADER_LEN - 4 + LWB_CONF_STREAM_EXTRA_DATA_LEN); streams[i].state = LWB_STREAM_STATE_WAITING; /* rejoin */ lwb_pending_requests |= (1 << i); /* set the 'request pending' bit */ DEBUG_PRINT_INFO("stream with ID %u updated (IPI %u)", stream_info->stream_id, stream_info->ipi); return 1; } if(idx == 0xff && streams[i].state == LWB_STREAM_STATE_INACTIVE) { idx = i; /* this stream is not being used -> take this slot */ } } /* add the new stream */ if(idx != 0xff) { /* copy the stream info (skip the first 2 bytes, the node ID) */ memcpy((uint8_t*)&streams[idx], (uint8_t*)stream_info + 2, (LWB_STREAM_REQ_HEADER_LEN + LWB_CONF_STREAM_EXTRA_DATA_LEN - 2)); streams[idx].state = LWB_STREAM_STATE_WAITING; lwb_pending_requests |= (1 << idx); /* set the 'request pending' bit */ DEBUG_PRINT_INFO("stream with ID %u added (IPI %u)", streams[idx].id, streams[idx].ipi); return 1; } else { DEBUG_PRINT_ERROR("no more space for new streams"); } return 0; }
/*---------------------------- Glossy interface -----------------------------*/ void glossy_start(uint16_t initiator_id, uint8_t *payload, uint8_t payload_len, uint8_t n_tx_max, glossy_sync_t sync, glossy_rf_cal_t rf_cal) { GLOSSY_STARTED; DEBUG_PRINT_VERBOSE("Glossy started: in=%u, pl=%u, n=%u, s=%u", initiator_id, payload_len, n_tx_max, sync); /* disable undesired interrupts */ GLOSSY_DISABLE_INTERRUPTS; /* reset the data structure */ g.active = 1; g.payload = payload; g.payload_len = payload_len; g.n_rx = 0; g.n_tx = 0; g.relay_cnt_last_rx = 0; g.relay_cnt_last_tx = 0; g.t_ref_updated = 0; g.T_slot_sum = 0; g.n_T_slot = 0; #if GLOSSY_CONF_COLLECT_STATS g.stats.last_flood_n_rx_started = 0; g.stats.last_flood_n_rx_fail = 0; g.stats.already_counted = 0; g.stats.last_flood_rssi_sum = 0; g.stats.last_flood_rssi_noise = 0; g.stats.last_flood_t_to_rx = 0; g.stats.last_flood_duration = rtimer_now_hf(); if(WITH_RELAY_CNT()) { /* clear last_flood_rssi and last_flood_hops in one memset call */ memset(g.stats.last_flood_rssi, 0, 6); } #endif /* GLOSSY_CONF_COLLECT_STATS */ /* prepare the Glossy header, with the information known so far */ g.header.initiator_id = initiator_id; SET_PKT_TYPE(g.header.pkt_type, sync, n_tx_max); g.header.relay_cnt = 0; /* automatically switch to TX at the end of RX */ rf1a_set_rxoff_mode(RF1A_OFF_MODE_TX); /* automatically switch to RX at the end of TX */ rf1a_set_txoff_mode(RF1A_OFF_MODE_RX); /* do not calibrate automatically */ rf1a_set_calibration_mode(RF1A_CALIBRATION_MODE_MANUAL); /* re-configure patable (config is lost when radio was in sleep mode) */ rf1a_set_tx_power(RF_CONF_TX_POWER); if(rf_cal == GLOSSY_WITH_RF_CAL) { /* if instructed so, perform a manual calibration */ rf1a_manual_calibration(); } rf1a_set_header_len_rx(GLOSSY_HEADER_LEN(g.header.pkt_type)); rf1a_go_to_idle(); if(IS_INITIATOR()) { /* Glossy initiator */ if(GET_SYNC(g.header.pkt_type) == GLOSSY_UNKNOWN_SYNC || (g.payload_len + GLOSSY_HEADER_LEN(g.header.pkt_type) + 1) > RF_CONF_MAX_PKT_LEN) { /* the initiator must know whether there will be synchronization or * not and the packet length may not exceed the max. length */ DEBUG_PRINT_ERROR("invalid parameters, Glossy stopped"); glossy_stop(); } else { /* start the first transmission */ g.t_timeout = rtimer_now_hf() + TIMEOUT_EXTRA_TICKS; rf1a_start_tx(); rf1a_write_to_tx_fifo((uint8_t *)&g.header, GLOSSY_HEADER_LEN(g.header.pkt_type), (uint8_t *)g.payload, g.payload_len); g.relay_cnt_timeout = 0; } } else { /* Glossy receiver */ rf1a_start_rx(); #if GLOSSY_CONF_COLLECT_STATS /* measure the channel noise (but only if waiting for the schedule */ if(sync == GLOSSY_WITH_SYNC) { /* wait after entering RX mode before reading RSSI (see swra114d.pdf) */ __delay_cycles(MCLK_SPEED / 3000); /* wait 0.33 ms */ g.stats.last_flood_rssi_noise = rf1a_get_rssi(); /* RSSI of the noise floor */ } #endif /* GLOSSY_CONF_COLLECT_STATS */ } /* note: RF_RDY bit must be cleared by the radio core before entering LPM * after a transition from idle to RX or TX. Either poll the status of the * radio core (SNOP strobe) or read the GDOx signal assigned to RF_RDY */ while(RF1AIN & BIT0); /* check GDO0 signal (added by rdaforno) */ }
/* ADIE execute command */ int32_t adie_execute_command(void *input_buf_ptr, uint32_t *resp_buf_length_ptr) { int16_t nCommand = 0; int32_t result = ACPH_SUCCESS; int fd = -1; if(!found_codec_path) { if (get_adie_codec_file_names()) LOGE("failed to get Peek and Poke names\n"); } memcpy(&nCommand,input_buf_ptr, ACPH_COMMAND_ID_LENGTH); switch(nCommand) { /** this is the init on LA */ case ACPH_CMD_ADIE_DAL_ATTACH: { break; } /** this is the deinit on LA */ case ACPH_CMD_ADIE_DAL_DETACH: { break; } case ACPH_CMD_GET_ADIE_REGISTER: { if(resp_buf_length_ptr!=NULL) { int found = 0; int32_t nReqBufLen = 0; int32_t nRespBufLen = 0; uint32_t ultempRegAddr = 0; int32_t lRegValue = 0; uint32_t regAddr = 0; uint32_t regMask = 0; size_t numBytes = 0; uint32_t nOutputBufPos = (uint32_t)acph_main_buffer + ACPH_ACDB_BUFFER_POSITION; char_t *pInputBuf = (char_t *)input_buf_ptr; memcpy(&nReqBufLen, (pInputBuf+ACPH_DATA_LENGTH_POSITION), ACPH_DATA_LENGTH_LENGTH); if(2*ACPH_CAL_DATA_UNIT_LENGTH > nReqBufLen) { #ifdef ACDB_RTC_DEBUG DEBUG_PRINT_ERROR("[ACPH_CMD_GET_ADIE_REGISTER]->insufficient length of req buffer to get data\n"); #endif result = ACPH_ERR_LENGTH_NOT_MATCH; goto end; } else { char_t reg[5], val[3]; reg[4] = '\0', val[2] = '\0'; uint32_t offset = 0; memcpy(®Addr, (pInputBuf+ACPH_HEADER_LENGTH), ACPH_CAL_DATA_UNIT_LENGTH); memcpy(®Mask, (pInputBuf+ACPH_HEADER_LENGTH+ACPH_CAL_DATA_UNIT_LENGTH), ACPH_CAL_DATA_UNIT_LENGTH); fd = open(MsmAdieCodecPeek, O_RDWR); if(fd < 0) { result = ACPH_ERR_ADIE_INIT_FAILURE; #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACPH_CMD_GET_ADIE_REGISTER]->ERROR! cannot open adie peek error: %d, path %s", fd, MsmAdieCodecPeek); #endif goto end; } // First four bytes is register address numBytes = read(fd, rtc_io_buf, RTC_IO_BUF_SIZE); close(fd); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[rtc_apps_intf]->ACPH_CMD_GET_ADIE_REGISTER->byte read[%d]\n",numBytes); #endif if (numBytes <= 0) { // This is an error because if the result = ACPH_ERR_ADIE_GET_CMD_FAILURE; #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACPH_CMD_GET_ADIE_REGISTER]->ERROR! length of written bytes does not match expected value %d", numBytes); #endif //close(fd); goto end; } while(numBytes>offset) { memcpy((void*)reg, (void*)rtc_io_buf+offset, sizeof(uint32_t)); offset += sizeof(uint32_t); ultempRegAddr = strtoul(reg, NULL, 16); offset += 2; memcpy((void*)val, (void*)rtc_io_buf+offset, sizeof(uint16_t)); lRegValue = strtol(val, NULL, 16); offset += 3; #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_GET_ADIE_REGISTER]->reg[%08X],val[%08X]\n", ultempRegAddr, lRegValue); #endif if(ultempRegAddr == regAddr) { found = 1; #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_GET_ADIE_REGISTER]->register[%08X] found from the file!\n",regAddr); #endif break; } } /** make sure the conversion is successful */ if (found == 0) { result = ACPH_ERR_ADIE_GET_CMD_FAILURE; #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACPH_CMD_GET_ADIE_REGISTER]->ERROR! get adie register[0x%x] failed",regAddr); #endif goto end; } else { #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("ACPH_CMD_GET_ADIE_REGISTER command success. Found the value for register = 0x%X, value = 0x%X\n",regAddr,lRegValue); #endif } /* return a masked value */ lRegValue &= regMask; memcpy((void *)nOutputBufPos,(const void *)&lRegValue, sizeof(uint32_t)); nRespBufLen = ACPH_CAL_DATA_UNIT_LENGTH; memcpy((void *)resp_buf_length_ptr, (const void *)&nRespBufLen, sizeof(int32_t)); } }//check for resp_buf_length_ptr break; } case ACPH_CMD_SET_ADIE_REGISTER: { if(NULL!=resp_buf_length_ptr) { int32_t nReqBufLen = 0; int32_t nRespBufLen = 0; uint32_t ulRegValue = 0; uint32_t regAddr = 0; uint32_t regMask = 0; size_t numBytes1 = 0; size_t numBytes2 = 0; char *temp = NULL; char_t *pInputBuf = (char_t *)input_buf_ptr; memcpy(&nReqBufLen, (pInputBuf+ACPH_DATA_LENGTH_POSITION), ACPH_DATA_LENGTH_LENGTH); if(3*ACPH_CAL_DATA_UNIT_LENGTH > nReqBufLen) { #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_SET_ADIE_REGISTER]->insufficient length of req buffer to get data\n"); #endif result = ACPH_ERR_LENGTH_NOT_MATCH; goto end; } else { memcpy(®Addr, (pInputBuf+ACPH_HEADER_LENGTH), ACPH_CAL_DATA_UNIT_LENGTH); memcpy(®Mask, (pInputBuf+ACPH_HEADER_LENGTH+ACPH_CAL_DATA_UNIT_LENGTH), ACPH_CAL_DATA_UNIT_LENGTH); memcpy(&ulRegValue, (pInputBuf+ACPH_HEADER_LENGTH + 2*ACPH_CAL_DATA_UNIT_LENGTH), ACPH_CAL_DATA_UNIT_LENGTH); /* set the value as masked one*/ ulRegValue &= regMask; numBytes1 = asprintf(&temp, "0x%x 0x%x", regAddr, ulRegValue); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("set register request received for ==> reg[%X], val[%X], bytes[%d]\n", regAddr, ulRegValue, numBytes1); #endif fd = open(MsmAdieCodecPoke, O_RDWR); if(fd < 0) { result = ACPH_ERR_ADIE_INIT_FAILURE; #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACPH_CMD_SET_ADIE_REGISTER]->ERROR! cannot open adie poke error: %d, path: %s", fd, MsmAdieCodecPoke); #endif if (temp != NULL) { free(temp); temp=NULL; } goto end; } numBytes2 = write(fd, temp, numBytes1); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("set register ==> actual bytes written[%d]\n", numBytes2); #endif if (temp != NULL) { free(temp); temp=NULL; } close(fd); /** make sure the write is successful */ if (numBytes1 != numBytes2) { result = ACPH_ERR_ADIE_SET_CMD_FAILURE; ACDB_DEBUG_LOG("[ACPH_CMD_SET_ADIE_REGISTER]->ERROR! set adie register failed for Register[0x%X], numBytes[%d]",regAddr ,numBytes1); goto end; } memcpy((void *)resp_buf_length_ptr, (const void *)&nRespBufLen, sizeof(uint32_t)); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_SET_ADIE_REGISTER]->Success\n"); #endif } }//end of checking for resp_buf_length_ptr break; } case ACPH_CMD_GET_MULTIPLE_ADIE_REGISTERS: { if(NULL!=resp_buf_length_ptr) { int32_t nReqBufLen = 0; int32_t nRespBufLen = 0; uint32_t nOutputBufPos = (uint32_t) acph_main_buffer + ACPH_ACDB_BUFFER_POSITION; int32_t nTotalRegisters = 0; int32_t lRegValue = 0; uint32_t ultempRegAddr = 0; size_t numBytes = 0; int32_t i=0; char_t *pInputBuf = (char_t *)input_buf_ptr; char_t *pCurInputBuf = NULL; memcpy(&nReqBufLen, (pInputBuf+ACPH_DATA_LENGTH_POSITION), ACPH_DATA_LENGTH_LENGTH); if(ACPH_CAL_DATA_UNIT_LENGTH>nReqBufLen) { #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_GET_MULTIPLE_ADIE_REGISTERS]->insufficient length of req buffer to get data\n"); #endif result = ACPH_ERR_LENGTH_NOT_MATCH; goto end; } else { char_t reg[5], val[3]; reg[4] = '\0', val[2] = '\0'; uint32_t offset = 0; uint32_t count = 0; uint32_t regAddr = 0; uint32_t regMask = 0; uint32_t found = 1; pCurInputBuf = pInputBuf + ACPH_HEADER_LENGTH; memcpy(&nTotalRegisters,pCurInputBuf,ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; if((0<nTotalRegisters)&& ((nTotalRegisters*2*ACPH_CAL_DATA_UNIT_LENGTH) +ACPH_CAL_DATA_UNIT_LENGTH ==nReqBufLen)&& (ACPH_BUFFER_LENGTH >= nReqBufLen) ) { fd = open(MsmAdieCodecPeek, O_RDWR); if(fd < 0) { result = ACPH_ERR_ADIE_INIT_FAILURE; #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACPH_CMD_GET_MULTIPLE_ADIE_REGISTERS]->ERROR! cannot open adie peek error: %d, path %s", fd, MsmAdieCodecPeek); #endif goto end; } // First four bytes is register address numBytes = read(fd, rtc_io_buf, RTC_IO_BUF_SIZE); if (numBytes <= 0) { // read failure error result = ACPH_ERR_ADIE_GET_CMD_FAILURE; #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACPH_CMD_GET_ADIE_REGISTER]->ERROR! length of written bytes does not match expected value %d", numBytes); #endif close(fd); goto end; } close(fd); } //Perform search for get registers for(i=0; i<nTotalRegisters && found; i++) { memcpy(®Addr,pCurInputBuf,ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; memcpy(®Mask,pCurInputBuf,ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("GET_MULTI-Reg ==> Reg[%08X],Mask[%08X]\n", regAddr, regMask); #endif offset = 0; found = 0; while(numBytes>offset) { memcpy((void*)reg, (void*)rtc_io_buf+offset, sizeof(uint32_t)); offset += sizeof(uint32_t); ultempRegAddr = strtoul(reg, NULL, 16); offset += 2; memcpy((void*)val, (void*)rtc_io_buf+offset, sizeof(uint16_t)); lRegValue = strtol(val, NULL, 16); offset += 3; if(ultempRegAddr == regAddr) { count++; found = 1; /* return a masked value */ lRegValue &= regMask; memcpy((void *)nOutputBufPos,(const void *)&lRegValue, sizeof(uint32_t)); nOutputBufPos += ACPH_CAL_DATA_UNIT_LENGTH; usleep(30); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_GET_ADIE_REGISTER]->reg[%08X],val[%08X], count[%d]\n", ultempRegAddr, lRegValue,count); #endif break; } } } if (found == 0) { ACDB_DEBUG_LOG("GetMultipleAdieReg failed because reg[%08x] is not found\n",regAddr); result = ACPH_ERR_ADIE_GET_CMD_FAILURE; goto end; } if(ACPH_SUCCESS==result && nTotalRegisters == count) { nRespBufLen = sizeof(uint32_t)*(count); memcpy((void *)resp_buf_length_ptr,(const void *)&nRespBufLen,sizeof(int32_t)); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_GET_MULTIPLE_ADIE_REGISTERS]->Success\n"); #endif } else { ACDB_DEBUG_LOG("[ACPH_CMD_GET_MULTIPLE_ADIE_REGISTERS]->Error in lengths of input or output buffers or total registers\n"); result = ACPH_ERR_UNKNOWN_REASON; goto end; } } }//end of checking for resp_buf_length_ptr break; } case ACPH_CMD_SET_MULTIPLE_ADIE_REGISTERS: { if(NULL!=resp_buf_length_ptr) { int32_t nReqBufLen = 0; int32_t nRespBufLen = 0; char_t *pInputBuf = (char_t *)input_buf_ptr; char_t *pCurInputBuf = NULL; int32_t nTotalRegisters = 0; uint32_t ulRegValue = 0; uint32_t regAddr = 0; uint32_t regMask = 0; size_t numBytes1 = 0; size_t numBytes2 = 0; uint32_t i=0; memcpy(&nReqBufLen, (pInputBuf+ACPH_DATA_LENGTH_POSITION), ACPH_DATA_LENGTH_LENGTH); if(ACPH_CAL_DATA_UNIT_LENGTH>nReqBufLen) { #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_SET_MULTIPLE_ADIE_REGISTERS]->insufficient length of req buffer to get data\n"); #endif result = ACPH_ERR_LENGTH_NOT_MATCH; goto end; } else { pCurInputBuf = pInputBuf + ACPH_HEADER_LENGTH; memcpy(&nTotalRegisters,pCurInputBuf,ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; if((0<nTotalRegisters)&& (nReqBufLen==(nTotalRegisters*3*ACPH_CAL_DATA_UNIT_LENGTH)+ ACPH_CAL_DATA_UNIT_LENGTH) ) { for(i=0;i<nTotalRegisters;i++) { char *temp = NULL; memcpy(®Addr,pCurInputBuf,ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; memcpy(®Mask,pCurInputBuf,ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; memcpy(&ulRegValue, pCurInputBuf, ACPH_CAL_DATA_UNIT_LENGTH); pCurInputBuf += ACPH_CAL_DATA_UNIT_LENGTH; #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("SET_MULTI-Reg ==> Reg[%08X],Val[%08X], Mask[%08X]\n", regAddr, ulRegValue, regMask); #endif /* set the value as masked one*/ ulRegValue &= regMask; numBytes1 = asprintf(&temp, "0x%x 0x%x", regAddr, ulRegValue); fd = open(MsmAdieCodecPoke, O_RDWR); if(fd < 0) { #ifdef DEBUG_PRINT_ERROR ACDB_DEBUG_LOG("[ACPH_CMD_GET_ADIE_REGISTER]->ERROR! cannot open adie poke error: %d, path %s", fd, MsmAdieCodecPoke); #endif result = ACPH_ERR_ADIE_INIT_FAILURE; if (temp != NULL) { free(temp); temp=NULL; } goto end; } numBytes2 = write(fd, temp, numBytes1); if (temp != NULL) { free(temp); temp=NULL; } close(fd); /** make sure the write is successful */ if (numBytes1 != numBytes2) { ACDB_DEBUG_LOG("[ACPH_CMD_SET_MULTIPLE_ADIE_REGISTERS]->set multi register failed, numBytes1[%d],numBytes2[%d]\n", numBytes1, numBytes2); result = ACPH_ERR_ADIE_GET_CMD_FAILURE; goto end; } usleep(30); }//end of for loop memcpy((void *)resp_buf_length_ptr, (const void *)&nRespBufLen, sizeof(int32_t)); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACPH_CMD_SET_MULTIPLE_ADIE_REGISTERS]->success\n"); #endif }//end of checking for input buf length and total registers else { ACDB_DEBUG_LOG("[ACPH_CMD_SET_MULTIPLE_ADIE_REGISTERS]->Error in lengths of input or output buffers or total registers\n"); result = ACPH_ERR_UNKNOWN_REASON; goto end; } } }//end of checking for resp_buf_length_ptr break; }//end of case ACPH_CMD_SET_MULTIPLE_ADIE_REGISTERS default: { #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("Cannot recognize the ACPH_ADIE command\n"); result = ACPH_ERR_INVALID_COMMAND; #endif break; } } end: return result; }
/** * FUNCTION : query_voc_all_active_streams * * DESCRIPTION : query for all active voice streams * * DEPENDENCIES : CSD needs to be available and initialized * * PARAMS: * req_buf_ptr - pointer to request buffer * resp_buf_ptr - pointer to response buffer * resp_buf_length - length of the response buffer * * RETURN VALUE : None * * SIDE EFFECTS : None * * Expected data input: None * * Expected data output: * number of streams (32-bit) * voice_stream_array[n] * Each element of voice_stream_array is: * cvs_handle (32-bit) * voc_vs_handle (32-bit) * */ void query_voc_all_active_streams (char_t *req_buf_ptr, char_t **resp_buf_ptr, uint32_t *resp_buf_length ) { /* assumption is there will only be 1 stream, so it will at most * have 1 cvs_handle, 1 cvp_handle */ uint8_t* nBufferPointer = (uint8_t *)(acph_main_buffer + ACPH_ACDB_BUFFER_POSITION); size_t bytes_read = 0; uint32_t num_streams = 0; uint32_t my_cvs_handle = 0; int i,fd, result; uint32_t real_tx_acdb_id = 0, real_rx_acdb_id = 0; if (NULL == acph_main_buffer) { #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACDB RTC ERROR]->(get voc all active strm)->null acph_main_buffer\n"); #endif /**not initilized*/ create_error_resp(ACPH_ERR_UNKNOWN_REASON, req_buf_ptr, resp_buf_ptr, resp_buf_length); return; } /** open device control debugfs */ fd = open(RtacDev, O_RDWR); if (fd < 0) { create_error_resp(ACPH_ERR_CSD_OPEN_HANDLE, req_buf_ptr, resp_buf_ptr, resp_buf_length); #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACDB RTC ERROR]->(get voc all active strm)->open device control, response [%d]\n", fd); #endif return; } /* get the voice info from debugfs */ #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACDB RTC]->(get voc all active strm)->enter ioctl\n"); #endif bytes_read = ioctl(fd, AUDIO_GET_RTAC_VOICE_INFO, &active_voice_info); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACDB RTC]->(get voc all active strm)->exit ioctl, actual byte read[%d]\n",bytes_read); #endif /* close debugfs after read */ close(fd); if (bytes_read <= 0 || active_voice_info.num_of_voice_combos > RTC_MAX_ACTIVE_VOC_DEVICES) { #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACDB RTC]->(get voc all active strm)->bytes read less than 0 or number of active dev pair > %d\n", RTC_MAX_ACTIVE_VOC_DEVICES); #endif create_error_resp(ACPH_ERR_CSD_VOC_CMD_FAILURE, req_buf_ptr, resp_buf_ptr, resp_buf_length); return; } /* prepare response buffer */ for (i=0; i<(int)active_voice_info.num_of_voice_combos; i++) { num_streams++; nBufferPointer += sizeof(uint32_t); /* QACT is expecting a 32-bit number */ my_cvs_handle = (uint32_t)active_voice_info.voice_combo[i].cvs_handle; memcpy(nBufferPointer, &my_cvs_handle, sizeof(uint32_t)); nBufferPointer += sizeof(uint32_t); memcpy(nBufferPointer, &my_cvs_handle, sizeof(uint32_t)); } memcpy(acph_main_buffer + ACPH_ACDB_BUFFER_POSITION, &num_streams, sizeof(uint32_t)); create_suc_resp((num_streams*2+1)*sizeof(uint32_t), req_buf_ptr, resp_buf_ptr, resp_buf_length); }
/******************************Public*Routine******************************\ * OMX_FreeHandle() * * Description:This method will unload the OMX component pointed by * OMX_HANDLETYPE. It is the responsibility of the calling method to ensure that * the Deinit method of the component has been called prior to unloading component * * Parameters: * @param[in] hComponent the component to unload * * Returns: OMX_NOERROR Successful * * Note * \**************************************************************************/ OMX_ERRORTYPE OMX_FreeHandle (OMX_HANDLETYPE hComponent) { OMX_ERRORTYPE retVal = OMX_ErrorUndefined; OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)hComponent; OMX_U32 refIndex = 0; OMX_S32 handleIndex = 0; OMX_U32 i = 0; if(pthread_mutex_lock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex lock\n", __func__); return OMX_ErrorUndefined; } /* Locate the component handle in the array of handles */ for(i = 0; i < COUNTOF(pModules); i++) { if(pComponents[i] == hComponent) { break; } } if(i == COUNTOF(pModules)) { DEBUG_PRINT_ERROR("%s :: Core: component %p is not found\n", __func__, hComponent); retVal = OMX_ErrorBadParameter; goto EXIT; } /* call component deinit method */ retVal = pHandle->ComponentDeInit(hComponent); if (retVal != OMX_ErrorNone) { DEBUG_PRINT_ERROR("%s :: ComponentDeInit failed %d\n", __func__, retVal); goto EXIT; } for (refIndex=0; refIndex < MAX_TABLE_SIZE; refIndex++) { for (handleIndex=0; handleIndex < g_ComponentTable[refIndex].refCount; handleIndex++) { /* get the position for the component in the table */ if (g_ComponentTable[refIndex].pHandle[handleIndex] == hComponent) { if (g_ComponentTable[refIndex].refCount) { g_ComponentTable[refIndex].refCount -= 1; } g_ComponentTable[refIndex].pHandle[handleIndex] = NULL; #ifdef DYNAMIC_LOAD dlclose(pModules[i]); #endif pModules[i] = NULL; free(pComponents[i]); pComponents[i] = NULL; retVal = OMX_ErrorNone; goto EXIT; } } } // If we are here, we have not found the matching component retVal = OMX_ErrorComponentNotFound; EXIT: /* The unload is now complete, so set the error code to pass and exit */ if(pthread_mutex_unlock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex unlock\n", __func__); return OMX_ErrorUndefined; } return retVal; }
OMX_ERRORTYPE OMX_GetHandle( OMX_HANDLETYPE* pHandle, OMX_STRING cComponentName, OMX_PTR pAppData, OMX_CALLBACKTYPE* pCallBacks) { static const char prefix[] = "lib"; static const char postfix[] = ".so"; OMX_ERRORTYPE (*pComponentInit)(OMX_HANDLETYPE, OMX_STRING); OMX_ERRORTYPE err = OMX_ErrorNone; OMX_COMPONENTTYPE *componentType; #ifdef DYNAMIC_LOAD const char *pErr = dlerror(); #endif OMX_U32 refIndex = 0; OMX_U32 i = 0; DEBUG_PRINT("%s :: enter!\n", __func__); DEBUG_PRINT("%s :: component name:%s !\n", __func__, cComponentName); if(pthread_mutex_lock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex lock\n",__func__); return OMX_ErrorUndefined; } if ((NULL == cComponentName) || (NULL == pHandle) || (NULL == pCallBacks)) { err = OMX_ErrorBadParameter; DEBUG_PRINT_ERROR("%s :: invalid param!\n", __func__); goto UNLOCK_MUTEX; } /* Verify that the name is not too long and could cause a crash. Notice * that the comparison is a greater than or equals. This is to make * sure that there is room for the terminating NULL at the end of the * name. */ if(strlen(cComponentName) >= MAX_COMP_NAME_LEN) { err = OMX_ErrorInvalidComponentName; DEBUG_PRINT_ERROR("%s :: invalid component name!\n", __func__); goto UNLOCK_MUTEX; } /* Locate the first empty slot for a component. If no slots * are available, error out */ for(i = 0; i < COUNTOF(pModules); i++) { if(pModules[i] == NULL) { break; } } if(i == COUNTOF(pModules)) { err = OMX_ErrorInsufficientResources; DEBUG_PRINT_ERROR("%s :: modules load too much!\n", __func__); goto UNLOCK_MUTEX; } for (refIndex = 0; refIndex < MAX_TABLE_SIZE; refIndex++) { char buf[sizeof(prefix) + MAX_COMP_NAME_LEN + sizeof(postfix)]; //get the index for the component in the table if (strcmp(g_ComponentTable[refIndex].name, cComponentName) != 0) { continue; } /* check if the component is already loaded */ if (g_ComponentTable[refIndex].refCount >= MAX_COMP_INSTANCES) { err = OMX_ErrorInsufficientResources; DEBUG_PRINT_ERROR("%s :: Max instances of component %s already created.\n", __func__, cComponentName); goto UNLOCK_MUTEX; } /* load the component and check for an error. If filename is not an * absolute path (i.e., it does not begin with a "/"), then the * file is searched for in the following locations: * * The LD_LIBRARY_PATH environment variable locations * The library cache, /etc/ld.so.cache. * /lib * /usr/lib * * If there is an error, we can't go on, so set the error code and exit */ /* the lengths are defined herein or have been * checked already, so strcpy and strcat are * are safe to use in this context. */ strncpy(buf, prefix, sizeof(prefix)); strncat(buf, cComponentName, strlen(cComponentName)); strncat(buf, postfix, sizeof(postfix)); DEBUG_PRINT("%s :: prepare to load %s\n", __func__, buf); #ifdef DYNAMIC_LOAD pModules[i] = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); if( pModules[i] == NULL ) { DEBUG_PRINT_ERROR("%s :: dlopen %s failed because %s\n", __func__, buf, dlerror()); err = OMX_ErrorComponentNotFound; goto UNLOCK_MUTEX; } /* Get a function pointer to the "OMX_ComponentInit" function. If * there is an error, we can't go on, so set the error code and exit */ pComponentInit = dlsym(pModules[i], "component_init"); pErr = dlerror(); if( (pErr != NULL) || (pComponentInit == NULL) ) { DEBUG_PRINT_ERROR("%s:: dlsym failed for module %p\n", __func__, pModules[i]); err = OMX_ErrorComponentNotFound; goto CLEAN_UP; } #else extern OMX_ERRORTYPE component_init(OMX_HANDLETYPE, OMX_STRING); pComponentInit = OMX_ComponentInit; #endif DEBUG_PRINT("%s :: load %s ok\n", __func__, buf); *pHandle = malloc(sizeof(OMX_COMPONENTTYPE)); if(*pHandle == NULL) { err = OMX_ErrorInsufficientResources; DEBUG_PRINT_ERROR("%s:: malloc of pHandle* failed\n", __func__); goto CLEAN_UP; } /* We now can access the dll. So, we need to call the "OMX_ComponentInit" * method to load up the "handle" (which is just a list of functions to * call) and we should be all set.*/ pComponents[i] = *pHandle; componentType = (OMX_COMPONENTTYPE*) *pHandle; componentType->nSize = sizeof(OMX_COMPONENTTYPE); err = (*pComponentInit)(*pHandle, cComponentName); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("%s :: OMX_ComponentInit failed 0x%08x\n", __func__, err); goto CLEAN_UP; } err = (componentType->SetCallbacks)(*pHandle, pCallBacks, pAppData); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("%s :: Core: SetCallBack failed %d\n", __func__, err); goto CLEAN_UP; } /* finally, OMX_ComponentInit() was successful and SetCallbacks was successful, we have a valid instance, so now we increase refCount */ g_ComponentTable[refIndex].pHandle[g_ComponentTable[refIndex].refCount] = *pHandle; g_ComponentTable[refIndex].refCount += 1; goto UNLOCK_MUTEX; // Component is found, and thus we are done } // If we are here, we have not found the component err = OMX_ErrorComponentNotFound; goto UNLOCK_MUTEX; CLEAN_UP: if(*pHandle != NULL) { free(*pHandle); *pHandle = NULL; } pComponents[i] = NULL; #ifdef DYNAMIC_LOAD dlclose(pModules[i]); #endif pModules[i] = NULL; UNLOCK_MUTEX: if(pthread_mutex_unlock(&g_Mutex) != 0) { DEBUG_PRINT_ERROR("%s :: Core: Error in Mutex unlock\n", __func__); err = OMX_ErrorUndefined; } return (err); }
/*=========================================================================== FUNCTION: HEVC_Utils::iSNewFrame DESCRIPTION: Returns true if NAL parsing successfull otherwise false. INPUT/OUTPUT PARAMETERS: <In> buffer : buffer containing start code or nal length + NAL units buffer_length : the length of the NAL buffer start_code : If true, start code is detected, otherwise size nal length is detected size_of_nal_length_field: size of nal length field <out> isNewFrame: true if the NAL belongs to a differenet frame false if the NAL belongs to a current frame RETURN VALUE: boolean true, if nal parsing is successful false, if the nal parsing has errors SIDE EFFECTS: None. ===========================================================================*/ bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, OMX_IN OMX_U32 size_of_nal_length_field, OMX_OUT OMX_BOOL &isNewFrame) { OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer; OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen; byte bFirstSliceInPic = 0; byte coef1=1, coef2=0, coef3=0; uint32 pos = 0; uint32 nal_len = buffer_length; uint32 sizeofNalLengthField = 0; uint32 zero_count; boolean start_code = (size_of_nal_length_field==0)?true:false; if (start_code) { // Search start_code_prefix_one_3bytes (0x000001) coef2 = buffer[pos++]; coef3 = buffer[pos++]; do { if (pos >= buffer_length) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } coef1 = coef2; coef2 = coef3; coef3 = buffer[pos++]; } while (coef1 || coef2 || coef3 != 1); } else if (size_of_nal_length_field) { /* This is the case to play multiple NAL units inside each access unit*/ /* Extract the NAL length depending on sizeOfNALength field */ sizeofNalLengthField = size_of_nal_length_field; nal_len = 0; while (size_of_nal_length_field--) { nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3); } if (nal_len >= buffer_length) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } } if (nal_len > buffer_length) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } if (pos + 2 > (nal_len + sizeofNalLengthField)) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } nalu_type = (buffer[pos] & 0x7E)>>1 ; //=== nal_unit_type DEBUG_PRINT_LOW("@#@# Pos = %x NalType = %x buflen = %u", pos-1, nalu_type, (unsigned int) buffer_length); isNewFrame = OMX_FALSE; if (nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_SEI) { DEBUG_PRINT_LOW("Non-AU boundary with NAL type %d", nalu_type); if (m_au_data) { isNewFrame = OMX_TRUE; m_au_data = false; } m_forceToStichNextNAL = true; } else if (nalu_type <= NAL_UNIT_RESERVED_23) { DEBUG_PRINT_LOW("AU Boundary with NAL type %d ", nalu_type); if (!m_forceToStichNextNAL) { bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7); if (bFirstSliceInPic) { //=== first_ctb_in_slice is only 1'b1 coded tree block DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block"); isNewFrame = OMX_TRUE; } }
/************************************************************************* * OMX_GetComponentsOfRole() * * Description: This method will query the component for its supported roles * *Parameters: * @param[in] role The role name to query for * @param[in] pNumComps The number of components supporting the given role * @param[in] compNames The names of the components supporting the given role * * Returns: OMX_NOERROR Successful * * Note * **************************************************************************/ OMX_ERRORTYPE OMX_GetComponentsOfRole ( OMX_IN OMX_STRING role, OMX_INOUT OMX_U32 *pNumComps, OMX_INOUT OMX_U8 **compNames) { OMX_U32 i = 0; OMX_U32 j = 0; OMX_U32 k = 0; OMX_U32 compOfRoleCount = 0; OMX_ERRORTYPE eError = OMX_ErrorNone; if (role == NULL || pNumComps == NULL) { if (role == NULL) { DEBUG_PRINT_ERROR("%s :: role is NULL", __func__); } if (pNumComps == NULL) { DEBUG_PRINT_ERROR("%s :: pNumComps is NULL\n", __func__); } eError = OMX_ErrorBadParameter; goto EXIT; } /* This implies that the g_ComponentTable is not filled */ if (!g_TableCount) { eError = OMX_ErrorUndefined; DEBUG_PRINT_ERROR("%s :: Component table is empty. Please reload OMX Core\n", __func__); goto EXIT; } /* no matter, we always want to know number of matching components so this will always run */ for (i = 0; i < g_TableCount; i++) { for (j = 0; j < g_ComponentTable[i].nRoles; j++) { if (strcmp(g_ComponentTable[i].pRoleArray[j], role) == 0) { /* the first call to this function should only count the number of roles*/ compOfRoleCount++; } } } if (compOfRoleCount == 0) { eError = OMX_ErrorComponentNotFound; DEBUG_PRINT_ERROR("%s :: Component supporting role %s was not found\n", __func__, role); } if (compNames == NULL) { /* must be the first of two calls */ *pNumComps = compOfRoleCount; } else { /* must be the second of two calls */ if (*pNumComps < compOfRoleCount) { /* pNumComps is input in this context, it can not be less, this would indicate the array is not large enough */ eError = OMX_ErrorBadParameter; DEBUG_PRINT_ERROR("%s :: pNumComps (%ld) is less than the actual number (%ld) of components supporting role %s\n", __func__, *pNumComps, compOfRoleCount, role); } else { k = 0; for (i = 0; i < g_TableCount; i++) { for (j = 0; j < g_ComponentTable[i].nRoles; j++) { if (strcmp(g_ComponentTable[i].pRoleArray[j], role) == 0) { /* the second call compNames can be allocated with the proper size for that number of roles. */ compNames[k] = (OMX_U8*)g_ComponentTable[i].name; k++; if (k == compOfRoleCount) { /* there are no more components of this role so we can exit here */ *pNumComps = k; goto EXIT; } } } } } } EXIT: return eError; }
OMX_ERRORTYPE omx_video::set_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { ALOGI("set_vendor_extension_config"); if (ext->nIndex >= mVendorExtensionStore.size()) { DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)", ext->nIndex, mVendorExtensionStore.size()); return OMX_ErrorBadParameter; } const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name()); OMX_ERRORTYPE err = OMX_ErrorNone; err = vExt.isConfigValid(ext); if (err != OMX_ErrorNone) { return err; } // mark this as set, regardless of set_config succeeding/failing. // App will know by inconsistent values in output-format vExt.set(); bool valueSet = false; switch ((OMX_U32)vExt.extensionIndex()) { case OMX_IndexConfigCommonRotate: { OMX_CONFIG_ROTATIONTYPE rotationParam; memcpy(&rotationParam, &m_sConfigFrameRotation, sizeof(OMX_CONFIG_ROTATIONTYPE)); valueSet |= vExt.readParamInt32(ext, "angle", &rotationParam.nRotation); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_IndexConfigCommonRotate : %d", rotationParam.nRotation); err = set_config( NULL, OMX_IndexConfigCommonRotate, &rotationParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigCommonRotate failed !"); } break; } case OMX_IndexConfigVideoAVCIntraPeriod: { OMX_VIDEO_CONFIG_AVCINTRAPERIOD idrConfig; memcpy(&idrConfig, &m_sConfigAVCIDRPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD)); valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(idrConfig.nPFrames)); valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(idrConfig.nIDRPeriod)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: AVC-intra-period : nP=%d, nIDR=%d", idrConfig.nPFrames, idrConfig.nIDRPeriod); err = set_config( NULL, OMX_IndexConfigVideoAVCIntraPeriod, &idrConfig); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigVideoAVCIntraPeriod failed !"); } break; } case OMX_IndexParamVideoErrorCorrection: { OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ecParam; memcpy(&ecParam, &m_sErrorCorrection, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); valueSet |= vExt.readParamInt32(ext, "resync-marker-spacing-bits", (OMX_S32 *)&(ecParam.nResynchMarkerSpacing)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: resync-marker-spacing : %d bits", ecParam.nResynchMarkerSpacing); err = set_parameter( NULL, OMX_IndexParamVideoErrorCorrection, &ecParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoErrorCorrection failed !"); } break; } case OMX_IndexParamVideoProfileLevelCurrent: { OMX_VIDEO_PARAM_PROFILELEVELTYPE profileParam; memcpy(&profileParam, &m_sParamProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); valueSet |= vExt.readParamInt32(ext, "profile", (OMX_S32 *)&(profileParam.eProfile)); valueSet |= vExt.readParamInt32(ext, "level", (OMX_S32 *)&(profileParam.eLevel)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: custom-profile/level : profile=%u level=%u", (OMX_U32)profileParam.eProfile, (OMX_U32)profileParam.eLevel); err = set_parameter( NULL, OMX_IndexParamVideoProfileLevelCurrent, &profileParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoProfileLevelCurrent failed !"); } break; } case OMX_QTIIndexParamEnableAVTimerTimestamps: { QOMX_ENABLETYPE avTimerEnableParam; memcpy(&avTimerEnableParam, &m_sParamAVTimerTimestampMode, sizeof(QOMX_ENABLETYPE)); valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(avTimerEnableParam.bEnable)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: AV-timer timestamp mode enable=%u", avTimerEnableParam.bEnable); err = set_parameter( NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamEnableAVTimerTimestamps, &avTimerEnableParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamEnableAVTimerTimestamps failed !"); } break; } default: { return OMX_ErrorNotImplemented; } } return err; }
/** * FUNCTION : query_aud_topology_copp_handles * * DESCRIPTION : query for audio copp handles with a given device * * DEPENDENCIES : CSD needs to be available and initialized * * PARAMS: * req_buf_ptr - pointer to request buffer * resp_buf_ptr - pointer to response buffer * resp_buf_length - length of the response buffer * * RETURN VALUE : None * * SIDE EFFECTS : None * * Expected data input: None * * Expected data output: * number of audio copp handles (32-bit) * audio_copp_handle_array[n] * Each element of audio_copp_handle_array is: * topology_id (32-bit) * ac_handle (32-bit) * audproc_copp_id (32-bit) * num_as_handles (32-bit) * */ void query_aud_topology_copp_handles (char_t *req_buf_ptr, char_t **resp_buf_ptr, uint32_t *resp_buf_length ) { uint8_t* nBufferPointer = (uint8_t *)(acph_main_buffer + ACPH_ACDB_BUFFER_POSITION); size_t bytes_read = 0; uint32_t num_as_handles = 0; int i, fd, result; uint32_t real_acdb_id = 0; if (NULL == acph_main_buffer) { /**not initilized*/ create_error_resp(ACPH_ERR_UNKNOWN_REASON, req_buf_ptr, resp_buf_ptr, resp_buf_length); return; } /** open adm debugfs */ fd = open(RtacDev, O_RDWR); if (fd < 0) { create_error_resp(ACPH_ERR_CSD_OPEN_HANDLE, req_buf_ptr, resp_buf_ptr, resp_buf_length); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACDB RTC]->(get aud copp handles)->open device control, response [%d]\n", fd); #endif return; } /* get the copp info from debugfs */ #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACDB RTC]->(get aud copp info)->enter ioctl\n"); #endif bytes_read = ioctl(fd, AUDIO_GET_RTAC_ADM_INFO, &active_copp_info); #ifdef ACDB_RTC_DEBUG ACDB_DEBUG_LOG("[ACDB RTC]->(get aud copp info)->exit ioctl, actual byte read[%d]\n",bytes_read); #endif /* close debugfs after read */ close(fd); if (bytes_read <= 0 || active_copp_info.num_of_handles > RTC_MAX_ACTIVE_AUD_DEVICES) { #ifdef DEBUG_PRINT_ERROR DEBUG_PRINT_ERROR("[ACDB RTC ERROR]->(get aud copp handles)->bytes read less than 0 or number of active dev > %d\n", RTC_MAX_ACTIVE_AUD_DEVICES); #endif create_error_resp(ACPH_ERR_CSD_AUD_CMD_FAILURE, req_buf_ptr, resp_buf_ptr, resp_buf_length); return; } /* prepare response buffer */ for (i=0; i<(int)active_copp_info.num_of_handles; i++) { num_as_handles = active_copp_info.handle[i].num_of_popp; nBufferPointer += sizeof(uint32_t); memcpy(nBufferPointer, &(active_copp_info.handle[i].topology_id), sizeof(uint32_t)); nBufferPointer += sizeof(uint32_t); memcpy(nBufferPointer, &(active_copp_info.handle[i].copp), sizeof(uint32_t)); nBufferPointer += sizeof(uint32_t); memcpy(nBufferPointer, &(active_copp_info.handle[i].copp), sizeof(uint32_t)); /* find the number of as handles */ nBufferPointer += sizeof(uint32_t); memcpy(nBufferPointer, &num_as_handles, sizeof(uint32_t)); } memcpy(acph_main_buffer + ACPH_ACDB_BUFFER_POSITION, &(active_copp_info.num_of_handles), sizeof(uint32_t)); create_suc_resp(((active_copp_info.num_of_handles)*4)*sizeof(uint32_t) + sizeof(uint32_t), req_buf_ptr, resp_buf_ptr, resp_buf_length); }