@ -25,6 +25,9 @@
# include <ctype.h>
# include "framehook.h"
# include "avformat.h"
# include "swscale.h"
static int sws_flags = SWS_BICUBIC ;
/** Bi-directional pipe structure.
*/
@ -188,6 +191,12 @@ typedef struct
char * buf1 ;
int size2 ;
char * buf2 ;
// This vhook first converts frame to RGB ...
struct SwsContext * toRGB_convert_ctx ;
// ... then processes it via a PPM command pipe ...
// ... and finally converts back frame from RGB to initial format
struct SwsContext * fromRGB_convert_ctx ;
}
ContextInfo ;
@ -246,8 +255,24 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width,
if ( ! err )
{
avpicture_fill ( & picture1 , ci - > buf1 , PIX_FMT_RGB24 , width , height ) ;
if ( img_convert ( & picture1 , PIX_FMT_RGB24 , picture , pix_fmt , width , height ) < 0 )
err = 1 ;
// if we already got a SWS context, let's realloc if is not re-useable
ci - > toRGB_convert_ctx = sws_getCachedContext ( ci - > toRGB_convert_ctx ,
width , height , pix_fmt ,
width , height , PIX_FMT_RGB24 ,
sws_flags , NULL , NULL , NULL ) ;
if ( ci - > toRGB_convert_ctx = = NULL ) {
av_log ( NULL , AV_LOG_ERROR ,
" Cannot initialize the toRGB conversion context \n " ) ;
exit ( 1 ) ;
}
// img_convert parameters are 2 first destination, then 4 source
// sws_scale parameters are context, 4 first source, then 2 destination
sws_scale ( ci - > toRGB_convert_ctx ,
picture - > data , picture - > linesize , 0 , height ,
picture1 . data , picture1 . linesize ) ;
pict = & picture1 ;
}
}
@ -294,22 +319,28 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width,
/* Convert the returned PPM back to the input format */
if ( ! err )
{
/* Actually, this is wrong, since the out_width/out_height returned from the
* filter won ' t necessarily be the same as width and height - img_resample
* won ' t scale rgb24 , so the only way out of this is to convert to something
* that img_resample does like [ which may or may not be pix_fmt ] , rescale
* and finally convert to pix_fmt . . . slow , but would provide the most flexibility .
*
* Currently , we take the upper left width / height pixels from the filtered image ,
* smaller images are going to be corrupted or cause a crash .
*
* Finally , what should we do in case of this call failing ? Up to now , failures
* are gracefully ignored and the original image is returned - in this case , a
* failure may corrupt the input .
/* The out_width/out_height returned from the PPM
* filter won ' t necessarily be the same as width and height
* but it will be scaled anyway to width / height .
*/
if ( img_convert ( picture , pix_fmt , & picture2 , PIX_FMT_RGB24 , width , height ) < 0 )
{
av_log ( NULL , AV_LOG_DEBUG ,
" PPM vhook: Input dimensions: %d x %d Output dimensions: %d x %d \n " ,
width , height , out_width , out_height ) ;
ci - > fromRGB_convert_ctx = sws_getCachedContext ( ci - > fromRGB_convert_ctx ,
out_width , out_height , PIX_FMT_RGB24 ,
width , height , pix_fmt ,
sws_flags , NULL , NULL , NULL ) ;
if ( ci - > fromRGB_convert_ctx = = NULL ) {
av_log ( NULL , AV_LOG_ERROR ,
" Cannot initialize the fromRGB conversion context \n " ) ;
exit ( 1 ) ;
}
// img_convert parameters are 2 first destination, then 4 source
// sws_scale parameters are context, 4 first source, then 2 destination
sws_scale ( ci - > fromRGB_convert_ctx ,
picture2 . data , picture2 . linesize , 0 , out_height ,
picture - > data , picture - > linesize ) ;
}
}
@ -326,6 +357,8 @@ void Release(void *ctx)
rwpipe_close ( ci - > rw ) ;
av_free ( ci - > buf1 ) ;
av_free ( ci - > buf2 ) ;
sws_freeContext ( ci - > toRGB_convert_ctx ) ;
sws_freeContext ( ci - > fromRGB_convert_ctx ) ;
av_free ( ctx ) ;
}
}