void Start(CThreadProc pThreadProc, T* pInstance, const char* pThreadName = "") { m_pThreadProc = pThreadProc; m_pInstance = pInstance; CHECK_VCOS(vcos_thread_create(&m_Thread, pThreadName, NULL, static_cast<VCOS_THREAD_ENTRY_FN_T>(&CThreadT::ThreadProc), this), "failed to create thread"); CHECK_VCOS(vcos_event_wait(&m_InitializedEvent), "failed to wait for the thread to start"); }
/*********************************************************** * Name: dispmanx_notify_handle * * Arguments: not used * * Description: this purely notifies the update callback * * Returns: does not return * ***********************************************************/ static void *dispmanx_notify_func( void *arg ) { int32_t success; VCOS_STATUS_T status; (void)arg; while (1) { DISPMANX_UPDATE_HANDLE_T handle; status = vcos_event_wait(&dispmanx_notify_available_event); if (status != VCOS_SUCCESS || !dispmanx_client.initialised) break; success = vchi_msg_dequeue( dispmanx_client.notify_handle[0], dispmanx_client.notify_buffer, sizeof(dispmanx_client.notify_buffer), &dispmanx_client.notify_length, VCHI_FLAGS_NONE ); if (success != 0) continue; handle = (DISPMANX_UPDATE_HANDLE_T)dispmanx_client.notify_buffer[0]; if (handle) { // This is the response to an update submit // Decrement the use count - the corresponding "use" is in vc_dispmanx_update_submit. vchi_service_release(dispmanx_client.notify_handle[0]); if (dispmanx_client.update_callback ) { vcos_assert( dispmanx_client.pending_update_handle == handle); dispmanx_client.update_callback(handle, dispmanx_client.update_callback_param); } } else { // This is a vsync notification if (dispmanx_client.vsync_callback ) { dispmanx_client.vsync_callback(handle, dispmanx_client.vsync_callback_param); } } } return 0; }
/*********************************************************** * Name: os_cond_wait * * Arguments: OS_COND_T *cond, * OS_SEMAPHORE_T *semaphore * * Description: Routine to wait for a condition variable * to be signalled. Semaphore is released * while waiting. The same semaphore must * always be used. * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t os_cond_wait( OS_COND_T *cond, OS_SEMAPHORE_T *semaphore ) { int32_t success = -1; if (cond && semaphore) { COND_WAITER_T w; COND_WAITER_T *p, **prev; // Check the API is being followed os_assert((*cond)->semaphore == semaphore && os_semaphore_obtained(semaphore)); // Fill in a new waiter structure allocated on our stack w.next = NULL; vcos_demand(vcos_event_create(&w.latch, NULL) == VCOS_SUCCESS); // Add it to the end of the condvar's wait queue (we wake first come, first served) prev = &(*cond)->waiters; p = (*cond)->waiters; while (p) prev = &p->next, p = p->next; *prev = &w; // Ready to go to sleep now success = os_semaphore_release(semaphore); os_assert(success == 0); vcos_event_wait(&w.latch); success = os_semaphore_obtain(semaphore); os_assert(success == 0); } return success; }
VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue) { while (queue->write == queue->read) vcos_event_wait(&queue->push); return queue->storage[queue->read & (queue->size - 1)]; }
static int __inline remote_event_wait(REMOTE_EVENT_T *event) { #ifdef VCHIQ_LOCAL return (vcos_event_wait(&event->event) == VCOS_SUCCESS); #else return local_event_wait(&event->local); #endif }
static void *khrn_worker_main(void * param) { UNUSED(param); do { vcos_event_wait(&event); while (more_msgs(khrn_worker_msg.done_it, khrn_worker_msg.post) && do_it()) ; } while (!exit_thread); return NULL; }
void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header) { while (queue->write == queue->read + queue->size) vcos_event_wait(&queue->pop); queue->storage[queue->write & (queue->size - 1)] = header; queue->write++; vcos_event_signal(&queue->push); }
void CComponent::ChangeState(OMX_STATETYPE State) { OMX_STATETYPE CurrentState; CHECK_OMX(OMX_GetState(m_hComponent, &CurrentState), "failed to query the current state of the component"); if (CurrentState == State) { return; } CHECK_OMX(OMX_SendCommand(m_hComponent, OMX_CommandStateSet, State, NULL), "component state transtition failed"); CHECK_VCOS(vcos_event_wait(&m_StateChangedEvent), "failed to wait for component state transition"); }
/****************************************************************************** NAME vc_gencmd_read_response SYNOPSIS int vc_gencmd_read_response FUNCTION Block until something comes back RETURNS Error code from dequeue message ******************************************************************************/ int vc_gencmd_read_response (char *response, int maxlen) { int i = 0; int success = -1; int ret_code = 0; int32_t sem_ok = 0; if(lock_obtain() == 0) { //Note this will ALWAYS reset response buffer and overwrite any partially read responses use_gencmd_service(); do { //TODO : we need to deal with messages coming through on more than one connections properly //At the moment it will always try to read the first connection if there is something there for(i = 0; i < gencmd_client.num_connections; i++) { //Check if there is something in the queue, if so return immediately //otherwise wait for the event and read again success = (int) vchi_msg_dequeue( gencmd_client.open_handle[i], gencmd_client.response_buffer, sizeof(gencmd_client.response_buffer), &gencmd_client.response_length, VCHI_FLAGS_NONE); if(success == 0) { #ifdef __NetBSD__ uint32_t v; #endif #ifdef __NetBSD__ memcpy(&v, gencmd_client.response_buffer, sizeof(v)); ret_code = VC_VTOH32(v); #else ret_code = VC_VTOH32( *(int *)gencmd_client.response_buffer ); #endif break; } else { gencmd_client.response_length = 0; } } } while(!gencmd_client.response_length && vcos_event_wait(&gencmd_client.message_available_event) == VCOS_SUCCESS); if(gencmd_client.response_length && sem_ok == 0) { gencmd_client.response_length -= sizeof(int); //first word is error code memcpy(response, gencmd_client.response_buffer+sizeof(int), (size_t) vcos_min((int)gencmd_client.response_length, (int)maxlen)); } release_gencmd_service(); lock_release(); } // If we read anything, return the VideoCore code. Error codes < 0 mean we failed to // read anything... //How do we let the caller know the response code of gencmd? //return ret_code; return success; }
/*********************************************************** * Name: dispmanx_wait_for_reply * * Arguments: response buffer, buffer length * * Description: blocked until something is in the buffer * * Returns error code of vchi * ***********************************************************/ static int32_t dispmanx_wait_for_reply(void *response, uint32_t max_length) { int32_t success = 0; uint32_t length_read = 0; do { //TODO : we need to deal with messages coming through on more than one connections properly //At the moment it will always try to read the first connection if there is something there //Check if there is something in the queue, if so return immediately //otherwise wait for the semaphore and read again success = vchi_msg_dequeue( dispmanx_client.client_handle[0], response, max_length, &length_read, VCHI_FLAGS_NONE ); } while( length_read == 0 && vcos_event_wait(&dispmanx_message_available_event) == VCOS_SUCCESS ); return success; }
static void recv_bulk(CLIENT_THREAD_STATE_T *thread, void *out, uint32_t len) { if (len <= CTRL_THRESHOLD) { VCHIQ_HEADER_T *header = vchiu_queue_pop(get_queue(thread)); assert(header->size == len); memcpy(out, header->data, len); vchiq_release_message(get_handle(thread), header); } else { VCHIQ_STATUS_T vchiq_status = vchiq_queue_bulk_receive(get_handle(thread), out, rpc_pad_bulk(len), NULL); assert(vchiq_status == VCHIQ_SUCCESS); VCOS_STATUS_T vcos_status = vcos_event_wait(&bulk_event); assert(vcos_status == VCOS_SUCCESS); } }
VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue) { VCHIQ_HEADER_T *header; while (queue->write == queue->read) vcos_event_wait(&queue->push); header = queue->storage[queue->read & (queue->size - 1)]; queue->read++; vcos_event_signal(&queue->pop); return header; }
static void send_bulk(CLIENT_THREAD_STATE_T *thread, const void *in, uint32_t len) { if (len <= CTRL_THRESHOLD) { VCHIQ_ELEMENT_T element; element.data = in; element.size = len; VCHIQ_STATUS_T vchiq_status = vchiq_queue_message(get_handle(thread), &element, 1); assert(vchiq_status == VCHIQ_SUCCESS); } else { VCHIQ_STATUS_T vchiq_status = vchiq_queue_bulk_transmit(get_handle(thread), in, rpc_pad_bulk(len), NULL); assert(vchiq_status == VCHIQ_SUCCESS); VCOS_STATUS_T vcos_status = vcos_event_wait(&bulk_event); assert(vcos_status == VCOS_SUCCESS); } }
/*********************************************************** * Name: dispmanx_notify_handle * * Arguments: not used * * Description: this purely notifies the update callback * * Returns: does not return * ***********************************************************/ static void *dispmanx_notify_func( void *arg ) { int32_t success; VCOS_STATUS_T status; (void)arg; while(1) { status = vcos_event_wait(&dispmanx_notify_available_event); if(status != VCOS_SUCCESS || !dispmanx_client.initialised) break; success = vchi_msg_dequeue( dispmanx_client.notify_handle[0], dispmanx_client.notify_buffer, sizeof(dispmanx_client.notify_buffer), &dispmanx_client.notify_length, VCHI_FLAGS_NONE ); vchi_service_release(dispmanx_client.notify_handle[0]); // corresponding use in vc_dispmanx_update_submit if(success != 0) continue; if(dispmanx_client.update_callback ) { vcos_assert( dispmanx_client.pending_update_handle == (DISPMANX_UPDATE_HANDLE_T) dispmanx_client.notify_buffer[1]); dispmanx_client.update_callback((DISPMANX_UPDATE_HANDLE_T) dispmanx_client.notify_buffer[1], dispmanx_client.update_callback_param); } } return 0; }
VCHIQ_STATUS_T vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance) { VCHIQ_CHANNEL_T *local = state->local; int i; /* Find all services registered to this client and enable them. */ for (i = 0; i < VCHIQ_MAX_SERVICES; i++) if (local->services[i].instance == instance) { if (local->services[i].srvstate == VCHIQ_SRVSTATE_HIDDEN) vchiq_set_service_state(&local->services[i], VCHIQ_SRVSTATE_LISTENING); } if (!state->connected) { if (queue_message(state, VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0, 0) == VCHIQ_RETRY) return VCHIQ_RETRY; vcos_event_wait(&state->connect); state->connected = 1; } return VCHIQ_SUCCESS; }
int main( int argc, char **argv ) { int32_t ret; char optstring[OPTSTRING_LEN]; int opt; int opt_alloc = 0; int opt_status = 0; uint32_t alloc_size = 0; int opt_pid = -1; VCSM_STATUS_T status_mode = VCSM_STATUS_NONE; void *usr_ptr_1; unsigned int usr_hdl_1; #if defined(DOUBLE_ALLOC) || defined(RESIZE_ALLOC) void *usr_ptr_2; unsigned int usr_hdl_2; #endif // Initialize VCOS vcos_init(); vcos_log_set_level(&smem_log_category, VCOS_LOG_INFO); smem_log_category.flags.want_prefix = 0; vcos_log_register( "smem", &smem_log_category ); // Create the option string that we will be using to parse the arguments create_optstring( optstring ); // Parse the command line arguments while (( opt = getopt_long_only( argc, argv, optstring, long_opts, NULL )) != -1 ) { switch ( opt ) { case 0: { // getopt_long returns 0 for entries where flag is non-NULL break; } case OPT_ALLOC: { char *end; alloc_size = (uint32_t)strtoul( optarg, &end, 10 ); if (end == optarg) { vcos_log_info( "Invalid arguments '%s'", optarg ); goto err_out; } opt_alloc = 1; break; } case OPT_PID: { char *end; opt_pid = (int)strtol( optarg, &end, 10 ); if (end == optarg) { vcos_log_info( "Invalid arguments '%s'", optarg ); goto err_out; } break; } case OPT_STATUS: { char status_str[32]; /* coverity[secure_coding] String length specified, so can't overflow */ if ( sscanf( optarg, "%31s", status_str ) != 1 ) { vcos_log_info( "Invalid arguments '%s'", optarg ); goto err_out; } if ( vcos_strcasecmp( status_str, "all" ) == 0 ) { status_mode = VCSM_STATUS_VC_MAP_ALL; } else if ( vcos_strcasecmp( status_str, "vc" ) == 0 ) { status_mode = VCSM_STATUS_VC_WALK_ALLOC; } else if ( vcos_strcasecmp( status_str, "map" ) == 0 ) { status_mode = VCSM_STATUS_HOST_WALK_MAP; } else if ( vcos_strcasecmp( status_str, "host" ) == 0 ) { status_mode = VCSM_STATUS_HOST_WALK_PID_ALLOC; } else { goto err_out; } opt_status = 1; break; } default: { vcos_log_info( "Unrecognized option '%d'", opt ); goto err_usage; } case '?': case OPT_HELP: { goto err_usage; } } // end switch } // end while argc -= optind; argv += optind; if (( optind == 1 ) || ( argc > 0 )) { if ( argc > 0 ) { vcos_log_info( "Unrecognized argument -- '%s'", *argv ); } goto err_usage; } // Start the shared memory support. if ( vcsm_init() == -1 ) { vcos_log_info( "Cannot initialize smem device" ); goto err_out; } if ( opt_alloc == 1 ) { vcos_log_info( "Allocating 2 times %u-bytes in shared memory", alloc_size ); usr_hdl_1 = vcsm_malloc( alloc_size, "smem-test-alloc" ); vcos_log_info( "Allocation 1 result: user %x, vc-hdl %x", usr_hdl_1, vcsm_vc_hdl_from_hdl( usr_hdl_1 ) ); #if defined(DOUBLE_ALLOC) || defined(RESIZE_ALLOC) usr_hdl_2 = vcsm_malloc( alloc_size, NULL ); vcos_log_info( "Allocation 2 result: user %x", usr_hdl_2 ); usr_ptr_2 = vcsm_lock( usr_hdl_2 ); vcos_log_info( "Allocation 2 : lock %p", usr_ptr_2 ); vcos_log_info( "Allocation 2 : unlock %d", vcsm_unlock_hdl( usr_hdl_2 ) ); #endif // Do a simple write/read test. if ( usr_hdl_1 != 0 ) { usr_ptr_1 = vcsm_lock( usr_hdl_1 ); vcos_log_info( "Allocation 1 : lock %p", usr_ptr_1 ); if ( usr_ptr_1 ) { memset ( usr_ptr_1, 0, alloc_size ); memcpy ( usr_ptr_1, blah_blah, 32 ); vcos_log_info( "Allocation 1 contains: \"%s\"", (char *)usr_ptr_1 ); vcos_log_info( "Allocation 1: vc-hdl %x", vcsm_vc_hdl_from_ptr ( usr_ptr_1 ) ); vcos_log_info( "Allocation 1: usr-hdl %x", vcsm_usr_handle ( usr_ptr_1 ) ); vcos_log_info( "Allocation 1 : unlock %d", vcsm_unlock_ptr( usr_ptr_1 ) ); } usr_ptr_1 = vcsm_lock( usr_hdl_1 ); vcos_log_info( "Allocation 1 (relock) : lock %p", usr_ptr_1 ); if ( usr_ptr_1 ) { vcos_log_info( "Allocation 1 (relock) : unlock %d", vcsm_unlock_hdl( usr_hdl_1 ) ); } } #if defined(RESIZE_ALLOC) ret = vcsm_resize( usr_hdl_1, 2 * alloc_size ); vcos_log_info( "Allocation 1 : resize %d", ret ); if ( ret == 0 ) { usr_ptr_1 = vcsm_lock( usr_hdl_1 ); vcos_log_info( "Allocation 1 (resize) : lock %p", usr_ptr_1 ); if ( usr_ptr_1 ) { memset ( usr_ptr_1, 0, 2 * alloc_size ); memcpy ( usr_ptr_1, blah_blah, 32 ); vcos_log_info( "Allocation 1 (resized) contains: \"%s\"", (char *)usr_ptr_1 ); vcos_log_info( "Allocation 1 (resized) : unlock %d", vcsm_unlock_ptr( usr_ptr_1 ) ); } } // This checks that the memory can be remapped properly // because the Block 1 expanded beyond Block 2 boundary. // usr_ptr_2 = vcsm_lock( usr_hdl_2 ); vcos_log_info( "Allocation 2 : lock %p", usr_ptr_2 ); vcos_log_info( "Allocation 2 : unlock %d", vcsm_unlock_hdl( usr_hdl_2 ) ); // This checks that we can free a memory block even if it // is locked, which could be the case if the application // dies. // usr_ptr_2 = vcsm_lock( usr_hdl_2 ); vcos_log_info( "Allocation 2 : lock %p", usr_ptr_2 ); vcsm_free ( usr_hdl_2 ); #endif #if defined(DOUBLE_ALLOC) #endif } if ( opt_status == 1 ) { get_status( status_mode, opt_pid ); } // If we allocated something, wait for the signal to exit to give chance for the // user to poke around the allocation test. // if ( opt_alloc == 1 ) { start_monitor(); vcos_event_wait( &quit_event ); vcos_event_delete( &quit_event ); } // Terminate the shared memory support. vcsm_exit (); goto err_out; err_usage: show_usage(); err_out: exit( 1 ); }
int main( int argc, char **argv ) { int32_t ret; char optstring[OPTSTRING_LEN]; int opt; int opt_preferred = 0; int opt_explicit = 0; int opt_sdtvon = 0; int opt_off = 0; int opt_modes = 0; int opt_monitor = 0; int opt_status = 0; int opt_audiosup = 0; int opt_dumpedid = 0; int opt_showinfo = 0; int opt_3d = 0; int opt_json = 0; int opt_name = 0; char *dumpedid_filename = NULL; VCHI_INSTANCE_T vchi_instance; VCHI_CONNECTION_T *vchi_connection; HDMI_RES_GROUP_T power_on_explicit_group = HDMI_RES_GROUP_INVALID; uint32_t power_on_explicit_mode; uint32_t power_on_explicit_drive = HDMI_MODE_HDMI; HDMI_RES_GROUP_T get_modes_group = HDMI_RES_GROUP_INVALID; SDTV_MODE_T sdtvon_mode; SDTV_ASPECT_T sdtvon_aspect; // Initialize VCOS vcos_init(); // Create the option string that we will be using to parse the arguments create_optstring( optstring ); // Parse the command line arguments while (( opt = getopt_long_only( argc, argv, optstring, long_opts, NULL )) != -1 ) { switch ( opt ) { case 0: { // getopt_long returns 0 for entries where flag is non-NULL break; } case OPT_PREFERRED: { opt_preferred = 1; break; } case OPT_EXPLICIT: { char group_str[32], drive_str[32]; /* coverity[secure_coding] String length specified, so can't overflow */ int s = sscanf( optarg, "%31s %u %31s", group_str, &power_on_explicit_mode, drive_str ); if ( s != 2 && s != 3 ) { LOG_ERR( "Invalid arguments '%s'", optarg ); goto err_out; } // Check the group first if ( vcos_strcasecmp( "CEA", group_str ) == 0 ) { power_on_explicit_group = HDMI_RES_GROUP_CEA; } else if ( vcos_strcasecmp( "DMT", group_str ) == 0 ) { power_on_explicit_group = HDMI_RES_GROUP_DMT; } else if ( vcos_strcasecmp( "CEA_3D", group_str ) == 0 || vcos_strcasecmp( "CEA_3D_SBS", group_str ) == 0) { power_on_explicit_group = HDMI_RES_GROUP_CEA; opt_3d = 1; } else if ( vcos_strcasecmp( "CEA_3D_TB", group_str ) == 0 ) { power_on_explicit_group = HDMI_RES_GROUP_CEA; opt_3d = 2; } else { LOG_ERR( "Invalid group '%s'", group_str ); goto err_out; } if (s==3) { if (vcos_strcasecmp( "HDMI", drive_str ) == 0 ) { power_on_explicit_drive = HDMI_MODE_HDMI; } else if (vcos_strcasecmp( "DVI", drive_str ) == 0 ) { power_on_explicit_drive = HDMI_MODE_DVI; } else { LOG_ERR( "Invalid drive '%s'", drive_str ); goto err_out; } } // Then check if mode is a sane number if ( power_on_explicit_mode > MAX_MODE_ID ) { LOG_ERR( "Invalid mode '%u'", power_on_explicit_mode ); goto err_out; } opt_explicit = 1; break; } case OPT_SDTVON: { char mode_str[32], aspect_str[32]; if ( sscanf( optarg, "%s %s", mode_str, aspect_str ) != 2 ) { LOG_ERR( "Invalid arguments '%s'", optarg ); goto err_out; } // Check the group first if ( vcos_strcasecmp( "NTSC", mode_str ) == 0 ) { sdtvon_mode = SDTV_MODE_NTSC; } else if ( vcos_strcasecmp( "NTSC_J", mode_str ) == 0 ) { sdtvon_mode = SDTV_MODE_NTSC_J; } else if ( vcos_strcasecmp( "PAL", mode_str ) == 0 ) { sdtvon_mode = SDTV_MODE_PAL; } else if ( vcos_strcasecmp( "PAL_M", mode_str ) == 0 ) { sdtvon_mode = SDTV_MODE_PAL_M; } else { LOG_ERR( "Invalid mode '%s'", mode_str ); goto err_out; } if ( vcos_strcasecmp( "4:3", aspect_str ) == 0 ) { sdtvon_aspect = SDTV_ASPECT_4_3; } else if ( vcos_strcasecmp( "14:9", aspect_str ) == 0 ) { sdtvon_aspect = SDTV_ASPECT_14_9; } else if ( vcos_strcasecmp( "16:9", aspect_str ) == 0 ) { sdtvon_aspect = SDTV_ASPECT_16_9; } opt_sdtvon = 1; break; } case OPT_OFF: { opt_off = 1; break; } case OPT_MODES: { if ( vcos_strcasecmp( "CEA", optarg ) == 0 ) { get_modes_group = HDMI_RES_GROUP_CEA; } else if ( vcos_strcasecmp( "DMT", optarg ) == 0 ) { get_modes_group = HDMI_RES_GROUP_DMT; } else { LOG_ERR( "Invalid group '%s'", optarg ); goto err_out; } opt_modes = 1; break; } case OPT_MONITOR: { opt_monitor = 1; break; } case OPT_STATUS: { opt_status = 1; break; } case OPT_AUDIOSUP: { opt_audiosup = 1; break; } case OPT_DUMPEDID: { opt_dumpedid = 1; dumpedid_filename = optarg; break; } case OPT_SHOWINFO: { opt_showinfo = atoi(optarg)+1; break; } case OPT_JSON: { opt_json = 1; break; } case OPT_NAME: { opt_name = 1; break; } default: { LOG_ERR( "Unrecognized option '%d'\n", opt ); goto err_usage; } case '?': case OPT_HELP: { goto err_usage; } } // end switch } // end while argc -= optind; argv += optind; if (( optind == 1 ) || ( argc > 0 )) { if ( argc > 0 ) { LOG_ERR( "Unrecognized argument -- '%s'", *argv ); } goto err_usage; } if (( opt_preferred + opt_explicit + opt_sdtvon > 1 )) { LOG_ERR( "Conflicting power on options" ); goto err_usage; } if ((( opt_preferred == 1 ) || ( opt_explicit == 1 ) || ( opt_sdtvon == 1)) && ( opt_off == 1 )) { LOG_ERR( "Cannot power on and power off simultaneously" ); goto err_out; } // Initialize the VCHI connection ret = vchi_initialise( &vchi_instance ); if ( ret != 0 ) { LOG_ERR( "Failed to initialize VCHI (ret=%d)", ret ); goto err_out; } ret = vchi_connect( NULL, 0, vchi_instance ); if ( ret != 0) { LOG_ERR( "Failed to create VCHI connection (ret=%d)", ret ); goto err_out; } // LOG_INFO( "Starting tvservice" ); // Initialize the tvservice vc_vchi_tv_init( vchi_instance, &vchi_connection, 1 ); if ( opt_monitor == 1 ) { LOG_STD( "Starting to monitor for HDMI events" ); if ( start_monitor() != 0 ) { goto err_stop_service; } } if ( opt_modes == 1 ) { if ( get_modes( get_modes_group, opt_json ) != 0 ) { goto err_stop_service; } } if ( opt_preferred == 1 ) { if ( power_on_preferred() != 0 ) { goto err_stop_service; } } else if ( opt_explicit == 1 ) { //Distinguish between turning on 3D side by side and 3D top/bottom if(opt_3d == 1 && set_property( HDMI_PROPERTY_3D_STRUCTURE, HDMI_3D_FORMAT_SBS_HALF, 0) != 0) { goto err_stop_service; } else if(opt_3d == 2 && set_property( HDMI_PROPERTY_3D_STRUCTURE, HDMI_3D_FORMAT_TB_HALF, 0) != 0) { goto err_stop_service; } if ( power_on_explicit( power_on_explicit_group, power_on_explicit_mode, power_on_explicit_drive ) != 0 ) { goto err_stop_service; } } else if ( opt_sdtvon == 1 ) { if ( power_on_sdtv( sdtvon_mode, sdtvon_aspect ) != 0 ) { goto err_stop_service; } } else if (opt_off == 1 ) { if ( power_off() != 0 ) { goto err_stop_service; } } if ( opt_status == 1 ) { if ( get_status() != 0 ) { goto err_stop_service; } } if ( opt_audiosup == 1 ) { if ( get_audiosup() != 0 ) { goto err_stop_service; } } if ( opt_dumpedid == 1 ) { if ( dump_edid(dumpedid_filename) != 0 ) { goto err_stop_service; } } if ( opt_showinfo ) { if ( show_info(opt_showinfo-1) != 0 ) { goto err_stop_service; } } if ( opt_name == 1 ) { TV_DEVICE_ID_T id; memset(&id, 0, sizeof(id)); if(vc_tv_get_device_id(&id) == 0) { if(id.vendor[0] == '\0' || id.monitor_name[0] == '\0') { LOG_ERR( "No device present" ); } else { LOG_STD( "device_name=%s-%s", id.vendor, id.monitor_name); } } else { LOG_ERR( "Failed to obtain device name" ); } } if ( opt_monitor == 1 ) { // Wait until we get the signal to exit vcos_event_wait( &quit_event ); vcos_event_delete( &quit_event ); } err_stop_service: // LOG_INFO( "Stopping tvservice" ); // Stop the tvservice vc_vchi_tv_stop(); // Disconnect the VCHI connection vchi_disconnect( vchi_instance ); exit( 0 ); err_usage: show_usage(); err_out: exit( 1 ); }
static int __inline local_event_wait(LOCAL_EVENT_T *event) { return (vcos_event_wait(&event->event) == VCOS_SUCCESS); }