Exemplo n.º 1
0
static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
{
	struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
	struct s5p_mfc_dev *dev = ctx->dev;

	switch (ctrl->id) {
	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
		if (ctx->state >= MFCINST_HEAD_PARSED &&
		    ctx->state < MFCINST_ABORT) {
			ctrl->val = ctx->dpb_count;
			break;
		} else if (ctx->state != MFCINST_INIT) {
			v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
			return -EINVAL;
		}
		/* Should wait for the header to be parsed */
		s5p_mfc_clean_ctx_int_flags(ctx);
		s5p_mfc_wait_for_done_ctx(ctx,
				S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0);
		if (ctx->state >= MFCINST_HEAD_PARSED &&
		    ctx->state < MFCINST_ABORT) {
			ctrl->val = ctx->dpb_count;
		} else {
			v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
			return -EINVAL;
		}
		break;
	}
	return 0;
}
Exemplo n.º 2
0
/* Get format */
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	struct v4l2_pix_format_mplane *pix_mp;

	mfc_debug_enter();
	pix_mp = &f->fmt.pix_mp;
	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
	    (ctx->state == MFCINST_GOT_INST || ctx->state ==
						MFCINST_RES_CHANGE_END)) {
		/* If the MFC is parsing the header,
		 * so wait until it is finished */
		s5p_mfc_clean_ctx_int_flags(ctx);
		s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET,
									0);
	}
	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
	    ctx->state >= MFCINST_HEAD_PARSED &&
	    ctx->state < MFCINST_ABORT) {
		/* This is run on CAPTURE (decode output) */
		/* Width and height are set to the dimensions
		   of the movie, the buffer is bigger and
		   further processing stages should crop to this
		   rectangle. */
		pix_mp->width = ctx->buf_width;
		pix_mp->height = ctx->buf_height;
		pix_mp->field = V4L2_FIELD_NONE;
		pix_mp->num_planes = 2;
		/* Set pixelformat to the format in which MFC
		   outputs the decoded frame */
		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		/* This is run on OUTPUT
		   The buffer contains compressed image
		   so width and height have no meaning */
		pix_mp->width = 0;
		pix_mp->height = 0;
		pix_mp->field = V4L2_FIELD_NONE;
		pix_mp->plane_fmt[0].bytesperline = ctx->dec_src_buf_size;
		pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size;
		pix_mp->pixelformat = ctx->src_fmt->fourcc;
		pix_mp->num_planes = ctx->src_fmt->num_planes;
	} else {
		mfc_err("Format could not be read\n");
		mfc_debug(2, "%s-- with error\n", __func__);
		return -EINVAL;
	}
	mfc_debug_leave();
	return 0;
}
Exemplo n.º 3
0
/* Stream on */
static int vidioc_streamon(struct file *file, void *priv,
			   enum v4l2_buf_type type)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	struct s5p_mfc_dev *dev = ctx->dev;
	int ret = -EINVAL;

	mfc_debug_enter();
	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {

		if (ctx->state == MFCINST_INIT) {
			ctx->dst_bufs_cnt = 0;
			ctx->src_bufs_cnt = 0;
			ctx->capture_state = QUEUE_FREE;
			ctx->output_state = QUEUE_FREE;
			s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer,
					ctx);
			s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers,
					ctx);
			set_work_bit_irqsave(ctx);
			s5p_mfc_clean_ctx_int_flags(ctx);
			s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);

			if (s5p_mfc_wait_for_done_ctx(ctx,
				S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
				/* Error or timeout */
				mfc_err("Error getting instance from hardware\n");
				s5p_mfc_hw_call(dev->mfc_ops,
						release_instance_buffer, ctx);
				s5p_mfc_hw_call(dev->mfc_ops,
						release_dec_desc_buffer, ctx);
				return -EIO;
			}
			mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
		}
		ret = vb2_streamon(&ctx->vq_src, type);
		}
	else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		ret = vb2_streamon(&ctx->vq_dst, type);
	mfc_debug_leave();
	return ret;
}
Exemplo n.º 4
0
void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
{
    ctx->state = MFCINST_RETURN_INST;
    set_work_bit_irqsave(ctx);
    s5p_mfc_clean_ctx_int_flags(ctx);
    s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
    /* Wait until instance is returned or timeout occurred */
    if (s5p_mfc_wait_for_done_ctx(ctx,
                                  S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
        mfc_err("Err returning instance\n");

    /* Free resources */
    s5p_mfc_hw_call_void(dev->mfc_ops, release_codec_buffers, ctx);
    s5p_mfc_hw_call_void(dev->mfc_ops, release_instance_buffer, ctx);
    if (ctx->type == MFCINST_DECODER)
        s5p_mfc_hw_call_void(dev->mfc_ops, release_dec_desc_buffer, ctx);

    ctx->inst_no = MFC_NO_INSTANCE_SET;
    ctx->state = MFCINST_FREE;
}
Exemplo n.º 5
0
int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
{
    int ret = 0;

    ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
    if (ret) {
        mfc_err("Failed allocating instance buffer\n");
        goto err;
    }

    if (ctx->type == MFCINST_DECODER) {
        ret = s5p_mfc_hw_call(dev->mfc_ops,
                              alloc_dec_temp_buffers, ctx);
        if (ret) {
            mfc_err("Failed allocating temporary buffers\n");
            goto err_free_inst_buf;
        }
    }

    set_work_bit_irqsave(ctx);
    s5p_mfc_clean_ctx_int_flags(ctx);
    s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
    if (s5p_mfc_wait_for_done_ctx(ctx,
                                  S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
        /* Error or timeout */
        mfc_err("Error getting instance from hardware\n");
        ret = -EIO;
        goto err_free_desc_buf;
    }

    mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
    return ret;

err_free_desc_buf:
    if (ctx->type == MFCINST_DECODER)
        s5p_mfc_hw_call_void(dev->mfc_ops, release_dec_desc_buffer, ctx);
err_free_inst_buf:
    s5p_mfc_hw_call_void(dev->mfc_ops, release_instance_buffer, ctx);
err:
    return ret;
}