Commit fd32a7c3 authored by Laurent Aimar's avatar Laurent Aimar

No functionnal changes (vout).

parent f0fe302b
...@@ -53,12 +53,8 @@ ...@@ -53,12 +53,8 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int InitThread ( vout_thread_t * ); static void *Thread(void *);
static void* RunThread ( void * ); static void vout_Destructor(vlc_object_t *);
static void CleanThread ( vout_thread_t * );
static void EndThread ( vout_thread_t * );
static void vout_Destructor ( vlc_object_t * p_this );
/* Object variables callbacks */ /* Object variables callbacks */
static int FilterCallback( vlc_object_t *, char const *, static int FilterCallback( vlc_object_t *, char const *,
...@@ -76,25 +72,24 @@ static int PostProcessCallback( vlc_object_t *, char const *, ...@@ -76,25 +72,24 @@ static int PostProcessCallback( vlc_object_t *, char const *,
static void DeinterlaceEnable( vout_thread_t * ); static void DeinterlaceEnable( vout_thread_t * );
static void DeinterlaceNeeded( vout_thread_t *, bool ); static void DeinterlaceNeeded( vout_thread_t *, bool );
/* From vout_intf.c */
int vout_Snapshot( vout_thread_t *, picture_t * );
/* Display media title in OSD */ /* Display media title in OSD */
static void DisplayTitleOnOSD( vout_thread_t *p_vout ); static void DisplayTitleOnOSD( vout_thread_t *p_vout );
/* Time during which the thread will sleep if it has nothing to /* */
* display (in micro-seconds) */ static void PrintVideoFormat(vout_thread_t *, const char *, const video_format_t *);
#define VOUT_IDLE_SLEEP ((int)(0.020*CLOCK_FREQ))
/* Maximum delay between 2 displayed pictures.
* XXX it is needed for now but should be removed in the long term.
*/
#define VOUT_REDISPLAY_DELAY (INT64_C(80000))
/* Maximum lap of time allowed between the beginning of rendering and /**
* display. If, compared to the current date, the next image is too * Late pictures having a delay higher than this value are thrashed.
* late, the thread will perform an idle loop. This time should be */
* at least VOUT_IDLE_SLEEP plus the time required to render a few #define VOUT_DISPLAY_LATE_THRESHOLD (INT64_C(20000))
* images, to avoid trashing of decoded images */
#define VOUT_DISPLAY_DELAY ((int)(0.200*CLOCK_FREQ))
/* Better be in advance when awakening than late... */ /* Better be in advance when awakening than late... */
#define VOUT_MWAIT_TOLERANCE ((mtime_t)(0.020*CLOCK_FREQ)) #define VOUT_MWAIT_TOLERANCE (INT64_C(1000))
/***************************************************************************** /*****************************************************************************
* Video Filter2 functions * Video Filter2 functions
...@@ -107,7 +102,7 @@ static picture_t *video_new_buffer_filter( filter_t *p_filter ) ...@@ -107,7 +102,7 @@ static picture_t *video_new_buffer_filter( filter_t *p_filter )
static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic ) static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
{ {
vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner; VLC_UNUSED(p_filter);
picture_Release(p_pic); picture_Release(p_pic);
} }
...@@ -247,14 +242,13 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, ...@@ -247,14 +242,13 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
return p_vout; return p_vout;
} }
#undef vout_Create
/***************************************************************************** /*****************************************************************************
* vout_Create: creates a new video output thread * vout_Create: creates a new video output thread
***************************************************************************** *****************************************************************************
* This function creates a new video output thread, and returns a pointer * This function creates a new video output thread, and returns a pointer
* to its description. On error, it returns NULL. * to its description. On error, it returns NULL.
*****************************************************************************/ *****************************************************************************/
vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
{ {
vout_thread_t *p_vout; /* thread descriptor */ vout_thread_t *p_vout; /* thread descriptor */
vlc_value_t text; vlc_value_t text;
...@@ -303,21 +297,23 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -303,21 +297,23 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
vout_chrono_Init( &p_vout->p->render, 5, 10000 ); /* Arbitrary initial time */ vout_chrono_Init( &p_vout->p->render, 5, 10000 ); /* Arbitrary initial time */
vout_statistic_Init( &p_vout->p->statistic ); vout_statistic_Init( &p_vout->p->statistic );
p_vout->p->b_filter_change = 0; p_vout->p->b_filter_change = 0;
p_vout->p->b_paused = false;
p_vout->p->i_pause_date = 0;
p_vout->p->i_par_num = p_vout->p->i_par_num =
p_vout->p->i_par_den = 1; p_vout->p->i_par_den = 1;
p_vout->p->is_late_dropped = var_InheritBool( p_vout, "drop-late-frames" ); p_vout->p->is_late_dropped = var_InheritBool( p_vout, "drop-late-frames" );
p_vout->p->b_picture_empty = false; p_vout->p->b_picture_empty = false;
p_vout->p->displayed.clock = VLC_TS_INVALID; p_vout->p->displayed.date = VLC_TS_INVALID;
p_vout->p->displayed.decoded = NULL; p_vout->p->displayed.decoded = NULL;
p_vout->p->displayed.timestampX = VLC_TS_INVALID; p_vout->p->displayed.timestamp = VLC_TS_INVALID;
p_vout->p->displayed.qtype = QTYPE_NONE; p_vout->p->displayed.qtype = QTYPE_NONE;
p_vout->p->displayed.is_interlaced = false; p_vout->p->displayed.is_interlaced = false;
p_vout->p->step.is_requested = false; p_vout->p->step.is_requested = false;
p_vout->p->step.last = VLC_TS_INVALID; p_vout->p->step.last = VLC_TS_INVALID;
p_vout->p->step.timestamp = VLC_TS_INVALID; p_vout->p->step.timestamp = VLC_TS_INVALID;
p_vout->p->pause.is_on = false;
p_vout->p->pause.date = VLC_TS_INVALID;
p_vout->p->decoder_fifo = picture_fifo_New(); p_vout->p->decoder_fifo = picture_fifo_New();
p_vout->p->decoder_pool = NULL; p_vout->p->decoder_pool = NULL;
...@@ -400,7 +396,7 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -400,7 +396,7 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
else else
{ {
psz_parser = strdup( p_vout->p->psz_filter_chain ); psz_parser = strdup( p_vout->p->psz_filter_chain );
p_vout->p->b_title_show = false; p_vout->p->title.show = false;
} }
/* Create the vout thread */ /* Create the vout thread */
...@@ -433,7 +429,7 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -433,7 +429,7 @@ vout_thread_t * vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
/* */ /* */
vlc_cond_init( &p_vout->p->change_wait ); vlc_cond_init( &p_vout->p->change_wait );
if( vlc_clone( &p_vout->p->thread, RunThread, p_vout, if( vlc_clone( &p_vout->p->thread, Thread, p_vout,
VLC_THREAD_PRIORITY_OUTPUT ) ) VLC_THREAD_PRIORITY_OUTPUT ) )
{ {
spu_Attach( p_vout->p->p_spu, VLC_OBJECT(p_vout), false ); spu_Attach( p_vout->p->p_spu, VLC_OBJECT(p_vout), false );
...@@ -519,7 +515,7 @@ static void vout_Destructor( vlc_object_t * p_this ) ...@@ -519,7 +515,7 @@ static void vout_Destructor( vlc_object_t * p_this )
/* */ /* */
free( p_vout->p->psz_filter_chain ); free( p_vout->p->psz_filter_chain );
free( p_vout->p->psz_title ); free( p_vout->p->title.value );
config_ChainDestroy( p_vout->p->p_cfg ); config_ChainDestroy( p_vout->p->p_cfg );
...@@ -532,13 +528,13 @@ void vout_ChangePause( vout_thread_t *p_vout, bool b_paused, mtime_t i_date ) ...@@ -532,13 +528,13 @@ void vout_ChangePause( vout_thread_t *p_vout, bool b_paused, mtime_t i_date )
{ {
vlc_mutex_lock( &p_vout->p->change_lock ); vlc_mutex_lock( &p_vout->p->change_lock );
assert( !p_vout->p->b_paused || !b_paused ); assert( !p_vout->p->pause.is_on || !b_paused );
vlc_mutex_lock( &p_vout->p->picture_lock ); vlc_mutex_lock( &p_vout->p->picture_lock );
if( p_vout->p->b_paused ) if( p_vout->p->pause.is_on )
{ {
const mtime_t i_duration = i_date - p_vout->p->i_pause_date; const mtime_t i_duration = i_date - p_vout->p->pause.date;
if (p_vout->p->step.timestamp > VLC_TS_INVALID) if (p_vout->p->step.timestamp > VLC_TS_INVALID)
p_vout->p->step.timestamp += i_duration; p_vout->p->step.timestamp += i_duration;
...@@ -559,8 +555,8 @@ void vout_ChangePause( vout_thread_t *p_vout, bool b_paused, mtime_t i_date ) ...@@ -559,8 +555,8 @@ void vout_ChangePause( vout_thread_t *p_vout, bool b_paused, mtime_t i_date )
p_vout->p->step.last = p_vout->p->step.timestamp; p_vout->p->step.last = p_vout->p->step.timestamp;
vlc_mutex_unlock( &p_vout->p->picture_lock ); vlc_mutex_unlock( &p_vout->p->picture_lock );
} }
p_vout->p->b_paused = b_paused; p_vout->p->pause.is_on = b_paused;
p_vout->p->i_pause_date = i_date; p_vout->p->pause.date = i_date;
vlc_mutex_unlock( &p_vout->p->change_lock ); vlc_mutex_unlock( &p_vout->p->change_lock );
} }
...@@ -673,8 +669,8 @@ void vout_DisplayTitle( vout_thread_t *p_vout, const char *psz_title ) ...@@ -673,8 +669,8 @@ void vout_DisplayTitle( vout_thread_t *p_vout, const char *psz_title )
return; return;
vlc_mutex_lock( &p_vout->p->change_lock ); vlc_mutex_lock( &p_vout->p->change_lock );
free( p_vout->p->psz_title ); free( p_vout->p->title.value );
p_vout->p->psz_title = strdup( psz_title ); p_vout->p->title.value = strdup( psz_title );
vlc_mutex_unlock( &p_vout->p->change_lock ); vlc_mutex_unlock( &p_vout->p->change_lock );
} }
...@@ -686,75 +682,48 @@ spu_t *vout_GetSpu( vout_thread_t *p_vout ) ...@@ -686,75 +682,48 @@ spu_t *vout_GetSpu( vout_thread_t *p_vout )
/***************************************************************************** /*****************************************************************************
* InitThread: initialize video output thread * InitThread: initialize video output thread
***************************************************************************** *****************************************************************************
* This function is called from RunThread and performs the second step of the * This function is called from Thread and performs the second step of the
* initialization. It returns 0 on success. Note that the thread's flag are not * initialization. It returns 0 on success. Note that the thread's flag are not
* modified inside this function. * modified inside this function.
* XXX You have to enter it with change_lock taken. * XXX You have to enter it with change_lock taken.
*****************************************************************************/ *****************************************************************************/
static int InitThread( vout_thread_t *p_vout ) static int ThreadInit(vout_thread_t *vout)
{ {
int i;
/* Initialize output method, it allocates direct buffers for us */ /* Initialize output method, it allocates direct buffers for us */
if( vout_InitWrapper( p_vout ) ) if (vout_InitWrapper(vout))
return VLC_EGENERIC; return VLC_EGENERIC;
assert(vout->p->decoder_pool);
p_vout->p->displayed.decoded = NULL; vout->p->displayed.decoded = NULL;
assert( p_vout->fmt_out.i_width > 0 && p_vout->fmt_out.i_height > 0 );
if( !p_vout->fmt_out.i_sar_num || !p_vout->fmt_out.i_sar_num )
{
/* FIXME is it possible to end up here ? */
p_vout->fmt_out.i_sar_num = 1;
p_vout->fmt_out.i_sar_den = 1;
}
vlc_ureduce( &p_vout->fmt_out.i_sar_num, &p_vout->fmt_out.i_sar_den,
p_vout->fmt_out.i_sar_num, p_vout->fmt_out.i_sar_den, 0 );
/* FIXME removed the need of both fmt_* and heap infos */
/* Calculate shifts from system-updated masks */
video_format_FixRgb( &p_vout->fmt_render );
video_format_FixRgb( &p_vout->fmt_out );
/* print some usefull debug info about different vout formats /* print some usefull debug info about different vout formats
*/ */
msg_Dbg( p_vout, "pic render sz %ix%i, of (%i,%i), vsz %ix%i, 4cc %4.4s, sar %i:%i, msk r0x%x g0x%x b0x%x", PrintVideoFormat(vout, "pic render", &vout->fmt_render);
p_vout->fmt_render.i_width, p_vout->fmt_render.i_height, PrintVideoFormat(vout, "pic in", &vout->fmt_in);
p_vout->fmt_render.i_x_offset, p_vout->fmt_render.i_y_offset, PrintVideoFormat(vout, "pic out", &vout->fmt_out);
p_vout->fmt_render.i_visible_width,
p_vout->fmt_render.i_visible_height,
(char*)&p_vout->fmt_render.i_chroma,
p_vout->fmt_render.i_sar_num, p_vout->fmt_render.i_sar_den,
p_vout->fmt_render.i_rmask, p_vout->fmt_render.i_gmask, p_vout->fmt_render.i_bmask );
msg_Dbg( p_vout, "pic in sz %ix%i, of (%i,%i), vsz %ix%i, 4cc %4.4s, sar %i:%i, msk r0x%x g0x%x b0x%x",
p_vout->fmt_in.i_width, p_vout->fmt_in.i_height,
p_vout->fmt_in.i_x_offset, p_vout->fmt_in.i_y_offset,
p_vout->fmt_in.i_visible_width,
p_vout->fmt_in.i_visible_height,
(char*)&p_vout->fmt_in.i_chroma,
p_vout->fmt_in.i_sar_num, p_vout->fmt_in.i_sar_den,
p_vout->fmt_in.i_rmask, p_vout->fmt_in.i_gmask, p_vout->fmt_in.i_bmask );
msg_Dbg( p_vout, "pic out sz %ix%i, of (%i,%i), vsz %ix%i, 4cc %4.4s, sar %i:%i, msk r0x%x g0x%x b0x%x",
p_vout->fmt_out.i_width, p_vout->fmt_out.i_height,
p_vout->fmt_out.i_x_offset, p_vout->fmt_out.i_y_offset,
p_vout->fmt_out.i_visible_width,
p_vout->fmt_out.i_visible_height,
(char*)&p_vout->fmt_out.i_chroma,
p_vout->fmt_out.i_sar_num, p_vout->fmt_out.i_sar_den,
p_vout->fmt_out.i_rmask, p_vout->fmt_out.i_gmask, p_vout->fmt_out.i_bmask );
assert( p_vout->fmt_out.i_width == p_vout->fmt_render.i_width &&
p_vout->fmt_out.i_height == p_vout->fmt_render.i_height &&
p_vout->fmt_out.i_chroma == p_vout->fmt_render.i_chroma );
assert( p_vout->p->decoder_pool );
assert(vout->fmt_out.i_width == vout->fmt_render.i_width &&
vout->fmt_out.i_height == vout->fmt_render.i_height &&
vout->fmt_out.i_chroma == vout->fmt_render.i_chroma);
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* CleanThread: clean up after InitThread
*****************************************************************************
* This function is called after a sucessful
* initialization. It frees all resources allocated by InitThread.
* XXX You have to enter it with change_lock taken.
*****************************************************************************/
static void ThreadClean(vout_thread_t *vout)
{
/* Destroy translation tables */
if (!vout->p->b_error) {
picture_fifo_Flush(vout->p->decoder_fifo, INT64_MAX, false);
vout_EndWrapper(vout);
}
}
static int ThreadDisplayPicture(vout_thread_t *vout, static int ThreadDisplayPicture(vout_thread_t *vout,
bool now, mtime_t *deadline) bool now, mtime_t *deadline)
{ {
...@@ -763,7 +732,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -763,7 +732,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
for (;;) { for (;;) {
const mtime_t date = mdate(); const mtime_t date = mdate();
const bool is_paused = vout->p->b_paused; const bool is_paused = vout->p->pause.is_on;
bool redisplay = is_paused && !now; bool redisplay = is_paused && !now;
bool is_forced; bool is_forced;
...@@ -788,8 +757,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -788,8 +757,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
} }
if (redisplay) { if (redisplay) {
/* FIXME a better way for this delay is needed */ /* FIXME a better way for this delay is needed */
const mtime_t paused_display_period = 80000; const mtime_t date_update = vout->p->displayed.date + VOUT_REDISPLAY_DELAY;
const mtime_t date_update = vout->p->displayed.clock + paused_display_period;
if (date_update > date || !vout->p->displayed.decoded) { if (date_update > date || !vout->p->displayed.decoded) {
*deadline = vout->p->displayed.decoded ? date_update : VLC_TS_INVALID; *deadline = vout->p->displayed.decoded ? date_update : VLC_TS_INVALID;
break; break;
...@@ -798,6 +766,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -798,6 +766,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
is_forced = true; is_forced = true;
*deadline = date - vout_chrono_GetHigh(&vout->p->render); *deadline = date - vout_chrono_GetHigh(&vout->p->render);
} }
if (*deadline > VOUT_MWAIT_TOLERANCE)
*deadline -= VOUT_MWAIT_TOLERANCE;
/* If we are too early and can wait, do it */ /* If we are too early and can wait, do it */
if (date < *deadline && !now) if (date < *deadline && !now)
...@@ -814,9 +784,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -814,9 +784,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
const mtime_t predicted = date + vout_chrono_GetLow(&vout->p->render); const mtime_t predicted = date + vout_chrono_GetLow(&vout->p->render);
const mtime_t late = predicted - decoded->date; const mtime_t late = predicted - decoded->date;
if (late > 0) { if (late > 0) {
const mtime_t late_threshold = 20000; /* 20ms */
msg_Dbg(vout, "picture might be displayed late (missing %d ms)", (int)(late/1000)); msg_Dbg(vout, "picture might be displayed late (missing %d ms)", (int)(late/1000));
if (late > late_threshold) { if (late > VOUT_DISPLAY_LATE_THRESHOLD) {
msg_Warn(vout, "rejected picture because of render time"); msg_Warn(vout, "rejected picture because of render time");
/* TODO */ /* TODO */
picture_Release(decoded); picture_Release(decoded);
...@@ -829,7 +798,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -829,7 +798,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
vout->p->displayed.is_interlaced = !decoded->b_progressive; vout->p->displayed.is_interlaced = !decoded->b_progressive;
vout->p->displayed.qtype = decoded->i_qtype; vout->p->displayed.qtype = decoded->i_qtype;
} }
vout->p->displayed.timestampX = decoded->date; vout->p->displayed.timestamp = decoded->date;
/* */ /* */
if (vout->p->displayed.decoded) if (vout->p->displayed.decoded)
...@@ -855,8 +824,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -855,8 +824,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
*/ */
const bool do_snapshot = vout_snapshot_IsRequested(&vout->p->snapshot); const bool do_snapshot = vout_snapshot_IsRequested(&vout->p->snapshot);
mtime_t spu_render_time = is_forced ? mdate() : filtered->date; mtime_t spu_render_time = is_forced ? mdate() : filtered->date;
if (vout->p->b_paused) if (vout->p->pause.is_on)
spu_render_time = vout->p->i_pause_date; spu_render_time = vout->p->pause.date;
else else
spu_render_time = filtered->date > 1 ? filtered->date : mdate(); spu_render_time = filtered->date > 1 ? filtered->date : mdate();
...@@ -929,7 +898,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -929,7 +898,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
mwait(decoded->date); mwait(decoded->date);
/* Display the direct buffer returned by vout_RenderPicture */ /* Display the direct buffer returned by vout_RenderPicture */
vout->p->displayed.clock = mdate(); vout->p->displayed.date = mdate();
if (direct) if (direct)
vout_DisplayWrapper(vout, direct); vout_DisplayWrapper(vout, direct);
...@@ -944,13 +913,13 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -944,13 +913,13 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
} }
/***************************************************************************** /*****************************************************************************
* RunThread: video output thread * Thread: video output thread
***************************************************************************** *****************************************************************************
* Video output thread. This function does only returns when the thread is * Video output thread. This function does only returns when the thread is
* terminated. It handles the pictures arriving in the video heap and the * terminated. It handles the pictures arriving in the video heap and the
* display device events. * display device events.
*****************************************************************************/ *****************************************************************************/
static void *RunThread(void *object) static void *Thread(void *object)
{ {
vout_thread_t *vout = object; vout_thread_t *vout = object;
bool has_wrapper; bool has_wrapper;
...@@ -963,7 +932,7 @@ static void *RunThread(void *object) ...@@ -963,7 +932,7 @@ static void *RunThread(void *object)
vlc_mutex_lock(&vout->p->change_lock); vlc_mutex_lock(&vout->p->change_lock);
if (has_wrapper) if (has_wrapper)
vout->p->b_error = InitThread(vout); vout->p->b_error = ThreadInit(vout);
else else
vout->p->b_error = true; vout->p->b_error = true;
...@@ -985,7 +954,7 @@ static void *RunThread(void *object) ...@@ -985,7 +954,7 @@ static void *RunThread(void *object)
*/ */
while (!vout->p->b_done && !vout->p->b_error) { while (!vout->p->b_done && !vout->p->b_error) {
/* */ /* */
if(vout->p->b_title_show && vout->p->psz_title) if(vout->p->title.show && vout->p->title.value)
DisplayTitleOnOSD(vout); DisplayTitleOnOSD(vout);
vlc_mutex_lock(&vout->p->picture_lock); vlc_mutex_lock(&vout->p->picture_lock);
...@@ -994,7 +963,7 @@ static void *RunThread(void *object) ...@@ -994,7 +963,7 @@ static void *RunThread(void *object)
bool has_displayed = !ThreadDisplayPicture(vout, vout->p->step.is_requested, &deadline); bool has_displayed = !ThreadDisplayPicture(vout, vout->p->step.is_requested, &deadline);
if (has_displayed) { if (has_displayed) {
vout->p->step.timestamp = vout->p->displayed.timestampX; vout->p->step.timestamp = vout->p->displayed.timestamp;
if (vout->p->step.last <= VLC_TS_INVALID) if (vout->p->step.last <= VLC_TS_INVALID)
vout->p->step.last = vout->p->step.timestamp; vout->p->step.last = vout->p->step.timestamp;
} }
...@@ -1090,11 +1059,16 @@ static void *RunThread(void *object) ...@@ -1090,11 +1059,16 @@ static void *RunThread(void *object)
vlc_cond_wait(&vout->p->change_wait, &vout->p->change_lock); vlc_cond_wait(&vout->p->change_wait, &vout->p->change_lock);
/* Clean thread */ /* Clean thread */
CleanThread(vout); ThreadClean(vout);
exit_thread: exit_thread:
/* End of thread */ /* Detach subpicture unit from both input and vout */
EndThread(vout); spu_Attach(vout->p->p_spu, VLC_OBJECT(vout), false);
vlc_object_detach(vout->p->p_spu);
/* Destroy the video filters2 */
filter_chain_Delete(vout->p->p_vf2_chain);
vlc_mutex_unlock(&vout->p->change_lock); vlc_mutex_unlock(&vout->p->change_lock);
if (has_wrapper) if (has_wrapper)
...@@ -1103,44 +1077,6 @@ exit_thread: ...@@ -1103,44 +1077,6 @@ exit_thread:
return NULL; return NULL;
} }
/*****************************************************************************
* CleanThread: clean up after InitThread
*****************************************************************************
* This function is called after a sucessful
* initialization. It frees all resources allocated by InitThread.
* XXX You have to enter it with change_lock taken.
*****************************************************************************/
static void CleanThread( vout_thread_t *p_vout )
{
/* Destroy translation tables */
if( !p_vout->p->b_error )
{
picture_fifo_Flush( p_vout->p->decoder_fifo, INT64_MAX, false );
vout_EndWrapper( p_vout );
}
}
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
* This function is called when the thread ends.
* It frees all resources not allocated by InitThread.
* XXX You have to enter it with change_lock taken.
*****************************************************************************/
static void EndThread( vout_thread_t *p_vout )
{
/* FIXME does that function *really* need to be called inside the thread ? */
/* Detach subpicture unit from both input and vout */
spu_Attach( p_vout->p->p_spu, VLC_OBJECT(p_vout), false );
vlc_object_detach( p_vout->p->p_spu );
/* Destroy the video filters2 */
filter_chain_Delete( p_vout->p->p_vf2_chain );
}
/* following functions are local */
/***************************************************************************** /*****************************************************************************
* object variables callbacks: a bunch of object variables are used by the * object variables callbacks: a bunch of object variables are used by the
* interfaces to interact with the vout. * interfaces to interact with the vout.
...@@ -1299,7 +1235,7 @@ static void PostProcessSetFilterQuality( vout_thread_t *p_vout ) ...@@ -1299,7 +1235,7 @@ static void PostProcessSetFilterQuality( vout_thread_t *p_vout )
static void DisplayTitleOnOSD( vout_thread_t *p_vout ) static void DisplayTitleOnOSD( vout_thread_t *p_vout )
{ {
const mtime_t i_start = mdate(); const mtime_t i_start = mdate();
const mtime_t i_stop = i_start + INT64_C(1000) * p_vout->p->i_title_timeout; const mtime_t i_stop = i_start + INT64_C(1000) * p_vout->p->title.timeout;
if( i_stop <= i_start ) if( i_stop <= i_start )
return; return;
...@@ -1307,17 +1243,17 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout ) ...@@ -1307,17 +1243,17 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout )
vlc_assert_locked( &p_vout->p->change_lock ); vlc_assert_locked( &p_vout->p->change_lock );
vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,
p_vout->p->psz_title, NULL, p_vout->p->title.value, NULL,
p_vout->p->i_title_position, p_vout->p->title.position,
30 + p_vout->fmt_in.i_width 30 + p_vout->fmt_in.i_width
- p_vout->fmt_in.i_visible_width - p_vout->fmt_in.i_visible_width
- p_vout->fmt_in.i_x_offset, - p_vout->fmt_in.i_x_offset,
20 + p_vout->fmt_in.i_y_offset, 20 + p_vout->fmt_in.i_y_offset,
i_start, i_stop ); i_start, i_stop );
free( p_vout->p->psz_title ); free( p_vout->p->title.value );
p_vout->p->psz_title = NULL; p_vout->p->title.value = NULL;
} }
/***************************************************************************** /*****************************************************************************
...@@ -1617,3 +1553,17 @@ static void DeinterlaceNeeded( vout_thread_t *p_vout, bool is_interlaced ) ...@@ -1617,3 +1553,17 @@ static void DeinterlaceNeeded( vout_thread_t *p_vout, bool is_interlaced )
var_SetBool( p_vout, "deinterlace-needed", is_interlaced ); var_SetBool( p_vout, "deinterlace-needed", is_interlaced );
} }
/* */
static void PrintVideoFormat(vout_thread_t *vout,
const char *description,
const video_format_t *fmt)
{
msg_Dbg(vout, "%s sz %ix%i, of (%i,%i), vsz %ix%i, 4cc %4.4s, sar %i:%i, msk r0x%x g0x%x b0x%x",
description,
fmt->i_width, fmt->i_height, fmt->i_x_offset, fmt->i_y_offset,
fmt->i_visible_width, fmt->i_visible_height,
(char*)&fmt->i_chroma,
fmt->i_sar_num, fmt->i_sar_den,
fmt->i_rmask, fmt->i_gmask, fmt->i_bmask);
}
...@@ -66,18 +66,31 @@ struct vout_thread_sys_t ...@@ -66,18 +66,31 @@ struct vout_thread_sys_t
bool b_picture_empty; bool b_picture_empty;
vlc_cond_t picture_wait; vlc_cond_t picture_wait;
struct { struct {
mtime_t clock; mtime_t date;
mtime_t timestampX; mtime_t timestamp;
int qtype; int qtype;
bool is_interlaced; bool is_interlaced;
picture_t *decoded; picture_t *decoded;
} displayed; } displayed;
struct { struct {
bool is_requested; bool is_requested;
mtime_t last; mtime_t last;
mtime_t timestamp; mtime_t timestamp;
} step; } step;
struct {
bool is_on;
mtime_t date;
} pause;
struct {
bool show;
mtime_t timeout;
int position;
char *value;
} title;
/* */ /* */
vlc_mutex_t vfilter_lock; /**< video filter2 lock */ vlc_mutex_t vfilter_lock; /**< video filter2 lock */
...@@ -89,10 +102,6 @@ struct vout_thread_sys_t ...@@ -89,10 +102,6 @@ struct vout_thread_sys_t
/* Statistics */ /* Statistics */
vout_statistic_t statistic; vout_statistic_t statistic;
/* Pause */
bool b_paused;
mtime_t i_pause_date;
/* Filter chain */ /* Filter chain */
bool b_first_vout; /* True if it is the first vout of the filter chain */ bool b_first_vout; /* True if it is the first vout of the filter chain */
char *psz_filter_chain; char *psz_filter_chain;
...@@ -105,13 +114,6 @@ struct vout_thread_sys_t ...@@ -105,13 +114,6 @@ struct vout_thread_sys_t
/* Snapshot interface */ /* Snapshot interface */
vout_snapshot_t snapshot; vout_snapshot_t snapshot;
/* Show media title on videoutput */
bool b_title_show;
mtime_t i_title_timeout;
int i_title_position;
char *psz_title;
/* Subpicture unit */ /* Subpicture unit */
spu_t *p_spu; spu_t *p_spu;
...@@ -158,12 +160,6 @@ struct vout_thread_sys_t ...@@ -158,12 +160,6 @@ struct vout_thread_sys_t
/* */ /* */
void vout_IntfInit( vout_thread_t * ); void vout_IntfInit( vout_thread_t * );
/* DO NOT use vout_UsePictureLocked unless you are in src/video_ouput
*
* This function supposes that you call it with picture_lock taken.
*/
void vout_UsePictureLocked( vout_thread_t *p_vout, picture_t *p_pic );
/* */ /* */
int vout_OpenWrapper (vout_thread_t *, const char *); int vout_OpenWrapper (vout_thread_t *, const char *);
void vout_CloseWrapper(vout_thread_t *); void vout_CloseWrapper(vout_thread_t *);
......
...@@ -175,12 +175,12 @@ void vout_IntfInit( vout_thread_t *p_vout ) ...@@ -175,12 +175,12 @@ void vout_IntfInit( vout_thread_t *p_vout )
var_Create( p_vout, "mouse-hide-timeout", var_Create( p_vout, "mouse-hide-timeout",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
p_vout->p->b_title_show = var_CreateGetBool( p_vout, "video-title-show" ); p_vout->p->title.show = var_CreateGetBool( p_vout, "video-title-show" );
p_vout->p->i_title_timeout = p_vout->p->title.timeout = var_CreateGetInteger( p_vout,
(mtime_t)var_CreateGetInteger( p_vout, "video-title-timeout" ); "video-title-timeout" );
p_vout->p->i_title_position = p_vout->p->title.position = var_CreateGetInteger( p_vout,
var_CreateGetInteger( p_vout, "video-title-position" ); "video-title-position" );
p_vout->p->psz_title = NULL; p_vout->p->title.value = NULL;
var_AddCallback( p_vout, "video-title-show", TitleShowCallback, NULL ); var_AddCallback( p_vout, "video-title-show", TitleShowCallback, NULL );
var_AddCallback( p_vout, "video-title-timeout", TitleTimeoutCallback, NULL ); var_AddCallback( p_vout, "video-title-timeout", TitleTimeoutCallback, NULL );
...@@ -923,7 +923,7 @@ static int TitleShowCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -923,7 +923,7 @@ static int TitleShowCallback( vlc_object_t *p_this, char const *psz_cmd,
VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
VLC_UNUSED(p_data); VLC_UNUSED(p_data);
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_thread_t *p_vout = (vout_thread_t *)p_this;
p_vout->p->b_title_show = newval.b_bool; p_vout->p->title.show = newval.b_bool;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -932,7 +932,7 @@ static int TitleTimeoutCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -932,7 +932,7 @@ static int TitleTimeoutCallback( vlc_object_t *p_this, char const *psz_cmd,
{ {
VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_thread_t *p_vout = (vout_thread_t *)p_this;
p_vout->p->i_title_timeout = (mtime_t) newval.i_int; p_vout->p->title.timeout = (mtime_t) newval.i_int;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -942,6 +942,6 @@ static int TitlePositionCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -942,6 +942,6 @@ static int TitlePositionCallback( vlc_object_t *p_this, char const *psz_cmd,
VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
VLC_UNUSED(p_data); VLC_UNUSED(p_data);
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_thread_t *p_vout = (vout_thread_t *)p_this;
p_vout->p->i_title_position = newval.i_int; p_vout->p->title.position = newval.i_int;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -44,12 +44,6 @@ ...@@ -44,12 +44,6 @@
#include "vout_pictures.h" #include "vout_pictures.h"
#include "vout_internal.h" #include "vout_internal.h"
static void tracep(const char *msg, picture_t *picture)
{
//fprintf(stderr, "########## %s === picture=%p::%d\n", msg,
// picture, picture ? picture->i_refcount : -1);
}
/** /**
* Display a picture * Display a picture
* *
...@@ -60,8 +54,6 @@ void vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -60,8 +54,6 @@ void vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
{ {
vlc_mutex_lock( &p_vout->p->picture_lock ); vlc_mutex_lock( &p_vout->p->picture_lock );
tracep("vout_DisplayPicture", p_pic);
p_pic->p_next = NULL; p_pic->p_next = NULL;
picture_fifo_Push(p_vout->p->decoder_fifo, p_pic); picture_fifo_Push(p_vout->p->decoder_fifo, p_pic);
...@@ -97,7 +89,6 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, ...@@ -97,7 +89,6 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout,
picture_Reset(p_pic); picture_Reset(p_pic);
p_pic->p_next = NULL; // FIXME put it in picture_Reset ? p_pic->p_next = NULL; // FIXME put it in picture_Reset ?
} }
tracep("vout_CreatePicture", p_pic);
vlc_mutex_unlock( &p_vout->p->picture_lock ); vlc_mutex_unlock( &p_vout->p->picture_lock );
return p_pic; return p_pic;
...@@ -108,7 +99,6 @@ void vout_DropPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -108,7 +99,6 @@ void vout_DropPicture( vout_thread_t *p_vout, picture_t *p_pic )
{ {
vlc_mutex_lock( &p_vout->p->picture_lock ); vlc_mutex_lock( &p_vout->p->picture_lock );
tracep("vout_DropPicture", p_pic);
picture_Release( p_pic ); picture_Release( p_pic );
vlc_cond_signal( &p_vout->p->picture_wait ); vlc_cond_signal( &p_vout->p->picture_wait );
...@@ -117,7 +107,6 @@ void vout_DropPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -117,7 +107,6 @@ void vout_DropPicture( vout_thread_t *p_vout, picture_t *p_pic )
void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic ) void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
{ {
tracep("vout_DestroyPicture", p_pic);
vout_DropPicture( p_vout, p_pic ); vout_DropPicture( p_vout, p_pic );
} }
...@@ -131,7 +120,6 @@ void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -131,7 +120,6 @@ void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
void vout_LinkPicture( vout_thread_t *p_vout, picture_t *p_pic ) void vout_LinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
{ {
vlc_mutex_lock( &p_vout->p->picture_lock ); vlc_mutex_lock( &p_vout->p->picture_lock );
tracep("vout_LinkPicture", p_pic);
picture_Hold( p_pic ); picture_Hold( p_pic );
vlc_mutex_unlock( &p_vout->p->picture_lock ); vlc_mutex_unlock( &p_vout->p->picture_lock );
} }
...@@ -144,7 +132,6 @@ void vout_LinkPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -144,7 +132,6 @@ void vout_LinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic ) void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
{ {
vlc_mutex_lock( &p_vout->p->picture_lock ); vlc_mutex_lock( &p_vout->p->picture_lock );
tracep("vout_UnlinkPicture", p_pic);
picture_Release( p_pic ); picture_Release( p_pic );
vlc_cond_signal( &p_vout->p->picture_wait ); vlc_cond_signal( &p_vout->p->picture_wait );
......
...@@ -160,6 +160,13 @@ int vout_InitWrapper(vout_thread_t *vout) ...@@ -160,6 +160,13 @@ int vout_InitWrapper(vout_thread_t *vout)
vout->fmt_out.i_visible_width = source.i_width; vout->fmt_out.i_visible_width = source.i_width;
vout->fmt_out.i_height = vout->fmt_out.i_height =
vout->fmt_out.i_visible_height = source.i_height; vout->fmt_out.i_visible_height = source.i_height;
if (source.i_sar_num > 0 && source.i_sar_den > 0) {
vlc_ureduce(&vout->fmt_out.i_sar_num, &vout->fmt_out.i_sar_den,
source.i_sar_num, source.i_sar_den, 0);
} else {
vout->fmt_out.i_sar_num = 1;
vout->fmt_out.i_sar_den = 1;
}
vout->fmt_out.i_sar_num = source.i_sar_num; vout->fmt_out.i_sar_num = source.i_sar_num;
vout->fmt_out.i_sar_den = source.i_sar_den; vout->fmt_out.i_sar_den = source.i_sar_den;
vout->fmt_out.i_x_offset = 0; vout->fmt_out.i_x_offset = 0;
...@@ -167,6 +174,7 @@ int vout_InitWrapper(vout_thread_t *vout) ...@@ -167,6 +174,7 @@ int vout_InitWrapper(vout_thread_t *vout)
vout->fmt_out.i_rmask = source.i_rmask; vout->fmt_out.i_rmask = source.i_rmask;
vout->fmt_out.i_gmask = source.i_gmask; vout->fmt_out.i_gmask = source.i_gmask;
vout->fmt_out.i_bmask = source.i_bmask; vout->fmt_out.i_bmask = source.i_bmask;
video_format_FixRgb(&vout->fmt_out);
if (vout->fmt_in.i_visible_width != source.i_visible_width || if (vout->fmt_in.i_visible_width != source.i_visible_width ||
vout->fmt_in.i_visible_height != source.i_visible_height || vout->fmt_in.i_visible_height != source.i_visible_height ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment