Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: mediatek: vcodec: Fix h264 set lat buffer error

Will set lat buffer to lat_list two times when lat decode timeout for
inner racing mode.

If core thread can't get frame buffer, need to return error value.

Fixes: 59fba9eed5a7 ("media: mediatek: vcodec: support stateless H.264 decoding for mt8192")
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Yunfei Dong and committed by
Mauro Carvalho Chehab
23d677bd 3568ecd3

+17 -11
+17 -11
drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
··· 471 471 sizeof(share_info->h264_slice_params)); 472 472 473 473 fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); 474 - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; 475 - vdec_fb_va = (unsigned long)fb; 474 + if (!fb) { 475 + err = -EBUSY; 476 + mtk_vcodec_err(inst, "fb buffer is NULL"); 477 + goto vdec_dec_end; 478 + } 476 479 480 + vdec_fb_va = (unsigned long)fb; 481 + y_fb_dma = (u64)fb->base_y.dma_addr; 477 482 if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) 478 483 c_fb_dma = 479 484 y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h; 480 485 else 481 - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; 486 + c_fb_dma = (u64)fb->base_c.dma_addr; 482 487 483 488 mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, 484 489 c_fb_dma); ··· 661 656 err = vpu_dec_start(vpu, data, 2); 662 657 if (err) { 663 658 mtk_vcodec_debug(inst, "lat decode err: %d", err); 664 - goto err_scp_decode; 659 + goto err_free_fb_out; 665 660 } 666 661 667 662 share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr + ··· 678 673 /* wait decoder done interrupt */ 679 674 timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, 680 675 WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); 676 + if (timeout) 677 + mtk_vcodec_err(inst, "lat decode timeout: pic_%d", inst->slice_dec_num); 681 678 inst->vsi->dec.timeout = !!timeout; 682 679 683 680 err = vpu_dec_end(vpu); 684 - if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) { 685 - err = -EINVAL; 686 - goto err_scp_decode; 681 + if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) { 682 + if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) 683 + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); 684 + inst->slice_dec_num++; 685 + mtk_vcodec_err(inst, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err); 686 + return -EINVAL; 687 687 } 688 688 689 689 share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr + ··· 705 695 706 696 inst->slice_dec_num++; 707 697 return 0; 708 - 709 - err_scp_decode: 710 - if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) 711 - vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); 712 698 err_free_fb_out: 713 699 vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); 714 700 mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err);