~MmalStillCallbackData() { vcos_semaphore_delete(&complete_semaphore); }
void ofxRaspicam::takePhoto() { ofFile myFile; FILE *output_file = NULL; vcos_sleep(photo.timeout); // Open the file string fileName = ofToDataPath("photos/"+ ofGetTimestampString()+".jpg", true); char *toChar = const_cast<char*> ( fileName.c_str() ); photo.filename = toChar; ofLogVerbose() << "Opening output file" << fileName; output_file = fopen(photo.filename, "wb"); if (!output_file) { // Notify user, carry on but discarding encoded output buffers ofLogVerbose() << "Error opening output file"; } photo.add_exif_tags(); callback_data.file_handle = output_file; // We only capture if a filename was specified and it opened if (output_file) { // Send all the buffers to the encoder output port int num = mmal_queue_length(photo.encoder_pool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(photo.encoder_pool->queue); if (!buffer) { ofLogVerbose() << "Unable to get a required buffer " << q << " from pool queue"; } if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS) { ofLogVerbose() << "Unable to send a buffer to encoder output port " << q; } } ofLogVerbose() << "Starting capture"; if (mmal_port_parameter_set_boolean(camera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { ofLogVerbose() << "Failed to start capture"; } else { // Wait for capture to complete // For some reason using vcos_semaphore_wait_timeout sometimes returns immediately with bad parameter error // even though it appears to be all correct, so reverting to untimed one until figure out why its erratic vcos_semaphore_wait(&callback_data.complete_semaphore); ofLogVerbose() << "Finished capture " << fileName; lastImage.loadImage(callback_data.photo->filename); } // Ensure we don't die if get callback with no open file callback_data.file_handle = NULL; fclose(output_file); } vcos_semaphore_delete(&callback_data.complete_semaphore); }
static int create_test() { int passed = 1; VCOS_SEMAPHORE_T semas[MAX_TESTED]; GUARD_T guard; int i; for(i=0; i<MAX_TESTED; i++) { if(vcos_semaphore_create(semas+i, "sem", i) != VCOS_SUCCESS) { vcos_assert(0); passed = 0; } } for(i=0; i<MAX_TESTED; i+=2) vcos_semaphore_delete(semas+i); for(i=0; i<MAX_TESTED; i+=2) if(vcos_semaphore_create(semas+i, "sem2", i) != VCOS_SUCCESS) passed = 0; if(passed) { if(guard_init(&guard) < 0) passed = 0; else { /* see if the values appear to be independent */ for(i=0; i<MAX_TESTED && passed; i++) { int j; guard.wait[0] = 10; guard.post[0] = 1; guard.wait[1] = 10; guard.post[1] = 100; guard.guard = semas+i; vcos_semaphore_post(&guard.go); /* wait for one more than we set, the first wait by the guard * should timeout, and it will post one more time. We should * then wake up here, and set the event, so the second wait * shouldn't timeout. */ for(j=0; j<i+1; j++) vcos_semaphore_wait(semas+i); vcos_event_flags_set(&guard.event, 1, VCOS_OR); vcos_semaphore_wait(&guard.done); if(!guard.timeout[0] || guard.timeout[1]) passed = 0; } guard_deinit(&guard, &passed); } for(i=0; i<MAX_TESTED; i++) vcos_semaphore_delete(semas+i); } return passed; }
int main(int argc, char **argv) { MMAL_STATUS_T status = MMAL_EINVAL; MMAL_COMPONENT_T *decoder = 0; MMAL_POOL_T *pool_in = 0, *pool_out = 0; MMAL_BOOL_T eos_sent = MMAL_FALSE, eos_received = MMAL_FALSE; unsigned int count; if (argc < 2) { fprintf(stderr, "invalid arguments\n"); return -1; } vcos_semaphore_create(&context.semaphore, "example", 1); SOURCE_OPEN(argv[1]); /* Create the decoder component. * This specific component exposes 2 ports (1 input and 1 output). Like most components * its expects the format of its input port to be set by the client in order for it to * know what kind of data it will be fed. */ status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &decoder); CHECK_STATUS(status, "failed to create decoder"); /* Enable control port so we can receive events from the component */ decoder->control->userdata = (void *)&context; status = mmal_port_enable(decoder->control, control_callback); CHECK_STATUS(status, "failed to enable control port"); /* Get statistics on the input port */ MMAL_PARAMETER_CORE_STATISTICS_T stats = {{0}}; stats.hdr.id = MMAL_PARAMETER_CORE_STATISTICS; stats.hdr.size = sizeof(MMAL_PARAMETER_CORE_STATISTICS_T); status = mmal_port_parameter_get(decoder->input[0], &stats.hdr); CHECK_STATUS(status, "failed to get stats"); fprintf(stderr, "stats: %i, %i", stats.stats.buffer_count, stats.stats.max_delay); /* Set the zero-copy parameter on the input port */ MMAL_PARAMETER_BOOLEAN_T zc = {{MMAL_PARAMETER_ZERO_COPY, sizeof(zc)}, MMAL_TRUE}; status = mmal_port_parameter_set(decoder->input[0], &zc.hdr); fprintf(stderr, "status: %i\n", status); /* Set the zero-copy parameter on the output port */ status = mmal_port_parameter_set_boolean(decoder->output[0], MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); fprintf(stderr, "status: %i\n", status); /* Set format of video decoder input port */ MMAL_ES_FORMAT_T *format_in = decoder->input[0]->format; format_in->type = MMAL_ES_TYPE_VIDEO; format_in->encoding = MMAL_ENCODING_H264; format_in->es->video.width = 1280; format_in->es->video.height = 720; format_in->es->video.frame_rate.num = 30; format_in->es->video.frame_rate.den = 1; format_in->es->video.par.num = 1; format_in->es->video.par.den = 1; /* If the data is known to be framed then the following flag should be set: * format_in->flags |= MMAL_ES_FORMAT_FLAG_FRAMED; */ SOURCE_READ_CODEC_CONFIG_DATA(codec_header_bytes, codec_header_bytes_size); status = mmal_format_extradata_alloc(format_in, codec_header_bytes_size); CHECK_STATUS(status, "failed to allocate extradata"); format_in->extradata_size = codec_header_bytes_size; if (format_in->extradata_size) memcpy(format_in->extradata, codec_header_bytes, format_in->extradata_size); status = mmal_port_format_commit(decoder->input[0]); CHECK_STATUS(status, "failed to commit format"); /* Our decoder can do internal colour conversion, ask for a conversion to RGB565 */ MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format; format_out->encoding = MMAL_ENCODING_RGB16; status = mmal_port_format_commit(decoder->output[0]); CHECK_STATUS(status, "failed to commit format"); /* Display the output port format */ fprintf(stderr, "%s\n", decoder->output[0]->name); fprintf(stderr, " type: %i, fourcc: %4.4s\n", format_out->type, (char *)&format_out->encoding); fprintf(stderr, " bitrate: %i, framed: %i\n", format_out->bitrate, !!(format_out->flags & MMAL_ES_FORMAT_FLAG_FRAMED)); fprintf(stderr, " extra data: %i, %p\n", format_out->extradata_size, format_out->extradata); fprintf(stderr, " width: %i, height: %i, (%i,%i,%i,%i)\n", format_out->es->video.width, format_out->es->video.height, format_out->es->video.crop.x, format_out->es->video.crop.y, format_out->es->video.crop.width, format_out->es->video.crop.height); /* The format of both ports is now set so we can get their buffer requirements and create * our buffer headers. We use the buffer pool API to create these. */ decoder->input[0]->buffer_num = decoder->input[0]->buffer_num_min; decoder->input[0]->buffer_size = decoder->input[0]->buffer_size_min; decoder->output[0]->buffer_num = decoder->output[0]->buffer_num_min; decoder->output[0]->buffer_size = decoder->output[0]->buffer_size_min; pool_in = mmal_pool_create(decoder->input[0]->buffer_num, decoder->input[0]->buffer_size); pool_out = mmal_pool_create(decoder->output[0]->buffer_num, decoder->output[0]->buffer_size); /* Create a queue to store our decoded video frames. The callback we will get when * a frame has been decoded will put the frame into this queue. */ context.queue = mmal_queue_create(); /* Store a reference to our context in each port (will be used during callbacks) */ decoder->input[0]->userdata = (void *)&context; decoder->output[0]->userdata = (void *)&context; /* Enable all the input port and the output port. * The callback specified here is the function which will be called when the buffer header * we sent to the component has been processed. */ status = mmal_port_enable(decoder->input[0], input_callback); CHECK_STATUS(status, "failed to enable input port"); status = mmal_port_enable(decoder->output[0], output_callback); CHECK_STATUS(status, "failed to enable output port"); /* Component won't start processing data until it is enabled. */ status = mmal_component_enable(decoder); CHECK_STATUS(status, "failed to enable component"); /* Start decoding */ fprintf(stderr, "start decoding\n"); /* This is the main processing loop */ for (count = 0; !eos_received && count < 500; count++) { MMAL_BUFFER_HEADER_T *buffer; /* Wait for buffer headers to be available on either of the decoder ports */ vcos_semaphore_wait(&context.semaphore); /* Check for errors */ if (context.status != MMAL_SUCCESS) break; /* Send data to decode to the input port of the video decoder */ if (!eos_sent && (buffer = mmal_queue_get(pool_in->queue)) != NULL) { SOURCE_READ_DATA_INTO_BUFFER(buffer); if(!buffer->length) eos_sent = MMAL_TRUE; buffer->flags = buffer->length ? 0 : MMAL_BUFFER_HEADER_FLAG_EOS; buffer->pts = buffer->dts = MMAL_TIME_UNKNOWN; fprintf(stderr, "sending %i bytes\n", (int)buffer->length); status = mmal_port_send_buffer(decoder->input[0], buffer); CHECK_STATUS(status, "failed to send buffer"); } /* Get our decoded frames */ while ((buffer = mmal_queue_get(context.queue)) != NULL) { /* We have a frame, do something with it (why not display it for instance?). * Once we're done with it, we release it. It will automatically go back * to its original pool so it can be reused for a new video frame. */ eos_received = buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS; if (buffer->cmd) fprintf(stderr, "received event %4.4s", (char *)&buffer->cmd); else fprintf(stderr, "decoded frame (flags %x)\n", buffer->flags); mmal_buffer_header_release(buffer); } /* Send empty buffers to the output port of the decoder */ while ((buffer = mmal_queue_get(pool_out->queue)) != NULL) { status = mmal_port_send_buffer(decoder->output[0], buffer); CHECK_STATUS(status, "failed to send buffer"); } } /* Stop decoding */ fprintf(stderr, "stop decoding\n"); /* Stop everything. Not strictly necessary since mmal_component_destroy() * will do that anyway */ mmal_port_disable(decoder->input[0]); mmal_port_disable(decoder->output[0]); mmal_component_disable(decoder); error: /* Cleanup everything */ if (decoder) mmal_component_destroy(decoder); if (pool_in) mmal_pool_destroy(pool_in); if (pool_out) mmal_pool_destroy(pool_out); if (context.queue) mmal_queue_destroy(context.queue); SOURCE_CLOSE(); vcos_semaphore_delete(&context.semaphore); return status == MMAL_SUCCESS ? 0 : -1; }
/** * main */ int main(int argc, const char **argv) { // Our main data storage vessel.. RASPISTILLYUV_STATE state; int exit_code = EX_OK; MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_PORT_T *camera_preview_port = NULL; MMAL_PORT_T *camera_video_port = NULL; MMAL_PORT_T *camera_still_port = NULL; MMAL_PORT_T *preview_input_port = NULL; FILE *output_file = NULL; bcm_host_init(); // Register our application with the logging system vcos_log_register("RaspiStill", VCOS_LOG_CATEGORY); signal(SIGINT, signal_handler); // Disable USR1 for the moment - may be reenabled if go in to signal capture mode signal(SIGUSR1, SIG_IGN); default_status(&state); // Do we have any parameters if (argc == 1) { fprintf(stderr, "\n%s Camera App %s\n\n", basename(argv[0]), VERSION_STRING); display_valid_parameters(basename(argv[0])); exit(EX_USAGE); } default_status(&state); // Parse the command line and put options in to our status structure if (parse_cmdline(argc, argv, &state)) { status = -1; exit(EX_USAGE); } if (state.verbose) { fprintf(stderr, "\n%s Camera App %s\n\n", basename(argv[0]), VERSION_STRING); dump_status(&state); } // OK, we have a nice set of parameters. Now set up our components // We have two components. Camera and Preview // Camera is different in stills/video, but preview // is the same so handed off to a separate module if ((status = create_camera_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create camera component", __func__); exit_code = EX_SOFTWARE; } else if ((status = raspipreview_create(&state.preview_parameters)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create preview component", __func__); destroy_camera_component(&state); exit_code = EX_SOFTWARE; } else { PORT_USERDATA callback_data; if (state.verbose) fprintf(stderr, "Starting component connection stage\n"); camera_preview_port = state.camera_component->output[MMAL_CAMERA_PREVIEW_PORT]; camera_video_port = state.camera_component->output[MMAL_CAMERA_VIDEO_PORT]; camera_still_port = state.camera_component->output[MMAL_CAMERA_CAPTURE_PORT]; // Note we are lucky that the preview and null sink components use the same input port // so we can simple do this without conditionals preview_input_port = state.preview_parameters.preview_component->input[0]; // Connect camera to preview (which might be a null_sink if no preview required) status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection); if (status == MMAL_SUCCESS) { VCOS_STATUS_T vcos_status; // Set up our userdata - this is passed though to the callback where we need the information. // Null until we open our filename callback_data.file_handle = NULL; callback_data.pstate = &state; vcos_status = vcos_semaphore_create(&callback_data.complete_semaphore, "RaspiStill-sem", 0); vcos_assert(vcos_status == VCOS_SUCCESS); camera_still_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; if (state.verbose) fprintf(stderr, "Enabling camera still output port\n"); // Enable the camera still output port and tell it its callback function status = mmal_port_enable(camera_still_port, camera_buffer_callback); if (status != MMAL_SUCCESS) { vcos_log_error("Failed to setup camera output"); goto error; } if (state.verbose) fprintf(stderr, "Starting video preview\n"); int frame, keep_looping = 1; FILE *output_file = NULL; char *use_filename = NULL; // Temporary filename while image being written char *final_filename = NULL; // Name that file gets once writing complete frame = 0; while (keep_looping) { keep_looping = wait_for_next_frame(&state, &frame); // Open the file if (state.filename) { if (state.filename[0] == '-') { output_file = stdout; // Ensure we don't upset the output stream with diagnostics/info state.verbose = 0; } else { vcos_assert(use_filename == NULL && final_filename == NULL); status = create_filenames(&final_filename, &use_filename, state.filename, frame); if (status != MMAL_SUCCESS) { vcos_log_error("Unable to create filenames"); goto error; } if (state.verbose) fprintf(stderr, "Opening output file %s\n", final_filename); // Technically it is opening the temp~ filename which will be ranamed to the final filename output_file = fopen(use_filename, "wb"); if (!output_file) { // Notify user, carry on but discarding encoded output buffers vcos_log_error("%s: Error opening output file: %s\nNo output file will be generated\n", __func__, use_filename); } } callback_data.file_handle = output_file; } if (output_file) { int num, q; // There is a possibility that shutter needs to be set each loop. if (mmal_status_to_int(mmal_port_parameter_set_uint32(state.camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, state.camera_parameters.shutter_speed) != MMAL_SUCCESS)) vcos_log_error("Unable to set shutter speed"); // Send all the buffers to the camera output port num = mmal_queue_length(state.camera_pool->queue); for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.camera_pool->queue); if (!buffer) vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(camera_still_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to camera output port (%d)", q); } if (state.burstCaptureMode && frame==1) { mmal_port_parameter_set_boolean(state.camera_component->control, MMAL_PARAMETER_CAMERA_BURST_CAPTURE, 1); } if (state.verbose) fprintf(stderr, "Starting capture %d\n", frame); if (mmal_port_parameter_set_boolean(camera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to start capture", __func__); } else { // Wait for capture to complete // For some reason using vcos_semaphore_wait_timeout sometimes returns immediately with bad parameter error // even though it appears to be all correct, so reverting to untimed one until figure out why its erratic vcos_semaphore_wait(&callback_data.complete_semaphore); if (state.verbose) fprintf(stderr, "Finished capture %d\n", frame); } // Ensure we don't die if get callback with no open file callback_data.file_handle = NULL; if (output_file != stdout) { rename_file(&state, output_file, final_filename, use_filename, frame); } } if (use_filename) { free(use_filename); use_filename = NULL; } if (final_filename) { free(final_filename); final_filename = NULL; } } // end for (frame) vcos_semaphore_delete(&callback_data.complete_semaphore); } else { mmal_status_to_int(status); vcos_log_error("%s: Failed to connect camera to preview", __func__); } error: mmal_status_to_int(status); if (state.verbose) fprintf(stderr, "Closing down\n"); if (output_file) fclose(output_file); // Disable all our ports that are not handled by connections check_disable_port(camera_video_port); if (state.preview_connection) mmal_connection_destroy(state.preview_connection); /* Disable components */ if (state.preview_parameters.preview_component) mmal_component_disable(state.preview_parameters.preview_component); if (state.camera_component) mmal_component_disable(state.camera_component); raspipreview_destroy(&state.preview_parameters); destroy_camera_component(&state); if (state.verbose) fprintf(stderr, "Close down completed, all components disconnected, disabled and destroyed\n\n"); } if (status != MMAL_SUCCESS) raspicamcontrol_check_configuration(128); return exit_code; }
VCOS_STATUS_T vcos_thread_create(VCOS_THREAD_T *thread, const char *name, VCOS_THREAD_ATTR_T *attrs, VCOS_THREAD_ENTRY_FN_T entry, void *arg) { VCOS_STATUS_T st; pthread_attr_t pt_attrs; VCOS_THREAD_ATTR_T *local_attrs = attrs ? attrs : &default_attrs; int rc; vcos_assert(thread); memset(thread, 0, sizeof(VCOS_THREAD_T)); rc = pthread_attr_init(&pt_attrs); if (rc < 0) return VCOS_ENOMEM; st = vcos_semaphore_create(&thread->suspend, NULL, 0); if (st != VCOS_SUCCESS) { pthread_attr_destroy(&pt_attrs); return st; } pthread_attr_setstacksize(&pt_attrs, local_attrs->ta_stacksz); #if VCOS_CAN_SET_STACK_ADDR if (local_attrs->ta_stackaddr) { pthread_attr_setstackaddr(&pt_attrs, local_attrs->ta_stackaddr); } #else vcos_demand(local_attrs->ta_stackaddr == 0); #endif /* pthread_attr_setpriority(&pt_attrs, local_attrs->ta_priority); */ vcos_assert(local_attrs->ta_stackaddr == 0); /* Not possible */ thread->entry = entry; thread->arg = arg; thread->legacy = local_attrs->legacy; strncpy(thread->name, name, sizeof(thread->name)); thread->name[sizeof(thread->name)-1] = '\0'; memset(thread->at_exit, 0, sizeof(thread->at_exit)); rc = pthread_create(&thread->thread, &pt_attrs, vcos_thread_entry, thread); pthread_attr_destroy(&pt_attrs); if (rc < 0) { vcos_semaphore_delete(&thread->suspend); return VCOS_ENOMEM; } else { return VCOS_SUCCESS; } }
void internelVideoWithDetails(char *filename, int width, int height, int duration) { RASPISTILL_STATE state; MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_PORT_T *camera_video_port = NULL; MMAL_PORT_T *encoder_input_port = NULL; MMAL_PORT_T *encoder_output_port = NULL; FILE *output_file = NULL; if (width > 1920) { width = 1920; } else if (width < 20) { width = 20; } if (height > 1080) { height = 1080; } else if (height < 20) { height = 20; } bcm_host_init(); default_status(&state); state.width = width; state.height = height; state.quality = 0; state.videoEncode = 1; state.filename = filename; if ((status = create_video_camera_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create camera component", __func__); } else if ((status = create_video_encoder_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create encode component", __func__); destroy_camera_component(&state); } else { PORT_USERDATA callback_data; camera_video_port = state.camera_component->output[MMAL_CAMERA_VIDEO_PORT]; encoder_input_port = state.encoder_component->input[0]; encoder_output_port = state.encoder_component->output[0]; // Now connect the camera to the encoder status = connect_ports(camera_video_port, encoder_input_port, &state.encoder_connection); if (status != MMAL_SUCCESS) { vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__); goto error; } // Set up our userdata - this is passed though to the callback where we need the information. // Null until we open our filename callback_data.pstate = &state; if (status != MMAL_SUCCESS) { vcos_log_error("Failed to setup encoder output"); goto error; } if (state.filename) { output_file = fopen(state.filename, "wb"); callback_data.file_handle = output_file; callback_data.pstate = &state; callback_data.abort = 0; } encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; int wait; // Enable the encoder output port and tell it its callback function status = mmal_port_enable(encoder_output_port, encoder_buffer_callback); if (mmal_port_parameter_set_boolean(camera_video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { goto error; } // Send all the buffers to the encoder output port { int num = mmal_queue_length(state.encoder_pool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.encoder_pool->queue); if (!buffer) vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to encoder output port (%d)", q); } } for (wait = 0; wait < duration; wait+= ABORT_INTERVAL) { vcos_sleep(ABORT_INTERVAL); if (callback_data.abort) break; } // Disable encoder output port status = mmal_port_disable(encoder_output_port); vcos_semaphore_delete(&callback_data.complete_semaphore); } error: mmal_status_to_int(status); // Disable all our ports that are not handled by connections check_disable_port(encoder_output_port); if (output_file && output_file != stdout) fclose(output_file); mmal_connection_destroy(state.encoder_connection); if (state.encoder_component) mmal_component_disable(state.encoder_component); if (state.camera_component) mmal_component_disable(state.camera_component); destroy_encoder_component(&state); destroy_camera_component(&state); if (status != MMAL_SUCCESS) raspicamcontrol_check_configuration(128); }
uint8_t *internelPhotoWithDetails(int width, int height, int quality,MMAL_FOURCC_T encoding, PicamParams *parms, long *sizeread) { RASPISTILL_STATE state; MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_PORT_T *preview_input_port = NULL; MMAL_PORT_T *camera_preview_port = NULL; MMAL_PORT_T *camera_still_port = NULL; MMAL_PORT_T *encoder_input_port = NULL; MMAL_PORT_T *encoder_output_port = NULL; if (width > 2592) { width = 2592; } else if (width < 20) { width = 20; } if (height > 1944) { height = 1944; } else if (height < 20) { height = 20; } if (quality > 100) { quality = 100; } else if (quality < 0) { quality = 85; } bcm_host_init(); default_status(&state); state.width = width; state.height = height; state.quality = quality; state.encoding = encoding; state.videoEncode = 0; state.camera_parameters.exposureMode = parms->exposure; state.camera_parameters.exposureMeterMode = parms->meterMode; state.camera_parameters.awbMode = parms->awbMode; state.camera_parameters.imageEffect = parms->imageFX; state.camera_parameters.ISO = parms->ISO; state.camera_parameters.sharpness = parms->sharpness; state.camera_parameters.contrast = parms->contrast; state.camera_parameters.brightness= parms->brightness; state.camera_parameters.saturation = parms->saturation; state.camera_parameters.videoStabilisation = parms->videoStabilisation; /// 0 or 1 (false or true) state.camera_parameters.exposureCompensation = parms->exposureCompensation; state.camera_parameters.rotation = parms->rotation; state.camera_parameters.hflip = parms->hflip; state.camera_parameters.vflip = parms->vflip; MMAL_COMPONENT_T *preview = 0; if ((status = create_video_camera_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create camera component", __func__); } else if ((status = mmal_component_create("vc.null_sink", &preview)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create preview component", __func__); destroy_camera_component(&state); } else if ((status = create_encoder_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create encode component", __func__); destroy_camera_component(&state); } else { status = mmal_component_enable(preview); state.preview_component = preview; PORT_USERDATA callback_data; camera_preview_port = state.camera_component->output[MMAL_CAMERA_PREVIEW_PORT]; camera_still_port = state.camera_component->output[MMAL_CAMERA_CAPTURE_PORT]; encoder_input_port = state.encoder_component->input[0]; encoder_output_port = state.encoder_component->output[0]; preview_input_port = state.preview_component->input[0]; status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection); VCOS_STATUS_T vcos_status; // Now connect the camera to the encoder status = connect_ports(camera_still_port, encoder_input_port, &state.encoder_connection); if (status != MMAL_SUCCESS) { vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__); goto error; } // Set up our userdata - this is passed though to the callback where we need the information. // Null until we open our filename callback_data.pstate = &state; vcos_status = vcos_semaphore_create(&callback_data.complete_semaphore, "picam-sem", 0); vcos_assert(vcos_status == VCOS_SUCCESS); if (status != MMAL_SUCCESS) { vcos_log_error("Failed to setup encoder output"); goto error; } int num, q; // Enable the encoder output port encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; // Enable the encoder output port and tell it its callback function status = mmal_port_enable(encoder_output_port, encoder_buffer_callback); // Send all the buffers to the encoder output port num = mmal_queue_length(state.encoder_pool->queue); for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.encoder_pool->queue); if (!buffer) vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to encoder output port (%d)", q); } if (mmal_port_parameter_set_boolean(camera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to start capture", __func__); } else { // Wait for capture to complete // For some reason using vcos_semaphore_wait_timeout sometimes returns immediately with bad parameter error // even though it appears to be all correct, so reverting to untimed one until figure out why its erratic vcos_semaphore_wait(&callback_data.complete_semaphore); } // Disable encoder output port status = mmal_port_disable(encoder_output_port); *sizeread = state.bytesStored; vcos_semaphore_delete(&callback_data.complete_semaphore); } error: mmal_status_to_int(status); // Disable all our ports that are not handled by connections check_disable_port(encoder_output_port); mmal_connection_destroy(state.encoder_connection); if (state.encoder_component) mmal_component_disable(state.encoder_component); if (state.preview_component) { mmal_component_disable(state.preview_component); mmal_component_destroy(state.preview_component); state.preview_component = NULL; } if (state.camera_component) mmal_component_disable(state.camera_component); destroy_encoder_component(&state); destroy_camera_component(&state); if (status != MMAL_SUCCESS) raspicamcontrol_check_configuration(128); return state.filedata; }
/** * main */ int main(int argc, const char **argv) { // Our main data storage vessel.. RASPISTILL_STATE state; MMAL_STATUS_T status = -1; MMAL_PORT_T *camera_preview_port = NULL; MMAL_PORT_T *camera_video_port = NULL; MMAL_PORT_T *camera_still_port = NULL; MMAL_PORT_T *preview_input_port = NULL; MMAL_PORT_T *encoder_input_port = NULL; MMAL_PORT_T *encoder_output_port = NULL; bcm_host_init(); clock_t elapsedTime; time_t timer_begin,timer_end; double secondsElapsed; time(&timer_begin); /* get current time; same as: timer = time(NULL) */ // create window cvNamedWindow("camcvWin", CV_WINDOW_AUTOSIZE);//CV_WINDOW_NORMAL);//CV_WINDOW_AUTOSIZE); //cvResizeWindow("camcvWin",640,480); signal(SIGINT, signal_handler); default_status(&state); if (!create_camera_component(&state)) { vcos_log_error("%s: Failed to create camera component", __func__); } else if ( (status = raspipreview_create(&state.preview_parameters)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create preview component", __func__); destroy_camera_component(&state); } else if (!create_encoder_component(&state)) { vcos_log_error("%s: Failed to create encode component", __func__); raspipreview_destroy(&state.preview_parameters); destroy_camera_component(&state); } else { PORT_USERDATA callback_data; // *** PR : we don't want preview camera_preview_port = NULL;//state.camera_component->output[MMAL_CAMERA_PREVIEW_PORT]; camera_video_port = state.camera_component->output[MMAL_CAMERA_VIDEO_PORT]; camera_still_port = state.camera_component->output[MMAL_CAMERA_CAPTURE_PORT]; preview_input_port = state.preview_parameters.preview_component->input[0]; encoder_input_port = state.encoder_component->input[0]; encoder_output_port = state.encoder_component->output[0]; if (state.preview_parameters.wantPreview ) { // PR : we don't want preview // Connect camera to preview // status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection); } VCOS_STATUS_T vcos_status; // Now connect the camera to the encoder status = connect_ports(camera_still_port, encoder_input_port, &state.encoder_connection); if (status != MMAL_SUCCESS) { vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__); goto error; } // Set up our userdata - this is passed though to the callback where we need the information. // Null until we open our filename //callback_data.file_handle = NULL; callback_data.pstate = &state; vcos_status = vcos_semaphore_create(&callback_data.complete_semaphore, "RaspiStill-sem", 0); vcos_assert(vcos_status == VCOS_SUCCESS); encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; // Enable the encoder output port and tell it its callback function status = mmal_port_enable(encoder_output_port, encoder_buffer_callback); if (status != MMAL_SUCCESS) { vcos_log_error("Failed to setup encoder output"); goto error; } int num_iterations = 100; int frame,num,q; elapsedTime= clock(); printf("time=%d\n",elapsedTime); for (frame = 1;frame<=num_iterations; frame++) { // Send all the buffers to the encoder output port num = mmal_queue_length(state.encoder_pool->queue); for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.encoder_pool->queue); //if (!buffer) // vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to encoder output port (%d)", q); } if (mmal_port_parameter_set_boolean(camera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to start capture", __func__); } else { // Wait for capture to complete // For some reason using vcos_semaphore_wait_timeout sometimes returns immediately with bad parameter error // even though it appears to be all correct, so reverting to untimed one until figure out why its erratic vcos_semaphore_wait(&callback_data.complete_semaphore); } } // end for (frame) vcos_semaphore_delete(&callback_data.complete_semaphore); // compute elapsed time since begin of the loop and display error: mmal_status_to_int(status); // Disable all our ports that are not handled by connections check_disable_port(camera_video_port); check_disable_port(encoder_output_port); // PR : we don't want preview //if (state.preview_parameters.wantPreview ) // mmal_connection_destroy(state.preview_connection); mmal_connection_destroy(state.encoder_connection); /* Disable components */ if (state.encoder_component) mmal_component_disable(state.encoder_component); if (state.preview_parameters.preview_component) mmal_component_disable(state.preview_parameters.preview_component); if (state.camera_component) mmal_component_disable(state.camera_component); destroy_encoder_component(&state); raspipreview_destroy(&state.preview_parameters); destroy_camera_component(&state); } if (status != 0) raspicamcontrol_check_configuration(128); // compute FPS time(&timer_end); /* get current time; same as: timer = time(NULL) */ secondsElapsed = difftime(timer_end,timer_begin); printf ("%.f seconds for %d frames : FPS = %f", secondsElapsed,nbFrames,(float)((float)(nbFrames)/secondsElapsed)); printf("time=%d\n",clock()); elapsedTime=clock()-elapsedTime; printf ("(time) %d clicks (%f seconds). nb Frames = %d. FPS = %f\n",elapsedTime,((float)elapsedTime)/CLOCKS_PER_SEC, nbFrames, (float)nbFrames/(((float)elapsedTime)/CLOCKS_PER_SEC)); return 0; }
/** Allocate a port structure */ MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *component, MMAL_PORT_TYPE_T type, unsigned int extra_size) { MMAL_PORT_T *port; MMAL_PORT_PRIVATE_CORE_T *core; unsigned int name_size = strlen(component->name) + sizeof(PORT_NAME_FORMAT); unsigned int size = sizeof(*port) + sizeof(MMAL_PORT_PRIVATE_T) + sizeof(MMAL_PORT_PRIVATE_CORE_T) + name_size + extra_size; MMAL_BOOL_T lock = 0, lock_send = 0, lock_transit = 0, sema_transit = 0; MMAL_BOOL_T lock_stats = 0; LOG_TRACE("component:%s type:%u extra:%u", component->name, type, extra_size); port = vcos_calloc(1, size, "mmal port"); if (!port) { LOG_ERROR("failed to allocate port, size %u", size); return 0; } port->type = type; port->priv = (MMAL_PORT_PRIVATE_T *)(port+1); port->priv->core = core = (MMAL_PORT_PRIVATE_CORE_T *)(port->priv+1); if (extra_size) port->priv->module = (struct MMAL_PORT_MODULE_T *)(port->priv->core+1); port->component = component; port->name = core->name = ((char *)(port->priv->core+1)) + extra_size; core->name_size = name_size; mmal_port_name_update(port); port->priv->pf_connect = mmal_port_connect_default; lock = vcos_mutex_create(&port->priv->core->lock, "mmal port lock") == VCOS_SUCCESS; lock_send = vcos_mutex_create(&port->priv->core->send_lock, "mmal port send lock") == VCOS_SUCCESS; lock_transit = vcos_mutex_create(&port->priv->core->transit_lock, "mmal port transit lock") == VCOS_SUCCESS; sema_transit = vcos_semaphore_create(&port->priv->core->transit_sema, "mmal port transit sema", 1) == VCOS_SUCCESS; lock_stats = vcos_mutex_create(&port->priv->core->stats_lock, "mmal stats lock") == VCOS_SUCCESS; if (!lock || !lock_send || !lock_transit || !sema_transit || !lock_stats) { LOG_ERROR("%s: failed to create sync objects (%u,%u,%u,%u,%u)", port->name, lock, lock_send, lock_transit, sema_transit, lock_stats); goto error; } port->format = mmal_format_alloc(); if (!port->format) { LOG_ERROR("%s: failed to allocate format object", port->name); goto error; } port->priv->core->format_ptr_copy = port->format; LOG_TRACE("%s: created at %p", port->name, port); return port; error: if (lock) vcos_mutex_delete(&port->priv->core->lock); if (lock_send) vcos_mutex_delete(&port->priv->core->send_lock); if (lock_transit) vcos_mutex_delete(&port->priv->core->transit_lock); if (sema_transit) vcos_semaphore_delete(&port->priv->core->transit_sema); if (lock_stats) vcos_mutex_delete(&port->priv->core->stats_lock); if (port->format) mmal_format_free(port->format); vcos_free(port); return 0; }
VCOS_STATUS_T vcos_thread_create(VCOS_THREAD_T *thread, const char *name, VCOS_THREAD_ATTR_T *attrs, VCOS_THREAD_ENTRY_FN_T entry, void *arg) { VCOS_STATUS_T st; VCOS_THREAD_ATTR_T *local_attrs = attrs ? attrs : &default_attrs; vcos_assert(thread); memset(thread, 0, sizeof(VCOS_THREAD_T)); st = vcos_semaphore_create(&thread->suspend, NULL, 0); if (st != VCOS_SUCCESS) { return st; } vcos_assert(local_attrs->ta_stackaddr == 0); thread->entry = entry; thread->arg = arg; thread->legacy = local_attrs->legacy; #ifdef WIN32_KERN strncpy_s(thread->name, sizeof(thread->name), name, sizeof(thread->name)); #else strncpy(thread->name, name, sizeof(thread->name)); #endif thread->name[sizeof(thread->name) - 1] = '\0'; memset(thread->at_exit, 0, sizeof(thread->at_exit)); #ifdef WIN32_KERN OBJECT_ATTRIBUTES objectAttributes; InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); NTSTATUS status = PsCreateSystemThread( &thread->thread, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, vcos_thread_entry, thread); if (!NT_SUCCESS(status)) { vcos_semaphore_delete(&thread->suspend); st = VCOS_ENOMEM; } #else thread->thread = CreateThread(NULL, local_attrs->ta_stacksz, (LPTHREAD_START_ROUTINE)vcos_thread_entry, thread, 0, NULL); if (thread->thread == NULL) { vcos_semaphore_delete(&thread->suspend); st = VCOS_ENOMEM; } #endif return st; }