int vc_interface_set_req (int inum) { int status; int already_requested; int retval; int mask = 1<<inum; vc_lock_obtain(interface_lock); status = read_int_bits(); vc_assert(status == 0); vc_interface_debug[inum].vin_int_req = vc_sharedmem_header.vin_int_req; vc_interface_debug[inum].vin_int_ack = vc_sharedmem_header.vin_int_ack; // Request interrupts only where they are not already requested. already_requested = vc_sharedmem_header.vin_int_req ^ vc_sharedmem_header.vin_int_ack; mask &= ~already_requested; vc_sharedmem_header.vin_int_req ^= mask; vc_interface_debug[inum].new_vin_int_req = vc_sharedmem_header.vin_int_req; status = write_int_bits(); vc_assert(status == 0); retval = vc_sharedmem_header.vin_int_req ^ vc_sharedmem_header.vin_int_ack; vc_lock_release(interface_lock); return retval; }
/* ---------------------------------------------------------------------- * initialise host-side OpenMAX IL component service * -------------------------------------------------------------------- */ void vc_vchi_ilcs_init( VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { int32_t success; SERVICE_CREATION_T parameters = { MAKE_FOURCC("ILCS"), // 4cc service code connections[0], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) 0, // service callback 0 }; // callback parameter memset( &vc_ilcsg, 0, sizeof(VC_ILCS_GLOBALS_T) ); // create thread semaphore for blocking os_semaphore_create( &vc_ilcsg.component_lock, OS_SEMAPHORE_TYPE_SUSPEND ); // create semaphore for protecting wait/xid structures os_semaphore_create( &vc_ilcsg.wait_sem, OS_SEMAPHORE_TYPE_SUSPEND ); // create semaphore for correct ordering of control+bulk pairs os_semaphore_create( &vc_ilcsg.send_sem, OS_SEMAPHORE_TYPE_SUSPEND ); // open 'ILCS' service success = vchi_service_open( initialise_instance, ¶meters, &vc_ilcsg.vchi_handle ); vc_assert( success == 0 ); success = os_thread_start( &vc_ilcsg.thread, vc_ilcs_task, NULL, 4000, "ILCS_HOST" ); vc_assert( success == 0 ); }
void vcil_in_fill_this_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen) { IL_PASS_BUFFER_EXECUTE_T *exe = call; IL_RESPONSE_HEADER_T *ret = resp; OMX_COMPONENTTYPE *pComp = exe->reference; OMX_BUFFERHEADERTYPE *pHeader = exe->bufferHeader.pOutputPortPrivate; OMX_U8 *pBuffer = pHeader->pBuffer; OMX_PTR *pAppPrivate = pHeader->pAppPrivate; OMX_PTR *pPlatformPrivate = pHeader->pPlatformPrivate; OMX_PTR *pInputPortPrivate = pHeader->pInputPortPrivate; OMX_PTR *pOutputPortPrivate = pHeader->pOutputPortPrivate; vc_assert(pHeader); memcpy(pHeader, &exe->bufferHeader, sizeof(OMX_BUFFERHEADERTYPE)); pHeader->pBuffer = pBuffer; pHeader->pAppPrivate = pAppPrivate; pHeader->pPlatformPrivate = pPlatformPrivate; pHeader->pInputPortPrivate = pInputPortPrivate; pHeader->pOutputPortPrivate = pOutputPortPrivate; vc_assert(is_valid_hostside_buffer(pHeader)); *rlen = sizeof(IL_RESPONSE_HEADER_T); ret->func = IL_FILL_THIS_BUFFER; ret->err = pComp->FillThisBuffer(pComp, pHeader); }
/* ---------------------------------------------------------------------- * received response to an ILCS command * -------------------------------------------------------------------- */ static void vc_ilcs_command( uint32_t cmd, uint32_t xid, unsigned char *msg, int len ) { // execute this function call unsigned char resp[VC_ILCS_MAX_CMD_LENGTH]; int rlen = -1; VCIL_FN_T *fn; if ( cmd >= IL_FUNCTION_MAX_NUM ) { vc_assert(0); return; } fn = &vcilcs_fns[ cmd ]; if ( !fn ) { vc_assert(0); return; } // at this point we are executing in ILCS task context (host side). // NOTE: this cause vc_ilcs_execute_function() calls from within bowels of openmaxil? (*fn)( msg, len, resp, &rlen ); // make sure rlen has been initialised by the function vc_assert( rlen != -1 ); // if rlen is zero, then we don't send a response if ( rlen ) vc_ilcs_transmit( IL_RESPONSE, xid, resp, rlen, NULL, 0 ); }
/*********************************************************** * Name: dispman2_obj_create_resources * * Arguments: * DISPMAN2_OBJ_BITMAPS_T *bitmaps, uint32_t *resource_handles, const uint32_t num_bitmaps * * Description: A routine to create the resources which dispman can use * * Returns: int - < 0 is fail * ***********************************************************/ static int dispman2_obj_create_resources( DISPMAN2_OBJ_BITMAPS_T *bitmaps, uint32_t *resource_handles, const uint32_t num_bitmaps ) { int success = -1; //fail by default if( (NULL != bitmaps) && (NULL != resource_handles) && (0 != num_bitmaps ) ) { int32_t count = 0; //default to success! success = 0; for( count = 0; count < num_bitmaps; count++) { VC_IMAGE_PARAM_T image_params; uint32_t pitch = 0; //calculate the pitch of the bitmap //pitch = (((bitmaps[count].width * sizeof( uint32_t ))+15) & (~0xF)); pitch = (((bitmaps[count].width * sizeof( Pixel_t ))+15) & (~0xF)); //set up the dispman image params image_params.type = DISPMAN2_OBJ_BITMAP_TYPE; image_params.width = bitmaps[count].width; // width in pixels image_params.height = bitmaps[count].height; // height in pixels image_params.pitch = pitch; // pitch of image_data array in *bytes* image_params.size = pitch * bitmaps[count].height; // number of *bytes* available in the image_data array image_params.pointer = (uint32_t) bitmaps[count].data; // pointer for image_data //now, map the local resource to the if( 0 != vc_dispman_resource_create(&resource_handles[count], &image_params, VC_RESOURCE_TYPE_HOST) ) { //failed to created resource vc_assert( 0 ); //failed success = -1; //break; } } } else { //bad parameters vc_assert( 0 ); } return success; }
/* ---------------------------------------------------------------------- * check to see if there are any pending messages * * if there are no messages, return 0 * * otherwise, fetch and process the first queued message (which will * be either a command or response from host) * -------------------------------------------------------------------- */ static int vc_ilcs_process_message( int block ) { int32_t success; void *ptr; unsigned char *msg; uint32_t i, msg_len, cmd, xid; success = vchi_msg_peek( vc_ilcsg.vchi_handle, &ptr, &msg_len, block ? VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE : VCHI_FLAGS_NONE); vc_assert(!block || !success); if ( success != 0 ) return 0; // no more messages msg = ptr; cmd = vchi_readbuf_uint32( msg ); xid = vchi_readbuf_uint32( msg + 4 ); if ( cmd == IL_RESPONSE ) { vc_ilcs_response( xid, msg + 8, msg_len - 8 ); vchi_msg_remove( vc_ilcsg.vchi_handle ); } else { // we can only handle commands if we have space to copy the message first if(vc_ilcsg.msg_inuse == VC_ILCS_MSG_INUSE_MASK) { // this shouldn't happen, since we have more msg slots than the // remote side is allowed concurrent clients. We don't cope // with this assumption not being true. vc_assert(0); return 0; } i = 0; while(vc_ilcsg.msg_inuse & (1<<i)) i++; vc_ilcsg.msg_inuse |= (1<<i); memcpy( vc_ilcsg.msg[i], msg + 8, msg_len - 8 ); vchi_msg_remove( vc_ilcsg.vchi_handle ); vc_ilcs_command( cmd, xid, vc_ilcsg.msg[i], msg_len - 8); // mark the message copy as free vc_ilcsg.msg_inuse &= ~(1<<i); } return 1; }
int read_int_bits (void) { // Read from vin_int_req to the end. int status; int offset = (uint32_t)&vc_sharedmem_header.vin_int_req - (uint32_t)&vc_sharedmem_header; int attempt = 0; do { status = vc_host_read_consecutive(&vc_sharedmem_header.vin_int_req, vc_interface_base + offset, sizeof(VC_SHAREDMEM_HEADER_T) - offset, 0); vc_assert(status == 0); if ( attempt++ > 10 ) { printk( KERN_ERR "*****\n" ); printk( KERN_ERR "***** read_int_bits failed after %d attempts\n", attempt ); printk( KERN_ERR "*****\n" ); status = -1; break; } } while (( memcmp( vc_sharedmem_header.dummy1, testPattern, sizeof( testPattern )) != 0 ) || ( memcmp( vc_sharedmem_header.dummy2, testPattern, sizeof( testPattern )) != 0 )); return status; }
/* ---------------------------------------------------------------------- * received response to an ILCS command * -------------------------------------------------------------------- */ static void vc_ilcs_response( uint32_t xid, unsigned char *msg, int len ) { VC_ILCS_WAIT_T *wait; int i; // atomically retrieve given ->wait entry os_semaphore_obtain( &vc_ilcsg.wait_sem ); for (i=0; i<VC_ILCS_MAX_WAITING; i++) { wait = &vc_ilcsg.wait[i]; if ( wait->resp && wait->xid == xid ) break; } os_semaphore_release( &vc_ilcsg.wait_sem ); if ( i == VC_ILCS_MAX_WAITING ) { // something bad happened vc_assert(0); return; } // extract command from fifo and place in response buffer. memcpy( wait->resp, msg, len ); os_logging_message( "%s: waking waiter %d", __FUNCTION__, i ); os_semaphore_release( &wait->sem ); }
void vcil_in_free_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen) { IL_FREE_BUFFER_EXECUTE_T *exe = call; IL_RESPONSE_HEADER_T *ret = resp; OMX_COMPONENTTYPE *pComp = exe->reference; OMX_BUFFERHEADERTYPE *pHeader; OMX_U8 *buffer; OMX_PARAM_PORTDEFINITIONTYPE def; OMX_ERRORTYPE error; def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); def.nVersion.nVersion = OMX_VERSION; def.nPortIndex = exe->port; error = pComp->GetParameter(pComp, OMX_IndexParamPortDefinition, &def); vc_assert(error == OMX_ErrorNone); if (def.eDir == OMX_DirInput) pHeader = exe->inputPrivate; else pHeader = exe->outputPrivate; buffer = pHeader->pBuffer; *rlen = sizeof(IL_RESPONSE_HEADER_T); ret->func = IL_FREE_BUFFER; ret->err = pComp->FreeBuffer(pComp, exe->port, pHeader); if (ret->err == OMX_ErrorNone) vcos_free(buffer); }
/****************************************************************************** NAME vc_ilcs_execute_function SYNOPSIS void vc_ilcs_execute_function(IL_FUNCTION_T func, void *data, int len, void *resp) FUNCTION Executes this function on VideoCore via the IL component service RETURNS Response bytes and length ******************************************************************************/ static char* ilfunc2str(IL_FUNCTION_T func) { char* str[] = { "IL_RESPONSE", "IL_CREATE_COMPONENT", "IL_GET_COMPONENT_VERSION", "IL_SEND_COMMAND", // 4 "IL_GET_PARAMETER", "IL_SET_PARAMETER", // 6 "IL_GET_CONFIG", "IL_SET_CONFIG", // 8 "IL_GET_EXTENSION_INDEX", "IL_GET_STATE", "IL_COMPONENT_TUNNEL_REQUEST", "IL_USE_BUFFER", // 12 "IL_USE_EGL_IMAGE", // 13 "IL_ALLOCATE_BUFFER", // 14 "IL_FREE_BUFFER", // 15 "IL_EMPTY_THIS_BUFFER", // 16 "IL_FILL_THIS_BUFFER", // 17 "IL_SET_CALLBACKS", // 18 "IL_COMPONENT_ROLE_ENUM", "IL_COMPONENT_DEINIT", "IL_EVENT_HANDLER", // 21 "IL_EMPTY_BUFFER_DONE", "IL_FILL_BUFFER_DONE", "IL_COMPONENT_NAME_ENUM", "IL_FUNCTION_MAX_NUM", }; vc_assert(func < IL_FUNCTION_MAX_NUM); return str[func]; }
static char* ilstate2str(OMX_STATETYPE val) { char* str[] = { "OMX_StateInvalid", /**< component has detected that it's internal data structures are corrupted to the point that it cannot determine it's state properly */ "OMX_StateLoaded", /**< component has been loaded but has not completed initialization. The OMX_SetParameter macro and the OMX_GetParameter macro are the only valid macros allowed to be sent to the component in this state. */ "OMX_StateIdle", /**< component initialization has been completed successfully and the component is ready to to start. */ "OMX_StateExecuting", /**< component has accepted the start command and is processing data (if data is available) */ "OMX_StatePause", /**< component has received pause command */ "OMX_StateWaitForResources", /**< component is waiting for resources, either after preemption or before it gets the resources requested. See specification for complete details. */ "OMX_StateMax" }; vc_assert(val < OMX_StateMax); val = min((int)val, (int)OMX_EventMax); return str[val]; }
/*********************************************************** * Name: vclcd_test * * Arguments: None. * * Description: The entry point for the test app * * Returns: void * ***********************************************************/ void vclcd_test( void ) { int success = 0; //success by default static DISPMAN2_OBJ_STATE_T *dispman2_obj_state; //the dispman2_obj tutorials state lcd_get_info( &gLcdInfo ); { //malloc and zero a some storage to contain this apps state //dispman2_obj_state = (DISPMAN2_OBJ_STATE_T *)calloc( 1, sizeof( DISPMAN2_OBJ_STATE_T ) ); dispman2_obj_state = &gDispman2ObjState; memset( &gDispman2ObjState, 0, sizeof( gDispman2ObjState ) ); if( NULL != dispman2_obj_state) { //create the initial bitmaps, fill them in with colours and display them on the screen success = dispman2_obj_create_and_display_bitmaps( dispman2_obj_state->bitmaps, //pointers to the bitmaps DISPMAN2_OBJ_NUM_BITMAPS, //number of bitmaps to add to the display DISPMAN2_OBJ_WIDTH_BITMAPS, //the width of the bitmaps to create DISPMAN2_OBJ_HEIGHT_BITMAPS, //the height of the bitmaps to create dispman2_obj_state->bitmap_resource_handles, //the resource handles of the bitmaps dispman2_obj_state->bitmap_object_handles ); //the object handles of the bitmaps } //check the initialisation worked vc_assert( success >= 0 ); } }
int vc_host_get_app (void) { int status; uint32_t buffer; // Read app id. status = vc_host_read_consecutive(&buffer, VC_APP_ADDRESS, 4, 0); vc_assert(status == 0); return VC_VTOH32(buffer); }
static void create_vbo(GLenum type, GLuint *vbo, int size, void *data) { glGenBuffers(1, vbo); vc_assert(*vbo); glBindBuffer(type, *vbo); glBufferData(type, size, data, GL_STATIC_DRAW); glBindBuffer(type, 0); }
static OMX_ERRORTYPE vcil_out_FillThisBuffer(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { OMX_ERRORTYPE err; OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *) hComponent; VC_PRIVATE_COMPONENT_T *comp; VC_PRIVATE_PORT_T *port; ILCS_COMMON_T *st; if (!(pComp && pBuffer)) return (OMX_ErrorBadParameter); st = pComp->pApplicationPrivate; comp = (VC_PRIVATE_COMPONENT_T *) pComp->pComponentPrivate; port = find_port(comp, pBuffer->nOutputPortIndex); if(!port) return OMX_ErrorBadPortIndex; if(pBuffer->pBuffer == 0) return OMX_ErrorIncorrectStateOperation; vcos_assert(pComp != NULL && comp != NULL && port != NULL && st != NULL); // The lower layers will attempt to transfer the bytes specified if we don't // clear these - callers should ideally do this themselves, but it is not // mandated in the specification. pBuffer->nFilledLen = 0; pBuffer->nFlags = 0; vc_assert(port->bEGL == OMX_TRUE || is_valid_hostside_buffer(pBuffer)); err = ilcs_pass_buffer(st->ilcs, IL_FILL_THIS_BUFFER, comp->reference, pBuffer); if (err == OMX_ErrorNone && port->bEGL == OMX_TRUE) { // If an output port is marked as an EGL port, we request EGL to notify the IL component // when it's allowed to render into the buffer/EGLImage. vc_assert(local_eglIntOpenMAXILDoneMarker != NULL); local_eglIntOpenMAXILDoneMarker(comp->reference, pBuffer->pBuffer); } return err; }
static void load_eglIntOpenMAXILDoneMarker(void) { void *handle; /* First try to load from the current process, this will succeed * if something that is linked to libEGL is already loaded or * something explicitly loaded libEGL with RTLD_GLOBAL */ handle = vcos_dlopen(NULL, VCOS_DL_GLOBAL); local_eglIntOpenMAXILDoneMarker = (void * )vcos_dlsym(handle, "eglIntOpenMAXILDoneMarker"); if (local_eglIntOpenMAXILDoneMarker == NULL) { vcos_dlclose(handle); /* If that failed try to load libEGL.so explicitely */ handle = vcos_dlopen("libEGL.so", VCOS_DL_LAZY | VCOS_DL_LOCAL); vc_assert(handle != NULL); local_eglIntOpenMAXILDoneMarker = (void * )vcos_dlsym(handle, "eglIntOpenMAXILDoneMarker"); vc_assert(local_eglIntOpenMAXILDoneMarker != NULL); } }
int vc_interface_query_req (void) { int status, retval; vc_lock_obtain(interface_lock); status = read_int_bits(); vc_assert(status == 0); retval = vc_sharedmem_header.vin_int_req ^ vc_sharedmem_header.vin_int_ack; vc_lock_release(interface_lock); return retval; }
int read_header (void) { // Read up to vin_int_req. int status; unsigned int i; int offset = (uint32_t)&vc_sharedmem_header.vin_int_req - (uint32_t)&vc_sharedmem_header; status = vc_host_read_consecutive(&vc_sharedmem_header, vc_interface_base, offset, 0); vc_assert(status == 0); for (i = 0; i < sizeof(vc_sharedmem_header.iface)/sizeof(uint16_t); i++) vc_sharedmem_header.iface[i] = VC_VTOH16(vc_sharedmem_header.iface[i]); return status; }
static void create_vbo(GLenum type, GLuint *vbo, int size, void *data) { // Generate buffer glGenBuffers(1, vbo); vc_assert(*vbo); // Bind buffer glBindBuffer(type, *vbo); // Create buffer data glBufferData(type, size, data, GL_STATIC_DRAW); // Unbind buffer glBindBuffer(type, 0); }
static int log_add(IL_FUNCTION_T func, char* data, int len, char* fmt) { #define MAXSTR 500 char str[MAXSTR+1]; int strlen, nbytes; char prefix[50]; unsigned long j; static unsigned long jstart = 0; if(jstart == 0) jstart = jiffies; j = jiffies - jstart; sprintf(prefix, "%04lu.%02lu %s", (j / HZ), (j % HZ), fmt); strlen = log_func(str, func, data, len, prefix); sprintf(str + strlen, "\n"); strlen += 1; // delay_msec(1); VC_PRINTK( IlcsTrace, "%s", str ); // printk(KERN_ERR"%s", str); if(down_interruptible(&vc_ilcsg.omxlog_lock)) return -1; nbytes = min(VC03_OMXLOG_MAX - vc_ilcsg.omxlog_windex, strlen); memcpy(vc_ilcsg.omxlog + vc_ilcsg.omxlog_windex, str, nbytes); if(vc_ilcsg.omxlog_windex < vc_ilcsg.omxlog_rindex) { vc_ilcsg.omxlog_windex += nbytes; if(vc_ilcsg.omxlog_windex >= (vc_ilcsg.omxlog_rindex - 1)) { vc_ilcsg.omxlog_rindex = (vc_ilcsg.omxlog_windex + 1) % VC03_OMXLOG_MAX; } } else { vc_ilcsg.omxlog_windex += nbytes; } if(nbytes < strlen) { vc_assert(vc_ilcsg.omxlog_windex >= VC03_OMXLOG_MAX); memcpy(vc_ilcsg.omxlog + 0, str + nbytes, strlen - nbytes); vc_ilcsg.omxlog_windex = strlen - nbytes; vc_ilcsg.omxlog_rindex = max(vc_ilcsg.omxlog_rindex, vc_ilcsg.omxlog_windex + 1); } up(&vc_ilcsg.omxlog_lock); return 0; }
int vc_interface_interrupt_handler(void) { int status; int host_requests; int i; vc_lock_obtain(interface_lock); /* Read request and ack bits from the interface */ status = read_int_bits(); vc_assert(status == 0); host_requests = vc_sharedmem_header.vout_int_req ^ vc_sharedmem_header.vout_int_ack; if (host_requests == 0) { vc_lock_release(interface_lock); return 0; } /* Acknowledge all requests immediately */ vc_sharedmem_header.vout_int_ack ^= host_requests; status = write_int_bits(); vc_assert(status == 0); vc_lock_release(interface_lock); if (host_requests) { /* Signal all registered events that have a mask matching any request */ REGISTERED_EVENT_T *reg_event = registered_events; for (i = 0; i < num_reg_events; i++) { if (host_requests & reg_event->mask) { vc_event_set(reg_event->event); } reg_event++; } } return (host_requests); }
/*********************************************************** * Name: dispman2_obj_display_bitmaps * * Arguments: * DISPMAN2_OBJ_BITMAPS_T *bitmaps, uint32_t *resource_handles, uint32_t *object_handles, const uint32_t num_bitmaps, const int32_t display_bitmaps * * Description: A routine to display bitmaps on the screen * * Returns: int - < 0 is fail * ***********************************************************/ static int dispman2_obj_display_bitmaps( DISPMAN2_OBJ_BITMAPS_T *bitmaps, uint32_t *resource_handles, uint32_t *object_handles, const uint32_t num_bitmaps, const int32_t display_bitmaps ) { int success = -1; //fail by default if( (NULL != bitmaps) && ( NULL != resource_handles) && (0 != num_bitmaps ) ) { int32_t count = 0; int32_t response = 0; //default to success! success = 0; //start an update if( 0 == vc_dispman_update_start(&response) ) { for( count = 0; count < num_bitmaps; count++) { //do we want to display the bitmaps? if( display_bitmaps ) { success = vc_dispman_object_add( object_handles, 0, 0, //the z order of the bitmap - we use the count var to give some depth to the image bitmaps[count].x, bitmaps[count].y, bitmaps[count].width, bitmaps[count].height, resource_handles[ count ], 0, 0, 0); } } // This call blocks until the update is done. success += vc_dispman_update_end(&response); } } else { //bad parameters vc_assert( 0 ); } return success; }
static char* ilerr2str(OMX_ERRORTYPE val) { char* str[] = { "OMX_ErrorNone", "OMX_ErrorInsufficientResources", "OMX_ErrorUndefined", "OMX_ErrorInvalidComponentName", "OMX_ErrorComponentNotFound", "OMX_ErrorInvalidComponent", "OMX_ErrorBadParameter", "OMX_ErrorNotImplemented", "OMX_ErrorUnderflow", "OMX_ErrorOverflow", "OMX_ErrorHardware", "OMX_ErrorInvalidState", "OMX_ErrorStreamCorrupt", "OMX_ErrorPortsNotCompatible", "OMX_ErrorResourcesLost", "OMX_ErrorNoMore", "OMX_ErrorVersionMismatch", "OMX_ErrorNotReady", "OMX_ErrorTimeout", "OMX_ErrorSameState", "OMX_ErrorResourcesPreempted", "OMX_ErrorPortUnresponsiveDuringAllocation", "OMX_ErrorPortUnresponsiveDuringDeallocation", "OMX_ErrorPortUnresponsiveDuringStop", "OMX_ErrorIncorrectStateTransition", "OMX_ErrorIncorrectStateOperation", "OMX_ErrorUnsupportedSetting", "OMX_ErrorUnsupportedIndex", "OMX_ErrorBadPortIndex", "OMX_ErrorPortUnpopulated", "OMX_ErrorComponentSuspended", "OMX_ErrorDynamicResourcesUnavailable", "OMX_ErrorMbErrorsInFrame", "OMX_ErrorFormatNotDetected", "OMX_ErrorContentPipeOpenFailed", "OMX_ErrorContentPipeCreationFailed", "OMX_ErrorSeperateTablesUsed", "OMX_ErrorTunnelingUnsupported" "OMX_ErrorMax", }; val &= 0xfff; vc_assert(val < OMX_ErrorMax); val = min((int)val, (int)OMX_ErrorMax); return str[val]; }
static char* ilcmd2str(OMX_COMMANDTYPE val) { char* str[] = { "OMX_CommandStateSet", /**< Change the component state */ "OMX_CommandFlush", /**< Flush the data queue(s) of a component */ "OMX_CommandPortDisable", /**< Disable a port on a component. */ "OMX_CommandPortEnable", /**< Enable a port on a component. */ "OMX_CommandMarkBuffer", /**< Mark a component/buffer for observation */ "OMX_CommandMax", }; vc_assert(val < OMX_CommandMax); return str[val]; }
void vcil_in_use_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen) { IL_ADD_BUFFER_EXECUTE_T *exe = call; IL_ADD_BUFFER_RESPONSE_T *ret = resp; OMX_COMPONENTTYPE *pComp = exe->reference; OMX_U8 *buffer; OMX_BUFFERHEADERTYPE *bufferHeader; *rlen = sizeof(IL_ADD_BUFFER_RESPONSE_T); buffer = vcos_malloc_aligned(exe->size, 32, "vcin mapping buffer"); // 32-byte aligned if (!buffer) { ret->err = OMX_ErrorInsufficientResources; return; } //OMX_OSAL_Trace(OMX_OSAL_TRACE_COMPONENT, "hostcomp: use buffer(%p)\n", buffer); ret->func = IL_USE_BUFFER; ret->err = pComp->UseBuffer(pComp, &bufferHeader, exe->port, exe->bufferReference, exe->size, buffer); if (ret->err == OMX_ErrorNone) { // we're going to pass this buffer to VC // initialise our private field in their copy with the host buffer reference OMX_PARAM_PORTDEFINITIONTYPE def; OMX_ERRORTYPE error; def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); def.nVersion.nVersion = OMX_VERSION; def.nPortIndex = exe->port; error = pComp->GetParameter(pComp, OMX_IndexParamPortDefinition, &def); vc_assert(error == OMX_ErrorNone); ret->reference = bufferHeader; memcpy(&ret->bufferHeader, bufferHeader, sizeof(OMX_BUFFERHEADERTYPE)); if (def.eDir == OMX_DirInput) ret->bufferHeader.pInputPortPrivate = bufferHeader; else ret->bufferHeader.pOutputPortPrivate = bufferHeader; } else vcos_free(buffer); }
/* ---------------------------------------------------------------------- * helper function to transmit an ilcs command/response + payload * -------------------------------------------------------------------- */ static void vc_ilcs_transmit( uint32_t cmd, uint32_t xid, unsigned char *msg, int len, unsigned char *msg2, int len2 ) { // could do this in 3 vectors, but hey VCHI_MSG_VECTOR_T vec[4]; int32_t result; vec[0].vec_base = &cmd; vec[0].vec_len = sizeof(cmd); vec[1].vec_base = &xid; vec[1].vec_len = sizeof(xid); vec[2].vec_base = msg; vec[2].vec_len = len; vec[3].vec_base = msg2; vec[3].vec_len = len2; result = vchi_msg_queuev( vc_ilcsg.vchi_handle, vec, 4, VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL ); // call to VCHI vc_assert(result == 0); }
void vcil_in_empty_this_buffer(ILCS_COMMON_T *st, void *call, int clen, void *resp, int *rlen) { IL_RESPONSE_HEADER_T *ret = resp; OMX_COMPONENTTYPE *pComp; OMX_BUFFERHEADERTYPE *pHeader; pHeader = ilcs_receive_buffer(st->ilcs, call, clen, &pComp); *rlen = sizeof(IL_RESPONSE_HEADER_T); ret->func = IL_EMPTY_THIS_BUFFER; if(pHeader) { vc_assert(is_valid_hostside_buffer(pHeader)); ret->err = pComp->EmptyThisBuffer(pComp, pHeader); } else ret->err = OMX_ErrorHardware; }
static char* ilevent2str(OMX_EVENTTYPE val) { char* str[] = { "OMX_EventCmdComplete", "OMX_EventError", /**< component has detected an error condition */ "OMX_EventMark", /**< component has detected a buffer mark */ "OMX_EventPortSettingsChanged", /**< component is reported a port settings change */ "OMX_EventBufferFlag", /**< component has detected an EOS */ "OMX_EventResourcesAcquired", /**< component has been granted resources and is automatically starting the state change from OMX_StateWaitForResources to OMX_StateIdle. */ "OMX_EventComponentResumed", /**< Component resumed due to reacquisition of resources */ "OMX_EventDynamicResourcesAvailable", /**< Component has acquired previously unavailable dynamic resources */ "OMX_EventPortFormatDetected", /**< Component has detected a supported format. */ "OMX_EventMax" }; vc_assert(val < OMX_EventMax); val = min((int)val, (int)OMX_EventMax); return str[val]; }
/* ---------------------------------------------------------------------- * check to see if there are any pending messages * * if there are no messages, return 0 * * otherwise, fetch and process the first queued message (which will * be either a command or response from host) * -------------------------------------------------------------------- */ static int vc_ilcs_process_message( void ) { int32_t success; void *ptr; unsigned char *msg; VCHI_HELD_MSG_T msg_handle; uint32_t msg_len; success = vchi_msg_hold( vc_ilcsg.vchi_handle, &ptr, &msg_len, VCHI_FLAGS_NONE, &msg_handle ); if ( success != 0 ) return 0; // no more messages msg = ptr; uint32_t cmd = vchi_readbuf_uint32( msg ); uint32_t xid = vchi_readbuf_uint32( msg + 4 ); log_add(cmd, msg + 8, msg_len - 8, "<-"); if ( cmd == IL_RESPONSE ) vc_ilcs_response( xid, msg + 8, msg_len - 8 ); else //vc_ilcs_command( cmd, xid, msg + 8, msg_len - 8 ); { msg += 8; msg_len -= 8; if(component_in_kernel(msg)) { vc_ilcs_command( cmd, xid, msg, msg_len); } else { vc_ilcs_command_usr( cmd, xid, msg, msg_len); } } success = vchi_held_msg_release( &msg_handle ); vc_assert(success == 0); return 1; }
int mphi_logadd(struct mphi_driver* drv, char* str, int len, int lock) { int nbytes; if(lock) if(down_interruptible(&drv->mphilog_lock)) return -1; nbytes = min(VC03_MPHILOG_MAX - drv->mphilog_windex, len); memcpy(drv->mphilog + drv->mphilog_windex, str, nbytes); if(drv->mphilog_windex < drv->mphilog_rindex) { drv->mphilog_windex += nbytes; if(drv->mphilog_windex >= (drv->mphilog_rindex - 1)) { drv->mphilog_rindex = (drv->mphilog_windex + 1) % VC03_MPHILOG_MAX; } } else { drv->mphilog_windex += nbytes; } if(nbytes < len) { vc_assert(drv->mphilog_windex >= VC03_MPHILOG_MAX); memcpy(drv->mphilog + 0, str + nbytes, len - nbytes); drv->mphilog_windex = len - nbytes; drv->mphilog_rindex = max(drv->mphilog_rindex, drv->mphilog_windex + 1); } if(lock) up(&drv->mphilog_lock); return 0; }