[Mplayerxp-cvslog] SF.net SVN: mplayerxp:[372] mplayerxp
Brought to you by:
olov
From: <nic...@us...> - 2012-11-15 14:13:38
|
Revision: 372 http://mplayerxp.svn.sourceforge.net/mplayerxp/?rev=372&view=rev Author: nickols_k Date: 2012-11-15 14:13:23 +0000 (Thu, 15 Nov 2012) Log Message: ----------- cumulative patch: use own stack for each thread + overload operators new & delete + SECURE_NAMES + fixes + cleanups + more .cpp sources Modified Paths: -------------- mplayerxp/configure mplayerxp/input2/input.c mplayerxp/libao2/ao_nas.c mplayerxp/libao2/audio_out.c mplayerxp/libmpcodecs/ad_faad.c mplayerxp/libmpcodecs/dec_video.c mplayerxp/libmpcodecs/vd_libmpeg2.c mplayerxp/libmpdemux/Makefile mplayerxp/libmpdemux/cache2.c mplayerxp/libmpdemux/demux_dv.c mplayerxp/libmpdemux/demuxer.h mplayerxp/libmpdemux/stream.h mplayerxp/libvo/video_out.c mplayerxp/mp-opt-reg.cpp mplayerxp/mp_msg.cpp mplayerxp/mp_msg.h mplayerxp/mplayerxp.cpp mplayerxp/osdep/Makefile mplayerxp/osdep/getch2.c mplayerxp/osdep/getch2.h mplayerxp/osdep/mplib.h mplayerxp/postproc/af.c mplayerxp/postproc/vf.c mplayerxp/xmpcore/PointerProtector.h mplayerxp/xmpcore/sig_hand.cpp mplayerxp/xmpcore/xmp_adecoder.cpp mplayerxp/xmpcore/xmp_aplayer.cpp mplayerxp/xmpcore/xmp_core.cpp mplayerxp/xmpcore/xmp_vdecoder.cpp mplayerxp/xmpcore/xmp_vplayer.cpp Added Paths: ----------- mplayerxp/libmpdemux/demuxer.cpp mplayerxp/libmpdemux/demuxer_r.cpp mplayerxp/libmpdemux/stream.cpp mplayerxp/osdep/mp_malloc.cpp mplayerxp/osdep/mplib.cpp Removed Paths: ------------- mplayerxp/libmpdemux/demuxer.c mplayerxp/libmpdemux/demuxer_r.c mplayerxp/libmpdemux/stream.c mplayerxp/osdep/mp_malloc.c mplayerxp/osdep/mplib.c Modified: mplayerxp/configure =================================================================== --- mplayerxp/configure 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/configure 2012-11-15 14:13:23 UTC (rev 372) @@ -90,7 +90,7 @@ "gcov|compile gnu coverage information into PROGRAM", "profile|compile profiling information into PROGRAM", "static|build static libraries", - "gdb23|allow additional level of debug messages", + "dbg23|allow additional level of debug messages", "win32loader|build support for Win32 codecs", "random_name|generates pseudo random suffix of target" ) @@ -763,7 +763,7 @@ # (FIXME: 'echocheck "dynamic linking"' above and modify here accordingly) bsd && add_ldflags "-rdynamic" -enabled gdb23 def_debug='#define MP_DEBUG 1' || def_debug='#undef MP_DEBUG' +enabled dbg23 def_debug='#define MP_DEBUG 1' || def_debug='#undef MP_DEBUG' # Checking for VIDIX enabled vidix && require2 vidix vidix/vidixlib.h vdlAllocFourccS -lvidix @@ -1072,16 +1072,16 @@ #define RND_NUMBER8 $rnd8 #define RND_NUMBER9 $rnd9 -#define RND_STR0 "$srnd0" -#define RND_STR1 "$srnd1" -#define RND_STR2 "$srnd2" -#define RND_STR3 "$srnd3" -#define RND_STR4 "$srnd4" -#define RND_STR5 "$srnd5" -#define RND_STR6 "$srnd6" -#define RND_STR7 "$srnd7" -#define RND_STR8 "$srnd8" -#define RND_STR9 "$srnd9" +#define RND_STR0 "x$srnd0" +#define RND_STR1 "x$srnd1" +#define RND_STR2 "x$srnd2" +#define RND_STR3 "x$srnd3" +#define RND_STR4 "x$srnd4" +#define RND_STR5 "x$srnd5" +#define RND_STR6 "x$srnd6" +#define RND_STR7 "x$srnd7" +#define RND_STR8 "x$srnd8" +#define RND_STR9 "x$srnd9" #define RND_RENAME0(a) a ## $frnd0 @@ -1095,6 +1095,17 @@ #define RND_RENAME8(a) a ## $frnd8 #define RND_RENAME9(a) a ## $frnd9 +#define SECURE_NAME0(a) x$srnd0 +#define SECURE_NAME1(a) x$srnd1 +#define SECURE_NAME2(a) x$srnd2 +#define SECURE_NAME3(a) x$srnd3 +#define SECURE_NAME4(a) x$srnd4 +#define SECURE_NAME5(a) x$srnd5 +#define SECURE_NAME6(a) x$srnd6 +#define SECURE_NAME7(a) x$srnd7 +#define SECURE_NAME8(a) x$srnd8 +#define SECURE_NAME9(a) x$srnd9 + #endif /* MPXP_CONFIG_H */ EOF Modified: mplayerxp/input2/input.c =================================================================== --- mplayerxp/input2/input.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/input2/input.c 2012-11-15 14:13:23 UTC (rev 372) @@ -86,12 +86,11 @@ }; typedef struct priv_s { + char antiviral_hole[RND_CHAR1]; // These are the user defined binds mp_cmd_bind_t* cmd_binds; mp_cmd_filter_t* cmd_filters; - char antiviral_hole[RND_CHAR1]; - mp_input_fd_t key_fds[MP_MAX_KEY_FD]; unsigned int num_key_fd; mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; @@ -743,7 +742,7 @@ filter->ctx = ctx; filter->next = priv->cmd_filters; priv->cmd_filters = filter; - RND_RENAME0(rnd_fill)(priv->antiviral_hole,sizeof(priv->antiviral_hole)); + SECURE_NAME9(rnd_fill)(priv->antiviral_hole,offsetof(priv_t,cmd_binds)-offsetof(priv_t,antiviral_hole)); } static char* mp_input_find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) { Modified: mplayerxp/libao2/ao_nas.c =================================================================== --- mplayerxp/libao2/ao_nas.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libao2/ao_nas.c 2012-11-15 14:13:23 UTC (rev 372) @@ -98,7 +98,7 @@ "Hardware", "Any" }; -#ifdef MP_DEBUG + static const char* nas_reason(unsigned int reason) { if (reason > 6) reason = 6; @@ -120,7 +120,6 @@ if (state>3) state = 3; return nas_states[state]; } -#endif static const ao_info_t info = { "NAS audio output", Modified: mplayerxp/libao2/audio_out.c =================================================================== --- mplayerxp/libao2/audio_out.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libao2/audio_out.c 2012-11-15 14:13:23 UTC (rev 372) @@ -217,8 +217,8 @@ ao->buffersize=-1; ao->opaque=mp_malloc(sizeof(priv_t)); priv_t* priv=ao->opaque; - RND_RENAME0(rnd_fill)(priv->antiviral_hole,sizeof(priv_t)); - RND_RENAME0(rnd_fill)(ao->antiviral_hole,offsetof(ao_data_t,samplerate)-offsetof(ao_data_t,antiviral_hole)); + 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)); priv->audio_out=NULL; return ao; } Modified: mplayerxp/libmpcodecs/ad_faad.c =================================================================== --- mplayerxp/libmpcodecs/ad_faad.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpcodecs/ad_faad.c 2012-11-15 14:13:23 UTC (rev 372) @@ -348,7 +348,7 @@ } else { /* XXX: samples already multiplied by channels! */ MSG_DBG2("FAAD: Successfully decoded frame (%d Bytes)!\n", - sh->samplesize*NeAAC_finfo.samples); + afmt2bps(sh->afmt)*NeAAC_finfo.samples); memcpy(buf+len,NeAAC_sample_buffer, afmt2bps(sh->afmt)*NeAAC_finfo.samples); len += afmt2bps(sh->afmt)*NeAAC_finfo.samples; //printf("FAAD: buffer: %d bytes consumed: %d \n", k, NeAAC_finfo.bytesconsumed); Modified: mplayerxp/libmpcodecs/dec_video.c =================================================================== --- mplayerxp/libmpcodecs/dec_video.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpcodecs/dec_video.c 2012-11-15 14:13:23 UTC (rev 372) @@ -199,10 +199,10 @@ } sh_video->codec->flags|=CODECS_FLAG_SELECTED; // tagging it // ok, it matches all rules, let's find the driver! - if(!(mpvdec=vfm_find_driver(sh_video->codec->driver_name))) continue; - else MSG_DBG3("mpcv_init: mpcodecs_vd_drivers[%s]->mpvdec==0\n",mpcodecs_vd_drivers[i]->info->driver_name); + if(!(priv->mpvdec=vfm_find_driver(sh_video->codec->driver_name))) continue; + else MSG_DBG3("mpcv_init: mpcodecs_vd_drivers[%s]->mpvdec==0\n",priv->mpvdec->info->driver_name); // it's available, let's try to init! - if(mpvdec->init(sh_video,libinput)!=MPXP_Ok){ + if(priv->mpvdec->init(sh_video,libinput)!=MPXP_Ok){ MSG_ERR(MSGTR_CODEC_CANT_INITV); continue; // try next... } @@ -249,13 +249,13 @@ for(j=0;j<num_slices;j+=smp_num_cpus) { #pragma omp parallel for shared(vf) private(i) for(i=j;i<smp_num_cpus;i++) { - MSG_DBG2("parallel: dec_video.put_slice[%ux%u] %i %i %i %i\n",ampi[i].width,ampi[i].height,ampi[i].x,ampi[i].y,ampi[i].w,ampi[i].h); + MSG_DBG2("parallel: dec_video.put_slice[%ux%u] %i %i %i %i\n",ampi[i]->width,ampi[i]->height,ampi[i]->x,ampi[i]->y,ampi[i]->w,ampi[i]->h); vf->put_slice(vf,ampi[i]); free_mp_image(ampi[i]); } } for(;j<num_slices;j++) { - MSG_DBG2("par_tail: dec_video.put_slice[%ux%u] %i %i %i %i\n",ampi[i].width,ampi[i].height,ampi[i].x,ampi[i].y,ampi[i].w,ampi[i].h); + MSG_DBG2("par_tail: dec_video.put_slice[%ux%u] %i %i %i %i\n",ampi[i]->width,ampi[i]->height,ampi[i]->x,ampi[i]->y,ampi[i]->w,ampi[i]->h); vf->put_slice(vf,ampi[j]); free_mp_image(ampi[j]); } @@ -265,7 +265,7 @@ { /* execute slices instead of whole frame make faster multiple filters */ for(i=0;i<num_slices;i++) { - MSG_DBG2("dec_video.put_slice[%ux%u] %i %i %i %i -> [%i]\n",ampi[i].width,ampi[i].height,ampi[i].x,ampi[i].y,ampi[i].w,ampi[i].h,ampi[i].xp_idx); + MSG_DBG2("dec_video.put_slice[%ux%u] %i %i %i %i -> [%i]\n",ampi[i]->width,ampi[i]->height,ampi[i]->x,ampi[i]->y,ampi[i]->w,ampi[i]->h,ampi[i]->xp_idx); vf->put_slice(vf,ampi[i]); free_mp_image(ampi[i]); } @@ -296,7 +296,7 @@ sh_video->active_slices=0; mpi=priv->mpvdec->decode(sh_video, frame); - MSG_DBG2("decvideo: decoding video %u bytes\n",in_size); + MSG_DBG2("decvideo: decoding video %u bytes\n",frame->len); while(sh_video->active_slices!=0) usleep(0); /* ------------------------ frame decoded. -------------------- */ Modified: mplayerxp/libmpcodecs/vd_libmpeg2.c =================================================================== --- mplayerxp/libmpcodecs/vd_libmpeg2.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpcodecs/vd_libmpeg2.c 2012-11-15 14:13:23 UTC (rev 372) @@ -296,7 +296,7 @@ _info=mpeg2_info(priv->mpeg2dec); mpi=NULL; buf=0; - MSG_DBG2("len=%u ***mpeg2_info***\n",len); + MSG_DBG2("len=%u ***mpeg2_info***\n",frame->len); while(1) { state=mpeg2_parse(priv->mpeg2dec); Modified: mplayerxp/libmpdemux/Makefile =================================================================== --- mplayerxp/libmpdemux/Makefile 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpdemux/Makefile 2012-11-15 14:13:23 UTC (rev 372) @@ -29,11 +29,11 @@ ifeq ($(HAVE_LIBDV),yes) SRCS += demux_dv.c endif -SRCS += cache2.c stream.c tvi_dummy.c tvi_v4l.c +SRCS += cache2.c tvi_dummy.c tvi_v4l.c SRCS += tvi_bsdbt848.c frequencies.c mrl.c -SRCS += demuxer_r.c mp3_hdr.c video.c mpeg_hdr.c aviprint.c demux_asf.c -SRCS += demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_viv.c demuxer.c +SRCS += mp3_hdr.c video.c mpeg_hdr.c aviprint.c demux_asf.c +SRCS += demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_viv.c SRCS += parse_es.c demux_fli.c demux_ra.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c SRCS += demux_nuv.c demux_film.c demux_roq.c demux_audio.c demux_demuxers.c SRCS += mpdemux.c demux_bmp.c demux_rawaudio.c demux_aiff.c demux_vqf.c @@ -53,9 +53,13 @@ SUBDIRS = endif +CXXSRCS = demuxer.cpp demuxer_r.cpp stream.cpp + OBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cpp=.o) INCLUDE = -I../ CFLAGS = $(OPTFLAGS) $(INCLUDE) -W -Wall +CXXFLAGS = $(OPTXXFLAGS) $(INCLUDE) -W -Wall .SUFFIXES: .c .o @@ -68,9 +72,11 @@ .c.o: $(CC) -c $(CFLAGS) -o $@ $< +.cpp.o: + $(CXX) -c $(CXXFLAGS) -o $@ $< -$(LIBNAME): $(SUBDIRS) $(OBJS) - $(AR) r $(LIBNAME) $(OBJS) +$(LIBNAME): $(SUBDIRS) $(OBJS) $(CXXOBJS) + $(AR) r $(LIBNAME) $(OBJS) $(CXXOBJS) ifeq ($(HAVE_STREAMING),yes) $(AR) r $(LIBNAME) \ $(wildcard freesdp/*.o) \ @@ -93,7 +99,7 @@ depend: $(DO_MAKE) - $(CC) -MM $(CFLAGS) test.c $(SRCS) 1>.depend + $(CC) -MM $(CFLAGS) test.c $(SRCS) $(CXXSRCS) 1>.depend # # include dependency files if they exist Modified: mplayerxp/libmpdemux/cache2.c =================================================================== --- mplayerxp/libmpdemux/cache2.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpdemux/cache2.c 2012-11-15 14:13:23 UTC (rev 372) @@ -228,7 +228,7 @@ static void sig_cache2( void ) { MSG_V("cache2 segfault\n"); - mp_msg_flush(); + mpxp_print_flush(); xmp_killall_threads(pthread_self()); __exit_sighandler(); } Modified: mplayerxp/libmpdemux/demux_dv.c =================================================================== --- mplayerxp/libmpdemux/demux_dv.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpdemux/demux_dv.c 2012-11-15 14:13:23 UTC (rev 372) @@ -174,7 +174,7 @@ sh_video->src_w = dv_decoder->width; sh_video->src_h = dv_decoder->height; - mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() frame_size: %d w: %d h: %d dif_seq: %d system: %d\n",dv_decoder->frame_size,dv_decoder->width, dv_decoder->height,dv_decoder->num_dif_seqs,dv_decoder->system); + MSG_V("demux_open_rawdv() frame_size: %d w: %d h: %d dif_seq: %d system: %d\n",dv_decoder->frame_size,dv_decoder->width, dv_decoder->height,dv_decoder->num_dif_seqs,dv_decoder->system); sh_video->fps= (dv_decoder->system==e_dv_system_525_60?29.97:25); Deleted: mplayerxp/libmpdemux/demuxer.c =================================================================== --- mplayerxp/libmpdemux/demuxer.c 2012-11-15 12:56:27 UTC (rev 371) +++ mplayerxp/libmpdemux/demuxer.c 2012-11-15 14:13:23 UTC (rev 372) @@ -1,830 +0,0 @@ -//=================== DEMUXER v2.5 ========================= - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "stream.h" -#include "mp_config.h" -#include "help_mp.h" -#include "mplayerxp.h" -#include "libmpsub/subreader.h" -#include "libmpconf/cfgparser.h" -#include "nls/nls.h" - -#include "demuxer.h" -#include "stheader.h" - -#include "osdep/fastmemcpy.h" -#include "osdep/mplib.h" -#include "libvo/sub.h" -#include "libao2/afmt.h" -#include "demux_msg.h" - -extern demuxer_driver_t demux_aiff; -extern demuxer_driver_t demux_rawaudio; -extern demuxer_driver_t demux_rawvideo; -extern demuxer_driver_t demux_avi; -extern demuxer_driver_t demux_y4m; -extern demuxer_driver_t demux_asf; -extern demuxer_driver_t demux_nuv; -extern demuxer_driver_t demux_nsv; -extern demuxer_driver_t demux_mov; -extern demuxer_driver_t demux_mkv; -extern demuxer_driver_t demux_vivo; -extern demuxer_driver_t demux_ra; -extern demuxer_driver_t demux_real; -extern demuxer_driver_t demux_fli; -extern demuxer_driver_t demux_film; -extern demuxer_driver_t demux_roq; -extern demuxer_driver_t demux_bmp; -extern demuxer_driver_t demux_ogg; -extern demuxer_driver_t demux_pva; -extern demuxer_driver_t demux_smjpeg; -extern demuxer_driver_t demux_vqf; -extern demuxer_driver_t demux_mpxpav64; -extern demuxer_driver_t demux_mpgps; -extern demuxer_driver_t demux_mpgts; -extern demuxer_driver_t demux_ty; -extern demuxer_driver_t demux_audio; -extern demuxer_driver_t demux_lavf; -extern demuxer_driver_t demux_null; - -static const demuxer_driver_t *ddrivers[] = -{ - &demux_rawaudio, - &demux_rawvideo, - &demux_avi, - &demux_y4m, - &demux_asf, - &demux_nsv, - &demux_nuv, - &demux_mov, - &demux_mkv, - &demux_vivo, - &demux_ra, - &demux_real, - &demux_fli, - &demux_film, - &demux_roq, - &demux_bmp, -#ifdef HAVE_LIBVORBIS - &demux_ogg, -#endif - &demux_pva, - &demux_smjpeg, - &demux_vqf, - &demux_mpxpav64, - &demux_mpgps, - &demux_aiff, - &demux_audio, - &demux_mpgts, - &demux_ty, - &demux_lavf, - &demux_null, - NULL -}; - -typedef struct demuxer_info_st { - char *id[INFOT_MAX]; -} demuxer_info_t; - -void libmpdemux_register_options(m_config_t* cfg) -{ - unsigned i; - for(i=0;ddrivers[i];i++) { - if(ddrivers[i]->options) - m_config_register_options(cfg,ddrivers[i]->options); - if(ddrivers[i]==&demux_null) break; - } -} - -void free_demuxer_stream(demux_stream_t *ds){ - if(ds) { - ds_free_packs(ds); - mp_free(ds); - } -} - -int demux_aid_vid_mismatch = 0; - -demux_stream_t* new_demuxer_stream(struct demuxer_s *demuxer,int id){ - demux_stream_t* ds=mp_malloc(sizeof(demux_stream_t)); - RND_RENAME0(rnd_fill)(ds->antiviral_hole,offsetof(struct demuxer_s,pin)-offsetof(struct demuxer_s,antiviral_hole)); - ds->pin=DS_PIN; - ds->buffer_pos=ds->buffer_size=0; - ds->buffer=NULL; - ds->pts=0; - ds->pts_bytes=0; - ds->eof=0; - ds->pos=0; - ds->dpos=0; - ds->pack_no=0; -//--------------- - ds->packs=0; - ds->bytes=0; - ds->first=ds->last=ds->current=NULL; - ds->id=id; - ds->demuxer=demuxer; -//---------------- - ds->asf_seq=-1; - ds->asf_packet=NULL; -//---------------- - ds->sh=NULL; - ds->pts_flags=0; - ds->prev_pts=ds->pts_corr=0; - return ds; -} - -demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id){ - demuxer_t *d=mp_mallocz(sizeof(demuxer_t)); - RND_RENAME0(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; - d->movi_end=stream->end_pos; - d->movi_length=UINT_MAX; - d->flags|=DEMUXF_SEEKABLE; - d->synced=0; - d->filepos=0; - d->audio=new_demuxer_stream(d,a_id); - d->video=new_demuxer_stream(d,v_id); - d->sub=new_demuxer_stream(d,s_id); - d->file_format=type; - d->info=mp_mallocz(sizeof(demuxer_info_t)); - stream_reset(stream); - stream_seek(stream,stream->start_pos); - return d; -} - -sh_audio_t *get_sh_audio(demuxer_t *demuxer, int id) -{ - if(id > MAX_A_STREAMS-1 || id < 0) { - MSG_WARN("Requested audio stream id overflow (%d > %d)\n", - id, MAX_A_STREAMS); - return NULL; - } - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return demuxer->a_streams[id]; -} - -sh_audio_t* new_sh_audio_aid(demuxer_t *demuxer,int id,int aid){ - if(id > MAX_A_STREAMS-1 || id < 0) { - MSG_WARN("Requested audio stream id overflow (%d > %d)\n", - id, MAX_A_STREAMS); - return NULL; - } - if(demuxer->a_streams[id]) { - MSG_WARN(MSGTR_AudioStreamRedefined,id); - } else { - sh_audio_t *sh; - MSG_V("==> Found audio stream: %d\n",id); - demuxer->a_streams[id]=mp_calloc(1, sizeof(sh_audio_t)); - sh = demuxer->a_streams[id]; - // set some defaults - sh->afmt=bps2afmt(2); /* PCM */ - sh->audio_out_minsize=8192;/* default size, maybe not enough for Win32/ACM*/ - MSG_V("ID_AUDIO_ID=%d\n", aid); - } - ((sh_audio_t *)demuxer->a_streams[id])->aid = aid; - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return demuxer->a_streams[id]; -} - -void free_sh_audio(sh_audio_t* sh){ - MSG_V("DEMUXER: freeing sh_audio at %p \n",sh); - if(sh->wf) mp_free(sh->wf); - mp_free(sh); -} - -sh_video_t *get_sh_video(demuxer_t *demuxer, int id) -{ - if(id > MAX_V_STREAMS-1 || id < 0) { - MSG_WARN("Requested video stream id overflow (%d > %d)\n", - id, MAX_V_STREAMS); - return NULL; - } - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return demuxer->v_streams[id]; -} - -sh_video_t* new_sh_video_vid(demuxer_t *demuxer,int id,int vid){ - if(id > MAX_V_STREAMS-1 || id < 0) { - MSG_WARN("Requested video stream id overflow (%d > %d)\n", - id, MAX_V_STREAMS); - return NULL; - } - if(demuxer->v_streams[id]) { - MSG_WARN(MSGTR_VideoStreamRedefined,id); - } else { - MSG_V("==> Found video stream: %d\n",id); - demuxer->v_streams[id]=mp_calloc(1, sizeof(sh_video_t)); - MSG_V("ID_VIDEO_ID=%d\n", vid); - } - ((sh_video_t *)demuxer->v_streams[id])->vid = vid; - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return demuxer->v_streams[id]; -} - -void free_sh_video(sh_video_t* sh){ - MSG_V("DEMUXER: freeing sh_video at %p \n",sh); - if(sh->bih) mp_free(sh->bih); - mp_free(sh); -} - -void free_demuxer(demuxer_t *demuxer){ - unsigned i; - if(demuxer) - { - MSG_V("DEMUXER: freeing demuxer at %p \n",demuxer); - - if(demuxer->driver) demuxer->driver->close(demuxer); - - // mp_free streams: - for(i=0;i<MAX_A_STREAMS;i++) if(demuxer->a_streams[i]) free_sh_audio(demuxer->a_streams[i]); - for(i=0;i<MAX_V_STREAMS;i++) if(demuxer->v_streams[i]) free_sh_video(demuxer->v_streams[i]); - //if(sh_audio) free_sh_audio(sh_audio); - //if(sh_video) free_sh_video(sh_video); - // mp_free demuxers: - FREE_DEMUXER_STREAM(demuxer->audio); - FREE_DEMUXER_STREAM(demuxer->video); - FREE_DEMUXER_STREAM(demuxer->sub); - demux_info_free(demuxer); - mp_free(demuxer); - } -} - - -void ds_add_packet(demux_stream_t *ds,demux_packet_t* dp){ -// demux_packet_t* dp=new_demux_packet(len); -// stream_read(stream,dp->buffer,len); -// dp->pts=pts; //(float)pts/90000.0f; -// dp->pos=pos; - // append packet to DS stream: - if(dp->len>0) { - ++ds->packs; - ds->bytes+=dp->len; - if(ds->last) { - // next packet in stream - ds->last->next=dp; - ds->last=dp; - } else { - // first packet in stream - ds->first=ds->last=dp; - } - MSG_DBG2("DEMUX: Append packet to %s, len=%d pts=%5.3f pos=%u [packs: A=%d V=%d]\n", - (ds==ds->demuxer->audio)?"d_audio":"d_video", - dp->len,dp->pts,(unsigned int)dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs); - } - else - MSG_DBG2("DEMUX: Skip packet for %s, len=%d pts=%5.3f pos=%u [packs: A=%d V=%d]\n", - (ds==ds->demuxer->audio)?"d_audio":"d_video", - dp->len,dp->pts,(unsigned int)dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs); -} - -void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,off_t pos,int flags){ - demux_packet_t* dp=new_demux_packet(len); - len=stream_read(stream,dp->buffer,len); - resize_demux_packet(dp,len); - dp->pts=pts; //(float)pts/90000.0f; - dp->pos=pos; - dp->flags=flags; - // append packet to DS stream: - ds_add_packet(ds,dp); - MSG_DBG2("ds_read_packet(%s,%u,%f,%llu,%i)\n",ds==ds->demuxer->video?"video":"audio",len,pts,pos,flags); -} - -int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){ - /* Note: parameter 'ds' can be NULL! */ - return demux->driver->demux(demux,ds); -} - -// return value: -// 0 = EOF -// 1 = succesfull -int ds_fill_buffer(demux_stream_t *ds){ - demuxer_t *demux=ds->demuxer; - if(ds->buffer) mp_free(ds->buffer); -/* ds_free_packs(ds); */ - if(mp_conf.verbose>2) { - if(ds==demux->audio) - MSG_DBG3("ds_fill_buffer(d_audio) called\n"); - else - if(ds==demux->video) - MSG_DBG3("ds_fill_buffer(d_video) called\n"); - else - if(ds==demux->sub) - MSG_DBG3("ds_fill_buffer(d_sub) called\n"); - else - MSG_DBG3("ds_fill_buffer(unknown %p) called\n",ds); - } - check_pin("demuxer",ds->pin,DS_PIN); - while(1){ - if(ds->packs){ - demux_packet_t *p=ds->first; - // copy useful data: - ds->buffer=p->buffer; - ds->buffer_pos=0; - ds->buffer_size=p->len; - ds->pos=p->pos; - ds->dpos+=p->len; // !!! - ++ds->pack_no; - if(p->pts){ - ds->pts=p->pts; - ds->pts_bytes=0; - } - ds->pts_bytes+=p->len; // !!! - ds->flags=p->flags; - // mp_free packet: - ds->bytes-=p->len; - ds->current=p; - ds->first=p->next; - if(!ds->first) ds->last=NULL; - --ds->packs; - return 1; //ds->buffer_size; - } - if(demux->audio->bytes>=MAX_PACK_BYTES){ - MSG_ERR(MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); - MSG_HINT(MSGTR_MaybeNI); - break; - } - if(demux->video->bytes>=MAX_PACK_BYTES){ - MSG_ERR(MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); - MSG_HINT(MSGTR_MaybeNI); - break; - } - if(!demux->driver){ - MSG_DBG2("ds_fill_buffer: demux->driver==NULL failed\n"); - break; // EOF - } - if(!demux->driver->demux(demux,ds)){ - MSG_DBG2("ds_fill_buffer: demux->driver->demux() failed\n"); - break; // EOF - } - } - ds->buffer_pos=ds->buffer_size=0; - ds->buffer=NULL; - ds->current=NULL; - MSG_V("ds_fill_buffer: EOF reached (stream: %s) \n",ds==demux->audio?"audio":"video"); - ds->eof=1; - return 0; -} - -int demux_read_data(demux_stream_t *ds,unsigned char* mem,int len){ -int x; -int bytes=0; -while(len>0){ - x=ds->buffer_size-ds->buffer_pos; - if(x==0){ - if(!ds_fill_buffer(ds)) return bytes; - } else { - if(x>len) x=len; - if(x<0) return bytes; /* BAD!!! sometime happens. Broken stream, driver, gcc ??? */ - if(mem) memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x); - bytes+=x;len-=x;ds->buffer_pos+=x; - } -} -return bytes; -} - -void ds_free_packs(demux_stream_t *ds){ - demux_packet_t *dp=ds->first; - while(dp){ - demux_packet_t *dn=dp->next; - free_demux_packet(dp); - dp=dn; - } - if(ds->asf_packet){ - // mp_free unfinished .asf fragments: - mp_free(ds->asf_packet->buffer); - mp_free(ds->asf_packet); - ds->asf_packet=NULL; - } - ds->first=ds->last=NULL; - ds->packs=0; // !!!!! - ds->bytes=0; - if(ds->current) mp_free(ds->current); - ds->current=NULL; - ds->buffer=NULL; - ds->buffer_pos=ds->buffer_size; - ds->pts=0; ds->pts_bytes=0; -} - -void ds_free_packs_until_pts(demux_stream_t *ds,float pts){ - demux_packet_t *dp=ds->first; - unsigned packs,bytes; - packs=bytes=0; - while(dp){ - demux_packet_t *dn=dp->next; - if(dp->pts >= pts) break; - packs++; - bytes+=dp->len; - free_demux_packet(dp); - dp=dn; - } - if(!dp) - { - if(ds->asf_packet){ - // mp_free unfinished .asf fragments: - mp_free(ds->asf_packet->buffer); - mp_free(ds->asf_packet); - ds->asf_packet=NULL; - } - ds->first=ds->last=NULL; - ds->packs=0; // !!!!! - ds->bytes=0; - ds->pts=0; - } - else - { - ds->first=dp; - ds->packs-=packs; - ds->bytes-=bytes; - ds->pts=dp->pts; - } - if(ds->current) mp_free(ds->current); - ds->current=NULL; - ds->buffer=NULL; - ds->buffer_pos=ds->buffer_size; - ds->pts_bytes=0; -} - -demux_packet_t* clone_demux_packet(demux_packet_t* pack){ - demux_packet_t* dp=(demux_packet_t*)mp_malloc(sizeof(demux_packet_t)); -// while(pack->master) pack=pack->master; // find the master - memcpy(dp,pack,sizeof(demux_packet_t)); -// dp->next=NULL; -// dp->refcount=0; -// dp->master=pack; -// pack->refcount++; - return dp; -} - -int ds_get_packet(demux_stream_t *ds,unsigned char **start){ - while(1){ - int len; - if(ds->buffer_pos>=ds->buffer_size){ - if(!ds_fill_buffer(ds)){ - // EOF - *start = NULL; - return -1; - } - } - len=ds->buffer_size-ds->buffer_pos; - *start = &ds->buffer[ds->buffer_pos]; - ds->buffer_pos+=len; - return len; - } -} - -int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start){ - while(1){ - int len; - if(ds->buffer_pos>=ds->buffer_size){ - *start = NULL; - if(!ds->packs) return -1; // no sub - if(!ds_fill_buffer(ds)) return -1; // EOF - } - len=ds->buffer_size-ds->buffer_pos; - *start = &ds->buffer[ds->buffer_pos]; - ds->buffer_pos+=len; - return len; - } -} - -float ds_get_next_pts(demux_stream_t *ds) { - demuxer_t* demux = ds->demuxer; - while(!ds->first) { - if(demux->audio->bytes>=MAX_PACK_BYTES){ - MSG_ERR(MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); - MSG_HINT(MSGTR_MaybeNI); - return -1; - } - if(demux->video->bytes>=MAX_PACK_BYTES){ - MSG_ERR(MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); - MSG_HINT(MSGTR_MaybeNI); - return -1; - } - if(!demux_fill_buffer(demux,ds)) - return -1; - } - return ds->first->pts; -} - -// ==================================================================== -const struct s_stream_txt_ids -{ - unsigned demuxer_id; - unsigned stream_id; -}stream_txt_ids[]= -{ - { INFOT_AUTHOR, SCTRL_TXT_GET_STREAM_AUTHOR }, - { INFOT_NAME, SCTRL_TXT_GET_STREAM_NAME }, - { INFOT_SUBJECT, SCTRL_TXT_GET_STREAM_SUBJECT }, - { INFOT_COPYRIGHT, SCTRL_TXT_GET_STREAM_COPYRIGHT }, - { INFOT_DESCRIPTION,SCTRL_TXT_GET_STREAM_DESCRIPTION }, - { INFOT_ALBUM, SCTRL_TXT_GET_STREAM_ALBUM }, - { INFOT_DATE, SCTRL_TXT_GET_STREAM_DATE }, - { INFOT_TRACK, SCTRL_TXT_GET_STREAM_TRACK }, - { INFOT_GENRE, SCTRL_TXT_GET_STREAM_GENRE }, - { INFOT_ENCODER, SCTRL_TXT_GET_STREAM_ENCODER }, - { INFOT_SOURCE_MEDIA,SCTRL_TXT_GET_STREAM_SOURCE_MEDIA }, - { INFOT_RATING, SCTRL_TXT_GET_STREAM_RATING }, - { INFOT_COMMENTS, SCTRL_TXT_GET_STREAM_COMMENT }, - { INFOT_MIME, SCTRL_TXT_GET_STREAM_MIME } -}; -static demuxer_t* demux_open_stream(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id) -{ - unsigned i; - demuxer_t *demuxer=NULL,*new_demux=NULL; - - pts_from_bps=0; - demux_aid_vid_mismatch = 0; - i=0; -again: - for(;ddrivers[i]!=&demux_null;i++) { - /* don't remove it from loop!!! (for initializing) */ - demuxer = new_demuxer(stream,DEMUXER_TYPE_UNKNOWN,audio_id,video_id,dvdsub_id); - MSG_V("Probing %s ... ",ddrivers[i]->name); - stream_reset(demuxer->stream); - stream_seek(demuxer->stream,demuxer->stream->start_pos); - if(ddrivers[i]->probe(demuxer)==MPXP_Ok) { - MSG_V("OK\n"); - demuxer->driver = ddrivers[i]; - break; - } - MSG_V("False\n"); - FREE_DEMUXER(demuxer); - } - if(!demuxer || !demuxer->driver) { - MSG_ERR(MSGTR_FormatNotRecognized); - FREE_DEMUXER(demuxer); - return NULL; - } - - if(!(new_demux=demuxer->driver->open(demuxer))) { - MSG_ERR("Can't open stream with '%s'\n", demuxer->driver->name); - demuxer->driver=NULL; - i++; - goto again; - } - demuxer=new_demux; - MSG_OK("Using: %s\n",demuxer->driver->name); - for(i=0;i<sizeof(stream_txt_ids)/sizeof(struct s_stream_txt_ids);i++) - if(!demux_info_get(demuxer,stream_txt_ids[i].demuxer_id)) { - char stream_name[256]; - if(demuxer->stream->driver->control) { - if(demuxer->stream->driver->control(demuxer->stream,stream_txt_ids[i].stream_id,stream_name) == MPXP_Ok) { - demux_info_add(demuxer,stream_txt_ids[i].demuxer_id,stream_name); - } - } - } - stream->demuxer=demuxer; - return demuxer; -} - -static char* audio_stream = NULL; -static char* sub_stream = NULL; -static int demuxer_type = 0, audio_demuxer_type = 0, sub_demuxer_type = 0; - -demuxer_t* RND_RENAME1(demux_open)(stream_t *vs,int file_format,int audio_id,int video_id,int dvdsub_id){ - stream_t *as = NULL,*ss = NULL; - demuxer_t *vd,*ad = NULL,*sd = NULL; - int afmt = 0,sfmt = 0; - any_t* libinput=NULL; -#ifdef HAVE_STREAMIN - libinput=vs->streaming_strl->libinput; -#endif - - if(audio_stream) { - as = RND_RENAME2(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); - if(!ss) { - MSG_ERR("Can't open subtitles stream: %s\n",sub_stream); - return NULL; - } - } - - vd = demux_open_stream(vs,demuxer_type ? demuxer_type : file_format,audio_stream ? -2 : audio_id,video_id, sub_stream ? -2 : dvdsub_id); - if(!vd) - return NULL; - if(as) { - ad = demux_open_stream(as,audio_demuxer_type ? audio_demuxer_type : afmt,audio_id,-2,-2); - if(!ad) - MSG_WARN("Failed to open audio demuxer: %s\n",audio_stream); - else if(ad->audio->sh && ((sh_audio_t*)ad->audio->sh)->wtag == 0x55) // MP3 - m_config_set_flag(mp_data->mconfig,"mp3.hr-seek",1); // Enable high res seeking - } - if(ss) { - sd = demux_open_stream(ss,sub_demuxer_type ? sub_demuxer_type : sfmt,-2,-2,dvdsub_id); - if(!sd) - MSG_WARN("Failed to open subtitles demuxer: %s\n",sub_stream); - } - - if(ad && sd) - return new_demuxers_demuxer(vd,ad,sd); - else if(ad) - return new_demuxers_demuxer(vd,ad,vd); - else if(sd) - return new_demuxers_demuxer(vd,vd,sd); - return vd; -} - -int demux_seek(demuxer_t *demuxer,const seek_args_t* seeka){ - demux_stream_t *d_audio=demuxer->audio; - demux_stream_t *d_video=demuxer->video; - sh_audio_t *sh_audio=d_audio->sh; - sh_video_t *sh_video=d_video->sh; - - if(!(demuxer->stream->type&STREAMTYPE_SEEKABLE)) - { - MSG_WARN("Stream is not seekable\n"); - return 0; - } - if(!(demuxer->flags&DEMUXF_SEEKABLE)) - { - MSG_WARN("Demuxer is not seekable\n"); - return 0; - } - - // clear demux buffers: - if(sh_audio){ ds_free_packs(d_audio);sh_audio->a_buffer_len=0;} - ds_free_packs(d_video); - - stream_set_eof(demuxer->stream,0); // clear eof flag - demuxer->video->eof=0; - demuxer->audio->eof=0; - demuxer->video->prev_pts=0; - demuxer->audio->prev_pts=0; - - if(sh_audio) sh_audio->timer=0; - if(demuxer->driver->seek) demuxer->driver->seek(demuxer,seeka); - else MSG_WARN("Demuxer seek error\n"); - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return 1; -} - -static const char *info_names[INFOT_MAX] = -{ - "Author", - "Name", - "Subject", - "Copyright", - "Description", - "Album", - "Date", - "Track", - "Genre", - "Encoder", - "SrcMedia", - "WWW", - "Mail", - "Rating", - "Comments", - "Mime" -}; - -int demux_info_add(demuxer_t *demuxer, unsigned opt, const char *param) -{ - if(!opt || opt > INFOT_MAX) - { - MSG_WARN("Unknown info type %u\n",opt); - return 0; - } - opt--; - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - if(((demuxer_info_t *)demuxer->info)->id[opt]) - { - MSG_V( "Demuxer info '%s' already present as '%s'!\n",info_names[opt],((demuxer_info_t *)demuxer->info)->id[opt]); - mp_free(((demuxer_info_t *)demuxer->info)->id[opt]); - } - ((demuxer_info_t *)demuxer->info)->id[opt]=nls_recode2screen_cp(sub_data.cp,param,strlen(param)); - return 1; -} - -int demux_info_print(const demuxer_t *demuxer,const char *filename) -{ - unsigned i; - MSG_HINT(" CLIP INFO (%s):\n",filename); - for(i=0;i<INFOT_MAX;i++) - if(((demuxer_info_t *)demuxer->info)->id[i]) - MSG_HINT(" %s: %s\n",info_names[i],((demuxer_info_t *)demuxer->info)->id[i]); - return 0; -} - -void demux_info_free(demuxer_t* demuxer) -{ - unsigned i; - if(demuxer->info) - { - for(i=0;i<INFOT_MAX;i++) - if(((demuxer_info_t *)demuxer->info)->id[i]) - mp_free(((demuxer_info_t *)demuxer->info)->id[i]); - mp_free(demuxer->info); - } -} - -const char* demux_info_get(const demuxer_t *demuxer, unsigned opt) { - if(!opt || opt > INFOT_MAX) return NULL; - return ((demuxer_info_t *)demuxer->info)->id[opt-1]; -} - -/******************* Options stuff **********************/ - -static const config_t demux_opts[] = { - { "audiofile", &audio_stream, CONF_TYPE_STRING, 0, 0, 0, "forces reading of audio-stream from other file" }, - { "subfile", &sub_stream, CONF_TYPE_STRING, 0, 0, 0, "forces reading of subtitles from other file" }, - { "type", &demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, "forces demuxer by given number" }, - { "audio", &audio_demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, "forces using of audio-demuxer" }, - { "sub", &sub_demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, "forces using of subtitle-demuxer" }, - { NULL, NULL, 0, 0, 0, 0, NULL} -}; - -static const config_t demuxer_opts[] = { - { "demuxer", &demux_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, "Demuxer related options" }, - { NULL, NULL, 0, 0, 0, 0, NULL} -}; - -void demuxer_register_options(m_config_t* cfg) { - m_config_register_options(cfg,demuxer_opts); -} - -static MPXP_Rc demux_control(const demuxer_t *demuxer, int cmd, any_t*arg) { - - if(demuxer->driver) - return demuxer->driver->control(demuxer,cmd,arg); - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return MPXP_Unknown; -} - -int demuxer_switch_audio(const demuxer_t *demuxer, int id) -{ - if(id>MAX_A_STREAMS) id=0; - if (demux_control(demuxer, DEMUX_CMD_SWITCH_AUDIO, &id) == MPXP_Unknown) - id = demuxer->audio->id; - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return id; -} - -int demuxer_switch_video(const demuxer_t *demuxer, int id) -{ - if(id>MAX_V_STREAMS) id=0; - if (demux_control(demuxer, DEMUX_CMD_SWITCH_VIDEO, &id) == MPXP_Unknown) - id = demuxer->audio->id; - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return id; -} - -int demuxer_switch_subtitle(const demuxer_t *demuxer, int id) -{ - if(id>MAX_S_STREAMS) id=0; - if (demux_control(demuxer, DEMUX_CMD_SWITCH_SUBS, &id) == MPXP_Unknown) - id = demuxer->audio->id; - check_pin("demuxer",demuxer->pin,DEMUX_PIN); - return id; -} - -demux_packet_t* new_demux_packet(int len){ - demux_packet_t* dp=mp_malloc(sizeof(demux_packet_t)); - dp->len=len; - dp->buffer=mp_malloc(len); - dp->next=NULL; - dp->pts=0; - dp->pos=0; - dp->flags=0; - return dp; -} - -void free_demux_packet(demux_packet_t* dp){ - mp_free(dp->buffer); - mp_free(dp); -} - -void resize_demux_packet(demux_packet_t* dp, int len) -{ - if(dp->len!=len) - { - if(len) - { - dp->buffer=(unsigned char *)mp_realloc(dp->buffer,len+8); - memset(dp->buffer+len,0,8); - } - else - { - if(dp->buffer) mp_free(dp->buffer); - dp->buffer=NULL; - } - dp->len=len; - } -} Copied: mplayerxp/libmpdemux/demuxer.cpp (from rev 369, mplayerxp/libmpdemux/demuxer.c) =================================================================== --- mplayerxp/libmpdemux/demuxer.cpp (rev 0) +++ mplayerxp/libmpdemux/demuxer.cpp 2012-11-15 14:13:23 UTC (rev 372) @@ -0,0 +1,829 @@ +//=================== DEMUXER v2.5 ========================= +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +extern "C" { +#include "stream.h" +#include "mp_config.h" +#include "help_mp.h" +#include "libmpsub/subreader.h" +#include "libmpconf/cfgparser.h" +#include "nls/nls.h" + +#include "demuxer.h" +#include "stheader.h" + +#include "osdep/fastmemcpy.h" +#include "osdep/mplib.h" +#include "libvo/sub.h" +#include "libao2/afmt.h" +#include "demux_msg.h" +} +#include "mplayerxp.h" + +extern demuxer_driver_t demux_aiff; +extern demuxer_driver_t demux_rawaudio; +extern demuxer_driver_t demux_rawvideo; +extern demuxer_driver_t demux_avi; +extern demuxer_driver_t demux_y4m; +extern demuxer_driver_t demux_asf; +extern demuxer_driver_t demux_nuv; +extern demuxer_driver_t demux_nsv; +extern demuxer_driver_t demux_mov; +extern demuxer_driver_t demux_mkv; +extern demuxer_driver_t demux_vivo; +extern demuxer_driver_t demux_ra; +extern demuxer_driver_t demux_real; +extern demuxer_driver_t demux_fli; +extern demuxer_driver_t demux_film; +extern demuxer_driver_t demux_roq; +extern demuxer_driver_t demux_bmp; +extern demuxer_driver_t demux_ogg; +extern demuxer_driver_t demux_pva; +extern demuxer_driver_t demux_smjpeg; +extern demuxer_driver_t demux_vqf; +extern demuxer_driver_t demux_mpxpav64; +extern demuxer_driver_t demux_mpgps; +extern demuxer_driver_t demux_mpgts; +extern demuxer_driver_t demux_ty; +extern demuxer_driver_t demux_audio; +extern demuxer_driver_t demux_lavf; +extern demuxer_driver_t demux_null; + +static const demuxer_driver_t *ddrivers[] = +{ + &demux_rawaudio, + &demux_rawvideo, + &demux_avi, + &demux_y4m, + &demux_asf, + &demux_nsv, + &demux_nuv, + &demux_mov, + &demux_mkv, + &demux_vivo, + &demux_ra, + &demux_real, + &demux_fli, + &demux_film, + &demux_roq, + &demux_bmp, +#ifdef HAVE_LIBVORBIS + &demux_ogg, +#endif + &demux_pva, + &demux_smjpeg, + &demux_vqf, + &demux_mpxpav64, + &demux_mpgps, + &demux_aiff, + &demux_audio, + &demux_mpgts, + &demux_ty, + &demux_lavf, + &demux_null, + NULL +}; + +typedef struct demuxer_info_st { + char *id[INFOT_MAX]; +} demuxer_info_t; + +void libmpdemux_register_options(m_config_t* cfg) +{ + unsigned i; + for(i=0;ddrivers[i];i++) { + if(ddrivers[i]->options) + m_config_register_options(cfg,ddrivers[i]->options); + if(ddrivers[i]==&demux_null) break; + } +} + +void free_demuxer_stream(demux_stream_t *ds){ + if(ds) { + ds_free_packs(ds); + mp_free(ds); + } +} + +int demux_aid_vid_mismatch = 0; + +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)); + ds->pin=DS_PIN; + ds->buffer_pos=ds->buffer_size=0; + ds->buffer=NULL; + ds->pts=0; + ds->pts_bytes=0; + ds->eof=0; + ds->pos=0; + ds->dpos=0; + ds->pack_no=0; +//--------------- + ds->packs=0; + ds->bytes=0; + ds->first=ds->last=ds->current=NULL; + ds->id=id; + ds->demuxer=demuxer; +//---------------- + ds->asf_seq=-1; + ds->asf_packet=NULL; +//---------------- + ds->sh=NULL; + ds->pts_flags=0; + ds->prev_pts=ds->pts_corr=0; + return ds; +} + +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)); + d->pin=DEMUX_PIN; + d->stream=stream; + d->movi_start=stream->start_pos; + d->movi_end=stream->end_pos; + d->movi_length=UINT_MAX; + d->flags|=DEMUXF_SEEKABLE; + d->synced=0; + d->filepos=0; + d->audio=new_demuxer_stream(d,a_id); + d->video=new_demuxer_stream(d,v_id); + d->sub=new_demuxer_stream(d,s_id); + d->file_format=type; + d->info=mp_mallocz(sizeof(demuxer_info_t)); + stream_reset(stream); + stream_seek(stream,stream->start_pos); + return d; +} + +sh_audio_t *get_sh_audio(demuxer_t *demuxer, int id) +{ + if(id > MAX_A_STREAMS-1 || id < 0) { + MSG_WARN("Requested audio stream id overflow (%d > %d)\n", + id, MAX_A_STREAMS); + return NULL; + } + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return reinterpret_cast<sh_audio_t*>(demuxer->a_streams[id]); +} + +sh_audio_t* new_sh_audio_aid(demuxer_t *demuxer,int id,int aid){ + if(id > MAX_A_STREAMS-1 || id < 0) { + MSG_WARN("Requested audio stream id overflow (%d > %d)\n", + id, MAX_A_STREAMS); + return NULL; + } + if(demuxer->a_streams[id]) { + MSG_WARN(MSGTR_AudioStreamRedefined,id); + } else { + sh_audio_t *sh; + MSG_V("==> Found audio stream: %d\n",id); + demuxer->a_streams[id]=mp_calloc(1, sizeof(sh_audio_t)); + sh = reinterpret_cast<sh_audio_t*>(demuxer->a_streams[id]); + // set some defaults + sh->afmt=bps2afmt(2); /* PCM */ + sh->audio_out_minsize=8192;/* default size, maybe not enough for Win32/ACM*/ + MSG_V("ID_AUDIO_ID=%d\n", aid); + } + ((sh_audio_t *)demuxer->a_streams[id])->aid = aid; + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return reinterpret_cast<sh_audio_t*>(demuxer->a_streams[id]); +} + +void free_sh_audio(sh_audio_t* sh){ + MSG_V("DEMUXER: freeing sh_audio at %p \n",sh); + if(sh->wf) mp_free(sh->wf); + mp_free(sh); +} + +sh_video_t* get_sh_video(demuxer_t *demuxer, int id) +{ + if(id > MAX_V_STREAMS-1 || id < 0) { + MSG_WARN("Requested video stream id overflow (%d > %d)\n", + id, MAX_V_STREAMS); + return NULL; + } + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return reinterpret_cast<sh_video_t*>(demuxer->v_streams[id]); +} + +sh_video_t* new_sh_video_vid(demuxer_t *demuxer,int id,int vid){ + if(id > MAX_V_STREAMS-1 || id < 0) { + MSG_WARN("Requested video stream id overflow (%d > %d)\n", + id, MAX_V_STREAMS); + return NULL; + } + if(demuxer->v_streams[id]) { + MSG_WARN(MSGTR_VideoStreamRedefined,id); + } else { + MSG_V("==> Found video stream: %d\n",id); + demuxer->v_streams[id]=mp_calloc(1, sizeof(sh_video_t)); + MSG_V("ID_VIDEO_ID=%d\n", vid); + } + ((sh_video_t *)demuxer->v_streams[id])->vid = vid; + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return reinterpret_cast<sh_video_t*>(demuxer->v_streams[id]); +} + +void free_sh_video(sh_video_t* sh){ + MSG_V("DEMUXER: freeing sh_video at %p \n",sh); + if(sh->bih) mp_free(sh->bih); + mp_free(sh); +} + +void free_demuxer(demuxer_t *demuxer){ + unsigned i; + if(demuxer) + { + MSG_V("DEMUXER: freeing demuxer at %p \n",demuxer); + + if(demuxer->driver) demuxer->driver->close(demuxer); + + // mp_free streams: + for(i=0;i<MAX_A_STREAMS;i++) if(demuxer->a_streams[i]) free_sh_audio(reinterpret_cast<sh_audio_t*>(demuxer->a_streams[i])); + for(i=0;i<MAX_V_STREAMS;i++) if(demuxer->v_streams[i]) free_sh_video(reinterpret_cast<sh_video_t*>(demuxer->v_streams[i])); + //if(sh_audio) free_sh_audio(sh_audio); + //if(sh_video) free_sh_video(sh_video); + // mp_free demuxers: + FREE_DEMUXER_STREAM(demuxer->audio); + FREE_DEMUXER_STREAM(demuxer->video); + FREE_DEMUXER_STREAM(demuxer->sub); + demux_info_free(demuxer); + mp_free(demuxer); + } +} + + +void ds_add_packet(demux_stream_t *ds,demux_packet_t* dp){ +// demux_packet_t* dp=new_demux_packet(len); +// stream_read(stream,dp->buffer,len); +// dp->pts=pts; //(float)pts/90000.0f; +// dp->pos=pos; + // append packet to DS stream: + if(dp->len>0) { + ++ds->packs; + ds->bytes+=dp->len; + if(ds->last) { + // next packet in stream + ds->last->next=dp; + ds->last=dp; + } else { + // first packet in stream + ds->first=ds->last=dp; + } + MSG_DBG2("DEMUX: Append packet to %s, len=%d pts=%5.3f pos=%u [packs: A=%d V=%d]\n", + (ds==ds->demuxer->audio)?"d_audio":"d_video", + dp->len,dp->pts,(unsigned int)dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs); + } + else + MSG_DBG2("DEMUX: Skip packet for %s, len=%d pts=%5.3f pos=%u [packs: A=%d V=%d]\n", + (ds==ds->demuxer->audio)?"d_audio":"d_video", + dp->len,dp->pts,(unsigned int)dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs); +} + +void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,off_t pos,int flags){ + demux_packet_t* dp=new_demux_packet(len); + len=stream_read(stream,dp->buffer,len); + resize_demux_packet(dp,len); + dp->pts=pts; //(float)pts/90000.0f; + dp->pos=pos; + dp->flags=flags; + // append packet to DS stream: + ds_add_packet(ds,dp); + MSG_DBG2("ds_read_packet(%s,%u,%f,%llu,%i)\n",ds==ds->demuxer->video?"video":"audio",len,pts,pos,flags); +} + +int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){ + /* Note: parameter 'ds' can be NULL! */ + return demux->driver->demux(demux,ds); +} + +// return value: +// 0 = EOF +// 1 = succesfull +int ds_fill_buffer(demux_stream_t *ds){ + demuxer_t *demux=ds->demuxer; + if(ds->buffer) mp_free(ds->buffer); +/* ds_free_packs(ds); */ + if(mp_conf.verbose>2) { + if(ds==demux->audio) + MSG_DBG3("ds_fill_buffer(d_audio) called\n"); + else + if(ds==demux->video) + MSG_DBG3("ds_fill_buffer(d_video) called\n"); + else + if(ds==demux->sub) + MSG_DBG3("ds_fill_buffer(d_sub) called\n"); + else + MSG_DBG3("ds_fill_buffer(unknown %p) called\n",ds); + } + check_pin("demuxer",ds->pin,DS_PIN); + while(1){ + if(ds->packs){ + demux_packet_t *p=ds->first; + // copy useful data: + ds->buffer=p->buffer; + ds->buffer_pos=0; + ds->buffer_size=p->len; + ds->pos=p->pos; + ds->dpos+=p->len; // !!! + ++ds->pack_no; + if(p->pts){ + ds->pts=p->pts; + ds->pts_bytes=0; + } + ds->pts_bytes+=p->len; // !!! + ds->flags=p->flags; + // mp_free packet: + ds->bytes-=p->len; + ds->current=p; + ds->first=p->next; + if(!ds->first) ds->last=NULL; + --ds->packs; + return 1; //ds->buffer_size; + } + if(demux->audio->bytes>=MAX_PACK_BYTES){ + MSG_ERR(MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); + MSG_HINT(MSGTR_MaybeNI); + break; + } + if(demux->video->bytes>=MAX_PACK_BYTES){ + MSG_ERR(MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); + MSG_HINT(MSGTR_MaybeNI); + break; + } + if(!demux->driver){ + MSG_DBG2("ds_fill_buffer: demux->driver==NULL failed\n"); + break; // EOF + } + if(!demux->driver->demux(demux,ds)){ + MSG_DBG2("ds_fill_buffer: demux->driver->demux() failed\n"); + break; // EOF + } + } + ds->buffer_pos=ds->buffer_size=0; + ds->buffer=NULL; + ds->current=NULL; + MSG_V("ds_fill_buffer: EOF reached (stream: %s) \n",ds==demux->audio?"audio":"video"); + ds->eof=1; + return 0; +} + +int demux_read_data(demux_stream_t *ds,unsigned char* mem,int len){ +int x; +int bytes=0; +while(len>0){ + x=ds->buffer_size-ds->buffer_pos; + if(x==0){ + if(!ds_fill_buffer(ds)) return bytes; + } else { + if(x>len) x=len; + if(x<0) return bytes; /* BAD!!! sometime happens. Broken stream, driver, gcc ??? */ + if(mem) memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x); + bytes+=x;len-=x;ds->buffer_pos+=x; + } +} +return bytes; +} + +void ds_free_packs(demux_stream_t *ds){ + demux_packet_t *dp=ds->first; + while(dp){ + demux_packet_t *dn=dp->next; + free_demux_packet(dp); + dp=dn; + } + if(ds->asf_packet){ + // mp_free unfinished .asf fragments: + mp_free(ds->asf_packet->buffer); + mp_free(ds->asf_packet); + ds->asf_packet=NULL; + } + ds->first=ds->last=NULL; + ds->packs=0; // !!!!! + ds->bytes=0; + if(ds->current) mp_free(ds->current); + ds->current=NULL; + ds->buffer=NULL; + ds->buffer_pos=ds->buffer_size; + ds->pts=0; ds->pts_bytes=0; +} + +void ds_free_packs_until_pts(demux_stream_t *ds,float pts){ + demux_packet_t *dp=ds->first; + unsigned packs,bytes; + packs=bytes=0; + while(dp){ + demux_packet_t *dn=dp->next; + if(dp->pts >= pts) break; + packs++; + bytes+=dp->len; + free_demux_packet(dp); + dp=dn; + } + if(!dp) + { + if(ds->asf_packet){ + // mp_free unfinished .asf fragments: + mp_free(ds->asf_packet->buffer); + mp_free(ds->asf_packet); + ds->asf_packet=NULL; + } + ds->first=ds->last=NULL; + ds->packs=0; // !!!!! + ds->bytes=0; + ds->pts=0; + } + else + { + ds->first=dp; + ds->packs-=packs; + ds->bytes-=bytes; + ds->pts=dp->pts; + } + if(ds->current) mp_free(ds->current); + ds->current=NULL; + ds->buffer=NULL; + ds->buffer_pos=ds->buffer_size; + ds->pts_bytes=0; +} + +demux_packet_t* clone_demux_packet(demux_packet_t* pack){ + demux_packet_t* dp=(demux_packet_t*)mp_malloc(sizeof(demux_packet_t)); +// while(pack->master) pack=pack->master; // find the master + memcpy(dp,pack,sizeof(demux_packet_t)); +// dp->next=NULL; +// dp->refcount=0; +// dp->master=pack; +// pack->refcount++; + return dp; +} + +int ds_get_packet(demux_stream_t *ds,unsigned char **start){ + while(1){ + int len; + if(ds->buffer_pos>=ds->buffer_size){ + if(!ds_fill_buffer(ds)){ + // EOF + *start = NULL; + return -1; + } + } + len=ds->buffer_size-ds->buffer_pos; + *start = &ds->buffer[ds->buffer_pos]; + ds->buffer_pos+=len; + return len; + } +} + +int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start){ + while(1){ + int len; + if(ds->buffer_pos>=ds->buffer_size){ + *start = NULL; + if(!ds->packs) return -1; // no sub + if(!ds_fill_buffer(ds)) return -1; // EOF + } + len=ds->buffer_size-ds->buffer_pos; + *start = &ds->buffer[ds->buffer_pos]; + ds->buffer_pos+=len; + return len; + } +} + +float ds_get_next_pts(demux_stream_t *ds) { + demuxer_t* demux = ds->demuxer; + while(!ds->first) { + if(demux->audio->bytes>=MAX_PACK_BYTES){ + MSG_ERR(MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); + MSG_HINT(MSGTR_MaybeNI); + return -1; + } + if(demux->video->bytes>=MAX_PACK_BYTES){ + MSG_ERR(MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); + MSG_HINT(MSGTR_MaybeNI); + return -1; + } + if(!demux_fill_buffer(demux,ds)) + return -1; + } + return ds->first->pts; +} + +// ==================================================================== +const struct s_stream_txt_ids +{ + unsigned demuxer_id; + unsigned stream_id; +}stream_txt_ids[]= +{ + { INFOT_AUTHOR, SCTRL_TXT_GET_STREAM_AUTHOR }, + { INFOT_NAME, SCTRL_TXT_GET_STREAM_NAME }, + { INFOT_SUBJECT, SCTRL_TXT_GET_STREAM_SUBJECT }, + { INFOT_COPYRIGHT, SCTRL_TXT_GET_STREAM_COPYRIGHT }, + { INFOT_DESCRIPTION,SCTRL_TXT_GET_STREAM_DESCRIPTION }, + { INFOT_ALBUM, SCTRL_TXT_GET_STREAM_ALBUM }, + { INFOT_DATE, SCTRL_TXT_GET_STREAM_DATE }, + { INFOT_TRACK, SCTRL_TXT_GET_STREAM_TRACK }, + { INFOT_GENRE, SCTRL_TXT_GET_STREAM_GENRE }, + { INFOT_ENCODER, SCTRL_TXT_GET_STREAM_ENCODER }, + { INFOT_SOURCE_MEDIA,SCTRL_TXT_GET_STREAM_SOURCE_MEDIA }, + { INFOT_RATING, SCTRL_TXT_GET_STREAM_RATING }, + { INFOT_COMMENTS, SCTRL_TXT_GET_STREAM_COMMENT }, + { INFOT_MIME, SCTRL_TXT_GET_STREAM_MIME } +}; +static demuxer_t* demux_open_stream(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id) +{ + unsigned i; + demuxer_t *demuxer=NULL,*new_demux=NULL; + + pts_from_bps=0; + demux_aid_vid_mismatch = 0; + i=0; +again: + for(;ddrivers[i]!=&demux_null;i++) { + MSG_V("Probing %s ... ",ddrivers[i]->name); + /* don't remove it from loop!!! (for initializing) */ + demuxer = new_demuxer(stream,DEMUXER_TYPE_UNKNOWN,audio_id,video_id,dvdsub_id); + stream_reset(demuxer->stream); + stream_seek(demuxer->stream,demuxer->stream->start_pos); + if(ddrivers[i]->probe(demuxer)==MPXP_Ok) { + MSG_V("OK\n"); + demuxer->driver = ddrivers[i]; + break; + } + MSG_V("False\n"); + FREE_DEMUXER(demuxer); + } + if(!demuxer || !demuxer->driver) { + MSG_ERR(MSGTR_FormatNotRecognized); + FREE_DEMUXER(demuxer); + return NULL; + } + + if(!(new_demux=demuxer->driver->open(demuxer))) { + MSG_ERR("Can't open stream with '%s'\n", demuxer->driver->name); + demuxer->driver=NULL; + i++; + goto again; + } + demuxer=new_demux; + MSG_OK("Using: %s\n",demuxer->driver->name); + for(i=0;i<sizeof(stream_txt_ids)/sizeof(struct s_stream_txt_ids);i++) + if(!demux_info_get(demuxer,stream_txt_ids[i].demuxer_id)) { + char stream_name[256]; + if(demuxer->stream->driver->control) { + if(demuxer->stream->driver->control(demuxer->stream,stream_txt_ids[i].stream_id,stream_name) == MPXP_Ok) { + demux_info_add(demuxer,stream_txt_ids[i].demuxer_id,stream_name); + } + } + } + stream->demuxer=demuxer; + return demuxer; +} + +static char* audio_stream = NULL; +static char* sub_stream = NULL; +static int demuxer_type = 0, audio_demuxer_type = 0, sub_demuxer_type = 0; + +demuxer_t* demux_open(stream_t *vs,int file_format,int audio_id,int video_id,int dvdsub_id){ + stream_t *as = NULL,*ss = NULL; + demuxer_t *vd,*ad = NULL,*sd = NULL; + int afmt = 0,sfmt = 0; + any_t* libinput=NULL; +#ifdef HAVE_STREAMIN + libinput=vs->streaming_strl->libinput; +#endif + + if(audio_stream) { + as = RND_RENAME2(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); + if(!ss) { + MSG_ERR("Can't open subtitles stream: %s\n",sub_stream); + return NULL; + } + } + + vd = demux_open_stream(vs,demuxer_type ? demuxer_type : file_format,audio_stream ? -2 : audio_id,video_id, sub_stream ? -2 : dvdsub_id); + if(!vd) + return NULL; + if(as) { + ad = demux_open_stream(as,audio_demuxer_type ? audio_demuxer_type : afmt,audio_id,-2,-2); + if(!ad) + MSG_WARN("Failed to open audio demuxer: %s\n",audio_stream); + else if(ad->audio->sh && ((sh_audio_t*)ad->audio->sh)->wtag == 0x55) // MP3 + m_config_set_flag(mp_data->mconfig,"mp3.hr-seek",1); // Enable high res seeking + } + if(ss) { + sd = demux_open_stream(ss,sub_demuxer_type ? sub_demuxer_type : sfmt,-2,-2,dvdsub_id); + if(!sd) + MSG_WARN("Failed to open subtitles demuxer: %s\n",sub_stream); + } + + if(ad && sd) + return new_demuxers_demuxer(vd,ad,sd); + else if(ad) + return new_demuxers_demuxer(vd,ad,vd); + else if(sd) + return new_demuxers_demuxer(vd,vd,sd); + return vd; +} + +int demux_seek(demuxer_t *demuxer,const seek_args_t* seeka){ + demux_stream_t *d_audio=demuxer->audio; + demux_stream_t *d_video=demuxer->video; + sh_audio_t *sh_audio=reinterpret_cast<sh_audio_t*>(d_audio->sh); + + if(!(demuxer->stream->type&STREAMTYPE_SEEKABLE)) + { + MSG_WARN("Stream is not seekable\n"); + return 0; + } + if(!(demuxer->flags&DEMUXF_SEEKABLE)) + { + MSG_WARN("Demuxer is not seekable\n"); + return 0; + } + + // clear demux buffers: + if(sh_audio){ ds_free_packs(d_audio);sh_audio->a_buffer_len=0;} + ds_free_packs(d_video); + + stream_set_eof(demuxer->stream,0); // clear eof flag + demuxer->video->eof=0; + demuxer->audio->eof=0; + demuxer->video->prev_pts=0; + demuxer->audio->prev_pts=0; + + if(sh_audio) sh_audio->timer=0; + if(demuxer->driver->seek) demuxer->driver->seek(demuxer,seeka); + else MSG_WARN("Demuxer seek error\n"); + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return 1; +} + +static const char *info_names[INFOT_MAX] = +{ + "Author", + "Name", + "Subject", + "Copyright", + "Description", + "Album", + "Date", + "Track", + "Genre", + "Encoder", + "SrcMedia", + "WWW", + "Mail", + "Rating", + "Comments", + "Mime" +}; + +int demux_info_add(demuxer_t *demuxer, unsigned opt, const char *param) +{ + if(!opt || opt > INFOT_MAX) + { + MSG_WARN("Unknown info type %u\n",opt); + return 0; + } + opt--; + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + if(((demuxer_info_t *)demuxer->info)->id[opt]) + { + MSG_V( "Demuxer info '%s' already present as '%s'!\n",info_names[opt],((demuxer_info_t *)demuxer->info)->id[opt]); + mp_free(((demuxer_info_t *)demuxer->info)->id[opt]); + } + ((demuxer_info_t *)demuxer->info)->id[opt]=nls_recode2screen_cp(sub_data.cp,param,strlen(param)); + return 1; +} + +int demux_info_print(const demuxer_t *demuxer,const char *filename) +{ + unsigned i; + MSG_HINT(" CLIP INFO (%s):\n",filename); + for(i=0;i<INFOT_MAX;i++) + if(((demuxer_info_t *)demuxer->info)->id[i]) + MSG_HINT(" %s: %s\n",info_names[i],((demuxer_info_t *)demuxer->info)->id[i]); + return 0; +} + +void demux_info_free(demuxer_t* demuxer) +{ + unsigned i; + if(demuxer->info) + { + for(i=0;i<INFOT_MAX;i++) + if(((demuxer_info_t *)demuxer->info)->id[i]) + mp_free(((demuxer_info_t *)demuxer->info)->id[i]); + mp_free(demuxer->info); + } +} + +const char* demux_info_get(const demuxer_t *demuxer, unsigned opt) { + if(!opt || opt > INFOT_MAX) return NULL; + return ((demuxer_info_t *)demuxer->info)->id[opt-1]; +} + +/******************* Options stuff **********************/ + +static const config_t demux_opts[] = { + { "audiofile", &audio_stream, CONF_TYPE_STRING, 0, 0, 0, "forces reading of audio-stream from other file" }, + { "subfile", &sub_stream, CONF_TYPE_STRING, 0, 0, 0, "forces reading of subtitles from other file" }, + { "type", &demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, "forces demuxer by given number" }, + { "audio", &audio_demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, "forces using of audio-demuxer" }, + { "sub", &sub_demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, "forces using of subtitle-demuxer" }, + { NULL, NULL, 0, 0, 0, 0, NULL} +}; + +static const config_t demuxer_opts[] = { + { "demuxer", (any_t*)&demux_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, "Demuxer related options" }, + { NULL, NULL, 0, 0, 0, 0, NULL} +}; + +void demuxer_register_options(m_config_t* cfg) { + m_config_register_options(cfg,demuxer_opts); +} + +static MPXP_Rc demux_control(const demuxer_t *demuxer, int cmd, any_t*arg) { + + if(demuxer->driver) + return demuxer->driver->control(demuxer,cmd,arg); + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return MPXP_Unknown; +} + +int demuxer_switch_audio(const demuxer_t *demuxer, int id) +{ + if(id>MAX_A_STREAMS) id=0; + if (demux_control(demuxer, DEMUX_CMD_SWITCH_AUDIO, &id) == MPXP_Unknown) + id = demuxer->audio->id; + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return id; +} + +int demuxer_switch_video(const demuxer_t *demuxer, int id) +{ + if(id>MAX_V_STREAMS) id=0; + if (demux_control(demuxer, DEMUX_CMD_SWITCH_VIDEO, &id) == MPXP_Unknown) + id = demuxer->audio->id; + check_pin("demuxer",demuxer->pin,DEMUX_PIN); + return id; +} + +int demuxer_switch_subtitle(const demuxer_t *demuxer, int id) +{ + if(id>MAX_S_STREAMS) id=0; + if (demu... [truncated message content] |