コード例 #1
0
int fimc_is_queue_stop_streaming(struct fimc_is_queue *queue,
	void *qdevice)
{
	int ret = 0;

	BUG_ON(!queue);

	if (!test_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state)) {
		err("already stream off(%ld)", queue->state);
		ret = -EINVAL;
		goto p_err;
	}

	ret = CALL_QOPS(queue, stop_streaming, qdevice, queue);
	if (ret) {
		err("stop_streaming is fail(%d)", ret);
		ret = -EINVAL;
		goto p_err;
	}

	ret = fimc_is_frame_flush(&queue->framemgr);
	if (ret) {
		err("fimc_is_frame_flush is fail(%d)", ret);
		ret = -EINVAL;
		goto p_err;
	}

	clear_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state);
	clear_bit(FIMC_IS_QUEUE_BUFFER_READY, &queue->state);
	clear_bit(FIMC_IS_QUEUE_BUFFER_PREPARED, &queue->state);

p_err:
	return ret;
}
コード例 #2
0
int fimc_is_queue_start_streaming(struct fimc_is_queue *queue,
	void *qdevice)
{
	int ret = 0;

	BUG_ON(!queue);

	if (test_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state)) {
		err("already stream on(%ld)", queue->state);
		ret = -EINVAL;
		goto p_err;
	}

	if (queue->buf_rdycount && !test_bit(FIMC_IS_QUEUE_BUFFER_READY, &queue->state)) {
		err("buffer state is not ready(%ld)", queue->state);
		ret = -EINVAL;
		goto p_err;
	}

	ret = CALL_QOPS(queue, start_streaming, qdevice, queue);
	if (ret) {
		err("start_streaming is fail(%d)", ret);
		ret = -EINVAL;
		goto p_err;
	}

	set_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state);

p_err:
	return ret;
}
コード例 #3
0
int fimc_is_queue_stop_streaming(struct fimc_is_queue *queue,
	struct fimc_is_device_ischain *device,
	struct fimc_is_subdev *subdev,
	struct fimc_is_video_ctx *vctx)
{
	int ret = 0;

	BUG_ON(!queue);
	BUG_ON(!device);
	BUG_ON(!subdev);
	BUG_ON(!vctx);

	if (!test_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state)) {
		merr("already stream off(%ld)", vctx, queue->state);
		ret = -EINVAL;
		goto p_err;
	}

	ret = CALL_QOPS(queue, stop_streaming, device, subdev, queue);
	if (ret) {
		merr("stop_streaming is fail(%d)", vctx, ret);
		ret = -EINVAL;
		goto p_err;
	}

p_err:
	/* HACK: this state must be clear only if all ops was finished */
	clear_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state);
	clear_bit(FIMC_IS_QUEUE_BUFFER_READY, &queue->state);
	clear_bit(FIMC_IS_QUEUE_BUFFER_PREPARED, &queue->state);

	return ret;
}
コード例 #4
0
static int fimc_is_queue_set_format_mplane(struct fimc_is_queue *queue,
	void *device,
	struct v4l2_format *format)
{
	int ret = 0;
	u32 plane;
	struct v4l2_pix_format_mplane *pix;
	struct fimc_is_fmt *fmt;

	BUG_ON(!queue);

	pix = &format->fmt.pix_mp;
	fmt = fimc_is_find_format(&pix->pixelformat, NULL);
	if (!fmt) {
		err("pixel format is not found\n");
		ret = -EINVAL;
		goto p_err;
	}

	queue->framecfg.format.pixelformat	= fmt->pixelformat;
	queue->framecfg.colorspace		= pix->colorspace;
	queue->framecfg.format.mbus_code	= fmt->mbus_code;
	queue->framecfg.format.num_planes	= fmt->num_planes;
	queue->framecfg.width			= pix->width;
	queue->framecfg.height			= pix->height;

	for (plane = 0; plane < fmt->num_planes; ++plane) {
		if (pix->plane_fmt[plane].bytesperline) {
			queue->framecfg.bytesperline[plane] =
				pix->plane_fmt[plane].bytesperline;
			queue->framecfg.width_stride[plane] =
				pix->plane_fmt[plane].bytesperline - pix->width;
		} else {
			queue->framecfg.bytesperline[plane] = 0;
			queue->framecfg.width_stride[plane] = 0;
		}
	}

	ret = CALL_QOPS(queue, s_format, device, queue);
	if (ret) {
		err("s_format is fail(%d)", ret);
		goto p_err;
	}

p_err:
	return ret;
}
コード例 #5
0
int fimc_is_queue_start_streaming(struct fimc_is_queue *queue,
	struct fimc_is_device_ischain *device,
	struct fimc_is_subdev *subdev,
	struct fimc_is_video_ctx *vctx)
{
	int ret = 0;

	BUG_ON(!queue);
	BUG_ON(!device);
	BUG_ON(!subdev);
	BUG_ON(!vctx);

	if (test_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state)) {
		merr("already stream on(%ld)", vctx, queue->state);
		ret = -EINVAL;
		goto p_err;
	}

	if (!test_bit(FIMC_IS_QUEUE_BUFFER_READY, &queue->state)) {
		merr("buffer state is not ready(%ld)", vctx, queue->state);
		ret = -EINVAL;
		goto p_err;
	}

	ret = CALL_QOPS(queue, start_streaming, device, subdev, queue);
	if (ret) {
		merr("start_streaming is fail(%d)", vctx, ret);
		ret = -EINVAL;
		goto p_err;
	}

	set_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state);

p_err:
	return ret;
}
コード例 #6
0
int fimc_is_video_reqbufs(struct file *file,
	struct fimc_is_video_ctx *vctx,
	struct v4l2_requestbuffers *request)
{
	int ret = 0;
	struct fimc_is_queue *queue;
	struct fimc_is_framemgr *framemgr;

	BUG_ON(!vctx);
	BUG_ON(!request);

	if (!(vctx->state & (BIT(FIMC_IS_VIDEO_S_FORMAT) | BIT(FIMC_IS_VIDEO_STOP) | BIT(FIMC_IS_VIDEO_S_BUFS)))) {
		err("[V%02d] invalid reqbufs is requested(%lX)", vctx->video->id, vctx->state);
		return -EINVAL;
	}

	queue = GET_QUEUE(vctx);
	if (test_bit(FIMC_IS_QUEUE_STREAM_ON, &queue->state)) {
		err("video is stream on, not applied");
		ret = -EINVAL;
		goto p_err;
	}

	ret = CALL_QOPS(queue, request_bufs, GET_DEVICE(vctx), request->count);
	if (ret) {
		err("request_bufs is fail(%d)", ret);
		goto p_err;
	}

	ret = vb2_reqbufs(queue->vbq, request);
	if (ret) {
		err("vb2_reqbufs is fail(%d)", ret);
		goto p_err;
	}

	framemgr = &queue->framemgr;
	queue->buf_maxcount = request->count;
	if (queue->buf_maxcount == 0) {
		queue->buf_req = 0;
		queue->buf_pre = 0;
		queue->buf_que = 0;
		queue->buf_com = 0;
		queue->buf_dqe = 0;
		queue->buf_refcount = 0;
		clear_bit(FIMC_IS_QUEUE_BUFFER_READY, &queue->state);
		clear_bit(FIMC_IS_QUEUE_BUFFER_PREPARED, &queue->state);
		fimc_is_frame_close(framemgr);
	} else {
		if (queue->buf_maxcount < queue->buf_rdycount) {
			err("buffer count is not invalid(%d < %d)",
				queue->buf_maxcount, queue->buf_rdycount);
			ret = -EINVAL;
			goto p_err;
		}

		ret = fimc_is_frame_open(framemgr, queue->buf_maxcount);
		if (ret) {
			err("[V%02d] fimc_is_frame_open is fail(%d)", vctx->video->id, ret);
			goto p_err;
		}
	}

	vctx->state = BIT(FIMC_IS_VIDEO_S_BUFS);

p_err:
	return ret;
}