[Mplayerxp-cvslog] SF.net SVN: mplayerxp:[427] mplayerxp
Brought to you by:
olov
From: <nic...@us...> - 2012-11-21 17:14:52
|
Revision: 427 http://mplayerxp.svn.sourceforge.net/mplayerxp/?rev=427&view=rev Author: nickols_k Date: 2012-11-21 17:14:42 +0000 (Wed, 21 Nov 2012) Log Message: ----------- convert last .c source into .cpp and remove RND_RENAME. RND_NAMES much better to apply to classes but not to standalone functions Modified Paths: -------------- TODO mplayerxp/input2/input.cpp mplayerxp/input2/input.h mplayerxp/libao2/audio_out.cpp mplayerxp/libao2/audio_out.h mplayerxp/libao2/mixer.cpp mplayerxp/libmpcodecs/ad_vorbis.cpp mplayerxp/libmpcodecs/dec_audio.cpp mplayerxp/libmpcodecs/dec_audio.h mplayerxp/libmpcodecs/dec_video.cpp mplayerxp/libmpcodecs/dec_video.h mplayerxp/libmpdemux/demuxer.cpp mplayerxp/libmpstream/Makefile mplayerxp/libmpstream/mrl.h mplayerxp/libmpstream/stream.cpp mplayerxp/libmpstream/stream.h mplayerxp/libplaytree/asxparser.cpp mplayerxp/libplaytree/playtreeparser.cpp mplayerxp/libvo/video_out.cpp mplayerxp/libvo/video_out.h mplayerxp/mp_msg.h mplayerxp/mplayerxp.cpp mplayerxp/osdep/mp_malloc.cpp mplayerxp/osdep/mplib.cpp mplayerxp/osdep/mplib.h mplayerxp/postproc/af.cpp mplayerxp/postproc/af.h mplayerxp/postproc/af_ao2.cpp mplayerxp/postproc/vf.cpp mplayerxp/postproc/vf.h mplayerxp/postproc/vf_vo.cpp mplayerxp/xmpcore/xmp_adecoder.cpp mplayerxp/xmpcore/xmp_aplayer.cpp mplayerxp/xmpcore/xmp_vdecoder.cpp mplayerxp/xmpcore/xmp_vplayer.cpp Added Paths: ----------- mplayerxp/libmpstream/s_dvdread.cpp Removed Paths: ------------- mplayerxp/libmpstream/s_dvdread.c Modified: TODO =================================================================== --- TODO 2012-11-21 16:08:43 UTC (rev 426) +++ TODO 2012-11-21 17:14:42 UTC (rev 427) @@ -18,7 +18,6 @@ ... if(avcodec_open2(lavc_guard.unprotect(priv->ctx),priv->codec,NULL)<0){ ... -- use c++ instead of plain c - use libavfilter instead of some af_* vf_* - test frame-dropping - remove all #define with values (they maybe intercepted in other .h files) Modified: mplayerxp/input2/input.cpp =================================================================== --- mplayerxp/input2/input.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/input2/input.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -747,7 +747,7 @@ filter->ctx = ctx; filter->next = priv->cmd_filters; priv->cmd_filters = filter; - SECURE_NAME9(rnd_fill)(priv->antiviral_hole,offsetof(priv_t,cmd_binds)-offsetof(priv_t,antiviral_hole)); + rnd_fill(priv->antiviral_hole,offsetof(priv_t,cmd_binds)-offsetof(priv_t,antiviral_hole)); } static const char* mp_input_find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) { @@ -1345,7 +1345,7 @@ if(priv->in_file_fd==0) getch2_disable(); } -any_t* RND_RENAME0(mp_input_open)(void) { +any_t* mp_input_open(void) { priv_t* priv=new(zeromem) priv_t; priv->ar_state=-1; priv->in_file_fd=-1; Modified: mplayerxp/input2/input.h =================================================================== --- mplayerxp/input2/input.h 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/input2/input.h 2012-11-21 17:14:42 UTC (rev 427) @@ -149,7 +149,7 @@ extern void mp_cmd_free(mp_cmd_t* cmd); // When you create a new driver you should add it in this 2 functions. -extern any_t* RND_RENAME0(mp_input_open)(void); +extern any_t* mp_input_open(void); extern void mp_input_close(any_t* handle); extern void mp_input_print_keys(any_t*handle); Modified: mplayerxp/libao2/audio_out.cpp =================================================================== --- mplayerxp/libao2/audio_out.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libao2/audio_out.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -185,7 +185,7 @@ MSG_INFO("\n"); } -MPXP_Rc __FASTCALL__ RND_RENAME4(ao_register)(ao_data_t* ao,const char *driver_name,unsigned flags) +MPXP_Rc __FASTCALL__ ao_register(ao_data_t* ao,const char *driver_name,unsigned flags) { priv_t* priv=reinterpret_cast<priv_t*>(ao->opaque); unsigned i; @@ -208,7 +208,7 @@ return priv->audio_out->info; } -ao_data_t* __FASTCALL__ RND_RENAME5(ao_init)(const char *subdevice) +ao_data_t* __FASTCALL__ ao_init(const char *subdevice) { ao_data_t* ao; ao=new(zeromem) ao_data_t; @@ -217,8 +217,8 @@ ao->buffersize=-1; ao->opaque=mp_malloc(sizeof(priv_t)); priv_t* priv=reinterpret_cast<priv_t*>(ao->opaque); - SECURE_NAME9(rnd_fill)(priv->antiviral_hole,sizeof(priv_t)); - SECURE_NAME9(rnd_fill)(ao->antiviral_hole,offsetof(ao_data_t,samplerate)-offsetof(ao_data_t,antiviral_hole)); + rnd_fill(priv->antiviral_hole,sizeof(priv_t)); + rnd_fill(ao->antiviral_hole,offsetof(ao_data_t,samplerate)-offsetof(ao_data_t,antiviral_hole)); priv->audio_out=NULL; return ao; } @@ -265,7 +265,7 @@ return 0; } -unsigned __FASTCALL__ RND_RENAME6(ao_play)(ao_data_t*ao,const any_t* data,unsigned len,unsigned flags) +unsigned __FASTCALL__ ao_play(ao_data_t*ao,const any_t* data,unsigned len,unsigned flags) { if(ao) { priv_t* priv=reinterpret_cast<priv_t*>(ao->opaque); @@ -289,7 +289,7 @@ } } -MPXP_Rc __FASTCALL__ RND_RENAME7(ao_control)(const ao_data_t*ao,int cmd,long arg) +MPXP_Rc __FASTCALL__ ao_control(const ao_data_t*ao,int cmd,long arg) { if(ao) { priv_t* priv=reinterpret_cast<priv_t*>(ao->opaque); Modified: mplayerxp/libao2/audio_out.h =================================================================== --- mplayerxp/libao2/audio_out.h 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libao2/audio_out.h 2012-11-21 17:14:42 UTC (rev 427) @@ -101,17 +101,17 @@ extern int __FASTCALL__ ao_format_bits(int format); extern void ao_print_help( void ); -extern MPXP_Rc __FASTCALL__ RND_RENAME4(ao_register)(ao_data_t* ao,const char *driver_name,unsigned flags); +extern MPXP_Rc __FASTCALL__ ao_register(ao_data_t* ao,const char *driver_name,unsigned flags); extern const ao_info_t* ao_get_info( const ao_data_t* ao ); -extern ao_data_t* __FASTCALL__ RND_RENAME5(ao_init)(const char *subdevice); +extern ao_data_t* __FASTCALL__ ao_init(const char *subdevice); extern MPXP_Rc __FASTCALL__ ao_configure(ao_data_t* priv,unsigned rate,unsigned channels,unsigned format); extern void __FASTCALL__ ao_uninit(ao_data_t* priv); extern void __FASTCALL__ ao_reset(ao_data_t* priv); extern unsigned __FASTCALL__ ao_get_space(const ao_data_t* priv); -extern unsigned __FASTCALL__ RND_RENAME6(ao_play)(ao_data_t* priv,const any_t* data,unsigned len,unsigned flags); +extern unsigned __FASTCALL__ ao_play(ao_data_t* priv,const any_t* data,unsigned len,unsigned flags); extern float __FASTCALL__ ao_get_delay(const ao_data_t* priv); extern void __FASTCALL__ ao_pause(ao_data_t* priv); extern void __FASTCALL__ ao_resume(ao_data_t* priv); -extern MPXP_Rc __FASTCALL__ RND_RENAME7(ao_control)(const ao_data_t* priv,int cmd,long arg); +extern MPXP_Rc __FASTCALL__ ao_control(const ao_data_t* priv,int cmd,long arg); #endif Modified: mplayerxp/libao2/mixer.cpp =================================================================== --- mplayerxp/libao2/mixer.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libao2/mixer.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -12,7 +12,7 @@ { ao_control_vol_t vol; *l=0; *r=0; - if(MPXP_Ok != RND_RENAME7(ao_control)(ao,AOCONTROL_GET_VOLUME,(long)&vol)) return; + if(MPXP_Ok != ao_control(ao,AOCONTROL_GET_VOLUME,(long)&vol)) return; *r=vol.right; *l=vol.left; } @@ -21,7 +21,7 @@ { ao_control_vol_t vol; vol.right=r; vol.left=l; - RND_RENAME7(ao_control)(ao,AOCONTROL_SET_VOLUME,(long)&vol); + ao_control(ao,AOCONTROL_SET_VOLUME,(long)&vol); } #define MIXER_CHANGE 3 Modified: mplayerxp/libmpcodecs/ad_vorbis.cpp =================================================================== --- mplayerxp/libmpcodecs/ad_vorbis.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpcodecs/ad_vorbis.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -114,7 +114,7 @@ #define OGG_FMT16 AFMT_S16_LE #endif sh->afmt=OGG_FMT16; - if(RND_RENAME7(ao_control)(ao_data,AOCONTROL_QUERY_FORMAT,OGG_FMT32) == MPXP_Ok) { + if(ao_control(ao_data,AOCONTROL_QUERY_FORMAT,OGG_FMT32) == MPXP_Ok) { sh->afmt=OGG_FMT32; } // assume 128kbit if bitrate not specified in the header Modified: mplayerxp/libmpcodecs/dec_audio.cpp =================================================================== --- mplayerxp/libmpcodecs/dec_audio.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpcodecs/dec_audio.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -33,7 +33,7 @@ const ad_functions_t* mpadec; }priv_t; -any_t* RND_RENAME2(mpca_init)(sh_audio_t *sh_audio) +any_t* mpca_init(sh_audio_t *sh_audio) { const char *afm=NULL,*ac=NULL; const audio_probe_t* aprobe=NULL; @@ -183,7 +183,7 @@ unsigned in_samplerate, unsigned in_channels, unsigned in_format, unsigned* out_samplerate, unsigned* out_channels, unsigned* out_format){ char strbuf[200]; - af_stream_t* afs=RND_RENAME6(af_new)(sh_audio); + af_stream_t* afs=af_new(sh_audio); // input format: same as codec's output format: afs->input.rate = in_samplerate; @@ -203,7 +203,7 @@ afs->input.rate,afs->input.nch,(afs->input.format&MPAF_BPS_MASK)*8); // let's autoprobe it! - if(MPXP_Ok != RND_RENAME7(af_init)(afs,0)){ + if(MPXP_Ok != af_init(afs,0)){ delete afs; return MPXP_False; // failed :( } @@ -230,7 +230,7 @@ unsigned out_minsize, unsigned out_maxsize){ char strbuf[200]; af_stream_t* afs=sh_audio->afilter; - if(!afs) afs = RND_RENAME6(af_new)(sh_audio); + if(!afs) afs = af_new(sh_audio); // input format: same as codec's output format: afs->input.rate = in_samplerate; @@ -250,7 +250,7 @@ afs->output.rate,afs->output.nch,(afs->output.format&MPAF_BPS_MASK)*8,ao_format_name(mpaf2afmt(afs->output.format))); // let's autoprobe it! - if(MPXP_Ok != RND_RENAME7(af_init)(afs,1)){ + if(MPXP_Ok != af_init(afs,1)){ sh_audio->afilter=NULL; delete afs; return MPXP_False; // failed :( @@ -295,7 +295,7 @@ out_minsize,out_maxsize); } -unsigned RND_RENAME3(mpca_decode)(any_t *opaque,unsigned char *buf,unsigned minlen,unsigned maxlen,unsigned buflen,float *pts) +unsigned mpca_decode(any_t *opaque,unsigned char *buf,unsigned minlen,unsigned maxlen,unsigned buflen,float *pts) { priv_t* priv = (priv_t*)opaque; sh_audio_t* sh_audio = priv->parent; @@ -335,7 +335,7 @@ ,0); // xp_idx afd->audio=buf; afd->len=len; - pafd=RND_RENAME8(af_play)(sh_audio->afilter,afd); + pafd=af_play(sh_audio->afilter,afd); afd->audio=NULL; // fake no buffer if(!pafd) { Modified: mplayerxp/libmpcodecs/dec_audio.h =================================================================== --- mplayerxp/libmpcodecs/dec_audio.h 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpcodecs/dec_audio.h 2012-11-21 17:14:42 UTC (rev 427) @@ -6,9 +6,9 @@ // dec_audio.c: extern const ad_functions_t* __FASTCALL__ mpca_find_driver(const char *name); -extern any_t* __FASTCALL__ RND_RENAME2(mpca_init)(sh_audio_t *sh_audio); +extern any_t* __FASTCALL__ mpca_init(sh_audio_t *sh_audio); extern void __FASTCALL__ mpca_uninit(any_t *handle); -extern unsigned __FASTCALL__ RND_RENAME3(mpca_decode)(any_t *handle,unsigned char *buf,unsigned minlen,unsigned maxlen,unsigned buflen,float *pts); +extern unsigned __FASTCALL__ mpca_decode(any_t *handle,unsigned char *buf,unsigned minlen,unsigned maxlen,unsigned buflen,float *pts); extern void __FASTCALL__ mpca_resync_stream(any_t *handle); extern void __FASTCALL__ mpca_skip_frame(any_t *handle); struct codecs_st; Modified: mplayerxp/libmpcodecs/dec_video.cpp =================================================================== --- mplayerxp/libmpcodecs/dec_video.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpcodecs/dec_video.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -144,7 +144,7 @@ return priv; } -any_t * RND_RENAME3(mpcv_init)(sh_video_t *sh_video,const char* codecname,const char * vfm,int status,any_t*libinput){ +any_t * mpcv_init(sh_video_t *sh_video,const char* codecname,const char * vfm,int status,any_t*libinput){ int done=0; const video_probe_t* vprobe; sh_video->codec=NULL; @@ -280,7 +280,7 @@ extern vo_data_t* vo_data; static void update_subtitle(sh_video_t *sh_video,float v_pts,unsigned idx); -int RND_RENAME4(mpcv_decode)(any_t *opaque,const enc_frame_t* frame){ +int mpcv_decode(any_t *opaque,const enc_frame_t* frame){ priv_t* priv=(priv_t*)opaque; sh_video_t* sh_video = priv->parent; vf_instance_t* vf; @@ -465,13 +465,13 @@ MSG_WARN("'%s' ",vo_format_name(sh->codec->outfmt[ind])); } MSG_WARN("Trying -vf fmtcvt\n"); - sc=vf=RND_RENAME9(vf_open_filter)(vf,sh,"fmtcvt",NULL,libinput); + sc=vf=vf_open_filter(vf,sh,"fmtcvt",NULL,libinput); goto csp_again; } else if(palette==1){ MSG_V("vd: Trying -vf palette...\n"); palette=-1; - vf=RND_RENAME9(vf_open_filter)(vf,sh,"palette",NULL,libinput); + vf=vf_open_filter(vf,sh,"palette",NULL,libinput); goto csp_again; } else { // sws failed, if the last filter (vf_vo) support MPEGPES try to append vf_lavc @@ -505,7 +505,7 @@ if(vo_data->flags&VFCAP_FLIPPED) vo_FLIP_REVERT(vo_data); if(vo_FLIP(vo_data) && !(vo_data->flags&VFCAP_FLIP)){ // we need to flip, but no flipping filter avail. - sh->vfilter=vf=RND_RENAME9(vf_open_filter)(vf,sh,"flip",NULL,libinput); + sh->vfilter=vf=vf_open_filter(vf,sh,"flip",NULL,libinput); } // time to do aspect ratio corrections... Modified: mplayerxp/libmpcodecs/dec_video.h =================================================================== --- mplayerxp/libmpcodecs/dec_video.h 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpcodecs/dec_video.h 2012-11-21 17:14:42 UTC (rev 427) @@ -6,10 +6,10 @@ #include "libmpdemux/stheader.h" // dec_video.c: -extern any_t* __FASTCALL__ RND_RENAME3(mpcv_init)(sh_video_t *sh_video, const char *codec_name,const char *family,int status,any_t*libinput); +extern any_t* __FASTCALL__ mpcv_init(sh_video_t *sh_video, const char *codec_name,const char *family,int status,any_t*libinput); extern void __FASTCALL__ mpcv_uninit(any_t *handle); extern any_t* __FASTCALL__ mpcv_ffmpeg_init(sh_video_t*,any_t* libinput); -extern int __FASTCALL__ RND_RENAME4(mpcv_decode)(any_t *handle,const enc_frame_t* frame); +extern int __FASTCALL__ mpcv_decode(any_t *handle,const enc_frame_t* frame); extern MPXP_Rc __FASTCALL__ mpcv_get_quality_max(any_t *handle,unsigned *qual); extern MPXP_Rc __FASTCALL__ mpcv_set_quality(any_t *handle,int quality); Modified: mplayerxp/libmpdemux/demuxer.cpp =================================================================== --- mplayerxp/libmpdemux/demuxer.cpp 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpdemux/demuxer.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -115,7 +115,7 @@ demux_stream_t* new_demuxer_stream(struct demuxer_s *demuxer,int id){ demux_stream_t* ds=(demux_stream_t*)mp_malloc(sizeof(demux_stream_t)); - SECURE_NAME9(rnd_fill)(ds->antiviral_hole,offsetof(demux_stream_t,pin)-offsetof(demux_stream_t,antiviral_hole)); + rnd_fill(ds->antiviral_hole,offsetof(demux_stream_t,pin)-offsetof(demux_stream_t,antiviral_hole)); ds->pin=DS_PIN; ds->buffer_pos=ds->buffer_size=0; ds->buffer=NULL; @@ -143,7 +143,7 @@ demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id){ demuxer_t *d=(demuxer_t*)mp_mallocz(sizeof(demuxer_t)); - SECURE_NAME9(rnd_fill)(d->antiviral_hole,offsetof(demuxer_t,pin)-offsetof(demuxer_t,antiviral_hole)); + rnd_fill(d->antiviral_hole,offsetof(demuxer_t,pin)-offsetof(demuxer_t,antiviral_hole)); d->pin=DEMUX_PIN; d->stream=stream; d->movi_start=stream->start_pos; @@ -602,14 +602,14 @@ #endif if(audio_stream) { - as = RND_RENAME2(open_stream)(libinput,audio_stream,&afmt,NULL); + as = open_stream(libinput,audio_stream,&afmt,NULL); if(!as) { MSG_ERR("Can't open audio stream: %s\n",audio_stream); return NULL; } } if(sub_stream) { - ss = RND_RENAME2(open_stream)(libinput,sub_stream,&sfmt,NULL); + ss = open_stream(libinput,sub_stream,&sfmt,NULL); if(!ss) { MSG_ERR("Can't open subtitles stream: %s\n",sub_stream); return NULL; Modified: mplayerxp/libmpstream/Makefile =================================================================== --- mplayerxp/libmpstream/Makefile 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpstream/Makefile 2012-11-21 17:14:42 UTC (rev 427) @@ -19,7 +19,7 @@ CXXSRCS += s_dvdnav.cpp endif ifeq ($(USE_DVDREAD),yes) -SRCS += s_dvdread.c +CXXSRCS += s_dvdread.cpp endif CXXSRCS += url.cpp ifeq ($(USE_OSS_AUDIO),yes) Modified: mplayerxp/libmpstream/mrl.h =================================================================== --- mplayerxp/libmpstream/mrl.h 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpstream/mrl.h 2012-11-21 17:14:42 UTC (rev 427) @@ -3,9 +3,6 @@ #define __MPXP_MRL_H 1 #include "mp_config.h" -#ifdef __cplusplus -extern "C" { -#endif /** Parses line which contains MRL and splits it on components. * @param line source line to be parsed * @param user buffer which will contain username if present (maybe NULL) @@ -55,7 +52,4 @@ * @see mrl_parse_line **/ extern const char * mrl_parse_params(const char *param,const mrl_config_t * args); -#ifdef __cplusplus -} #endif -#endif Deleted: mplayerxp/libmpstream/s_dvdread.c =================================================================== --- mplayerxp/libmpstream/s_dvdread.c 2012-11-21 16:08:43 UTC (rev 426) +++ mplayerxp/libmpstream/s_dvdread.c 2012-11-21 17:14:42 UTC (rev 427) @@ -1,827 +0,0 @@ -/* - s_dvdread - DVDREAD stream interface -*/ - -#include "mp_config.h" -#include "mplayerxp.h" -#ifdef USE_DVDREAD -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include "stream.h" -#include "help_mp.h" -#include "stream_msg.h" -#include "osdep/mplib.h" - -#include <dvdread/dvd_reader.h> -#include <dvdread/ifo_types.h> -#include <dvdread/ifo_read.h> -#include <dvdread/nav_read.h> -#include "mrl.h" - -#undef DVDREAD_VERSION -#define DVDREAD_VERSION(maj,min,micro) ((maj)*10000 + (min)*100 + (micro)) - -/* - * Try to autodetect the libdvd-0.9.0 library - * (0.9.0 removed the <dvdread/dvd_udf.h> header, and moved the two defines - * DVD_VIDEO_LB_LEN and MAX_UDF_FILE_NAME_LEN from it to - * <dvdread/dvd_reader.h>) - */ -#if defined(DVD_VIDEO_LB_LEN) && defined(MAX_UDF_FILE_NAME_LEN) -#define LIBDVDREAD_VERSION DVDREAD_VERSION(0,9,0) -#else -#define LIBDVDREAD_VERSION DVDREAD_VERSION(0,8,0) -#endif - -typedef struct { - int id; // 0 - 31 mpeg; 128 - 159 ac3; 160 - 191 pcm - int language; - int type; - int channels; -} stream_language_t; - -typedef struct { - dvd_reader_t *dvd; - dvd_file_t *title; - ifo_handle_t *vmg_file; - tt_srpt_t *tt_srpt; - ifo_handle_t *vts_file; - vts_ptt_srpt_t *vts_ptt_srpt; - pgc_t *cur_pgc; - /* title sets */ - unsigned first_title,cur_title,last_title; -// - int cur_cell; - int last_cell; - int cur_pack; - int cell_last_pack; -// Navi: - int packs_left; - dsi_t dsi_pack; - pci_t pci_pack; - int angle_seek; - float vobu_s_pts,vobu_e_pts; -// audio datas - int nr_of_channels; - stream_language_t audio_streams[32]; -// subtitles - int nr_of_subtitles; - stream_language_t subtitles[32]; - - off_t spos; -} dvd_priv_t; - -static int dvd_chapter=1; -static int dvd_last_chapter=0; -static int dvd_angle=1; /**< some DVD discs contain scenes that can be viewed from multiple angles */ - -static const char * dvd_audio_stream_types[8] = - { "ac3","unknown","mpeg1","mpeg2ext","lpcm","unknown","dts" }; - -static const char * dvd_audio_stream_channels[8] = - { "unknown", "stereo", "unknown", "unknown", "unknown", "5.1", "6.1", "7.1" }; - -static int __FASTCALL__ dvd_chapter_from_cell(dvd_priv_t* dvd,int title,int cell) -{ - pgc_t * cur_pgc; - ptt_info_t* ptt; - int chapter = cell; - int pgc_id,pgn; - if(title < 0 || cell < 0){ - return 0; - } - /* for most DVD's chapter == cell */ - /* but there are more complecated cases... */ - if(chapter >= dvd->vmg_file->tt_srpt->title[title].nr_of_ptts){ - chapter = dvd->vmg_file->tt_srpt->title[title].nr_of_ptts-1; - } - title = dvd->tt_srpt->title[title].vts_ttn-1; - ptt = dvd->vts_file->vts_ptt_srpt->title[title].ptt; - while(chapter >= 0){ - pgc_id = ptt[chapter].pgcn; - pgn = ptt[chapter].pgn; - cur_pgc = dvd->vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc; - if(cell >= cur_pgc->program_map[pgn-1]-1){ - return chapter; - } - --chapter; - } - /* didn't find a chapter ??? */ - return chapter; -} - -static int __FASTCALL__ dvd_number_of_subs(stream_t *stream) -{ - dvd_priv_t *d; - if (!stream) return -1; - d = stream->priv; - if (!d) return -1; - return d->nr_of_subtitles; -} - -static int __FASTCALL__ dvd_aid_from_lang(stream_t *stream, unsigned char* lang){ -dvd_priv_t *d=stream->priv; -int code,i; - while(lang && strlen(lang)>=2){ - code=lang[1]|(lang[0]<<8); - for(i=0;i<d->nr_of_channels;i++){ - if(d->audio_streams[i].language==code){ - MSG_V("Selected DVD audio channel: %d language: %c%c\n", - d->audio_streams[i].id, lang[0],lang[1]); - return d->audio_streams[i].id; - } - } - lang+=2; while (lang[0]==',' || lang[0]==' ') ++lang; - } - MSG_WARN("No matching DVD audio language found!\n"); - return -1; -} - -static int __FASTCALL__ dvd_sid_from_lang(stream_t *stream, unsigned char* lang){ -dvd_priv_t *d=stream->priv; -int code,i; - while(lang && strlen(lang)>=2){ - code=lang[1]|(lang[0]<<8); - for(i=0;i<d->nr_of_subtitles;i++){ - if(d->subtitles[i].language==code){ - MSG_V("Selected DVD subtitle channel: %d language: %c%c\n", - d->subtitles[i].id, lang[0],lang[1]); - return d->subtitles[i].id; - } - } - lang+=2; while (lang[0]==',' || lang[0]==' ') ++lang; - } - MSG_WARN("No matching DVD subtitle language found!\n"); - return -1; -} - -static int __FASTCALL__ dvd_lang_from_sid(stream_t *stream, int id) -{ - dvd_priv_t *d; - if (!stream) return 0; - d = stream->priv; - if (!d) return 0; - if (id >= d->nr_of_subtitles) return 0; - return d->subtitles[id].language; -} - -static int __FASTCALL__ dvd_next_title(dvd_priv_t *d,int dvd_title) -{ - int ttn,pgc_id,pgn; - dvd_reader_t *dvd; - dvd_file_t *title; - ifo_handle_t *vmg_file; - tt_srpt_t *tt_srpt; - ifo_handle_t *vts_file; - - MSG_V("dvd_next_title %d\n",dvd_title); - - tt_srpt = d->tt_srpt; - vmg_file = d->vmg_file; - dvd = d->dvd; - if(d->vts_file) ifoClose(d->vts_file); - if(d->title) DVDCloseFile(d->title); - /** - * Load the VTS information for the title set our title is in. - */ - vts_file = ifoOpen( dvd, tt_srpt->title[dvd_title].title_set_nr ); - if( !vts_file ) { - MSG_ERR( MSGTR_DVDnoIFO, - tt_srpt->title[dvd_title].title_set_nr ); - ifoClose( vmg_file ); - DVDClose( dvd ); - return 0; - } - /** - * We've got enough info, time to open the title set data. - */ - title = DVDOpenFile( dvd, tt_srpt->title[dvd_title].title_set_nr, - DVD_READ_TITLE_VOBS ); - if( !title ) { - MSG_ERR( MSGTR_DVDnoVOBs, - tt_srpt->title[dvd_title].title_set_nr ); - ifoClose( vts_file ); - ifoClose( vmg_file ); - DVDClose( dvd ); - return 0; - } - d->vts_file=vts_file; - d->title=title; - - ttn = tt_srpt->title[dvd_title].vts_ttn - 1; - - /** - * Check number of audio channels and types - */ - { - const int ac3aid = 128; - const int dtsaid = 136; - const int mpegaid = 0; - const int pcmaid = 160; - - d->nr_of_channels=0; - - if ( vts_file->vts_pgcit ) - { - int i; - for ( i=0;i<8;i++ ) - if ( vts_file->vts_pgcit->pgci_srp[0].pgc->audio_control[i] & 0x8000 ) - { - audio_attr_t * audio = &vts_file->vtsi_mat->vts_audio_attr[i]; - int language = 0; - char tmp[] = "unknown"; - - if ( audio->lang_type == 1 ) - { - language=audio->lang_code; - tmp[0]=language>>8; - tmp[1]=language&0xff; - tmp[2]=0; - } - - d->audio_streams[d->nr_of_channels].language=language; - d->audio_streams[d->nr_of_channels].id=vts_file->vts_pgcit->pgci_srp[ttn].pgc->audio_control[i] >> 8 & 7; - switch ( audio->audio_format ) - { - case 0: // ac3 - d->audio_streams[d->nr_of_channels].id+=ac3aid; - break; - case 6: // dts - d->audio_streams[d->nr_of_channels].id+=dtsaid; - break; - case 2: // mpeg layer 1/2/3 - case 3: // mpeg2 ext - d->audio_streams[d->nr_of_channels].id+=mpegaid; - break; - case 4: // lpcm - d->audio_streams[d->nr_of_channels].id+=pcmaid; - break; - } - - d->audio_streams[d->nr_of_channels].type=audio->audio_format; - // Pontscho: to my mind, tha channels: - // 1 - stereo - // 5 - 5.1 - d->audio_streams[d->nr_of_channels].channels=audio->channels; - MSG_V("[open] audio stream: %d audio format: %s (%s) language: %s aid: %d\n", - d->nr_of_channels, - dvd_audio_stream_types[ audio->audio_format ], - dvd_audio_stream_channels[ audio->channels ], - tmp, - d->audio_streams[d->nr_of_channels].id - ); - - d->nr_of_channels++; - } - } - MSG_V("[open] number of audio channels on disk: %d.\n",d->nr_of_channels ); - } - - /** - * Check number of subtitles and language - */ - { - int i; - - d->nr_of_subtitles=0; - for ( i=0;i<32;i++ ) - if ( vts_file->vts_pgcit->pgci_srp[0].pgc->subp_control[i] & 0x80000000 ) - { - subp_attr_t * subtitle = &vts_file->vtsi_mat->vts_subp_attr[i]; - video_attr_t *video = &vts_file->vtsi_mat->vts_video_attr; - int language = 0; - char tmp[] = "unknown"; - - if ( subtitle->type == 1 ) - { - language=subtitle->lang_code; - tmp[0]=language>>8; - tmp[1]=language&0xff; - tmp[2]=0; - } - - d->subtitles[ d->nr_of_subtitles ].language=language; - d->subtitles[ d->nr_of_subtitles ].id=d->nr_of_subtitles; - if(video->display_aspect_ratio == 0) /* 4:3 */ - d->subtitles[d->nr_of_subtitles].id = vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i] >> 24 & 31; - else if(video->display_aspect_ratio == 3) /* 16:9 */ - d->subtitles[d->nr_of_subtitles].id = vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i] >> 8 & 31; - - MSG_V("[open] subtitle ( sid ): %d language: %s\n", - d->nr_of_subtitles, - tmp - ); - d->nr_of_subtitles++; - } - MSG_V("[open] number of subtitles on disk: %d\n",d->nr_of_subtitles ); - } - - /** - * Determine which program chain we want to watch. This is based on the - * chapter number. - */ - pgc_id = vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_chapter].pgcn; // local - pgn = vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_chapter].pgn; // local - d->cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc; - d->cur_cell = d->cur_pgc->program_map[pgn-1] - 1; // start playback here - d->packs_left=-1; // for Navi stuff - d->angle_seek=0; - /* XXX dvd_last_chapter is in the range 1..nr_of_ptts */ - if ( dvd_last_chapter > 0 && dvd_last_chapter < tt_srpt->title[dvd_title].nr_of_ptts ) { - pgn=vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_last_chapter].pgn; - d->last_cell=d->cur_pgc->program_map[pgn-1] - 1; - } - else - d->last_cell=d->cur_pgc->nr_of_cells; - - if( d->cur_pgc->cell_playback[d->cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle; - d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector; - d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector; - MSG_V( "DVD start cell: %d pack: 0x%X-0x%X \n",d->cur_cell,d->cur_pack,d->cell_last_pack); - - return 1; -} - -static int __FASTCALL__ dvd_next_cell(dvd_priv_t *d){ - int next_cell=d->cur_cell; - - MSG_V( "dvd_next_cell: next1=0x%X \n",next_cell); - - if( d->cur_pgc->cell_playback[ next_cell ].block_type - == BLOCK_TYPE_ANGLE_BLOCK ) { - while(next_cell<d->last_cell){ - if( d->cur_pgc->cell_playback[next_cell].block_mode - == BLOCK_MODE_LAST_CELL ) break; - ++next_cell; - } - } - MSG_V( "dvd_next_cell: next2=0x%X \n",next_cell); - - ++next_cell; - if(next_cell>=d->last_cell) return -1; // EOF - if( d->cur_pgc->cell_playback[next_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK ){ - next_cell+=dvd_angle; - if(next_cell>=d->last_cell) return -1; // EOF - } - MSG_V( "dvd_next_cell: next3=0x%X \n",next_cell); - return next_cell; -} - -static void __FASTCALL__ dvd_seek(stream_t* stream,dvd_priv_t *d,int pos); -static int __FASTCALL__ dvd_read_sector(stream_t* stream,dvd_priv_t *d,unsigned char* data){ - int len; -read_first: - if(d->packs_left==0){ - /** - * If we're not at the end of this cell, we can determine the next - * VOBU to display using the VOBU_SRI information section of the - * DSI. Using this value correctly follows the current angle, - * avoiding the doubled scenes in The Matrix, and makes our life - * really happy. - * - * Otherwise, we set our next address past the end of this cell to - * force the code above to go to the next cell in the program. - */ - if( d->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL ) { - d->cur_pack= d->dsi_pack.dsi_gi.nv_pck_lbn + - ( d->dsi_pack.vobu_sri.next_vobu & 0x3fffffff ); - MSG_V( "Navi new pos=0x%X \n",d->cur_pack); - } else { - // end of cell! find next cell! - MSG_V( "--- END OF CELL !!! ---\n"); - d->cur_pack=d->cell_last_pack+1; - } - } - -read_next: - - if(d->cur_pack>d->cell_last_pack){ - // end of cell! - int next=dvd_next_cell(d); - if(next>=0){ - d->cur_cell=next; - // if( d->cur_pgc->cell_playback[d->cur_cell].block_type - // == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle; - d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector; - d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector; - MSG_V( "DVD next cell: %d pack: 0x%X-0x%X \n",d->cur_cell,d->cur_pack,d->cell_last_pack); - } else - if(d->cur_title<d->last_title) - { - d->cur_title++; - dvd_next_title(d,d->cur_title); - goto read_first; - } - else return -1; // EOF - } - - len = DVDReadBlocks( d->title, d->cur_pack, 1, data ); - if(!len) return -1; //error -/* -Navigation packets are PES packets with a stream id 0xbf, i.e. -private stream 2. It's made up of PCI, Presentation Control Information -and DSI, Data Search Information. - - 0 6 7 0x3d4+0x6 0x3d4+0xb 0x3d4+0xc - +------+---------+----------------------+------+---------+-----------------+ - |Packet|Substream| PCI |Packet|Substream| DSI | - |Header| ID | Data |Header| ID | Data | - +------+---------+----------------------+------+---------+-----------------+ - - The packet head is just a PES packet header, a packet start code, a stream id -and a packet length. The first packet lenght is 0x3d4, the length of the PCI data -plus one. The second packet length is 0x3fa, the length of DSI data plus one. -The substream id for PCI packet is 0x00 and 0x01 for DSI. -*/ - if(data[38]==0 && data[39]==0 && data[40]==1 && data[41]==0xBF && - data[1024]==0 && data[1025]==0 && data[1026]==1 && data[1027]==0xBF){ - // found a Navi packet!!! -#if LIBDVDREAD_VERSION >= DVDREAD_VERSION(0,9,0) - navRead_DSI( &d->dsi_pack, &(data[DSI_START_BYTE]) ); - navRead_PCI( &d->pci_pack, &(data[DSI_START_BYTE-0x3DA]) ); -#else - navRead_DSI( &d->dsi_pack, &(data[DSI_START_BYTE]), sizeof(dsi_t)); - navRead_PCI( &d->pci_pack, &(data[DSI_START_BYTE-0x3DA]), sizeof(pci_t)); -#endif - /* - TODO!: if num_angles!=0 and d->dsi_pack.sml_agli.data[dvd_angle].address - doesn't work :( - > Invalid NAVIpacket! lba=30 gsi_navi=8002F pci_navi=8002F angle=0 - */ - if(d->cur_pack != d->dsi_pack.dsi_gi.nv_pck_lbn){ - MSG_V( "Invalid NAVIpacket! lba=%X gsi_navi=%X pci_navi=%X angle=%X\n" - ,d->cur_pack - ,d->dsi_pack.dsi_gi.nv_pck_lbn - ,d->pci_pack.pci_gi.nv_pck_lbn - ,d->dsi_pack.sml_agli.data[dvd_angle].address - ); - } else { - // process! - float vobu_s_pts,vobu_e_pts; - vobu_s_pts=d->pci_pack.pci_gi.vobu_s_ptm/90000.; - vobu_e_pts=d->pci_pack.pci_gi.vobu_e_ptm/90000.; - d->packs_left = d->dsi_pack.dsi_gi.vobu_ea; - MSG_V( "Found NAVI packet! lba=%X angle=%X len=%d vobu_s_pts=%f vobu_e_pts=%f\n" - ,d->cur_pack,d->packs_left - ,d->dsi_pack.sml_agli.data[dvd_angle].address - ,vobu_s_pts,vobu_e_pts); - - if(d->angle_seek){ - int i,skip=0; -#if defined(__GNUC__) && ( defined(__sparc__) || defined(hpux) ) - // workaround for a bug in the sparc/hpux version of gcc 2.95.X ... 3.2, - // it generates incorrect code for unaligned access to a packed - // structure member, resulting in an mplayer crash with a SIGBUS - // signal. - // - // See also gcc problem report PR c/7847: - // http://gcc.gnu.org/cgi-bin/gnatsweb.pl?database=gcc&cmd=view+audit-trail&pr=7847 - for(i=0;i<9;i++){ // check if all values zero: - typeof(d->dsi_pack.sml_agli.data[i].address) tmp_addr; - memcpy(&tmp_addr,&d->dsi_pack.sml_agli.data[i].address,sizeof(tmp_addr)); - if((skip=tmp_addr)!=0) break; - } -#else - for(i=0;i<9;i++) // check if all values zero: - if((skip=d->dsi_pack.sml_agli.data[i].address)!=0) break; -#endif - if(skip){ - // sml_agli table has valid data (at least one non-zero): - d->cur_pack=d->dsi_pack.dsi_gi.nv_pck_lbn+ - d->dsi_pack.sml_agli.data[dvd_angle].address; - d->angle_seek=0; - MSG_V("Angle-seek synced using sml_agli map! new_lba=0x%X\n",d->cur_pack); - } else { - // check if we're in the right cell, jump otherwise: - if( (d->dsi_pack.dsi_gi.vobu_c_idn==d->cur_pgc->cell_position[d->cur_cell].cell_nr) && - (d->dsi_pack.dsi_gi.vobu_vob_idn==d->cur_pgc->cell_position[d->cur_cell].vob_id_nr) ){ - d->angle_seek=0; - MSG_V("Angle-seek synced by cell/vob IDN search!\n"); - } else { - // wrong angle, skip this vobu: - d->cur_pack=d->dsi_pack.dsi_gi.nv_pck_lbn+ - d->dsi_pack.dsi_gi.vobu_ea; - d->angle_seek=2; // DEBUG - } - } - } - if(vobu_s_pts < d->vobu_e_pts) - { - stream->stream_pts += d->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; - d->vobu_s_pts = vobu_s_pts; - d->vobu_e_pts = vobu_e_pts; - } - ++d->cur_pack; - goto read_next; - } - - ++d->cur_pack; - if(d->packs_left>=0) --d->packs_left; - - if(d->angle_seek) goto read_next; // searching for Navi packet - - return d->cur_pack-1; -} - -static void __FASTCALL__ dvd_seek(stream_t* stream,dvd_priv_t *d,int pos){ - int dir=1; - d->packs_left=-1; - if(d->cur_pack>pos) dir=-1; - d->cur_pack=pos; - - reseek: -// check if we stay in current cell (speedup things, and avoid angle skip) -if(d->cur_pack>d->cell_last_pack || - d->cur_pack<d->cur_pgc->cell_playback[ d->cur_cell ].first_sector){ - - // ok, cell change, find the right cell! - d->cur_cell=0; - if( d->cur_pgc->cell_playback[d->cur_cell].block_type - == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle; - - while(1){ - int next; - d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector; - if(d->cur_pack<d->cur_pgc->cell_playback[ d->cur_cell ].first_sector){ - d->cur_pack=d->cur_pgc->cell_playback[ d->cur_cell ].first_sector; - break; - } - if(d->cur_pack<=d->cell_last_pack) break; // ok, we find it! :) - next=dvd_next_cell(d); - if(next<0){ - // we're after the last cell - if(dir>0) // FF - { - if(d->cur_title<d->last_title) - { - d->cur_title++; - dvd_next_title(d,d->cur_title); - goto reseek; - } - } - else // BACK - { - if(d->cur_title>d->first_title) - { - d->cur_title--; - dvd_next_title(d,d->cur_title); - goto reseek; - } - } - break; // EOF - } - d->cur_cell=next; - } - stream->stream_pts=d->vobu_s_pts=d->vobu_e_pts=0.; -} - -MSG_V( "DVD Seek! lba=0x%X cell=%d packs: 0x%X-0x%X \n", - d->cur_pack,d->cur_cell,d->cur_pgc->cell_playback[ d->cur_cell ].first_sector,d->cell_last_pack); - -// if we're in interleaved multi-angle cell, find the right angle chain! -// (read Navi block, and use the seamless angle jump table) -d->angle_seek=1; - -} - -static void __FASTCALL__ dvd_close(dvd_priv_t *d) { - ifoClose(d->vts_file); - ifoClose(d->vmg_file); - DVDCloseFile(d->title); - DVDClose(d->dvd); - /* for reenterability */ - dvd_chapter=1; - dvd_last_chapter=0; - dvd_angle=1; -} - -static MPXP_Rc __FASTCALL__ __dvdread_open(any_t*libinput,stream_t *stream,const char *filename,unsigned flags) -{ - int dvd_title,last_title=-1; - const char *args; - char *dvd_device,*tilde,*comma,*par; - char param[256]; -// int ret,ret2; - dvd_priv_t *d; - dvd_reader_t *dvd; - ifo_handle_t *vmg_file; - tt_srpt_t *tt_srpt; - UNUSED(libinput); - if(strcmp(filename,"help") == 0 || strlen(filename)==10) { - MSG_HINT("Usage: dvdread://<@device>#<titleno>-<lasttitle>,<chapter>-<lastchapter>,<angle>\n"); - return MPXP_False; - } - args=mrl_parse_line(filename,NULL,NULL,&dvd_device,NULL); - strncpy(param,args,sizeof(param)); - comma=strchr(param,','); - tilde=strchr(param,'-'); - if(comma) *comma=0; - if(tilde) *tilde=0; - dvd_title=atoi(param); - if(tilde) last_title=atoi(tilde+1); - else - if(comma) { - comma++; - par = comma; - tilde=strchr(comma,'-'); - comma=strchr(comma,','); - dvd_chapter=atoi(par); - if(tilde) { - tilde++; - dvd_last_chapter=atoi(tilde); - } - if(comma) { comma++; dvd_angle=atoi(comma); } - } - /** - * Open the disc. - */ - dvd = DVDOpen(dvd_device?dvd_device:DEFAULT_DVD_DEVICE); - if( !dvd ) { - MSG_ERR(MSGTR_CantOpenDVD,dvd_device?dvd_device:DEFAULT_DVD_DEVICE); - if(dvd_device) mp_free(dvd_device); - return MPXP_False; - } - if(dvd_device) mp_free(dvd_device); - MSG_V(MSGTR_DVDwait); - - /** - * Load the video manager to find out the information about the titles on - * this disc. - */ - vmg_file = ifoOpen( dvd, 0 ); - if( !vmg_file ) { - MSG_ERR( "Can't open VMG info!\n"); - DVDClose( dvd ); - return MPXP_False; - } - tt_srpt = vmg_file->tt_srpt; - /** - * Make sure our title number is valid. - */ - MSG_INFO( MSGTR_DVDnumTitles, - tt_srpt->nr_of_srpts ); - if( dvd_title < 1 || dvd_title > tt_srpt->nr_of_srpts ) { - MSG_ERR( MSGTR_DVDinvalidTitle, dvd_title); - ifoClose( vmg_file ); - DVDClose( dvd ); - return MPXP_False; - } - --dvd_title; // remap 1.. -> 0.. - --last_title;// remap 1.. -> 0.. - if( last_title < 0 || last_title >= tt_srpt->nr_of_srpts ) last_title=dvd_title; - /** - * Make sure the chapter number is valid for this title. - */ - MSG_INFO( MSGTR_DVDnumChapters, - tt_srpt->title[dvd_title].nr_of_ptts ); - if( dvd_chapter<1 || dvd_chapter>tt_srpt->title[dvd_title].nr_of_ptts ) { - MSG_ERR( MSGTR_DVDinvalidChapter, dvd_chapter); - ifoClose( vmg_file ); - DVDClose( dvd ); - return MPXP_False; - } - if( dvd_last_chapter>0 ) { - if ( dvd_last_chapter<dvd_chapter || dvd_last_chapter>tt_srpt->title[dvd_title].nr_of_ptts ) { - MSG_ERR( "Invalid DVD last chapter number: %d\n", dvd_last_chapter); - ifoClose( vmg_file ); - DVDClose( dvd ); - return MPXP_False; - } - } - --dvd_chapter; // remap 1.. -> 0.. - /* XXX No need to remap dvd_last_chapter */ - /** - * Make sure the angle number is valid for this title. - */ - MSG_V( MSGTR_DVDnumAngles, - tt_srpt->title[dvd_title].nr_of_angles ); - if( dvd_angle<1 || dvd_angle>tt_srpt->title[dvd_title].nr_of_angles ) { - MSG_ERR( MSGTR_DVDinvalidAngle, dvd_angle); - ifoClose( vmg_file ); - DVDClose( dvd ); - return MPXP_False; - } - --dvd_angle; // remap 1.. -> 0.. - - // store data - d=mp_mallocz(sizeof(dvd_priv_t)); - d->dvd=dvd; - d->title=0; - d->vmg_file=vmg_file; - d->tt_srpt=tt_srpt; - d->vts_file=0; - d->cur_title=d->first_title=dvd_title; - d->last_title=last_title; - - if(!dvd_next_title(d,dvd_title)) { - mp_free(d); - ifoClose( vmg_file ); - DVDClose( dvd ); - return MPXP_False; - } - - MSG_V( MSGTR_DVDopenOk); - - stream->start_pos=(off_t)d->cur_pack*2048; - stream->end_pos=(off_t)(d->cur_pgc->cell_playback[d->last_cell-1].last_sector)*2048; - if(dvd_next_title(d,last_title)) - stream->end_pos=(off_t)(d->cur_pgc->cell_playback[d->last_cell-1].last_sector)*2048; - MSG_V("DVD start=%d end=%d \n",d->cur_pack,d->cur_pgc->cell_playback[d->last_cell-1].last_sector); - dvd_next_title(d,dvd_title); - stream->priv=(any_t*)d; - stream->type = STREAMTYPE_SEEKABLE|STREAMTYPE_PROGRAM; - stream->sector_size=2048; - d->spos=0; -// check_pin("stream",stream->pin,STREAM_PIN); - return MPXP_Ok; -} - -static int __FASTCALL__ __dvdread_read(stream_t *stream,stream_packet_t *sp) -{ - dvd_priv_t *d=(dvd_priv_t *)stream->priv; - off_t pos=dvd_read_sector(stream,stream->priv,sp->buf); - sp->type=0; - if(pos>=0){ - sp->len=2048; // full sector - d->spos += 2048; - } else sp->len= -1; // error - return sp->len; -} - -static off_t __FASTCALL__ __dvdread_seek(stream_t *stream,off_t newpos) -{ - dvd_priv_t *d=(dvd_priv_t *)stream->priv; - off_t pos=newpos/2048; - dvd_seek(stream,stream->priv,pos); - d->spos=pos*2048; - return d->spos; -} - -static off_t __FASTCALL__ __dvdread_tell(const stream_t *stream) -{ - dvd_priv_t *d = (dvd_priv_t *)stream->priv; - return d->spos; -} - -static void __FASTCALL__ __dvdread_close(stream_t *stream) -{ - dvd_close(stream->priv); - mp_free(stream->priv); -} - -static unsigned int * __FASTCALL__ dvdread_stream_get_palette(stream_t *stream) -{ - dvd_priv_t *d=(dvd_priv_t *)stream->priv; - if(d) - if(d->cur_pgc) - return d->cur_pgc->palette; - return 0; -} - -static MPXP_Rc __FASTCALL__ __dvdread_ctrl(const stream_t *s,unsigned cmd,any_t*args) -{ - dvd_priv_t *dvd_priv=s->priv; - switch(cmd) { - case SCTRL_VID_GET_PALETTE: { - unsigned* pal; - pal=dvdread_stream_get_palette(s); - *((unsigned **)args)=pal; - return MPXP_Ok; - } - break; - case SCTRL_LNG_GET_AID: { - int aid; - aid=dvd_aid_from_lang(s,args); - *((int *)args)=aid; - return MPXP_Ok; - } - break; - case SCTRL_LNG_GET_SID: { - int aid; - aid=dvd_sid_from_lang(s,args); - *((int *)args)=aid; - return MPXP_Ok; - } - break; - default: break; - } - return MPXP_False; -} - -const stream_driver_t dvdread_stream = -{ - "dvdread://", - "reads multimedia stream using low-level libdvdread access", - __dvdread_open, - __dvdread_read, - __dvdread_seek, - __dvdread_tell, - __dvdread_close, - __dvdread_ctrl -}; -#endif - Copied: mplayerxp/libmpstream/s_dvdread.cpp (from rev 425, mplayerxp/libmpstream/s_dvdread.c) =================================================================== --- mplayerxp/libmpstream/s_dvdread.cpp (rev 0) +++ mplayerxp/libmpstream/s_dvdread.cpp 2012-11-21 17:14:42 UTC (rev 427) @@ -0,0 +1,834 @@ +/* + s_dvdread - DVDREAD stream interface +*/ +#include <limits> + +#include "mp_config.h" +#include "mplayerxp.h" + +/* fake stdint */ +#define UINT8_MAX std::numeric_limits<uint8_t>::max() +#define UINT16_MAX std::numeric_limits<uint16_t>::max() +#define INT32_MAX std::numeric_limits<int32_t>::max() +#ifdef USE_DVDREAD +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "stream.h" +#include "help_mp.h" +#include "stream_msg.h" +#include "osdep/mplib.h" + +#include <dvdread/dvd_reader.h> +#include <dvdread/ifo_types.h> +#include <dvdread/ifo_read.h> +#include <dvdread/nav_read.h> +#include "mrl.h" + +#undef DVDREAD_VERSION +#define DVDREAD_VERSION(maj,min,micro) ((maj)*10000 + (min)*100 + (micro)) + +/* + * Try to autodetect the libdvd-0.9.0 library + * (0.9.0 removed the <dvdread/dvd_udf.h> header, and moved the two defines + * DVD_VIDEO_LB_LEN and MAX_UDF_FILE_NAME_LEN from it to + * <dvdread/dvd_reader.h>) + */ +#if defined(DVD_VIDEO_LB_LEN) && defined(MAX_UDF_FILE_NAME_LEN) +#define LIBDVDREAD_VERSION DVDREAD_VERSION(0,9,0) +#else +#define LIBDVDREAD_VERSION DVDREAD_VERSION(0,8,0) +#endif + +typedef struct { + int id; // 0 - 31 mpeg; 128 - 159 ac3; 160 - 191 pcm + int language; + int type; + int channels; +} stream_language_t; + +typedef struct { + dvd_reader_t *dvd; + dvd_file_t *title; + ifo_handle_t *vmg_file; + tt_srpt_t *tt_srpt; + ifo_handle_t *vts_file; + vts_ptt_srpt_t *vts_ptt_srpt; + pgc_t *cur_pgc; + /* title sets */ + unsigned first_title,cur_title,last_title; +// + int cur_cell; + int last_cell; + int cur_pack; + int cell_last_pack; +// Navi: + int packs_left; + dsi_t dsi_pack; + pci_t pci_pack; + int angle_seek; + float vobu_s_pts,vobu_e_pts; +// audio datas + int nr_of_channels; + stream_language_t audio_streams[32]; +// subtitles + int nr_of_subtitles; + stream_language_t subtitles[32]; + + off_t spos; +} dvd_priv_t; + +static int dvd_chapter=1; +static int dvd_last_chapter=0; +static int dvd_angle=1; /**< some DVD discs contain scenes that can be viewed from multiple angles */ + +static const char * dvd_audio_stream_types[8] = + { "ac3","unknown","mpeg1","mpeg2ext","lpcm","unknown","dts" }; + +static const char * dvd_audio_stream_channels[8] = + { "unknown", "stereo", "unknown", "unknown", "unknown", "5.1", "6.1", "7.1" }; + +static int __FASTCALL__ dvd_chapter_from_cell(dvd_priv_t* dvd,int title,int cell) +{ + pgc_t * cur_pgc; + ptt_info_t* ptt; + int chapter = cell; + int pgc_id,pgn; + if(title < 0 || cell < 0){ + return 0; + } + /* for most DVD's chapter == cell */ + /* but there are more complecated cases... */ + if(chapter >= dvd->vmg_file->tt_srpt->title[title].nr_of_ptts){ + chapter = dvd->vmg_file->tt_srpt->title[title].nr_of_ptts-1; + } + title = dvd->tt_srpt->title[title].vts_ttn-1; + ptt = dvd->vts_file->vts_ptt_srpt->title[title].ptt; + while(chapter >= 0){ + pgc_id = ptt[chapter].pgcn; + pgn = ptt[chapter].pgn; + cur_pgc = dvd->vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc; + if(cell >= cur_pgc->program_map[pgn-1]-1){ + return chapter; + } + --chapter; + } + /* didn't find a chapter ??? */ + return chapter; +} + +static int __FASTCALL__ dvd_number_of_subs(stream_t *stream) +{ + dvd_priv_t *d; + if (!stream) return -1; + d = reinterpret_cast<dvd_priv_t*>(stream->priv); + if (!d) return -1; + return d->nr_of_subtitles; +} + +static int __FASTCALL__ dvd_aid_from_lang(const stream_t *stream, const char* lang){ + dvd_priv_t *d=reinterpret_cast<dvd_priv_t*>(stream->priv); + int code,i; + while(lang && strlen(lang)>=2){ + code=lang[1]|(lang[0]<<8); + for(i=0;i<d->nr_of_channels;i++){ + if(d->audio_streams[i].language==code){ + MSG_V("Selected DVD audio channel: %d language: %c%c\n", + d->audio_streams[i].id, lang[0],lang[1]); + return d->audio_streams[i].id; + } + } + lang+=2; while (lang[0]==',' || lang[0]==' ') ++lang; + } + MSG_WARN("No matching DVD audio language found!\n"); + return -1; +} + +static int __FASTCALL__ dvd_sid_from_lang(const stream_t *stream, const char* lang){ + dvd_priv_t *d=reinterpret_cast<dvd_priv_t*>(stream->priv); + int code,i; + while(lang && strlen(lang)>=2){ + code=lang[1]|(lang[0]<<8); + for(i=0;i<d->nr_of_subtitles;i++){ + if(d->subtitles[i].language==code){ + MSG_V("Selected DVD subtitle channel: %d language: %c%c\n", + d->subtitles[i].id, lang[0],lang[1]); + return d->subtitles[i].id; + } + } + lang+=2; while (lang[0]==',' || lang[0]==' ') ++lang; + } + MSG_WARN("No matching DVD subtitle language found!\n"); + return -1; +} + +static int __FASTCALL__ dvd_lang_from_sid(stream_t *stream, int id) +{ + dvd_priv_t *d; + if (!stream) return 0; + d = reinterpret_cast<dvd_priv_t*>(stream->priv); + if (!d) return 0; + if (id >= d->nr_of_subtitles) return 0; + return d->subtitles[id].language; +} + +static int __FASTCALL__ dvd_next_title(dvd_priv_t *d,int dvd_title) +{ + int ttn,pgc_id,pgn; + dvd_reader_t *dvd; + dvd_file_t *title; + ifo_handle_t *vmg_file; + tt_srpt_t *tt_srpt; + ifo_handle_t *vts_file; + + MSG_V("dvd_next_title %d\n",dvd_title); + + tt_srpt = d->tt_srpt; + vmg_file = d->vmg_file; + dvd = d->dvd; + if(d->vts_file) ifoClose(d->vts_file); + if(d->title) DVDCloseFile(d->title); + /** + * Load the VTS information for the title set our title is in. + */ + vts_file = ifoOpen( dvd, tt_srpt->title[dvd_title].title_set_nr ); + if( !vts_file ) { + MSG_ERR( MSGTR_DVDnoIFO, + tt_srpt->title[dvd_title].title_set_nr ); + ifoClose( vmg_file ); + DVDClose( dvd ); + return 0; + } + /** + * We've got enough info, time to open the title set data. + */ + title = DVDOpenFile( dvd, tt_srpt->title[dvd_title].title_set_nr, + DVD_READ_TITLE_VOBS ); + if( !title ) { + MSG_ERR( MSGTR_DVDnoVOBs, + tt_srpt->title[dvd_title].title_set_nr ); + ifoClose( vts_file ); + ifoClose( vmg_file ); + DVDClose( dvd ); + return 0; + } + d->vts_file=vts_file; + d->title=title; + + ttn = tt_srpt->title[dvd_title].vts_ttn - 1; + + /** + * Check number of audio channels and types + */ + { + const int ac3aid = 128; + const int dtsaid = 136; + const int mpegaid = 0; + const int pcmaid = 160; + + d->nr_of_channels=0; + + if ( vts_file->vts_pgcit ) + { + int i; + for ( i=0;i<8;i++ ) + if ( vts_file->vts_pgcit->pgci_srp[0].pgc->audio_control[i] & 0x8000 ) + { + audio_attr_t * audio = &vts_file->vtsi_mat->vts_audio_attr[i]; + int language = 0; + char tmp[] = "unknown"; + + if ( audio->lang_type == 1 ) + { + language=audio->lang_code; + tmp[0]=language>>8; + tmp[1]=language&0xff; + tmp[2]=0; + } + + d->audio_streams[d->nr_of_channels].language=language; + d->audio_streams[d->nr_of_channels].id=vts_file->vts_pgcit->pgci_srp[ttn].pgc->audio_control[i] >> 8 & 7; + switch ( audio->audio_format ) + { + case 0: // ac3 + d->audio_streams[d->nr_of_channels].id+=ac3aid; + break; + case 6: // dts + d->audio_streams[d->nr_of_channels].id+=dtsaid; + break; + case 2: // mpeg layer 1/2/3 + case 3: // mpeg2 ext + d->audio_streams[d->nr_of_channels].id+=mpegaid; + break; + case 4: // lpcm + d->audio_streams[d->nr_of_channels].id+=pcmaid; + break; + } + + d->audio_streams[d->nr_of_channels].type=audio->audio_format; + // Pontscho: to my mind, tha channels: + // 1 - stereo + // 5 - 5.1 + d->audio_streams[d->nr_of_channels].channels=audio->channels; + MSG_V("[open] audio stream: %d audio format: %s (%s) language: %s aid: %d\n", + d->nr_of_channels, + dvd_audio_stream_types[ audio->audio_format ], + dvd_audio_stream_channels[ audio->channels ], + tmp, + d->audio_streams[d->nr_of_channels].id + ); + + d->nr_of_channels++; + } + } + MSG_V("[open] number of audio channels on disk: %d.\n",d->nr_of_channels ); + } + + /** + * Check number of subtitles and language + */ + { + int i; + + d->nr_of_subtitles=0; + for ( i=0;i<32;i++ ) + if ( vts_file->vts_pgcit->pgci_srp[0].pgc->subp_control[i] & 0x80000000 ) + { + subp_attr_t * subtitle = &vts_file->vtsi_mat->vts_subp_attr[i]; + video_attr_t *video = &vts_file->vtsi_mat->vts_video_attr; + int language = 0; + char tmp[] = "unknown"; + + if ( subtitle->type == 1 ) + { + language=subtitle->lang_code; + tmp[0]=language>>8; + tmp[1]=language&0xff; + tmp[2]=0; + } + + d->subtitles[ d->nr_of_subtitles ].language=language; + d->subtitles[ d->nr_of_subtitles ].id=d->nr_of_subtitles; + if(video->display_aspect_ratio == 0) /* 4:3 */ + d->subtitles[d->nr_of_subtitles].id = vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i] >> 24 & 31; + else if(video->display_aspect_ratio == 3) /* 16:9 */ + d->subtitles[d->nr_of_subtitles].id = vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i] >> 8 & 31; + + MSG_V("[open] subtitle ( sid ): %d language: %s\n", + d->nr_of_subtitles, + tmp + ); + d->nr_of_subtitles++; + } + MSG_V("[open] number of subtitles on disk: %d\n",d->nr_of_subtitles ); + } + + /** + * Determine which program chain we want to watch. This is based on the + * chapter number. + */ + pgc_id = vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_chapter].pgcn; // local + pgn = vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_chapter].pgn; // local + d->cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc; + d->cur_cell = d->cur_pgc->program_map[pgn-1] - 1; // start playback here + d->packs_left=-1; // for Navi stuff + d->angle_seek=0; + /* XXX dvd_last_chapter is in the range 1..nr_of_ptts */ + if ( dvd_last_chapter > 0 && dvd_last_chapter < tt_srpt->title[dvd_title].nr_of_ptts ) { + pgn=vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_last_chapter].pgn; + d->last_cell=d->cur_pgc->program_map[pgn-1] - 1; + } + else + d->last_cell=d->cur_pgc->nr_of_cells; + + if( d->cur_pgc->cell_playback[d->cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle; + d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector; + d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector; + MSG_V( "DVD start cell: %d pack: 0x%X-0x%X \n",d->cur_cell,d->cur_pack,d->cell_last_pack); + + return 1; +} + +static int __FASTCALL__ dvd_next_cell(dvd_priv_t *d){ + int next_cell=d->cur_cell; + + MSG_V( "dvd_next_cell: next1=0x%X \n",next_cell); + + if( d->cur_pgc->cell_playback[ next_cell ].block_type + == BLOCK_TYPE_ANGLE_BLOCK ) { + while(next_cell<d->last_cell){ + if( d->cur_pgc->cell_playback[next_cell].block_mode + == BLOCK_MODE_LAST_CELL ) break; + ++next_cell; + } + } + MSG_V( "dvd_next_cell: next2=0x%X \n",next_cell); + + ++next_cell; + if(next_cell>=d->last_cell) return -1; // EOF + if( d->cur_pgc->cell_playback[next_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK ){ + next_cell+=dvd_angle; + if(next_cell>=d->last_cell) return -1; // EOF + } + MSG_V( "dvd_next_cell: next3=0x%X \n",next_cell); + return next_cell; +} + +static void __FASTCALL__ dvd_seek(stream_t* stream,dvd_priv_t *d,int pos); +static int __FASTCALL__ dvd_read_sector(stream_t* stream,dvd_priv_t *d,unsigned char* data){ + int len; +read_first: + if(d->packs_left==0){ + /** + * If we're not at the end of this cell, we can determine the next + * VOBU to display using the VOBU_SRI information section of the + * DSI. Using this value correctly follows the current angle, + * avoiding the doubled scenes in The Matrix, and makes our life + * really happy. + * + * Otherwise, we set our next address past the end of this cell to + * force the code above to go to the next cell in the program. + */ + if( d->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL ) { + d->cur_pack= d->dsi_pack.dsi_gi.nv_pck_lbn + + ( d->dsi_pack.vobu_sri.next_vobu & 0x3fffffff ); + MSG_V( "Navi new pos=0x%X \n",d->cur_pack); + } else { + // end of cell! find next cell! + MSG_V( "--- END OF CELL !!! ---\n"); + d->cur_pack=d->cell_last_pack+1; + } + } + +read_next: + + if(d->cur_pack>d->cell_last_pack){ + // end of cell! + int next=dvd_next_cell(d); + if(next>=0){ + d->cur_cell=next; + // if( d->cur_pgc->cell_playback[d->cur_cell].block_type + // == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle; + d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector; + d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector; + MSG_V( "DVD next cell: %d pack: 0x%X-0x%X \n",d->cur_cell,d->cur_pack,d->cell_last_pack); + } else + if(d->cur_title<d->last_title) + { + d->cur_title++; + dvd_next_title(d,d->cur_title); + goto read_first; + } + else return -1; // EOF + } + + len = DVDReadBlocks( d->title, d->cur_pack, 1, data ); + if(!len) return -1; //error +/* +Navigation packets are PES packets with a stream id 0xbf, i.e. +private stream 2. It's made up of PCI, Presentation Control Information +and DSI, Data Search Information. + + 0 6 7 0x3d4+0x6 0x3d4+0xb 0x3d4+0xc + +------+---------+----------------------+------+---------+-----------------+ + |Packet|Substream| PCI |Packet|Substream| DSI | + |Header| ID | Data |Header| ID | Data | + +------+---------+----------------------+------+---------+-----------------+ + + The packet head is just a PES packet header, a packet start code, a stream id +and a packet length. The first packet lenght is 0x3d4, the length of the PCI data +plus one. The second packet length is 0x3fa, the length of DSI data plus one. +The substream id for PCI packet is 0x00 and 0x01 for DSI. +*/ + if(data[38]==0 && data[39]==0 && data[40]==1 && data[41]==0xBF && + data[1024]==0 && data[1025]==0 && data[1026]==1 && data[1027]==0xBF){ + // found a Navi packet!!! +#if LIBDVDREAD_VERSION >= DVDREAD_VERSION(0,9,0) + navRead_DSI( &d->dsi_pack, &(data[DSI_START_BYTE]) ); + navRead_PCI( &d->pci_pack, &(data[DSI_START_BYTE-0x3DA]) ); +#else + navRead_DSI( &d->dsi_pack, &(data[DSI_START_BYTE]), sizeof(dsi_t)); + navRead_PCI( &d->pci_pack, &(data[DSI_START_BYTE-0x3DA]), sizeof(pci_t)); +#endif + /* + TODO!: if num_angles!=0 and d->dsi_pack.sml_agli.data[dvd_angle].address + doesn't work :( + > Invalid NAVIpacket! lba=30 gsi_navi=8002F pci_navi=8002F angle=0 + */ + if(d->cur_pack != d->dsi_pack.dsi_gi.nv_pck_lbn){ + MSG_V( "Invalid NAVIpacket! lba=%X gsi_navi=%X pci_navi=%X angle=%X\n" + ,d->cur_pack + ,d->dsi_pack.dsi_gi.nv_pck_lbn + ,d->pci_pack.pci_gi.nv_pck_lbn + ,d->dsi_pack.sml_agli.data[dvd_angle].address + ); + } else { + // process! + float vobu_s_pts,vobu_e_pts; + vobu_s_pts=d->pci_pack.pci_gi.vobu_s_ptm/90000.; + vobu_e_pts=d->pci_pack.pci_gi.vobu_e_ptm/90000.; + d->packs_left = d->dsi_pack.dsi_gi.vobu_ea; + MSG_V( "Found NAVI packet! lba=%X angle=%X len=%d vobu_s_pts=%f vobu_e_pts=%f\n" + ,d->cur_pack,d->packs_left + ,d->dsi_pack.sml_agli.data[dvd_angle].address + ,vobu_s_pts,vobu_e_pts); + + if(d->angle_seek){ + int i,skip=0; +#if defined(__GNUC__) && ( defined(__sparc__) || defined(hpux) ) + // workaround for a bug in the sparc/hpux version of gcc 2.95.X ... 3.2, + // it generates incorrect code for unaligned access to a packed + // structure member, resulting in an mplayer crash with a SIGBUS + // signal. + // + // See also gcc problem report PR c/7847: + // http://gcc.gnu.org/cgi-bin/gnatsweb.pl?database=gcc&cmd=view+audit-trail&pr=7847 + for(i=0;i<9;i++){ // check if all values zero: + typeof(d->dsi_pack.sml_agli.data[i].address) tmp_addr; + memcpy(&tmp_addr,&d->dsi_pack.sml_agli.data[i].address,sizeof(tmp_addr)); + if((skip=tmp_addr)!=0) break; + } +#else + for(i=0;i<9;i++) // check if all values zero: + if((skip=d->dsi_pack.sml_agli.data[i].address)!=0) break; +#endif + if(skip){ + // sml_agli table has valid data (at least one non-zero): + d->cur_pack=d->dsi_pack.dsi_gi.nv_pck_lbn+ + d->dsi_pack.sml_agli.data[dvd_angle].address; + d->angle_seek=0; + MSG_V("Angle-seek synced using sml_agli map! new_lba=0x%X\n",d->cur_pack); + } else { + // check if we're in the right cell, jump otherwise: + if( (d->dsi_pack.dsi_gi.vobu_c_idn==d->cur_pgc->cell_position[d->cur_cell].cell_nr) && + (d->dsi_pack.dsi_gi.vobu_vob_idn==d->cur_pgc->cell_position[d->cur_cell].vob_id_nr) ){ + d->angle_seek=0; + MSG_V("Angle-seek synced by cell/vob IDN search!\n"); + } else { + // wrong angle, skip this vobu: + d->cur_pack=d->dsi_pack.dsi_gi.nv_pck_lbn+ + d->dsi_pack.dsi_gi.vobu_ea; + d->angle_seek=2; // DEBUG + } + } + } + if(vobu_s_pts < d->vobu_e_pts) + { + stream->stream_pts += d->vobu_e_pts-vobu_s_pts; + MSG_V("DVD's discontinuities found! Applying delta: %f\n",stream->stream_pts); + } + e... [truncated message content] |