Lines Matching +full:vpu +full:- +full:side

1 // SPDX-License-Identifier: GPL-2.0
3 * Hantro VPU codec driver
7 * Alpha Lin <Alpha.Lin@rock-chips.com>
8 * Jeffy Chen <jeffy.chen@rock-chips.com>
13 * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
14 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-event.h>
25 #include <media/v4l2-mem2mem.h>
49 if (ctx->is_encoder) { in hantro_get_formats()
50 formats = ctx->dev->variant->enc_fmts; in hantro_get_formats()
51 *num_fmts = ctx->dev->variant->num_enc_fmts; in hantro_get_formats()
53 formats = ctx->dev->variant->dec_fmts; in hantro_get_formats()
54 *num_fmts = ctx->dev->variant->num_dec_fmts; in hantro_get_formats()
64 struct hantro_dev *vpu = ctx->dev; in hantro_get_postproc_formats() local
66 if (ctx->is_encoder || !vpu->variant->postproc_fmts) { in hantro_get_postproc_formats()
71 *num_fmts = ctx->dev->variant->num_postproc_fmts; in hantro_get_postproc_formats()
72 return ctx->dev->variant->postproc_fmts; in hantro_get_postproc_formats()
92 if (!fmt->match_depth && !fmt->postprocessed) in hantro_check_depth_match()
99 fmt_depth = hantro_get_format_depth(fmt->fourcc); in hantro_check_depth_match()
105 if (!fmt->match_depth) in hantro_check_depth_match()
158 struct hantro_dev *vpu = video_drvdata(file); in vidioc_querycap() local
161 strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver)); in vidioc_querycap()
162 strscpy(cap->card, vdev->name, sizeof(cap->card)); in vidioc_querycap()
172 fmt = hantro_find_format(ctx, fsize->pixel_format); in vidioc_enum_framesizes()
175 fsize->pixel_format); in vidioc_enum_framesizes()
176 return -EINVAL; in vidioc_enum_framesizes()
179 /* For non-coded formats check if postprocessing scaling is possible */ in vidioc_enum_framesizes()
180 if (fmt->codec_mode == HANTRO_MODE_NONE) { in vidioc_enum_framesizes()
184 return -ENOTTY; in vidioc_enum_framesizes()
185 } else if (fsize->index != 0) { in vidioc_enum_framesizes()
187 fsize->index); in vidioc_enum_framesizes()
188 return -EINVAL; in vidioc_enum_framesizes()
191 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in vidioc_enum_framesizes()
192 fsize->stepwise = fmt->frmsize; in vidioc_enum_framesizes()
208 * - on the capture side we want to filter out all MODE_NONE formats. in vidioc_enum_fmt()
209 * - on the output side we want to filter out all formats that are in vidioc_enum_fmt()
212 * - on the capture side we want to filter out all formats that are in vidioc_enum_fmt()
214 * - on the output side we want to filter out all MODE_NONE formats. in vidioc_enum_fmt()
216 skip_mode_none = capture == ctx->is_encoder; in vidioc_enum_fmt()
225 if (!hantro_check_depth_match(fmt, ctx->bit_depth)) in vidioc_enum_fmt()
227 if (j == f->index) { in vidioc_enum_fmt()
228 f->pixelformat = fmt->fourcc; in vidioc_enum_fmt()
235 * Enumerate post-processed formats. As per the specification, in vidioc_enum_fmt()
240 return -EINVAL; in vidioc_enum_fmt()
245 if (!hantro_check_depth_match(fmt, ctx->bit_depth)) in vidioc_enum_fmt()
247 if (j == f->index) { in vidioc_enum_fmt()
248 f->pixelformat = fmt->fourcc; in vidioc_enum_fmt()
254 return -EINVAL; in vidioc_enum_fmt()
272 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in vidioc_g_fmt_out_mplane()
275 vpu_debug(4, "f->type = %d\n", f->type); in vidioc_g_fmt_out_mplane()
277 *pix_mp = ctx->src_fmt; in vidioc_g_fmt_out_mplane()
285 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; in vidioc_g_fmt_cap_mplane()
288 vpu_debug(4, "f->type = %d\n", f->type); in vidioc_g_fmt_cap_mplane()
290 *pix_mp = ctx->dst_fmt; in vidioc_g_fmt_cap_mplane()
304 coded = capture == ctx->is_encoder; in hantro_try_fmt()
306 vpu_debug(4, "trying format %p4cc\n", &pix_mp->pixelformat); in hantro_try_fmt()
308 fmt = hantro_find_format(ctx, pix_mp->pixelformat); in hantro_try_fmt()
311 pix_mp->pixelformat = fmt->fourcc; in hantro_try_fmt()
315 pix_mp->num_planes = 1; in hantro_try_fmt()
317 } else if (ctx->is_encoder) { in hantro_try_fmt()
318 vpu_fmt = hantro_find_format(ctx, ctx->dst_fmt.pixelformat); in hantro_try_fmt()
324 pix_mp->width = ctx->src_fmt.width; in hantro_try_fmt()
325 pix_mp->height = ctx->src_fmt.height; in hantro_try_fmt()
329 pix_mp->field = V4L2_FIELD_NONE; in hantro_try_fmt()
331 v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height, in hantro_try_fmt()
332 &vpu_fmt->frmsize); in hantro_try_fmt()
336 v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width, in hantro_try_fmt()
337 pix_mp->height); in hantro_try_fmt()
338 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE && in hantro_try_fmt()
340 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
341 hantro_h264_mv_size(pix_mp->width, in hantro_try_fmt()
342 pix_mp->height); in hantro_try_fmt()
343 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME && in hantro_try_fmt()
345 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
346 hantro_vp9_mv_size(pix_mp->width, in hantro_try_fmt()
347 pix_mp->height); in hantro_try_fmt()
348 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE && in hantro_try_fmt()
350 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
351 hantro_hevc_mv_size(pix_mp->width, in hantro_try_fmt()
352 pix_mp->height); in hantro_try_fmt()
353 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME && in hantro_try_fmt()
355 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
356 hantro_av1_mv_size(pix_mp->width, in hantro_try_fmt()
357 pix_mp->height); in hantro_try_fmt()
358 } else if (!pix_mp->plane_fmt[0].sizeimage) { in hantro_try_fmt()
364 pix_mp->plane_fmt[0].sizeimage = fmt->header_size + in hantro_try_fmt()
365 pix_mp->width * pix_mp->height * fmt->max_depth; in hantro_try_fmt()
374 return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type); in vidioc_try_fmt_cap_mplane()
380 return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type); in vidioc_try_fmt_out_mplane()
389 fmt->pixelformat = vpu_fmt->fourcc; in hantro_reset_fmt()
390 fmt->field = V4L2_FIELD_NONE; in hantro_reset_fmt()
391 fmt->colorspace = V4L2_COLORSPACE_JPEG; in hantro_reset_fmt()
392 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in hantro_reset_fmt()
393 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in hantro_reset_fmt()
394 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in hantro_reset_fmt()
408 fmt.width = vpu_fmt->frmsize.min_width; in hantro_reset_encoded_fmt()
409 fmt.height = vpu_fmt->frmsize.min_height; in hantro_reset_encoded_fmt()
410 if (ctx->is_encoder) in hantro_reset_encoded_fmt()
425 return -EINVAL; in hantro_reset_raw_fmt()
427 if (ctx->is_encoder) { in hantro_reset_raw_fmt()
428 encoded_fmt = &ctx->dst_fmt; in hantro_reset_raw_fmt()
429 ctx->vpu_src_fmt = raw_vpu_fmt; in hantro_reset_raw_fmt()
431 encoded_fmt = &ctx->src_fmt; in hantro_reset_raw_fmt()
435 raw_fmt.width = encoded_fmt->width; in hantro_reset_raw_fmt()
436 raw_fmt.height = encoded_fmt->height; in hantro_reset_raw_fmt()
437 if (ctx->is_encoder) in hantro_reset_raw_fmt()
443 ctx->bit_depth = bit_depth; in hantro_reset_raw_fmt()
444 ctx->need_postproc = need_postproc; in hantro_reset_raw_fmt()
461 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = false; in hantro_update_requires_request()
468 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true; in hantro_update_requires_request()
480 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_update_requires_hold_capture_buf()
489 vq->subsystem_flags &= ~(VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF); in hantro_update_requires_hold_capture_buf()
492 vq->subsystem_flags |= VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF; in hantro_update_requires_hold_capture_buf()
506 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_set_fmt_out()
512 if (!ctx->is_encoder) { in hantro_set_fmt_out()
518 if (vb2_is_streaming(vq) && pix_mp->pixelformat != ctx->src_fmt.pixelformat) { in hantro_set_fmt_out()
519 return -EBUSY; in hantro_set_fmt_out()
527 return -EBUSY; in hantro_set_fmt_out()
530 ctx->vpu_src_fmt = hantro_find_format(ctx, pix_mp->pixelformat); in hantro_set_fmt_out()
531 ctx->src_fmt = *pix_mp; in hantro_set_fmt_out()
542 if (!ctx->is_encoder) in hantro_set_fmt_out()
544 hantro_get_format_depth(pix_mp->pixelformat), in hantro_set_fmt_out()
548 ctx->dst_fmt.colorspace = pix_mp->colorspace; in hantro_set_fmt_out()
549 ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc; in hantro_set_fmt_out()
550 ctx->dst_fmt.xfer_func = pix_mp->xfer_func; in hantro_set_fmt_out()
551 ctx->dst_fmt.quantization = pix_mp->quantization; in hantro_set_fmt_out()
553 hantro_update_requires_request(ctx, pix_mp->pixelformat); in hantro_set_fmt_out()
554 hantro_update_requires_hold_capture_buf(ctx, pix_mp->pixelformat); in hantro_set_fmt_out()
556 vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode); in hantro_set_fmt_out()
557 vpu_debug(0, "fmt - w: %d, h: %d\n", in hantro_set_fmt_out()
558 pix_mp->width, pix_mp->height); in hantro_set_fmt_out()
567 if (ctx->is_encoder) { in hantro_set_fmt_cap()
575 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_set_fmt_cap()
578 (pix_mp->pixelformat != ctx->dst_fmt.pixelformat || in hantro_set_fmt_cap()
579 pix_mp->height != ctx->dst_fmt.height || in hantro_set_fmt_cap()
580 pix_mp->width != ctx->dst_fmt.width)) in hantro_set_fmt_cap()
581 return -EBUSY; in hantro_set_fmt_cap()
588 ctx->vpu_dst_fmt = hantro_find_format(ctx, pix_mp->pixelformat); in hantro_set_fmt_cap()
589 ctx->dst_fmt = *pix_mp; in hantro_set_fmt_cap()
600 if (ctx->is_encoder) in hantro_set_fmt_cap()
604 ctx->src_fmt.colorspace = pix_mp->colorspace; in hantro_set_fmt_cap()
605 ctx->src_fmt.ycbcr_enc = pix_mp->ycbcr_enc; in hantro_set_fmt_cap()
606 ctx->src_fmt.xfer_func = pix_mp->xfer_func; in hantro_set_fmt_cap()
607 ctx->src_fmt.quantization = pix_mp->quantization; in hantro_set_fmt_cap()
609 vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode); in hantro_set_fmt_cap()
610 vpu_debug(0, "fmt - w: %d, h: %d\n", in hantro_set_fmt_cap()
611 pix_mp->width, pix_mp->height); in hantro_set_fmt_cap()
613 hantro_update_requires_request(ctx, pix_mp->pixelformat); in hantro_set_fmt_cap()
621 return hantro_set_fmt_out(fh_to_ctx(priv), &f->fmt.pix_mp, HANTRO_AUTO_POSTPROC); in vidioc_s_fmt_out_mplane()
627 return hantro_set_fmt_cap(fh_to_ctx(priv), &f->fmt.pix_mp); in vidioc_s_fmt_cap_mplane()
636 if (!ctx->is_encoder || in vidioc_g_selection()
637 sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_g_selection()
638 return -EINVAL; in vidioc_g_selection()
640 switch (sel->target) { in vidioc_g_selection()
643 sel->r.top = 0; in vidioc_g_selection()
644 sel->r.left = 0; in vidioc_g_selection()
645 sel->r.width = ctx->src_fmt.width; in vidioc_g_selection()
646 sel->r.height = ctx->src_fmt.height; in vidioc_g_selection()
649 sel->r.top = 0; in vidioc_g_selection()
650 sel->r.left = 0; in vidioc_g_selection()
651 sel->r.width = ctx->dst_fmt.width; in vidioc_g_selection()
652 sel->r.height = ctx->dst_fmt.height; in vidioc_g_selection()
655 return -EINVAL; in vidioc_g_selection()
665 struct v4l2_rect *rect = &sel->r; in vidioc_s_selection()
669 if (!ctx->is_encoder || in vidioc_s_selection()
670 sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_s_selection()
671 return -EINVAL; in vidioc_s_selection()
674 vq = v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx); in vidioc_s_selection()
676 return -EBUSY; in vidioc_s_selection()
678 if (sel->target != V4L2_SEL_TGT_CROP) in vidioc_s_selection()
679 return -EINVAL; in vidioc_s_selection()
683 * right-most or bottom-most macroblocks. in vidioc_s_selection()
685 if (rect->left != 0 || rect->top != 0 || in vidioc_s_selection()
686 round_up(rect->width, MB_DIM) != ctx->src_fmt.width || in vidioc_s_selection()
687 round_up(rect->height, MB_DIM) != ctx->src_fmt.height) { in vidioc_s_selection()
689 rect->left = 0; in vidioc_s_selection()
690 rect->top = 0; in vidioc_s_selection()
691 rect->width = ctx->src_fmt.width; in vidioc_s_selection()
692 rect->height = ctx->src_fmt.height; in vidioc_s_selection()
695 rect->width = round_up(rect->width, 4); in vidioc_s_selection()
698 ctx->dst_fmt.width = rect->width; in vidioc_s_selection()
699 ctx->dst_fmt.height = rect->height; in vidioc_s_selection()
718 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx)) || in vidioc_encoder_cmd()
719 !vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) in vidioc_encoder_cmd()
726 if (ec->cmd == V4L2_ENC_CMD_STOP && in vidioc_encoder_cmd()
727 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) in vidioc_encoder_cmd()
728 v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); in vidioc_encoder_cmd()
730 if (ec->cmd == V4L2_ENC_CMD_START) in vidioc_encoder_cmd()
731 vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q); in vidioc_encoder_cmd()
783 switch (vq->type) { in hantro_queue_setup()
785 pixfmt = &ctx->dst_fmt; in hantro_queue_setup()
788 pixfmt = &ctx->src_fmt; in hantro_queue_setup()
791 vpu_err("invalid queue type: %d\n", vq->type); in hantro_queue_setup()
792 return -EINVAL; in hantro_queue_setup()
796 if (*num_planes != pixfmt->num_planes) in hantro_queue_setup()
797 return -EINVAL; in hantro_queue_setup()
798 for (i = 0; i < pixfmt->num_planes; ++i) in hantro_queue_setup()
799 if (sizes[i] < pixfmt->plane_fmt[i].sizeimage) in hantro_queue_setup()
800 return -EINVAL; in hantro_queue_setup()
804 *num_planes = pixfmt->num_planes; in hantro_queue_setup()
805 for (i = 0; i < pixfmt->num_planes; ++i) in hantro_queue_setup()
806 sizes[i] = pixfmt->plane_fmt[i].sizeimage; in hantro_queue_setup()
817 for (i = 0; i < pixfmt->num_planes; ++i) { in hantro_buf_plane_check()
818 sz = pixfmt->plane_fmt[i].sizeimage; in hantro_buf_plane_check()
823 return -EINVAL; in hantro_buf_plane_check()
831 struct vb2_queue *vq = vb->vb2_queue; in hantro_buf_prepare()
836 if (V4L2_TYPE_IS_OUTPUT(vq->type)) in hantro_buf_prepare()
837 pix_fmt = &ctx->src_fmt; in hantro_buf_prepare()
839 pix_fmt = &ctx->dst_fmt; in hantro_buf_prepare()
845 * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets in hantro_buf_prepare()
848 if (V4L2_TYPE_IS_CAPTURE(vq->type)) { in hantro_buf_prepare()
849 if (ctx->is_encoder) in hantro_buf_prepare()
852 vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); in hantro_buf_prepare()
860 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in hantro_buf_queue()
863 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && in hantro_buf_queue()
864 vb2_is_streaming(vb->vb2_queue) && in hantro_buf_queue()
865 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { in hantro_buf_queue()
868 for (i = 0; i < vb->num_planes; i++) in hantro_buf_queue()
871 vbuf->field = V4L2_FIELD_NONE; in hantro_buf_queue()
872 vbuf->sequence = ctx->sequence_cap++; in hantro_buf_queue()
874 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); in hantro_buf_queue()
875 v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); in hantro_buf_queue()
879 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in hantro_buf_queue()
886 return ctx->is_encoder != V4L2_TYPE_IS_OUTPUT(q->type); in hantro_vq_is_coded()
894 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); in hantro_start_streaming()
896 if (V4L2_TYPE_IS_OUTPUT(q->type)) in hantro_start_streaming()
897 ctx->sequence_out = 0; in hantro_start_streaming()
899 ctx->sequence_cap = 0; in hantro_start_streaming()
904 if (V4L2_TYPE_IS_OUTPUT(q->type)) in hantro_start_streaming()
905 codec_mode = ctx->vpu_src_fmt->codec_mode; in hantro_start_streaming()
907 codec_mode = ctx->vpu_dst_fmt->codec_mode; in hantro_start_streaming()
910 ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode]; in hantro_start_streaming()
911 if (ctx->codec_ops->init) { in hantro_start_streaming()
912 ret = ctx->codec_ops->init(ctx); in hantro_start_streaming()
917 if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt)) { in hantro_start_streaming()
926 if (ctx->codec_ops->exit) in hantro_start_streaming()
927 ctx->codec_ops->exit(ctx); in hantro_start_streaming()
940 vbuf = buf_remove(ctx->fh.m2m_ctx); in hantro_return_bufs()
943 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, in hantro_return_bufs()
944 &ctx->ctrl_handler); in hantro_return_bufs()
955 if (ctx->codec_ops && ctx->codec_ops->exit) in hantro_stop_streaming()
956 ctx->codec_ops->exit(ctx); in hantro_stop_streaming()
964 if (V4L2_TYPE_IS_OUTPUT(q->type)) in hantro_stop_streaming()
969 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); in hantro_stop_streaming()
971 if (V4L2_TYPE_IS_OUTPUT(q->type) && in hantro_stop_streaming()
972 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) in hantro_stop_streaming()
973 v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); in hantro_stop_streaming()
978 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in hantro_buf_request_complete()
980 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_handler); in hantro_buf_request_complete()
987 vbuf->field = V4L2_FIELD_NONE; in hantro_buf_out_validate()