From 39a7f7e696685c58885539226344c9c93e24fce5 Mon Sep 17 00:00:00 2001 From: Rocky Bernstein Date: Fri, 5 Dec 2003 04:24:47 +0000 Subject: [PATCH] Slightly better handling of stills and toggling pause by using the different threads better. Still has stream still/to MPEG bug and duplicate video window bug though. (And could use lots of cleanup.) --- modules/access/vcdx/Modules.am | 8 +-- modules/access/vcdx/access.c | 123 ++++++++++++++++++++++++++++---- modules/access/vcdx/demux.c | 3 +- modules/access/vcdx/intf.c | 99 ++++++++++++------------- modules/access/vcdx/intf.h | 22 +++++- modules/access/vcdx/vcdplayer.c | 23 ++++-- 6 files changed, 201 insertions(+), 77 deletions(-) diff --git a/modules/access/vcdx/Modules.am b/modules/access/vcdx/Modules.am index c9dc7343ef..58af28076f 100644 --- a/modules/access/vcdx/Modules.am +++ b/modules/access/vcdx/Modules.am @@ -1,12 +1,12 @@ SOURCES_vcdx = \ + access.c \ + cdrom.c \ + cdrom.h \ + demux.c \ intf.c \ intf.h \ vcd.c \ vcd.h \ vcdplayer.h \ vcdplayer.c \ - cdrom.c \ - cdrom.h \ - demux.c \ - access.c \ $(NULL) diff --git a/modules/access/vcdx/access.c b/modules/access/vcdx/access.c index 04ffbfab17..320e597a37 100644 --- a/modules/access/vcdx/access.c +++ b/modules/access/vcdx/access.c @@ -4,7 +4,7 @@ * to go here. ***************************************************************************** * Copyright (C) 2000,2003 VideoLAN - * $Id: access.c,v 1.7 2003/12/03 21:55:33 rocky Exp $ + * $Id: access.c,v 1.8 2003/12/05 04:24:47 rocky Exp $ * * Authors: Rocky Bernstein * Johan Bilien @@ -30,12 +30,12 @@ #include #include -#include +#include #include "../../demux/mpeg/system.h" #include "vcd.h" -#include "intf.h" #include "vcdplayer.h" +#include "intf.h" #include #include @@ -50,6 +50,8 @@ #define VCD_BLOCKS_ONCE 20 #define VCD_DATA_ONCE (VCD_BLOCKS_ONCE * M2F2_SECTOR_SIZE) +#define VCD_MRL_PREFIX "vcdx://" + /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -193,9 +195,9 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) memset(p_buf, 0, M2F2_SECTOR_SIZE); p_buf += 2; *p_buf = 0x01; - dbg_print(INPUT_DBG_STILL, "Handled still event\n"); + dbg_print(INPUT_DBG_STILL, "Handled still event"); - /* p_vcd->p_intf->b_end_of_cell = true; */ + p_vcd->p_intf->p_sys->b_still = 1; input_SetStatus( p_input, INPUT_STATUS_PAUSE ); vlc_mutex_lock( &p_input->stream.stream_lock ); @@ -205,7 +207,9 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) vlc_mutex_unlock( &p_input->stream.stream_lock ); + dbg_print(INPUT_DBG_STILL, "Clock manage"); input_ClockManageControl( p_input, p_pgrm, 0 ); + dbg_print(INPUT_DBG_STILL, "Clock manage done"); return i_read + M2F2_SECTOR_SIZE; } @@ -945,7 +949,7 @@ VCDUpdateVar( input_thread_t *p_input, int i_num, int i_action, #define meta_info_add_str(title, str) \ if ( str ) { \ - dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str); \ + dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str); \ input_AddInfo( p_cat, _(title), "%s", str ); \ } @@ -977,6 +981,92 @@ static void InformationCreate( input_thread_t *p_input ) } +#if FINISHED_PLAYLIST +static void +VCDCreatePlayListItem(const input_thread_t *p_input, + thread_vcd_data_t *p_vcd, + playlist_t *p_playlist, unsigned int i_track, + char *psz_mrl, int psz_mrl_max, + const char *psz_source, int playlist_operation, + unsigned int i_pos) +{ + mtime_t i_duration = + (vcdinfo_get_track_size(p_vcd->vcd, i_track) * 8 * 10000000) + / (400 * p_input->stream.control.i_rate) ; + char *p_title; + char *config_varname = MODULE_STRING "-title-format"; + + snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u", + VCD_MRL_PREFIX, psz_source, i_track); + +#if 0 + p_title = VCDFormatStr(p_input, p_vcd, + config_GetPsz( p_input, config_varname ), + psz_mrl, i_track); +#else + p_title = psz_mrl; +#endif + + playlist_AddExt( p_playlist, psz_mrl, p_title, i_duration, + 0, 0, playlist_operation, i_pos ); +} + +static int +VCDFixupPlayList( input_thread_t *p_input, thread_vcd_data_t *p_vcd, + const char *psz_source ) +{ + unsigned int i; + playlist_t * p_playlist; + char * psz_mrl; + unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + strlen(psz_source) + + strlen("@T") + strlen("100") + 1; + + psz_mrl = malloc( psz_mrl_max ); + + if( psz_mrl == NULL ) + { + msg_Warn( p_input, "out of memory" ); + return -1; + } + + p_playlist = (playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( !p_playlist ) + { + msg_Warn( p_input, "can't find playlist" ); + free(psz_mrl); + return -1; + } + + if ( config_GetInt( p_input, MODULE_STRING "-PBC" ) ) { + /* May fill out more information when the playlist user interface becomes + more mature. + */ + VCDCreatePlayListItem(p_input, p_vcd, p_playlist, p_vcd->cur_track, + psz_mrl, psz_mrl_max, psz_source, PLAYLIST_REPLACE, + p_playlist->i_index); + } else { + + playlist_Delete( p_playlist, p_playlist->i_index); + + for( i = 1 ; i < p_vcd->num_tracks ; i++ ) + { + VCDCreatePlayListItem(p_input, p_vcd, p_playlist, i, psz_mrl, + psz_mrl_max, psz_source, PLAYLIST_APPEND, + PLAYLIST_END); + + } + + playlist_Command( p_playlist, PLAYLIST_GOTO, 0 ); + + } + + vlc_object_release( p_playlist ); + free(psz_mrl); + return 0; +} +#endif + /***************************************************************************** * Public routines. *****************************************************************************/ @@ -1061,16 +1151,13 @@ E_(Open) ( vlc_object_t *p_this ) if( !(p_vcd->vcd = vcd_Open( p_this, psz_source )) ) { msg_Warn( p_input, "could not open %s", psz_source ); - free( psz_source ); - free( p_vcd ); - return VLC_EGENERIC; + goto err_exit; } /* Get track information. */ p_vcd->num_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input), vcdinfo_get_cd_image(p_vcd->vcd), &p_vcd->p_sectors ); - free( psz_source ); if( p_vcd->num_tracks < 0 ) LOG_ERR ("unable to count tracks" ); else if( p_vcd->num_tracks <= 1 ) @@ -1078,8 +1165,7 @@ E_(Open) ( vlc_object_t *p_this ) if( p_vcd->num_tracks <= 1) { vcdinfo_close( p_vcd->vcd ); - free( p_vcd ); - return VLC_EGENERIC; + goto err_exit; } /* Set stream and area data */ @@ -1117,8 +1203,7 @@ E_(Open) ( vlc_object_t *p_this ) if ( ! b_play_ok ) { vcdinfo_close( p_vcd->vcd ); - free( p_vcd ); - return VLC_EGENERIC; + goto err_exit; } if( !p_input->psz_demux || !*p_input->psz_demux ) @@ -1136,7 +1221,17 @@ E_(Open) ( vlc_object_t *p_this ) InformationCreate( p_input ); +#if FINISHED_PLAYLIST + VCDFixupPlayList( p_input, p_vcd, psz_source ); +#endif + + free( psz_source ); + return VLC_SUCCESS; + err_exit: + free( psz_source ); + free( p_vcd ); + return VLC_EGENERIC; } /***************************************************************************** diff --git a/modules/access/vcdx/demux.c b/modules/access/vcdx/demux.c index 386598800a..ad2ed56ae1 100644 --- a/modules/access/vcdx/demux.c +++ b/modules/access/vcdx/demux.c @@ -2,7 +2,7 @@ * demux.c: demux functions for dvdplay. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: demux.c,v 1.2 2003/11/09 00:52:32 rocky Exp $ + * $Id: demux.c,v 1.3 2003/12/05 04:24:47 rocky Exp $ * * Author: Stéphane Borel * @@ -49,6 +49,7 @@ #endif #include "vcd.h" +#include "vcdplayer.h" #include "intf.h" /* how many packets vcdx_Demux will read in each loop */ diff --git a/modules/access/vcdx/intf.c b/modules/access/vcdx/intf.c index 8757e45bfa..cd70c4aa7a 100644 --- a/modules/access/vcdx/intf.c +++ b/modules/access/vcdx/intf.c @@ -2,7 +2,7 @@ * intf.c: Video CD interface to handle user interaction and still time ***************************************************************************** * Copyright (C) 2002,2003 VideoLAN - * $Id: intf.c,v 1.9 2003/11/26 01:45:03 rocky Exp $ + * $Id: intf.c,v 1.10 2003/12/05 04:24:47 rocky Exp $ * * Authors: Rocky Bernstein * from DVD code by Stéphane Borel @@ -35,33 +35,12 @@ #include "vcd.h" #include "vcdplayer.h" - -/***************************************************************************** - * intf_sys_t: description and status of interface - *****************************************************************************/ -struct intf_sys_t -{ - input_thread_t * p_input; - thread_vcd_data_t * p_vcd; - - vlc_bool_t b_still; - vlc_bool_t b_inf_still; - mtime_t m_still_time; - -#if FINISHED - vcdplay_ctrl_t control; -#else - int control; -#endif - vlc_bool_t b_click, b_move, b_key_pressed; -}; +#include "intf.h" /***************************************************************************** * Local prototypes. *****************************************************************************/ static int InitThread ( intf_thread_t *p_intf ); -static int MouseEvent ( vlc_object_t *, char const *, - vlc_value_t, vlc_value_t, void * ); static int KeyEvent ( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); @@ -100,6 +79,7 @@ int E_(OpenIntf) ( vlc_object_t *p_this ) void E_(CloseIntf) ( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; + var_DelCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf ); /* Destroy structure */ free( p_intf->p_sys ); @@ -112,6 +92,8 @@ void E_(CloseIntf) ( vlc_object_t *p_this ) static void RunIntf( intf_thread_t *p_intf ) { vlc_object_t * p_vout = NULL; + mtime_t mtime = 0; + mtime_t mlast = 0; thread_vcd_data_t * p_vcd; input_thread_t * p_input; @@ -136,6 +118,35 @@ static void RunIntf( intf_thread_t *p_intf ) { vlc_mutex_lock( &p_intf->change_lock ); + /* + * still images + */ + if( p_intf->p_sys->b_still && !p_intf->p_sys->b_inf_still ) + { + if( p_intf->p_sys->m_still_time > 0 ) + { + /* update remaining still time */ + dbg_print(INPUT_DBG_STILL, "updating still time"); + mtime = mdate(); + if( mlast ) + { + p_intf->p_sys->m_still_time -= mtime - mlast; + } + + mlast = mtime; + } + else + { + /* still time elasped */ + dbg_print(INPUT_DBG_STILL, "wait time done - setting play"); + input_SetStatus( p_intf->p_sys->p_input, + INPUT_STATUS_PLAY ); + p_intf->p_sys->m_still_time = 0; + p_intf->p_sys->b_still = 0; + mlast = 0; + } + } + /* * keyboard event */ @@ -215,6 +226,18 @@ static void RunIntf( intf_thread_t *p_intf ) } } number_addend = 0; + + /* we can safely interact with the VCD player + * with the stream lock */ + if( p_intf->p_sys->b_still ) + { + dbg_print(INPUT_DBG_STILL, "Playing still after activate"); + input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); + p_intf->p_sys->b_still = 0; + p_intf->p_sys->b_inf_still = 0; + p_intf->p_sys->m_still_time = 0; + } + } else { unsigned int digit_entered=0; @@ -259,8 +282,6 @@ static void RunIntf( intf_thread_t *p_intf ) VLC_OBJECT_VOUT, FIND_CHILD ); if( p_vout ) { - var_AddCallback( p_vout, "mouse-moved", MouseEvent, p_intf ); - var_AddCallback( p_vout, "mouse-clicked", MouseEvent, p_intf ); var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf ); } } @@ -272,8 +293,6 @@ static void RunIntf( intf_thread_t *p_intf ) if( p_vout ) { - var_DelCallback( p_vout, "mouse-moved", MouseEvent, p_intf ); - var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf ); var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf ); vlc_object_release( p_vout ); } @@ -317,30 +336,6 @@ static int InitThread( intf_thread_t * p_intf ) } } -/***************************************************************************** - * MouseEvent: callback for mouse events - *****************************************************************************/ -static int MouseEvent( vlc_object_t *p_this, char const *psz_var, - vlc_value_t oldval, vlc_value_t newval, void *p_data ) -{ - intf_thread_t *p_intf = (intf_thread_t *)p_data; - - vlc_mutex_lock( &p_intf->change_lock ); - - if( psz_var[6] == 'c' ) /* "mouse-clicked" */ - { - p_intf->p_sys->b_click = VLC_TRUE; - } - else if( psz_var[6] == 'm' ) /* "mouse-moved" */ - { - p_intf->p_sys->b_move = VLC_TRUE; - } - - vlc_mutex_unlock( &p_intf->change_lock ); - - return VLC_SUCCESS; -} - /***************************************************************************** * KeyEvent: callback for keyboard events *****************************************************************************/ @@ -358,7 +353,7 @@ static int KeyEvent( vlc_object_t *p_this, char const *psz_var, } /***************************************************************************** - * dvdIntfStillTime: function provided to demux plugin to request + * vcdIntfStillTime: function provided to demux plugin to request * still images *****************************************************************************/ int vcdIntfStillTime( intf_thread_t *p_intf, int i_sec ) diff --git a/modules/access/vcdx/intf.h b/modules/access/vcdx/intf.h index fb72e11e77..1adf05c698 100644 --- a/modules/access/vcdx/intf.h +++ b/modules/access/vcdx/intf.h @@ -2,7 +2,7 @@ * intf.h: send info to intf. ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: intf.h,v 1.1 2003/10/04 18:55:13 gbazin Exp $ + * $Id: intf.h,v 1.2 2003/12/05 04:24:47 rocky Exp $ * * Author: Stéphane Borel * @@ -21,6 +21,26 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +/***************************************************************************** + * intf_sys_t: description and status of interface + *****************************************************************************/ +struct intf_sys_t +{ + input_thread_t * p_input; + thread_vcd_data_t * p_vcd; + + vlc_bool_t b_still; + vlc_bool_t b_inf_still; + mtime_t m_still_time; + +#if FINISHED + vcdplay_ctrl_t control; +#else + int control; +#endif + vlc_bool_t b_click, b_move, b_key_pressed; +}; + int vcdIntfStillTime( struct intf_thread_t *, int ); int vcdIntfResetStillTime( intf_thread_t *p_intf ); diff --git a/modules/access/vcdx/vcdplayer.c b/modules/access/vcdx/vcdplayer.c index 054c3f60c7..91c4a11a16 100644 --- a/modules/access/vcdx/vcdplayer.c +++ b/modules/access/vcdx/vcdplayer.c @@ -3,7 +3,7 @@ * using libcdio, libvcd and libvcdinfo ***************************************************************************** * Copyright (C) 2003 Rocky Bernstein - * $Id: vcdplayer.c,v 1.5 2003/11/24 03:30:36 rocky Exp $ + * $Id: vcdplayer.c,v 1.6 2003/12/05 04:24:47 rocky Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,9 +31,11 @@ #include #include +#include #include "vcd.h" #include "vcdplayer.h" +#include "intf.h" #include @@ -183,9 +185,13 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) if (wait_time != 0) { /* FIXME */ p_vcd->in_still = wait_time - 1; - SLEEP_1_SEC_AND_HANDLE_EVENTS ; + p_vcd->p_intf->p_sys->m_still_time = (wait_time - 1) * 1000000; return READ_STILL_FRAME; + } else { + p_vcd->p_intf->p_sys->m_still_time = 0; + p_vcd->p_intf->p_sys->b_inf_still = 1; } + } vcdplayer_update_entry( p_input, vcdinf_pld_get_next_offset(p_vcd->pxd.pld), @@ -208,9 +214,16 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) /* Handle any wait time given */ if (-5 == p_vcd->in_still) { - p_vcd->in_still = wait_time - 1; - SLEEP_1_SEC_AND_HANDLE_EVENTS ; - return READ_STILL_FRAME; + if (wait_time != 0) { + /* FIXME */ + p_vcd->in_still = wait_time - 1; + p_vcd->p_intf->p_sys->m_still_time = (wait_time - 1) * 1000000; + return READ_STILL_FRAME; + } else { + p_vcd->p_intf->p_sys->m_still_time = 0; + p_vcd->p_intf->p_sys->b_inf_still = 1; + } + return READ_STILL_FRAME; } /* Handle any looping given. */ -- 2.39.2