⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb_demux.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			return -EINVAL;		}		demux->pesfilter[pes_type] = feed;		demux->pids[pes_type] = pid;	}	dvb_demux_feed_add(feed);	feed->pid = pid;	feed->buffer_size = circular_buffer_size;	feed->descramble = descramble;	feed->timeout = timeout;	feed->cb_length = callback_length;	feed->ts_type = ts_type;	feed->pes_type = pes_type;	if (feed->descramble) {		up(&demux->mutex);		return -ENOSYS;	}	if (feed->buffer_size) {#ifdef NOBUFS		feed->buffer=NULL;#else		feed->buffer = vmalloc(feed->buffer_size);		if (!feed->buffer) {			up(&demux->mutex);			return -ENOMEM;		}#endif	}		feed->state = DMX_STATE_READY;	up(&demux->mutex);	return 0;}static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed){	struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;	struct dvb_demux *demux = feed->demux;	int ret;	if (down_interruptible (&demux->mutex))		return -ERESTARTSYS;	if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {		up(&demux->mutex);		return -EINVAL;	}	if (!demux->start_feed) {		up(&demux->mutex);		return -ENODEV;	}	if ((ret = demux->start_feed(feed)) < 0) {		up(&demux->mutex);		return ret;	}	spin_lock_irq(&demux->lock);	ts_feed->is_filtering = 1;	feed->state = DMX_STATE_GO;	spin_unlock_irq(&demux->lock);	up(&demux->mutex);	return 0;} static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed){	struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;	struct dvb_demux *demux = feed->demux;	int ret;	if (down_interruptible (&demux->mutex))		return -ERESTARTSYS;	if (feed->state<DMX_STATE_GO) {		up(&demux->mutex);		return -EINVAL;	}	if (!demux->stop_feed) {		up(&demux->mutex);		return -ENODEV;	}	ret = demux->stop_feed(feed); 	spin_lock_irq(&demux->lock);	ts_feed->is_filtering = 0;	feed->state = DMX_STATE_ALLOCATED;	spin_unlock_irq(&demux->lock);	up(&demux->mutex);	return ret;}static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed, 			     dmx_ts_cb callback){	struct dvb_demux *demux = (struct dvb_demux *) dmx;	struct dvb_demux_feed *feed;	if (down_interruptible (&demux->mutex))		return -ERESTARTSYS;	if (!(feed = dvb_dmx_feed_alloc(demux))) {		up(&demux->mutex);		return -EBUSY;	}	feed->type = DMX_TYPE_TS;	feed->cb.ts = callback;	feed->demux = demux;	feed->pid = 0xffff;	feed->peslen = 0xfffa;	feed->buffer = NULL;	(*ts_feed) = &feed->feed.ts;	(*ts_feed)->parent = dmx;	(*ts_feed)->priv = NULL;	(*ts_feed)->is_filtering = 0;	(*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;	(*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;	(*ts_feed)->set = dmx_ts_feed_set;	if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {		feed->state = DMX_STATE_FREE;		up(&demux->mutex);		return -EBUSY;	}	feed->filter->type = DMX_TYPE_TS;	feed->filter->feed = feed;	feed->filter->state = DMX_STATE_READY;		up(&demux->mutex);	return 0;}static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed){	struct dvb_demux *demux = (struct dvb_demux *) dmx;	struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;	if (down_interruptible (&demux->mutex))		return -ERESTARTSYS;	if (feed->state == DMX_STATE_FREE) {		up(&demux->mutex);		return -EINVAL;	}#ifndef NOBUFS		vfree(feed->buffer);		feed->buffer=0;#endif	feed->state = DMX_STATE_FREE;	feed->filter->state = DMX_STATE_FREE;	dvb_demux_feed_del(feed);		feed->pid = 0xffff;		if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)		demux->pesfilter[feed->pes_type] = NULL;	up(&demux->mutex);	return 0;}/****************************************************************************** * dmx_section_feed API calls ******************************************************************************/static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed, 				     struct dmx_section_filter** filter) {	struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;	struct dvb_demux *dvbdemux=dvbdmxfeed->demux;	struct dvb_demux_filter *dvbdmxfilter;	if (down_interruptible (&dvbdemux->mutex))		return -ERESTARTSYS;	dvbdmxfilter=dvb_dmx_filter_alloc(dvbdemux);	if (!dvbdmxfilter) {		up(&dvbdemux->mutex);		return -EBUSY;	}	spin_lock_irq(&dvbdemux->lock);	*filter=&dvbdmxfilter->filter;	(*filter)->parent=feed;	(*filter)->priv=NULL;	dvbdmxfilter->feed=dvbdmxfeed;	dvbdmxfilter->type=DMX_TYPE_SEC;	dvbdmxfilter->state=DMX_STATE_READY;	dvbdmxfilter->next=dvbdmxfeed->filter;	dvbdmxfeed->filter=dvbdmxfilter;	spin_unlock_irq(&dvbdemux->lock);	up(&dvbdemux->mutex);	return 0;}static int dmx_section_feed_set(struct dmx_section_feed* feed, 		     u16 pid, size_t circular_buffer_size, 		     int descramble, int check_crc) {	struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;	struct dvb_demux *dvbdmx=dvbdmxfeed->demux;	if (pid>0x1fff)		return -EINVAL;	if (down_interruptible (&dvbdmx->mutex))		return -ERESTARTSYS;		dvb_demux_feed_add(dvbdmxfeed);	dvbdmxfeed->pid = pid;	dvbdmxfeed->buffer_size=circular_buffer_size;	dvbdmxfeed->descramble=descramble;	if (dvbdmxfeed->descramble) {		up(&dvbdmx->mutex);		return -ENOSYS;	}	dvbdmxfeed->feed.sec.check_crc=check_crc;#ifdef NOBUFS	dvbdmxfeed->buffer=NULL;#else	dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);	if (!dvbdmxfeed->buffer) {		up(&dvbdmx->mutex);		return -ENOMEM;	}#endif	dvbdmxfeed->state=DMX_STATE_READY;	up(&dvbdmx->mutex);	return 0;}static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed){	int i;	struct dvb_demux_filter *f;	struct dmx_section_filter *sf;	u8 mask, mode, doneq;			if (!(f=dvbdmxfeed->filter))		return;	do {		sf=&f->filter;		doneq=0;		for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {			mode=sf->filter_mode[i];			mask=sf->filter_mask[i];			f->maskandmode[i]=mask&mode;			doneq|=f->maskandnotmode[i]=mask&~mode;		}		f->doneq=doneq ? 1 : 0;	} while ((f=f->next));}static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed){	struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;	struct dvb_demux *dvbdmx=dvbdmxfeed->demux;	int ret;	if (down_interruptible (&dvbdmx->mutex))		return -ERESTARTSYS;		if (feed->is_filtering) {		up(&dvbdmx->mutex);		return -EBUSY;	}	if (!dvbdmxfeed->filter) {		up(&dvbdmx->mutex);		return -EINVAL;	}	dvbdmxfeed->feed.sec.tsfeedp = 0;	dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;	dvbdmxfeed->feed.sec.secbufp=0;	dvbdmxfeed->feed.sec.seclen=0;		if (!dvbdmx->start_feed) {		up(&dvbdmx->mutex);		return -ENODEV;	}	prepare_secfilters(dvbdmxfeed);	if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {		up(&dvbdmx->mutex);		return ret;	}	spin_lock_irq(&dvbdmx->lock);	feed->is_filtering=1;	dvbdmxfeed->state=DMX_STATE_GO;	spin_unlock_irq(&dvbdmx->lock);	up(&dvbdmx->mutex);	return 0;}static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed){	struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;	struct dvb_demux *dvbdmx=dvbdmxfeed->demux;	int ret;	if (down_interruptible (&dvbdmx->mutex))		return -ERESTARTSYS;	if (!dvbdmx->stop_feed) {		up(&dvbdmx->mutex);		return -ENODEV;	}	ret=dvbdmx->stop_feed(dvbdmxfeed); 	spin_lock_irq(&dvbdmx->lock);	dvbdmxfeed->state=DMX_STATE_READY;	feed->is_filtering=0;	spin_unlock_irq(&dvbdmx->lock);	up(&dvbdmx->mutex);	return ret;}static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, 				struct dmx_section_filter* filter){	struct dvb_demux_filter *dvbdmxfilter=(struct dvb_demux_filter *) filter, *f;	struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;	struct dvb_demux *dvbdmx=dvbdmxfeed->demux;	if (down_interruptible (&dvbdmx->mutex))		return -ERESTARTSYS;	if (dvbdmxfilter->feed!=dvbdmxfeed) {		up(&dvbdmx->mutex);		return -EINVAL;	}	if (feed->is_filtering) 		feed->stop_filtering(feed);		spin_lock_irq(&dvbdmx->lock);	f=dvbdmxfeed->filter;	if (f == dvbdmxfilter) {		dvbdmxfeed->filter=dvbdmxfilter->next;	} else {		while(f->next!=dvbdmxfilter)			f=f->next;		f->next=f->next->next;	}	dvbdmxfilter->state=DMX_STATE_FREE;	spin_unlock_irq(&dvbdmx->lock);	up(&dvbdmx->mutex);	return 0;}static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, 					struct dmx_section_feed **feed,					dmx_section_cb callback){	struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;	struct dvb_demux_feed *dvbdmxfeed;	if (down_interruptible (&dvbdmx->mutex))		return -ERESTARTSYS;	if (!(dvbdmxfeed=dvb_dmx_feed_alloc(dvbdmx))) {		up(&dvbdmx->mutex);		return -EBUSY;	}	dvbdmxfeed->type=DMX_TYPE_SEC;	dvbdmxfeed->cb.sec=callback;	dvbdmxfeed->demux=dvbdmx;	dvbdmxfeed->pid=0xffff;	dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;	dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;	dvbdmxfeed->feed.sec.tsfeedp = 0;	dvbdmxfeed->filter=NULL;	dvbdmxfeed->buffer=NULL;	(*feed)=&dvbdmxfeed->feed.sec;	(*feed)->is_filtering=0;	(*feed)->parent=demux;	(*feed)->priv=NULL;	(*feed)->set=dmx_section_feed_set;	(*feed)->allocate_filter=dmx_section_feed_allocate_filter;	(*feed)->start_filtering=dmx_section_feed_start_filtering;	(*feed)->stop_filtering=dmx_section_feed_stop_filtering;	(*feed)->release_filter = dmx_section_feed_release_filter;	up(&dvbdmx->mutex);	return 0;}static int dvbdmx_release_section_feed(struct dmx_demux *demux, 				       struct dmx_section_feed *feed){	struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;	struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;	if (down_interruptible (&dvbdmx->mutex))		return -ERESTARTSYS;	if (dvbdmxfeed->state==DMX_STATE_FREE) {		up(&dvbdmx->mutex);		return -EINVAL;	}#ifndef NOBUFS		vfree(dvbdmxfeed->buffer);		dvbdmxfeed->buffer=0;#endif	dvbdmxfeed->state=DMX_STATE_FREE;	dvb_demux_feed_del(dvbdmxfeed);		dvbdmxfeed->pid = 0xffff;	up(&dvbdmx->mutex);	return 0;}/****************************************************************************** * dvb_demux kernel data API calls ******************************************************************************/static int dvbdmx_open(struct dmx_demux *demux){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	if (dvbdemux->users>=MAX_DVB_DEMUX_USERS)		return -EUSERS;	dvbdemux->users++;	return 0;}static int dvbdmx_close(struct dmx_demux *demux){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	if (dvbdemux->users==0)		return -ENODEV;	dvbdemux->users--;	//FIXME: release any unneeded resources if users==0	return 0;}static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))		return -EINVAL;	if (down_interruptible (&dvbdemux->mutex))		return -ERESTARTSYS;	dvb_dmx_swfilter(dvbdemux, buf, count);	up(&dvbdemux->mutex);	if (signal_pending(current))		return -EINTR;	return count;}static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	struct list_head *head = &dvbdemux->frontend_list;	list_add(&(frontend->connectivity_list), head);	return 0;}static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	struct list_head *pos, *n, *head=&dvbdemux->frontend_list;	list_for_each_safe (pos, n, head) {		if (DMX_FE_ENTRY(pos) == frontend) {			list_del(pos);			return 0;		}	}	return -ENODEV;}static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	if (list_empty(&dvbdemux->frontend_list))		return NULL;	return &dvbdemux->frontend_list;}int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	if (demux->frontend)		return -EINVAL;		if (down_interruptible (&dvbdemux->mutex))		return -ERESTARTSYS;	demux->frontend=frontend;	up(&dvbdemux->mutex);	return 0;}EXPORT_SYMBOL(dvbdmx_connect_frontend);int dvbdmx_disconnect_frontend(struct dmx_demux *demux){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	if (down_interruptible (&dvbdemux->mutex))		return -ERESTARTSYS;	demux->frontend=NULL;	up(&dvbdemux->mutex);	return 0;}EXPORT_SYMBOL(dvbdmx_disconnect_frontend);static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids){	struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;	memcpy(pids, dvbdemux->pids, 5*sizeof(u16));	return 0;}int dvb_dmx_init(struct dvb_demux *dvbdemux){	int i, err;	struct dmx_demux *dmx = &dvbdemux->dmx;	dvbdemux->users=0;	dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));	if (!dvbdemux->filter)		return -ENOMEM;	dvbdemux->feed=vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));	if (!dvbdemux->feed) {		vfree(dvbdemux->filter);		return -ENOMEM;	}	for (i=0; i<dvbdemux->filternum; i++) {		dvbdemux->filter[i].state=DMX_STATE_FREE;		dvbdemux->filter[i].index=i;	}	for (i=0; i<dvbdemux->feednum; i++)		dvbdemux->feed[i].state=DMX_STATE_FREE;	dvbdemux->frontend_list.next=	  dvbdemux->frontend_list.prev=	    &dvbdemux->frontend_list;	for (i=0; i<DMX_TS_PES_OTHER; i++) {		dvbdemux->pesfilter[i]=NULL;		dvbdemux->pids[i]=0xffff;	}	INIT_LIST_HEAD(&dvbdemux->feed_list);	dvbdemux->playing = 0;	dvbdemux->recording = 0;	dvbdemux->tsbufp=0;	if (!dvbdemux->check_crc32)		dvbdemux->check_crc32 = dvb_dmx_crc32;	 if (!dvbdemux->memcopy)		 dvbdemux->memcopy = dvb_dmx_memcopy;	dmx->frontend=NULL;	dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list;	dmx->priv=(void *) dvbdemux;	dmx->open=dvbdmx_open;	dmx->close=dvbdmx_close;	dmx->write=dvbdmx_write;	dmx->allocate_ts_feed=dvbdmx_allocate_ts_feed;	dmx->release_ts_feed=dvbdmx_release_ts_feed;	dmx->allocate_section_feed=dvbdmx_allocate_section_feed;	dmx->release_section_feed=dvbdmx_release_section_feed;	dmx->descramble_mac_address=NULL;	dmx->descramble_section_payload=NULL;		dmx->add_frontend=dvbdmx_add_frontend;	dmx->remove_frontend=dvbdmx_remove_frontend;	dmx->get_frontends=dvbdmx_get_frontends;	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);	spin_lock_init(&dvbdemux->lock);	if ((err = dmx_register_demux(dmx)) < 0) 		return err;	return 0;}EXPORT_SYMBOL(dvb_dmx_init);int dvb_dmx_release(struct dvb_demux *dvbdemux){	struct dmx_demux *dmx = &dvbdemux->dmx;	dmx_unregister_demux(dmx);		vfree(dvbdemux->filter);		vfree(dvbdemux->feed);	return 0;}EXPORT_SYMBOL(dvb_dmx_release);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -