/** * main */ int main(int argc, const char **argv) { // Our main data storage vessel.. RASPIVID_STATE state; 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; MMAL_PORT_T *encoder_input_port = NULL; MMAL_PORT_T *encoder_output_port = NULL; FILE *output_file = NULL; bcm_host_init(); // Register our application with the logging system vcos_log_register("RaspiVid", VCOS_LOG_CATEGORY); signal(SIGINT, signal_handler); 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(0); } // Parse the command line and put options in to our status structure if (parse_cmdline(argc, argv, &state)) { status = -1; exit(0); } 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 three components. Camera, Preview and encoder. if ((status = create_camera_component(&state)) != MMAL_SUCCESS) { 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 ((status = create_encoder_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create encode component", __func__); raspipreview_destroy(&state.preview_parameters); destroy_camera_component(&state); } 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]; 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 ) { if (state.verbose) { fprintf(stderr, "Connecting camera preview port to preview input port\n"); fprintf(stderr, "Starting video preview\n"); } // Connect camera to preview status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection); } else { status = MMAL_SUCCESS; } if (status == MMAL_SUCCESS) { if (state.verbose) fprintf(stderr, "Connecting camera stills port to encoder input port\n"); // 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; } 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 { if (state.verbose) fprintf(stderr, "Opening output file \"%s\"\n", state.filename); output_file = fopen(state.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__, state.filename); } } // Set up our userdata - this is passed though to the callback where we need the information. callback_data.file_handle = output_file; callback_data.image = Mat(Size(state.width, state.height), CV_8UC1); callback_data.pstate = &state; callback_data.abort = 0; encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; if (state.verbose) fprintf(stderr, "Enabling encoder output port\n"); // 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; } if (state.demoMode) { // Run for the user specific time.. int num_iterations = state.timeout / state.demoInterval; int i; if (state.verbose) fprintf(stderr, "Running in demo mode\n"); for (i=0;state.timeout == 0 || i<num_iterations;i++) { raspicamcontrol_cycle_test(state.camera_component); vcos_sleep(state.demoInterval); } } else { // Only encode stuff if we have a filename and it opened if (output_file) { int wait; if (state.verbose) fprintf(stderr, "Starting video capture\n"); 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); } } // Now wait until we need to stop. Whilst waiting we do need to check to see if we have aborted (for example // out of storage space) // Going to check every ABORT_INTERVAL milliseconds for (wait = 0; state.timeout == 0 || wait < state.timeout; wait+= ABORT_INTERVAL) { vcos_sleep(ABORT_INTERVAL); if (callback_data.abort) break; } if (state.verbose) fprintf(stderr, "Finished capture\n"); } else { if (state.timeout) vcos_sleep(state.timeout); else for (;;) vcos_sleep(ABORT_INTERVAL); } } } 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"); // Disable all our ports that are not handled by connections check_disable_port(camera_still_port); check_disable_port(encoder_output_port); if (state.preview_parameters.wantPreview ) mmal_connection_destroy(state.preview_connection); mmal_connection_destroy(state.encoder_connection); // Can now close our file. Note disabling ports may flush buffers which causes // problems if we have already closed the file! if (output_file && output_file != stdout) fclose(output_file); /* 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 (state.verbose) fprintf(stderr, "Close down completed, all components disconnected, disabled and destroyed\n\n"); } if (status != MMAL_SUCCESS) raspicamcontrol_check_configuration(128); return 0; }
/** * main */ int main(int argc, const char **argv) { // Our main data storage vessel.. RASPIVID_STATE state; MMAL_STATUS_T status; 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; FILE *output_file = NULL; // Register our application with the logging system vcos_log_register("RaspiVid", VCOS_LOG_CATEGORY); printf("\nRaspiVid Camera App\n"); printf("===================\n\n"); signal(SIGINT, signal_handler); default_status(&state); // Do we have any parameters if (argc == 1) { display_valid_parameters(); exit(0); } // Parse the command line and put options in to our status structure if (parse_cmdline(argc, argv, &state)) { status = -1; exit(0); } if (state.verbose) dump_status(&state); // OK, we have a nice set of parameters. Now set up our components // We have three components. Camera, Preview and encoder. if (!create_camera_component(&state)) { vcos_log_error("%s: Failed to create camera component", __func__); } else if (!raspipreview_create(&state.preview_parameters)) { 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; if (state.verbose) printf("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]; 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 ) { if (state.verbose) { printf("Connecting camera preview port to preview input port\n"); printf("Starting video preview\n"); } // Connect camera to preview status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection); } if (status == MMAL_SUCCESS) { VCOS_STATUS_T vcos_status; if (state.verbose) printf("Connecting camera stills port to encoder input port\n"); // 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; } if (state.filename) { if (state.verbose) printf("Opening output file %s\n", state.filename); output_file = fopen(state.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__, state.filename); } } // Set up our userdata - this is passed though to the callback where we need the information. callback_data.file_handle = output_file; 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; if (state.verbose) printf("Enabling encoder output port\n"); // 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; } if (state.demoMode) { // Run for the user specific time.. int num_iterations = state.timeout / state.demoInterval; int i; printf("Running in demo mode\n"); for (i=0;i<num_iterations;i++) { raspicamcontrol_cycle_test(state.camera_component); vcos_sleep(state.demoInterval); } } else { // Only encode stuff if we have a filename and it opened if (output_file) { if (state.verbose) printf("Starting video capture\n"); 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); } } // Now wait until we need to stop vcos_sleep(state.timeout); printf("Finished capture\n"); } else vcos_sleep(state.timeout); } } 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) printf("Closing down\n"); // Disable all our ports that are not handled by connections check_disable_port(camera_still_port); check_disable_port(encoder_output_port); if (state.preview_parameters.wantPreview ) mmal_connection_destroy(state.preview_connection); mmal_connection_destroy(state.encoder_connection); // Can now close our file. Note disabling ports may flush buffers which causes // problems if we have already closed the file! if (output_file) fclose(output_file); /* 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 (state.verbose) printf("Close down completed, all components disconnected, disabled and destroyed\n\n"); } return 0; }