hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/platform/qcom/venus/vdec.c
....@@ -495,6 +495,7 @@
495495 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
496496 {
497497 struct venus_inst *inst = to_inst(file);
498
+ struct vb2_queue *dst_vq;
498499 struct hfi_frame_data fdata = {0};
499500 int ret;
500501
....@@ -518,8 +519,17 @@
518519
519520 ret = hfi_session_process_buf(inst, &fdata);
520521
521
- if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING)
522
+ if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) {
522523 inst->codec_state = VENUS_DEC_STATE_DRAIN;
524
+ inst->drain_active = true;
525
+ }
526
+ } else if (cmd->cmd == V4L2_DEC_CMD_START &&
527
+ inst->codec_state == VENUS_DEC_STATE_STOPPED) {
528
+ dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx,
529
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
530
+ vb2_clear_last_buffer_dequeued(dst_vq);
531
+
532
+ inst->codec_state = VENUS_DEC_STATE_DECODING;
523533 }
524534
525535 unlock:
....@@ -636,6 +646,7 @@
636646 {
637647 struct venus_core *core = inst->core;
638648 struct hfi_enable en = { .enable = 1 };
649
+ struct hfi_buffer_requirements bufreq;
639650 u32 width = inst->out_width;
640651 u32 height = inst->out_height;
641652 u32 out_fmt, out2_fmt;
....@@ -711,6 +722,23 @@
711722 }
712723
713724 if (IS_V3(core) || IS_V4(core)) {
725
+ ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
726
+ if (ret)
727
+ return ret;
728
+
729
+ if (bufreq.size > inst->output_buf_size)
730
+ return -EINVAL;
731
+
732
+ if (inst->dpb_fmt) {
733
+ ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT2,
734
+ &bufreq);
735
+ if (ret)
736
+ return ret;
737
+
738
+ if (bufreq.size > inst->output2_buf_size)
739
+ return -EINVAL;
740
+ }
741
+
714742 if (inst->output2_buf_size) {
715743 ret = venus_helper_set_bufsize(inst,
716744 inst->output2_buf_size,
....@@ -916,10 +944,6 @@
916944 return 0;
917945
918946 reconfigure:
919
- ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true);
920
- if (ret)
921
- return ret;
922
-
923947 ret = vdec_output_conf(inst);
924948 if (ret)
925949 return ret;
....@@ -947,15 +971,21 @@
947971
948972 venus_pm_load_scale(inst);
949973
974
+ inst->next_buf_last = false;
975
+
950976 ret = hfi_session_continue(inst);
951977 if (ret)
952978 goto free_dpb_bufs;
953979
954980 inst->codec_state = VENUS_DEC_STATE_DECODING;
955981
982
+ if (inst->drain_active)
983
+ inst->codec_state = VENUS_DEC_STATE_DRAIN;
984
+
956985 inst->streamon_cap = 1;
957986 inst->sequence_cap = 0;
958987 inst->reconfig = false;
988
+ inst->drain_active = false;
959989
960990 return 0;
961991
....@@ -971,7 +1001,10 @@
9711001
9721002 if (inst->codec_state == VENUS_DEC_STATE_SEEK) {
9731003 ret = venus_helper_process_initial_out_bufs(inst);
974
- inst->codec_state = VENUS_DEC_STATE_DECODING;
1004
+ if (inst->next_buf_last)
1005
+ inst->codec_state = VENUS_DEC_STATE_DRC;
1006
+ else
1007
+ inst->codec_state = VENUS_DEC_STATE_DECODING;
9751008 goto done;
9761009 }
9771010
....@@ -987,6 +1020,7 @@
9871020 venus_helper_init_instance(inst);
9881021 inst->sequence_out = 0;
9891022 inst->reconfig = false;
1023
+ inst->next_buf_last = false;
9901024
9911025 ret = vdec_set_properties(inst);
9921026 if (ret)
....@@ -1076,13 +1110,14 @@
10761110 ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
10771111 fallthrough;
10781112 case VENUS_DEC_STATE_DRAIN:
1079
- vdec_cancel_dst_buffers(inst);
10801113 inst->codec_state = VENUS_DEC_STATE_STOPPED;
1114
+ inst->drain_active = false;
1115
+ fallthrough;
1116
+ case VENUS_DEC_STATE_SEEK:
1117
+ vdec_cancel_dst_buffers(inst);
10811118 break;
10821119 case VENUS_DEC_STATE_DRC:
1083
- WARN_ON(1);
1084
- fallthrough;
1085
- case VENUS_DEC_STATE_DRC_FLUSH_DONE:
1120
+ ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true);
10861121 inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
10871122 venus_helper_free_dpb_bufs(inst);
10881123 break;
....@@ -1101,6 +1136,7 @@
11011136 case VENUS_DEC_STATE_DECODING:
11021137 case VENUS_DEC_STATE_DRAIN:
11031138 case VENUS_DEC_STATE_STOPPED:
1139
+ case VENUS_DEC_STATE_DRC:
11041140 ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
11051141 inst->codec_state = VENUS_DEC_STATE_SEEK;
11061142 break;
....@@ -1206,8 +1242,27 @@
12061242 static void vdec_vb2_buf_queue(struct vb2_buffer *vb)
12071243 {
12081244 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1245
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1246
+ static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS };
12091247
12101248 vdec_pm_get_put(inst);
1249
+
1250
+ mutex_lock(&inst->lock);
1251
+
1252
+ if (inst->next_buf_last && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1253
+ inst->codec_state == VENUS_DEC_STATE_DRC) {
1254
+ vbuf->flags |= V4L2_BUF_FLAG_LAST;
1255
+ vbuf->sequence = inst->sequence_cap++;
1256
+ vbuf->field = V4L2_FIELD_NONE;
1257
+ vb2_set_plane_payload(vb, 0, 0);
1258
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
1259
+ v4l2_event_queue_fh(&inst->fh, &eos);
1260
+ inst->next_buf_last = false;
1261
+ mutex_unlock(&inst->lock);
1262
+ return;
1263
+ }
1264
+
1265
+ mutex_unlock(&inst->lock);
12111266
12121267 venus_helper_vb2_buf_queue(vb);
12131268 }
....@@ -1252,20 +1307,15 @@
12521307 vb->timestamp = timestamp_us * NSEC_PER_USEC;
12531308 vbuf->sequence = inst->sequence_cap++;
12541309
1255
- if (inst->last_buf == vb) {
1256
- inst->last_buf = NULL;
1257
- vbuf->flags |= V4L2_BUF_FLAG_LAST;
1258
- vb2_set_plane_payload(vb, 0, 0);
1259
- vb->timestamp = 0;
1260
- }
1261
-
12621310 if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
12631311 const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
12641312
12651313 v4l2_event_queue_fh(&inst->fh, &ev);
12661314
1267
- if (inst->codec_state == VENUS_DEC_STATE_DRAIN)
1315
+ if (inst->codec_state == VENUS_DEC_STATE_DRAIN) {
1316
+ inst->drain_active = false;
12681317 inst->codec_state = VENUS_DEC_STATE_STOPPED;
1318
+ }
12691319 }
12701320
12711321 if (!bytesused)
....@@ -1321,19 +1371,16 @@
13211371 dev_dbg(dev, VDBGM "event %s sufficient resources (%ux%u)\n",
13221372 sufficient ? "" : "not", ev_data->width, ev_data->height);
13231373
1324
- if (sufficient) {
1325
- hfi_session_continue(inst);
1326
- } else {
1327
- switch (inst->codec_state) {
1328
- case VENUS_DEC_STATE_INIT:
1329
- inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
1330
- break;
1331
- case VENUS_DEC_STATE_DECODING:
1332
- inst->codec_state = VENUS_DEC_STATE_DRC;
1333
- break;
1334
- default:
1335
- break;
1336
- }
1374
+ switch (inst->codec_state) {
1375
+ case VENUS_DEC_STATE_INIT:
1376
+ inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
1377
+ break;
1378
+ case VENUS_DEC_STATE_DECODING:
1379
+ case VENUS_DEC_STATE_DRAIN:
1380
+ inst->codec_state = VENUS_DEC_STATE_DRC;
1381
+ break;
1382
+ default:
1383
+ break;
13371384 }
13381385
13391386 /*
....@@ -1342,19 +1389,17 @@
13421389 * itself doesn't mark the last decoder output buffer with HFI EOS flag.
13431390 */
13441391
1345
- if (!sufficient && inst->codec_state == VENUS_DEC_STATE_DRC) {
1346
- struct vb2_v4l2_buffer *last;
1392
+ if (inst->codec_state == VENUS_DEC_STATE_DRC) {
13471393 int ret;
13481394
1349
- last = v4l2_m2m_last_dst_buf(inst->m2m_ctx);
1350
- if (last)
1351
- inst->last_buf = &last->vb2_buf;
1395
+ inst->next_buf_last = true;
13521396
13531397 ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, false);
13541398 if (ret)
13551399 dev_dbg(dev, VDBGH "flush output error %d\n", ret);
13561400 }
13571401
1402
+ inst->next_buf_last = true;
13581403 inst->reconfig = true;
13591404 v4l2_event_queue_fh(&inst->fh, &ev);
13601405 wake_up(&inst->reconf_wait);
....@@ -1397,8 +1442,7 @@
13971442
13981443 static void vdec_flush_done(struct venus_inst *inst)
13991444 {
1400
- if (inst->codec_state == VENUS_DEC_STATE_DRC)
1401
- inst->codec_state = VENUS_DEC_STATE_DRC_FLUSH_DONE;
1445
+ dev_dbg(inst->core->dev_dec, VDBGH "flush done\n");
14021446 }
14031447
14041448 static const struct hfi_inst_ops vdec_hfi_ops = {