[vlc-devel] [PATCH 2/2] [RFC] vlc_es: add a sub_chroma structure
Steve Lhomme
robux4 at videolabs.io
Sat Apr 16 10:57:44 CEST 2016
Tis is needed to compare chroma that rely on surfaces that may not all
be the same for the same VLC chroma integer.
---
include/vlc_es.h | 46 +++++++++++++++++++++++++++++++++++++++++
src/input/decoder.c | 2 +-
src/misc/es_format.c | 2 +-
src/misc/filter.c | 11 +++++++++-
src/video_output/display.c | 11 ++++++++--
src/video_output/video_output.c | 2 +-
6 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/include/vlc_es.h b/include/vlc_es.h
index cbd03e5..c15bc67 100644
--- a/include/vlc_es.h
+++ b/include/vlc_es.h
@@ -192,12 +192,16 @@ typedef enum video_transform_t
TRANSFORM_ANTI_TRANSPOSE = ORIENT_ANTI_TRANSPOSED
} video_transform_t;
+typedef struct sub_chroma sub_chroma;
+
/**
* video format description
*/
struct video_format_t
{
vlc_fourcc_t i_chroma; /**< picture chroma */
+ sub_chroma *p_sub_chroma; /**< data depending on the chroma */
+ size_t i_sub_chroma_size; /**< size of the sub chroma buffer */
unsigned int i_width; /**< picture width */
unsigned int i_height; /**< picture height */
@@ -233,6 +237,8 @@ static inline void video_format_Init( video_format_t *p_src, vlc_fourcc_t i_chro
p_src->i_chroma = i_chroma;
p_src->i_sar_num = p_src->i_sar_den = 1;
p_src->p_palette = NULL;
+ p_src->p_sub_chroma = NULL;
+ p_src->i_sub_chroma_size = 0;
}
/**
@@ -250,6 +256,17 @@ static inline int video_format_Copy( video_format_t *p_dst, const video_format_t
return VLC_ENOMEM;
memcpy( p_dst->p_palette, p_src->p_palette, sizeof( *p_dst->p_palette ) );
}
+ if ( p_src->i_sub_chroma_size && p_src->p_sub_chroma != NULL )
+ {
+ p_dst->p_sub_chroma = (sub_chroma *) malloc( p_src->i_sub_chroma_size );
+ if( !p_dst->p_sub_chroma )
+ {
+ free( p_dst->p_palette );
+ return VLC_ENOMEM;
+ }
+ memcpy( p_dst->p_sub_chroma, p_src->p_sub_chroma, p_src->i_sub_chroma_size );
+ p_dst->i_sub_chroma_size = p_src->i_sub_chroma_size;
+ }
return VLC_SUCCESS;
}
@@ -259,10 +276,39 @@ static inline int video_format_Copy( video_format_t *p_dst, const video_format_t
*/
static inline void video_format_Clean( video_format_t *p_src )
{
+ free( p_src->p_sub_chroma );
free( p_src->p_palette );
memset( p_src, 0, sizeof( video_format_t ) );
}
+static inline bool video_format_IsSimilarChroma( const video_format_t *f1, const video_format_t *f2 )
+{
+ return f1->i_chroma == f2->i_chroma && f1->i_sub_chroma_size == f2->i_sub_chroma_size &&
+ ( !f1->i_sub_chroma_size || !memcmp(f1->p_sub_chroma, f2->p_sub_chroma, f1->i_sub_chroma_size));
+}
+
+static inline int video_format_SetChroma( video_format_t *p_fmt, vlc_fourcc_t i_chroma,
+ const sub_chroma *p_sub_chroma, size_t i_sub_chroma_size )
+{
+ if ( p_fmt->i_chroma == i_chroma &&
+ p_fmt->i_sub_chroma_size == i_sub_chroma_size &&
+ ( !i_sub_chroma_size || !memcmp(p_fmt->p_sub_chroma, p_sub_chroma, i_sub_chroma_size)) )
+ return VLC_SUCCESS;
+ sub_chroma *p_schroma = NULL;
+ if ( i_sub_chroma_size != 0 )
+ {
+ p_schroma = (sub_chroma *)malloc( i_sub_chroma_size );
+ if ( unlikely( p_schroma == NULL ) )
+ return VLC_ENOMEM;
+ memcpy( p_schroma, p_sub_chroma, i_sub_chroma_size );
+ }
+ free( p_fmt->p_sub_chroma );
+ p_fmt->p_sub_chroma = p_schroma;
+ p_fmt->i_sub_chroma_size = i_sub_chroma_size;
+ p_fmt->i_chroma = i_chroma;
+ return VLC_SUCCESS;
+}
+
/**
* It will fill up a video_format_t using the given arguments.
* Note that the video_format_t must already be initialized.
diff --git a/src/input/decoder.c b/src/input/decoder.c
index a1d7414..f9b0c53 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -325,7 +325,7 @@ static int vout_update_format( decoder_t *p_dec )
|| p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
|| p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
|| p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset
- || p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma
+ || !video_format_IsSimilarChroma( &p_dec->fmt_out.video, &p_owner->fmt.video )
|| (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
(int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num ||
p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation )
diff --git a/src/misc/es_format.c b/src/misc/es_format.c
index 0375767..7c8b0d6 100644
--- a/src/misc/es_format.c
+++ b/src/misc/es_format.c
@@ -381,7 +381,7 @@ void video_format_ApplyRotation( video_format_t *restrict out,
bool video_format_IsSimilar( const video_format_t *f1,
const video_format_t *f2 )
{
- if( f1->i_chroma != f2->i_chroma )
+ if( !video_format_IsSimilarChroma( f1, f2 ) )
return false;
if( f1->i_width != f2->i_width || f1->i_height != f2->i_height ||
diff --git a/src/misc/filter.c b/src/misc/filter.c
index 36f1ba4..24b4f95 100644
--- a/src/misc/filter.c
+++ b/src/misc/filter.c
@@ -43,6 +43,15 @@ filter_t *filter_NewBlend( vlc_object_t *p_this,
p_blend->fmt_out.i_codec =
p_blend->fmt_out.video.i_chroma = p_dst_chroma->i_chroma;
+ if ( p_dst_chroma->i_sub_chroma_size != 0 )
+ {
+ p_blend->fmt_out.video.p_sub_chroma = malloc( p_dst_chroma->i_sub_chroma_size );
+ if ( p_blend->fmt_out.video.p_sub_chroma == NULL )
+ vlc_object_release( p_blend );
+ memcpy( p_blend->fmt_out.video.p_sub_chroma, p_dst_chroma->p_sub_chroma,
+ p_dst_chroma->i_sub_chroma_size );
+ }
+
p_blend->fmt_out.video.i_rmask = p_dst_chroma->i_rmask;
p_blend->fmt_out.video.i_gmask = p_dst_chroma->i_gmask;
p_blend->fmt_out.video.i_bmask = p_dst_chroma->i_bmask;
@@ -66,7 +75,7 @@ int filter_ConfigureBlend( filter_t *p_blend,
{
/* */
if( p_blend->p_module &&
- p_blend->fmt_in.video.i_chroma != p_src->i_chroma )
+ !video_format_IsSimilarChroma( &p_blend->fmt_in.video, p_src ) )
{
/* The chroma is not the same, we need to reload the blend module */
module_unneed( p_blend, p_blend->p_module );
diff --git a/src/video_output/display.c b/src/video_output/display.c
index ecf661a..1a8df71 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -55,7 +55,7 @@ static picture_t *VideoBufferNew(filter_t *filter)
vout_display_t *vd = filter->owner.sys;
const video_format_t *fmt = &filter->fmt_out.video;
- assert(vd->fmt.i_chroma == fmt->i_chroma &&
+ assert(video_format_IsSimilarChroma( &vd->fmt, fmt) &&
vd->fmt.i_width == fmt->i_width &&
vd->fmt.i_height == fmt->i_height);
@@ -432,10 +432,17 @@ static int VoutDisplayCreateRender(vout_display_t *vd)
(v_src.i_chroma == VLC_CODEC_J440 && v_dst.i_chroma == VLC_CODEC_I440) ||
(v_src.i_chroma == VLC_CODEC_J444 && v_dst.i_chroma == VLC_CODEC_I444))
v_dst_cmp.i_chroma = v_src.i_chroma;
+ v_dst_cmp.p_sub_chroma = NULL; // for memcmp
+ v_src.p_sub_chroma = NULL; // for memcmp
- const bool convert = memcmp(&v_src, &v_dst_cmp, sizeof(v_src)) != 0;
+ const bool convert = memcmp(&v_src, &v_dst_cmp, sizeof(v_src)) != 0 ||
+ (vd->source.i_sub_chroma_size && memcmp( vd->source.p_sub_chroma,
+ vd->fmt.p_sub_chroma,
+ vd->source.i_sub_chroma_size ) != 0 );
if (!convert)
return 0;
+ v_src.p_sub_chroma = vd->source.p_sub_chroma;
+ v_dst_cmp.p_sub_chroma = vd->fmt.p_sub_chroma;
msg_Dbg(vd, "A filter to adapt decoder %4.4s to display %4.4s is needed",
(const char *)&v_src.i_chroma, (const char *)&v_dst.i_chroma);
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 7994bec..48c88c8 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -893,7 +893,7 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
subpicture_chromas = NULL;
if (vout->p->spu_blend &&
- vout->p->spu_blend->fmt_out.video.i_chroma != fmt_spu.i_chroma) {
+ !video_format_IsSimilarChroma( &vout->p->spu_blend->fmt_out.video, &fmt_spu )) {
filter_DeleteBlend(vout->p->spu_blend);
vout->p->spu_blend = NULL;
vout->p->spu_blend_chroma = 0;
--
2.7.0.windows.1
More information about the vlc-devel
mailing list