From d9abee217889ccc079bc8f5e0483b621f75f0de6 Mon Sep 17 00:00:00 2001 From: Thomas Guillem Date: Fri, 13 Jul 2018 14:50:15 +0200 Subject: [PATCH] es_out: add ES_OUT_SPU_SET_HIGHLIGHT This control allows demuxers to highlight a specific area of a SPU (already sent). This will replace the p_input highlight variables and the VLC_HIGHLIGHT_MUTEX. --- include/vlc_es_out.h | 3 ++ include/vlc_subpicture.h | 10 ++++++ src/input/decoder.c | 19 +++++++++++ src/input/decoder.h | 2 +- src/input/es_out.c | 9 ++++++ src/input/es_out_timeshift.c | 7 +++++ src/video_output/video_output.c | 8 +++++ src/video_output/vout_internal.h | 3 ++ src/video_output/vout_subpictures.c | 63 ++++++++++++------------------------- 9 files changed, 80 insertions(+), 44 deletions(-) diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h index cad9d0567f..627b1c5494 100644 --- a/include/vlc_es_out.h +++ b/include/vlc_es_out.h @@ -109,6 +109,9 @@ enum es_out_query_e ES_OUT_VOUT_FLUSH_OVERLAY, /* arg1= es_out_id_t* (video es), * arg2= int (channel id), res= can fail */ + ES_OUT_SPU_SET_HIGHLIGHT, /* arg1= es_out_id_t* (spu es), + arg2= const vlc_spu_highlight_t *, res=can fail */ + /* First value usable for private control */ ES_OUT_PRIVATE_START = 0x10000, }; diff --git a/include/vlc_subpicture.h b/include/vlc_subpicture.h index ee6752f443..f001df0894 100644 --- a/include/vlc_subpicture.h +++ b/include/vlc_subpicture.h @@ -46,6 +46,7 @@ * Video subtitle region spu core private */ typedef struct subpicture_region_private_t subpicture_region_private_t; +typedef struct vlc_spu_highlight_t vlc_spu_highlight_t; /** * Video subtitle region @@ -77,6 +78,15 @@ struct subpicture_region_t subpicture_region_private_t *p_private; /**< Private data for spu_t *only* */ }; +struct vlc_spu_highlight_t +{ + int x_start; + int x_end; + int y_start; + int y_end; + video_palette_t palette; +}; + /* Subpicture region position flags */ #define SUBPICTURE_ALIGN_LEFT 0x1 #define SUBPICTURE_ALIGN_RIGHT 0x2 diff --git a/src/input/decoder.c b/src/input/decoder.c index 4d9d42d36c..2e0231a9fd 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -2523,3 +2523,22 @@ int input_DecoderFlushVoutOverlay( decoder_t *dec, int channel ) vlc_mutex_unlock( &owner->lock ); return VLC_SUCCESS; } + +int input_DecoderSetSpuHighlight( decoder_t *dec, + const vlc_spu_highlight_t *spu_hl ) +{ + struct decoder_owner *p_owner = dec_get_owner( dec ); + assert( dec->fmt_out.i_cat == SPU_ES ); + + vlc_mutex_lock( &p_owner->lock ); + if( !p_owner->p_vout ) + { + vlc_mutex_unlock( &p_owner->lock ); + return VLC_EGENERIC; + } + + vout_SetSpuHighlight( p_owner->p_vout, spu_hl ); + + vlc_mutex_unlock( &p_owner->lock ); + return VLC_SUCCESS; +} diff --git a/src/input/decoder.h b/src/input/decoder.h index 2da6eb78a2..67d29cdc3a 100644 --- a/src/input/decoder.h +++ b/src/input/decoder.h @@ -118,8 +118,8 @@ size_t input_DecoderGetFifoSize( decoder_t *p_dec ); void input_DecoderGetObjects( decoder_t *, vout_thread_t **, audio_output_t ** ); void input_DecoderSetVoutMouseEvent( decoder_t *, vlc_mouse_event, void * ); - int input_DecoderAddVoutOverlay( decoder_t *, subpicture_t *, int * ); int input_DecoderFlushVoutOverlay( decoder_t *, int ); +int input_DecoderSetSpuHighlight( decoder_t *, const vlc_spu_highlight_t * ); #endif diff --git a/src/input/es_out.c b/src/input/es_out.c index cc1ddb53c2..74a176bf97 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -2958,6 +2958,15 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return input_DecoderFlushVoutOverlay( p_es->p_dec, channel ); return VLC_EGENERIC; } + case ES_OUT_SPU_SET_HIGHLIGHT: + { + es_out_id_t *p_es = va_arg( args, es_out_id_t * ); + const vlc_spu_highlight_t *spu_hl = + va_arg( args, const vlc_spu_highlight_t * ); + if( p_es && p_es->fmt.i_cat == SPU_ES && p_es->p_dec ) + return input_DecoderSetSpuHighlight( p_es->p_dec, spu_hl ); + return VLC_EGENERIC; + } default: msg_Err( p_sys->p_input, "unknown query 0x%x in %s", i_query, diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c index 42d8584b2e..245abefb24 100644 --- a/src/input/es_out_timeshift.c +++ b/src/input/es_out_timeshift.c @@ -676,6 +676,13 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args ) return es_out_Control( p_sys->p_out, ES_OUT_VOUT_FLUSH_OVERLAY, p_es->p_es, channel ); } + case ES_OUT_SPU_SET_HIGHLIGHT: + { + es_out_id_t *p_es = (es_out_id_t*)va_arg( args, es_out_id_t * ); + const vlc_spu_highlight_t *p_hl = va_arg( args, const vlc_spu_highlight_t * ); + return es_out_Control( p_sys->p_out, ES_OUT_SPU_SET_HIGHLIGHT, + p_es->p_es, p_hl ); + } /* Special internal input control */ case ES_OUT_GET_EMPTY: { diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 43e55b163b..fca04e1227 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -398,6 +398,14 @@ void vout_FlushSubpictureChannel( vout_thread_t *vout, int channel ) vout_control_PushInteger(&vout->p->control, VOUT_CONTROL_FLUSH_SUBPICTURE, channel); } +void vout_SetSpuHighlight( vout_thread_t *vout, + const vlc_spu_highlight_t *spu_hl ) +{ + vlc_mutex_lock(&vout->p->spu_lock); + if (vout->p->spu) + spu_SetHighlight(vout->p->spu, spu_hl); + vlc_mutex_unlock(&vout->p->spu_lock); +} /** * Allocates a video output picture buffer. diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h index 155efdf189..1ff5dde454 100644 --- a/src/video_output/vout_internal.h +++ b/src/video_output/vout_internal.h @@ -223,6 +223,7 @@ void vout_ManageWrapper(vout_thread_t *); int spu_ProcessMouse(spu_t *, const vlc_mouse_t *, const video_format_t *); void spu_Attach( spu_t *, vlc_object_t *input, bool ); void spu_ChangeMargin(spu_t *, int); +void spu_SetHighlight(spu_t *, const vlc_spu_highlight_t*); /** * This function will (un)pause the display of pictures. @@ -278,4 +279,6 @@ void vout_DisplayTitle( vout_thread_t *p_vout, const char *psz_title ); */ bool vout_IsEmpty( vout_thread_t *p_vout ); +void vout_SetSpuHighlight( vout_thread_t *p_vout, const vlc_spu_highlight_t * ); + #endif diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c index e5bcc1555d..e56838c53d 100644 --- a/src/video_output/vout_subpictures.c +++ b/src/video_output/vout_subpictures.c @@ -80,8 +80,7 @@ struct spu_private_t { } crop; /**< cropping */ int margin; /**< force position of a subpicture */ - bool force_palette; /**< force palette of subpicture */ - uint8_t palette[4][4]; /**< forced palette */ + video_palette_t palette; /**< force palette of subpicture */ /* Subpiture filters */ char *source_chain_current; @@ -695,7 +694,7 @@ static void SpuRenderRegion(spu_t *spu, * instead of only the right one (being the dvd spu). */ const bool using_palette = region->fmt.i_chroma == VLC_CODEC_YUVP; - const bool force_palette = using_palette && sys->force_palette; + const bool force_palette = using_palette && sys->palette.i_entries > 0; const bool crop_requested = (force_palette && sys->force_crop) || region->i_max_width || region->i_max_height; bool changed_palette = false; @@ -754,7 +753,7 @@ static void SpuRenderRegion(spu_t *spu, for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) - new_palette.palette[i][j] = sys->palette[i][j]; + new_palette.palette[i][j] = sys->palette.palette[i][j]; b_opaque |= (new_palette.palette[i][3] > 0x00); } @@ -1141,55 +1140,35 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu, /***************************************************************************** * UpdateSPU: update subpicture settings - ***************************************************************************** - * This function is called from CropCallback and at initialization time, to - * retrieve crop information from the input. *****************************************************************************/ -static void UpdateSPU(spu_t *spu, vlc_object_t *object) +static void UpdateSPU(spu_t *spu, const vlc_spu_highlight_t *hl) { spu_private_t *sys = spu->p; - vlc_value_t val; vlc_mutex_lock(&sys->lock); - sys->force_palette = false; + sys->palette.i_entries = 0; sys->force_crop = false; - if (var_Get(object, "highlight", &val) || !val.b_bool) { + if (hl == NULL) { vlc_mutex_unlock(&sys->lock); return; } sys->force_crop = true; - sys->crop.x = var_GetInteger(object, "x-start"); - sys->crop.y = var_GetInteger(object, "y-start"); - sys->crop.width = var_GetInteger(object, "x-end") - sys->crop.x; - sys->crop.height = var_GetInteger(object, "y-end") - sys->crop.y; - - if (var_Get(object, "menu-palette", &val) == VLC_SUCCESS) { - memcpy(sys->palette, val.p_address, 16); - sys->force_palette = true; - } + sys->crop.x = hl->x_start; + sys->crop.y = hl->y_start; + sys->crop.width = hl->x_end - sys->crop.x; + sys->crop.height = hl->y_end - sys->crop.y; + + if (hl->palette.i_entries == 4) /* XXX: Only DVD palette for now */ + memcpy(&sys->palette, &hl->palette, sizeof(sys->palette)); vlc_mutex_unlock(&sys->lock); - msg_Dbg(object, "crop: %i,%i,%i,%i, palette forced: %i", + msg_Dbg(spu, "crop: %i,%i,%i,%i, palette forced: %i", sys->crop.x, sys->crop.y, sys->crop.width, sys->crop.height, - sys->force_palette); -} - -/***************************************************************************** - * CropCallback: called when the highlight properties are changed - ***************************************************************************** - * This callback is called from the input thread when we need cropping - *****************************************************************************/ -static int CropCallback(vlc_object_t *object, char const *var, - vlc_value_t oldval, vlc_value_t newval, void *data) -{ - VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(var); - - UpdateSPU((spu_t *)data, object); - return VLC_SUCCESS; + sys->palette.i_entries); } /***************************************************************************** @@ -1390,9 +1369,7 @@ void spu_Destroy(spu_t *spu) void spu_Attach(spu_t *spu, vlc_object_t *input, bool attach) { if (attach) { - UpdateSPU(spu, input); - var_Create(input, "highlight", VLC_VAR_BOOL); - var_AddCallback(input, "highlight", CropCallback, spu); + UpdateSPU(spu, NULL); vlc_mutex_lock(&spu->p->lock); spu->p->input = input; @@ -1406,10 +1383,6 @@ void spu_Attach(spu_t *spu, vlc_object_t *input, bool attach) vlc_mutex_lock(&spu->p->lock); spu->p->input = NULL; vlc_mutex_unlock(&spu->p->lock); - - /* Delete callbacks */ - var_DelCallback(input, "highlight", CropCallback, spu); - var_Destroy(input, "highlight"); } } @@ -1714,3 +1687,7 @@ void spu_ChangeMargin(spu_t *spu, int margin) vlc_mutex_unlock(&sys->lock); } +void spu_SetHighlight(spu_t *spu, const vlc_spu_highlight_t *hl) +{ + UpdateSPU(spu, hl); +} -- 2.11.4.GIT