#include <vlc_vout.h>
#include <vlc_block.h>
#include <vlc_filter.h>
-#include <vlc_osd.h>
+#include <vlc_spu.h>
#include "../libvlc.h"
#include "vout_internal.h"
#include <vlc_image.h>
static int MarginCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
-static int SpuControl( spu_t *, int, va_list );
-
-static void SpuClearChannel( spu_t *p_spu, int i_channel );
-
/* Buffer allocation for SPU filter (blend, scale, ...) */
static subpicture_t *spu_new_buffer( filter_t * );
static void spu_del_buffer( filter_t *, subpicture_t * );
static void spu_del_video_buffer( filter_t *, picture_t * );
/* Buffer aloccation fir SUB filter */
-static int SubFilterCallback( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
-
static int SubFilterAllocationInit( filter_t *, void * );
static void SubFilterAllocationClean( filter_t * );
vlc_object_attach( p_spu, p_this );
/* Initialize spu fields */
- p_spu->pf_control = SpuControl;
p_spu->p = p_sys = (spu_private_t*)&p_spu[1];
/* Initialize private fields */
return p_spu;
}
-/**
- * Initialise the subpicture unit
- *
- * \param p_spu the subpicture unit object
- */
-int spu_Init( spu_t *p_spu )
-{
- var_Create( p_spu, "sub-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
- var_AddCallback( p_spu, "sub-filter", SubFilterCallback, p_spu );
- var_TriggerCallback( p_spu, "sub-filter" );
-
- return VLC_SUCCESS;
-}
-
/**
* Destroy the subpicture unit
*
{
spu_private_t *p_sys = p_spu->p;
- var_DelCallback( p_spu, "sub-filter", SubFilterCallback, p_spu );
-
if( p_sys->p_blend )
filter_DeleteBlend( p_sys->p_blend );
* \param p_this the object in which to destroy the subpicture unit
* \param b_attach to select attach or detach
*/
-void spu_Attach( spu_t *p_spu, vlc_object_t *p_this, bool b_attach )
+void spu_Attach( spu_t *p_spu, vlc_object_t *p_input, bool b_attach )
{
- vlc_object_t *p_input;
-
- p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );
- if( !p_input )
- return;
-
if( b_attach )
{
UpdateSPU( p_spu, VLC_OBJECT(p_input) );
vlc_mutex_lock( &p_spu->p->lock );
p_spu->p->i_margin = var_GetInteger( p_input, "sub-margin" );
vlc_mutex_unlock( &p_spu->p->lock );
-
- vlc_object_release( p_input );
}
else
{
var_DelCallback( p_input, "sub-margin", MarginCallback, p_spu->p );
var_DelCallback( p_input, "highlight", CropCallback, p_spu );
var_Destroy( p_input, "highlight" );
- vlc_object_release( p_input );
}
}
{
spu_private_t *p_sys = p_spu->p;
- /* DEFAULT_CHAN always reset itself */
- if( p_subpic->i_channel == DEFAULT_CHAN )
- SpuClearChannel( p_spu, DEFAULT_CHAN );
+ /* SPU_DEFAULT_CHANNEL always reset itself */
+ if( p_subpic->i_channel == SPU_DEFAULT_CHANNEL )
+ spu_ClearChannel( p_spu, SPU_DEFAULT_CHANNEL );
/* p_private is for spu only and cannot be non NULL here */
for( subpicture_region_t *r = p_subpic->p_region; r != NULL; r = r->p_next )
vlc_mutex_unlock( &p_sys->lock );
}
+int spu_RegisterChannel( spu_t *p_spu )
+{
+ spu_private_t *p_sys = p_spu->p;
+
+ vlc_mutex_lock( &p_sys->lock );
+ int i_channel = p_sys->i_channel++;
+ vlc_mutex_unlock( &p_sys->lock );
+
+ return i_channel;
+}
+
+void spu_ClearChannel( spu_t *p_spu, int i_channel )
+{
+ spu_private_t *p_sys = p_spu->p;
+
+ vlc_mutex_lock( &p_sys->lock );
+
+ for( int i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
+ {
+ spu_heap_entry_t *p_entry = &p_sys->heap.p_entry[i_subpic];
+ subpicture_t *p_subpic = p_entry->p_subpicture;
+
+ if( !p_subpic )
+ continue;
+ if( p_subpic->i_channel != i_channel && ( i_channel != -1 || p_subpic->i_channel == SPU_DEFAULT_CHANNEL ) )
+ continue;
+
+ /* You cannot delete subpicture outside of spu_SortSubpictures */
+ p_entry->b_reject = true;
+ }
+
+ vlc_mutex_unlock( &p_sys->lock );
+}
+
+void spu_ChangeFilters( spu_t *p_spu, const char *psz_filters )
+{
+ spu_private_t *p_sys = p_spu->p;
+
+ vlc_mutex_lock( &p_sys->lock );
+
+ free( p_sys->psz_chain_update );
+ p_sys->psz_chain_update = strdup( psz_filters );
+
+ vlc_mutex_unlock( &p_sys->lock );
+}
+
/*****************************************************************************
* subpicture_t allocation
*****************************************************************************/
i_y = i_delta_y;
}
- /* Margin shifts all subpictures */
- /* NOTE We have margin only for subtitles, so we don't really need this here
- if( i_margin_y != 0 )
- i_y -= i_margin_y;*/
-
- /* Clamp offset to not go out of the screen (when possible) */
- /* NOTE Again, useful only for subtitles, otherwise goes against the alignment logic above
- const int i_error_x = (i_x + p_region->fmt.i_width) - p_subpic->i_original_picture_width;
- if( i_error_x > 0 )
- i_x -= i_error_x;
- if( i_x < 0 )
- i_x = 0;
-
- const int i_error_y = (i_y + p_region->fmt.i_height) - p_subpic->i_original_picture_height;
- if( i_error_y > 0 )
- i_y -= i_error_y;
- if( i_y < 0 )
- i_y = 0;*/
-
*pi_x = i_x;
*pi_y = i_y;
}
/* apply margin to subtitles and correct if they go over the picture edge */
if( p_subpic->b_subtitle )
- {
restrained.i_y -= i_margin_y;
- spu_area_t display = spu_area_create( 0, 0, p_fmt->i_width, p_fmt->i_height,
- spu_scale_unit() );
- SpuAreaFitInside( &restrained, &display );
- }
+
+ spu_area_t display = spu_area_create( 0, 0, p_fmt->i_width, p_fmt->i_height,
+ spu_scale_unit() );
+ SpuAreaFitInside( &restrained, &display );
/* Fix the position for the current scale_size */
i_x_offset = spu_scale_w( restrained.i_x, restrained.scale );
return r;
}
-/*****************************************************************************
- * SpuClearChannel: clear an spu channel
- *****************************************************************************
- * This function destroys the subpictures which belong to the spu channel
- * corresponding to i_channel_id.
- *****************************************************************************/
-static void SpuClearChannel( spu_t *p_spu, int i_channel )
-{
- spu_private_t *p_sys = p_spu->p;
- int i_subpic; /* subpicture index */
-
- vlc_mutex_lock( &p_sys->lock );
-
- for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
- {
- spu_heap_entry_t *p_entry = &p_sys->heap.p_entry[i_subpic];
- subpicture_t *p_subpic = p_entry->p_subpicture;
-
- if( !p_subpic )
- continue;
- if( p_subpic->i_channel != i_channel && ( i_channel != -1 || p_subpic->i_channel == DEFAULT_CHAN ) )
- continue;
-
- /* You cannot delete subpicture outside of spu_SortSubpictures */
- p_entry->b_reject = true;
- }
-
- vlc_mutex_unlock( &p_sys->lock );
-}
-
-/*****************************************************************************
- * spu_ControlDefault: default methods for the subpicture unit control.
- *****************************************************************************/
-static int SpuControl( spu_t *p_spu, int i_query, va_list args )
-{
- spu_private_t *p_sys = p_spu->p;
- int *pi, i;
-
- switch( i_query )
- {
- case SPU_CHANNEL_REGISTER:
- pi = (int *)va_arg( args, int * );
- vlc_mutex_lock( &p_sys->lock );
- if( pi )
- *pi = p_sys->i_channel++;
- vlc_mutex_unlock( &p_sys->lock );
- break;
-
- case SPU_CHANNEL_CLEAR:
- i = (int)va_arg( args, int );
- SpuClearChannel( p_spu, i );
- break;
-
- default:
- msg_Dbg( p_spu, "control query not supported" );
- return VLC_EGENERIC;
- }
-
- return VLC_SUCCESS;
-}
-
/*****************************************************************************
* Object variables callbacks
*****************************************************************************/
p_filter->pf_sub_buffer_del = sub_del_buffer;
p_filter->p_owner = p_sys;
- spu_Control( p_spu, SPU_CHANNEL_REGISTER, &p_sys->i_channel );
+ p_sys->i_channel = spu_RegisterChannel( p_spu );
p_sys->p_spu = p_spu;
return VLC_SUCCESS;
{
filter_owner_sys_t *p_sys = p_filter->p_owner;
- SpuClearChannel( p_sys->p_spu, p_sys->i_channel );
+ spu_ClearChannel( p_sys->p_spu, p_sys->i_channel );
free( p_filter->p_owner );
}
-static int SubFilterCallback( vlc_object_t *p_object, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
- spu_t *p_spu = p_data;
- spu_private_t *p_sys = p_spu->p;
-
- VLC_UNUSED(p_object); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);
-
- vlc_mutex_lock( &p_sys->lock );
-
- free( p_sys->psz_chain_update );
- p_sys->psz_chain_update = strdup( newval.psz_string );
-
- vlc_mutex_unlock( &p_sys->lock );
- return VLC_SUCCESS;
-}
-