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()
307 (pix_mp->pixelformat & 0x7f), in hantro_try_fmt()
308 (pix_mp->pixelformat >> 8) & 0x7f, in hantro_try_fmt()
309 (pix_mp->pixelformat >> 16) & 0x7f, in hantro_try_fmt()
310 (pix_mp->pixelformat >> 24) & 0x7f); in hantro_try_fmt()
312 fmt = hantro_find_format(ctx, pix_mp->pixelformat); in hantro_try_fmt()
315 pix_mp->pixelformat = fmt->fourcc; in hantro_try_fmt()
319 pix_mp->num_planes = 1; in hantro_try_fmt()
321 } else if (ctx->is_encoder) { in hantro_try_fmt()
322 vpu_fmt = hantro_find_format(ctx, ctx->dst_fmt.pixelformat); in hantro_try_fmt()
328 pix_mp->width = ctx->src_fmt.width; in hantro_try_fmt()
329 pix_mp->height = ctx->src_fmt.height; in hantro_try_fmt()
333 pix_mp->field = V4L2_FIELD_NONE; in hantro_try_fmt()
335 v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height, in hantro_try_fmt()
336 &vpu_fmt->frmsize); in hantro_try_fmt()
340 v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width, in hantro_try_fmt()
341 pix_mp->height); in hantro_try_fmt()
342 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE && in hantro_try_fmt()
344 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
345 hantro_h264_mv_size(pix_mp->width, in hantro_try_fmt()
346 pix_mp->height); in hantro_try_fmt()
347 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME && in hantro_try_fmt()
349 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
350 hantro_vp9_mv_size(pix_mp->width, in hantro_try_fmt()
351 pix_mp->height); in hantro_try_fmt()
352 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE && in hantro_try_fmt()
354 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
355 hantro_hevc_mv_size(pix_mp->width, in hantro_try_fmt()
356 pix_mp->height); in hantro_try_fmt()
357 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME && in hantro_try_fmt()
359 pix_mp->plane_fmt[0].sizeimage += in hantro_try_fmt()
360 hantro_av1_mv_size(pix_mp->width, in hantro_try_fmt()
361 pix_mp->height); in hantro_try_fmt()
362 } else if (!pix_mp->plane_fmt[0].sizeimage) { in hantro_try_fmt()
368 pix_mp->plane_fmt[0].sizeimage = fmt->header_size + in hantro_try_fmt()
369 pix_mp->width * pix_mp->height * fmt->max_depth; in hantro_try_fmt()
378 return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type); in vidioc_try_fmt_cap_mplane()
384 return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type); in vidioc_try_fmt_out_mplane()
393 fmt->pixelformat = vpu_fmt->fourcc; in hantro_reset_fmt()
394 fmt->field = V4L2_FIELD_NONE; in hantro_reset_fmt()
395 fmt->colorspace = V4L2_COLORSPACE_JPEG; in hantro_reset_fmt()
396 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in hantro_reset_fmt()
397 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in hantro_reset_fmt()
398 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in hantro_reset_fmt()
412 fmt.width = vpu_fmt->frmsize.min_width; in hantro_reset_encoded_fmt()
413 fmt.height = vpu_fmt->frmsize.min_height; in hantro_reset_encoded_fmt()
414 if (ctx->is_encoder) in hantro_reset_encoded_fmt()
429 return -EINVAL; in hantro_reset_raw_fmt()
431 if (ctx->is_encoder) { in hantro_reset_raw_fmt()
432 encoded_fmt = &ctx->dst_fmt; in hantro_reset_raw_fmt()
433 ctx->vpu_src_fmt = raw_vpu_fmt; in hantro_reset_raw_fmt()
435 encoded_fmt = &ctx->src_fmt; in hantro_reset_raw_fmt()
439 raw_fmt.width = encoded_fmt->width; in hantro_reset_raw_fmt()
440 raw_fmt.height = encoded_fmt->height; in hantro_reset_raw_fmt()
441 if (ctx->is_encoder) in hantro_reset_raw_fmt()
447 ctx->bit_depth = bit_depth; in hantro_reset_raw_fmt()
448 ctx->need_postproc = need_postproc; in hantro_reset_raw_fmt()
465 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = false; in hantro_update_requires_request()
472 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true; in hantro_update_requires_request()
484 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_update_requires_hold_capture_buf()
493 vq->subsystem_flags &= ~(VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF); in hantro_update_requires_hold_capture_buf()
496 vq->subsystem_flags |= VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF; in hantro_update_requires_hold_capture_buf()
510 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_set_fmt_out()
516 if (!ctx->is_encoder) { in hantro_set_fmt_out()
525 pix_mp->pixelformat != ctx->src_fmt.pixelformat)) in hantro_set_fmt_out()
526 return -EBUSY; in hantro_set_fmt_out()
532 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_set_fmt_out()
535 return -EBUSY; in hantro_set_fmt_out()
542 return -EBUSY; in hantro_set_fmt_out()
545 ctx->vpu_src_fmt = hantro_find_format(ctx, pix_mp->pixelformat); in hantro_set_fmt_out()
546 ctx->src_fmt = *pix_mp; in hantro_set_fmt_out()
557 if (!ctx->is_encoder) in hantro_set_fmt_out()
559 hantro_get_format_depth(pix_mp->pixelformat), in hantro_set_fmt_out()
563 ctx->dst_fmt.colorspace = pix_mp->colorspace; in hantro_set_fmt_out()
564 ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc; in hantro_set_fmt_out()
565 ctx->dst_fmt.xfer_func = pix_mp->xfer_func; in hantro_set_fmt_out()
566 ctx->dst_fmt.quantization = pix_mp->quantization; in hantro_set_fmt_out()
568 hantro_update_requires_request(ctx, pix_mp->pixelformat); in hantro_set_fmt_out()
569 hantro_update_requires_hold_capture_buf(ctx, pix_mp->pixelformat); in hantro_set_fmt_out()
571 vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode); in hantro_set_fmt_out()
572 vpu_debug(0, "fmt - w: %d, h: %d\n", in hantro_set_fmt_out()
573 pix_mp->width, pix_mp->height); in hantro_set_fmt_out()
584 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_set_fmt_cap()
587 return -EBUSY; in hantro_set_fmt_cap()
589 if (ctx->is_encoder) { in hantro_set_fmt_cap()
597 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, in hantro_set_fmt_cap()
600 (pix_mp->pixelformat != ctx->dst_fmt.pixelformat || in hantro_set_fmt_cap()
601 pix_mp->height != ctx->dst_fmt.height || in hantro_set_fmt_cap()
602 pix_mp->width != ctx->dst_fmt.width)) in hantro_set_fmt_cap()
603 return -EBUSY; in hantro_set_fmt_cap()
610 ctx->vpu_dst_fmt = hantro_find_format(ctx, pix_mp->pixelformat); in hantro_set_fmt_cap()
611 ctx->dst_fmt = *pix_mp; in hantro_set_fmt_cap()
622 if (ctx->is_encoder) in hantro_set_fmt_cap()
626 ctx->src_fmt.colorspace = pix_mp->colorspace; in hantro_set_fmt_cap()
627 ctx->src_fmt.ycbcr_enc = pix_mp->ycbcr_enc; in hantro_set_fmt_cap()
628 ctx->src_fmt.xfer_func = pix_mp->xfer_func; in hantro_set_fmt_cap()
629 ctx->src_fmt.quantization = pix_mp->quantization; in hantro_set_fmt_cap()
631 vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode); in hantro_set_fmt_cap()
632 vpu_debug(0, "fmt - w: %d, h: %d\n", in hantro_set_fmt_cap()
633 pix_mp->width, pix_mp->height); in hantro_set_fmt_cap()
635 hantro_update_requires_request(ctx, pix_mp->pixelformat); in hantro_set_fmt_cap()
643 return hantro_set_fmt_out(fh_to_ctx(priv), &f->fmt.pix_mp, HANTRO_AUTO_POSTPROC); in vidioc_s_fmt_out_mplane()
649 return hantro_set_fmt_cap(fh_to_ctx(priv), &f->fmt.pix_mp); in vidioc_s_fmt_cap_mplane()
658 if (!ctx->is_encoder || in vidioc_g_selection()
659 sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_g_selection()
660 return -EINVAL; in vidioc_g_selection()
662 switch (sel->target) { in vidioc_g_selection()
665 sel->r.top = 0; in vidioc_g_selection()
666 sel->r.left = 0; in vidioc_g_selection()
667 sel->r.width = ctx->src_fmt.width; in vidioc_g_selection()
668 sel->r.height = ctx->src_fmt.height; in vidioc_g_selection()
671 sel->r.top = 0; in vidioc_g_selection()
672 sel->r.left = 0; in vidioc_g_selection()
673 sel->r.width = ctx->dst_fmt.width; in vidioc_g_selection()
674 sel->r.height = ctx->dst_fmt.height; in vidioc_g_selection()
677 return -EINVAL; in vidioc_g_selection()
687 struct v4l2_rect *rect = &sel->r; in vidioc_s_selection()
691 if (!ctx->is_encoder || in vidioc_s_selection()
692 sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_s_selection()
693 return -EINVAL; in vidioc_s_selection()
696 vq = v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx); in vidioc_s_selection()
698 return -EBUSY; in vidioc_s_selection()
700 if (sel->target != V4L2_SEL_TGT_CROP) in vidioc_s_selection()
701 return -EINVAL; in vidioc_s_selection()
705 * right-most or bottom-most macroblocks. in vidioc_s_selection()
707 if (rect->left != 0 || rect->top != 0 || in vidioc_s_selection()
708 round_up(rect->width, MB_DIM) != ctx->src_fmt.width || in vidioc_s_selection()
709 round_up(rect->height, MB_DIM) != ctx->src_fmt.height) { in vidioc_s_selection()
711 rect->left = 0; in vidioc_s_selection()
712 rect->top = 0; in vidioc_s_selection()
713 rect->width = ctx->src_fmt.width; in vidioc_s_selection()
714 rect->height = ctx->src_fmt.height; in vidioc_s_selection()
717 rect->width = round_up(rect->width, 4); in vidioc_s_selection()
720 ctx->dst_fmt.width = rect->width; in vidioc_s_selection()
721 ctx->dst_fmt.height = rect->height; in vidioc_s_selection()
740 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx)) || in vidioc_encoder_cmd()
741 !vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) in vidioc_encoder_cmd()
748 if (ec->cmd == V4L2_ENC_CMD_STOP && in vidioc_encoder_cmd()
749 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) in vidioc_encoder_cmd()
750 v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); in vidioc_encoder_cmd()
752 if (ec->cmd == V4L2_ENC_CMD_START) in vidioc_encoder_cmd()
753 vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q); in vidioc_encoder_cmd()
801 switch (vq->type) { in hantro_queue_setup()
803 pixfmt = &ctx->dst_fmt; in hantro_queue_setup()
806 pixfmt = &ctx->src_fmt; in hantro_queue_setup()
809 vpu_err("invalid queue type: %d\n", vq->type); in hantro_queue_setup()
810 return -EINVAL; in hantro_queue_setup()
814 if (*num_planes != pixfmt->num_planes) in hantro_queue_setup()
815 return -EINVAL; in hantro_queue_setup()
816 for (i = 0; i < pixfmt->num_planes; ++i) in hantro_queue_setup()
817 if (sizes[i] < pixfmt->plane_fmt[i].sizeimage) in hantro_queue_setup()
818 return -EINVAL; in hantro_queue_setup()
822 *num_planes = pixfmt->num_planes; in hantro_queue_setup()
823 for (i = 0; i < pixfmt->num_planes; ++i) in hantro_queue_setup()
824 sizes[i] = pixfmt->plane_fmt[i].sizeimage; in hantro_queue_setup()
835 for (i = 0; i < pixfmt->num_planes; ++i) { in hantro_buf_plane_check()
836 sz = pixfmt->plane_fmt[i].sizeimage; in hantro_buf_plane_check()
841 return -EINVAL; in hantro_buf_plane_check()
849 struct vb2_queue *vq = vb->vb2_queue; in hantro_buf_prepare()
854 if (V4L2_TYPE_IS_OUTPUT(vq->type)) in hantro_buf_prepare()
855 pix_fmt = &ctx->src_fmt; in hantro_buf_prepare()
857 pix_fmt = &ctx->dst_fmt; in hantro_buf_prepare()
863 * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets in hantro_buf_prepare()
866 if (V4L2_TYPE_IS_CAPTURE(vq->type)) { in hantro_buf_prepare()
867 if (ctx->is_encoder) in hantro_buf_prepare()
870 vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); in hantro_buf_prepare()
878 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in hantro_buf_queue()
881 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && in hantro_buf_queue()
882 vb2_is_streaming(vb->vb2_queue) && in hantro_buf_queue()
883 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { in hantro_buf_queue()
886 for (i = 0; i < vb->num_planes; i++) in hantro_buf_queue()
889 vbuf->field = V4L2_FIELD_NONE; in hantro_buf_queue()
890 vbuf->sequence = ctx->sequence_cap++; in hantro_buf_queue()
892 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); in hantro_buf_queue()
893 v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); in hantro_buf_queue()
897 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in hantro_buf_queue()
904 return ctx->is_encoder != V4L2_TYPE_IS_OUTPUT(q->type); in hantro_vq_is_coded()
912 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); in hantro_start_streaming()
914 if (V4L2_TYPE_IS_OUTPUT(q->type)) in hantro_start_streaming()
915 ctx->sequence_out = 0; in hantro_start_streaming()
917 ctx->sequence_cap = 0; in hantro_start_streaming()
922 if (V4L2_TYPE_IS_OUTPUT(q->type)) in hantro_start_streaming()
923 codec_mode = ctx->vpu_src_fmt->codec_mode; in hantro_start_streaming()
925 codec_mode = ctx->vpu_dst_fmt->codec_mode; in hantro_start_streaming()
928 ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode]; in hantro_start_streaming()
929 if (ctx->codec_ops->init) { in hantro_start_streaming()
930 ret = ctx->codec_ops->init(ctx); in hantro_start_streaming()
935 if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt)) { in hantro_start_streaming()
944 if (ctx->codec_ops->exit) in hantro_start_streaming()
945 ctx->codec_ops->exit(ctx); in hantro_start_streaming()
958 vbuf = buf_remove(ctx->fh.m2m_ctx); in hantro_return_bufs()
961 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, in hantro_return_bufs()
962 &ctx->ctrl_handler); in hantro_return_bufs()
973 if (ctx->codec_ops && ctx->codec_ops->exit) in hantro_stop_streaming()
974 ctx->codec_ops->exit(ctx); in hantro_stop_streaming()
982 if (V4L2_TYPE_IS_OUTPUT(q->type)) in hantro_stop_streaming()
987 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); in hantro_stop_streaming()
989 if (V4L2_TYPE_IS_OUTPUT(q->type) && in hantro_stop_streaming()
990 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) in hantro_stop_streaming()
991 v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); in hantro_stop_streaming()
996 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in hantro_buf_request_complete()
998 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_handler); in hantro_buf_request_complete()
1005 vbuf->field = V4L2_FIELD_NONE; in hantro_buf_out_validate()