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

📄 vino.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 5 页
字号:
		dprintk("vino_queue_free_with_count(): freeing buffer %d\n",			i);		vino_free_buffer(q->buffer[i]);		kfree(q->buffer[i]);	}	q->type = VINO_MEMORY_NONE;	q->magic = 0;}static void vino_queue_free(struct vino_framebuffer_queue *q){	dprintk("vino_queue_free():\n");	if (q->magic != VINO_QUEUE_MAGIC)		return;	if (q->type != VINO_MEMORY_MMAP)		return;	mutex_lock(&q->queue_mutex);	vino_queue_free_with_count(q, q->length);	mutex_unlock(&q->queue_mutex);}static int vino_queue_init(struct vino_framebuffer_queue *q,			   unsigned int *length){	unsigned int i;	int ret = 0;	dprintk("vino_queue_init(): length = %d\n", *length);	if (q->magic == VINO_QUEUE_MAGIC) {		dprintk("vino_queue_init(): queue already initialized!\n");		return -EINVAL;	}	if (q->type != VINO_MEMORY_NONE) {		dprintk("vino_queue_init(): queue already initialized!\n");		return -EINVAL;	}	if (*length < 1)		return -EINVAL;	mutex_lock(&q->queue_mutex);	if (*length > VINO_FRAMEBUFFER_COUNT_MAX)		*length = VINO_FRAMEBUFFER_COUNT_MAX;	q->length = 0;	for (i = 0; i < *length; i++) {		dprintk("vino_queue_init(): allocating buffer %d\n", i);		q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),				       GFP_KERNEL);		if (!q->buffer[i]) {			dprintk("vino_queue_init(): kmalloc() failed\n");			ret = -ENOMEM;			break;		}		ret = vino_allocate_buffer(q->buffer[i],					   VINO_FRAMEBUFFER_SIZE);		if (ret) {			kfree(q->buffer[i]);			dprintk("vino_queue_init(): "				"vino_allocate_buffer() failed\n");			break;		}		q->buffer[i]->id = i;		if (i > 0) {			q->buffer[i]->offset = q->buffer[i - 1]->offset +				q->buffer[i - 1]->size;		} else {			q->buffer[i]->offset = 0;		}		spin_lock_init(&q->buffer[i]->state_lock);		dprintk("vino_queue_init(): buffer = %d, offset = %d, "			"size = %d\n", i, q->buffer[i]->offset,			q->buffer[i]->size);	}	if (ret) {		vino_queue_free_with_count(q, i);		*length = 0;	} else {		q->length = *length;		vino_fifo_init(&q->in, q->length);		vino_fifo_init(&q->out, q->length);		q->type = VINO_MEMORY_MMAP;		q->magic = VINO_QUEUE_MAGIC;	}	mutex_unlock(&q->queue_mutex);	return ret;}static struct vino_framebuffer *vino_queue_add(struct					       vino_framebuffer_queue *q,					       unsigned int id){	struct vino_framebuffer *ret = NULL;	unsigned int total;	unsigned long flags;	dprintk("vino_queue_add(): id = %d\n", id);	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	if (id >= q->length)		goto out;	/* not needed?: if (vino_fifo_full(&q->out)) {		goto out;		}*/	/* check that outgoing queue isn't already full	 * (or that it won't become full) */	total = vino_fifo_get_used(&q->in) +		vino_fifo_get_used(&q->out);	if (total >= q->length)		goto out;	if (vino_fifo_enqueue(&q->in, id))		goto out;	ret = q->buffer[id];out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}static struct vino_framebuffer *vino_queue_transfer(struct						    vino_framebuffer_queue *q){	struct vino_framebuffer *ret = NULL;	struct vino_framebuffer *fb;	int id;	unsigned long flags;	dprintk("vino_queue_transfer():\n");	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	// now this actually removes an entry from the incoming queue	if (vino_fifo_dequeue(&q->in, &id)) {		goto out;	}	dprintk("vino_queue_transfer(): id = %d\n", id);	fb = q->buffer[id];	// we have already checked that the outgoing queue is not full, but...	if (vino_fifo_enqueue(&q->out, id)) {		printk(KERN_ERR "vino_queue_transfer(): "		       "outgoing queue is full, this shouldn't happen!\n");		goto out;	}	ret = fb;out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}/* returns true/false */static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,					unsigned int id){	int ret = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	ret = vino_fifo_has_id(&q->in, id);out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}/* returns true/false */static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,					unsigned int id){	int ret = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	ret = vino_fifo_has_id(&q->out, id);out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,				   unsigned int *used){	int ret = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return VINO_QUEUE_ERROR;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0) {		ret = VINO_QUEUE_ERROR;		goto out;	}	*used = vino_fifo_get_used(&q->in);out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,				   unsigned int *used){	int ret = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return VINO_QUEUE_ERROR;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0) {		ret = VINO_QUEUE_ERROR;		goto out;	}	*used = vino_fifo_get_used(&q->out);out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}#if 0 /* keep */;static int vino_queue_get_total(struct vino_framebuffer_queue *q,				unsigned int *total){	int ret = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return VINO_QUEUE_ERROR;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0) {		ret = VINO_QUEUE_ERROR;		goto out;	}	*total = vino_fifo_get_used(&q->in) +		vino_fifo_get_used(&q->out);out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}#endifstatic struct vino_framebuffer *vino_queue_peek(struct						vino_framebuffer_queue *q,						unsigned int *id){	struct vino_framebuffer *ret = NULL;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	if (vino_fifo_peek(&q->in, id)) {		goto out;	}	ret = q->buffer[*id];out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}static struct vino_framebuffer *vino_queue_remove(struct						  vino_framebuffer_queue *q,						  unsigned int *id){	struct vino_framebuffer *ret = NULL;	unsigned long flags;	dprintk("vino_queue_remove():\n");	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	if (vino_fifo_dequeue(&q->out, id)) {		goto out;	}	dprintk("vino_queue_remove(): id = %d\n", *id);	ret = q->buffer[*id];out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}static structvino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,					unsigned int id){	struct vino_framebuffer *ret = NULL;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	if (q->length == 0)		goto out;	if (id >= q->length)		goto out;	ret = q->buffer[id]; out:	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q){	unsigned int length = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return length;	}	spin_lock_irqsave(&q->queue_lock, flags);	length = q->length;	spin_unlock_irqrestore(&q->queue_lock, flags);	return length;}static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q){	unsigned int i;	int ret = 0;	unsigned long flags;	if (q->magic != VINO_QUEUE_MAGIC) {		return ret;	}	spin_lock_irqsave(&q->queue_lock, flags);	for (i = 0; i < q->length; i++) {		if (q->buffer[i]->map_count > 0) {			ret = 1;			break;		}	}	spin_unlock_irqrestore(&q->queue_lock, flags);	return ret;}/* VINO functions *//* execute with input_lock locked */static void vino_update_line_size(struct vino_channel_settings *vcs){	unsigned int w = vcs->clipping.right - vcs->clipping.left;	unsigned int d = vcs->decimation;	unsigned int bpp = vino_data_formats[vcs->data_format].bpp;	unsigned int lsize;	dprintk("update_line_size(): before: w = %d, d = %d, "		"line_size = %d\n", w, d, vcs->line_size);	/* line size must be multiple of 8 bytes */	lsize = (bpp * (w / d)) & ~7;	w = (lsize / bpp) * d;	vcs->clipping.right = vcs->clipping.left + w;	vcs->line_size = lsize;	dprintk("update_line_size(): after: w = %d, d = %d, "		"line_size = %d\n", w, d, vcs->line_size);}/* execute with input_lock locked */static void vino_set_clipping(struct vino_channel_settings *vcs,			      unsigned int x, unsigned int y,			      unsigned int w, unsigned int h){	unsigned int maxwidth, maxheight;	unsigned int d;	maxwidth = vino_data_norms[vcs->data_norm].width;	maxheight = vino_data_norms[vcs->data_norm].height;	d = vcs->decimation;	y &= ~1;	/* odd/even fields */	if (x > maxwidth) {		x = 0;	}	if (y > maxheight) {		y = 0;	}	if (((w / d) < VINO_MIN_WIDTH)	    || ((h / d) < VINO_MIN_HEIGHT)) {		w = VINO_MIN_WIDTH * d;		h = VINO_MIN_HEIGHT * d;	}	if ((x + w) > maxwidth) {		w = maxwidth - x;		if ((w / d) < VINO_MIN_WIDTH)			x = maxwidth - VINO_MIN_WIDTH * d;	}	if ((y + h) > maxheight) {		h = maxheight - y;		if ((h / d) < VINO_MIN_HEIGHT)			y = maxheight - VINO_MIN_HEIGHT * d;	}	vcs->clipping.left = x;	vcs->clipping.top = y;	vcs->clipping.right = x + w;	vcs->clipping.bottom = y + h;	vino_update_line_size(vcs);	dprintk("clipping %d, %d, %d, %d / %d - %d\n",		vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,		vcs->clipping.bottom, vcs->decimation, vcs->line_size);}/* execute with input_lock locked */static inline void vino_set_default_clipping(struct vino_channel_settings *vcs){	vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,			  vino_data_norms[vcs->data_norm].height);}/* execute with input_lock locked */static void vino_set_scaling(struct vino_channel_settings *vcs,			     unsigned int w, unsigned int h){	unsigned int x, y, curw, curh, d;	x = vcs->clipping.left;	y = vcs->clipping.top;	curw = vcs->clipping.right - vcs->clipping.left;	curh = vcs->clipping.bottom - vcs->clipping.top;	d = max(curw / w, curh / h);	dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",		w, h, curw, curh, d);	if (d < 1) {		d = 1;	} else if (d > 8) {		d = 8;	}	vcs->decimation = d;	vino_set_clipping(vcs, x, y, w * d, h * d);	dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,		vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,		vcs->decimation, vcs->line_size);}/* execute with input_lock locked */static inline void vino_set_default_scaling(struct vino_channel_settings *vcs){	vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,			 vcs->clipping.bottom - vcs->clipping.top);}/* execute with input_lock locked */static void vino_set_framerate(struct vino_channel_settings *vcs,			       unsigned int fps){	unsigned int mask;	switch (vcs->data_norm) {

⌨️ 快捷键说明

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