/*****************************************************************************
* Preamble
*****************************************************************************/
+#include <vlc/vlc.h>
+
#include <stdlib.h> /* free() */
+#include <string.h>
-#include <vlc/vlc.h>
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
-#include "vlc_video.h"
-#include "video_output.h"
-#include "vlc_spu.h"
-#include <vlc/input.h> /* for input_thread_t and i_pts_delay */
-#include "vlc_playlist.h"
+#include <vlc_vout.h>
+#include <vlc_playlist.h>
-#include "vlc_filter.h"
-#include <vlc/sout.h> /* sout_CfgParse */
+#include <vlc_filter.h>
+#include <vlc_osd.h>
#if defined( __APPLE__ )
-#include "darwin_specific.h"
+/* Include darwin_specific.h here if needed */
#endif
+/** FIXME This is quite ugly but needed while we don't have counters
+ * helpers */
+#include "input/input_internal.h"
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
{
if( !p_fmt )
{
- /* Reattach video output to input before bailing out */
+ /* Reattach video output to playlist before bailing out */
if( p_vout )
{
- vlc_object_t *p_playlist;
-
- p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
-
- if( p_playlist )
- {
- spu_Attach( p_vout->p_spu, p_this, VLC_FALSE );
- vlc_object_detach( p_vout );
- vlc_object_attach( p_vout, p_playlist );
-
- vlc_object_release( p_playlist );
- }
- else
- {
- msg_Dbg( p_this, "cannot find playlist, destroying vout" );
- vlc_object_detach( p_vout );
- vout_Destroy( p_vout );
- }
+ playlist_t *p_playlist = pl_Yield( p_this );
+ spu_Attach( p_vout->p_spu, p_this, VLC_FALSE );
+ vlc_object_detach( p_vout );
+ vlc_object_attach( p_vout, p_playlist );
+ pl_Release( p_this );
}
return NULL;
}
if( !p_vout )
{
- playlist_t *p_playlist;
-
- p_playlist = vlc_object_find( p_this,
- VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
- if( p_playlist )
+ playlist_t *p_playlist = pl_Yield( p_this );
+ vlc_mutex_lock( &p_playlist->gc_lock );
+ p_vout = vlc_object_find( p_playlist,
+ VLC_OBJECT_VOUT, FIND_CHILD );
+ /* only first children of p_input for unused vout */
+ if( p_vout && p_vout->p_parent != (vlc_object_t *)p_playlist )
{
- vlc_mutex_lock( &p_playlist->gc_lock );
- p_vout = vlc_object_find( p_playlist,
- VLC_OBJECT_VOUT, FIND_CHILD );
- /* only first children of p_input for unused vout */
- if( p_vout && p_vout->p_parent != (vlc_object_t *)p_playlist )
- {
- vlc_object_release( p_vout );
- p_vout = NULL;
- }
- vlc_mutex_unlock( &p_playlist->gc_lock );
- vlc_object_release( p_playlist );
+ vlc_object_release( p_vout );
+ p_vout = NULL;
}
+ if( p_vout )
+ vlc_object_detach( p_vout ); /* Remove it from the GC */
+ vlc_mutex_unlock( &p_playlist->gc_lock );
+ pl_Release( p_this );
}
}
p_vout->b_filter_change )
{
/* We are not interested in this format, close this vout */
- vlc_object_detach( p_vout );
vlc_object_release( p_vout );
vout_Destroy( p_vout );
p_vout = NULL;
else
{
/* This video output is cool! Hijack it. */
- vlc_object_detach( p_vout );
spu_Attach( p_vout->p_spu, p_this, VLC_TRUE );
vlc_object_attach( p_vout, p_this );
vlc_object_release( p_vout );
/* Initialize locks */
vlc_mutex_init( p_vout, &p_vout->picture_lock );
vlc_mutex_init( p_vout, &p_vout->change_lock );
+ vlc_mutex_init( p_vout, &p_vout->vfilter_lock );
/* Mouse coordinates */
var_Create( p_vout, "mouse-x", VLC_VAR_INTEGER );
var_Create( p_vout, "deinterlace", VLC_VAR_STRING | VLC_VAR_HASCHOICE );
text.psz_string = _("Deinterlace");
var_Change( p_vout, "deinterlace", VLC_VAR_SETTEXT, &text, NULL );
- val.psz_string = ""; text.psz_string = _("Disable");
+ val.psz_string = (char *)""; text.psz_string = _("Disable");
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
- val.psz_string = "discard"; text.psz_string = _("Discard");
+ val.psz_string = (char *)"discard"; text.psz_string = _("Discard");
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
- val.psz_string = "blend"; text.psz_string = _("Blend");
+ val.psz_string = (char *)"blend"; text.psz_string = _("Blend");
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
- val.psz_string = "mean"; text.psz_string = _("Mean");
+ val.psz_string = (char *)"mean"; text.psz_string = _("Mean");
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
- val.psz_string = "bob"; text.psz_string = _("Bob");
+ val.psz_string = (char *)"bob"; text.psz_string = _("Bob");
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
- val.psz_string = "linear"; text.psz_string = _("Linear");
+ val.psz_string = (char *)"linear"; text.psz_string = _("Linear");
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
- val.psz_string = "x"; text.psz_string = "X";
+ val.psz_string = (char *)"x"; text.psz_string = (char *)"X";
var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
if( var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS )
*****************************************************************************/
void vout_Destroy( vout_thread_t *p_vout )
{
- vlc_object_t *p_playlist;
+ vout_thread_t *p_another_vout;
+ playlist_t *p_playlist = pl_Yield( p_vout );
/* Request thread destruction */
p_vout->b_die = VLC_TRUE;
var_Destroy( p_vout, "intf-change" );
- p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
-
if( p_vout->psz_filter_chain ) free( p_vout->psz_filter_chain );
/* Free structure */
vlc_object_destroy( p_vout );
-
- /* If it was the last vout, tell the interface to show up */
- if( p_playlist != NULL )
+#ifndef __APPLE__
+ /* This is a dirty hack for mostly Linux, where there is no way to get the GUI
+ back if you closed it while playing video. This is solved in Mac OS X,
+ where we have this novelty called menubar, that will always allow you access
+ to the applications main functionality. They should try that on linux sometime */
+ p_another_vout = vlc_object_find( p_playlist,
+ VLC_OBJECT_VOUT, FIND_ANYWHERE );
+ if( p_another_vout == NULL )
{
- vout_thread_t *p_another_vout = vlc_object_find( p_playlist,
- VLC_OBJECT_VOUT, FIND_ANYWHERE );
- if( p_another_vout == NULL )
- {
- vlc_value_t val;
- val.b_bool = VLC_TRUE;
- var_Set( p_playlist, "intf-show", val );
- }
- else
- {
- vlc_object_release( p_another_vout );
- }
- vlc_object_release( p_playlist );
+ vlc_value_t val;
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-show", val );
+ }
+ else
+ {
+ vlc_object_release( p_another_vout );
}
+#endif
+ vlc_object_release( p_playlist );
}
/*****************************************************************************
subpicture_t * p_subpic = NULL; /* subpicture pointer */
- input_thread_t *p_input = NULL ; /* Parent input, if it exists */
+ input_thread_t *p_input = NULL ; /* Parent input, if it exists */
vlc_value_t val;
vlc_bool_t b_drop_late;
display_date = 0;
current_date = mdate();
+ if( p_input && p_input->b_die )
+ {
+ vlc_object_release( p_input );
+ p_input = NULL;
+ }
+
i_loops++;
if( i_loops % 20 == 0 )
{
- p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
+ if( !p_input )
+ {
+ p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
+ FIND_PARENT );
+ }
if( p_input )
{
- vlc_mutex_lock( &p_input->counters.counters_lock );
- stats_UpdateInteger( p_vout, p_input->counters.p_lost_pictures,
+ vlc_mutex_lock( &p_input->p->counters.counters_lock );
+ stats_UpdateInteger( p_vout, p_input->p->counters.p_lost_pictures,
i_lost , NULL);
stats_UpdateInteger( p_vout,
- p_input->counters.p_displayed_pictures,
+ p_input->p->counters.p_displayed_pictures,
i_displayed , NULL);
i_displayed = i_lost = 0;
- vlc_mutex_unlock( &p_input->counters.counters_lock );
- vlc_object_release( p_input );
+ vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
}
#if 0
if( p_vout->b_vfilter_change == VLC_TRUE )
{
int i;
+ vlc_mutex_lock( &p_vout->vfilter_lock );
RemoveVideoFilters2( p_vout );
for( i = 0; i < p_vout->i_vfilters_cfg; i++ )
{
p_vfilter->pf_vout_buffer_new = video_new_buffer_filter;
p_vfilter->pf_vout_buffer_del = video_del_buffer_filter;
- p_vfilter->fmt_in.video = p_vout->fmt_render;
+ if( !p_vout->i_vfilters )
+ {
+ p_vfilter->fmt_in.video = p_vout->fmt_render;
+ }
+ else
+ {
+ p_vfilter->fmt_in.video = (p_vfilter-1)->fmt_out.video;
+ }
+ /* TODO: one day filters in the middle of the chain might
+ * have a different fmt_out.video than fmt_render ... */
p_vfilter->fmt_out.video = p_vout->fmt_render;
p_vfilter->p_cfg = p_vout->p_vfilters_cfg[i];
}
}
p_vout->b_vfilter_change = VLC_FALSE;
+ vlc_mutex_unlock( &p_vout->vfilter_lock );
}
if( p_picture )
*/
if( display_date > 0 )
{
- p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date );
+ if( !p_input )
+ {
+ p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
+ FIND_PARENT );
+ }
+ p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date,
+ p_input ? var_GetBool( p_input, "state" ) == PAUSE_S : VLC_FALSE );
}
/*
}
}
+ if( p_input )
+ {
+ vlc_object_release( p_input );
+ }
+
/*
* Error loop - wait until the thread destruction is requested
*/
/* Destroy the locks */
vlc_mutex_destroy( &p_vout->picture_lock );
vlc_mutex_destroy( &p_vout->change_lock );
+ vlc_mutex_destroy( &p_vout->vfilter_lock );
/* Release the module */
if( p_vout && p_vout->p_module )
int i;
for( i = 0; i < p_vout->i_vfilters_cfg; i++ )
{
- /* FIXME: this should be moved in a separate function */
- struct sout_cfg_t *p_cfg =
+ struct config_chain_t *p_cfg =
p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg];
- while( p_cfg )
+ config_ChainDestroy( p_cfg );
+ if( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] )
{
- struct sout_cfg_t *p_next = p_cfg->p_next;
- free( p_cfg->psz_name );
- free( p_cfg->psz_value );
- free( p_cfg );
- p_cfg = p_next;
+ free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );
+ p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL;
}
- /* </FIXME> */
-
- free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );
}
p_vout->i_vfilters_cfg = 0;
if( psz_vfilters && *psz_vfilters )
while( psz_parser && *psz_parser )
{
- psz_parser = sout_CfgCreate(
+ psz_parser = config_ChainCreate(
&p_vout->psz_vfilters[p_vout->i_vfilters_cfg],
&p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg],
psz_parser );
- msg_Dbg( p_vout, "adding vfilter: %s\n",
+ msg_Dbg( p_vout, "adding vfilter: %s",
p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );
p_vout->i_vfilters_cfg++;
- if( psz_parser && psz_parser )
+ if( psz_parser && *psz_parser )
{
if( p_vout->i_vfilters_cfg == MAX_VFILTERS )
{
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
- if( !strcmp( oldval.psz_string, newval.psz_string ) )
- {
- ParseVideoFilter2Chain( p_vout, newval.psz_string );
- p_vout->b_vfilter_change = VLC_TRUE;
- }
+ vlc_mutex_lock( &p_vout->vfilter_lock );
+ ParseVideoFilter2Chain( p_vout, newval.psz_string );
+ p_vout->b_vfilter_change = VLC_TRUE;
+ vlc_mutex_unlock( &p_vout->vfilter_lock );
return VLC_SUCCESS;
}