X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fdv%2Fproducer_libdv.c;h=30111dad2fc9e67a7612d1c7513623b64b36cddd;hb=1d3ab5568258841b1741b8c2fc88ce4e958e6fc6;hp=02bef1f39f25a7f150b5488570ec123a7a57e0bb;hpb=94dce1aea965163f8dcd2f97271f2652abb0e62d;p=melted diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c index 02bef1f..30111da 100644 --- a/src/modules/dv/producer_libdv.c +++ b/src/modules/dv/producer_libdv.c @@ -64,7 +64,7 @@ mlt_producer producer_libdv_init( char *filename ) // Create the dv_decoder this->dv_decoder = dv_decoder_new( FALSE, FALSE, FALSE ); - this->dv_decoder->quality = DV_QUALITY_BEST; + this->dv_decoder->quality = DV_QUALITY_COLOR | DV_QUALITY_AC_1; this->dv_decoder->audio->arg_audio_emphasis = 2; dv_set_audio_correction( this->dv_decoder, DV_AUDIO_CORRECT_AVERAGE ); @@ -112,8 +112,7 @@ static int producer_collect_info( producer_libdv this ) { int valid = 0; - void *release = NULL; - uint8_t *dv_data = mlt_pool_allocate( frame_size_625_50, &release ); + uint8_t *dv_data = mlt_pool_alloc( frame_size_625_50 ); if ( dv_data != NULL ) { @@ -154,10 +153,11 @@ static int producer_collect_info( producer_libdv this ) // Parse the header for meta info dv_parse_header( this->dv_decoder, dv_data ); - mlt_properties_set_double( properties, "aspect_ratio", dv_format_wide( this->dv_decoder ) ? 16.0/9.0 : 4.0/3.0 ); + mlt_properties_set_double( properties, "aspect_ratio", + dv_format_wide( this->dv_decoder ) ? ( this->is_pal ? 512.0/351.0 : 96.0/79.0 ) : ( this->is_pal ? 128.0/117.0 : 72.0/79.0 ) ); } - mlt_pool_release( release ); + mlt_pool_release( dv_data ); } return valid; @@ -188,12 +188,10 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma if ( *format == mlt_image_yuv422 ) { // Allocate an image - void *release = NULL; - uint8_t *image = mlt_pool_allocate( *width * ( *height + 1 ) * 2, &release ); + uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 2 ); // Pass to properties for clean up - mlt_properties_set_data( properties, "image_release", release, 0, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, NULL, NULL ); + mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); // Decode the image pitches[ 0 ] = *width * 2; @@ -206,12 +204,10 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma else if ( *format == mlt_image_rgb24 ) { // Allocate an image - void *release = NULL; - uint8_t *image = mlt_pool_allocate( *width * ( *height + 1 ) * 3, &release ); + uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 3 ); // Pass to properties for clean up - mlt_properties_set_data( properties, "image_release", release, 0, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 3, NULL, NULL ); + mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 3, ( mlt_destructor )mlt_pool_release, NULL ); // Decode the frame pitches[ 0 ] = 720 * 3; @@ -227,10 +223,8 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) { - void *release = NULL; int16_t *p; int i, j; - void *audio_release[ 4 ] = { NULL, NULL, NULL, NULL }; int16_t *audio_channels[ 4 ]; // Get the frames properties @@ -245,35 +239,43 @@ static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_forma // Parse the header for meta info dv_parse_header( decoder, dv_data ); - // Obtain required values - //fprintf( stderr, "libdv: frequency %d\n", decoder->audio->frequency ); - *frequency = decoder->audio->frequency; - *samples = decoder->audio->samples_this_frame; - *channels = decoder->audio->num_channels; - - // Create a temporary workspace - for ( i = 0; i < 4; i++ ) - audio_channels[ i ] = mlt_pool_allocate( DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ), &audio_release[ i ] ); - - // Create a workspace for the result - *buffer = mlt_pool_allocate( *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ), &release ); - - // Pass the allocated audio buffer as a property - mlt_properties_set_data( properties, "audio_release", release, 0, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "audio", *buffer, *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ), NULL, NULL ); - - // Decode the audio - dv_decode_full_audio( decoder, dv_data, audio_channels ); + // Check that we have audio + if ( decoder->audio->num_channels > 0 ) + { + // Obtain required values + *frequency = decoder->audio->frequency; + *samples = decoder->audio->samples_this_frame; + *channels = decoder->audio->num_channels; + + // Create a temporary workspace + for ( i = 0; i < 4; i++ ) + audio_channels[ i ] = mlt_pool_alloc( DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ) ); - // Interleave the audio - p = *buffer; - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - *p++ = audio_channels[ j ][ i ]; - - // Free the temporary work space - for ( i = 0; i < 4; i++ ) - mlt_pool_release( audio_release[ i ] ); + // Create a workspace for the result + *buffer = mlt_pool_alloc( *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ) ); + + // Pass the allocated audio buffer as a property + mlt_properties_set_data( properties, "audio", *buffer, *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ), ( mlt_destructor )mlt_pool_release, NULL ); + + // Decode the audio + dv_decode_full_audio( decoder, dv_data, audio_channels ); + + // Interleave the audio + p = *buffer; + for ( i = 0; i < *samples; i++ ) + for ( j = 0; j < *channels; j++ ) + *p++ = audio_channels[ j ][ i ]; + + // Free the temporary work space + for ( i = 0; i < 4; i++ ) + mlt_pool_release( audio_channels[ i ] ); + } + else + { + // No audio available on the frame, so get test audio (silence) + this->get_audio = NULL; + mlt_frame_get_audio( this, buffer, format, frequency, channels, samples ); + } return 0; } @@ -281,8 +283,7 @@ static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_forma static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) { producer_libdv this = producer->child; - void *release = NULL; - uint8_t *data = mlt_pool_allocate( frame_size_625_50, &release ); + uint8_t *data = mlt_pool_alloc( frame_size_625_50 ); // Obtain the current frame number uint64_t position = mlt_producer_frame( producer ); @@ -305,18 +306,29 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i mlt_properties_set_data( properties, "dv_decoder", this->dv_decoder, 0, NULL, NULL ); // Pass the dv data - mlt_properties_set_data( properties, "dv_data_release", release, 0, ( mlt_destructor )mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "dv_data", data, frame_size_625_50, NULL, NULL ); + mlt_properties_set_data( properties, "dv_data", data, frame_size_625_50, ( mlt_destructor )mlt_pool_release, NULL ); // Update other info on the frame mlt_properties_set_int( properties, "width", 720 ); mlt_properties_set_int( properties, "height", this->is_pal ? 576 : 480 ); mlt_properties_set_int( properties, "top_field_first", 0 ); + + char *quality = mlt_properties_get( mlt_producer_properties( producer ), "quality" ); + if ( quality != NULL ) + { + if ( strncmp( quality, "fast", 4 ) == 0 ) + this->dv_decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_DC ); + else if ( strncmp( quality, "best", 4 ) == 0 ) + this->dv_decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_2 ); + else + this->dv_decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_1 ); + } // Parse the header for meta info dv_parse_header( this->dv_decoder, data ); mlt_properties_set_int( properties, "progressive", dv_is_progressive( this->dv_decoder ) ); - mlt_properties_set_double( properties, "aspect_ratio", dv_format_wide( this->dv_decoder ) ? 16.0/9.0 : 4.0/3.0 ); + mlt_properties_set_double( properties, "aspect_ratio", + dv_format_wide( this->dv_decoder ) ? ( this->is_pal ? 512.0/351.0 : 96.0/79.0 ) : ( this->is_pal ? 128.0/117.0 : 72.0/79.0 ) ); // Hmm - register audio callback ( *frame )->get_audio = producer_get_audio; @@ -326,7 +338,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i } else { - mlt_pool_release( release ); + mlt_pool_release( data ); } // Update timecode on the frame we're creating @@ -357,4 +369,3 @@ static void producer_close( mlt_producer parent ) // Free the memory free( this ); } -