X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Favformat%2Ffilter_swscale.c;h=d1266aeaeed5c97d5285d915ef685ce75855a3a0;hb=f4963a6aa07644399b273b5d2b1f9299c9047414;hp=4571acd66c693db953aafd0e579007f425ceffa4;hpb=27464f5e6d9efb356afd7dc294a11e7c1a009de8;p=melted diff --git a/src/modules/avformat/filter_swscale.c b/src/modules/avformat/filter_swscale.c index 4571acd..d1266ae 100644 --- a/src/modules/avformat/filter_swscale.c +++ b/src/modules/avformat/filter_swscale.c @@ -31,6 +31,12 @@ #include #include #include +#include + +#if LIBAVUTIL_VERSION_INT < (50<<16) +#define PIX_FMT_RGB32 PIX_FMT_RGBA32 +#define PIX_FMT_YUYV422 PIX_FMT_YUV422 +#endif static inline int is_big_endian( ) { @@ -50,10 +56,10 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format ) value = PIX_FMT_RGB24; break; case mlt_image_rgb24a: - value = PIX_FMT_RGBA32; + value = PIX_FMT_RGB32; break; case mlt_image_yuv422: - value = PIX_FMT_YUV422; + value = PIX_FMT_YUYV422; break; case mlt_image_yuv420p: value = PIX_FMT_YUV420P; @@ -96,29 +102,72 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform else if ( strcmp( interps, "spline" ) == 0 ) interp = SWS_SPLINE; + AVPicture input; + AVPicture output; + uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); + // Convert the pixel formats iformat = convert_mlt_to_av_cs( iformat ); oformat = convert_mlt_to_av_cs( oformat ); - // Create the context and output image - struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL); - AVPicture input; avpicture_fill( &input, *image, iformat, iwidth, iheight ); - AVPicture output; - uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); avpicture_fill( &output, outbuf, oformat, owidth, oheight ); + // Extract the alpha channel + if ( iformat == PIX_FMT_RGB32 && oformat == PIX_FMT_YUYV422 ) + { + // Allocate the alpha mask + uint8_t *alpha = mlt_pool_alloc( iwidth * ( iheight + 1 ) ); + if ( alpha ) + { + // Convert the image and extract alpha + mlt_convert_rgb24a_to_yuv422( *image, iwidth, iheight, iwidth * 4, outbuf, alpha ); + mlt_properties_set_data( properties, "alpha", alpha, iwidth * ( iheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); + iformat = PIX_FMT_YUYV422; + avpicture_fill( &input, outbuf, iformat, iwidth, iheight ); + avpicture_fill( &output, *image, oformat, owidth, oheight ); + } + } + + // Create the context and output image + struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL); + assert(context); + // Perform the scaling sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize); sws_freeContext( context ); // Now update the frame - mlt_properties_set_data( properties, "image", outbuf, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); + mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); mlt_properties_set_int( properties, "width", owidth ); mlt_properties_set_int( properties, "height", oheight ); // Return the output - *image = outbuf; + *image = output.data[0]; + + // Scale the alpha channel only if exists and not correct size + int alpha_size = 0; + mlt_properties_get_data( properties, "alpha", &alpha_size ); + if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) ) + { + // Create the context and output image + uint8_t *alpha = mlt_frame_get_alpha_mask( this ); + if ( alpha ) + { + iformat = oformat = PIX_FMT_GRAY8; + struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL); + avpicture_fill( &input, alpha, iformat, iwidth, iheight ); + outbuf = mlt_pool_alloc( owidth * oheight ); + avpicture_fill( &output, outbuf, oformat, owidth, oheight ); + + // Perform the scaling + sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize); + sws_freeContext( context ); + + // Set it back on the frame + mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output.data[0], owidth * oheight, mlt_pool_release, NULL ); + } + } return 0; }