--- margi2/dvb_demux.c 2001/06/01 16:43:07 1.7 +++ margi2/dvb_demux.c 2001/10/15 12:40:28 1.8 @@ -28,8 +28,14 @@ #include "dvb_demux.h" -/* allocate no buffers, firmware buffers good enough - (and somewhere there is a memory leak ...) */ +#ifdef MODULE +MODULE_DESCRIPTION(""); +MODULE_AUTHOR("Ralph Metzler, Marcus Metzler"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +#endif + #define NOBUFS LIST_HEAD(dmx_muxs); @@ -45,7 +51,6 @@ int dmx_register_demux(dmx_demux_t *demu if (!strcmp(DMX_DIR_ENTRY(pos)->id, demux->id)) return -EEXIST; } - demux->users=0; list_add(&(demux->reg_list), head); MOD_INC_USE_COUNT; @@ -60,7 +65,7 @@ int dmx_unregister_demux(dmx_demux_t* de { if (DMX_DIR_ENTRY(pos)==demux) { - if (demux->users!=0) + if (demux->users>0) return -EINVAL; list_del(pos); MOD_DEC_USE_COUNT; @@ -388,11 +393,12 @@ DvbDmxSWFilterPackets(dvb_demux_t *dvbdm { dvb_demux_feed_t *dvbdmxfeed; + if ((dvbdmxfeed=dvbdmx->pid2feed[0x2000])) + dvbdmxfeed->cb.ts((u8 *)buf, count*188, 0, 0, + &dvbdmxfeed->feed.ts, DMX_OK); for (; count>0; count--, buf+=188) { if ((dvbdmxfeed=dvbdmx->pid2feed[ts_pid(buf)])) DvbDmxSWFilterPacketType(dvbdmxfeed, buf); - //if ((dvbdmxfeed=dvbdmx->pid2feed[0x1fff])) - // DvbDmxSWFilterPacketType(dvbdmxfeed, buf); } } @@ -444,7 +450,7 @@ DvbDmxFilterAlloc(dvb_demux_t *dvbdmx) for (i=0; ifilternum; i++) if (dvbdmx->filter[i].state==DMX_STATE_FREE) break; - if (i==dvbdmx->filternum) + if (i==dvbdmx->filternum) return 0; dvbdmx->filter[i].state=DMX_STATE_ALLOCATED; return &dvbdmx->filter[i]; @@ -475,36 +481,43 @@ dmx_ts_feed_set_type(dmx_ts_feed_t *feed dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; dvb_demux_t *dvbdmx=dvbdmxfeed->demux; + down_interruptible(&dvbdmx->mutex); dvbdmxfeed->ts_type=type; dvbdmxfeed->pes_type=pes_type; if (dvbdmxfeed->ts_type & TS_DECODER) { - if (pes_type >= DMX_TS_PES_OTHER) + if (pes_type >= DMX_TS_PES_OTHER) { + up(&dvbdmx->mutex); return -EINVAL; + } if (dvbdmx->pesfilter[pes_type] && - (dvbdmx->pesfilter[pes_type]!=dvbdmxfeed)) + (dvbdmx->pesfilter[pes_type]!=dvbdmxfeed)) { + up(&dvbdmx->mutex); return -EINVAL; + } dvbdmx->pesfilter[pes_type]=dvbdmxfeed; dvbdmx->pids[pes_type]=dvbdmxfeed->pid; } + up(&dvbdmx->mutex); return 0; } static int -dmx_pid_set(__u16 pid, dvb_demux_feed_t *dvbdmxfeed) +dmx_pid_set(u16 pid, dvb_demux_feed_t *dvbdmxfeed) { dvb_demux_t *dvbdmx=dvbdmxfeed->demux; dvb_demux_feed_t **pid2feed=dvbdmx->pid2feed; - if (pid>0x1fff) + if (pid>DMX_MAX_PID) return -EINVAL; if (dvbdmxfeed->pid!=0xffff) { - if (dvbdmxfeed->pid<=0x1fff) + if (dvbdmxfeed->pid<=DMX_MAX_PID) pid2feed[dvbdmxfeed->pid]=0; dvbdmxfeed->pid=0xffff; } - if (pid2feed[pid]) + if (pid2feed[pid]) { return -EBUSY; + } pid2feed[pid]=dvbdmxfeed; dvbdmxfeed->pid=pid; return 0; @@ -513,7 +526,7 @@ dmx_pid_set(__u16 pid, dvb_demux_feed_t static int dmx_ts_feed_set(struct dmx_ts_feed_s* feed, - __u16 pid, + u16 pid, size_t callback_length, size_t circular_buffer_size, int descramble, @@ -521,48 +534,39 @@ dmx_ts_feed_set(struct dmx_ts_feed_s* fe ) { dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; -#if 0 dvb_demux_t *dvbdmx=dvbdmxfeed->demux; - - if (pid>0x1fff) - return -EINVAL; - if (dvbdmxfeed->pid!=0xffff) { - if (dvbdmxfeed->pid<=0x1fff) - dvbdmx->pid2feed[dvbdmxfeed->pid]=0; - dvbdmxfeed->pid=0xffff; - } - if (dvbdmx->pid2feed[pid]) - return -EBUSY; - - dvbdmx->pid2feed[pid]=dvbdmxfeed; - dvbdmxfeed->pid=pid; -#else int ret; + down_interruptible(&dvbdmx->mutex); ret=dmx_pid_set(pid, dvbdmxfeed); - if (ret<0) - return ret; -#endif - + if (ret<0) { + up(&dvbdmx->mutex); + return ret; + } dvbdmxfeed->buffer_size=circular_buffer_size; dvbdmxfeed->descramble=descramble; dvbdmxfeed->timeout=timeout; dvbdmxfeed->cb_length=callback_length; dvbdmxfeed->ts_type=TS_PACKET; - if (dvbdmxfeed->descramble) + if (dvbdmxfeed->descramble) { + up(&dvbdmx->mutex); return -ENOSYS; + } if (dvbdmxfeed->buffer_size) { #ifdef NOBUFS dvbdmxfeed->buffer=0; #else dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size); - if (!dvbdmxfeed->buffer) + if (!dvbdmxfeed->buffer) { + up(&dvbdmx->mutex); return -ENOMEM; + } #endif } dvbdmxfeed->state=DMX_STATE_READY; + up(&dvbdmx->mutex); return 0; } @@ -573,18 +577,24 @@ dmx_ts_feed_start_filtering(struct dmx_t dvb_demux_t *dvbdmx=dvbdmxfeed->demux; int ret; - if (dvbdmxfeed->state!=DMX_STATE_READY) + down_interruptible(&dvbdmx->mutex); + if (dvbdmxfeed->state!=DMX_STATE_READY || + dvbdmxfeed->type!=DMX_TYPE_TS) { + up(&dvbdmx->mutex); return -EINVAL; - if (dvbdmxfeed->type!=DMX_TYPE_TS) - return -EINVAL; - - if (!dvbdmx->start_feed) + } + if (!dvbdmx->start_feed) { + up(&dvbdmx->mutex); return -1; + } ret=dvbdmx->start_feed(dvbdmxfeed); - if (ret<0) - return ret; + if (ret<0) { + up(&dvbdmx->mutex); + return ret; + } feed->is_filtering=1; dvbdmxfeed->state=DMX_STATE_GO; + up(&dvbdmx->mutex); return 0; } @@ -595,15 +605,20 @@ dmx_ts_feed_stop_filtering(struct dmx_ts dvb_demux_t *dvbdmx=dvbdmxfeed->demux; int ret; - //printk ("function : %s\n", __FUNCTION__); - if (dvbdmxfeed->statemutex); + if (dvbdmxfeed->statemutex); return -EINVAL; - if (!dvbdmx->stop_feed) + } + if (!dvbdmx->stop_feed) { + up(&dvbdmx->mutex); return -1; + } ret=dvbdmx->stop_feed(dvbdmxfeed); feed->is_filtering=0; dvbdmxfeed->state=DMX_STATE_ALLOCATED; + up(&dvbdmx->mutex); return ret; } @@ -614,14 +629,17 @@ static int dvbdmx_allocate_ts_feed(dmx_d dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; dvb_demux_feed_t *dvbdmxfeed; - if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) + down_interruptible(&dvbdmx->mutex); + if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) { + up(&dvbdmx->mutex); return -EBUSY; - + } dvbdmxfeed->type=DMX_TYPE_TS; dvbdmxfeed->cb.ts=callback; dvbdmxfeed->demux=dvbdmx; dvbdmxfeed->pid=0xffff; dvbdmxfeed->peslen=0xfffa; + dvbdmxfeed->buffer=0; (*feed)=&dvbdmxfeed->feed.ts; (*feed)->is_filtering=0; @@ -635,6 +653,7 @@ static int dvbdmx_allocate_ts_feed(dmx_d if (!(dvbdmxfeed->filter=DvbDmxFilterAlloc(dvbdmx))) { dvbdmxfeed->state=DMX_STATE_FREE; + up(&dvbdmx->mutex); return -EBUSY; } @@ -642,27 +661,35 @@ static int dvbdmx_allocate_ts_feed(dmx_d dvbdmxfeed->filter->feed=dvbdmxfeed; dvbdmxfeed->filter->state=DMX_STATE_READY; + up(&dvbdmx->mutex); return 0; } static int dvbdmx_release_ts_feed(dmx_demux_t *demux, dmx_ts_feed_t *feed) { + dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; - if (dvbdmxfeed->state==DMX_STATE_FREE) + down_interruptible(&dvbdmx->mutex); + if (dvbdmxfeed->state==DMX_STATE_FREE) { + up(&dvbdmx->mutex); return -EINVAL; + } +#ifndef NOBUFS if (dvbdmxfeed->buffer) { vfree(dvbdmxfeed->buffer); dvbdmxfeed->buffer=0; } +#endif dvbdmxfeed->state=DMX_STATE_FREE; dvbdmxfeed->filter->state=DMX_STATE_FREE; if (dvbdmxfeed->pid!=0xffff) { - if (dvbdmxfeed->pid<=0x1fff) + if (dvbdmxfeed->pid<=DMX_MAX_PID) dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; dvbdmxfeed->pid=0xffff; } + up(&dvbdmx->mutex); return 0; } @@ -673,7 +700,7 @@ static int dvbdmx_release_ts_feed(dmx_de /* static int dmx_pes_feed_set(struct dmx_pes_feed_s* feed, - __u16 pid, + u16 pid, size_t circular_buffer_size, int descramble, struct timespec timeout) @@ -720,10 +747,12 @@ dmx_section_feed_allocate_filter(struct dvb_demux_t *dvbdemux=dvbdmxfeed->demux; dvb_demux_filter_t *dvbdmxfilter; + down_interruptible(&dvbdemux->mutex); dvbdmxfilter=DvbDmxFilterAlloc(dvbdemux); - if (!dvbdmxfilter) + if (!dvbdmxfilter) { + up(&dvbdemux->mutex); return -ENOSPC; - + } *filter=&dvbdmxfilter->filter; (*filter)->parent=feed; (*filter)->priv=0; @@ -734,12 +763,13 @@ dmx_section_feed_allocate_filter(struct dvbdmxfilter->next=dvbdmxfeed->filter; dvbdmxfeed->filter=dvbdmxfilter; + up(&dvbdemux->mutex); return 0; } static int dmx_section_feed_set(struct dmx_section_feed_s* feed, - __u16 pid, size_t circular_buffer_size, + u16 pid, size_t circular_buffer_size, int descramble, int check_crc) { dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; @@ -747,29 +777,37 @@ dmx_section_feed_set(struct dmx_section_ if (pid>0x1fff) return -EINVAL; + down_interruptible(&dvbdmx->mutex); if (dvbdmxfeed->pid!=0xffff) { dvbdmx->pid2feed[dvbdmxfeed->pid]=0; dvbdmxfeed->pid=0xffff; } - if (dvbdmx->pid2feed[pid]) - return -EBUSY; + if (dvbdmx->pid2feed[pid]) { + up(&dvbdmx->mutex); + return -EBUSY; + } dvbdmx->pid2feed[pid]=dvbdmxfeed; dvbdmxfeed->pid=pid; dvbdmxfeed->buffer_size=circular_buffer_size; dvbdmxfeed->descramble=descramble; - if (dvbdmxfeed->descramble) + if (dvbdmxfeed->descramble) { + up(&dvbdmx->mutex); return -ENOSYS; + } dvbdmxfeed->check_crc=check_crc; #ifdef NOBUFS dvbdmxfeed->buffer=0; #else dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size); - if (!dvbdmxfeed->buffer) + if (!dvbdmxfeed->buffer) { + up(&dvbdmx->mutex); return -ENOMEM; + } #endif dvbdmxfeed->state=DMX_STATE_READY; + up(&dvbdmx->mutex); return 0; } @@ -780,21 +818,30 @@ dmx_section_feed_start_filtering(dmx_sec dvb_demux_t *dvbdmx=dvbdmxfeed->demux; int ret; - if (feed->is_filtering) - return -EBUSY; - if (!dvbdmxfeed->filter) + down_interruptible(&dvbdmx->mutex); + if (feed->is_filtering) { + up(&dvbdmx->mutex); + return -EBUSY; + } + if (!dvbdmxfeed->filter) { + up(&dvbdmx->mutex); return -EINVAL; - + } dvbdmxfeed->secbufp=0; dvbdmxfeed->seclen=0; - if (!dvbdmx->start_feed) + if (!dvbdmx->start_feed) { + up(&dvbdmx->mutex); return -1; + } ret=dvbdmx->start_feed(dvbdmxfeed); - if (ret<0) - return ret; + if (ret<0) { + up(&dvbdmx->mutex); + return ret; + } feed->is_filtering=1; dvbdmxfeed->state=DMX_STATE_GO; + up(&dvbdmx->mutex); return 0; } @@ -805,12 +852,16 @@ dmx_section_feed_stop_filtering(struct d dvb_demux_t *dvbdmx=dvbdmxfeed->demux; int ret; - if (!dvbdmx->stop_feed) + down_interruptible(&dvbdmx->mutex); + if (!dvbdmx->stop_feed) { + up(&dvbdmx->mutex); return -1; + } ret=dvbdmx->stop_feed(dvbdmxfeed); dvbdmxfeed->state=DMX_STATE_READY; feed->is_filtering=0; + up(&dvbdmx->mutex); return ret; } @@ -820,13 +871,16 @@ dmx_section_feed_release_filter(dmx_sect { dvb_demux_filter_t *dvbdmxfilter=(dvb_demux_filter_t *) filter, *f; dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=dvbdmxfeed->demux; - if (dvbdmxfilter->feed!=dvbdmxfeed) + down_interruptible(&dvbdmx->mutex); + if (dvbdmxfilter->feed!=dvbdmxfeed) { + up(&dvbdmx->mutex); return -EINVAL; + } if (feed->is_filtering) feed->stop_filtering(feed); - //return -EBUSY; - + f=dvbdmxfeed->filter; if (f==dvbdmxfilter) dvbdmxfeed->filter=dvbdmxfilter->next; @@ -837,6 +891,7 @@ dmx_section_feed_release_filter(dmx_sect } dvbdmxfilter->state=DMX_STATE_FREE; + up(&dvbdmx->mutex); return 0; } @@ -847,14 +902,18 @@ static int dvbdmx_allocate_section_feed( dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; dvb_demux_feed_t *dvbdmxfeed; - if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) + down_interruptible(&dvbdmx->mutex); + if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) { + up(&dvbdmx->mutex); return -EBUSY; + } dvbdmxfeed->type=DMX_TYPE_SEC; dvbdmxfeed->cb.sec=callback; dvbdmxfeed->demux=dvbdmx; dvbdmxfeed->pid=0xffff; dvbdmxfeed->secbufp=0; dvbdmxfeed->filter=0; + dvbdmxfeed->buffer=0; (*feed)=&dvbdmxfeed->feed.sec; (*feed)->is_filtering=0; @@ -865,6 +924,8 @@ static int dvbdmx_allocate_section_feed( (*feed)->release_filter=dmx_section_feed_release_filter; (*feed)->start_filtering=dmx_section_feed_start_filtering; (*feed)->stop_filtering=dmx_section_feed_stop_filtering; + + up(&dvbdmx->mutex); return 0; } @@ -872,17 +933,24 @@ static int dvbdmx_release_section_feed(d dmx_section_feed_t *feed) { dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed; + dvb_demux_t *dvbdmx=(dvb_demux_t *) demux; - if (dvbdmxfeed->state==DMX_STATE_FREE) + down_interruptible(&dvbdmx->mutex); + if (dvbdmxfeed->state==DMX_STATE_FREE) { + up(&dvbdmx->mutex); return -EINVAL; + } +#ifndef NOBUFS if (dvbdmxfeed->buffer) { vfree(dvbdmxfeed->buffer); dvbdmxfeed->buffer=0; } +#endif dvbdmxfeed->state=DMX_STATE_FREE; dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; if (dvbdmxfeed->pid!=0xffff) dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; + up(&dvbdmx->mutex); return 0; } @@ -976,24 +1044,32 @@ dvbdmx_get_frontends(dmx_demux_t *demux) static int dvbdmx_connect_frontend(dmx_demux_t *demux, dmx_frontend_t *frontend) { + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + if (demux->frontend) return -EINVAL; + down_interruptible(&dvbdemux->mutex); demux->frontend=frontend; + up(&dvbdemux->mutex); return 0; } static int dvbdmx_disconnect_frontend(dmx_demux_t *demux) { + dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; + + down_interruptible(&dvbdemux->mutex); demux->frontend=NULL; + up(&dvbdemux->mutex); return 0; } -static int dvbdmx_get_pes_pids(dmx_demux_t *demux, __u16 *pids) +static int dvbdmx_get_pes_pids(dmx_demux_t *demux, u16 *pids) { dvb_demux_t *dvbdemux=(dvb_demux_t *) demux; - memcpy(pids, dvbdemux->pids, 5*sizeof(__u16)); + memcpy(pids, dvbdemux->pids, 5*sizeof(u16)); return 0; } @@ -1027,7 +1103,7 @@ DvbDmxInit(dvb_demux_t *dvbdemux) dvbdemux->pids[i]=0xffff; } dvbdemux->playing=dvbdemux->recording=0; - memset(dvbdemux->pid2feed, 0, 0x2000*sizeof(dvb_demux_feed_t *)); + memset(dvbdemux->pid2feed, 0, (DMX_MAX_PID+1)*sizeof(dvb_demux_feed_t *)); dvbdemux->tsbufp=0; dmx->frontend=0; @@ -1053,11 +1129,11 @@ DvbDmxInit(dvb_demux_t *dvbdemux) dmx->connect_frontend=dvbdmx_connect_frontend; dmx->disconnect_frontend=dvbdmx_disconnect_frontend; dmx->get_pes_pids=dvbdmx_get_pes_pids; + sema_init(&dvbdemux->mutex, 1); if (dmx_register_demux(dmx)<0) return -1; - sema_init(&dvbdemux->mutex, 1); return 0; }