X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=mlt%2Fsrc%2Fmodules%2Fcore%2Fproducer_ppm.c;h=ca1947172c319fbb86e4ab144ecf32c2bdff5029;hb=092636b85449e57fd33ffd4954a2de23c2a5f81c;hp=e1357c8fb34374a0c18740c172de0800908abe91;hpb=885cb897cfb90465e61c39c1c266891b7e499055;p=melted diff --git a/mlt/src/modules/core/producer_ppm.c b/mlt/src/modules/core/producer_ppm.c index e1357c8..ca19471 100644 --- a/mlt/src/modules/core/producer_ppm.c +++ b/mlt/src/modules/core/producer_ppm.c @@ -36,13 +36,9 @@ mlt_producer producer_ppm_init( void *command ) producer->get_frame = producer_get_frame; producer->close = producer_close; - if ( command == NULL ) - this->command = strdup( "image2raw -n -a -r 3 -ppm /usr/share/pixmaps/*.png" ); - else + if ( command != NULL ) this->command = strdup( command ); - this->pipe = popen( this->command, "r" ); - return producer; } free( this ); @@ -77,6 +73,84 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma return 0; } +static void producer_ppm_position( producer_ppm this, uint64_t requested ) +{ + if ( requested != this->expected ) + { + if ( this->video != NULL ) + pclose( this->video ); + this->video = NULL; + if ( this->audio != NULL ) + pclose( this->audio ); + this->audio = NULL; + } + + // This is the next frame we expect + this->expected = mlt_producer_frame( &this->parent ) + 1; +} + +FILE *producer_ppm_run_video( producer_ppm this ) +{ + if ( this->video == NULL ) + { + if ( this->command == NULL ) + { + this->video = popen( "image2raw -n -a -r 3 -ppm /usr/share/pixmaps/*.png", "r" ); + } + else + { + char command[ 1024 ]; + float fps = mlt_producer_get_fps( &this->parent ); + float position = mlt_producer_position( &this->parent ); + sprintf( command, "ffmpeg -i \"%s\" -ss %f -f imagepipe -r %f -img ppm -", this->command, position, fps ); + this->video = popen( command, "r" ); + } + } + return this->video; +} + +FILE *producer_ppm_run_audio( producer_ppm this ) +{ + if ( this->audio == NULL ) + { + if ( this->command != NULL ) + { + char command[ 1024 ]; + float position = mlt_producer_position( &this->parent ); + sprintf( command, "ffmpeg -i \"%s\" -ss %f -f s16le -ar 48000 -ac 2 -", this->command, position ); + this->audio = popen( command, "r" ); + } + } + return this->audio; +} + + +static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) +{ + // Get the frames properties + mlt_properties properties = mlt_frame_properties( this ); + + FILE *pipe = mlt_properties_get_data( properties, "audio.pipe", NULL ); + + *frequency = 48000; + *channels = 2; + *samples = 1920; + + // Size + int size = *samples * *channels * 2; + + // Allocate an image + *buffer = malloc( size ); + + // Read it + fread( *buffer, size, 1, pipe ); + + // Pass the data on the frame properties + mlt_properties_set_data( properties, "audio", *buffer, size, free, NULL ); + + return 0; +} + static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) { producer_ppm this = producer->child; @@ -86,17 +160,26 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Construct a test frame *frame = mlt_frame_init( ); - // Scan the header - if ( fscanf( this->pipe, "P6\n%d %d\n255\n", &width, &height ) == 2 ) - { - // Get the frames properties - mlt_properties properties = mlt_frame_properties( *frame ); + // Are we at the position expected? + producer_ppm_position( this, mlt_producer_frame( producer ) ); + + // Open the pipe + FILE *video = producer_ppm_run_video( this ); + + // Open the audio pipe + FILE *audio = producer_ppm_run_audio( this ); + + // Get the frames properties + mlt_properties properties = mlt_frame_properties( *frame ); + // Read the video + if ( video != NULL && fscanf( video, "P6\n%d %d\n255\n", &width, &height ) == 2 ) + { // Allocate an image uint8_t *image = malloc( width * height * 3 ); // Read it - fread( image, width * height * 3, 1, this->pipe ); + fread( image, width * height * 3, 1, video ); // Pass the data on the frame properties mlt_properties_set_data( properties, "image", image, width * height * 3, free, NULL ); @@ -107,6 +190,16 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i mlt_frame_push_get_image( *frame, producer_get_image ); } + // Read the audio + if ( audio != NULL ) + { + // Set the audio pipe + mlt_properties_set_data( properties, "audio.pipe", audio, 0, NULL, NULL ); + + // Hmm - register audio callback + ( *frame )->get_audio = producer_get_audio; + } + // Update timecode on the frame we're creating mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) ); @@ -119,7 +212,10 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i static void producer_close( mlt_producer parent ) { producer_ppm this = parent->child; - pclose( this->pipe ); + if ( this->video ) + pclose( this->video ); + if ( this->audio ) + pclose( this->audio ); free( this->command ); parent->close = NULL; mlt_producer_close( parent );