X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fframework%2Fmlt_frame.c;h=53472dbfb6537ecdc839033ac9aa3f6e49d5a25b;hb=cab7cd53c3a4d9c4355751088fec61860dcabbce;hp=d8d3c8ae1bdd2ad7cfa5db841ffa5f0e83aba8a1;hpb=702e73b84d90830062ebe07ba01b72ad59d48d93;p=melted diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index d8d3c8a..53472db 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -92,12 +92,12 @@ int mlt_frame_is_test_card( mlt_frame this ) return mlt_deque_count( this->stack_image ) == 0 || mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "test_image" ); } -/** Check if we have a way to derive something than test audio. +/** Check if we have a way to derive something other than test audio. */ int mlt_frame_is_test_audio( mlt_frame this ) { - return this->get_audio == NULL || mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "test_audio" ); + return mlt_deque_count( this->stack_audio ) == 0 || mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "test_audio" ); } /** Get the aspect ratio of the frame. @@ -181,6 +181,22 @@ void *mlt_frame_pop_service( mlt_frame this ) return mlt_deque_pop_back( this->stack_image ); } +/** Push a service. +*/ + +int mlt_frame_push_service_int( mlt_frame this, int that ) +{ + return mlt_deque_push_back_int( this->stack_image, that ); +} + +/** Pop a service. +*/ + +int mlt_frame_pop_service_int( mlt_frame this ) +{ + return mlt_deque_pop_back_int( this->stack_image ); +} + /** Push an audio item on the stack. */ @@ -205,21 +221,56 @@ mlt_deque mlt_frame_service_stack( mlt_frame this ) return this->stack_service; } +/** [EXPERIMENTAL] Replace image stack with the information provided. + + This might prove to be unreliable and restrictive - the idea is that a transition + which normally uses two images may decide to only use the b frame (ie: in the case + of a composite where the b frame completely obscures the a frame). + + The image must be writable and the destructor for the image itself must be taken + care of on another frame and that frame cannot have a replace applied to it... + Further it assumes that no alpha mask is in use. + + For these reasons, it can only be used in a specific situation - when you have + multiple tracks each with their own transition and these transitions are applied + in a strictly reversed order (ie: highest numbered [lowest track] is processed + first). + + More reliable approach - the cases should be detected during the process phase + and the upper tracks should simply not be invited to stack... +*/ + +void mlt_frame_replace_image( mlt_frame this, uint8_t *image, mlt_image_format format, int width, int height ) +{ + // Herein lies the potential problem for this function - it makes a potentially + // dangerous assumption that all content on the image stack can be removed without a destructor + while( mlt_deque_pop_back( this->stack_image ) ) ; + + // Update the information + mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "image", image, 0, NULL, NULL ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "width", width ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "height", height ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "format", format ); + this->get_alpha_mask = NULL; +} + +/** Get the image associated to the frame. +*/ + int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) { mlt_properties properties = MLT_FRAME_PROPERTIES( this ); mlt_get_image get_image = mlt_frame_pop_get_image( this ); mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL ); + int error = 0; *width = *width >> 1 << 1; if ( get_image != NULL ) { - int error = 0; mlt_position position = mlt_frame_get_position( this ); error = get_image( this, buffer, format, width, height, writable ); mlt_frame_set_position( this, position ); - return error; } else if ( mlt_properties_get_data( properties, "image", NULL ) != NULL ) { @@ -308,7 +359,7 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for mlt_properties_set_int( properties, "test_image", 1 ); } - return 0; + return error; } uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ) @@ -320,13 +371,14 @@ uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ) int mlt_frame_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) { + mlt_get_audio get_audio = mlt_frame_pop_audio( this ); mlt_properties properties = MLT_FRAME_PROPERTIES( this ); int hide = mlt_properties_get_int( properties, "test_audio" ); - if ( hide == 0 && this->get_audio != NULL ) + if ( hide == 0 && get_audio != NULL ) { mlt_position position = mlt_frame_get_position( this ); - this->get_audio( this, buffer, format, frequency, channels, samples ); + get_audio( this, buffer, format, frequency, channels, samples ); mlt_frame_set_position( this, position ); } else if ( mlt_properties_get_data( properties, "audio", NULL ) ) @@ -681,7 +733,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input uint8_t *out_ptr = out_line; // Calculate a middle and possibly invalid pointer in the input - uint8_t *in_middle = input + istride * ( iheight / 2 ) + ( iwidth / 2 ) * 2; + uint8_t *in_middle = input + istride * ( iheight / 2 ) + iwidth; int in_line = - in_y_range * istride - in_x_range * 2; int elements; @@ -697,10 +749,18 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input } int active_width = 2 * iwidth; - int inactive_width = out_x_range - in_x_range; + int left_inactive_width = out_x_range - in_x_range; + int right_inactive_width = left_inactive_width; uint8_t *p = NULL; uint8_t *end = NULL; + if ( in_line % 4 ) + { + active_width -= 2; + in_middle += 2; + right_inactive_width += 2; + } + // Loop for the entirety of our output height. while ( iheight -- ) { @@ -708,7 +768,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input out_ptr = out_line; // Fill the outer part with black - elements = inactive_width; + elements = left_inactive_width; while ( elements -- ) { *out_ptr ++ = 16; @@ -725,7 +785,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input } // Fill the outer part with black - elements = inactive_width; + elements = right_inactive_width; while ( elements -- ) { *out_ptr ++ = 16;