[Mplayerxp-cvslog] SF.net SVN: mplayerxp:[417] mplayerxp
Brought to you by:
olov
From: <nic...@us...> - 2012-11-20 17:02:11
|
Revision: 417 http://mplayerxp.svn.sourceforge.net/mplayerxp/?rev=417&view=rev Author: nickols_k Date: 2012-11-20 17:01:59 +0000 (Tue, 20 Nov 2012) Log Message: ----------- more c++ sources + constantization Modified Paths: -------------- mplayerxp/libmpstream/Makefile mplayerxp/libmpstream/cdd.h mplayerxp/libmpsub/Makefile mplayerxp/libmpsub/spudec.h mplayerxp/libmpsub/subreader.h mplayerxp/libmpsub/vobsub.h mplayerxp/libvo/Makefile mplayerxp/mp-opt-reg.cpp mplayerxp/mplayerxp.cpp mplayerxp/mplayerxp.h mplayerxp/nls/nls.h Added Paths: ----------- mplayerxp/libmpstream/s_cdd.cpp mplayerxp/libmpstream/s_dvdnav.cpp mplayerxp/libmpstream/s_ffmpeg.cpp mplayerxp/libmpstream/s_file.cpp mplayerxp/libmpstream/s_null.cpp mplayerxp/libmpsub/find_sub.cpp mplayerxp/libmpsub/subreader.cpp mplayerxp/libmpsub/vobsub.cpp mplayerxp/libvo/osd.cpp mplayerxp/libvo/sub.cpp Removed Paths: ------------- mplayerxp/libmpstream/s_cdd.c mplayerxp/libmpstream/s_dvdnav.c mplayerxp/libmpstream/s_ffmpeg.c mplayerxp/libmpstream/s_file.c mplayerxp/libmpstream/s_null.c mplayerxp/libmpsub/find_sub.c mplayerxp/libmpsub/subreader.c mplayerxp/libmpsub/vobsub.c mplayerxp/libvo/osd.c mplayerxp/libvo/sub.c Modified: mplayerxp/libmpstream/Makefile =================================================================== --- mplayerxp/libmpstream/Makefile 2012-11-20 16:18:38 UTC (rev 416) +++ mplayerxp/libmpstream/Makefile 2012-11-20 17:01:59 UTC (rev 417) @@ -7,16 +7,16 @@ DO_ALL = @ for i in $(SUBDIRS); do $(MAKE) -C $$i all || exit; done CXXSRCS=s_tv.cpp -SRCS = s_file.c s_ffmpeg.c s_null.c +CXXSRCS+= s_file.cpp s_ffmpeg.cpp s_null.cpp ifeq ($(HAVE_LIBCDIO_CDDA),yes) -SRCS += s_cdd.c +CXXSRCS += s_cdd.cpp CXXSRCS += cdda.cpp ifeq ($(HAVE_STREAMING),yes) CXXSRCS += cddb.cpp endif endif ifeq ($(USE_DVDNAV),yes) -SRCS += s_dvdnav.c +CXXSRCS += s_dvdnav.cpp endif ifeq ($(USE_DVDREAD),yes) SRCS += s_dvdread.c Modified: mplayerxp/libmpstream/cdd.h =================================================================== --- mplayerxp/libmpstream/cdd.h 2012-11-20 16:18:38 UTC (rev 416) +++ mplayerxp/libmpstream/cdd.h 2012-11-20 17:01:59 UTC (rev 417) @@ -3,10 +3,6 @@ #include <cdio/cdda.h> #include "libmpconf/cfgparser.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { char cddb_hello[1024]; unsigned long disc_id; @@ -80,7 +76,4 @@ off_t __FASTCALL__ tell_cdda(const stream_t* s); void __FASTCALL__ close_cdda(stream_t* s); void cdda_register_options(m_config_t* cfg); -#ifdef __cplusplus -} -#endif #endif // __CDD_H__ Deleted: mplayerxp/libmpstream/s_cdd.c =================================================================== --- mplayerxp/libmpstream/s_cdd.c 2012-11-20 16:18:38 UTC (rev 416) +++ mplayerxp/libmpstream/s_cdd.c 2012-11-20 17:01:59 UTC (rev 417) @@ -1,133 +0,0 @@ -/* - s_cdd - cdda & cddb streams interface -*/ -#include "mp_config.h" -#include "mplayerxp.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "stream.h" -#include "osdep/mplib.h" -#include "stream_msg.h" - -#ifdef HAVE_LIBCDIO -#include "cdd.h" -#include "mrl.h" - -static track_t track_idx=255; -static MPXP_Rc __FASTCALL__ _cdda_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) -{ - const char *param; - char *device; - int retval; - UNUSED(libinput); - UNUSED(flags); - stream->type=STREAMTYPE_RAWAUDIO|STREAMTYPE_SEEKABLE; - stream->sector_size=CD_FRAMESIZE_RAW; - if(strcmp(filename,"help") == 0) { - MSG_HINT("Usage: cdda://<@device><#trackno>\n"); - return MPXP_False; - } - param=mrl_parse_line(filename,NULL,NULL,&device,NULL); - retval = open_cdda(stream,device ? device : DEFAULT_CDROM_DEVICE,param); - if(device) mp_free(device); - check_pin("stream",stream->pin,STREAM_PIN); - return retval; -} - -static MPXP_Rc __FASTCALL__ _cddb_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) -{ - const char *param; - char *device; - int retval; - UNUSED(flags); - stream->type=STREAMTYPE_RAWAUDIO|STREAMTYPE_SEEKABLE; - stream->sector_size=CD_FRAMESIZE_RAW; - if(strcmp(filename,"help") == 0) { - MSG_HINT("Usage: cddb://<@device><#trackno>\n"); - return MPXP_False; - } - param=mrl_parse_line(filename,NULL,NULL,&device,NULL); - retval = open_cddb(stream,device ? device : DEFAULT_CDROM_DEVICE,param); - if(device) mp_free(device); - check_pin("stream",stream->pin,STREAM_PIN); - return retval; -} - -static int __FASTCALL__ cdd_read(stream_t*stream,stream_packet_t*sp) -{ - sp->type=0; - sp->len=read_cdda(stream,sp->buf,&track_idx); - return sp->len; -} - -static off_t __FASTCALL__ cdd_seek(stream_t*stream,off_t pos) -{ - seek_cdda(stream,pos,&track_idx); - return pos; -} - -static off_t __FASTCALL__ cdd_tell(const stream_t*stream) -{ - return tell_cdda(stream); -} - -static void __FASTCALL__ cdd_close(stream_t*stream) -{ - close_cdda(stream); -} - -static MPXP_Rc __FASTCALL__ cdd_ctrl(const stream_t *s,unsigned cmd,any_t*args) -{ - cdda_priv *p=s->priv; - switch(cmd) { - case SCTRL_TXT_GET_STREAM_NAME: { - if(track_idx!=255) - sprintf((char *)args,"Track %d",track_idx); - return MPXP_Ok; - } - break; - case SCTRL_AUD_GET_CHANNELS: - *(int *)args=cdio_cddap_track_channels(p->cd, track_idx); - if(*(int *)args<=0) *(int *)args=2; - MSG_V("cdda channels: %u\n",*(int *)args); - return MPXP_Ok; - case SCTRL_AUD_GET_SAMPLERATE: - *(int *)args = 44100; - return MPXP_Ok; - case SCTRL_AUD_GET_SAMPLESIZE: - *(int *)args=2; - return MPXP_Ok; - case SCTRL_AUD_GET_FORMAT: - *(int *)args=0x01; /* Raw PCM */ - return MPXP_Ok; - default: break; - } - return MPXP_False; -} - -const stream_driver_t cdda_stream= -{ - "cdda://", - "reads multimedia stream directly from Digital Audio Compact Disc [CD-DA]", - _cdda_open, - cdd_read, - cdd_seek, - cdd_tell, - cdd_close, - cdd_ctrl -}; - -const stream_driver_t cddb_stream= -{ - "cddb://", - "reads multimedia stream from CD-DA but tracks names from CDDB servers", - _cddb_open, - cdd_read, - cdd_seek, - cdd_tell, - cdd_close, - cdd_ctrl -}; -#endif Copied: mplayerxp/libmpstream/s_cdd.cpp (from rev 414, mplayerxp/libmpstream/s_cdd.c) =================================================================== --- mplayerxp/libmpstream/s_cdd.cpp (rev 0) +++ mplayerxp/libmpstream/s_cdd.cpp 2012-11-20 17:01:59 UTC (rev 417) @@ -0,0 +1,133 @@ +/* + s_cdd - cdda & cddb streams interface +*/ +#include "mp_config.h" +#include "mplayerxp.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "stream.h" +#include "osdep/mplib.h" +#include "stream_msg.h" + +#ifdef HAVE_LIBCDIO +#include "cdd.h" +#include "mrl.h" + +static track_t track_idx=255; +static MPXP_Rc __FASTCALL__ _cdda_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) +{ + const char *param; + char *device; + MPXP_Rc retval; + UNUSED(libinput); + UNUSED(flags); + stream->type=STREAMTYPE_RAWAUDIO|STREAMTYPE_SEEKABLE; + stream->sector_size=CD_FRAMESIZE_RAW; + if(strcmp(filename,"help") == 0) { + MSG_HINT("Usage: cdda://<@device><#trackno>\n"); + return MPXP_False; + } + param=mrl_parse_line(filename,NULL,NULL,&device,NULL); + retval = open_cdda(stream,device ? device : DEFAULT_CDROM_DEVICE,param); + if(device) mp_free(device); + check_pin("stream",stream->pin,STREAM_PIN); + return retval; +} + +static MPXP_Rc __FASTCALL__ _cddb_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) +{ + const char *param; + char *device; + MPXP_Rc retval; + UNUSED(flags); + stream->type=STREAMTYPE_RAWAUDIO|STREAMTYPE_SEEKABLE; + stream->sector_size=CD_FRAMESIZE_RAW; + if(strcmp(filename,"help") == 0) { + MSG_HINT("Usage: cddb://<@device><#trackno>\n"); + return MPXP_False; + } + param=mrl_parse_line(filename,NULL,NULL,&device,NULL); + retval = open_cddb(stream,device ? device : DEFAULT_CDROM_DEVICE,param); + if(device) mp_free(device); + check_pin("stream",stream->pin,STREAM_PIN); + return retval; +} + +static int __FASTCALL__ cdd_read(stream_t*stream,stream_packet_t*sp) +{ + sp->type=0; + sp->len=read_cdda(stream,sp->buf,&track_idx); + return sp->len; +} + +static off_t __FASTCALL__ cdd_seek(stream_t*stream,off_t pos) +{ + seek_cdda(stream,pos,&track_idx); + return pos; +} + +static off_t __FASTCALL__ cdd_tell(const stream_t*stream) +{ + return tell_cdda(stream); +} + +static void __FASTCALL__ cdd_close(stream_t*stream) +{ + close_cdda(stream); +} + +static MPXP_Rc __FASTCALL__ cdd_ctrl(const stream_t *s,unsigned cmd,any_t*args) +{ + cdda_priv *p=reinterpret_cast<cdda_priv*>(s->priv); + switch(cmd) { + case SCTRL_TXT_GET_STREAM_NAME: { + if(track_idx!=255) + sprintf((char *)args,"Track %d",track_idx); + return MPXP_Ok; + } + break; + case SCTRL_AUD_GET_CHANNELS: + *(int *)args=cdio_cddap_track_channels(p->cd, track_idx); + if(*(int *)args<=0) *(int *)args=2; + MSG_V("cdda channels: %u\n",*(int *)args); + return MPXP_Ok; + case SCTRL_AUD_GET_SAMPLERATE: + *(int *)args = 44100; + return MPXP_Ok; + case SCTRL_AUD_GET_SAMPLESIZE: + *(int *)args=2; + return MPXP_Ok; + case SCTRL_AUD_GET_FORMAT: + *(int *)args=0x01; /* Raw PCM */ + return MPXP_Ok; + default: break; + } + return MPXP_False; +} + +extern const stream_driver_t cdda_stream= +{ + "cdda://", + "reads multimedia stream directly from Digital Audio Compact Disc [CD-DA]", + _cdda_open, + cdd_read, + cdd_seek, + cdd_tell, + cdd_close, + cdd_ctrl +}; + +extern const stream_driver_t cddb_stream= +{ + "cddb://", + "reads multimedia stream from CD-DA but tracks names from CDDB servers", + _cddb_open, + cdd_read, + cdd_seek, + cdd_tell, + cdd_close, + cdd_ctrl +}; +#endif Deleted: mplayerxp/libmpstream/s_dvdnav.c =================================================================== --- mplayerxp/libmpstream/s_dvdnav.c 2012-11-20 16:18:38 UTC (rev 416) +++ mplayerxp/libmpstream/s_dvdnav.c 2012-11-20 17:01:59 UTC (rev 417) @@ -1,660 +0,0 @@ -/* - s_dvdnav - DVDNAV's stream interface -*/ -#include "mp_config.h" -#ifdef USE_DVDNAV -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include "stream.h" -#include "help_mp.h" -#include "libmpdemux/demuxer.h" -#include "libmpsub/spudec.h" -#include "libvo/sub.h" -#include "input2/input.h" -#include "mplayerxp.h" -#include "stream_msg.h" - -#include <dvdnav/dvdnav.h> -#include <stdio.h> -#include <unistd.h> -#include "osdep/timer.h" -#include "osdep/mplib.h" -#include "mrl.h" -#define DVD_BLOCK_SIZE 2048 - -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif -#ifndef max -#define max(a,b) ((a)>(b)?(a):(b)) -#endif - -extern vo_data_t* vo_data; - -typedef struct { - dvdnav_t * dvdnav; /* handle to libdvdnav stuff */ - char * filename; /* path */ - int ignore_timers; /* should timers be skipped? */ - int sleeping; /* are we sleeping? */ - unsigned int sleep_until; /* timer */ - int started; /* Has mplayer initialization finished? */ - unsigned char prebuf[STREAM_BUFFER_SIZE]; /* prefill buffer */ - int prelen; /* length of prefill buffer */ - off_t cpos; - float vobu_s_pts,vobu_e_pts; - int menu_mode; - dvdnav_highlight_event_t hlev; -} dvdnav_priv_t; - -typedef struct { - int event; /* event number fromd dvdnav_events.h */ - any_t* details; /* event details */ - int len; /* bytes in details */ -} dvdnav_event_t; - -static int dvd_nav_still=0; /* are we on a still picture? */ -static int dvd_nav_skip_opening=0; /* skip opening stalls? */ - -static void __FASTCALL__ dvdnav_stream_ignore_timers(stream_t * stream, int ignore) { - dvdnav_priv_t *dvdnav_priv=stream->priv; - dvdnav_priv->ignore_timers=ignore; -} - -static dvdnav_priv_t * __FASTCALL__ new_dvdnav_stream(stream_t *stream,char * filename) { - const char * title_str; - dvdnav_priv_t *dvdnav_priv; - - if (!filename) - return NULL; - - if (!(dvdnav_priv=(dvdnav_priv_t*)mp_calloc(1,sizeof(*dvdnav_priv)))) - return NULL; - - if (!(dvdnav_priv->filename=mp_strdup(filename))) { - mp_free(dvdnav_priv); - return NULL; - } - - if(dvdnav_open(&(dvdnav_priv->dvdnav),dvdnav_priv->filename)!=DVDNAV_STATUS_OK) - { - mp_free(dvdnav_priv->filename); - mp_free(dvdnav_priv); - return NULL; - } - - if (!dvdnav_priv->dvdnav) { - mp_free(dvdnav_priv); - return NULL; - } - - stream->priv=dvdnav_priv; - dvdnav_stream_ignore_timers(stream,dvd_nav_skip_opening); - - if(1) //from vlc: if not used dvdnav from cvs will fail - { - int len, event; - char buf[2048]; - - dvdnav_get_next_block(dvdnav_priv->dvdnav,buf,&event,&len); - dvdnav_sector_search(dvdnav_priv->dvdnav, 0, SEEK_SET); - } - - /* turn on/off dvdnav caching */ - dvdnav_set_readahead_flag(dvdnav_priv->dvdnav,mp_conf.s_cache_size?0:1); - - /* report the title?! */ - if (dvdnav_get_title_string(dvdnav_priv->dvdnav,&title_str)==DVDNAV_STATUS_OK) { - MSG_INFO("Title: '%s'\n",title_str); - } - check_pin("stream",stream->pin,STREAM_PIN); - return dvdnav_priv; -} - -static void __FASTCALL__ dvdnav_stream_sleep(const stream_t * stream, int seconds) { - dvdnav_priv_t *dvdnav_priv=stream->priv; - - if (!dvdnav_priv->started) return; - - dvdnav_priv->sleeping=0; - switch (seconds) { - case 0: - return; - case 0xff: - MSG_V( "Sleeping indefinately\n" ); - dvdnav_priv->sleeping=2; - break; - default: - MSG_V( "Sleeping %d sec(s)\n", seconds ); - dvdnav_priv->sleep_until = GetTimer();// + seconds*1000000; - dvdnav_priv->sleeping=1; - break; - } - //if (dvdnav_priv->started) dvd_nav_still=1; -} - -static int __FASTCALL__ dvdnav_stream_sleeping(const stream_t * stream) { - dvdnav_priv_t *dvdnav_priv=stream->priv; - unsigned int now; - - if (!dvdnav_priv) return 0; - - if(dvdnav_priv->sleeping) - { - now=GetTimer(); - while(dvdnav_priv->sleeping>1 || now<dvdnav_priv->sleep_until) { -// usec_sleep(1000); /* 1ms granularity */ - return 1; - } - dvdnav_still_skip(dvdnav_priv->dvdnav); // continue past... - dvdnav_priv->sleeping=0; - MSG_V("%s: woke up!\n",__FUNCTION__); - } - dvd_nav_still=0; - MSG_V("%s: active\n",__FUNCTION__); - return 0; -} - -static unsigned int * __FASTCALL__ dvdnav_stream_get_palette(const stream_t * stream) { -#if 0 /* latest versions if libdvdnav don't provide such info */ - dvdnav_priv_t *dvdnav_priv=stream->priv; - if (!dvdnav_priv) { - MSG_V("%s: NULL dvdnav_priv\n",__FUNCTION__); - return NULL; - } - if (!dvdnav_priv->dvdnav) { - MSG_V("%s: NULL dvdnav_priv->dvdnav\n",__FUNCTION__); - return NULL; - } - if (!dvdnav_priv->dvdnav->vm) { - MSG_V("%s: NULL dvdnav_priv->dvdnav->vm\n",__FUNCTION__); - return NULL; - } - if (!dvdnav_priv->dvdnav->vm->state.pgc) { - MSG_V("%s: NULL dvdnav_priv->dvdnav->vm->state.pgc\n",__FUNCTION__); - return NULL; - } - return dvdnav_priv->dvdnav->vm->state.pgc->palette; -#else - UNUSED(stream); -#endif - return 0; -} - -static dvdnav_event_t *tevent; -static int tevent_full=0; -static int dvd_title=-1,dvd_chapter=-1; - -static const mrl_config_t dvdnavopts_conf[]={ - { "skipopening", &dvd_nav_skip_opening, MRL_TYPE_BOOL, 0, 1 }, - { "T", &dvd_title, MRL_TYPE_INT, 0, 999 }, - { "C", &dvd_chapter, MRL_TYPE_INT, 0, 999 }, - { NULL, NULL, 0, 0, 0 } -}; - -static MPXP_Rc __FASTCALL__ __dvdnav_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) -{ - const char *param; - char *dvd_device; - int ntitles; - UNUSED(flags); - UNUSED(libinput); - stream->type = STREAMTYPE_SEEKABLE|STREAMTYPE_PROGRAM; - param=mrl_parse_line(filename,NULL,NULL,&dvd_device,NULL); - if(strcmp(param,"help") == 0) { - MSG_HINT("Usage: dvdnav://<title>,<chapter>\n"); - return MPXP_False; - } - param=mrl_parse_params(param,dvdnavopts_conf); - if (!(stream->priv=new_dvdnav_stream(stream,dvd_device?dvd_device:DEFAULT_DVD_DEVICE))) { - MSG_ERR(MSGTR_CantOpenDVD,dvd_device?dvd_device:DEFAULT_DVD_DEVICE); - if(!dvd_device) { - if (!(stream->priv=new_dvdnav_stream(stream,DEFAULT_CDROM_DEVICE))) - MSG_ERR(MSGTR_CantOpenDVD,DEFAULT_CDROM_DEVICE); - else - goto dvd_ok; - } - mp_free(stream->priv); - if(dvd_device) mp_free(dvd_device); - return MPXP_False; - } - dvd_ok: - if(dvd_device) mp_free(dvd_device); - ((dvdnav_priv_t *)stream->priv)->started=1; - if(mp_conf.s_cache_size) { - tevent = mp_malloc(sizeof(dvdnav_event_t)); - if(tevent) - if((tevent->details=mp_malloc(DVD_BLOCK_SIZE))==NULL) { - mp_free(tevent); - tevent=NULL; - } - } - tevent_full=0; - /* By rumours 1 PGC == whole movie */ - dvdnav_set_PGC_positioning_flag(((dvdnav_priv_t *)stream->priv)->dvdnav,1); - ntitles=0; - dvdnav_get_number_of_titles(((dvdnav_priv_t *)stream->priv)->dvdnav,&ntitles); - MSG_INFO(MSGTR_DVDnumTitles,ntitles); - if(dvd_title != -1) { - int nparts; - dvdnav_get_number_of_parts(((dvdnav_priv_t *)stream->priv)->dvdnav,dvd_title,&nparts); - MSG_INFO(MSGTR_DVDnumChapters,dvd_title,nparts); - if(dvd_chapter != -1) dvdnav_part_play(((dvdnav_priv_t *)stream->priv)->dvdnav,dvd_title,dvd_chapter); - else dvdnav_title_play(((dvdnav_priv_t *)stream->priv)->dvdnav,dvd_title); - ((dvdnav_priv_t *)stream->priv)->cpos=stream->start_pos=2048; /* disallow dvdnav_reset */ - dvdnav_current_title_info(((dvdnav_priv_t *)stream->priv)->dvdnav,&dvd_title,&dvd_chapter); - MSG_INFO("Playing %i part of %i title\n",dvd_chapter,dvd_title); - } - stream->sector_size=tevent?DVD_BLOCK_SIZE*10:DVD_BLOCK_SIZE; - if( dvdnav_is_domain_vmgm(((dvdnav_priv_t *)stream->priv)->dvdnav) || - dvdnav_is_domain_vtsm(((dvdnav_priv_t *)stream->priv)->dvdnav)) - stream->type = STREAMTYPE_MENU|STREAMTYPE_SEEKABLE; - check_pin("stream",stream->pin,STREAM_PIN); - return MPXP_Ok; -} - -static void __FASTCALL__ dvdnav_stream_read(stream_t * stream, dvdnav_event_t*de) { - dvdnav_priv_t *dvdnav_priv=stream->priv; - int event = DVDNAV_NOP; - int done; - - if (!de->len) return; - de->len=-1; - if (!dvdnav_priv) return; - if (!de->details) return; - - if (dvd_nav_still) { - MSG_V("%s: got a stream_read while I should be asleep!\n",__FUNCTION__); - de->event=DVDNAV_STILL_FRAME; - de->len=0; - return; - } - done=0; - while(!done) - { - if (dvdnav_get_next_block(dvdnav_priv->dvdnav,de->details,&event,&de->len)!=DVDNAV_STATUS_OK) - { - MSG_ERR( "Error getting next block from DVD (%s)\n",dvdnav_err_to_string(dvdnav_priv->dvdnav) ); - de->len=-1; - } - if(event == DVDNAV_STILL_FRAME) - { - dvdnav_still_skip(dvdnav_priv->dvdnav); /* don't let dvdnav stall on this image */ - while (dvdnav_stream_sleeping(stream)) usleep(1000); /* 1ms */ - } -#ifdef DVDNAV_WAIT - else - if(event == DVDNAV_WAIT) - { - usleep(1000); - dvdnav_wait_skip(dvdnav_priv->dvdnav); /* don't let dvdnav stall on this image */ - } -#endif - else - if(event == DVDNAV_NAV_PACKET) - { - /* Try to suppress PTS discontinuity here!!! */ - pci_t *_this; - float vobu_s_pts,vobu_e_pts; - _this=dvdnav_get_current_nav_pci(dvdnav_priv->dvdnav); - vobu_s_pts=_this->pci_gi.vobu_s_ptm/90000.; - vobu_e_pts=_this->pci_gi.vobu_e_ptm/90000.; - MSG_V("Handling NAV_PACKET: vobu_s_ptm=%f vobu_e_ptm=%f e_eltm=%f\n" - ,vobu_s_pts - ,vobu_e_pts - ,(float)_this->pci_gi.e_eltm.second+_this->pci_gi.e_eltm.minute*60.+_this->pci_gi.e_eltm.hour*3600.); - if(vobu_s_pts < dvdnav_priv->vobu_e_pts) - { - stream->stream_pts += dvdnav_priv->vobu_e_pts-vobu_s_pts; - MSG_V("DVD's discontinuities found! Applying delta: %f\n",stream->stream_pts); - } - else stream->stream_pts = vobu_s_pts; - dvdnav_priv->vobu_s_pts = vobu_s_pts; - dvdnav_priv->vobu_e_pts = vobu_e_pts; - } - else - if(event == DVDNAV_CELL_CHANGE) - { - int ct,cc; - dvdnav_current_title_info(dvdnav_priv->dvdnav, &ct, &cc); - if(ct<=0) { - dvdnav_priv->menu_mode=1; - MSG_V("entering menu mode: %i %i\n",ct,cc); - MSG_V("vmgm: %i vtsm: %i\n", - dvdnav_is_domain_vmgm(dvdnav_priv->dvdnav), - dvdnav_is_domain_vtsm(dvdnav_priv->dvdnav)); - } - else { - dvdnav_priv->menu_mode=0; - MSG_V("leaving menu mode: %i %i\n",ct,cc); - } - /**/ - if(dvdnav_priv->menu_mode) - stream->type = STREAMTYPE_MENU|STREAMTYPE_SEEKABLE; - else stream->type = STREAMTYPE_SEEKABLE|STREAMTYPE_PROGRAM; - } - else done=1; - } - if(!event) dvdnav_priv->cpos += DVD_BLOCK_SIZE; - de->event=event; -} - -static int __FASTCALL__ __dvdnav_read(stream_t *stream,stream_packet_t *sp) -{ - dvdnav_event_t de; - unsigned len=sp->len; - if(tevent && tevent_full) - { - sp->len=tevent->len; - sp->type=tevent->event; - memcpy(sp->buf,tevent->details,tevent->len); - tevent_full=0; - return sp->len; - } - de.len=sp->len; - de.details=sp->buf; - dvdnav_stream_read(stream,&de); - sp->len=de.len; - sp->type=de.event; - if(tevent && !sp->type) - { - len -= sp->len; - while(len) - { - de.len=len; - de.details=&sp->buf[sp->len]; - dvdnav_stream_read(stream,&de); - if(de.event) - { - tevent->len=de.len; - tevent->event=de.event; - memcpy(tevent->details,de.details,de.len); - tevent_full=1; - break; - } - if(de.len<0 || (!de.event&&de.len==0)) break; - sp->len += de.len; - len-=de.len; - } - } - return sp->len; -} - -static off_t __FASTCALL__ __dvdnav_seek(stream_t *stream,off_t pos) -{ - dvdnav_priv_t *dvdnav_priv=stream->priv; - uint32_t newpos=0; - uint32_t length=1; - uint32_t sector; - - if (pos==0) - { - dvdnav_priv->started=0; - dvdnav_priv->cpos=0; - return 0; - } - sector=pos/DVD_BLOCK_SIZE; - dvdnav_sector_search(dvdnav_priv->dvdnav,sector,SEEK_SET); - usleep(0); /* wait for HOP_CHANNEL event */ - dvdnav_get_position(dvdnav_priv->dvdnav, &newpos, &length); - if(newpos > sector) newpos=sector; - dvdnav_priv->cpos = (newpos)*2048; - /* reset pts_fix after seeking */ - { - dvdnav_priv->vobu_s_pts= - dvdnav_priv->vobu_e_pts= - stream->stream_pts=0; - } - return dvdnav_priv->cpos; -} - -static off_t __FASTCALL__ __dvdnav_tell(const stream_t *stream) -{ - dvdnav_priv_t *dvdnav_priv=stream->priv; - return (off_t)dvdnav_priv->cpos; -} - -static void __FASTCALL__ __dvdnav_close(stream_t *stream) -{ - dvdnav_priv_t *dvdnav_priv=stream->priv; - dvdnav_close(dvdnav_priv->dvdnav); - mp_free(dvdnav_priv); - if(tevent) { mp_free(tevent->details); mp_free(tevent); } -} - -/** - * \brief mp_dvdnav_get_highlight() get dvdnav highlight struct - * \param stream: - stream pointer - * \param hl : - highlight struct pointer - */ -static void mp_dvdnav_get_highlight (const stream_t *stream, rect_highlight_t *hl) { - dvdnav_priv_t *priv = (dvdnav_priv_t *) stream->priv; - int button; - dvdnav_highlight_area_t ha; - pci_t *pnavpci = NULL; - - dvdnav_get_current_highlight(priv->dvdnav, &button); - pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav); - /* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */ - dvdnav_get_highlight_area(pnavpci, button, 1, &ha); - - hl->sx = ha.sx; - hl->sy = ha.sy; - hl->ex = ha.ex; - hl->ey = ha.ey; -} - -static void __FASTCALL__ dvdnav_event_handler(const stream_t* s,const stream_packet_t*sp) -{ - demux_stream_t *d_audio=s->demuxer->audio; - dvdnav_priv_t *priv=s->priv; - switch(sp->type) { - case DVDNAV_BLOCK_OK: /* be silent about this one */ - break; - case DVDNAV_HIGHLIGHT: { - pci_t *pnavpci = NULL; - dvdnav_highlight_event_t *_hlev = (dvdnav_highlight_event_t*)(sp->buf); - int btnum; - int display_mode=1; - MSG_V("DVDNAV_HIGHLIGHT: %i %i %i %i\n",_hlev->sx,_hlev->sy,_hlev->ex,_hlev->ey); - if (!priv || !priv->dvdnav) return; - memcpy(&priv->hlev,_hlev,sizeof(dvdnav_highlight_event_t)); - pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav); - if (!pnavpci) return; - - dvdnav_get_current_highlight (priv->dvdnav, &(priv->hlev.buttonN)); - priv->hlev.display = display_mode; /* show */ - - if (priv->hlev.buttonN > 0 && pnavpci->hli.hl_gi.btn_ns > 0 && priv->hlev.display) { - for (btnum = 0; btnum < pnavpci->hli.hl_gi.btn_ns; btnum++) { - btni_t *btni = &(pnavpci->hli.btnit[btnum]); - - if (priv->hlev.buttonN == (unsigned)btnum + 1) { - priv->hlev.sx = min (btni->x_start, btni->x_end); - priv->hlev.ex = max (btni->x_start, btni->x_end); - priv->hlev.sy = min (btni->y_start, btni->y_end); - priv->hlev.ey = max (btni->y_start, btni->y_end); - - priv->hlev.palette = (btni->btn_coln == 0) ? 0 : - pnavpci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0]; - break; - } - } - } else { /* hide button or no button */ - priv->hlev.sx = priv->hlev.ex = 0; - priv->hlev.sy = priv->hlev.ey = 0; - priv->hlev.palette = priv->hlev.buttonN = 0; - } - break; - } - case DVDNAV_STILL_FRAME: { - const dvdnav_still_event_t *still_event = (const dvdnav_still_event_t*)(sp->buf); - MSG_DBG2( "######## DVDNAV Event: Still Frame: %d sec(s)\n", still_event->length ); - while (dvdnav_stream_sleeping(s)) { - usleep(1000); /* 1ms */ - } - dvdnav_stream_sleep(s,still_event->length); - break; - } - case DVDNAV_STOP: - MSG_DBG2( "DVDNAV Event: Nav Stop\n" ); - break; - case DVDNAV_NOP: - MSG_V("DVDNAV Event: Nav NOP\n"); - break; -#if 0 - case DVDNAV_SPU_STREAM_CHANGE: { - const dvdnav_spu_stream_change_event_t * stream_change=(const dvdnav_spu_stream_change_event_t*)(sp->buf); - MSG_DBG2("DVDNAV Event: Nav SPU Stream Change: phys_wide: %d phys_letterbox: %d phys_panscan: %d logical: %d\n", - stream_change->physical_wide, - stream_change->physical_letterbox, - stream_change->physical_pan_scan, - stream_change->logical); - if (vo_data->spudec && mp_conf.dvdsub_id!=stream_change->physical_wide) { - MSG_DBG2("d_dvdsub->id change: was %d is now %d\n", - d_dvdsub->id,stream_change->physical_wide); - // FIXME: need a better way to change SPU id - d_dvdsub->id=mp_conf.dvdsub_id=stream_change->physical_wide; - if (vo_data->spudec) spudec_reset(vo_data->spudec); - } - break; - } -#endif - case DVDNAV_AUDIO_STREAM_CHANGE: { - int aid_temp; - const dvdnav_audio_stream_change_event_t *stream_change = (const dvdnav_audio_stream_change_event_t*)(sp->buf); - MSG_DBG2("DVDNAV Event: Nav Audio Stream Change: phys: %d logical: %d\n", - stream_change->physical, - stream_change->logical); - aid_temp=stream_change->physical; - if (aid_temp>=0) aid_temp+=128; // FIXME: is this sane? - if (d_audio && mp_conf.audio_id!=aid_temp) { - MSG_DBG2("d_audio->id change: was %d is now %d\n", - d_audio->id,aid_temp); - // FIXME: need a bettery way to change audio stream id - d_audio->id=mp_conf.dvdsub_id=aid_temp; - mpxp_resync_audio_stream(); - } - break; - } - case DVDNAV_VTS_CHANGE:{ - const dvdnav_vts_change_event_t *evts = (const dvdnav_vts_change_event_t *)(sp->buf); - MSG_V("DVDNAV Event: Nav VTS Change %u\n",evts->new_domain); - } - break; - case DVDNAV_CELL_CHANGE: { - const dvdnav_cell_change_event_t *ecell=(const dvdnav_cell_change_event_t*)(sp->buf); - MSG_V("DVDNAV_CELL_CHANGE: N=%i pgN=%i cell_start=%f pg_start=%f cell_length=%f pg_length=%f pgc_length=%f\n" - ,ecell->cellN - ,ecell->pgN - ,ecell->cell_start/90000. - ,ecell->pg_start/90000. - ,ecell->cell_length/90000. - ,ecell->pg_length/90000. - ,ecell->pgc_length/90000.); - } - break; - case DVDNAV_NAV_PACKET: - MSG_V("DVDNAV Event: Nav Packet\n"); - break; - case DVDNAV_SPU_CLUT_CHANGE: - MSG_DBG2("DVDNAV Event: Nav SPU CLUT Change\n"); - if(sp->len!=64) MSG_WARN("DVDNAV Event: Nav SPU CLUT Change: %i bytes <> 64\n",sp->len); - // send new palette to SPU decoder - if (vo_data->spudec) spudec_update_palette(vo_data->spudec,(const unsigned int *)(sp->buf)); - break; - } -} - -static void __FASTCALL__ dvdnav_cmd_handler(const stream_t* s,unsigned cmd) -{ - dvdnav_priv_t *dvdnav_priv=s->priv; - int button; - pci_t *pci = dvdnav_get_current_nav_pci(dvdnav_priv->dvdnav); - switch (cmd) { - case MP_CMD_DVDNAV_UP: - dvdnav_upper_button_select(dvdnav_priv->dvdnav,pci); - break; - case MP_CMD_DVDNAV_DOWN: - dvdnav_lower_button_select(dvdnav_priv->dvdnav,pci); - break; - case MP_CMD_DVDNAV_LEFT: - dvdnav_left_button_select(dvdnav_priv->dvdnav,pci); - break; - case MP_CMD_DVDNAV_RIGHT: - dvdnav_right_button_select(dvdnav_priv->dvdnav,pci); - break; - case MP_CMD_DVDNAV_MENU: { - int title,part; - MSG_V("Menu call\n"); - dvdnav_current_title_info(dvdnav_priv->dvdnav, &title, &part); - if(title>0) { - if(dvdnav_menu_call(dvdnav_priv->dvdnav, DVD_MENU_Part) == DVDNAV_STATUS_OK - || dvdnav_menu_call(dvdnav_priv->dvdnav, DVD_MENU_Title) == DVDNAV_STATUS_OK) - break; - } - dvdnav_menu_call(dvdnav_priv->dvdnav, DVD_MENU_Root); - dvdnav_button_select(dvdnav_priv->dvdnav, pci, 1); - } - break; - case MP_CMD_DVDNAV_SELECT: - dvdnav_button_activate(dvdnav_priv->dvdnav,pci); - break; - default: - MSG_V("Weird DVD Nav cmd %d\n",cmd); - break; - } - dvdnav_get_current_highlight(dvdnav_priv->dvdnav, &button); - dvdnav_button_select(dvdnav_priv->dvdnav,pci,button); -} - -static MPXP_Rc __FASTCALL__ __dvdnav_ctrl(const stream_t *s,unsigned cmd,any_t*args) -{ - dvdnav_priv_t *dvdnav_priv=s->priv; - switch(cmd) { - case SCTRL_TXT_GET_STREAM_NAME: { - const char *title_str; - if (dvdnav_get_title_string(dvdnav_priv->dvdnav,&title_str)==DVDNAV_STATUS_OK) { - strncpy(args,title_str,256); - ((char *)args)[255]=0; - return MPXP_Ok; - } - } - break; - case SCTRL_VID_GET_PALETTE: { - unsigned* pal; - pal=dvdnav_stream_get_palette(s); - *((unsigned **)args)=pal; - return MPXP_Ok; - } - break; - case SCTRL_VID_GET_HILIGHT: { - mp_dvdnav_get_highlight (s,args); - return MPXP_Ok; - } - case SCRTL_EVT_HANDLE: { - dvdnav_event_handler(s,args); - return MPXP_Ok; - } - break; - case SCRTL_MPXP_CMD: { - dvdnav_cmd_handler(s,(unsigned)args); - return MPXP_Ok; - } - default: break; - } - return MPXP_False; -} - -const stream_driver_t dvdnav_stream= -{ - "dvdnav://", - "reads multimedia stream with using of libdvdnav library", - __dvdnav_open, - __dvdnav_read, - __dvdnav_seek, - __dvdnav_tell, - __dvdnav_close, - __dvdnav_ctrl -}; -#endif Copied: mplayerxp/libmpstream/s_dvdnav.cpp (from rev 414, mplayerxp/libmpstream/s_dvdnav.c) =================================================================== --- mplayerxp/libmpstream/s_dvdnav.cpp (rev 0) +++ mplayerxp/libmpstream/s_dvdnav.cpp 2012-11-20 17:01:59 UTC (rev 417) @@ -0,0 +1,660 @@ +/* + s_dvdnav - DVDNAV's stream interface +*/ +#include "mp_config.h" +#ifdef USE_DVDNAV +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "stream.h" +#include "help_mp.h" +#include "libmpdemux/demuxer.h" +#include "libmpsub/spudec.h" +#include "libvo/sub.h" +#include "input2/input.h" +#include "mplayerxp.h" +#include "stream_msg.h" + +#include <dvdnav/dvdnav.h> +#include <stdio.h> +#include <unistd.h> +#include "osdep/timer.h" +#include "osdep/mplib.h" +#include "mrl.h" +#define DVD_BLOCK_SIZE 2048 + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif + +extern vo_data_t* vo_data; + +typedef struct { + dvdnav_t * dvdnav; /* handle to libdvdnav stuff */ + char * filename; /* path */ + int ignore_timers; /* should timers be skipped? */ + int sleeping; /* are we sleeping? */ + unsigned int sleep_until; /* timer */ + int started; /* Has mplayer initialization finished? */ + unsigned char prebuf[STREAM_BUFFER_SIZE]; /* prefill buffer */ + int prelen; /* length of prefill buffer */ + off_t cpos; + float vobu_s_pts,vobu_e_pts; + int menu_mode; + dvdnav_highlight_event_t hlev; +} dvdnav_priv_t; + +typedef struct { + int event; /* event number fromd dvdnav_events.h */ + any_t* details; /* event details */ + int len; /* bytes in details */ +} dvdnav_event_t; + +static int dvd_nav_still=0; /* are we on a still picture? */ +static int dvd_nav_skip_opening=0; /* skip opening stalls? */ + +static void __FASTCALL__ dvdnav_stream_ignore_timers(stream_t * stream, int ignore) { + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + dvdnav_priv->ignore_timers=ignore; +} + +static dvdnav_priv_t * __FASTCALL__ new_dvdnav_stream(stream_t *stream,const char * filename) { + const char * title_str; + dvdnav_priv_t *dvdnav_priv; + + if (!filename) + return NULL; + + if (!(dvdnav_priv=(dvdnav_priv_t*)mp_calloc(1,sizeof(*dvdnav_priv)))) + return NULL; + + if (!(dvdnav_priv->filename=mp_strdup(filename))) { + mp_free(dvdnav_priv); + return NULL; + } + + if(dvdnav_open(&(dvdnav_priv->dvdnav),dvdnav_priv->filename)!=DVDNAV_STATUS_OK) + { + mp_free(dvdnav_priv->filename); + mp_free(dvdnav_priv); + return NULL; + } + + if (!dvdnav_priv->dvdnav) { + mp_free(dvdnav_priv); + return NULL; + } + + stream->priv=dvdnav_priv; + dvdnav_stream_ignore_timers(stream,dvd_nav_skip_opening); + + if(1) //from vlc: if not used dvdnav from cvs will fail + { + int len, event; + uint8_t buf[2048]; + + dvdnav_get_next_block(dvdnav_priv->dvdnav,buf,&event,&len); + dvdnav_sector_search(dvdnav_priv->dvdnav, 0, SEEK_SET); + } + + /* turn on/off dvdnav caching */ + dvdnav_set_readahead_flag(dvdnav_priv->dvdnav,mp_conf.s_cache_size?0:1); + + /* report the title?! */ + if (dvdnav_get_title_string(dvdnav_priv->dvdnav,&title_str)==DVDNAV_STATUS_OK) { + MSG_INFO("Title: '%s'\n",title_str); + } + check_pin("stream",stream->pin,STREAM_PIN); + return dvdnav_priv; +} + +static void __FASTCALL__ dvdnav_stream_sleep(const stream_t * stream, int seconds) { + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + + if (!dvdnav_priv->started) return; + + dvdnav_priv->sleeping=0; + switch (seconds) { + case 0: + return; + case 0xff: + MSG_V( "Sleeping indefinately\n" ); + dvdnav_priv->sleeping=2; + break; + default: + MSG_V( "Sleeping %d sec(s)\n", seconds ); + dvdnav_priv->sleep_until = GetTimer();// + seconds*1000000; + dvdnav_priv->sleeping=1; + break; + } + //if (dvdnav_priv->started) dvd_nav_still=1; +} + +static int __FASTCALL__ dvdnav_stream_sleeping(const stream_t * stream) { + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + unsigned int now; + + if (!dvdnav_priv) return 0; + + if(dvdnav_priv->sleeping) + { + now=GetTimer(); + while(dvdnav_priv->sleeping>1 || now<dvdnav_priv->sleep_until) { +// usec_sleep(1000); /* 1ms granularity */ + return 1; + } + dvdnav_still_skip(dvdnav_priv->dvdnav); // continue past... + dvdnav_priv->sleeping=0; + MSG_V("%s: woke up!\n",__FUNCTION__); + } + dvd_nav_still=0; + MSG_V("%s: active\n",__FUNCTION__); + return 0; +} + +static unsigned int * __FASTCALL__ dvdnav_stream_get_palette(const stream_t * stream) { +#if 0 /* latest versions if libdvdnav don't provide such info */ + dvdnav_priv_t *dvdnav_priv=stream->priv; + if (!dvdnav_priv) { + MSG_V("%s: NULL dvdnav_priv\n",__FUNCTION__); + return NULL; + } + if (!dvdnav_priv->dvdnav) { + MSG_V("%s: NULL dvdnav_priv->dvdnav\n",__FUNCTION__); + return NULL; + } + if (!dvdnav_priv->dvdnav->vm) { + MSG_V("%s: NULL dvdnav_priv->dvdnav->vm\n",__FUNCTION__); + return NULL; + } + if (!dvdnav_priv->dvdnav->vm->state.pgc) { + MSG_V("%s: NULL dvdnav_priv->dvdnav->vm->state.pgc\n",__FUNCTION__); + return NULL; + } + return dvdnav_priv->dvdnav->vm->state.pgc->palette; +#else + UNUSED(stream); +#endif + return 0; +} + +static dvdnav_event_t *tevent; +static int tevent_full=0; +static int dvd_title=-1,dvd_chapter=-1; + +static const mrl_config_t dvdnavopts_conf[]={ + { "skipopening", &dvd_nav_skip_opening, MRL_TYPE_BOOL, 0, 1 }, + { "T", &dvd_title, MRL_TYPE_INT, 0, 999 }, + { "C", &dvd_chapter, MRL_TYPE_INT, 0, 999 }, + { NULL, NULL, 0, 0, 0 } +}; + +static MPXP_Rc __FASTCALL__ __dvdnav_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) +{ + const char *param; + char *dvd_device; + int ntitles; + UNUSED(flags); + UNUSED(libinput); + stream->type = STREAMTYPE_SEEKABLE|STREAMTYPE_PROGRAM; + param=mrl_parse_line(filename,NULL,NULL,&dvd_device,NULL); + if(strcmp(param,"help") == 0) { + MSG_HINT("Usage: dvdnav://<title>,<chapter>\n"); + return MPXP_False; + } + param=mrl_parse_params(param,dvdnavopts_conf); + if (!(stream->priv=new_dvdnav_stream(stream,dvd_device?dvd_device:DEFAULT_DVD_DEVICE))) { + MSG_ERR(MSGTR_CantOpenDVD,dvd_device?dvd_device:DEFAULT_DVD_DEVICE); + if(!dvd_device) { + if (!(stream->priv=new_dvdnav_stream(stream,DEFAULT_CDROM_DEVICE))) + MSG_ERR(MSGTR_CantOpenDVD,DEFAULT_CDROM_DEVICE); + else + goto dvd_ok; + } + mp_free(stream->priv); + if(dvd_device) mp_free(dvd_device); + return MPXP_False; + } + dvd_ok: + if(dvd_device) mp_free(dvd_device); + ((dvdnav_priv_t *)stream->priv)->started=1; + if(mp_conf.s_cache_size) { + tevent = new(zeromem) dvdnav_event_t; + if(tevent) + if((tevent->details=mp_malloc(DVD_BLOCK_SIZE))==NULL) { + mp_free(tevent); + tevent=NULL; + } + } + tevent_full=0; + /* By rumours 1 PGC == whole movie */ + dvdnav_set_PGC_positioning_flag(((dvdnav_priv_t *)stream->priv)->dvdnav,1); + ntitles=0; + dvdnav_get_number_of_titles(((dvdnav_priv_t *)stream->priv)->dvdnav,&ntitles); + MSG_INFO(MSGTR_DVDnumTitles,ntitles); + if(dvd_title != -1) { + int nparts; + dvdnav_get_number_of_parts(((dvdnav_priv_t *)stream->priv)->dvdnav,dvd_title,&nparts); + MSG_INFO(MSGTR_DVDnumChapters,dvd_title,nparts); + if(dvd_chapter != -1) dvdnav_part_play(((dvdnav_priv_t *)stream->priv)->dvdnav,dvd_title,dvd_chapter); + else dvdnav_title_play(((dvdnav_priv_t *)stream->priv)->dvdnav,dvd_title); + ((dvdnav_priv_t *)stream->priv)->cpos=stream->start_pos=2048; /* disallow dvdnav_reset */ + dvdnav_current_title_info(((dvdnav_priv_t *)stream->priv)->dvdnav,&dvd_title,&dvd_chapter); + MSG_INFO("Playing %i part of %i title\n",dvd_chapter,dvd_title); + } + stream->sector_size=tevent?DVD_BLOCK_SIZE*10:DVD_BLOCK_SIZE; + if( dvdnav_is_domain_vmgm(((dvdnav_priv_t *)stream->priv)->dvdnav) || + dvdnav_is_domain_vtsm(((dvdnav_priv_t *)stream->priv)->dvdnav)) + stream->type = STREAMTYPE_MENU|STREAMTYPE_SEEKABLE; + check_pin("stream",stream->pin,STREAM_PIN); + return MPXP_Ok; +} + +static void __FASTCALL__ dvdnav_stream_read(stream_t * stream, dvdnav_event_t*de) { + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + int event = DVDNAV_NOP; + int done; + + if (!de->len) return; + de->len=-1; + if (!dvdnav_priv) return; + if (!de->details) return; + + if (dvd_nav_still) { + MSG_V("%s: got a stream_read while I should be asleep!\n",__FUNCTION__); + de->event=DVDNAV_STILL_FRAME; + de->len=0; + return; + } + done=0; + while(!done) + { + if (dvdnav_get_next_block(dvdnav_priv->dvdnav,reinterpret_cast<uint8_t*>(de->details),&event,&de->len)!=DVDNAV_STATUS_OK) + { + MSG_ERR( "Error getting next block from DVD (%s)\n",dvdnav_err_to_string(dvdnav_priv->dvdnav) ); + de->len=-1; + } + if(event == DVDNAV_STILL_FRAME) + { + dvdnav_still_skip(dvdnav_priv->dvdnav); /* don't let dvdnav stall on this image */ + while (dvdnav_stream_sleeping(stream)) usleep(1000); /* 1ms */ + } +#ifdef DVDNAV_WAIT + else + if(event == DVDNAV_WAIT) + { + usleep(1000); + dvdnav_wait_skip(dvdnav_priv->dvdnav); /* don't let dvdnav stall on this image */ + } +#endif + else + if(event == DVDNAV_NAV_PACKET) + { + /* Try to suppress PTS discontinuity here!!! */ + pci_t *_this; + float vobu_s_pts,vobu_e_pts; + _this=dvdnav_get_current_nav_pci(dvdnav_priv->dvdnav); + vobu_s_pts=_this->pci_gi.vobu_s_ptm/90000.; + vobu_e_pts=_this->pci_gi.vobu_e_ptm/90000.; + MSG_V("Handling NAV_PACKET: vobu_s_ptm=%f vobu_e_ptm=%f e_eltm=%f\n" + ,vobu_s_pts + ,vobu_e_pts + ,(float)_this->pci_gi.e_eltm.second+_this->pci_gi.e_eltm.minute*60.+_this->pci_gi.e_eltm.hour*3600.); + if(vobu_s_pts < dvdnav_priv->vobu_e_pts) + { + stream->stream_pts += dvdnav_priv->vobu_e_pts-vobu_s_pts; + MSG_V("DVD's discontinuities found! Applying delta: %f\n",stream->stream_pts); + } + else stream->stream_pts = vobu_s_pts; + dvdnav_priv->vobu_s_pts = vobu_s_pts; + dvdnav_priv->vobu_e_pts = vobu_e_pts; + } + else + if(event == DVDNAV_CELL_CHANGE) + { + int ct,cc; + dvdnav_current_title_info(dvdnav_priv->dvdnav, &ct, &cc); + if(ct<=0) { + dvdnav_priv->menu_mode=1; + MSG_V("entering menu mode: %i %i\n",ct,cc); + MSG_V("vmgm: %i vtsm: %i\n", + dvdnav_is_domain_vmgm(dvdnav_priv->dvdnav), + dvdnav_is_domain_vtsm(dvdnav_priv->dvdnav)); + } + else { + dvdnav_priv->menu_mode=0; + MSG_V("leaving menu mode: %i %i\n",ct,cc); + } + /**/ + if(dvdnav_priv->menu_mode) + stream->type = STREAMTYPE_MENU|STREAMTYPE_SEEKABLE; + else stream->type = STREAMTYPE_SEEKABLE|STREAMTYPE_PROGRAM; + } + else done=1; + } + if(!event) dvdnav_priv->cpos += DVD_BLOCK_SIZE; + de->event=event; +} + +static int __FASTCALL__ __dvdnav_read(stream_t *stream,stream_packet_t *sp) +{ + dvdnav_event_t de; + unsigned len=sp->len; + if(tevent && tevent_full) + { + sp->len=tevent->len; + sp->type=tevent->event; + memcpy(sp->buf,tevent->details,tevent->len); + tevent_full=0; + return sp->len; + } + de.len=sp->len; + de.details=sp->buf; + dvdnav_stream_read(stream,&de); + sp->len=de.len; + sp->type=de.event; + if(tevent && !sp->type) + { + len -= sp->len; + while(len) + { + de.len=len; + de.details=&sp->buf[sp->len]; + dvdnav_stream_read(stream,&de); + if(de.event) + { + tevent->len=de.len; + tevent->event=de.event; + memcpy(tevent->details,de.details,de.len); + tevent_full=1; + break; + } + if(de.len<0 || (!de.event&&de.len==0)) break; + sp->len += de.len; + len-=de.len; + } + } + return sp->len; +} + +static off_t __FASTCALL__ __dvdnav_seek(stream_t *stream,off_t pos) +{ + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + uint32_t newpos=0; + uint32_t length=1; + uint32_t sector; + + if (pos==0) + { + dvdnav_priv->started=0; + dvdnav_priv->cpos=0; + return 0; + } + sector=pos/DVD_BLOCK_SIZE; + dvdnav_sector_search(dvdnav_priv->dvdnav,sector,SEEK_SET); + usleep(0); /* wait for HOP_CHANNEL event */ + dvdnav_get_position(dvdnav_priv->dvdnav, &newpos, &length); + if(newpos > sector) newpos=sector; + dvdnav_priv->cpos = (newpos)*2048; + /* reset pts_fix after seeking */ + { + dvdnav_priv->vobu_s_pts= + dvdnav_priv->vobu_e_pts= + stream->stream_pts=0; + } + return dvdnav_priv->cpos; +} + +static off_t __FASTCALL__ __dvdnav_tell(const stream_t *stream) +{ + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + return (off_t)dvdnav_priv->cpos; +} + +static void __FASTCALL__ __dvdnav_close(stream_t *stream) +{ + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(stream->priv); + dvdnav_close(dvdnav_priv->dvdnav); + mp_free(dvdnav_priv); + if(tevent) { mp_free(tevent->details); mp_free(tevent); } +} + +/** + * \brief mp_dvdnav_get_highlight() get dvdnav highlight struct + * \param stream: - stream pointer + * \param hl : - highlight struct pointer + */ +static void mp_dvdnav_get_highlight (const stream_t *stream, rect_highlight_t *hl) { + dvdnav_priv_t *priv = reinterpret_cast<dvdnav_priv_t*>(stream->priv); + int button; + dvdnav_highlight_area_t ha; + pci_t *pnavpci = NULL; + + dvdnav_get_current_highlight(priv->dvdnav, &button); + pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav); + /* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */ + dvdnav_get_highlight_area(pnavpci, button, 1, &ha); + + hl->sx = ha.sx; + hl->sy = ha.sy; + hl->ex = ha.ex; + hl->ey = ha.ey; +} + +static void __FASTCALL__ dvdnav_event_handler(const stream_t* s,const stream_packet_t*sp) +{ + demux_stream_t *d_audio=s->demuxer->audio; + dvdnav_priv_t *priv=reinterpret_cast<dvdnav_priv_t*>(s->priv); + switch(sp->type) { + case DVDNAV_BLOCK_OK: /* be silent about this one */ + break; + case DVDNAV_HIGHLIGHT: { + pci_t *pnavpci = NULL; + dvdnav_highlight_event_t *_hlev = (dvdnav_highlight_event_t*)(sp->buf); + int btnum; + int display_mode=1; + MSG_V("DVDNAV_HIGHLIGHT: %i %i %i %i\n",_hlev->sx,_hlev->sy,_hlev->ex,_hlev->ey); + if (!priv || !priv->dvdnav) return; + memcpy(&priv->hlev,_hlev,sizeof(dvdnav_highlight_event_t)); + pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav); + if (!pnavpci) return; + + dvdnav_get_current_highlight (priv->dvdnav, reinterpret_cast<int32_t*>(&(priv->hlev.buttonN))); + priv->hlev.display = display_mode; /* show */ + + if (priv->hlev.buttonN > 0 && pnavpci->hli.hl_gi.btn_ns > 0 && priv->hlev.display) { + for (btnum = 0; btnum < pnavpci->hli.hl_gi.btn_ns; btnum++) { + btni_t *btni = &(pnavpci->hli.btnit[btnum]); + + if (priv->hlev.buttonN == (unsigned)btnum + 1) { + priv->hlev.sx = min (btni->x_start, btni->x_end); + priv->hlev.ex = max (btni->x_start, btni->x_end); + priv->hlev.sy = min (btni->y_start, btni->y_end); + priv->hlev.ey = max (btni->y_start, btni->y_end); + + priv->hlev.palette = (btni->btn_coln == 0) ? 0 : + pnavpci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0]; + break; + } + } + } else { /* hide button or no button */ + priv->hlev.sx = priv->hlev.ex = 0; + priv->hlev.sy = priv->hlev.ey = 0; + priv->hlev.palette = priv->hlev.buttonN = 0; + } + break; + } + case DVDNAV_STILL_FRAME: { + const dvdnav_still_event_t *still_event = (const dvdnav_still_event_t*)(sp->buf); + MSG_DBG2( "######## DVDNAV Event: Still Frame: %d sec(s)\n", still_event->length ); + while (dvdnav_stream_sleeping(s)) { + usleep(1000); /* 1ms */ + } + dvdnav_stream_sleep(s,still_event->length); + break; + } + case DVDNAV_STOP: + MSG_DBG2( "DVDNAV Event: Nav Stop\n" ); + break; + case DVDNAV_NOP: + MSG_V("DVDNAV Event: Nav NOP\n"); + break; +#if 0 + case DVDNAV_SPU_STREAM_CHANGE: { + const dvdnav_spu_stream_change_event_t * stream_change=(const dvdnav_spu_stream_change_event_t*)(sp->buf); + MSG_DBG2("DVDNAV Event: Nav SPU Stream Change: phys_wide: %d phys_letterbox: %d phys_panscan: %d logical: %d\n", + stream_change->physical_wide, + stream_change->physical_letterbox, + stream_change->physical_pan_scan, + stream_change->logical); + if (vo_data->spudec && mp_conf.dvdsub_id!=stream_change->physical_wide) { + MSG_DBG2("d_dvdsub->id change: was %d is now %d\n", + d_dvdsub->id,stream_change->physical_wide); + // FIXME: need a better way to change SPU id + d_dvdsub->id=mp_conf.dvdsub_id=stream_change->physical_wide; + if (vo_data->spudec) spudec_reset(vo_data->spudec); + } + break; + } +#endif + case DVDNAV_AUDIO_STREAM_CHANGE: { + int aid_temp; + const dvdnav_audio_stream_change_event_t *stream_change = (const dvdnav_audio_stream_change_event_t*)(sp->buf); + MSG_DBG2("DVDNAV Event: Nav Audio Stream Change: phys: %d logical: %d\n", + stream_change->physical, + stream_change->logical); + aid_temp=stream_change->physical; + if (aid_temp>=0) aid_temp+=128; // FIXME: is this sane? + if (d_audio && mp_conf.audio_id!=aid_temp) { + MSG_DBG2("d_audio->id change: was %d is now %d\n", + d_audio->id,aid_temp); + // FIXME: need a bettery way to change audio stream id + d_audio->id=mp_conf.dvdsub_id=aid_temp; + mpxp_resync_audio_stream(); + } + break; + } + case DVDNAV_VTS_CHANGE:{ + const dvdnav_vts_change_event_t *evts = (const dvdnav_vts_change_event_t *)(sp->buf); + MSG_V("DVDNAV Event: Nav VTS Change %u\n",evts->new_domain); + } + break; + case DVDNAV_CELL_CHANGE: { + const dvdnav_cell_change_event_t *ecell=(const dvdnav_cell_change_event_t*)(sp->buf); + MSG_V("DVDNAV_CELL_CHANGE: N=%i pgN=%i cell_start=%f pg_start=%f cell_length=%f pg_length=%f pgc_length=%f\n" + ,ecell->cellN + ,ecell->pgN + ,ecell->cell_start/90000. + ,ecell->pg_start/90000. + ,ecell->cell_length/90000. + ,ecell->pg_length/90000. + ,ecell->pgc_length/90000.); + } + break; + case DVDNAV_NAV_PACKET: + MSG_V("DVDNAV Event: Nav Packet\n"); + break; + case DVDNAV_SPU_CLUT_CHANGE: + MSG_DBG2("DVDNAV Event: Nav SPU CLUT Change\n"); + if(sp->len!=64) MSG_WARN("DVDNAV Event: Nav SPU CLUT Change: %i bytes <> 64\n",sp->len); + // send new palette to SPU decoder + if (vo_data->spudec) spudec_update_palette(vo_data->spudec,(const unsigned int *)(sp->buf)); + break; + } +} + +static void __FASTCALL__ dvdnav_cmd_handler(const stream_t* s,unsigned cmd) +{ + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(s->priv); + int button; + pci_t *pci = dvdnav_get_current_nav_pci(dvdnav_priv->dvdnav); + switch (cmd) { + case MP_CMD_DVDNAV_UP: + dvdnav_upper_button_select(dvdnav_priv->dvdnav,pci); + break; + case MP_CMD_DVDNAV_DOWN: + dvdnav_lower_button_select(dvdnav_priv->dvdnav,pci); + break; + case MP_CMD_DVDNAV_LEFT: + dvdnav_left_button_select(dvdnav_priv->dvdnav,pci); + break; + case MP_CMD_DVDNAV_RIGHT: + dvdnav_right_button_select(dvdnav_priv->dvdnav,pci); + break; + case MP_CMD_DVDNAV_MENU: { + int title,part; + MSG_V("Menu call\n"); + dvdnav_current_title_info(dvdnav_priv->dvdnav, &title, &part); + if(title>0) { + if(dvdnav_menu_call(dvdnav_priv->dvdnav, DVD_MENU_Part) == DVDNAV_STATUS_OK + || dvdnav_menu_call(dvdnav_priv->dvdnav, DVD_MENU_Title) == DVDNAV_STATUS_OK) + break; + } + dvdnav_menu_call(dvdnav_priv->dvdnav, DVD_MENU_Root); + dvdnav_button_select(dvdnav_priv->dvdnav, pci, 1); + } + break; + case MP_CMD_DVDNAV_SELECT: + dvdnav_button_activate(dvdnav_priv->dvdnav,pci); + break; + default: + MSG_V("Weird DVD Nav cmd %d\n",cmd); + break; + } + dvdnav_get_current_highlight(dvdnav_priv->dvdnav, &button); + dvdnav_button_select(dvdnav_priv->dvdnav,pci,button); +} + +static MPXP_Rc __FASTCALL__ __dvdnav_ctrl(const stream_t *s,unsigned cmd,any_t*args) +{ + dvdnav_priv_t *dvdnav_priv=reinterpret_cast<dvdnav_priv_t*>(s->priv); + switch(cmd) { + case SCTRL_TXT_GET_STREAM_NAME: { + const char *title_str; + if (dvdnav_get_title_string(dvdnav_priv->dvdnav,&title_str)==DVDNAV_STATUS_OK) { + strncpy(reinterpret_cast<char*>(args),title_str,256); + ((char *)args)[255]=0; + return MPXP_Ok; + } + } + break; + case SCTRL_VID_GET_PALETTE: { + unsigned* pal; + pal=dvdnav_stream_get_palette(s); + *((unsigned **)args)=pal; + return MPXP_Ok; + } + break; + case SCTRL_VID_GET_HILIGHT: { + mp_dvdnav_get_highlight (s,reinterpret_cast<rect_highlight_t*>(args)); + return MPXP_Ok; + } + case SCRTL_EVT_HANDLE: { + dvdnav_event_handler(s,reinterpret_cast<stream_packet_t*>(args)); + return MPXP_Ok; + } + break; + case SCRTL_MPXP_CMD: { + dvdnav_cmd_handler(s,(long)args); + return MPXP_Ok; + } + default: break; + } + return MPXP_False; +} + +extern const stream_driver_t dvdnav_stream= +{ + "dvdnav://", + "reads multimedia stream with using of libdvdnav library", + __dvdnav_open, + __dvdnav_read, + __dvdnav_seek, + __dvdnav_tell, + __dvdnav_close, + __dvdnav_ctrl +}; +#endif Deleted: mplayerxp/libmpstream/s_ffmpeg.c =================================================================== --- mplayerxp/libmpstream/s_ffmpeg.c 2012-11-20 16:18:38 UTC (rev 416) +++ mplayerxp/libmpstream/s_ffmpeg.c 2012-11-20 17:01:59 UTC (rev 417) @@ -1,94 +0,0 @@ -#include "mp_config.h" -#include "mplayerxp.h" - -#include <dlfcn.h> -#include "mp_conf_lavc.h" -#include "libmpcodecs/codecs_ld.h" -#include "osdep/mplib.h" -#include "stream.h" -#include "stream_msg.h" - -typedef struct ffmpeg_priv_s -{ - URLContext *ctx; - off_t spos; -}ffmpeg_priv_t; - -static int ffmpeg_int_cb(any_t*op) { return 0; } /* non interrupt blicking */ -static AVIOInterruptCB int_cb = { ffmpeg_int_cb, NULL }; - -static int __FASTCALL__ ffmpeg_read(stream_t *s, stream_packet_t*sp) -{ - ffmpeg_priv_t*p=s->priv; - sp->len = ffurl_read_complete(p->ctx, sp->buf, sp->len); - if(sp->len>0) p->spos += sp->len; - return sp->len; -} - -static off_t __FASTCALL__ ffmpeg_seek(stream_t *s, off_t newpos) -{ - ffmpeg_priv_t*p=s->priv; - p->spos = newpos; - p->spos = ffurl_seek(p->ctx, newpos, SEEK_SET); - return p->spos; -} - -static off_t ffmpeg_tell(const stream_t *s) -{ - ffmpeg_priv_t*p=s->priv; - return p->spos; -} - -static MPXP_Rc __FASTCALL__ ffmpeg_ctrl(const stream_t *s, unsigned cmd, any_t*arg) -{ - UNUSED(s); - UNUSED(cmd); - UNUSED(arg); - return MPXP_Unknown; -} - -static void __FASTCALL__ ffmpeg_close(stream_t *stream) -{ - ffmpeg_priv_t*p=stream->priv; - ffurl_close(p->ctx); - mp_free(p); -} - -static const char prefix[] = "ffmpeg://"; - -static MPXP_Rc __FASTCALL__ ffmpeg_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) -{ - URLContext *ctx = NULL; - ffmpeg_priv_t *p; - int64_t size; - - UNUSED(flags); - UNUSED(libinput); - av_register_all(); - MSG_V("[ffmpeg] Opening %s\n", filename); - - if (ffurl_open(&ctx, filename, 0, &int_cb, NULL) < 0) return MPXP_False; - p = mp_malloc(sizeof(ffmpeg_priv_t)); - p->ctx = ctx; - p->spos = 0; - size = ffurl_size(ctx); - if (size >= 0) - stream->end_pos = size; - stream->type = STREAMTYPE_SEEKABLE; - stream->priv = p; - if (ctx->is_streamed) stream->type = STREAMTYPE_STREAM; - check_pin("stream",stream->pin,STREAM_PIN); - return MPXP_Ok; -} - -const stream_driver_t ffmpeg_stream = -{ - "ffmpeg:", - "reads multimedia stream through ffmpeg library", - ffmpeg_open, - ffmpeg_read, - ffmpeg_seek, - ffmpeg_tell, - ffmpeg_close, - ffmpeg_ctrl -}; Copied: mplayerxp/libmpstream/s_ffmpeg.cpp (from rev 414, mplayerxp/libmpstream/s_ffmpeg.c) =================================================================== --- mplayerxp/libmpstream/s_ffmpeg.cpp (rev 0) +++ mplayerxp/libmpstream/s_ffmpeg.cpp 2012-11-20 17:01:59 UTC (rev 417) @@ -0,0 +1,94 @@ +#include "mp_config.h" +#include "mplayerxp.h" + +#include <dlfcn.h> +#include "mp_conf_lavc.h" +#include "libmpcodecs/codecs_ld.h" +#include "osdep/mplib.h" +#include "stream.h" +#include "stream_msg.h" + +typedef struct ffmpeg_priv_s +{ + URLContext *ctx; + off_t spos; +}ffmpeg_priv_t; + +static int ffmpeg_int_cb(any_t*op) { return 0; } /* non interrupt blicking */ +static AVIOInterruptCB int_cb = { ffmpeg_int_cb, NULL }; + +static int __FASTCALL__ ffmpeg_read(stream_t *s, stream_packet_t*sp) +{ + ffmpeg_priv_t*p=reinterpret_cast<ffmpeg_priv_t*>(s->priv); + sp->len = ffurl_read_complete(p->ctx, reinterpret_cast<unsigned char*>(sp->buf), sp->len); + if(sp->len>0) p->spos += sp->len; + return sp->len; +} + +static off_t __FASTCALL__ ffmpeg_seek(stream_t *s, off_t newpos) +{ + ffmpeg_priv_t*p=reinterpret_cast<ffmpeg_priv_t*>(s->priv); + p->spos = newpos; + p->spos = ffurl_seek(p->ctx, newpos, SEEK_SET); + return p->spos; +} + +static off_t ffmpeg_tell(const stream_t *s) +{ + ffmpeg_priv_t*p=reinterpret_cast<ffmpeg_priv_t*>(s->priv); + return p->spos; +} + +static MPXP_Rc __FASTCALL__ ffmpeg_ctrl(const stream_t *s, unsigned cmd, any_t*arg) +{ + UNUSED(s); + UNUSED(cmd); + UNUSED(arg); + return MPXP_Unknown; +} + +static void __FASTCALL__ ffmpeg_close(stream_t *stream) +{ + ffmpeg_priv_t*p=reinterpret_cast<ffmpeg_priv_t*>(stream->priv); + ffurl_close(p->ctx); + mp_free(p); +} + +static const char prefix[] = "ffmpeg://"; + +static MPXP_Rc __FASTCALL__ ffmpeg_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) +{ + URLContext *ctx = NULL; + ffmpeg_priv_t *p; + int64_t size; + + UNUSED(flags); + UNUSED(libinput); + av_register_all(); + MSG_V("[ffmpeg] Opening %s\n", filename); + + if (ffurl_open(&ctx, filename, 0, &int_cb, NULL) < 0) return MPXP_False; + p = new(zeromem) ffmpeg_priv_t; + p->ctx = ctx; + p->spos = 0; + size = ffurl_size(ctx); + if (size >= 0) + stream->end_pos = size; + stream->type = STREAMTYPE_SEEKABLE; + stream->priv = p; + if (ctx->is_streamed) stream->type = STREAMTYPE_STREAM; + check_pin("stream",stream->pin,STREAM_PIN); + return MPXP_Ok; +} + +extern const stream_driver_t ffmpeg_stream = +{ + "ffmpeg:", + "reads multimedia stream through ffmpeg library", + ffmpeg_open, + ffmpeg_read, + ffmpeg_seek, + ffmpeg_tell, + ffmpeg_close, + ffmpeg_ctrl +}; Deleted: mplayerxp/libmpstream/s_file.c =================================================================== --- mplayerxp/libmpstream/s_file.c 2012-11-20 16:18:38 UTC (rev 416) +++ mplayerxp/libmpstream/s_file.c 2012-11-20 17:01:59 UTC (rev 417) @@ -1,124 +0,0 @@ -/* - s_file - stream interface for file i/o. -*/ -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifndef __USE_GNU -#define __USE_GNU -#endif -#include <unistd.h> -#include <fcntl.h> - -#include "mplayerxp.h" -#include "stream.h" -#include "osdep/mplib.h" - -typedef struct file_priv_s -{ - int was_open; - off_t spos; -}file_priv_t; - - -static MPXP_Rc __FASTCALL__ file_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) -{ - UNUSED(flags); - UNUSED(libinput); - if(!(stream->priv = mp_malloc(sizeof(file_priv_t)))) return MPXP_False; - if(strcmp(filename,"-")==0) stream->fd=0; - else stream->fd=open(filename,O_RDONLY); - if(stream->fd<0) { mp_free(stream->priv); return MPXP_False; } - ((file_priv_t*)stream->priv)->was_open = stream->fd==0?0:1; - stream->end_pos = lseek(stream->fd,0,SEEK_END); - lseek(stream->fd,0,SEEK_SET); - if(stream->end_pos == -1) stream->type = STREAMTYPE_STREAM; - else stream->type = STREAMTYPE_SEEKABLE; - /* decreasing number of packet from 256 to 10 speedups cache2 from 3.27% to 1.26% - with full speed 1.04% for -nocache */ - /* Note: Please locate sector_size changinf after all read/write operations of open() function */ - stream->sector_size=mp_conf.s_cache_size?mp_conf.s_cache_size*1024/10:STREAM_BUFFER_SIZE; - ((file_priv_t*)stream->priv)->spos = 0; - check_pin("stream",stream->pin,STREAM_PIN); - return MPXP_Ok; -} - -static MPXP_Rc __FASTCALL__ stdin_open(stream_t *stream,const char *filename,unsigned flags) { - UNUSED(filename); - return file_open(NULL,stream,"-",flags); -} - -#ifndef TEMP_FAILURE_RETRY -#define TEMP_FAILURE_RETRY(x) (x) -#endif - -static int __FASTCALL__ file_read(stream_t*stream,stream_packet_t*sp) -{ -/* - Should we repeate read() again on these errno: `EAGAIN', `EIO' ??? -*/ - file_priv_t*p=stream->priv; - sp->type=0; - sp->len = TEMP_FAILURE_RETRY(read(stream->fd,sp->buf,sp->len)); - if(sp->len>0) p->spos += sp->len; - return sp->len; -} - -# define TEMP_FAILURE_RETRY64(expression) \ - (__extension__ \ - ({ long long int __result; \ - do __result = (long long int) (expression); \ - while (__result == -1LL && errno == EINTR); \ - __result; })) - -static off_t __FASTCALL__ file_seek(stream_t*stream,off_t pos) -{ - file_priv_t*p=stream->priv; - p->spos=TEMP_FAILURE_RETRY64(lseek(stream->fd,pos,SEEK_SET)); - return p->spos; -} - -static off_t __FASTCALL__ file_tell(const stream_... [truncated message content] |