From 98a73f61a9b95c346df3b7f6991eec4f88e132d5 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Fri, 6 Oct 2023 10:56:55 +0200 Subject: [PATCH] image: separate the encoding codec from the output video format The output is a bitstream in some codec, not a chroma that can be used as such. The codec value should not be set as a chroma in the video_format_t. The output video format is only used to force some dimensions on the output that may not be the ones from the source. --- include/vlc_image.h | 10 ++++++---- include/vlc_picture.h | 4 ++-- lib/picture.c | 2 +- modules/video_filter/scene.c | 4 ++-- src/misc/image.c | 29 +++++++++++++++++------------ src/misc/picture.c | 5 ++--- test/src/misc/image.c | 6 +++--- test/src/misc/image_cvpx.c | 4 ++-- 8 files changed, 35 insertions(+), 29 deletions(-) diff --git a/include/vlc_image.h b/include/vlc_image.h index 250974f368..d982a7b04b 100644 --- a/include/vlc_image.h +++ b/include/vlc_image.h @@ -43,9 +43,11 @@ struct image_handler_t picture_t * (*pf_read_url) ( image_handler_t *, const char *, video_format_t * ); block_t * (*pf_write) ( image_handler_t *, picture_t *, - const video_format_t *, const video_format_t * ); + const video_format_t *, + vlc_fourcc_t, const video_format_t * ); int (*pf_write_url) ( image_handler_t *, picture_t *, - const video_format_t *, const video_format_t *, + const video_format_t *, + vlc_fourcc_t, const video_format_t *, const char * ); picture_t * (*pf_convert) ( image_handler_t *, picture_t *, @@ -66,8 +68,8 @@ VLC_API void image_HandlerDelete( image_handler_t * ); #define image_Read( a, b, c, d ) a->pf_read( a, b, c, d ) #define image_ReadUrl( a, b, c ) a->pf_read_url( a, b, c ) -#define image_Write( a, b, c, d ) a->pf_write( a, b, c, d ) -#define image_WriteUrl( a, b, c, d, e ) a->pf_write_url( a, b, c, d, e ) +#define image_Write( a, b, c, d, e ) a->pf_write( a, b, c, d, e ) +#define image_WriteUrl( a, b, c, d, e, f ) a->pf_write_url( a, b, c, d, e, f ) #define image_Convert( a, b, c, d ) a->pf_convert( a, b, c, d ) VLC_API vlc_fourcc_t image_Type2Fourcc( const char *psz_name ); diff --git a/include/vlc_picture.h b/include/vlc_picture.h index 4f9a7deb22..54171e140f 100644 --- a/include/vlc_picture.h +++ b/include/vlc_picture.h @@ -461,7 +461,7 @@ picture_GetAncillary(const picture_t *pic, vlc_ancillary_id id); /** * This function will export a picture to an encoded bitstream. * - * pp_image will contain the encoded bitstream in psz_format format. + * pp_image will contain the encoded bitstream in i_codec codec. * * p_fmt can be NULL otherwise it will be set with the format used for the * picture before encoding. @@ -476,7 +476,7 @@ picture_GetAncillary(const picture_t *pic, vlc_ancillary_id id); * If at most one of them is > 0 then the picture aspect ratio will be kept. */ VLC_API int picture_Export( vlc_object_t *p_obj, block_t **pp_image, video_format_t *p_fmt, - picture_t *p_picture, vlc_fourcc_t i_format, int i_override_width, + picture_t *p_picture, vlc_fourcc_t i_codec, int i_override_width, int i_override_height, bool b_crop ); /** diff --git a/lib/picture.c b/lib/picture.c index adf803dbff..3d5e6280bb 100644 --- a/lib/picture.c +++ b/lib/picture.c @@ -126,7 +126,7 @@ static libvlc_picture_t* libvlc_picture_from_attachment( input_attachment_t* att vlc_atomic_rc_init( &pic->rc ); pic->attachment = vlc_input_attachment_Hold( attachment ); pic->time = VLC_TICK_INVALID; - video_format_Init( &pic->fmt, fcc ); + video_format_Init( &pic->fmt, 0 ); switch ( fcc ) { case VLC_CODEC_PNG: diff --git a/modules/video_filter/scene.c b/modules/video_filter/scene.c index 1819153b62..fcaccc057b 100644 --- a/modules/video_filter/scene.c +++ b/modules/video_filter/scene.c @@ -290,7 +290,7 @@ static void SavePicture( filter_t *p_filter, picture_t *p_pic ) char *psz_temp = NULL; int i_ret; - video_format_Init( &fmt_out, p_sys->i_format ); + video_format_Init( &fmt_out, 0 ); /* Save snapshot psz_format to a memory zone */ fmt_in = p_pic->format; @@ -325,7 +325,7 @@ static void SavePicture( filter_t *p_filter, picture_t *p_pic ) } /* Save the image */ - i_ret = image_WriteUrl( p_sys->p_image, p_pic, &fmt_in, &fmt_out, + i_ret = image_WriteUrl( p_sys->p_image, p_pic, &fmt_in, p_sys->i_format, &fmt_out, psz_temp ); if( i_ret != VLC_SUCCESS ) { diff --git a/src/misc/image.c b/src/misc/image.c index 3c18ec5ca9..b65e0148e9 100644 --- a/src/misc/image.c +++ b/src/misc/image.c @@ -66,16 +66,19 @@ static picture_t *ImageRead( image_handler_t *, block_t *, static picture_t *ImageReadUrl( image_handler_t *, const char *, video_format_t * ); static block_t *ImageWrite( image_handler_t *, picture_t *, - const video_format_t *, const video_format_t * ); + const video_format_t *, + vlc_fourcc_t, const video_format_t * ); static int ImageWriteUrl( image_handler_t *, picture_t *, - const video_format_t *, const video_format_t *, const char * ); + const video_format_t *, + vlc_fourcc_t, const video_format_t *, + const char * ); static picture_t *ImageConvert( image_handler_t *, picture_t *, const video_format_t *, video_format_t * ); static decoder_t *CreateDecoder( image_handler_t *, const es_format_t * ); static encoder_t *CreateEncoder( vlc_object_t *, const video_format_t *, - const video_format_t * ); + vlc_fourcc_t, const video_format_t * ); static filter_t *CreateConverter( vlc_object_t *, const es_format_t *, struct vlc_video_context *, const video_format_t * ); @@ -353,11 +356,11 @@ error: static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic, const video_format_t *p_fmt_in, - const video_format_t *p_fmt_out ) + vlc_fourcc_t codec, const video_format_t *p_fmt_out ) { /* Check if we can reuse the current encoder */ if( p_image->p_enc && - ( p_image->p_enc->fmt_out.i_codec != p_fmt_out->i_chroma || + ( p_image->p_enc->fmt_out.i_codec != codec || p_image->p_enc->fmt_out.video.i_width != p_fmt_out->i_width || p_image->p_enc->fmt_out.video.i_height != p_fmt_out->i_height ) ) { @@ -369,7 +372,7 @@ static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic, if( !p_image->p_enc ) { p_image->p_enc = CreateEncoder( p_image->p_parent, - p_fmt_in, p_fmt_out ); + p_fmt_in, codec, p_fmt_out ); if( !p_image->p_enc ) return NULL; } @@ -441,17 +444,18 @@ static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic, } static int ImageWriteUrl( image_handler_t *p_image, picture_t *p_pic, - const video_format_t *p_fmt_in, const video_format_t *p_fmt_out, + const video_format_t *p_fmt_in, + vlc_fourcc_t codec, const video_format_t *p_fmt_out, const char *psz_url ) { block_t *p_block; FILE *file; video_format_t fmt_out = *p_fmt_out; - if( !fmt_out.i_chroma ) + if( !codec ) { /* Try to guess format from file name */ - fmt_out.i_chroma = image_Ext2Fourcc( psz_url ); + codec = image_Ext2Fourcc( psz_url ); } file = vlc_fopen( psz_url, "wb" ); @@ -461,7 +465,7 @@ static int ImageWriteUrl( image_handler_t *p_image, picture_t *p_pic, return VLC_EGENERIC; } - p_block = ImageWrite( p_image, p_pic, p_fmt_in, &fmt_out ); + p_block = ImageWrite( p_image, p_pic, p_fmt_in, codec, &fmt_out ); int err = 0; if( p_block ) @@ -691,7 +695,7 @@ static decoder_t *CreateDecoder( image_handler_t *p_image, const es_format_t *fm static encoder_t *CreateEncoder( vlc_object_t *p_this, const video_format_t *fmt_in, - const video_format_t *fmt_out ) + vlc_fourcc_t codec, const video_format_t *fmt_out ) { encoder_t *p_enc; @@ -723,6 +727,8 @@ static encoder_t *CreateEncoder( vlc_object_t *p_this, const video_format_t *fmt p_enc->fmt_in.video.i_frame_rate_base = 1; es_format_InitFromVideo( &p_enc->fmt_out, fmt_out ); + p_enc->fmt_out.i_codec = codec; + p_enc->fmt_out.video.i_chroma = 0; p_enc->fmt_out.video.i_width = p_enc->fmt_in.video.i_width; p_enc->fmt_out.video.i_height = p_enc->fmt_in.video.i_height; p_enc->ops = NULL; @@ -739,7 +745,6 @@ static encoder_t *CreateEncoder( vlc_object_t *p_this, const video_format_t *fmt return NULL; } assert( p_enc->ops != NULL ); - p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec; return p_enc; } diff --git a/src/misc/picture.c b/src/misc/picture.c index a712ed22e9..bdb17a846a 100644 --- a/src/misc/picture.c +++ b/src/misc/picture.c @@ -518,7 +518,7 @@ int picture_Export( vlc_object_t *p_obj, block_t **pp_image, video_format_t *p_fmt, picture_t *p_picture, - vlc_fourcc_t i_format, + vlc_fourcc_t i_codec, int i_override_width, int i_override_height, bool b_crop ) { @@ -535,7 +535,6 @@ int picture_Export( vlc_object_t *p_obj, memset( &fmt_out, 0, sizeof(fmt_out) ); fmt_out.i_sar_num = fmt_out.i_sar_den = 1; - fmt_out.i_chroma = i_format; /* compute original width/height */ unsigned int i_width, i_height, i_original_width, i_original_height; @@ -610,7 +609,7 @@ int picture_Export( vlc_object_t *p_obj, return VLC_ENOMEM; vlc_tick_t date = p_picture->date; - block_t *p_block = image_Write( p_image, p_picture, &fmt_in, &fmt_out ); + block_t *p_block = image_Write( p_image, p_picture, &fmt_in, i_codec, &fmt_out ); image_HandlerDelete( p_image ); diff --git a/test/src/misc/image.c b/test/src/misc/image.c index 798f4dff00..69d5a80eb4 100644 --- a/test/src/misc/image.c +++ b/test/src/misc/image.c @@ -57,7 +57,7 @@ static int OpenIntf(vlc_object_t *root) fmt_in.i_height = fmt_in.i_visible_height = 600; video_format_t fmt_out; - video_format_Init(&fmt_out, VLC_CODEC_PNG); + video_format_Init(&fmt_out, 0); fmt_out.i_width = fmt_out.i_visible_width = 800; fmt_out.i_height = fmt_out.i_visible_height = 600; @@ -66,7 +66,7 @@ static int OpenIntf(vlc_object_t *root) block_t *block; - block = image_Write(ih, picture, &fmt_in, &fmt_out); + block = image_Write(ih, picture, &fmt_in, VLC_CODEC_PNG, &fmt_out); assert(block != NULL); block_Release(block); picture_Release(picture); @@ -76,7 +76,7 @@ static int OpenIntf(vlc_object_t *root) picture = picture_NewFromFormat(&fmt_in); fmt_out.i_width = fmt_out.i_visible_width = 400; fmt_out.i_height = fmt_out.i_visible_height = 300; - block = image_Write(ih, picture, &fmt_in, &fmt_out); + block = image_Write(ih, picture, &fmt_in, VLC_CODEC_PNG, &fmt_out); assert(block != NULL); block_Release(block); picture_Release(picture); diff --git a/test/src/misc/image_cvpx.c b/test/src/misc/image_cvpx.c index fee068d8a8..40d43cb7e3 100644 --- a/test/src/misc/image_cvpx.c +++ b/test/src/misc/image_cvpx.c @@ -74,13 +74,13 @@ static int OpenIntf(vlc_object_t *root) assert(ret == VLC_SUCCESS); video_format_t fmt_out; - video_format_Init(&fmt_out, VLC_CODEC_PNG); + video_format_Init(&fmt_out, 0); fmt_out.i_width = fmt_out.i_visible_width = 800; fmt_out.i_height = fmt_out.i_visible_height = 600; block_t *block; - block = image_Write(ih, picture, &fmt_in, &fmt_out); + block = image_Write(ih, picture, &fmt_in, VLC_CODEC_PNG, &fmt_out); assert(block != NULL); block_Release(block); image_HandlerDelete(ih);