X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fframework%2Fmlt_frame.c;h=da7bb8e04a8a81af6c5f18f55b52170357e3923b;hb=3f84fe14c06956b5092c257fd27da490565566e5;hp=7b431df7bcd2bb09930eba5ddb1448039ec550a8;hpb=96c605eaac7272e3b37a0df718f9196fd5acbe96;p=mlt diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 7b431df7..da7bb8e0 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -3,8 +3,9 @@ * \brief interface for all frame classes * \see mlt_frame_s * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited + * Copyright (C) 2003-2013 Ushodaya Enterprises Limited * \author Charles Yates + * \author Dan Dennedy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -183,7 +184,7 @@ int mlt_frame_set_position( mlt_frame self, mlt_position value ) * * \public \memberof mlt_frame_s * \param self a frame - * \param the get_image callback + * \param get_image the get_image callback * \return true if error */ @@ -436,6 +437,10 @@ int mlt_image_format_size( mlt_image_format format, int width, int height, int * case mlt_image_yuv420p: if ( bpp ) *bpp = 3 / 2; return width * height * 3 / 2; + case mlt_image_glsl: + case mlt_image_glsl_texture: + if ( bpp ) *bpp = 0; + return 4; default: if ( bpp ) *bpp = 0; return 0; @@ -443,90 +448,39 @@ int mlt_image_format_size( mlt_image_format format, int width, int height, int * return 0; } -/** Get the image associated to the frame. - * - * You should express the desired format, width, and height as inputs. As long - * as the loader producer was used to generate this or the imageconvert filter - * was attached, then you will get the image back in the format you desire. - * However, you do not always get the width and height you request depending - * on properties and filters. You do not need to supply a pre-allocated - * buffer, but you should always supply the desired image format. - * - * \public \memberof mlt_frame_s - * \param self a frame - * \param[out] buffer an image buffer - * \param[in,out] format the image format - * \param[in,out] width the horizontal size in pixels - * \param[in,out] height the vertical size in pixels - * \param writable whether or not you will need to be able to write to the memory returned in \p buffer - * \return true if error - * \todo Better describe the width and height as inputs. - */ - -int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) +static int generate_test_image( mlt_properties properties, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) { - mlt_properties properties = MLT_FRAME_PROPERTIES( self ); - mlt_get_image get_image = mlt_frame_pop_get_image( self ); mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL ); mlt_image_format requested_format = *format; - int error = 0; + int error = 1; - if ( get_image ) - { - mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 ); - error = get_image( self, buffer, format, width, height, writable ); - if ( !error && *buffer ) - { - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - if ( self->convert_image && *buffer && requested_format != mlt_image_none ) - self->convert_image( self, buffer, format, requested_format ); - mlt_properties_set_int( properties, "format", *format ); - } - else - { - // Cause the image to be loaded from test card or fallback (white) below. - mlt_frame_get_image( self, buffer, format, width, height, writable ); - } - } - else if ( mlt_properties_get_data( properties, "image", NULL ) ) - { - *format = mlt_properties_get_int( properties, "format" ); - *buffer = mlt_properties_get_data( properties, "image", NULL ); - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - if ( self->convert_image && *buffer && requested_format != mlt_image_none ) - { - self->convert_image( self, buffer, format, requested_format ); - mlt_properties_set_int( properties, "format", *format ); - } - } - else if ( producer ) + if ( producer ) { mlt_frame test_frame = NULL; mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &test_frame, 0 ); if ( test_frame ) { mlt_properties test_properties = MLT_FRAME_PROPERTIES( test_frame ); - mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); - mlt_frame_get_image( test_frame, buffer, format, width, height, writable ); mlt_properties_set_data( properties, "test_card_frame", test_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( test_frame ) ); -// mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL ); -// mlt_properties_set_int( properties, "width", *width ); -// mlt_properties_set_int( properties, "height", *height ); -// mlt_properties_set_int( properties, "format", *format ); + mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); + error = mlt_frame_get_image( test_frame, buffer, format, width, height, writable ); + if ( !error && buffer && *buffer ) + { + mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( test_frame ) ); + mlt_properties_set_int( properties, "width", *width ); + mlt_properties_set_int( properties, "height", *height ); + if ( test_frame->convert_image && requested_format != mlt_image_none ) + test_frame->convert_image( test_frame, buffer, format, requested_format ); + mlt_properties_set_int( properties, "format", *format ); + } } else { mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); - mlt_frame_get_image( self, buffer, format, width, height, writable ); } } - else + if ( error && buffer && *format != mlt_image_none ) { - register uint8_t *p; - register uint8_t *q; int size = 0; *width = *width == 0 ? 720 : *width; @@ -536,7 +490,7 @@ int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *for mlt_properties_set_int( properties, "format", *format ); mlt_properties_set_int( properties, "width", *width ); mlt_properties_set_int( properties, "height", *height ); - mlt_properties_set_int( properties, "aspect_ratio", 0 ); + mlt_properties_set_double( properties, "aspect_ratio", 1.0 ); switch( *format ) { @@ -555,32 +509,103 @@ int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *for if ( *buffer ) memset( *buffer, 255, size ); break; + case mlt_image_glsl: + case mlt_image_glsl_texture: + *format = mlt_image_yuv422; case mlt_image_yuv422: size *= 2; size += *width * 2; *buffer = mlt_pool_alloc( size ); - p = *buffer; - q = p + size; - while ( p != NULL && p != q ) + if ( *buffer ) { - *p ++ = 235; - *p ++ = 128; + register uint8_t *p = *buffer; + register uint8_t *q = p + size; + while ( p != NULL && p != q ) + { + *p ++ = 235; + *p ++ = 128; + } } break; case mlt_image_yuv420p: - size = size * 3 / 2; - *buffer = mlt_pool_alloc( size ); + *buffer = mlt_pool_alloc( size * 3 / 2 ); if ( *buffer ) - memset( *buffer, 255, size ); + { + memset( *buffer, 235, size ); + memset( *buffer + size, 128, size / 2 ); + } break; default: size = 0; - *buffer = NULL; break; } - mlt_properties_set_data( properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); mlt_properties_set_int( properties, "test_image", 1 ); + error = 0; + } + return error; +} + + +/** Get the image associated to the frame. + * + * You should express the desired format, width, and height as inputs. As long + * as the loader producer was used to generate this or the imageconvert filter + * was attached, then you will get the image back in the format you desire. + * However, you do not always get the width and height you request depending + * on properties and filters. You do not need to supply a pre-allocated + * buffer, but you should always supply the desired image format. + * + * \public \memberof mlt_frame_s + * \param self a frame + * \param[out] buffer an image buffer + * \param[in,out] format the image format + * \param[in,out] width the horizontal size in pixels + * \param[in,out] height the vertical size in pixels + * \param writable whether or not you will need to be able to write to the memory returned in \p buffer + * \return true if error + * \todo Better describe the width and height as inputs. + */ + +int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) +{ + mlt_properties properties = MLT_FRAME_PROPERTIES( self ); + mlt_get_image get_image = mlt_frame_pop_get_image( self ); + mlt_image_format requested_format = *format; + int error = 0; + + if ( get_image ) + { + mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 ); + error = get_image( self, buffer, format, width, height, writable ); + if ( !error && buffer && *buffer ) + { + mlt_properties_set_int( properties, "width", *width ); + mlt_properties_set_int( properties, "height", *height ); + if ( self->convert_image && requested_format != mlt_image_none ) + self->convert_image( self, buffer, format, requested_format ); + mlt_properties_set_int( properties, "format", *format ); + } + else + { + error = generate_test_image( properties, buffer, format, width, height, writable ); + } + } + else if ( mlt_properties_get_data( properties, "image", NULL ) && buffer ) + { + *format = mlt_properties_get_int( properties, "format" ); + *buffer = mlt_properties_get_data( properties, "image", NULL ); + *width = mlt_properties_get_int( properties, "width" ); + *height = mlt_properties_get_int( properties, "height" ); + if ( self->convert_image && *buffer && requested_format != mlt_image_none ) + { + self->convert_image( self, buffer, format, requested_format ); + mlt_properties_set_int( properties, "format", *format ); + } + } + else + { + error = generate_test_image( properties, buffer, format, width, height, writable ); } return error; @@ -719,26 +744,11 @@ int mlt_frame_get_audio( mlt_frame self, void **buffer, mlt_audio_format *format mlt_properties_set_int( properties, "audio_samples", *samples ); mlt_properties_set_int( properties, "audio_format", *format ); - switch( *format ) - { - case mlt_image_none: - size = 0; - *buffer = NULL; - break; - case mlt_audio_s16: - size = *samples * *channels * sizeof( int16_t ); - break; - case mlt_audio_s32: - size = *samples * *channels * sizeof( int32_t ); - break; - case mlt_audio_float: - size = *samples * *channels * sizeof( float ); - break; - default: - break; - } + size = mlt_audio_format_size( *format, *samples, *channels ); if ( size ) *buffer = mlt_pool_alloc( size ); + else + *buffer = NULL; if ( *buffer ) memset( *buffer, 0, size ); mlt_properties_set_data( properties, "audio", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); @@ -965,7 +975,7 @@ void mlt_frame_write_ppm( mlt_frame frame ) FILE *file; char filename[16]; - sprintf( filename, "frame-%05d.ppm", mlt_frame_get_position( frame ) ); + sprintf( filename, "frame-%05d.ppm", (int)mlt_frame_get_position( frame ) ); file = fopen( filename, "wb" ); if ( !file ) return; @@ -1052,10 +1062,12 @@ mlt_frame mlt_frame_clone( mlt_frame self, int is_deep ) data = mlt_properties_get_data( properties, "image", &size ); if ( data ) { + int width = mlt_properties_get_int( properties, "width" ); + int height = mlt_properties_get_int( properties, "height" ); + if ( ! size ) size = mlt_image_format_size( mlt_properties_get_int( properties, "format" ), - mlt_properties_get_int( properties, "width" ), - mlt_properties_get_int( properties, "height" ), NULL ); + width, height, NULL ); copy = mlt_pool_alloc( size ); memcpy( copy, data, size ); mlt_properties_set_data( new_props, "image", copy, size, mlt_pool_release, NULL ); @@ -1064,8 +1076,7 @@ mlt_frame mlt_frame_clone( mlt_frame self, int is_deep ) if ( data ) { if ( ! size ) - size = mlt_properties_get_int( properties, "width" ) * - mlt_properties_get_int( properties, "height" ); + size = width * height; copy = mlt_pool_alloc( size ); memcpy( copy, data, size ); mlt_properties_set_data( new_props, "alpha", copy, size, mlt_pool_release, NULL );