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

📄 dvb_demux.c

📁 linux环境下的dvb驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 = 0;	(*ts_feed) = &feed->feed.ts;	(*ts_feed)->parent = dmx;	(*ts_feed)->priv = 0;	(*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	if (feed->buffer) { 		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)		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 = 0;	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 = 0;#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 = 0;	dvbdmxfeed->buffer = 0;	(*feed)=&dvbdmxfeed->feed.sec;	(*feed)->is_filtering = 0;	(*feed)->parent = demux;	(*feed)->priv = 0;	(*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	if (dvbdmxfeed->buffer) {		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;}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;}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 = 0;	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;}int dvb_dmx_release(struct dvb_demux *dvbdemux){	struct dmx_demux *dmx = &dvbdemux->dmx;	dmx_unregister_demux(dmx);	if (dvbdemux->filter)		vfree(dvbdemux->filter);	if (dvbdemux->feed)		vfree(dvbdemux->feed);	return 0;}

⌨️ 快捷键说明

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