struct fs_dirent *vc_hostfs_readdir_r(void *dhandle, struct fs_dirent *result) { struct fs_dir *fsdir = (struct fs_dir *)dhandle; DEBUG_MINOR( "vc_hostfs_readdir_r(%p)", fsdir ); if (fsdir && result) { struct dirent *dent; while ((dent = readdir(fsdir->dhandle)) != NULL) { struct stat statbuf; int ret; /* Append the filename, and stat the resulting path */ fsdir->pathbuf[fsdir->pathlen] = '/'; vcos_safe_strcpy(fsdir->pathbuf, dent->d_name, sizeof(fsdir->pathbuf), fsdir->pathlen + 1); ret = stat(fsdir->pathbuf, &statbuf); fsdir->pathbuf[fsdir->pathlen] = '\0'; if (ret == 0) { vcos_safe_strcpy(result->d_name, dent->d_name, sizeof(result->d_name), 0); result->d_size = (statbuf.st_size <= 0xffffffff) ? (unsigned int)statbuf.st_size : 0xffffffff; result->d_attrib = ATTR_NORMAL; if ((statbuf.st_mode & S_IWUSR) == 0) result->d_attrib |= ATTR_RDONLY; if (statbuf.st_mode & S_IFDIR) result->d_attrib |= ATTR_DIRENT; result->d_creatime = statbuf.st_ctime; result->d_modtime = statbuf.st_mtime; DEBUG_MINOR( "vc_hostfs_readdir_r() = '%s', %x, %x", result->d_name, result->d_size, result->d_attrib ); break; } } if (!dent) { DEBUG_MINOR( "vc_hostfs_readdir_r() = NULL" ); rewinddir(fsdir->dhandle); result = NULL; } } else { result = NULL; } return result; }
MMAL_OPAQUE_IMAGE_HANDLE_T mmal_vc_opaque_alloc_desc(const char *description) { MMAL_STATUS_T ret; MMAL_OPAQUE_IMAGE_HANDLE_T h = 0; mmal_worker_opaque_allocator msg; size_t len = sizeof(msg); msg.op = MMAL_WORKER_OPAQUE_MEM_ALLOC; vcos_safe_strcpy(msg.description, description, sizeof(msg.description), 0); ret = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_OPAQUE_ALLOCATOR_DESC, &msg, &len, MMAL_FALSE); if (ret == MMAL_SUCCESS) { h = msg.handle; } return h; }
static MMAL_STATUS_T mmalplay_setup_container_writer(MMALPLAY_T *ctx, MMAL_COMPONENT_T *writer, const char *uri) { MMAL_PARAMETER_URI_T *param = 0; unsigned int param_size; MMAL_STATUS_T status = MMAL_EINVAL; size_t uri_len; MMAL_PARAM_UNUSED(ctx); if(!writer->input_num) { LOG_ERROR("%s doesn't have input ports", writer->name); goto error; } /* Open the given URI */ uri_len = strlen(uri); param_size = sizeof(MMAL_PARAMETER_HEADER_T) + uri_len; param = malloc(param_size); if(!param) { LOG_ERROR("out of memory"); status = MMAL_ENOMEM; goto error; } memset(param, 0, param_size); param->hdr.id = MMAL_PARAMETER_URI; param->hdr.size = param_size; vcos_safe_strcpy(param->uri, uri, uri_len + 1, 0); status = mmal_port_parameter_set(writer->control, ¶m->hdr); if(status != MMAL_SUCCESS) { LOG_ERROR("could not open file %s", uri); goto error; } error: if(param) free(param); return status; }
static MMAL_STATUS_T mmalplay_setup_container_reader(MMALPLAY_T *ctx, MMAL_COMPONENT_T *reader, const char *uri) { MMAL_PARAMETER_SEEK_T seek = {{MMAL_PARAMETER_SEEK, sizeof(MMAL_PARAMETER_SEEK_T)},0,0}; MMAL_PARAMETER_STRING_T *param = 0; unsigned int param_size, track_audio, track_video; MMAL_STATUS_T status = MMAL_EINVAL; uint32_t encoding; size_t uri_len; if(!reader->output_num) { LOG_ERROR("%s doesn't have output ports", reader->name); goto error; } /* Open the given URI */ uri_len = strlen(uri); param_size = sizeof(MMAL_PARAMETER_STRING_T) + uri_len; param = malloc(param_size); if(!param) { LOG_ERROR("out of memory"); status = MMAL_ENOMEM; goto error; } memset(param, 0, param_size); param->hdr.id = MMAL_PARAMETER_URI; param->hdr.size = param_size; vcos_safe_strcpy(param->str, uri, uri_len + 1, 0); status = mmal_port_parameter_set(reader->control, ¶m->hdr); if(status != MMAL_SUCCESS && status != MMAL_ENOSYS) { LOG_ERROR("%s could not open file %s", reader->name, uri); goto error; } status = MMAL_SUCCESS; /* Look for a video track */ for(track_video = 0; track_video < reader->output_num; track_video++) if(reader->output[track_video]->format->type == MMAL_ES_TYPE_VIDEO) break; if(track_video != reader->output_num) { ctx->reader_video = reader->output[track_video]; /* Try to detect still images */ encoding = ctx->reader_video->format->encoding; if (encoding == MMAL_ENCODING_JPEG || encoding == MMAL_ENCODING_GIF || encoding == MMAL_ENCODING_PNG || encoding == MMAL_ENCODING_PPM || encoding == MMAL_ENCODING_TGA || encoding == MMAL_ENCODING_BMP) ctx->is_still_image = 1; } /* Look for an audio track */ for(track_audio = 0; track_audio < reader->output_num; track_audio++) if(reader->output[track_audio]->format->type == MMAL_ES_TYPE_AUDIO) break; if(track_audio != reader->output_num) ctx->reader_audio = reader->output[track_audio]; if(track_video == reader->output_num && track_audio == reader->output_num) { LOG_ERROR("no track to decode"); status = MMAL_EINVAL; goto error; } LOG_INFO("----Reader input port format-----"); if(track_video != reader->output_num) log_format(reader->output[track_video]->format, 0); if(track_audio != reader->output_num) log_format(reader->output[track_audio]->format, 0); if(ctx->options.seeking) { LOG_DEBUG("seek to %fs", ctx->options.seeking); seek.offset = ctx->options.seeking * INT64_C(1000000); status = mmal_port_parameter_set(reader->control, &seek.hdr); if(status != MMAL_SUCCESS) LOG_ERROR("failed to seek to %fs", ctx->options.seeking); } error: if(param) free(param); return status; }
static MMAL_COMPONENT_T *mmalplay_component_create(MMALPLAY_T *ctx, const char *name, MMAL_STATUS_T *status) { MMALPLAY_COMPONENT_T *component = &ctx->component[ctx->component_num]; const char *component_name = name; LOG_TRACE("%p, %s", ctx, name); if (ctx->component_num >= MMAL_COUNTOF(ctx->component)) { *status = MMAL_ENOSPC; return NULL; } /* Decide whether we want an image decoder instead of a video_decoder */ if (ctx->is_still_image && !strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER) && !ctx->options.component_video_decoder) ctx->options.component_video_decoder = MMAL_COMPONENT_DEFAULT_IMAGE_DECODER; /* Override name if requested by the user */ if (!strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER) && ctx->options.component_video_decoder) component_name = ctx->options.component_video_decoder; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_SPLITTER) && ctx->options.component_splitter) component_name = ctx->options.component_splitter; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER) && ctx->options.component_video_render) component_name = ctx->options.component_video_render; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER) && ctx->options.component_video_converter) component_name = ctx->options.component_video_converter; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_SCHEDULER) && ctx->options.component_video_scheduler) component_name = ctx->options.component_video_scheduler; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_AUDIO_DECODER) && ctx->options.component_audio_decoder) component_name = ctx->options.component_audio_decoder; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER) && ctx->options.component_audio_render) component_name = ctx->options.component_audio_render; else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_CONTAINER_READER) && ctx->options.component_container_reader) component_name = ctx->options.component_container_reader; component->comp = NULL; vcos_safe_strcpy(component->name, component_name, sizeof(component->name), 0); component->time_setup = vcos_getmicrosecs(); /* Create the component */ *status = mmal_component_create(component_name, &component->comp); if(*status != MMAL_SUCCESS) { LOG_ERROR("couldn't create %s", component_name); goto error; } if (!strcmp(name, MMAL_COMPONENT_DEFAULT_CONTAINER_READER)) *status = mmalplay_setup_container_reader(ctx, component->comp, ctx->uri); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_CONTAINER_WRITER)) *status = mmalplay_setup_container_writer(ctx, component->comp, ctx->options.output_uri); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER)) *status = mmalplay_setup_video_decoder(ctx, component->comp); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_SPLITTER)) *status = mmalplay_setup_splitter(ctx, component->comp); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER)) *status = mmalplay_setup_video_converter(ctx, component->comp); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER)) *status = mmalplay_setup_video_render(ctx, component->comp); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_SCHEDULER)) *status = mmalplay_setup_video_scheduler(ctx, component->comp); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_AUDIO_DECODER)) *status = mmalplay_setup_audio_decoder(ctx, component->comp); else if (!strcmp(name, MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER)) *status = mmalplay_setup_audio_render(ctx, component->comp); if (*status != MMAL_SUCCESS) goto error; /* Enable component */ *status = mmal_component_enable(component->comp); if(*status) { LOG_ERROR("%s couldn't be enabled", component_name); goto error; } /* Enable control port. The callback specified here is the function which * will be called when an empty buffer header comes back to the port. */ component->comp->control->userdata = (void *)ctx; *status = mmal_port_enable(component->comp->control, mmalplay_bh_control_cb); if (*status) { LOG_ERROR("control port couldn't be enabled"); goto error; } component->time_setup = vcos_getmicrosecs() - component->time_setup; ctx->component_num++; return component->comp; error: component->time_setup = vcos_getmicrosecs() - component->time_setup; if (component->comp) mmal_component_destroy(component->comp); return NULL; }
int main( int argc, char **argv ) { int instNum = 0; VCHI_INSTANCE_T vchi_instance; VCHI_CONNECTION_T *vchi_connection = NULL; if ( argc > 1 ) { if (( strcmp( argv[1], "0" ) == 0 ) || ( strcmp( argv[1], "1" ) == 0 )) { instNum = atoi( argv[1] ); argv++; argc--; } } vcos_init(); if ( vchi_initialise( &vchi_instance ) != 0) { printf( "VCHI initialization failed\n" ); return -1; } //create a vchi connection if ( vchi_connect( NULL, 0, vchi_instance ) != 0) { printf( "VCHI connection failed\n" ); return -1; } vc_vchi_gencmd_init(vchi_instance, &vchi_connection, 1 ); if (argc > 1) { int i = 1; char buffer[ 1024 ]; size_t buffer_offset = 0; clock_t before=0, after=0; double time_diff; uint32_t show_time = 0; int ret; //reset the string buffer[0] = '\0'; //first, strip out a potential leading -t if( strcmp( argv[1], "-t" ) == 0 ) { show_time = 1; i++; } for (; i <= argc-1; i++) { buffer_offset = vcos_safe_strcpy( buffer, argv[i], sizeof(buffer), buffer_offset ); buffer_offset = vcos_safe_strcpy( buffer, " ", sizeof(buffer), buffer_offset ); } if( show_time ) before = clock(); //send the gencmd for the argument if (( ret = vc_gencmd_send( "%s", buffer )) != 0 ) { printf( "vc_gencmd_send returned %d\n", ret ); } //get + print out the response! if (( ret = vc_gencmd_read_response( buffer, sizeof( buffer ) )) != 0 ) { printf( "vc_gencmd_read_response returned %d\n", ret ); } if( show_time ) after = clock(); if( show_time ) { time_diff = ((double) (after - before)) / CLOCKS_PER_SEC; printf( "Time took %f seconds (%f msecs) (%f usecs)\n", time_diff, time_diff * 1000, time_diff * 1000000 ); } if ( buffer[0] != '\0' ) { if ( buffer[ strlen( buffer) - 1] == '\n' ) { fputs( buffer, stdout ); } else { printf("%s\n", buffer ); } } } vc_gencmd_stop(); //close the vchi connection if ( vchi_disconnect( vchi_instance ) != 0) { printf( "VCHI disconnect failed\n" ); return -1; } return 0; }