int result = mlt_frame_get_image( nested_frame, image, format, width, height, writable );
// Allocate the image
- int size = *width * *height * ( *format == mlt_image_yuv422 ? 2 : *format == mlt_image_rgb24 ? 3 : *format == mlt_image_rgb24a ? 4 : ( 3 / 2 ) );
+ int size = *width * *height * ( *format == mlt_image_yuv422 ? 2 : *format == mlt_image_rgb24 ? 3 :
+ ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ) ? 4 : ( 3 / 2 ) );
uint8_t *new_image = mlt_pool_alloc( size );
// Update the frame
mlt_properties properties = mlt_frame_properties( frame );
mlt_properties_set_data( properties, "image", new_image, size, mlt_pool_release, NULL );
memcpy( new_image, *image, size );
- mlt_frame_close( nested_frame );
+ mlt_properties_set( properties, "progressive", mlt_properties_get( MLT_FRAME_PROPERTIES(nested_frame), "progressive" ) );
*image = new_image;
-// mlt_properties_debug( properties, "frame", stderr );
-// mlt_properties_debug( mlt_frame_properties( nested_frame ), "nested_frame", stderr );
-
return result;
}
-static int get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+static int get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
{
mlt_frame nested_frame = mlt_frame_pop_audio( frame );
int result = mlt_frame_get_audio( nested_frame, buffer, format, frequency, channels, samples );
- int size = *channels * *samples * sizeof( int16_t );
+ int size = *channels * *samples;
+
+ switch ( *format )
+ {
+ case mlt_audio_s16:
+ size *= sizeof( int16_t );
+ break;
+ case mlt_audio_s32:
+ size *= sizeof( int32_t );
+ case mlt_audio_float:
+ size *= sizeof( float );
+ default:
+ mlt_log_error( NULL, "[producer consumer] Invalid audio format\n" );
+ }
int16_t *new_buffer = mlt_pool_alloc( size );
mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "audio", new_buffer, size, mlt_pool_release, NULL );
memcpy( new_buffer, *buffer, size );
*buffer = new_buffer;
- mlt_frame_close( nested_frame );
+
return result;
}
cx->profile->frame_rate_num = profile->frame_rate_num;
cx->profile->frame_rate_den = profile->frame_rate_den;
+ // Encapsulate a real producer for the resource
+ cx->producer = mlt_factory_producer( cx->profile, NULL,
+ mlt_properties_get( properties, "resource" ) );
+ mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( cx->producer ),
+ "out, length" );
+
+ // Since we control the seeking, prevent it from seeking on its own
+ mlt_producer_set_speed( cx->producer, 0 );
+
// We will encapsulate a consumer
cx->consumer = mlt_consumer_new( cx->profile );
// Do not use _pass_list on real_time so that it defaults to 0 in the absence of
mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( cx->consumer ), "real_time",
mlt_properties_get_int( properties, "real_time" ) );
mlt_properties_pass_list( MLT_CONSUMER_PROPERTIES( cx->consumer ), properties,
- "buffer, prefill" );
+ "buffer, prefill, deinterlace_method, rescale" );
- // Encapsulate a real producer for the resource
- cx->producer = mlt_factory_producer( cx->profile, mlt_environment( "MLT_PRODUCER" ),
- mlt_properties_get( properties, "resource" ) );
- mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( cx->producer ),
- "in, out, length, resource" );
-
- // Since we control the seeking, prevent it from seeking on its own
- mlt_producer_set_speed( cx->producer, 0 );
-
// Connect it all together
mlt_consumer_connect( cx->consumer, MLT_PRODUCER_SERVICE( cx->producer ) );
mlt_consumer_start( cx->consumer );
if ( frame )
{
// Our "in" needs to be the same, keep it so
- mlt_properties_pass_list( MLT_PRODUCER_PROPERTIES( cx->producer ), properties, "in" );
+ mlt_properties_pass_list( MLT_PRODUCER_PROPERTIES( cx->producer ), properties, "in, out" );
// Seek the producer to the correct place
// Calculate our positions
// Give the returned frame temporal identity
mlt_frame_set_position( *frame, mlt_producer_position( this ) );
- // Put additional references on the frame so both get_image and get_audio
- // methods can close it.
- mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( nested_frame ) );
+ // Store the nested frame on the produced frame for destruction
+ mlt_properties frame_props = MLT_FRAME_PROPERTIES( *frame );
+ mlt_properties_set_data( frame_props, "_producer_consumer.frame", nested_frame, 0, (mlt_destructor) mlt_frame_close, NULL );
// Inform the normalizers about our video properties
- mlt_properties frame_props = MLT_FRAME_PROPERTIES( *frame );
mlt_properties_set_double( frame_props, "aspect_ratio", mlt_profile_sar( cx->profile ) );
- mlt_properties_set_double( frame_props, "width", cx->profile->width );
- mlt_properties_set_double( frame_props, "height", cx->profile->height );
+ mlt_properties_set_int( frame_props, "width", cx->profile->width );
+ mlt_properties_set_int( frame_props, "height", cx->profile->height );
+ mlt_properties_set_int( frame_props, "real_width", cx->profile->width );
+ mlt_properties_set_int( frame_props, "real_height", cx->profile->height );
+ mlt_properties_set_int( frame_props, "progressive", cx->profile->progressive );
}
// Calculate the next timecode
mlt_producer this = mlt_producer_new( );
// Encapsulate the real producer
- mlt_producer real_producer = mlt_factory_producer( profile, mlt_environment( "MLT_PRODUCER" ), arg );
+ mlt_profile temp_profile = mlt_profile_init( NULL );
+ mlt_producer real_producer = mlt_factory_producer( temp_profile, NULL, arg );
if ( this && real_producer )
{
this = NULL;
}
+ mlt_profile_close( temp_profile );
return this;
}