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 "../spu/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
*, const es_format_t
* );
77 static void Del ( sout_stream_t
*, sout_stream_id_sys_t
* );
78 static int Send( sout_stream_t
*, sout_stream_id_sys_t
*, block_t
* );
80 static int decoder_queue_video( decoder_t
*p_dec
, picture_t
*p_pic
);
81 inline static int video_update_format_decoder( decoder_t
*p_dec
);
82 inline static picture_t
*video_new_buffer_decoder( decoder_t
* );
83 inline static picture_t
*video_new_buffer_filter( filter_t
* );
84 static int video_update_format( vlc_object_t
*, decoder_owner_sys_t
*,
87 static int HeightCallback( vlc_object_t
*, char const *,
88 vlc_value_t
, vlc_value_t
, void * );
89 static int WidthCallback( vlc_object_t
*, char const *,
90 vlc_value_t
, vlc_value_t
, void * );
91 static int alphaCallback( vlc_object_t
*, char const *,
92 vlc_value_t
, vlc_value_t
, void * );
93 static int xCallback( vlc_object_t
*, char const *,
94 vlc_value_t
, vlc_value_t
, void * );
95 static int yCallback( vlc_object_t
*, char const *,
96 vlc_value_t
, vlc_value_t
, void * );
98 /*****************************************************************************
100 *****************************************************************************/
101 #define ID_TEXT N_("ID")
102 #define ID_LONGTEXT N_( \
103 "Specify an identifier string for this subpicture" )
105 #define WIDTH_TEXT N_("Video width")
106 #define WIDTH_LONGTEXT N_( \
107 "Output video width." )
108 #define HEIGHT_TEXT N_("Video height")
109 #define HEIGHT_LONGTEXT N_( \
110 "Output video height." )
111 #define RATIO_TEXT N_("Sample aspect ratio")
112 #define RATIO_LONGTEXT N_( \
113 "Sample aspect ratio of the destination (1:1, 3:4, 2:3)." )
115 #define VFILTER_TEXT N_("Video filter")
116 #define VFILTER_LONGTEXT N_( \
117 "Video filters will be applied to the video stream." )
119 #define CHROMA_TEXT N_("Image chroma")
120 #define CHROMA_LONGTEXT N_( \
121 "Force the use of a specific chroma. Use YUVA if you're planning " \
122 "to use the Alphamask or Bluescreen video filter." )
124 #define ALPHA_TEXT N_("Transparency")
125 #define ALPHA_LONGTEXT N_( \
126 "Transparency of the mosaic picture." )
128 #define X_TEXT N_("X offset")
129 #define X_LONGTEXT N_( \
130 "X coordinate of the upper left corner in the mosaic if non negative." )
132 #define Y_TEXT N_("Y offset")
133 #define Y_LONGTEXT N_( \
134 "Y coordinate of the upper left corner in the mosaic if non negative." )
136 #define CFG_PREFIX "sout-mosaic-bridge-"
139 set_shortname( N_( "Mosaic bridge" ) )
140 set_description(N_("Mosaic bridge stream output") )
141 set_capability( "sout stream", 0 )
142 add_shortcut( "mosaic-bridge" )
144 add_string( CFG_PREFIX
"id", "Id", ID_TEXT
, ID_LONGTEXT
,
146 add_integer( CFG_PREFIX
"width", 0, WIDTH_TEXT
,
147 WIDTH_LONGTEXT
, true )
148 add_integer( CFG_PREFIX
"height", 0, HEIGHT_TEXT
,
149 HEIGHT_LONGTEXT
, true )
150 add_string( CFG_PREFIX
"sar", "1:1", RATIO_TEXT
,
151 RATIO_LONGTEXT
, false )
152 add_string( CFG_PREFIX
"chroma", NULL
, CHROMA_TEXT
, CHROMA_LONGTEXT
,
155 add_module_list( CFG_PREFIX
"vfilter", "video filter",
156 NULL
, VFILTER_TEXT
, VFILTER_LONGTEXT
, false )
158 add_integer_with_range( CFG_PREFIX
"alpha", 255, 0, 255,
159 ALPHA_TEXT
, ALPHA_LONGTEXT
, false )
160 add_integer( CFG_PREFIX
"x", -1, X_TEXT
, X_LONGTEXT
, false )
161 add_integer( CFG_PREFIX
"y", -1, Y_TEXT
, Y_LONGTEXT
, false )
163 set_callbacks( Open
, Close
)
166 static const char *const ppsz_sout_options
[] = {
167 "id", "width", "height", "sar", "vfilter", "chroma", "alpha", "x", "y", NULL
170 /*****************************************************************************
172 *****************************************************************************/
173 static int Open( vlc_object_t
*p_this
)
175 sout_stream_t
*p_stream
= (sout_stream_t
*)p_this
;
176 sout_stream_sys_t
*p_sys
;
179 config_ChainParse( p_stream
, CFG_PREFIX
, ppsz_sout_options
,
182 p_sys
= malloc( sizeof( sout_stream_sys_t
) );
186 p_stream
->p_sys
= p_sys
;
187 p_sys
->b_inited
= false;
189 p_sys
->psz_id
= var_CreateGetString( p_stream
, CFG_PREFIX
"id" );
192 var_CreateGetIntegerCommand( p_stream
, CFG_PREFIX
"height" );
193 var_AddCallback( p_stream
, CFG_PREFIX
"height", HeightCallback
, p_stream
);
196 var_CreateGetIntegerCommand( p_stream
, CFG_PREFIX
"width" );
197 var_AddCallback( p_stream
, CFG_PREFIX
"width", WidthCallback
, p_stream
);
199 var_Get( p_stream
, CFG_PREFIX
"sar", &val
);
202 char *psz_parser
= strchr( val
.psz_string
, ':' );
206 *psz_parser
++ = '\0';
207 p_sys
->i_sar_num
= atoi( val
.psz_string
);
208 p_sys
->i_sar_den
= atoi( psz_parser
);
209 vlc_ureduce( &p_sys
->i_sar_num
, &p_sys
->i_sar_den
,
210 p_sys
->i_sar_num
, p_sys
->i_sar_den
, 0 );
214 msg_Warn( p_stream
, "bad aspect ratio %s", val
.psz_string
);
215 p_sys
->i_sar_num
= p_sys
->i_sar_den
= 1;
218 free( val
.psz_string
);
222 p_sys
->i_sar_num
= p_sys
->i_sar_den
= 1;
226 val
.psz_string
= var_GetNonEmptyString( p_stream
, CFG_PREFIX
"chroma" );
227 if( val
.psz_string
&& strlen( val
.psz_string
) >= 4 )
229 memcpy( &p_sys
->i_chroma
, val
.psz_string
, 4 );
230 msg_Dbg( p_stream
, "Forcing image chroma to 0x%.8x (%4.4s)", p_sys
->i_chroma
, (char*)&p_sys
->i_chroma
);
232 free( val
.psz_string
);
234 #define INT_COMMAND( a ) do { \
235 var_Create( p_stream, CFG_PREFIX #a, \
236 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND ); \
237 var_AddCallback( p_stream, CFG_PREFIX #a, a ## Callback, \
238 p_stream ); } while(0)
239 INT_COMMAND( alpha
);
245 p_stream
->pf_add
= Add
;
246 p_stream
->pf_del
= Del
;
247 p_stream
->pf_send
= Send
;
248 p_stream
->pace_nocontrol
= true;
253 /*****************************************************************************
255 *****************************************************************************/
256 static void Close( vlc_object_t
* p_this
)
258 sout_stream_t
*p_stream
= (sout_stream_t
*)p_this
;
259 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
261 /* Delete the callbacks */
262 var_DelCallback( p_stream
, CFG_PREFIX
"height", HeightCallback
, p_stream
);
263 var_DelCallback( p_stream
, CFG_PREFIX
"width", WidthCallback
, p_stream
);
264 var_DelCallback( p_stream
, CFG_PREFIX
"alpha", alphaCallback
, p_stream
);
265 var_DelCallback( p_stream
, CFG_PREFIX
"x", xCallback
, p_stream
);
266 var_DelCallback( p_stream
, CFG_PREFIX
"y", yCallback
, p_stream
);
268 free( p_sys
->psz_id
);
273 static sout_stream_id_sys_t
* Add( sout_stream_t
*p_stream
, const es_format_t
*p_fmt
)
275 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
281 if( p_sys
->b_inited
|| p_fmt
->i_cat
!= VIDEO_ES
)
284 /* Create decoder object */
285 p_sys
->p_decoder
= vlc_object_create( p_stream
, sizeof( decoder_t
) );
286 if( !p_sys
->p_decoder
)
288 p_sys
->p_decoder
->p_module
= NULL
;
289 p_sys
->p_decoder
->fmt_in
= *p_fmt
;
290 p_sys
->p_decoder
->b_frame_drop_allowed
= true;
291 p_sys
->p_decoder
->fmt_out
= p_sys
->p_decoder
->fmt_in
;
292 p_sys
->p_decoder
->fmt_out
.i_extra
= 0;
293 p_sys
->p_decoder
->fmt_out
.p_extra
= 0;
294 p_sys
->p_decoder
->pf_decode
= NULL
;
295 p_sys
->p_decoder
->pf_queue_video
= decoder_queue_video
;
296 p_sys
->p_decoder
->p_queue_ctx
= p_stream
;
297 p_sys
->p_decoder
->pf_vout_format_update
= video_update_format_decoder
;
298 p_sys
->p_decoder
->pf_vout_buffer_new
= video_new_buffer_decoder
;
299 p_sys
->p_decoder
->p_owner
= malloc( sizeof(decoder_owner_sys_t
) );
300 if( !p_sys
->p_decoder
->p_owner
)
302 vlc_object_release( p_sys
->p_decoder
);
306 p_sys
->p_decoder
->p_owner
->video
= p_fmt
->video
;
307 //p_sys->p_decoder->p_cfg = p_sys->p_video_cfg;
309 p_sys
->p_decoder
->p_module
=
310 module_need( p_sys
->p_decoder
, "video decoder", "$codec", false );
312 if( !p_sys
->p_decoder
->p_module
)
314 msg_Err( p_stream
, "cannot find decoder" );
315 free( p_sys
->p_decoder
->p_owner
);
316 vlc_object_release( p_sys
->p_decoder
);
320 p_sys
->b_inited
= true;
321 vlc_global_lock( VLC_MOSAIC_MUTEX
);
323 p_bridge
= GetBridge( p_stream
);
324 if ( p_bridge
== NULL
)
326 vlc_object_t
*p_libvlc
= VLC_OBJECT( p_stream
->obj
.libvlc
);
329 p_bridge
= xmalloc( sizeof( bridge_t
) );
331 var_Create( p_libvlc
, "mosaic-struct", VLC_VAR_ADDRESS
);
332 val
.p_address
= p_bridge
;
333 var_Set( p_libvlc
, "mosaic-struct", val
);
335 p_bridge
->i_es_num
= 0;
336 p_bridge
->pp_es
= NULL
;
339 for ( i
= 0; i
< p_bridge
->i_es_num
; i
++ )
341 if ( p_bridge
->pp_es
[i
]->b_empty
)
345 if ( i
== p_bridge
->i_es_num
)
347 p_bridge
->pp_es
= xrealloc( p_bridge
->pp_es
,
348 (p_bridge
->i_es_num
+ 1) * sizeof(bridged_es_t
*) );
349 p_bridge
->i_es_num
++;
350 p_bridge
->pp_es
[i
] = xmalloc( sizeof(bridged_es_t
) );
353 p_sys
->p_es
= p_es
= p_bridge
->pp_es
[i
];
355 p_es
->i_alpha
= var_GetInteger( p_stream
, CFG_PREFIX
"alpha" );
356 p_es
->i_x
= var_GetInteger( p_stream
, CFG_PREFIX
"x" );
357 p_es
->i_y
= var_GetInteger( p_stream
, CFG_PREFIX
"y" );
359 //p_es->fmt = *p_fmt;
360 p_es
->psz_id
= p_sys
->psz_id
;
361 p_es
->p_picture
= NULL
;
362 p_es
->pp_last
= &p_es
->p_picture
;
363 p_es
->b_empty
= false;
365 vlc_global_unlock( VLC_MOSAIC_MUTEX
);
367 if ( p_sys
->i_height
|| p_sys
->i_width
)
369 p_sys
->p_image
= image_HandlerCreate( p_stream
);
373 p_sys
->p_image
= NULL
;
376 msg_Dbg( p_stream
, "mosaic bridge id=%s pos=%d", p_es
->psz_id
, i
);
378 /* Create user specified video filters */
379 psz_chain
= var_GetNonEmptyString( p_stream
, CFG_PREFIX
"vfilter" );
380 msg_Dbg( p_stream
, "psz_chain: %s", psz_chain
);
383 filter_owner_t owner
= {
384 .sys
= p_sys
->p_decoder
->p_owner
,
386 .buffer_new
= video_new_buffer_filter
,
390 p_sys
->p_vf2
= filter_chain_NewVideo( p_stream
, false, &owner
);
391 if (p_sys
->p_vf2
!= NULL
)
394 es_format_Copy( &fmt
, &p_sys
->p_decoder
->fmt_out
);
395 if( p_sys
->i_chroma
)
396 fmt
.video
.i_chroma
= p_sys
->i_chroma
;
397 filter_chain_Reset( p_sys
->p_vf2
, &fmt
, &fmt
);
398 es_format_Clean( &fmt
);
399 filter_chain_AppendFromString( p_sys
->p_vf2
, psz_chain
);
408 return (sout_stream_id_sys_t
*)p_sys
;
411 static void Del( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
)
414 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
417 bool b_last_es
= true;
420 if( !p_sys
->b_inited
)
423 if( p_sys
->p_decoder
!= NULL
)
425 decoder_owner_sys_t
*p_owner
= p_sys
->p_decoder
->p_owner
;
427 if( p_sys
->p_decoder
->p_module
)
428 module_unneed( p_sys
->p_decoder
, p_sys
->p_decoder
->p_module
);
429 if( p_sys
->p_decoder
->p_description
)
430 vlc_meta_Delete( p_sys
->p_decoder
->p_description
);
432 vlc_object_release( p_sys
->p_decoder
);
437 /* Destroy user specified video filters */
439 filter_chain_Delete( p_sys
->p_vf2
);
441 vlc_global_lock( VLC_MOSAIC_MUTEX
);
443 p_bridge
= GetBridge( p_stream
);
446 p_es
->b_empty
= true;
447 while ( p_es
->p_picture
)
449 picture_t
*p_next
= p_es
->p_picture
->p_next
;
450 picture_Release( p_es
->p_picture
);
451 p_es
->p_picture
= p_next
;
454 for ( i
= 0; i
< p_bridge
->i_es_num
; i
++ )
456 if ( !p_bridge
->pp_es
[i
]->b_empty
)
465 vlc_object_t
*p_libvlc
= VLC_OBJECT( p_stream
->obj
.libvlc
);
466 for ( i
= 0; i
< p_bridge
->i_es_num
; i
++ )
467 free( p_bridge
->pp_es
[i
] );
468 free( p_bridge
->pp_es
);
470 var_Destroy( p_libvlc
, "mosaic-struct" );
473 vlc_global_unlock( VLC_MOSAIC_MUTEX
);
475 if ( p_sys
->p_image
)
477 image_HandlerDelete( p_sys
->p_image
);
480 p_sys
->b_inited
= false;
483 static int decoder_queue_video( decoder_t
*p_dec
, picture_t
*p_pic
)
485 sout_stream_t
*p_stream
= p_dec
->p_queue_ctx
;
486 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
487 picture_t
*p_new_pic
;
488 const video_format_t
*p_fmt_in
= &p_sys
->p_decoder
->fmt_out
.video
;
490 if( p_sys
->i_height
|| p_sys
->i_width
)
492 video_format_t fmt_out
;
494 memset( &fmt_out
, 0, sizeof(video_format_t
) );
497 if( p_sys
->i_chroma
)
498 fmt_out
.i_chroma
= p_sys
->i_chroma
;
500 fmt_out
.i_chroma
= VLC_CODEC_I420
;
502 const unsigned i_fmt_in_aspect
=
503 (int64_t)VOUT_ASPECT_FACTOR
*
504 p_fmt_in
->i_sar_num
* p_fmt_in
->i_width
/
505 (p_fmt_in
->i_sar_den
* p_fmt_in
->i_height
);
506 if ( !p_sys
->i_height
)
508 fmt_out
.i_width
= p_sys
->i_width
;
509 fmt_out
.i_height
= (p_sys
->i_width
* VOUT_ASPECT_FACTOR
510 * p_sys
->i_sar_num
/ p_sys
->i_sar_den
/ i_fmt_in_aspect
)
513 else if ( !p_sys
->i_width
)
515 fmt_out
.i_height
= p_sys
->i_height
;
516 fmt_out
.i_width
= (p_sys
->i_height
* i_fmt_in_aspect
517 * p_sys
->i_sar_den
/ p_sys
->i_sar_num
/ VOUT_ASPECT_FACTOR
)
522 fmt_out
.i_width
= p_sys
->i_width
;
523 fmt_out
.i_height
= p_sys
->i_height
;
525 fmt_out
.i_visible_width
= fmt_out
.i_width
;
526 fmt_out
.i_visible_height
= fmt_out
.i_height
;
528 p_new_pic
= image_Convert( p_sys
->p_image
,
529 p_pic
, p_fmt_in
, &fmt_out
);
530 if( p_new_pic
== NULL
)
532 msg_Err( p_stream
, "image conversion failed" );
533 picture_Release( p_pic
);
539 /* TODO: chroma conversion if needed */
541 p_new_pic
= picture_New( p_pic
->format
.i_chroma
,
542 p_pic
->format
.i_width
, p_pic
->format
.i_height
,
544 p_fmt_in
->i_sar_den
);
547 picture_Release( p_pic
);
548 msg_Err( p_stream
, "image allocation failed" );
552 picture_Copy( p_new_pic
, p_pic
);
554 picture_Release( p_pic
);
557 p_new_pic
= filter_chain_VideoFilter( p_sys
->p_vf2
, p_new_pic
);
559 /* push the picture in the mosaic-struct structure */
560 bridged_es_t
*p_es
= p_sys
->p_es
;
561 vlc_global_lock( VLC_MOSAIC_MUTEX
);
562 *p_es
->pp_last
= p_new_pic
;
563 p_new_pic
->p_next
= NULL
;
564 p_es
->pp_last
= &p_new_pic
->p_next
;
565 vlc_global_unlock( VLC_MOSAIC_MUTEX
);
569 static int Send( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
,
572 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
574 if ( (sout_stream_sys_t
*)id
!= p_sys
)
576 block_ChainRelease( p_buffer
);
580 int ret
= p_sys
->p_decoder
->pf_decode( p_sys
->p_decoder
, p_buffer
);
581 return ret
== VLCDEC_SUCCESS
? VLC_SUCCESS
: VLC_EGENERIC
;
584 inline static int video_update_format_decoder( decoder_t
*p_dec
)
586 return video_update_format( VLC_OBJECT( p_dec
),
587 (decoder_owner_sys_t
*)p_dec
->p_owner
,
591 inline static picture_t
*video_new_buffer_decoder( decoder_t
*p_dec
)
593 return picture_NewFromFormat( &p_dec
->fmt_out
.video
);
596 inline static picture_t
*video_new_buffer_filter( filter_t
*p_filter
)
598 if( video_update_format( VLC_OBJECT( p_filter
),
599 (decoder_owner_sys_t
*)p_filter
->owner
.sys
,
600 &p_filter
->fmt_out
) ) {
601 msg_Warn( p_filter
, "can't get output picture" );
604 return picture_NewFromFormat( &p_filter
->fmt_out
.video
);
607 static int video_update_format( vlc_object_t
*p_this
,
608 decoder_owner_sys_t
*p_sys
,
609 es_format_t
*fmt_out
)
612 if( fmt_out
->video
.i_width
!= p_sys
->video
.i_width
||
613 fmt_out
->video
.i_height
!= p_sys
->video
.i_height
||
614 fmt_out
->video
.i_chroma
!= p_sys
->video
.i_chroma
||
615 (int64_t)fmt_out
->video
.i_sar_num
* p_sys
->video
.i_sar_den
!=
616 (int64_t)fmt_out
->video
.i_sar_den
* p_sys
->video
.i_sar_num
)
618 vlc_ureduce( &fmt_out
->video
.i_sar_num
,
619 &fmt_out
->video
.i_sar_den
,
620 fmt_out
->video
.i_sar_num
,
621 fmt_out
->video
.i_sar_den
, 0 );
623 if( !fmt_out
->video
.i_visible_width
||
624 !fmt_out
->video
.i_visible_height
)
626 fmt_out
->video
.i_visible_width
= fmt_out
->video
.i_width
;
627 fmt_out
->video
.i_visible_height
= fmt_out
->video
.i_height
;
630 fmt_out
->video
.i_chroma
= fmt_out
->i_codec
;
631 p_sys
->video
= fmt_out
->video
;
635 fmt_out
->video
.i_chroma
= fmt_out
->i_codec
;
639 /**********************************************************************
640 * Callback to update (some) params on the fly
641 **********************************************************************/
642 static int HeightCallback( vlc_object_t
*p_this
, char const *psz_var
,
643 vlc_value_t oldval
, vlc_value_t newval
,
646 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
647 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
648 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
650 /* We create the handler before updating the value in p_sys
651 * so we don't have to worry about locking */
652 if( !p_sys
->p_image
&& newval
.i_int
)
653 p_sys
->p_image
= image_HandlerCreate( p_stream
);
654 p_sys
->i_height
= newval
.i_int
;
659 static int WidthCallback( vlc_object_t
*p_this
, char const *psz_var
,
660 vlc_value_t oldval
, vlc_value_t newval
,
663 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
664 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
665 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
667 /* We create the handler before updating the value in p_sys
668 * so we don't have to worry about locking */
669 if( !p_sys
->p_image
&& newval
.i_int
)
670 p_sys
->p_image
= image_HandlerCreate( p_stream
);
671 p_sys
->i_width
= newval
.i_int
;
676 static int alphaCallback( vlc_object_t
*p_this
, char const *psz_var
,
677 vlc_value_t oldval
, vlc_value_t newval
,
680 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
681 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
682 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
685 p_sys
->p_es
->i_alpha
= newval
.i_int
;
690 static int xCallback( vlc_object_t
*p_this
, char const *psz_var
,
691 vlc_value_t oldval
, vlc_value_t newval
,
694 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
695 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
696 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
699 p_sys
->p_es
->i_x
= newval
.i_int
;
704 static int yCallback( vlc_object_t
*p_this
, char const *psz_var
,
705 vlc_value_t oldval
, vlc_value_t newval
,
708 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
); VLC_UNUSED(psz_var
);
709 sout_stream_t
*p_stream
= (sout_stream_t
*)p_data
;
710 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
713 p_sys
->p_es
->i_y
= newval
.i_int
;