1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004-2007 VLC authors and VideoLAN
7 * Authors: Antoine Cellerier <dionoea@videolan.org>
8 * Christophe Massiot <massiot@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
36 #include <vlc_block.h>
37 #include <vlc_codec.h>
40 #include <vlc_image.h>
41 #include <vlc_filter.h>
42 #include <vlc_modules.h>
44 #include "../video_filter/mosaic.h"
46 /*****************************************************************************
48 *****************************************************************************/
49 struct sout_stream_sys_t
54 image_handler_t
*p_image
; /* filter for resizing */
55 int i_height
, i_width
;
56 unsigned int i_sar_num
, i_sar_den
;
60 int i_chroma
; /* force image format chroma */
62 filter_chain_t
*p_vf2
;
65 struct decoder_owner_sys_t
67 /* Current format in use by the output */
71 /*****************************************************************************
73 *****************************************************************************/
74 static int Open ( vlc_object_t
* );
75 static void Close ( vlc_object_t
* );
76 static sout_stream_id_sys_t
*Add ( sout_stream_t
*, es_format_t
* );
77 static int Del ( sout_stream_t
*, sout_stream_id_sys_t
* );
78 static int Send( sout_stream_t
*, sout_stream_id_sys_t
*, block_t
* );
80 inline static void video_del_buffer_decoder( decoder_t
*, picture_t
* );
81 inline static void video_del_buffer_filter( filter_t
*, picture_t
* );
83 inline static picture_t
*video_new_buffer_decoder( decoder_t
* );
84 inline static picture_t
*video_new_buffer_filter( filter_t
* );
85 static picture_t
*video_new_buffer( vlc_object_t
*, decoder_owner_sys_t
*,
88 static void video_link_picture_decoder( decoder_t
*, picture_t
* );
89 static void video_unlink_picture_decoder( decoder_t
*, picture_t
* );
91 static int HeightCallback( vlc_object_t
*, char const *,
92 vlc_value_t
, vlc_value_t
, void * );
93 static int WidthCallback( vlc_object_t
*, char const *,
94 vlc_value_t
, vlc_value_t
, void * );
95 static int alphaCallback( vlc_object_t
*, char const *,
96 vlc_value_t
, vlc_value_t
, void * );
97 static int xCallback( vlc_object_t
*, char const *,
98 vlc_value_t
, vlc_value_t
, void * );
99 static int yCallback( vlc_object_t
*, char const *,
100 vlc_value_t
, vlc_value_t
, void * );
102 /*****************************************************************************
104 *****************************************************************************/
105 #define ID_TEXT N_("ID")
106 #define ID_LONGTEXT N_( \
107 "Specify an identifier string for this subpicture" )
109 #define WIDTH_TEXT N_("Video width")
110 #define WIDTH_LONGTEXT N_( \
111 "Output video width." )
112 #define HEIGHT_TEXT N_("Video height")
113 #define HEIGHT_LONGTEXT N_( \
114 "Output video height." )
115 #define RATIO_TEXT N_("Sample aspect ratio")
116 #define RATIO_LONGTEXT N_( \
117 "Sample aspect ratio of the destination (1:1, 3:4, 2:3)." )
119 #define VFILTER_TEXT N_("Video filter")
120 #define VFILTER_LONGTEXT N_( \
121 "Video filters will be applied to the video stream." )
123 #define CHROMA_TEXT N_("Image chroma")
124 #define CHROMA_LONGTEXT N_( \
125 "Force the use of a specific chroma. Use YUVA if you're planning " \
126 "to use the Alphamask or Bluescreen video filter." )
128 #define ALPHA_TEXT N_("Transparency")
129 #define ALPHA_LONGTEXT N_( \
130 "Transparency of the mosaic picture." )
132 #define X_TEXT N_("X offset")
133 #define X_LONGTEXT N_( \
134 "X coordinate of the upper left corner in the mosaic if non negative." )
136 #define Y_TEXT N_("Y offset")
137 #define Y_LONGTEXT N_( \
138 "Y coordinate of the upper left corner in the mosaic if non negative." )
140 #define CFG_PREFIX "sout-mosaic-bridge-"
143 set_shortname( N_( "Mosaic bridge" ) )
144 set_description(N_("Mosaic bridge stream output") )
145 set_capability( "sout stream", 0 )
146 add_shortcut( "mosaic-bridge" )
148 add_string( CFG_PREFIX
"id", "Id", ID_TEXT
, ID_LONGTEXT
,
150 add_integer( CFG_PREFIX
"width", 0, WIDTH_TEXT
,
151 WIDTH_LONGTEXT
, true )
152 add_integer( CFG_PREFIX
"height", 0, HEIGHT_TEXT
,
153 HEIGHT_LONGTEXT
, true )
154 add_string( CFG_PREFIX
"sar", "1:1", RATIO_TEXT
,
155 RATIO_LONGTEXT
, false )
156 add_string( CFG_PREFIX
"chroma", NULL
, CHROMA_TEXT
, CHROMA_LONGTEXT
,
159 add_module_list( CFG_PREFIX
"vfilter", "video filter2",
160 NULL
, VFILTER_TEXT
, VFILTER_LONGTEXT
, false )
162 add_integer_with_range( CFG_PREFIX
"alpha", 255, 0, 255,
163 ALPHA_TEXT
, ALPHA_LONGTEXT
, false )
164 add_integer( CFG_PREFIX
"x", -1, X_TEXT
, X_LONGTEXT
, false )
165 add_integer( CFG_PREFIX
"y", -1, Y_TEXT
, Y_LONGTEXT
, false )
167 set_callbacks( Open
, Close
)
170 static const char *const ppsz_sout_options
[] = {
171 "id", "width", "height", "sar", "vfilter", "chroma", "alpha", "x", "y", NULL
174 /*****************************************************************************
176 *****************************************************************************/
177 static int Open( vlc_object_t
*p_this
)
179 sout_stream_t
*p_stream
= (sout_stream_t
*)p_this
;
180 sout_stream_sys_t
*p_sys
;
183 config_ChainParse( p_stream
, CFG_PREFIX
, ppsz_sout_options
,
186 p_sys
= malloc( sizeof( sout_stream_sys_t
) );
190 p_stream
->p_sys
= p_sys
;
191 p_sys
->b_inited
= false;
193 p_sys
->psz_id
= var_CreateGetString( p_stream
, CFG_PREFIX
"id" );
196 var_CreateGetIntegerCommand( p_stream
, CFG_PREFIX
"height" );
197 var_AddCallback( p_stream
, CFG_PREFIX
"height", HeightCallback
, p_stream
);
200 var_CreateGetIntegerCommand( p_stream
, CFG_PREFIX
"width" );
201 var_AddCallback( p_stream
, CFG_PREFIX
"width", WidthCallback
, p_stream
);
203 var_Get( p_stream
, CFG_PREFIX
"sar", &val
);
206 char *psz_parser
= strchr( val
.psz_string
, ':' );
210 *psz_parser
++ = '\0';
211 p_sys
->i_sar_num
= atoi( val
.psz_string
);
212 p_sys
->i_sar_den
= atoi( psz_parser
);
213 vlc_ureduce( &p_sys
->i_sar_num
, &p_sys
->i_sar_den
,
214 p_sys
->i_sar_num
, p_sys
->i_sar_den
, 0 );
218 msg_Warn( p_stream
, "bad aspect ratio %s", val
.psz_string
);
219 p_sys
->i_sar_num
= p_sys
->i_sar_den
= 1;
222 free( val
.psz_string
);
226 p_sys
->i_sar_num
= p_sys
->i_sar_den
= 1;
230 val
.psz_string
= var_GetNonEmptyString( p_stream
, CFG_PREFIX
"chroma" );
231 if( val
.psz_string
&& strlen( val
.psz_string
) >= 4 )
233 memcpy( &p_sys
->i_chroma
, val
.psz_string
, 4 );
234 msg_Dbg( p_stream
, "Forcing image chroma to 0x%.8x (%4.4s)", p_sys
->i_chroma
, (char*)&p_sys
->i_chroma
);
236 free( val
.psz_string
);
238 #define INT_COMMAND( a ) do { \
239 var_Create( p_stream, CFG_PREFIX #a, \
240 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND ); \
241 var_AddCallback( p_stream, CFG_PREFIX #a, a ## Callback, \
242 p_stream ); } while(0)
243 INT_COMMAND( alpha
);
249 p_stream
->pf_add
= Add
;
250 p_stream
->pf_del
= Del
;
251 p_stream
->pf_send
= Send
;
252 p_stream
->pace_nocontrol
= true;
257 /*****************************************************************************
259 *****************************************************************************/
260 static void Close( vlc_object_t
* p_this
)
262 sout_stream_t
*p_stream
= (sout_stream_t
*)p_this
;
263 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
265 /* Delete the callbacks */
266 var_DelCallback( p_stream
, CFG_PREFIX
"height", HeightCallback
, p_stream
);
267 var_DelCallback( p_stream
, CFG_PREFIX
"width", WidthCallback
, p_stream
);
268 var_DelCallback( p_stream
, CFG_PREFIX
"alpha", alphaCallback
, p_stream
);
269 var_DelCallback( p_stream
, CFG_PREFIX
"x", xCallback
, p_stream
);
270 var_DelCallback( p_stream
, CFG_PREFIX
"y", yCallback
, p_stream
);
272 free( p_sys
->psz_id
);
277 static int video_filter_buffer_allocation_init( filter_t
*p_filter
, void *p_data
)
279 p_filter
->pf_video_buffer_new
= video_new_buffer_filter
;
280 p_filter
->pf_video_buffer_del
= video_del_buffer_filter
;
281 p_filter
->p_owner
= p_data
;
285 static sout_stream_id_sys_t
* Add( sout_stream_t
*p_stream
, es_format_t
*p_fmt
)
287 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
293 if( p_sys
->b_inited
|| p_fmt
->i_cat
!= VIDEO_ES
)
296 /* Create decoder object */
297 p_sys
->p_decoder
= vlc_object_create( p_stream
, sizeof( decoder_t
) );
298 if( !p_sys
->p_decoder
)
300 p_sys
->p_decoder
->p_module
= NULL
;
301 p_sys
->p_decoder
->fmt_in
= *p_fmt
;
302 p_sys
->p_decoder
->b_pace_control
= false;
303 p_sys
->p_decoder
->fmt_out
= p_sys
->p_decoder
->fmt_in
;
304 p_sys
->p_decoder
->fmt_out
.i_extra
= 0;
305 p_sys
->p_decoder
->fmt_out
.p_extra
= 0;
306 p_sys
->p_decoder
->pf_decode_video
= 0;
307 p_sys
->p_decoder
->pf_vout_buffer_new
= video_new_buffer_decoder
;
308 p_sys
->p_decoder
->pf_vout_buffer_del
= video_del_buffer_decoder
;
309 p_sys
->p_decoder
->pf_picture_link
= video_link_picture_decoder
;
310 p_sys
->p_decoder
->pf_picture_unlink
= video_unlink_picture_decoder
;
311 p_sys
->p_decoder
->p_owner
= malloc( sizeof(decoder_owner_sys_t
) );
312 if( !p_sys
->p_decoder
->p_owner
)
314 vlc_object_release( p_sys
->p_decoder
);
318 p_sys
->p_decoder
->p_owner
->video
= p_fmt
->video
;
319 //p_sys->p_decoder->p_cfg = p_sys->p_video_cfg;
321 p_sys
->p_decoder
->p_module
=
322 module_need( p_sys
->p_decoder
, "decoder", "$codec", false );
324 if( !p_sys
->p_decoder
->p_module
|| !p_sys
->p_decoder
->pf_decode_video
)
326 if( p_sys
->p_decoder
->p_module
)
328 msg_Err( p_stream
, "instanciated a non video decoder" );
329 module_unneed( p_sys
->p_decoder
, p_sys
->p_decoder
->p_module
);
333 msg_Err( p_stream
, "cannot find decoder" );
335 free( p_sys
->p_decoder
->p_owner
);
336 vlc_object_release( p_sys
->p_decoder
);
340 p_sys
->b_inited
= true;
341 vlc_global_lock( VLC_MOSAIC_MUTEX
);
343 p_bridge
= GetBridge( p_stream
);
344 if ( p_bridge
== NULL
)
346 vlc_object_t
*p_libvlc
= VLC_OBJECT( p_stream
->p_libvlc
);
349 p_bridge
= xmalloc( sizeof( bridge_t
) );
351 var_Create( p_libvlc
, "mosaic-struct", VLC_VAR_ADDRESS
);
352 val
.p_address
= p_bridge
;
353 var_Set( p_libvlc
, "mosaic-struct", val
);
355 p_bridge
->i_es_num
= 0;
356 p_bridge
->pp_es
= NULL
;
359 for ( i
= 0; i
< p_bridge
->i_es_num
; i
++ )
361 if ( p_bridge
->pp_es
[i
]->b_empty
)
365 if ( i
== p_bridge
->i_es_num
)
367 p_bridge
->pp_es
= xrealloc( p_bridge
->pp_es
,
368 (p_bridge
->i_es_num
+ 1) * sizeof(bridged_es_t
*) );
369 p_bridge
->i_es_num
++;
370 p_bridge
->pp_es
[i
] = xmalloc( sizeof(bridged_es_t
) );
373 p_sys
->p_es
= p_es
= p_bridge
->pp_es
[i
];
375 p_es
->i_alpha
= var_GetInteger( p_stream
, CFG_PREFIX
"alpha" );
376 p_es
->i_x
= var_GetInteger( p_stream
, CFG_PREFIX
"x" );
377 p_es
->i_y
= var_GetInteger( p_stream
, CFG_PREFIX
"y" );
379 //p_es->fmt = *p_fmt;
380 p_es
->psz_id
= p_sys
->psz_id
;
381 p_es
->p_picture
= NULL
;
382 p_es
->pp_last
= &p_es
->p_picture
;
383 p_es
->b_empty
= false;
385 vlc_global_unlock( VLC_MOSAIC_MUTEX
);
387 if ( p_sys
->i_height
|| p_sys
->i_width
)
389 p_sys
->p_image
= image_HandlerCreate( p_stream
);
393 p_sys
->p_image
= NULL
;
396 msg_Dbg( p_stream
, "mosaic bridge id=%s pos=%d", p_es
->psz_id
, i
);
398 /* Create user specified video filters */
399 psz_chain
= var_GetNonEmptyString( p_stream
, CFG_PREFIX
"vfilter" );
400 msg_Dbg( p_stream
, "psz_chain: %s", psz_chain
);
403 p_sys
->p_vf2
= filter_chain_New( p_stream
, "video filter2", false,
404 video_filter_buffer_allocation_init
,
405 NULL
, p_sys
->p_decoder
->p_owner
);
407 es_format_Copy( &fmt
, &p_sys
->p_decoder
->fmt_out
);
408 if( p_sys
->i_chroma
)
409 fmt
.video
.i_chroma
= p_sys
->i_chroma
;
410 filter_chain_Reset( p_sys
->p_vf2
, &fmt
, &fmt
);
411 filter_chain_AppendFromString( p_sys
->p_vf2
, psz_chain
);
419 return (sout_stream_id_sys_t
*)p_sys
;
422 static int Del( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
)
425 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
428 bool b_last_es
= true;
431 if( !p_sys
->b_inited
)
434 if( p_sys
->p_decoder
!= NULL
)
436 decoder_owner_sys_t
*p_owner
= p_sys
->p_decoder
->p_owner
;
438 if( p_sys
->p_decoder
->p_module
)
439 module_unneed( p_sys
->p_decoder
, p_sys
->p_decoder
->p_module
);
440 if( p_sys
->p_decoder
->p_description
)
441 vlc_meta_Delete( p_sys
->p_decoder
->p_description
);
443 vlc_object_release( p_sys
->p_decoder
);
448 /* Destroy user specified video filters */
450 filter_chain_Delete( p_sys
->p_vf2
);
452 vlc_global_lock( VLC_MOSAIC_MUTEX
);
454 p_bridge
= GetBridge( p_stream
);
457 p_es
->b_empty
= true;
458 while ( p_es
->p_picture
)
460 picture_t
*p_next
= p_es
->p_picture
->p_next
;
461 picture_Release( p_es
->p_picture
);
462 p_es
->p_picture
= p_next
;
465 for ( i
= 0; i
< p_bridge
->i_es_num
; i
++ )
467 if ( !p_bridge
->pp_es
[i
]->b_empty
)
476 vlc_object_t
*p_libvlc
= VLC_OBJECT( p_stream
->p_libvlc
);
477 for ( i
= 0; i
< p_bridge
->i_es_num
; i
++ )
478 free( p_bridge
->pp_es
[i
] );
479 free( p_bridge
->pp_es
);
481 var_Destroy( p_libvlc
, "mosaic-struct" );
484 vlc_global_unlock( VLC_MOSAIC_MUTEX
);
486 if ( p_sys
->p_image
)
488 image_HandlerDelete( p_sys
->p_image
);
491 p_sys
->b_inited
= false;
496 /*****************************************************************************
497 * PushPicture : push a picture in the mosaic-struct structure
498 *****************************************************************************/
499 static void PushPicture( sout_stream_t
*p_stream
, picture_t
*p_picture
)
501 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
502 bridged_es_t
*p_es
= p_sys
->p_es
;
504 vlc_global_lock( VLC_MOSAIC_MUTEX
);
506 *p_es
->pp_last
= p_picture
;
507 p_picture
->p_next
= NULL
;
508 p_es
->pp_last
= &p_picture
->p_next
;
510 vlc_global_unlock( VLC_MOSAIC_MUTEX
);
513 static int Send( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
,
516 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
519 if ( (sout_stream_sys_t
*)id
!= p_sys
)
521 block_ChainRelease( p_buffer
);
525 while ( (p_pic
= p_sys
->p_decoder
->pf_decode_video( p_sys
->p_decoder
,
528 picture_t
*p_new_pic
;
530 if( p_sys
->i_height
|| p_sys
->i_width
)
532 video_format_t fmt_out
, fmt_in
;
534 memset( &fmt_in
, 0, sizeof(video_format_t
) );
535 memset( &fmt_out
, 0, sizeof(video_format_t
) );
536 fmt_in
= p_sys
->p_decoder
->fmt_out
.video
;
539 if( p_sys
->i_chroma
)
540 fmt_out
.i_chroma
= p_sys
->i_chroma
;
542 fmt_out
.i_chroma
= VLC_CODEC_I420
;
544 const unsigned i_fmt_in_aspect
=
545 (int64_t)VOUT_ASPECT_FACTOR
*
546 fmt_in
.i_sar_num
* fmt_in
.i_width
/
547 (fmt_in
.i_sar_den
* fmt_in
.i_height
);
548 if ( !p_sys
->i_height
)
550 fmt_out
.i_width
= p_sys
->i_width
;
551 fmt_out
.i_height
= (p_sys
->i_width
* VOUT_ASPECT_FACTOR
552 * p_sys
->i_sar_num
/ p_sys
->i_sar_den
/ i_fmt_in_aspect
)
555 else if ( !p_sys
->i_width
)
557 fmt_out
.i_height
= p_sys
->i_height
;
558 fmt_out
.i_width
= (p_sys
->i_height
* i_fmt_in_aspect
559 * p_sys
->i_sar_den
/ p_sys
->i_sar_num
/ VOUT_ASPECT_FACTOR
)
564 fmt_out
.i_width
= p_sys
->i_width
;
565 fmt_out
.i_height
= p_sys
->i_height
;
567 fmt_out
.i_visible_width
= fmt_out
.i_width
;
568 fmt_out
.i_visible_height
= fmt_out
.i_height
;
570 p_new_pic
= image_Convert( p_sys
->p_image
,
571 p_pic
, &fmt_in
, &fmt_out
);
572 if( p_new_pic
== NULL
)
574 msg_Err( p_stream
, "image conversion failed" );
575 picture_Release( p_pic
);
581 /* TODO: chroma conversion if needed */
583 p_new_pic
= picture_New( p_pic
->format
.i_chroma
,
584 p_pic
->format
.i_width
, p_pic
->format
.i_height
,
585 p_sys
->p_decoder
->fmt_out
.video
.i_sar_num
,
586 p_sys
->p_decoder
->fmt_out
.video
.i_sar_den
);
589 picture_Release( p_pic
);
590 msg_Err( p_stream
, "image allocation failed" );
594 picture_Copy( p_new_pic
, p_pic
);
596 picture_Release( p_pic
);
599 p_new_pic
= filter_chain_VideoFilter( p_sys
->p_vf2
, p_new_pic
);
601 PushPicture( p_stream
, p_new_pic
);
607 inline static picture_t
*video_new_buffer_decoder( decoder_t
*p_dec
)
609 return video_new_buffer( VLC_OBJECT( p_dec
),
610 (decoder_owner_sys_t
*)p_dec
->p_owner
,
614 inline static picture_t
*video_new_buffer_filter( filter_t
*p_filter
)
616 return video_new_buffer( VLC_OBJECT( p_filter
),
617 (decoder_owner_sys_t
*)p_filter
->p_owner
,
618 &p_filter
->fmt_out
);
621 static picture_t
*video_new_buffer( vlc_object_t
*p_this
,
622 decoder_owner_sys_t
*p_sys
,
623 es_format_t
*fmt_out
)
626 if( fmt_out
->video
.i_width
!= p_sys
->video
.i_width
||
627 fmt_out
->video
.i_height
!= p_sys
->video
.i_height
||
628 fmt_out
->video
.i_chroma
!= p_sys
->video
.i_chroma
||
629 (int64_t)fmt_out
->video
.i_sar_num
* p_sys
->video
.i_sar_den
!=
630 (int64_t)fmt_out
->video
.i_sar_den
* p_sys
->video
.i_sar_num
)
632 vlc_ureduce( &fmt_out
->video
.i_sar_num
,
633 &fmt_out
->video
.i_sar_den
,
634 fmt_out
->video
.i_sar_num
,
635 fmt_out
->video
.i_sar_den
, 0 );
637 if( !fmt_out
->video
.i_visible_width
||
638 !fmt_out
->video
.i_visible_height
)
640 fmt_out
->video
.i_visible_width
= fmt_out
->video
.i_width
;
641 fmt_out
->video
.i_visible_height
= fmt_out
->video
.i_height
;
644 fmt_out
->video
.i_chroma
= fmt_out
->i_codec
;
645 p_sys
->video
= fmt_out
->video
;
649 fmt_out
->video
.i_chroma
= fmt_out
->i_codec
;
651 return picture_NewFromFormat( &fmt_out
->video
);
654 inline static void video_del_buffer_decoder( decoder_t
*p_this
,
658 picture_Release( p_pic
);
661 inline static void video_del_buffer_filter( filter_t
*p_this
,
665 picture_Release( p_pic
);
668 static void video_link_picture_decoder( decoder_t
*p_dec
, picture_t
*p_pic
)
671 picture_Hold( p_pic
);
674 static void video_unlink_picture_decoder( decoder_t
*p_dec
, picture_t
*p_pic
)
677 picture_Release( p_pic
);
681 /**********************************************************************
682 * Callback to update (some) params on the fly
683 **********************************************************************/
684 static int HeightCallback( vlc_object_t
*p_this
, char const *psz_var
,
685 vlc_value_t oldval
, vlc_value_t newval
,
688 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
689 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
690 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
692 /* We create the handler before updating the value in p_sys
693 * so we don't have to worry about locking */
694 if( !p_sys
->p_image
&& newval
.i_int
)
695 p_sys
->p_image
= image_HandlerCreate( p_stream
);
696 p_sys
->i_height
= newval
.i_int
;
701 static int WidthCallback( vlc_object_t
*p_this
, char const *psz_var
,
702 vlc_value_t oldval
, vlc_value_t newval
,
705 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
706 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
707 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
709 /* We create the handler before updating the value in p_sys
710 * so we don't have to worry about locking */
711 if( !p_sys
->p_image
&& newval
.i_int
)
712 p_sys
->p_image
= image_HandlerCreate( p_stream
);
713 p_sys
->i_width
= newval
.i_int
;
718 static int alphaCallback( vlc_object_t
*p_this
, char const *psz_var
,
719 vlc_value_t oldval
, vlc_value_t newval
,
722 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
723 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
724 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
727 p_sys
->p_es
->i_alpha
= newval
.i_int
;
732 static int xCallback( vlc_object_t
*p_this
, char const *psz_var
,
733 vlc_value_t oldval
, vlc_value_t newval
,
736 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
737 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
738 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
741 p_sys
->p_es
->i_x
= newval
.i_int
;
746 static int yCallback( vlc_object_t
*p_this
, char const *psz_var
,
747 vlc_value_t oldval
, vlc_value_t newval
,
750 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
751 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
752 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
755 p_sys
->p_es
->i_y
= newval
.i_int
;