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

media: mediatek: vcodec: using empty lat buffer as the last one

Adding one empty lat buffer with parameter 'is_empty_flag = true'
used to flush core work queue decode.

Queue the empty lat buffer to core list when driver need to flush decode.
It's mean core already decode all existed lat buffer when get empty lat
buffer, then wake up core decode done event, the driver will exit when
getting core dec done event.

Fixes: d227af847ac2 ("media: mediatek: vcodec: add core decode done event")
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
962508e3 297160d4

+28 -15
+20 -15
drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
··· 177 177 178 178 bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue) 179 179 { 180 - int ret; 181 - long timeout_jiff; 182 - 183 180 if (atomic_read(&msg_queue->lat_list_cnt) == NUM_BUFFER_COUNT) { 184 181 mtk_v4l2_debug(3, "wait buf full: list(%d %d) ready_num:%d status:%d", 185 182 atomic_read(&msg_queue->lat_list_cnt), ··· 186 189 return true; 187 190 } 188 191 189 - timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2)); 190 - ret = wait_event_timeout(msg_queue->core_dec_done, 191 - msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT, 192 - timeout_jiff); 193 - if (ret) { 194 - mtk_v4l2_debug(3, "success to get lat buf: %d", 195 - msg_queue->lat_ctx.ready_num); 196 - return true; 197 - } 192 + msg_queue->flush_done = false; 193 + vdec_msg_queue_qbuf(&msg_queue->core_ctx, &msg_queue->empty_lat_buf); 194 + wait_event(msg_queue->core_dec_done, msg_queue->flush_done); 198 195 199 - mtk_v4l2_err("failed with lat buf isn't full: list(%d %d)", 200 - atomic_read(&msg_queue->lat_list_cnt), 201 - atomic_read(&msg_queue->core_list_cnt)); 196 + mtk_v4l2_debug(3, "flush done => ready_num:%d status:%d list(%d %d)", 197 + msg_queue->lat_ctx.ready_num, msg_queue->status, 198 + atomic_read(&msg_queue->lat_list_cnt), 199 + atomic_read(&msg_queue->core_list_cnt)); 202 200 203 201 return false; 204 202 } ··· 241 249 lat_buf = vdec_msg_queue_dqbuf(&msg_queue->core_ctx); 242 250 if (!lat_buf) 243 251 return; 252 + 253 + if (lat_buf->is_last_frame) { 254 + ctx->msg_queue.status = CONTEXT_LIST_DEC_DONE; 255 + msg_queue->flush_done = true; 256 + wake_up(&ctx->msg_queue.core_dec_done); 257 + 258 + return; 259 + } 244 260 245 261 ctx = lat_buf->ctx; 246 262 mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE); ··· 300 300 msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr; 301 301 msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr; 302 302 303 + msg_queue->empty_lat_buf.ctx = ctx; 304 + msg_queue->empty_lat_buf.core_decode = NULL; 305 + msg_queue->empty_lat_buf.is_last_frame = true; 306 + 303 307 for (i = 0; i < NUM_BUFFER_COUNT; i++) { 304 308 lat_buf = &msg_queue->lat_buf[i]; 305 309 ··· 329 325 330 326 lat_buf->ctx = ctx; 331 327 lat_buf->core_decode = core_decode; 328 + lat_buf->is_last_frame = false; 332 329 err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf); 333 330 if (err) { 334 331 mtk_v4l2_err("failed to qbuf buf[%d]", i);
+8
drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h
··· 62 62 * @core_decode: different codec use different decode callback function 63 63 * @lat_list: add lat buffer to lat head list 64 64 * @core_list: add lat buffer to core head list 65 + * 66 + * @is_last_frame: meaning this buffer is the last frame 65 67 */ 66 68 struct vdec_lat_buf { 67 69 struct mtk_vcodec_mem wdma_err_addr; ··· 76 74 core_decode_cb_t core_decode; 77 75 struct list_head lat_list; 78 76 struct list_head core_list; 77 + 78 + bool is_last_frame; 79 79 }; 80 80 81 81 /** ··· 92 88 * 93 89 * @lat_list_cnt: used to record each instance lat list count 94 90 * @core_list_cnt: used to record each instance core list count 91 + * @flush_done: core flush done status 92 + * @empty_lat_buf: the last lat buf used to flush decode 95 93 * @core_dec_done: core work queue decode done event 96 94 * @status: current context decode status for core hardware 97 95 */ ··· 110 104 111 105 atomic_t lat_list_cnt; 112 106 atomic_t core_list_cnt; 107 + bool flush_done; 108 + struct vdec_lat_buf empty_lat_buf; 113 109 wait_queue_head_t core_dec_done; 114 110 int status; 115 111 };