* Local prototypes
*****************************************************************************/
static int InitThread ( vout_thread_t * );
-static void RunThread ( vout_thread_t * );
+static void* RunThread ( vlc_object_t * );
static void ErrorThread ( vout_thread_t * );
static void CleanThread ( vout_thread_t * );
static void EndThread ( vout_thread_t * );
static void AspectRatio ( int, int *, int * );
-static int BinaryLog ( uint32_t );
-static void MaskToShift ( int *, int *, uint32_t );
+
+static void VideoFormatImportRgb( video_format_t *, const picture_heap_t * );
+static void PictureHeapFixRgb( picture_heap_t * );
static void vout_Destructor ( vlc_object_t * p_this );
p_vout->b_filter_change )
{
/* We are not interested in this format, close this vout */
- vlc_object_release( p_vout );
+ vout_CloseAndRelease( p_vout );
vlc_object_release( p_vout );
p_vout = NULL;
}
}
/* Create the vout thread */
- config_ChainCreate( &psz_name, &p_cfg, psz_parser );
+ char* psz_tmp = config_ChainCreate( &psz_name, &p_cfg, psz_parser );
free( psz_parser );
+ free( psz_tmp );
p_vout->p_cfg = p_cfg;
p_vout->p_module = module_Need( p_vout,
( p_vout->psz_filter_chain && *p_vout->psz_filter_chain ) ?
vlc_object_kill( p_vout );
vlc_thread_join( p_vout );
module_Unneed( p_vout, p_vout->p_module );
+ p_vout->p_module = NULL;
}
/* */
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
+ /* Make sure the vout was stopped first */
+ assert( !p_vout->p_module );
+
/* Destroy the locks */
vlc_mutex_destroy( &p_vout->picture_lock );
vlc_mutex_destroy( &p_vout->change_lock );
*****************************************************************************/
static int ChromaCreate( vout_thread_t *p_vout );
static void ChromaDestroy( vout_thread_t *p_vout );
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture );
static int InitThread( vout_thread_t *p_vout )
{
i_aspect_x, i_aspect_y,
p_vout->fmt_out.i_sar_num, p_vout->fmt_out.i_sar_den );
+ /* FIXME removed the need of both fmt_* and heap infos */
/* Calculate shifts from system-updated masks */
- MaskToShift( &p_vout->render.i_lrshift, &p_vout->output.i_rrshift,
- p_vout->render.i_rmask );
- MaskToShift( &p_vout->render.i_lgshift, &p_vout->output.i_rgshift,
- p_vout->render.i_gmask );
- MaskToShift( &p_vout->render.i_lbshift, &p_vout->output.i_rbshift,
- p_vout->render.i_bmask );
-
- MaskToShift( &p_vout->output.i_lrshift, &p_vout->output.i_rrshift,
- p_vout->output.i_rmask );
- MaskToShift( &p_vout->output.i_lgshift, &p_vout->output.i_rgshift,
- p_vout->output.i_gmask );
- MaskToShift( &p_vout->output.i_lbshift, &p_vout->output.i_rbshift,
- p_vout->output.i_bmask );
+ PictureHeapFixRgb( &p_vout->render );
+ VideoFormatImportRgb( &p_vout->fmt_render, &p_vout->render );
+
+ PictureHeapFixRgb( &p_vout->output );
+ VideoFormatImportRgb( &p_vout->fmt_out, &p_vout->output );
/* Check whether we managed to create direct buffers similar to
* the render buffers, ie same size and chroma */
* terminated. It handles the pictures arriving in the video heap and the
* display device events.
*****************************************************************************/
-static void RunThread( vout_thread_t *p_vout)
+static void* RunThread( vlc_object_t *p_this )
{
+ vout_thread_t *p_vout = (vout_thread_t *)p_this;
int i_index; /* index in heap */
int i_idle_loops = 0; /* loops without displaying a picture */
mtime_t current_date; /* current date */
{
EndThread( p_vout );
vlc_mutex_unlock( &p_vout->change_lock );
- return;
+ return NULL;
}
vlc_object_lock( p_vout );
* Main loop - it is not executed if an error occurred during
* initialization
*/
- while( (vlc_object_alive( p_vout )) && (!p_vout->b_error) )
+ while( vlc_object_alive( p_vout ) && !p_vout->b_error )
{
/* Initialize loop variables */
p_picture = NULL;
current_date = mdate();
i_loops++;
- if( !p_input )
- {
- p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
- FIND_PARENT );
- }
- if( p_input )
- {
- 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->p->counters.p_displayed_pictures,
- i_displayed , NULL);
- i_displayed = i_lost = 0;
- vlc_mutex_unlock( &p_input->p->counters.counters_lock );
- vlc_object_release( p_input );
- p_input = NULL;
- }
+ if( !p_input )
+ {
+ p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
+ FIND_PARENT );
+ }
+ if( p_input )
+ {
+ 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->p->counters.p_displayed_pictures,
+ i_displayed , NULL);
+ i_displayed = i_lost = 0;
+ vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+ vlc_object_release( p_input );
+ p_input = NULL;
+ }
#if 0
p_vout->c_loops++;
if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
/* If we found better than the last picture, destroy it */
if( p_last_picture && p_picture != p_last_picture )
{
- vlc_mutex_lock( &p_vout->picture_lock );
- if( p_last_picture->i_refcount )
- {
- p_last_picture->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- p_last_picture->i_status = DESTROYED_PICTURE;
- p_vout->i_heap_size--;
- }
- vlc_mutex_unlock( &p_vout->picture_lock );
+ DropPicture( p_vout, p_last_picture );
p_last_picture = NULL;
}
{
/* Picture is late: it will be destroyed and the thread
* will directly choose the next picture */
- vlc_mutex_lock( &p_vout->picture_lock );
- if( p_picture->i_refcount )
- {
- /* Pretend we displayed the picture, but don't destroy
- * it since the decoder might still need it. */
- p_picture->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- /* Destroy the picture without displaying it */
- p_picture->i_status = DESTROYED_PICTURE;
- p_vout->i_heap_size--;
- }
+ DropPicture( p_vout, p_picture );
+ i_lost++;
msg_Warn( p_vout, "late picture skipped (%"PRId64")",
current_date - display_date );
- i_lost++;
- vlc_mutex_unlock( &p_vout->picture_lock );
-
continue;
}
current_date + p_vout->i_pts_delay + VOUT_BOGUS_DELAY )
{
/* Picture is waaay too early: it will be destroyed */
- vlc_mutex_lock( &p_vout->picture_lock );
- if( p_picture->i_refcount )
- {
- /* Pretend we displayed the picture, but don't destroy
- * it since the decoder might still need it. */
- p_picture->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- /* Destroy the picture without displaying it */
- p_picture->i_status = DESTROYED_PICTURE;
- p_vout->i_heap_size--;
- }
+ DropPicture( p_vout, p_picture );
i_lost++;
msg_Warn( p_vout, "vout warning: early picture skipped "
"(%"PRId64")", display_date - current_date
- p_vout->i_pts_delay );
- vlc_mutex_unlock( &p_vout->picture_lock );
-
continue;
}
vlc_mutex_unlock( &p_vout->change_lock );
vlc_object_unlock( p_vout );
+ return NULL;
}
/*****************************************************************************
return p_pic;
}
-static void ChromaCopyRgbInfo( es_format_t *p_fmt, picture_heap_t *p_heap )
-{
- p_fmt->video.i_rmask = p_heap->i_rmask;
- p_fmt->video.i_gmask = p_heap->i_gmask;
- p_fmt->video.i_bmask = p_heap->i_bmask;
- p_fmt->video.i_rrshift = p_heap->i_rrshift;
- p_fmt->video.i_lrshift = p_heap->i_lrshift;
- p_fmt->video.i_rgshift = p_heap->i_rgshift;
- p_fmt->video.i_lgshift = p_heap->i_lgshift;
- p_fmt->video.i_rbshift = p_heap->i_rbshift;
- p_fmt->video.i_lbshift = p_heap->i_lbshift;
-}
-
static int ChromaCreate( vout_thread_t *p_vout )
{
static const char typename[] = "chroma";
/* TODO: Set the fmt_in and fmt_out stuff here */
p_chroma->fmt_in.video = p_vout->fmt_render;
p_chroma->fmt_out.video = p_vout->fmt_out;
- ChromaCopyRgbInfo( &p_chroma->fmt_in, &p_vout->render );
- ChromaCopyRgbInfo( &p_chroma->fmt_out, &p_vout->output );
+ VideoFormatImportRgb( &p_chroma->fmt_in.video, &p_vout->render );
+ VideoFormatImportRgb( &p_chroma->fmt_out.video, &p_vout->output );
p_chroma->p_module = module_Need( p_chroma, "video filter2", NULL, 0 );
p_vout->p_chroma = NULL;
}
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture )
+{
+ vlc_mutex_lock( &p_vout->picture_lock );
+ if( p_picture->i_refcount )
+ {
+ /* Pretend we displayed the picture, but don't destroy
+ * it since the decoder might still need it. */
+ p_picture->i_status = DISPLAYED_PICTURE;
+ }
+ else
+ {
+ /* Destroy the picture without displaying it */
+ p_picture->i_status = DESTROYED_PICTURE;
+ p_vout->i_heap_size--;
+ }
+ vlc_mutex_unlock( &p_vout->picture_lock );
+}
+
/* following functions are local */
*i_aspect_y = VOUT_ASPECT_FACTOR / i_pgcd;
}
-/*****************************************************************************
- * BinaryLog: computes the base 2 log of a binary value
- *****************************************************************************
- * This functions is used by MaskToShift, to get a bit index from a binary
- * value.
- *****************************************************************************/
-static int BinaryLog( uint32_t i )
+/**
+ * This function copies all RGB informations from a picture_heap_t into
+ * a video_format_t
+ */
+static void VideoFormatImportRgb( video_format_t *p_fmt, const picture_heap_t *p_heap )
{
- int i_log = 0;
-
- if( i == 0 ) return -31337;
-
- if( i & 0xffff0000 ) i_log += 16;
- if( i & 0xff00ff00 ) i_log += 8;
- if( i & 0xf0f0f0f0 ) i_log += 4;
- if( i & 0xcccccccc ) i_log += 2;
- if( i & 0xaaaaaaaa ) i_log += 1;
-
- return i_log;
+ p_fmt->i_rmask = p_heap->i_rmask;
+ p_fmt->i_gmask = p_heap->i_gmask;
+ p_fmt->i_bmask = p_heap->i_bmask;
+ p_fmt->i_rrshift = p_heap->i_rrshift;
+ p_fmt->i_lrshift = p_heap->i_lrshift;
+ p_fmt->i_rgshift = p_heap->i_rgshift;
+ p_fmt->i_lgshift = p_heap->i_lgshift;
+ p_fmt->i_rbshift = p_heap->i_rbshift;
+ p_fmt->i_lbshift = p_heap->i_lbshift;
}
-/*****************************************************************************
- * MaskToShift: transform a color mask into right and left shifts
- *****************************************************************************
- * This function is used for obtaining color shifts from masks.
- *****************************************************************************/
-static void MaskToShift( int *pi_left, int *pi_right, uint32_t i_mask )
+/**
+ * This funtion copes all RGB informations from a video_format_t into
+ * a picture_heap_t
+ */
+static void VideoFormatExportRgb( const video_format_t *p_fmt, picture_heap_t *p_heap )
{
- uint32_t i_low, i_high; /* lower hand higher bits of the mask */
-
- if( !i_mask )
- {
- *pi_left = *pi_right = 0;
- return;
- }
+ p_heap->i_rmask = p_fmt->i_rmask;
+ p_heap->i_gmask = p_fmt->i_gmask;
+ p_heap->i_bmask = p_fmt->i_bmask;
+ p_heap->i_rrshift = p_fmt->i_rrshift;
+ p_heap->i_lrshift = p_fmt->i_lrshift;
+ p_heap->i_rgshift = p_fmt->i_rgshift;
+ p_heap->i_lgshift = p_fmt->i_lgshift;
+ p_heap->i_rbshift = p_fmt->i_rbshift;
+ p_heap->i_lbshift = p_fmt->i_lbshift;
+}
- /* Get bits */
- i_low = i_high = i_mask;
+/**
+ * This function computes rgb shifts from masks
+ */
+static void PictureHeapFixRgb( picture_heap_t *p_heap )
+{
+ video_format_t fmt;
- i_low &= - (int32_t)i_low; /* lower bit of the mask */
- i_high += i_low; /* higher bit of the mask */
+ /* */
+ fmt.i_chroma = p_heap->i_chroma;
+ VideoFormatImportRgb( &fmt, p_heap );
- /* Transform bits into an index. Also deal with i_high overflow, which
- * is faster than changing the BinaryLog code to handle 64 bit integers. */
- i_low = BinaryLog (i_low);
- i_high = i_high ? BinaryLog (i_high) : 32;
+ /* */
+ video_format_FixRgb( &fmt );
- /* Update pointers and return */
- *pi_left = i_low;
- *pi_right = (8 - i_high + i_low);
+ VideoFormatExportRgb( &fmt, p_heap );
}
/*****************************************************************************
} suxor_thread_t;
-static void SuxorRestartVideoES( suxor_thread_t *p_this )
+static void* SuxorRestartVideoES( vlc_object_t * p_vlc_t )
{
+ suxor_thread_t *p_this = (suxor_thread_t *) p_vlc_t;
/* Now restart current video stream */
int val = var_GetInteger( p_this->p_input, "video-es" );
if( val >= 0 )
vlc_object_release( p_this->p_input );
vlc_object_release( p_this );
+ return NULL;
}
/*****************************************************************************
input_thread_t *p_input;
mtime_t i_now, i_stop;
+ if( !config_GetInt( p_vout, "osd" ) ) return;
+
p_input = (input_thread_t *)vlc_object_find( p_vout,
VLC_OBJECT_INPUT, FIND_ANYWHERE );
if( p_input )