Mercurial > mplayer.hg
view libmpdemux/stream.c @ 9278:caea8ed36b48
The reason why mplayer crashes (in some cases) when using x11
output and -wid (>0) parameter is this:
Mplayer by default creates a colormap using DirectColor visual. If the
window given to mplayer uses TrueColor visual there will be an error
when mplayer sets the colormap for the window. This patch
modifies mplayer to use TrueColor visual if the window given to mplayer
uses TrueColor. Another solution is to make sure that the window given to
mplayer is created using DirectColor visual if it is supported by the
display.
Jouni Tulkki <jitulkki@cc.hut.fi>
author | arpi |
---|---|
date | Tue, 04 Feb 2003 18:31:44 +0000 |
parents | c5ca1ae42555 |
children | edfe34c5405d |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <fcntl.h> #include <signal.h> #include "config.h" #include "mp_msg.h" #include "help_mp.h" #include "../linux/shmem.h" #include "stream.h" #include "demuxer.h" extern int verbose; // defined in mplayer.c #include "cue_read.h" #ifdef HAVE_VCD #ifdef __FreeBSD__ #include "vcd_read_fbsd.h" #elif defined(__NetBSD__) #include "vcd_read_nbsd.h" #else #include "vcd_read.h" #endif #endif //#include "vcd_read_bincue.h" #ifdef USE_DVDREAD int dvd_read_sector(dvd_priv_t *d,unsigned char* data); void dvd_seek(dvd_priv_t *d,int pos); void dvd_close(dvd_priv_t *d); #endif #ifdef HAVE_CDDA int read_cdda(stream_t* s); void seek_cdda(stream_t* s); void close_cdda(stream_t* s); #endif #ifdef LIBSMBCLIENT #include "libsmbclient.h" #endif //=================== STREAMER ========================= int stream_fill_buffer(stream_t *s){ int len; if(s->eof){ s->buf_pos=s->buf_len=0; return 0; } switch(s->type){ #ifdef LIBSMBCLIENT case STREAMTYPE_SMB: len=smbc_read(s->fd,s->buffer,STREAM_BUFFER_SIZE); break; #endif case STREAMTYPE_FILE: case STREAMTYPE_STREAM: case STREAMTYPE_PLAYLIST: #ifdef STREAMING if( s->streaming_ctrl!=NULL ) { len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl);break; } else { len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE);break; } #else len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE);break; #endif #ifdef HAVE_CDDA case STREAMTYPE_CDDA: len = read_cdda(s); break; #endif #ifdef HAVE_VCD case STREAMTYPE_VCD: len=vcd_read(s->fd,s->buffer);break; #endif case STREAMTYPE_VCDBINCUE: len=cue_vcd_read(s->buffer);break; #ifdef USE_DVDNAV case STREAMTYPE_DVDNAV: { dvdnav_stream_read((dvdnav_priv_t*)s->priv,s->buffer,&len); if (len==0) return 0; // this was an event, so repeat the read break; } #endif #ifdef USE_DVDREAD case STREAMTYPE_DVD: { off_t pos=dvd_read_sector(s->priv,s->buffer); if(pos>=0){ len=2048; // full sector s->pos=2048*pos-len; } else len=-1; // error break; } #endif case STREAMTYPE_DS: len = demux_read_data((demux_stream_t*)s->priv,s->buffer,STREAM_BUFFER_SIZE); break; default: len=0; } if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; } s->buf_pos=0; s->buf_len=len; s->pos+=len; // printf("[%d]",len);fflush(stdout); return len; } int stream_seek_long(stream_t *s,off_t pos){ off_t newpos=0; // if(verbose>=3) printf("seek_long to 0x%X\n",(unsigned int)pos); s->buf_pos=s->buf_len=0; switch(s->type){ case STREAMTYPE_FILE: case STREAMTYPE_SMB: case STREAMTYPE_STREAM: #ifdef _LARGEFILE_SOURCE newpos=pos&(~((long long)STREAM_BUFFER_SIZE-1));break; #else newpos=pos&(~(STREAM_BUFFER_SIZE-1));break; #endif case STREAMTYPE_VCD: newpos=(pos/VCD_SECTOR_DATA)*VCD_SECTOR_DATA;break; case STREAMTYPE_VCDBINCUE: newpos=(pos/VCD_SECTOR_DATA)*VCD_SECTOR_DATA;break; case STREAMTYPE_DVD: newpos=pos/2048; newpos*=2048; break; #ifdef HAVE_CDDA case STREAMTYPE_CDDA: newpos=(pos/VCD_SECTOR_SIZE)*VCD_SECTOR_SIZE;break; #endif } if(verbose>=3){ #ifdef _LARGEFILE_SOURCE printf("s->pos=%llX newpos=%llX new_bufpos=%llX buflen=%X \n", (long long)s->pos,(long long)newpos,(long long)pos,s->buf_len); #else printf("s->pos=%X newpos=%X new_bufpos=%X buflen=%X \n", (unsigned int)s->pos,newpos,pos,s->buf_len); #endif } pos-=newpos; if(newpos==0 || newpos!=s->pos){ switch(s->type){ case STREAMTYPE_FILE: s->pos=newpos; // real seek if(lseek(s->fd,s->pos,SEEK_SET)<0) s->eof=1; break; #ifdef LIBSMBCLIENT case STREAMTYPE_SMB: s->pos=newpos; // real seek if(smbc_lseek(s->fd,s->pos,SEEK_SET)<0) s->eof=1; break; #endif #ifdef HAVE_VCD case STREAMTYPE_VCD: s->pos=newpos; // real seek vcd_set_msf(s->pos/VCD_SECTOR_DATA); break; #endif case STREAMTYPE_VCDBINCUE: s->pos=newpos; // real seek cue_set_msf(s->pos/VCD_SECTOR_DATA); break; #ifdef HAVE_CDDA case STREAMTYPE_CDDA: { s->pos=newpos; seek_cdda(s); break; } #endif #ifdef USE_DVDNAV case STREAMTYPE_DVDNAV: { if (newpos==0) { if (dvdnav_stream_reset((dvdnav_priv_t*)s->priv)) s->pos=0; } if(newpos!=s->pos){ mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek in DVDNAV streams yet!\n"); return 1; } break; } #endif #ifdef USE_DVDREAD case STREAMTYPE_DVD: s->pos=newpos; // real seek dvd_seek(s->priv,s->pos/2048); break; #endif case STREAMTYPE_STREAM: //s->pos=newpos; // real seek // Some streaming protocol allow to seek backward and forward // A function call that return -1 can tell that the protocol // doesn't support seeking. #ifdef STREAMING if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_seek ) { if( s->streaming_ctrl->streaming_seek( s->fd, pos, s->streaming_ctrl )<0 ) { mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n"); return 1; } } #else if(newpos<s->pos){ mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); return 1; } while(s->pos<newpos){ if(stream_fill_buffer(s)<=0) break; // EOF } #endif break; default: return 0; } // putchar('.');fflush(stdout); //} else { // putchar('%');fflush(stdout); } stream_fill_buffer(s); if(pos>=0 && pos<=s->buf_len){ s->buf_pos=pos; // byte position in sector return 1; } // if(pos==s->buf_len) printf("XXX Seek to last byte of file -> EOF\n"); #ifdef _LARGEFILE_SOURCE mp_msg(MSGT_STREAM,MSGL_V,"stream_seek: WARNING! Can't seek to 0x%llX !\n",(long long)(pos+newpos)); #else mp_msg(MSGT_STREAM,MSGL_V,"stream_seek: WARNING! Can't seek to 0x%X !\n",(pos+newpos)); #endif return 0; } void stream_reset(stream_t *s){ if(s->eof){ s->pos=0; //ftell(f); // s->buf_pos=s->buf_len=0; s->eof=0; } //stream_seek(s,0); } stream_t* new_memory_stream(unsigned char* data,int len){ stream_t *s=malloc(sizeof(stream_t)+len); memset(s,0,sizeof(stream_t)); s->fd=-1; s->type=STREAMTYPE_MEMORY; s->buf_pos=0; s->buf_len=len; s->start_pos=0; s->end_pos=len; stream_reset(s); s->pos=len; memcpy(s->buffer,data,len); return s; } stream_t* new_stream(int fd,int type){ stream_t *s=malloc(sizeof(stream_t)); if(s==NULL) return NULL; memset(s,0,sizeof(stream_t)); s->fd=fd; s->type=type; s->buf_pos=s->buf_len=0; s->start_pos=s->end_pos=0; s->priv=NULL; s->url=NULL; s->cache_pid=0; stream_reset(s); return s; } void free_stream(stream_t *s){ // printf("\n*** free_stream() called ***\n"); if(s->cache_pid) { // kill(s->cache_pid,SIGTERM); kill(s->cache_pid,SIGKILL); waitpid(s->cache_pid,NULL,0); shmem_free(s->cache_data); } if(s->fd>0) close(s->fd); switch(s->type) { #ifdef LIBSMBCLIENT case STREAMTYPE_SMB: smbc_close(s->fd); break; #endif #ifdef HAVE_CDDA case STREAMTYPE_CDDA: close_cdda(s); break; #endif #ifdef USE_DVDREAD case STREAMTYPE_DVD: dvd_close(s->priv); #endif } if(s->priv) free(s->priv); free(s); } stream_t* new_ds_stream(demux_stream_t *ds) { stream_t* s = new_stream(-1,STREAMTYPE_DS); s->priv = ds; return s; }