.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. |
---|
3 | 4 | * Copyright (C) 2017 Linaro Ltd. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License version 2 and |
---|
7 | | - * only version 2 as published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | | - * |
---|
14 | 5 | */ |
---|
15 | 6 | #include <linux/clk.h> |
---|
16 | 7 | #include <linux/module.h> |
---|
.. | .. |
---|
29 | 20 | #include "core.h" |
---|
30 | 21 | #include "helpers.h" |
---|
31 | 22 | #include "venc.h" |
---|
| 23 | +#include "pm_helpers.h" |
---|
32 | 24 | |
---|
33 | 25 | #define NUM_B_FRAMES_MAX 4 |
---|
34 | 26 | |
---|
.. | .. |
---|
121 | 113 | static int venc_v4l2_to_hfi(int id, int value) |
---|
122 | 114 | { |
---|
123 | 115 | switch (id) { |
---|
124 | | - case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: |
---|
125 | | - switch (value) { |
---|
126 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: |
---|
127 | | - default: |
---|
128 | | - return HFI_MPEG4_LEVEL_0; |
---|
129 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: |
---|
130 | | - return HFI_MPEG4_LEVEL_0b; |
---|
131 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: |
---|
132 | | - return HFI_MPEG4_LEVEL_1; |
---|
133 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: |
---|
134 | | - return HFI_MPEG4_LEVEL_2; |
---|
135 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: |
---|
136 | | - return HFI_MPEG4_LEVEL_3; |
---|
137 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: |
---|
138 | | - return HFI_MPEG4_LEVEL_4; |
---|
139 | | - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: |
---|
140 | | - return HFI_MPEG4_LEVEL_5; |
---|
141 | | - } |
---|
142 | | - case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: |
---|
143 | | - switch (value) { |
---|
144 | | - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: |
---|
145 | | - default: |
---|
146 | | - return HFI_MPEG4_PROFILE_SIMPLE; |
---|
147 | | - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: |
---|
148 | | - return HFI_MPEG4_PROFILE_ADVANCEDSIMPLE; |
---|
149 | | - } |
---|
150 | | - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: |
---|
151 | | - switch (value) { |
---|
152 | | - case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: |
---|
153 | | - return HFI_H264_PROFILE_BASELINE; |
---|
154 | | - case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: |
---|
155 | | - return HFI_H264_PROFILE_CONSTRAINED_BASE; |
---|
156 | | - case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: |
---|
157 | | - return HFI_H264_PROFILE_MAIN; |
---|
158 | | - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: |
---|
159 | | - default: |
---|
160 | | - return HFI_H264_PROFILE_HIGH; |
---|
161 | | - } |
---|
162 | | - case V4L2_CID_MPEG_VIDEO_H264_LEVEL: |
---|
163 | | - switch (value) { |
---|
164 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: |
---|
165 | | - return HFI_H264_LEVEL_1; |
---|
166 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_1B: |
---|
167 | | - return HFI_H264_LEVEL_1b; |
---|
168 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: |
---|
169 | | - return HFI_H264_LEVEL_11; |
---|
170 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: |
---|
171 | | - return HFI_H264_LEVEL_12; |
---|
172 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: |
---|
173 | | - return HFI_H264_LEVEL_13; |
---|
174 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: |
---|
175 | | - return HFI_H264_LEVEL_2; |
---|
176 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: |
---|
177 | | - return HFI_H264_LEVEL_21; |
---|
178 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: |
---|
179 | | - return HFI_H264_LEVEL_22; |
---|
180 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: |
---|
181 | | - return HFI_H264_LEVEL_3; |
---|
182 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: |
---|
183 | | - return HFI_H264_LEVEL_31; |
---|
184 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: |
---|
185 | | - return HFI_H264_LEVEL_32; |
---|
186 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: |
---|
187 | | - return HFI_H264_LEVEL_4; |
---|
188 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: |
---|
189 | | - return HFI_H264_LEVEL_41; |
---|
190 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: |
---|
191 | | - return HFI_H264_LEVEL_42; |
---|
192 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: |
---|
193 | | - default: |
---|
194 | | - return HFI_H264_LEVEL_5; |
---|
195 | | - case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: |
---|
196 | | - return HFI_H264_LEVEL_51; |
---|
197 | | - } |
---|
198 | 116 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: |
---|
199 | 117 | switch (value) { |
---|
200 | 118 | case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC: |
---|
.. | .. |
---|
202 | 120 | return HFI_H264_ENTROPY_CAVLC; |
---|
203 | 121 | case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC: |
---|
204 | 122 | return HFI_H264_ENTROPY_CABAC; |
---|
205 | | - } |
---|
206 | | - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: |
---|
207 | | - switch (value) { |
---|
208 | | - case 0: |
---|
209 | | - default: |
---|
210 | | - return HFI_VPX_PROFILE_VERSION_0; |
---|
211 | | - case 1: |
---|
212 | | - return HFI_VPX_PROFILE_VERSION_1; |
---|
213 | | - case 2: |
---|
214 | | - return HFI_VPX_PROFILE_VERSION_2; |
---|
215 | | - case 3: |
---|
216 | | - return HFI_VPX_PROFILE_VERSION_3; |
---|
217 | 123 | } |
---|
218 | 124 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: |
---|
219 | 125 | switch (value) { |
---|
.. | .. |
---|
225 | 131 | case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: |
---|
226 | 132 | return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY; |
---|
227 | 133 | } |
---|
228 | | - case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: |
---|
229 | | - switch (value) { |
---|
230 | | - case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: |
---|
231 | | - default: |
---|
232 | | - return HFI_HEVC_PROFILE_MAIN; |
---|
233 | | - case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: |
---|
234 | | - return HFI_HEVC_PROFILE_MAIN_STILL_PIC; |
---|
235 | | - case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10: |
---|
236 | | - return HFI_HEVC_PROFILE_MAIN10; |
---|
237 | | - } |
---|
238 | | - case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: |
---|
239 | | - switch (value) { |
---|
240 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_1: |
---|
241 | | - default: |
---|
242 | | - return HFI_HEVC_LEVEL_1; |
---|
243 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_2: |
---|
244 | | - return HFI_HEVC_LEVEL_2; |
---|
245 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1: |
---|
246 | | - return HFI_HEVC_LEVEL_21; |
---|
247 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_3: |
---|
248 | | - return HFI_HEVC_LEVEL_3; |
---|
249 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1: |
---|
250 | | - return HFI_HEVC_LEVEL_31; |
---|
251 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_4: |
---|
252 | | - return HFI_HEVC_LEVEL_4; |
---|
253 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1: |
---|
254 | | - return HFI_HEVC_LEVEL_41; |
---|
255 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_5: |
---|
256 | | - return HFI_HEVC_LEVEL_5; |
---|
257 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1: |
---|
258 | | - return HFI_HEVC_LEVEL_51; |
---|
259 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2: |
---|
260 | | - return HFI_HEVC_LEVEL_52; |
---|
261 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_6: |
---|
262 | | - return HFI_HEVC_LEVEL_6; |
---|
263 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1: |
---|
264 | | - return HFI_HEVC_LEVEL_61; |
---|
265 | | - case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2: |
---|
266 | | - return HFI_HEVC_LEVEL_62; |
---|
267 | | - } |
---|
268 | 134 | } |
---|
269 | 135 | |
---|
270 | 136 | return 0; |
---|
.. | .. |
---|
273 | 139 | static int |
---|
274 | 140 | venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) |
---|
275 | 141 | { |
---|
276 | | - strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver)); |
---|
277 | | - strlcpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card)); |
---|
278 | | - strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); |
---|
| 142 | + strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); |
---|
| 143 | + strscpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card)); |
---|
| 144 | + strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); |
---|
279 | 145 | |
---|
280 | 146 | return 0; |
---|
281 | 147 | } |
---|
.. | .. |
---|
303 | 169 | struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; |
---|
304 | 170 | struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; |
---|
305 | 171 | const struct venus_format *fmt; |
---|
| 172 | + u32 sizeimage; |
---|
306 | 173 | |
---|
307 | 174 | memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); |
---|
308 | 175 | memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); |
---|
.. | .. |
---|
336 | 203 | pixmp->num_planes = fmt->num_planes; |
---|
337 | 204 | pixmp->flags = 0; |
---|
338 | 205 | |
---|
339 | | - pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat, |
---|
340 | | - pixmp->width, |
---|
341 | | - pixmp->height); |
---|
| 206 | + sizeimage = venus_helper_get_framesz(pixmp->pixelformat, |
---|
| 207 | + pixmp->width, |
---|
| 208 | + pixmp->height); |
---|
| 209 | + pfmt[0].sizeimage = max(ALIGN(pfmt[0].sizeimage, SZ_4K), sizeimage); |
---|
342 | 210 | |
---|
343 | 211 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
---|
344 | 212 | pfmt[0].bytesperline = ALIGN(pixmp->width, 128); |
---|
.. | .. |
---|
365 | 233 | const struct venus_format *fmt; |
---|
366 | 234 | struct v4l2_format format; |
---|
367 | 235 | u32 pixfmt_out = 0, pixfmt_cap = 0; |
---|
| 236 | + struct vb2_queue *q; |
---|
| 237 | + |
---|
| 238 | + q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); |
---|
| 239 | + if (!q) |
---|
| 240 | + return -EINVAL; |
---|
| 241 | + |
---|
| 242 | + if (vb2_is_busy(q)) |
---|
| 243 | + return -EBUSY; |
---|
368 | 244 | |
---|
369 | 245 | orig_pixmp = *pixmp; |
---|
370 | 246 | |
---|
.. | .. |
---|
410 | 286 | |
---|
411 | 287 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
---|
412 | 288 | inst->fmt_out = fmt; |
---|
413 | | - else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
---|
| 289 | + else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
---|
414 | 290 | inst->fmt_cap = fmt; |
---|
| 291 | + inst->output_buf_size = pixmp->plane_fmt[0].sizeimage; |
---|
| 292 | + } |
---|
415 | 293 | |
---|
416 | 294 | return 0; |
---|
417 | 295 | } |
---|
.. | .. |
---|
582 | 460 | { |
---|
583 | 461 | struct venus_inst *inst = to_inst(file); |
---|
584 | 462 | const struct venus_format *fmt; |
---|
| 463 | + unsigned int framerate_factor = 1; |
---|
585 | 464 | |
---|
586 | 465 | fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; |
---|
587 | 466 | |
---|
.. | .. |
---|
606 | 485 | fival->height < frame_height_min(inst)) |
---|
607 | 486 | return -EINVAL; |
---|
608 | 487 | |
---|
| 488 | + if (IS_V1(inst->core)) { |
---|
| 489 | + /* framerate is reported in 1/65535 fps unit */ |
---|
| 490 | + framerate_factor = (1 << 16); |
---|
| 491 | + } |
---|
| 492 | + |
---|
609 | 493 | fival->stepwise.min.numerator = 1; |
---|
610 | | - fival->stepwise.min.denominator = frate_max(inst); |
---|
| 494 | + fival->stepwise.min.denominator = frate_max(inst) / framerate_factor; |
---|
611 | 495 | fival->stepwise.max.numerator = 1; |
---|
612 | | - fival->stepwise.max.denominator = frate_min(inst); |
---|
| 496 | + fival->stepwise.max.denominator = frate_min(inst) / framerate_factor; |
---|
613 | 497 | fival->stepwise.step.numerator = 1; |
---|
614 | | - fival->stepwise.step.denominator = frate_max(inst); |
---|
| 498 | + fival->stepwise.step.denominator = frate_max(inst) / framerate_factor; |
---|
615 | 499 | |
---|
616 | 500 | return 0; |
---|
617 | 501 | } |
---|
618 | 502 | |
---|
619 | 503 | static const struct v4l2_ioctl_ops venc_ioctl_ops = { |
---|
620 | 504 | .vidioc_querycap = venc_querycap, |
---|
621 | | - .vidioc_enum_fmt_vid_cap_mplane = venc_enum_fmt, |
---|
622 | | - .vidioc_enum_fmt_vid_out_mplane = venc_enum_fmt, |
---|
| 505 | + .vidioc_enum_fmt_vid_cap = venc_enum_fmt, |
---|
| 506 | + .vidioc_enum_fmt_vid_out = venc_enum_fmt, |
---|
623 | 507 | .vidioc_s_fmt_vid_cap_mplane = venc_s_fmt, |
---|
624 | 508 | .vidioc_s_fmt_vid_out_mplane = venc_s_fmt, |
---|
625 | 509 | .vidioc_g_fmt_vid_cap_mplane = venc_g_fmt, |
---|
.. | .. |
---|
649 | 533 | { |
---|
650 | 534 | struct venc_controls *ctr = &inst->controls.enc; |
---|
651 | 535 | struct hfi_intra_period intra_period; |
---|
652 | | - struct hfi_profile_level pl; |
---|
653 | 536 | struct hfi_framerate frate; |
---|
654 | 537 | struct hfi_bitrate brate; |
---|
655 | 538 | struct hfi_idr_period idrp; |
---|
656 | | - u32 ptype, rate_control, bitrate, profile = 0, level = 0; |
---|
| 539 | + struct hfi_quantization quant; |
---|
| 540 | + struct hfi_quantization_range quant_range; |
---|
| 541 | + u32 ptype, rate_control, bitrate; |
---|
| 542 | + u32 profile, level; |
---|
657 | 543 | int ret; |
---|
658 | 544 | |
---|
659 | 545 | ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); |
---|
660 | | - if (ret) |
---|
661 | | - return ret; |
---|
662 | | - |
---|
663 | | - ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2); |
---|
664 | 546 | if (ret) |
---|
665 | 547 | return ret; |
---|
666 | 548 | |
---|
.. | .. |
---|
736 | 618 | if (ret) |
---|
737 | 619 | return ret; |
---|
738 | 620 | |
---|
739 | | - if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
---|
740 | | - rate_control = HFI_RATE_CONTROL_VBR_CFR; |
---|
741 | | - else |
---|
742 | | - rate_control = HFI_RATE_CONTROL_CBR_CFR; |
---|
| 621 | + if (!ctr->rc_enable) |
---|
| 622 | + rate_control = HFI_RATE_CONTROL_OFF; |
---|
| 623 | + else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
---|
| 624 | + rate_control = ctr->frame_skip_mode ? HFI_RATE_CONTROL_VBR_VFR : |
---|
| 625 | + HFI_RATE_CONTROL_VBR_CFR; |
---|
| 626 | + else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) |
---|
| 627 | + rate_control = ctr->frame_skip_mode ? HFI_RATE_CONTROL_CBR_VFR : |
---|
| 628 | + HFI_RATE_CONTROL_CBR_CFR; |
---|
| 629 | + else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) |
---|
| 630 | + rate_control = HFI_RATE_CONTROL_CQ; |
---|
743 | 631 | |
---|
744 | 632 | ptype = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL; |
---|
745 | 633 | ret = hfi_session_set_property(inst, ptype, &rate_control); |
---|
746 | 634 | if (ret) |
---|
747 | 635 | return ret; |
---|
| 636 | + |
---|
| 637 | + if (rate_control == HFI_RATE_CONTROL_CQ && ctr->const_quality) { |
---|
| 638 | + struct hfi_heic_frame_quality quality = {}; |
---|
| 639 | + |
---|
| 640 | + ptype = HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY; |
---|
| 641 | + quality.frame_quality = ctr->const_quality; |
---|
| 642 | + ret = hfi_session_set_property(inst, ptype, &quality); |
---|
| 643 | + if (ret) |
---|
| 644 | + return ret; |
---|
| 645 | + } |
---|
748 | 646 | |
---|
749 | 647 | if (!ctr->bitrate) |
---|
750 | 648 | bitrate = 64000; |
---|
.. | .. |
---|
772 | 670 | if (ret) |
---|
773 | 671 | return ret; |
---|
774 | 672 | |
---|
775 | | - if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) { |
---|
776 | | - profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_PROFILE, |
---|
777 | | - ctr->profile.h264); |
---|
778 | | - level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_LEVEL, |
---|
779 | | - ctr->level.h264); |
---|
780 | | - } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { |
---|
781 | | - profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_VP8_PROFILE, |
---|
782 | | - ctr->profile.vpx); |
---|
| 673 | + ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP; |
---|
| 674 | + quant.qp_i = ctr->h264_i_qp; |
---|
| 675 | + quant.qp_p = ctr->h264_p_qp; |
---|
| 676 | + quant.qp_b = ctr->h264_b_qp; |
---|
| 677 | + quant.layer_id = 0; |
---|
| 678 | + ret = hfi_session_set_property(inst, ptype, &quant); |
---|
| 679 | + if (ret) |
---|
| 680 | + return ret; |
---|
| 681 | + |
---|
| 682 | + ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE; |
---|
| 683 | + quant_range.min_qp = ctr->h264_min_qp; |
---|
| 684 | + quant_range.max_qp = ctr->h264_max_qp; |
---|
| 685 | + quant_range.layer_id = 0; |
---|
| 686 | + ret = hfi_session_set_property(inst, ptype, &quant_range); |
---|
| 687 | + if (ret) |
---|
| 688 | + return ret; |
---|
| 689 | + |
---|
| 690 | + switch (inst->hfi_codec) { |
---|
| 691 | + case HFI_VIDEO_CODEC_H264: |
---|
| 692 | + profile = ctr->profile.h264; |
---|
| 693 | + level = ctr->level.h264; |
---|
| 694 | + break; |
---|
| 695 | + case HFI_VIDEO_CODEC_MPEG4: |
---|
| 696 | + profile = ctr->profile.mpeg4; |
---|
| 697 | + level = ctr->level.mpeg4; |
---|
| 698 | + break; |
---|
| 699 | + case HFI_VIDEO_CODEC_VP8: |
---|
| 700 | + profile = ctr->profile.vp8; |
---|
783 | 701 | level = 0; |
---|
784 | | - } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_MPEG4) { |
---|
785 | | - profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, |
---|
786 | | - ctr->profile.mpeg4); |
---|
787 | | - level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, |
---|
788 | | - ctr->level.mpeg4); |
---|
789 | | - } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H263) { |
---|
| 702 | + break; |
---|
| 703 | + case HFI_VIDEO_CODEC_VP9: |
---|
| 704 | + profile = ctr->profile.vp9; |
---|
| 705 | + level = ctr->level.vp9; |
---|
| 706 | + break; |
---|
| 707 | + case HFI_VIDEO_CODEC_HEVC: |
---|
| 708 | + profile = ctr->profile.hevc; |
---|
| 709 | + level = ctr->level.hevc; |
---|
| 710 | + break; |
---|
| 711 | + case HFI_VIDEO_CODEC_MPEG2: |
---|
| 712 | + default: |
---|
790 | 713 | profile = 0; |
---|
791 | 714 | level = 0; |
---|
792 | | - } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { |
---|
793 | | - profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, |
---|
794 | | - ctr->profile.hevc); |
---|
795 | | - level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, |
---|
796 | | - ctr->level.hevc); |
---|
| 715 | + break; |
---|
797 | 716 | } |
---|
798 | 717 | |
---|
799 | | - ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; |
---|
800 | | - pl.profile = profile; |
---|
801 | | - pl.level = level; |
---|
802 | | - |
---|
803 | | - ret = hfi_session_set_property(inst, ptype, &pl); |
---|
| 718 | + ret = venus_helper_set_profile_level(inst, profile, level); |
---|
804 | 719 | if (ret) |
---|
805 | 720 | return ret; |
---|
806 | 721 | |
---|
.. | .. |
---|
827 | 742 | goto deinit; |
---|
828 | 743 | |
---|
829 | 744 | ret = venus_helper_set_color_format(inst, inst->fmt_out->pixfmt); |
---|
| 745 | + if (ret) |
---|
| 746 | + goto deinit; |
---|
| 747 | + |
---|
| 748 | + ret = venus_helper_init_codec_freq_data(inst); |
---|
830 | 749 | if (ret) |
---|
831 | 750 | goto deinit; |
---|
832 | 751 | |
---|
.. | .. |
---|
910 | 829 | sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, |
---|
911 | 830 | inst->width, |
---|
912 | 831 | inst->height); |
---|
| 832 | + sizes[0] = max(sizes[0], inst->output_buf_size); |
---|
913 | 833 | inst->output_buf_size = sizes[0]; |
---|
914 | 834 | break; |
---|
915 | 835 | default: |
---|
.. | .. |
---|
974 | 894 | if (ret) |
---|
975 | 895 | goto bufs_done; |
---|
976 | 896 | |
---|
| 897 | + ret = venus_pm_acquire_core(inst); |
---|
| 898 | + if (ret) |
---|
| 899 | + goto deinit_sess; |
---|
| 900 | + |
---|
977 | 901 | ret = venc_set_properties(inst); |
---|
978 | 902 | if (ret) |
---|
979 | 903 | goto deinit_sess; |
---|
.. | .. |
---|
998 | 922 | deinit_sess: |
---|
999 | 923 | hfi_session_deinit(inst); |
---|
1000 | 924 | bufs_done: |
---|
1001 | | - venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED); |
---|
| 925 | + venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED); |
---|
1002 | 926 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
---|
1003 | 927 | inst->streamon_out = 0; |
---|
1004 | 928 | else |
---|
.. | .. |
---|
1076 | 1000 | int ret; |
---|
1077 | 1001 | |
---|
1078 | 1002 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
---|
1079 | | - src_vq->io_modes = VB2_MMAP | VB2_DMABUF; |
---|
| 1003 | + src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; |
---|
1080 | 1004 | src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
---|
1081 | 1005 | src_vq->ops = &venc_vb2_ops; |
---|
1082 | 1006 | src_vq->mem_ops = &vb2_dma_sg_memops; |
---|
.. | .. |
---|
1092 | 1016 | return ret; |
---|
1093 | 1017 | |
---|
1094 | 1018 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
---|
1095 | | - dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; |
---|
| 1019 | + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; |
---|
1096 | 1020 | dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
---|
1097 | 1021 | dst_vq->ops = &venc_vb2_ops; |
---|
1098 | 1022 | dst_vq->mem_ops = &vb2_dma_sg_memops; |
---|
.. | .. |
---|
1101 | 1025 | dst_vq->allow_zero_bytesused = 1; |
---|
1102 | 1026 | dst_vq->min_buffers_needed = 1; |
---|
1103 | 1027 | dst_vq->dev = inst->core->dev; |
---|
1104 | | - ret = vb2_queue_init(dst_vq); |
---|
1105 | | - if (ret) { |
---|
1106 | | - vb2_queue_release(src_vq); |
---|
1107 | | - return ret; |
---|
1108 | | - } |
---|
1109 | | - |
---|
1110 | | - return 0; |
---|
| 1028 | + return vb2_queue_init(dst_vq); |
---|
1111 | 1029 | } |
---|
1112 | 1030 | |
---|
1113 | 1031 | static void venc_inst_init(struct venus_inst *inst) |
---|
.. | .. |
---|
1142 | 1060 | |
---|
1143 | 1061 | inst->core = core; |
---|
1144 | 1062 | inst->session_type = VIDC_SESSION_TYPE_ENC; |
---|
| 1063 | + inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; |
---|
| 1064 | + inst->core_acquired = false; |
---|
1145 | 1065 | |
---|
1146 | 1066 | venus_helper_init_instance(inst); |
---|
1147 | 1067 | |
---|
1148 | 1068 | ret = pm_runtime_get_sync(core->dev_enc); |
---|
1149 | 1069 | if (ret < 0) |
---|
1150 | | - goto err_free_inst; |
---|
| 1070 | + goto err_put_sync; |
---|
1151 | 1071 | |
---|
1152 | 1072 | ret = venc_ctrl_init(inst); |
---|
1153 | 1073 | if (ret) |
---|
.. | .. |
---|
1192 | 1112 | venc_ctrl_deinit(inst); |
---|
1193 | 1113 | err_put_sync: |
---|
1194 | 1114 | pm_runtime_put_sync(core->dev_enc); |
---|
1195 | | -err_free_inst: |
---|
1196 | 1115 | kfree(inst); |
---|
1197 | 1116 | return ret; |
---|
1198 | 1117 | } |
---|
.. | .. |
---|
1238 | 1157 | if (!core) |
---|
1239 | 1158 | return -EPROBE_DEFER; |
---|
1240 | 1159 | |
---|
1241 | | - if (IS_V3(core) || IS_V4(core)) { |
---|
1242 | | - core->core1_clk = devm_clk_get(dev, "core"); |
---|
1243 | | - if (IS_ERR(core->core1_clk)) |
---|
1244 | | - return PTR_ERR(core->core1_clk); |
---|
1245 | | - } |
---|
1246 | | - |
---|
1247 | | - if (IS_V4(core)) { |
---|
1248 | | - core->core1_bus_clk = devm_clk_get(dev, "bus"); |
---|
1249 | | - if (IS_ERR(core->core1_bus_clk)) |
---|
1250 | | - return PTR_ERR(core->core1_bus_clk); |
---|
1251 | | - } |
---|
1252 | | - |
---|
1253 | 1160 | platform_set_drvdata(pdev, core); |
---|
| 1161 | + |
---|
| 1162 | + if (core->pm_ops->venc_get) { |
---|
| 1163 | + ret = core->pm_ops->venc_get(dev); |
---|
| 1164 | + if (ret) |
---|
| 1165 | + return ret; |
---|
| 1166 | + } |
---|
1254 | 1167 | |
---|
1255 | 1168 | vdev = video_device_alloc(); |
---|
1256 | 1169 | if (!vdev) |
---|
1257 | 1170 | return -ENOMEM; |
---|
1258 | 1171 | |
---|
1259 | | - strlcpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); |
---|
| 1172 | + strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); |
---|
1260 | 1173 | vdev->release = video_device_release; |
---|
1261 | 1174 | vdev->fops = &venc_fops; |
---|
1262 | 1175 | vdev->ioctl_ops = &venc_ioctl_ops; |
---|
.. | .. |
---|
1264 | 1177 | vdev->v4l2_dev = &core->v4l2_dev; |
---|
1265 | 1178 | vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
---|
1266 | 1179 | |
---|
1267 | | - ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); |
---|
| 1180 | + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); |
---|
1268 | 1181 | if (ret) |
---|
1269 | 1182 | goto err_vdev_release; |
---|
1270 | 1183 | |
---|
.. | .. |
---|
1288 | 1201 | video_unregister_device(core->vdev_enc); |
---|
1289 | 1202 | pm_runtime_disable(core->dev_enc); |
---|
1290 | 1203 | |
---|
| 1204 | + if (core->pm_ops->venc_put) |
---|
| 1205 | + core->pm_ops->venc_put(core->dev_enc); |
---|
| 1206 | + |
---|
1291 | 1207 | return 0; |
---|
1292 | 1208 | } |
---|
1293 | 1209 | |
---|
1294 | 1210 | static __maybe_unused int venc_runtime_suspend(struct device *dev) |
---|
1295 | 1211 | { |
---|
1296 | 1212 | struct venus_core *core = dev_get_drvdata(dev); |
---|
1297 | | - int ret; |
---|
| 1213 | + const struct venus_pm_ops *pm_ops = core->pm_ops; |
---|
| 1214 | + int ret = 0; |
---|
1298 | 1215 | |
---|
1299 | | - if (IS_V1(core)) |
---|
1300 | | - return 0; |
---|
| 1216 | + if (pm_ops->venc_power) |
---|
| 1217 | + ret = pm_ops->venc_power(dev, POWER_OFF); |
---|
1301 | 1218 | |
---|
1302 | | - ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); |
---|
1303 | | - if (ret) |
---|
1304 | | - return ret; |
---|
1305 | | - |
---|
1306 | | - if (IS_V4(core)) |
---|
1307 | | - clk_disable_unprepare(core->core1_bus_clk); |
---|
1308 | | - |
---|
1309 | | - clk_disable_unprepare(core->core1_clk); |
---|
1310 | | - |
---|
1311 | | - return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); |
---|
| 1219 | + return ret; |
---|
1312 | 1220 | } |
---|
1313 | 1221 | |
---|
1314 | 1222 | static __maybe_unused int venc_runtime_resume(struct device *dev) |
---|
1315 | 1223 | { |
---|
1316 | 1224 | struct venus_core *core = dev_get_drvdata(dev); |
---|
1317 | | - int ret; |
---|
| 1225 | + const struct venus_pm_ops *pm_ops = core->pm_ops; |
---|
| 1226 | + int ret = 0; |
---|
1318 | 1227 | |
---|
1319 | | - if (IS_V1(core)) |
---|
1320 | | - return 0; |
---|
| 1228 | + if (pm_ops->venc_power) |
---|
| 1229 | + ret = pm_ops->venc_power(dev, POWER_ON); |
---|
1321 | 1230 | |
---|
1322 | | - ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); |
---|
1323 | | - if (ret) |
---|
1324 | | - return ret; |
---|
1325 | | - |
---|
1326 | | - ret = clk_prepare_enable(core->core1_clk); |
---|
1327 | | - if (ret) |
---|
1328 | | - goto err_power_disable; |
---|
1329 | | - |
---|
1330 | | - if (IS_V4(core)) |
---|
1331 | | - ret = clk_prepare_enable(core->core1_bus_clk); |
---|
1332 | | - |
---|
1333 | | - if (ret) |
---|
1334 | | - goto err_unprepare_core1; |
---|
1335 | | - |
---|
1336 | | - return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); |
---|
1337 | | - |
---|
1338 | | -err_unprepare_core1: |
---|
1339 | | - clk_disable_unprepare(core->core1_clk); |
---|
1340 | | -err_power_disable: |
---|
1341 | | - venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); |
---|
1342 | 1231 | return ret; |
---|
1343 | 1232 | } |
---|
1344 | 1233 | |
---|