int main(int argc, char **argv) { FILE *dest = NULL; image frame_image; evx1_encoder *encoder; bit_stream cairo_stream; int32 frame_index = 0; int32 encoded_size = 0; int32 content_width = 0; int32 content_height = 0; int32 content_format = 0; EVX_MEDIA_FILE_HEADER header; evx_msg("Copyright (c) 2010-2014 Joe Bertolami. All Right Reserved."); if (4 != argc) { // No need to get fancy. evx_msg("Required syntax: convert <input_filename> quality <output_filename>"); return 0; } dest = fopen(argv[3], "wb"); if (!dest) { evx_msg("Error opening dest file %s", argv[3]); return 0; } ffmpeg_initialize(); if (0 != ffmpeg_play_file(argv[1], (int*) &content_format, (int*) &content_width, (int*) &content_height)) { evx_msg("Failed to open content file %s", argv[1]); ffmpeg_deinitialize(); fclose(dest); return 0; } create_encoder(&encoder); encoder->set_quality(atoi(argv[2])); create_image(EVX_IMAGE_FORMAT_R8G8B8, content_width, content_height, &frame_image); cairo_stream.resize_capacity((4*EVX_MB) << 3); _prepare_evx_header(&header, content_width, content_height); fwrite(&header, sizeof(header), 1, dest); while (ffmpeg_refresh(&encoded_size) >= 0) { ffmpeg_copy_current_frame(frame_image.query_data(), frame_image.query_row_pitch()); // encode using cairo and then flush the frame to disk. encoder->encode(frame_image.query_data(), frame_image.query_width(), frame_image.query_height(), &cairo_stream); EVX_MEDIA_FRAME_HEADER frame_header; frame_header.magic[0] = 'E'; frame_header.magic[0] = 'V'; frame_header.magic[0] = 'F'; frame_header.magic[0] = 'H'; frame_header.frame_index = frame_index++; frame_header.frame_size = cairo_stream.query_byte_occupancy(); frame_header.header_size = sizeof(frame_header); fwrite(&frame_header, sizeof(frame_header), 1, dest); fwrite(cairo_stream.query_data(), cairo_stream.query_byte_occupancy(), 1, dest); cairo_stream.empty(); if (0 == (frame_index % 10)) { evx_msg("Processing frame %i", frame_index); } } destroy_encoder(encoder); ffmpeg_deinitialize(); fclose(dest); return 0; }
void obe_close( obe_t *h ) { void *ret_ptr; fprintf( stderr, "closing obe \n" ); /* Cancel input thread */ for( int i = 0; i < h->num_devices; i++ ) { pthread_cancel( h->devices[i]->device_thread ); pthread_join( h->devices[i]->device_thread, &ret_ptr ); } fprintf( stderr, "input cancelled \n" ); /* Cancel filter threads */ for( int i = 0; i < h->num_filters; i++ ) { pthread_mutex_lock( &h->filters[i]->queue.mutex ); h->filters[i]->cancel_thread = 1; pthread_cond_signal( &h->filters[i]->queue.in_cv ); pthread_mutex_unlock( &h->filters[i]->queue.mutex ); pthread_join( h->filters[i]->filter_thread, &ret_ptr ); } fprintf( stderr, "filters cancelled \n" ); /* Cancel encoder threads */ for( int i = 0; i < h->num_encoders; i++ ) { pthread_mutex_lock( &h->encoders[i]->queue.mutex ); h->encoders[i]->cancel_thread = 1; pthread_cond_signal( &h->encoders[i]->queue.in_cv ); pthread_mutex_unlock( &h->encoders[i]->queue.mutex ); pthread_join( h->encoders[i]->encoder_thread, &ret_ptr ); } fprintf( stderr, "encoders cancelled \n" ); /* Cancel encoder smoothing thread */ if ( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) { pthread_mutex_lock( &h->enc_smoothing_queue.mutex ); h->cancel_enc_smoothing_thread = 1; pthread_cond_signal( &h->enc_smoothing_queue.in_cv ); pthread_mutex_unlock( &h->enc_smoothing_queue.mutex ); /* send a clock tick in case smoothing is waiting for one */ pthread_mutex_lock( &h->obe_clock_mutex ); pthread_cond_broadcast( &h->obe_clock_cv ); pthread_mutex_unlock( &h->obe_clock_mutex ); pthread_join( h->enc_smoothing_thread, &ret_ptr ); } fprintf( stderr, "encoder smoothing cancelled \n" ); /* Cancel mux thread */ pthread_mutex_lock( &h->mux_queue.mutex ); h->cancel_mux_thread = 1; pthread_cond_signal( &h->mux_queue.in_cv ); pthread_mutex_unlock( &h->mux_queue.mutex ); pthread_join( h->mux_thread, &ret_ptr ); fprintf( stderr, "mux cancelled \n" ); /* Cancel mux smoothing thread */ pthread_mutex_lock( &h->mux_smoothing_queue.mutex ); h->cancel_mux_smoothing_thread = 1; pthread_cond_signal( &h->mux_smoothing_queue.in_cv ); pthread_mutex_unlock( &h->mux_smoothing_queue.mutex ); pthread_join( h->mux_smoothing_thread, &ret_ptr ); fprintf( stderr, "mux smoothing cancelled \n" ); /* Cancel output_thread */ pthread_mutex_lock( &h->output_queue.mutex ); h->cancel_output_thread = 1; pthread_cond_signal( &h->output_queue.in_cv ); pthread_mutex_unlock( &h->output_queue.mutex ); pthread_join( h->output_thread, &ret_ptr ); /* could be blocking on OS so have to cancel thread too */ pthread_cancel( h->output_thread ); pthread_join( h->output_thread, &ret_ptr ); fprintf( stderr, "output thread cancelled \n" ); /* Destroy devices */ for( int i = 0; i < h->num_devices; i++ ) destroy_device( h->devices[i] ); fprintf( stderr, "devices destroyed \n" ); /* Destroy filters */ for( int i = 0; i < h->num_filters; i++ ) destroy_filter( h->filters[i] ); fprintf( stderr, "filters destroyed \n" ); /* Destroy encoders */ for( int i = 0; i < h->num_encoders; i++ ) destroy_encoder( h->encoders[i] ); fprintf( stderr, "encoders destroyed \n" ); // FIXME destroy smoothing thread /* Destroy mux */ destroy_mux( h ); fprintf( stderr, "mux destroyed \n" ); /* Destroy output */ destroy_output( h ); fprintf( stderr, "output destroyed \n" ); free( h->output_streams ); /* TODO: free other things */ free( h ); h = NULL; }