Commit f976d6ae authored by Christophe Massiot's avatar Christophe Massiot

* ALL: converted the video output module "picture" to a stream output

   module "mosaic-bridge".
parent 0ae97f35
......@@ -986,7 +986,7 @@ if test "${SYS}" != "mingwce"; then
VLC_ADD_PLUGINS([externrun])
VLC_ADD_PLUGINS([access_fake access_filter_timeshift])
VLC_ADD_PLUGINS([gestures rc telnet hotkeys netsync showintf time marq sap shout])
VLC_ADD_PLUGINS([picture mosaic wall motiondetect clone crop])
VLC_ADD_PLUGINS([mosaic wall motiondetect clone crop])
VLC_ADD_PLUGINS([i420_yuy2 i422_yuy2 i420_ymga])
VLC_ADD_PLUGINS([aout_file linear_resampler bandlimited_resampler])
VLC_ADD_PLUGINS([float32_mixer spdif_mixer simple_channel_mixer])
......@@ -1227,7 +1227,7 @@ then
VLC_ADD_PLUGINS([packetizer_copy])
VLC_ADD_PLUGINS([stream_out_dummy stream_out_standard stream_out_es stream_out_rtp stream_out_description vod_rtsp])
VLC_ADD_PLUGINS([stream_out_duplicate stream_out_gather stream_out_display stream_out_transcode stream_out_bridge])
VLC_ADD_PLUGINS([stream_out_duplicate stream_out_gather stream_out_display stream_out_transcode stream_out_bridge stream_out_mosaic_bridge])
# VLC_ADD_PLUGINS([stream_out_transrate])
AC_DEFINE(ENABLE_SOUT, 1, Define if you want the stream output support)
......@@ -2533,7 +2533,7 @@ AC_ARG_ENABLE(speex,
if test "${enable_speex}" != "no"
then
AC_CHECK_HEADERS(speex/speex.h, [
LDFLAGS="${LDFLAGS_save} ${LDFLAGS_toolame}"
LDFLAGS="${LDFLAGS_save} ${LDFLAGS_speex}"
AC_CHECK_LIB(speex, speex_decode_int, [
VLC_ADD_PLUGINS([speex])
VLC_ADD_LDFLAGS([speex],[-lspeex]) ],
......
......@@ -11,3 +11,4 @@ SOURCES_stream_out_gather = gather.c
SOURCES_stream_out_rtp = rtp.c
SOURCES_stream_out_switcher = switcher.c
SOURCES_stream_out_bridge = bridge.c
SOURCES_stream_out_mosaic_bridge = mosaic_bridge.c
......@@ -58,7 +58,7 @@ vlc_module_begin();
set_shortname( _("Bridge"));
set_description( _("Bridge stream output"));
add_submodule();
set_section( N_("Bridge out"),NULL);
set_section( N_("Bridge out"), NULL );
set_capability( "sout stream", 50 );
add_shortcut( "bridge-out" );
/* Only usable with VLM. No category so not in gui preferences
......@@ -69,12 +69,12 @@ vlc_module_begin();
set_callbacks( OpenOut, CloseOut );
add_submodule();
set_section( N_("Bridge in"),NULL);
set_section( N_("Bridge in"), NULL );
set_capability( "sout stream", 50 );
add_shortcut( "bridge-in" );
/*set_category( CAT_SOUT );
set_subcategory( SUBCAT_SOUT_STREAM );*/
add_integer( SOUT_CFG_PREFIX_IN "delay", 100, NULL, DELAY_TEXT,
add_integer( SOUT_CFG_PREFIX_IN "delay", 0, NULL, DELAY_TEXT,
DELAY_LONGTEXT, VLC_FALSE );
add_integer( SOUT_CFG_PREFIX_IN "id-offset", 8192, NULL, ID_OFFSET_TEXT,
ID_OFFSET_LONGTEXT, VLC_FALSE );
......@@ -109,7 +109,6 @@ typedef struct bridged_es_t
block_t *p_block;
block_t **pp_last;
vlc_bool_t b_empty;
int i_id;
/* bridge in part */
sout_stream_id_t *id;
......@@ -150,9 +149,9 @@ static bridge_t *__GetBridge( vlc_object_t *p_object )
typedef struct out_sout_stream_sys_t
{
vlc_mutex_t *p_lock;
bridged_es_t *p_es;
int i_id;
vlc_bool_t b_inited;
int i_position;
} out_sout_stream_sys_t;
/*****************************************************************************
......@@ -160,7 +159,7 @@ typedef struct out_sout_stream_sys_t
*****************************************************************************/
static int OpenOut( vlc_object_t *p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_t *p_stream = (sout_stream_t *)p_this;
out_sout_stream_sys_t *p_sys;
vlc_value_t val;
......@@ -182,7 +181,6 @@ static int OpenOut( vlc_object_t *p_this )
p_stream->p_sys = (sout_stream_sys_t *)p_sys;
/* update p_sout->i_out_pace_nocontrol */
p_stream->p_sout->i_out_pace_nocontrol++;
return VLC_SUCCESS;
......@@ -243,14 +241,12 @@ static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
p_bridge->pp_es = realloc( p_bridge->pp_es,
(p_bridge->i_es_num + 1)
* sizeof(bridged_es_t *) );
p_sys->i_position = p_bridge->i_es_num;
p_bridge->i_es_num++;
p_bridge->pp_es[i] = malloc( sizeof(bridged_es_t) );
}
else
p_sys->i_position = i;
p_es = p_bridge->pp_es[ p_sys->i_position ];
p_sys->p_es = p_es = p_bridge->pp_es[i];
p_es->fmt = *p_fmt;
p_es->fmt.i_id = p_sys->i_id;
p_es->p_block = NULL;
......@@ -262,7 +258,7 @@ static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
p_es->b_changed = VLC_TRUE;
msg_Dbg( p_stream, "bridging out input codec=%4.4s id=%d pos=%d",
(char*)&p_es->fmt.i_codec, p_es->fmt.i_id, p_sys->i_position );
(char*)&p_es->fmt.i_codec, p_es->fmt.i_id, i );
vlc_mutex_unlock( p_sys->p_lock );
......@@ -272,7 +268,6 @@ static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
static int DelOut( sout_stream_t *p_stream, sout_stream_id_t *id )
{
out_sout_stream_sys_t *p_sys = (out_sout_stream_sys_t *)p_stream->p_sys;
bridge_t *p_bridge;
bridged_es_t *p_es;
if ( !p_sys->b_inited )
......@@ -282,8 +277,7 @@ static int DelOut( sout_stream_t *p_stream, sout_stream_id_t *id )
vlc_mutex_lock( p_sys->p_lock );
p_bridge = GetBridge( p_stream );
p_es = p_bridge->pp_es[ p_sys->i_position ];
p_es = p_sys->p_es;
p_es->b_empty = VLC_TRUE;
block_ChainRelease( p_es->p_block );
......@@ -299,7 +293,6 @@ static int SendOut( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *p_buffer )
{
out_sout_stream_sys_t *p_sys = (out_sout_stream_sys_t *)p_stream->p_sys;
bridge_t *p_bridge;
bridged_es_t *p_es;
if ( (out_sout_stream_sys_t *)id != p_sys )
......@@ -310,8 +303,7 @@ static int SendOut( sout_stream_t *p_stream, sout_stream_id_t *id,
vlc_mutex_lock( p_sys->p_lock );
p_bridge = GetBridge( p_stream );
p_es = p_bridge->pp_es[ p_sys->i_position ];
p_es = p_sys->p_es;
*p_es->pp_last = p_buffer;
while ( p_buffer != NULL )
{
......
/*****************************************************************************
* picture.c:
* mosaic_bridge.c:
*****************************************************************************
* Copyright (C) 2004-2005 VideoLAN
* $Id$
......@@ -30,32 +30,33 @@
#include <string.h> /* strerror() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/sout.h>
#include <vlc/decoder.h>
#include "vlc_image.h"
#include "picture.h"
#include "../video_filter/mosaic.h"
/*****************************************************************************
* Local structures
*****************************************************************************/
struct vout_sys_t
struct sout_stream_sys_t
{
picture_vout_t *p_picture_vout;
bridged_es_t *p_es;
vlc_mutex_t *p_lock;
int i_picture_pos; /* picture position in p_picture_vout */
image_handler_t *p_image; /* filters for resizing */
#ifdef IMAGE_2PASSES
image_handler_t *p_image2;
#endif
decoder_t *p_decoder;
image_handler_t *p_image; /* filter for resizing */
int i_height, i_width;
mtime_t i_last_pic;
char *psz_id;
vlc_bool_t b_inited;
};
/* Delay after which the picture is blanked out if there hasn't been any
* new picture. */
#define BLANK_DELAY I64C(1000000)
#define PICTURE_RING_SIZE 64
struct decoder_owner_sys_t
{
picture_t *pp_pics[PICTURE_RING_SIZE];
};
typedef void (* pf_release_t)( picture_t * );
static void ReleasePicture( picture_t *p_pic )
......@@ -83,10 +84,14 @@ static void ReleasePicture( picture_t *p_pic )
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int Init ( vout_thread_t * );
static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void Display ( vout_thread_t *, picture_t * );
static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
static int Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, block_t * );
static void video_del_buffer( decoder_t *, picture_t * );
static picture_t *video_new_buffer( decoder_t * );
static void video_link_picture_decoder( decoder_t *, picture_t * );
static void video_unlink_picture_decoder( decoder_t *, picture_t * );
/*****************************************************************************
* Module descriptor
......@@ -102,226 +107,231 @@ static void Display ( vout_thread_t *, picture_t * );
#define HEIGHT_LONGTEXT N_( \
"Allows you to specify the output video height." )
vlc_module_begin();
set_shortname( _( "Picture" ) );
set_description(_("VLC internal picture video output") );
set_capability( "video output", 0 );
#define SOUT_CFG_PREFIX "sout-mosaic-bridge-"
add_string( "picture-id", "Id", NULL, ID_TEXT, ID_LONGTEXT, VLC_FALSE );
add_integer( "picture-width", 0, NULL, WIDTH_TEXT,
vlc_module_begin();
set_shortname( _( "Mosaic bridge" ) );
set_description(_("Mosaic bridge stream output") );
set_capability( "sout stream", 0 );
add_shortcut( "mosaic-bridge" );
add_string( SOUT_CFG_PREFIX "id", "Id", NULL, ID_TEXT, ID_LONGTEXT,
VLC_FALSE );
add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
WIDTH_LONGTEXT, VLC_TRUE );
add_integer( "picture-height", 0, NULL, HEIGHT_TEXT,
add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
HEIGHT_LONGTEXT, VLC_TRUE );
set_callbacks( Open, Close );
var_Create( p_module->p_libvlc, "picture-lock", VLC_VAR_MUTEX );
var_Create( p_module->p_libvlc, "mosaic-lock", VLC_VAR_MUTEX );
vlc_module_end();
static const char *ppsz_sout_options[] = {
"id", "width", "height", NULL
};
/*****************************************************************************
* Open : allocate video thread output method
* Open
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
vout_sys_t *p_sys;
libvlc_t *p_libvlc = p_vout->p_libvlc;
picture_vout_t *p_picture_vout = NULL;
picture_vout_e_t *p_pic;
vlc_value_t val, lockval;
p_sys = p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_sys == NULL )
{
msg_Err( p_vout, "out of memory" );
return VLC_ENOMEM;
}
sout_stream_t *p_stream = (sout_stream_t *)p_this;
sout_stream_sys_t *p_sys;
libvlc_t *p_libvlc = p_this->p_libvlc;
vlc_value_t val;
var_Get( p_libvlc, "picture-lock", &lockval );
p_sys->p_lock = lockval.p_address;
vlc_mutex_lock( p_sys->p_lock );
sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
p_stream->p_cfg );
p_sys->i_picture_pos = -1;
if( var_Get( p_libvlc, "p_picture_vout", &val ) != VLC_SUCCESS )
{
p_picture_vout = malloc( sizeof( struct picture_vout_t ) );
if( p_picture_vout == NULL )
{
msg_Err( p_vout, "out of memory" );
return VLC_ENOMEM;
}
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_stream->p_sys = p_sys;
p_sys->b_inited = VLC_FALSE;
var_Create( p_libvlc, "p_picture_vout", VLC_VAR_ADDRESS );
val.p_address = p_picture_vout;
var_Set( p_libvlc, "p_picture_vout", val );
var_Get( p_libvlc, "mosaic-lock", &val );
p_sys->p_lock = val.p_address;
p_picture_vout->i_picture_num = 0;
p_picture_vout->p_pic = NULL;
}
else
{
int i;
p_picture_vout = val.p_address;
for ( i = 0; i < p_picture_vout->i_picture_num; i++ )
{
if ( p_picture_vout->p_pic[i].i_status == PICTURE_VOUT_E_AVAILABLE )
break;
}
if ( i != p_picture_vout->i_picture_num )
p_sys->i_picture_pos = i;
}
p_sys->p_picture_vout = p_picture_vout;
if ( p_sys->i_picture_pos == -1 )
{
p_picture_vout->p_pic = realloc( p_picture_vout->p_pic,
(p_picture_vout->i_picture_num + 1)
* sizeof(picture_vout_e_t) );
p_sys->i_picture_pos = p_picture_vout->i_picture_num;
p_picture_vout->i_picture_num++;
}
p_pic = &p_picture_vout->p_pic[p_sys->i_picture_pos];
p_pic->p_picture = NULL;
p_pic->i_status = PICTURE_VOUT_E_OCCUPIED;
var_Get( p_stream, SOUT_CFG_PREFIX "id", &val );
p_sys->psz_id = val.psz_string;
var_Create( p_vout, "picture-id", VLC_VAR_STRING );
var_Change( p_vout, "picture-id", VLC_VAR_INHERITVALUE, &val, NULL );
p_pic->psz_id = val.psz_string;
vlc_mutex_unlock( p_sys->p_lock );
var_Create( p_vout, "picture-height", VLC_VAR_INTEGER );
var_Change( p_vout, "picture-height", VLC_VAR_INHERITVALUE, &val, NULL );
var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
p_sys->i_height = val.i_int;
var_Create( p_vout, "picture-width", VLC_VAR_INTEGER );
var_Change( p_vout, "picture-width", VLC_VAR_INHERITVALUE, &val, NULL );
var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
p_sys->i_width = val.i_int;
if ( p_sys->i_height || p_sys->i_width )
{
p_sys->p_image = image_HandlerCreate( p_vout );
#ifdef IMAGE_2PASSES
p_sys->p_image2 = image_HandlerCreate( p_vout );
#endif
p_sys->p_image = image_HandlerCreate( p_stream );
}
p_sys->i_last_pic = 0;
p_stream->pf_add = Add;
p_stream->pf_del = Del;
p_stream->pf_send = Send;
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = Manage;
p_vout->pf_render = NULL;
p_vout->pf_display = Display;
p_stream->p_sout->i_out_pace_nocontrol++;
return VLC_SUCCESS;
}
/*****************************************************************************
* Init
* Close
*****************************************************************************/
static int Init( vout_thread_t *p_vout )
static void Close( vlc_object_t * p_this )
{
picture_t *p_pic;
int i_index;
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
p_stream->p_sout->i_out_pace_nocontrol--;
I_OUTPUTPICTURES = 0;
if ( p_sys->psz_id )
free( p_sys->psz_id );
p_vout->output.i_chroma = p_vout->render.i_chroma;
p_vout->output.i_width = p_vout->render.i_width;
p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
free( p_sys );
}
static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
bridge_t *p_bridge;
bridged_es_t *p_es;
int i;
while( VLC_TRUE )
if ( p_sys->b_inited )
{
p_pic = NULL;
return NULL;
}
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
/* Create decoder object */
p_sys->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
vlc_object_attach( p_sys->p_decoder, p_stream );
p_sys->p_decoder->p_module = NULL;
p_sys->p_decoder->fmt_in = *p_fmt;
p_sys->p_decoder->b_pace_control = VLC_FALSE;
p_sys->p_decoder->fmt_out = p_sys->p_decoder->fmt_in;
p_sys->p_decoder->fmt_out.i_extra = 0;
p_sys->p_decoder->fmt_out.p_extra = 0;
p_sys->p_decoder->pf_decode_video = 0;
p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer;
p_sys->p_decoder->pf_vout_buffer_del = video_del_buffer;
p_sys->p_decoder->pf_picture_link = video_link_picture_decoder;
p_sys->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
p_sys->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
for( i = 0; i < PICTURE_RING_SIZE; i++ )
p_sys->p_decoder->p_owner->pp_pics[i] = 0;
//p_sys->p_decoder->p_cfg = p_sys->p_video_cfg;
p_sys->p_decoder->p_module =
module_Need( p_sys->p_decoder, "decoder", "$codec", 0 );
if( !p_sys->p_decoder->p_module )
{
msg_Err( p_stream, "cannot find decoder" );
vlc_object_detach( p_sys->p_decoder );
vlc_object_destroy( p_sys->p_decoder );
return NULL;
}
if( p_pic == NULL )
{
return VLC_SUCCESS;
}
p_sys->b_inited = VLC_TRUE;
vlc_mutex_lock( p_sys->p_lock );
vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic,
p_vout->output.i_chroma,
p_vout->output.i_width, p_vout->output.i_height,
p_vout->output.i_aspect );
p_bridge = GetBridge( p_stream );
if ( p_bridge == NULL )
{
libvlc_t *p_libvlc = p_stream->p_libvlc;
vlc_value_t val;
if( p_pic->i_planes == 0 )
{
return VLC_EGENERIC;
}
p_bridge = malloc( sizeof( bridge_t ) );
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
var_Create( p_libvlc, "mosaic-struct", VLC_VAR_ADDRESS );
val.p_address = p_bridge;
var_Set( p_libvlc, "mosaic-struct", val );
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
p_bridge->i_es_num = 0;
p_bridge->pp_es = NULL;
}
I_OUTPUTPICTURES++;
for ( i = 0; i < p_bridge->i_es_num; i++ )
{
if ( p_bridge->pp_es[i]->b_empty )
break;
}
//return VLC_SUCCESS;
if ( i == p_bridge->i_es_num )
{
p_bridge->pp_es = realloc( p_bridge->pp_es,
(p_bridge->i_es_num + 1)
* sizeof(bridged_es_t *) );
p_bridge->i_es_num++;
p_bridge->pp_es[i] = malloc( sizeof(bridged_es_t) );
}
}
p_sys->p_es = p_es = p_bridge->pp_es[i];
/*****************************************************************************
* End
*****************************************************************************/
static void End( vout_thread_t *p_vout )
{
return;
//p_es->fmt = *p_fmt;
p_es->psz_id = p_sys->psz_id;
p_es->p_picture = NULL;
p_es->pp_last = &p_es->p_picture;
p_es->b_empty = VLC_FALSE;
vlc_mutex_unlock( p_sys->p_lock );
msg_Dbg( p_stream, "mosaic bridge id=%s pos=%d", p_es->psz_id, i );
return (sout_stream_id_t *)p_sys;
}
/*****************************************************************************
* Close
*****************************************************************************/
static void Close( vlc_object_t *p_this )
static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
vout_sys_t *p_sys = p_vout->p_sys;
picture_vout_t *p_picture_vout = p_sys->p_picture_vout;
picture_vout_e_t *p_pic;
vlc_bool_t b_last_picture = VLC_TRUE;
sout_stream_sys_t *p_sys = p_stream->p_sys;
bridge_t *p_bridge;
bridged_es_t *p_es;
vlc_bool_t b_last_es = VLC_TRUE;
int i;
if ( !p_sys->b_inited )
{
return VLC_SUCCESS;
}
if ( p_sys->p_decoder )
{
if( p_sys->p_decoder->p_module )
module_Unneed( p_sys->p_decoder, p_sys->p_decoder->p_module );
vlc_object_detach( p_sys->p_decoder );
vlc_object_destroy( p_sys->p_decoder );
}
vlc_mutex_lock( p_sys->p_lock );
p_pic = &p_picture_vout->p_pic[p_sys->i_picture_pos];
if( p_pic->p_picture )
p_bridge = GetBridge( p_stream );
p_es = p_sys->p_es;
p_es->b_empty = VLC_TRUE;
while ( p_es->p_picture )
{
p_pic->p_picture->pf_release( p_pic->p_picture );
p_pic->p_picture = NULL;
picture_t *p_next = p_es->p_picture->p_next;
p_es->p_picture->pf_release( p_es->p_picture );
p_es->p_picture = p_next;
}
p_pic->i_status = PICTURE_VOUT_E_AVAILABLE;
if( p_pic->psz_id )
free( p_pic->psz_id );
for( i = 0; i < p_picture_vout->i_picture_num; i ++)
for ( i = 0; i < p_bridge->i_es_num; i++ )
{
if( p_picture_vout->p_pic[i].i_status == PICTURE_VOUT_E_OCCUPIED )
if ( !p_bridge->pp_es[i]->b_empty )
{
b_last_picture = VLC_FALSE;
b_last_es = VLC_FALSE;
break;
}
}
if( b_last_picture )
if ( b_last_es )
{
free( p_picture_vout->p_pic );
free( p_picture_vout );
var_Destroy( p_this->p_libvlc, "p_picture_vout" );
libvlc_t *p_libvlc = p_stream->p_libvlc;
for ( i = 0; i < p_bridge->i_es_num; i++ )
free( p_bridge->pp_es[i] );
free( p_bridge->pp_es );
free( p_bridge );
var_Destroy( p_libvlc, "mosaic-struct" );
}
vlc_mutex_unlock( p_sys->p_lock );
......@@ -329,160 +339,174 @@ static void Close( vlc_object_t *p_this )
if ( p_sys->i_height || p_sys->i_width )
{
image_HandlerDelete( p_sys->p_image );
#ifdef IMAGE_2PASSES
image_HandlerDelete( p_sys->p_image2 );
#endif
}
free( p_sys );
p_sys->b_inited = VLC_FALSE;
return VLC_SUCCESS;
}
/*****************************************************************************
* PushPicture : push a picture in the p_picture_vout structure
* PushPicture : push a picture in the mosaic-struct structure
*****************************************************************************/
static void PushPicture( vout_thread_t *p_vout, picture_t *p_picture )
static void PushPicture( sout_stream_t *p_stream, picture_t *p_picture )
{
vout_sys_t *p_sys = p_vout->p_sys;
picture_vout_t *p_picture_vout = p_sys->p_picture_vout;
picture_vout_e_t *p_pic;
sout_stream_sys_t *p_sys = p_stream->p_sys;
bridged_es_t *p_es = p_sys->p_es;
vlc_mutex_lock( p_sys->p_lock );
p_pic = &p_picture_vout->p_pic[p_sys->i_picture_pos];
if( p_pic->p_picture != NULL )
{
p_pic->p_picture->pf_release( p_pic->p_picture );
}
p_pic->p_picture = p_picture;
*p_es->pp_last = p_picture;
p_picture->p_next = NULL;
p_es->pp_last = &p_picture->p_next;
vlc_mutex_unlock( p_sys->p_lock );
}
/*****************************************************************************
* Manage
*****************************************************************************/
static int Manage( vout_thread_t *p_vout )
static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *p_buffer )
{
vout_sys_t *p_sys = p_vout->p_sys;
sout_stream_sys_t *p_sys = p_stream->p_sys;
picture_t *p_pic;
if ( (sout_stream_sys_t *)id != p_sys )
{
block_ChainRelease( p_buffer );
return VLC_SUCCESS;
}
if ( mdate() - p_sys->i_last_pic > BLANK_DELAY )
while ( (p_pic = p_sys->p_decoder->pf_decode_video( p_sys->p_decoder,
&p_buffer )) )
{
/* Display black */
#if 0
picture_t *p_new_pic = (picture_t*)malloc( sizeof(picture_t) );
int i;
picture_t *p_new_pic;
if ( p_sys->i_height || p_sys->i_width )
{
vout_AllocatePicture( p_vout, p_new_pic,
VLC_FOURCC('Y','U','V','A'),
p_sys->i_width, p_sys->i_height,
p_vout->render.i_aspect );
video_format_t fmt_out = {0}, fmt_in = {0};
fmt_in = p_sys->p_decoder->fmt_out.video;
fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
fmt_out.i_width = p_sys->i_width;
fmt_out.i_height = p_sys->i_height;
fmt_out.i_visible_width = fmt_out.i_width;
fmt_out.i_visible_height = fmt_out.i_height;
p_new_pic = image_Convert( p_sys->p_image,
p_pic, &fmt_in, &fmt_out );
if ( p_new_pic == NULL )
{
msg_Err( p_stream, "image conversion failed" );
continue;
}
}
else
{
vout_AllocatePicture( p_vout, p_new_pic, p_vout->render.i_chroma,
p_vout->render.i_width,
p_vout->render.i_height,
p_vout->render.i_aspect );
p_new_pic = (picture_t*)malloc( sizeof(picture_t) );
vout_AllocatePicture( p_stream, p_new_pic, p_pic->format.i_chroma,
p_pic->format.i_width, p_pic->format.i_height,
p_sys->p_decoder->fmt_out.video.i_aspect );
vout_CopyPicture( p_stream, p_new_pic, p_pic );
}
p_pic->pf_release( p_pic );
p_new_pic->i_refcount++;
p_new_pic->i_refcount = 1;
p_new_pic->i_status = DESTROYED_PICTURE;
p_new_pic->i_type = DIRECT_PICTURE;
p_new_pic->p_sys = (picture_sys_t *)p_new_pic->pf_release;
p_new_pic->pf_release = ReleasePicture;
p_new_pic->date = p_pic->date;
for ( i = 0; i < p_pic->i_planes; i++ )
{