.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2016 MediaTek Inc. |
---|
3 | 4 | * Author: PC Chen <pc.chen@mediatek.com> |
---|
4 | 5 | * Tiffany Lin <tiffany.lin@mediatek.com> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, |
---|
11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 | | - * GNU General Public License for more details. |
---|
14 | 6 | */ |
---|
15 | 7 | |
---|
16 | 8 | #include <media/v4l2-event.h> |
---|
.. | .. |
---|
32 | 24 | #define DFT_CFG_WIDTH MTK_VDEC_MIN_W |
---|
33 | 25 | #define DFT_CFG_HEIGHT MTK_VDEC_MIN_H |
---|
34 | 26 | |
---|
35 | | -static struct mtk_video_fmt mtk_video_formats[] = { |
---|
| 27 | +static const struct mtk_video_fmt mtk_video_formats[] = { |
---|
36 | 28 | { |
---|
37 | 29 | .fourcc = V4L2_PIX_FMT_H264, |
---|
38 | 30 | .type = MTK_FMT_DEC, |
---|
39 | 31 | .num_planes = 1, |
---|
| 32 | + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, |
---|
40 | 33 | }, |
---|
41 | 34 | { |
---|
42 | 35 | .fourcc = V4L2_PIX_FMT_VP8, |
---|
43 | 36 | .type = MTK_FMT_DEC, |
---|
44 | 37 | .num_planes = 1, |
---|
| 38 | + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, |
---|
45 | 39 | }, |
---|
46 | 40 | { |
---|
47 | 41 | .fourcc = V4L2_PIX_FMT_VP9, |
---|
48 | 42 | .type = MTK_FMT_DEC, |
---|
49 | 43 | .num_planes = 1, |
---|
| 44 | + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, |
---|
50 | 45 | }, |
---|
51 | 46 | { |
---|
52 | 47 | .fourcc = V4L2_PIX_FMT_MT21C, |
---|
.. | .. |
---|
76 | 71 | #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes) |
---|
77 | 72 | #define NUM_FORMATS ARRAY_SIZE(mtk_video_formats) |
---|
78 | 73 | |
---|
79 | | -static struct mtk_video_fmt *mtk_vdec_find_format(struct v4l2_format *f) |
---|
| 74 | +static const struct mtk_video_fmt *mtk_vdec_find_format(struct v4l2_format *f) |
---|
80 | 75 | { |
---|
81 | | - struct mtk_video_fmt *fmt; |
---|
| 76 | + const struct mtk_video_fmt *fmt; |
---|
82 | 77 | unsigned int k; |
---|
83 | 78 | |
---|
84 | 79 | for (k = 0; k < NUM_FORMATS; k++) { |
---|
.. | .. |
---|
109 | 104 | { |
---|
110 | 105 | struct vdec_fb *disp_frame_buffer = NULL; |
---|
111 | 106 | struct mtk_video_dec_buf *dstbuf; |
---|
| 107 | + struct vb2_v4l2_buffer *vb; |
---|
112 | 108 | |
---|
113 | 109 | mtk_v4l2_debug(3, "[%d]", ctx->id); |
---|
114 | 110 | if (vdec_if_get_param(ctx, |
---|
.. | .. |
---|
126 | 122 | |
---|
127 | 123 | dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf, |
---|
128 | 124 | frame_buffer); |
---|
| 125 | + vb = &dstbuf->m2m_buf.vb; |
---|
129 | 126 | mutex_lock(&ctx->lock); |
---|
130 | 127 | if (dstbuf->used) { |
---|
131 | | - vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, |
---|
132 | | - ctx->picinfo.y_bs_sz); |
---|
133 | | - vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, |
---|
134 | | - ctx->picinfo.c_bs_sz); |
---|
135 | | - |
---|
136 | | - dstbuf->ready_to_display = true; |
---|
| 128 | + vb2_set_plane_payload(&vb->vb2_buf, 0, |
---|
| 129 | + ctx->picinfo.fb_sz[0]); |
---|
| 130 | + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) |
---|
| 131 | + vb2_set_plane_payload(&vb->vb2_buf, 1, |
---|
| 132 | + ctx->picinfo.fb_sz[1]); |
---|
137 | 133 | |
---|
138 | 134 | mtk_v4l2_debug(2, |
---|
139 | 135 | "[%d]status=%x queue id=%d to done_list %d", |
---|
140 | 136 | ctx->id, disp_frame_buffer->status, |
---|
141 | | - dstbuf->vb.vb2_buf.index, |
---|
| 137 | + vb->vb2_buf.index, |
---|
142 | 138 | dstbuf->queued_in_vb2); |
---|
143 | 139 | |
---|
144 | | - v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE); |
---|
| 140 | + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE); |
---|
145 | 141 | ctx->decoded_frame_cnt++; |
---|
146 | 142 | } |
---|
147 | 143 | mutex_unlock(&ctx->lock); |
---|
148 | | - return &dstbuf->vb.vb2_buf; |
---|
| 144 | + return &vb->vb2_buf; |
---|
149 | 145 | } |
---|
150 | 146 | |
---|
151 | 147 | /* |
---|
.. | .. |
---|
160 | 156 | { |
---|
161 | 157 | struct mtk_video_dec_buf *dstbuf; |
---|
162 | 158 | struct vdec_fb *free_frame_buffer = NULL; |
---|
| 159 | + struct vb2_v4l2_buffer *vb; |
---|
163 | 160 | |
---|
164 | 161 | if (vdec_if_get_param(ctx, |
---|
165 | 162 | GET_PARAM_FREE_FRAME_BUFFER, |
---|
.. | .. |
---|
177 | 174 | |
---|
178 | 175 | dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf, |
---|
179 | 176 | frame_buffer); |
---|
| 177 | + vb = &dstbuf->m2m_buf.vb; |
---|
180 | 178 | |
---|
181 | 179 | mutex_lock(&ctx->lock); |
---|
182 | 180 | if (dstbuf->used) { |
---|
.. | .. |
---|
193 | 191 | mtk_v4l2_debug(2, |
---|
194 | 192 | "[%d]status=%x queue id=%d to rdy_queue %d", |
---|
195 | 193 | ctx->id, free_frame_buffer->status, |
---|
196 | | - dstbuf->vb.vb2_buf.index, |
---|
| 194 | + vb->vb2_buf.index, |
---|
197 | 195 | dstbuf->queued_in_vb2); |
---|
198 | | - v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb); |
---|
199 | | - } else if ((dstbuf->queued_in_vb2 == false) && |
---|
200 | | - (dstbuf->queued_in_v4l2 == true)) { |
---|
| 196 | + v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); |
---|
| 197 | + } else if (!dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2) { |
---|
201 | 198 | /* |
---|
202 | 199 | * If buffer in v4l2 driver but not in vb2 queue yet, |
---|
203 | 200 | * and we get this buffer from free_list, it means |
---|
.. | .. |
---|
211 | 208 | mtk_v4l2_debug(2, |
---|
212 | 209 | "[%d]status=%x queue id=%d to rdy_queue", |
---|
213 | 210 | ctx->id, free_frame_buffer->status, |
---|
214 | | - dstbuf->vb.vb2_buf.index); |
---|
215 | | - v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb); |
---|
| 211 | + vb->vb2_buf.index); |
---|
| 212 | + v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); |
---|
216 | 213 | dstbuf->queued_in_vb2 = true; |
---|
217 | 214 | } else { |
---|
218 | 215 | /* |
---|
.. | .. |
---|
225 | 222 | */ |
---|
226 | 223 | mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d", |
---|
227 | 224 | ctx->id, free_frame_buffer->status, |
---|
228 | | - dstbuf->vb.vb2_buf.index, |
---|
| 225 | + vb->vb2_buf.index, |
---|
229 | 226 | dstbuf->queued_in_vb2, |
---|
230 | 227 | dstbuf->queued_in_v4l2); |
---|
231 | 228 | } |
---|
232 | 229 | dstbuf->used = false; |
---|
233 | 230 | } |
---|
234 | 231 | mutex_unlock(&ctx->lock); |
---|
235 | | - return &dstbuf->vb.vb2_buf; |
---|
| 232 | + return &vb->vb2_buf; |
---|
236 | 233 | } |
---|
237 | 234 | |
---|
238 | 235 | static void clean_display_buffer(struct mtk_vcodec_ctx *ctx) |
---|
.. | .. |
---|
278 | 275 | clean_free_buffer(ctx); |
---|
279 | 276 | } |
---|
280 | 277 | |
---|
| 278 | +static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx, |
---|
| 279 | + unsigned int pixelformat) |
---|
| 280 | +{ |
---|
| 281 | + const struct mtk_video_fmt *fmt; |
---|
| 282 | + struct mtk_q_data *dst_q_data; |
---|
| 283 | + unsigned int k; |
---|
| 284 | + |
---|
| 285 | + dst_q_data = &ctx->q_data[MTK_Q_DATA_DST]; |
---|
| 286 | + for (k = 0; k < NUM_FORMATS; k++) { |
---|
| 287 | + fmt = &mtk_video_formats[k]; |
---|
| 288 | + if (fmt->fourcc == pixelformat) { |
---|
| 289 | + mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)", |
---|
| 290 | + dst_q_data->fmt->fourcc, pixelformat); |
---|
| 291 | + dst_q_data->fmt = fmt; |
---|
| 292 | + return; |
---|
| 293 | + } |
---|
| 294 | + } |
---|
| 295 | + |
---|
| 296 | + mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat); |
---|
| 297 | +} |
---|
| 298 | + |
---|
281 | 299 | static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) |
---|
282 | 300 | { |
---|
283 | 301 | unsigned int dpbsize = 0; |
---|
.. | .. |
---|
298 | 316 | mtk_v4l2_err("Cannot get correct pic info"); |
---|
299 | 317 | return -EINVAL; |
---|
300 | 318 | } |
---|
| 319 | + |
---|
| 320 | + if (ctx->last_decoded_picinfo.cap_fourcc != ctx->picinfo.cap_fourcc && |
---|
| 321 | + ctx->picinfo.cap_fourcc != 0) |
---|
| 322 | + mtk_vdec_update_fmt(ctx, ctx->picinfo.cap_fourcc); |
---|
301 | 323 | |
---|
302 | 324 | if ((ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w) || |
---|
303 | 325 | (ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h)) |
---|
.. | .. |
---|
325 | 347 | struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, |
---|
326 | 348 | decode_work); |
---|
327 | 349 | struct mtk_vcodec_dev *dev = ctx->dev; |
---|
328 | | - struct vb2_buffer *src_buf, *dst_buf; |
---|
| 350 | + struct vb2_v4l2_buffer *src_buf, *dst_buf; |
---|
329 | 351 | struct mtk_vcodec_mem buf; |
---|
330 | 352 | struct vdec_fb *pfb; |
---|
331 | 353 | bool res_chg = false; |
---|
332 | 354 | int ret; |
---|
333 | 355 | struct mtk_video_dec_buf *dst_buf_info, *src_buf_info; |
---|
334 | | - struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; |
---|
335 | 356 | |
---|
336 | 357 | src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); |
---|
337 | 358 | if (src_buf == NULL) { |
---|
.. | .. |
---|
347 | 368 | return; |
---|
348 | 369 | } |
---|
349 | 370 | |
---|
350 | | - src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf); |
---|
351 | | - src_buf_info = container_of(src_vb2_v4l2, struct mtk_video_dec_buf, vb); |
---|
352 | | - |
---|
353 | | - dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); |
---|
354 | | - dst_buf_info = container_of(dst_vb2_v4l2, struct mtk_video_dec_buf, vb); |
---|
| 371 | + src_buf_info = container_of(src_buf, struct mtk_video_dec_buf, |
---|
| 372 | + m2m_buf.vb); |
---|
| 373 | + dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf, |
---|
| 374 | + m2m_buf.vb); |
---|
355 | 375 | |
---|
356 | 376 | pfb = &dst_buf_info->frame_buffer; |
---|
357 | | - pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0); |
---|
358 | | - pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); |
---|
359 | | - pfb->base_y.size = ctx->picinfo.y_bs_sz + ctx->picinfo.y_len_sz; |
---|
| 377 | + pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); |
---|
| 378 | + pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); |
---|
| 379 | + pfb->base_y.size = ctx->picinfo.fb_sz[0]; |
---|
360 | 380 | |
---|
361 | | - pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1); |
---|
362 | | - pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1); |
---|
363 | | - pfb->base_c.size = ctx->picinfo.c_bs_sz + ctx->picinfo.c_len_sz; |
---|
| 381 | + pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1); |
---|
| 382 | + pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1); |
---|
| 383 | + pfb->base_c.size = ctx->picinfo.fb_sz[1]; |
---|
364 | 384 | pfb->status = 0; |
---|
365 | 385 | mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id); |
---|
366 | 386 | |
---|
367 | 387 | mtk_v4l2_debug(3, |
---|
368 | 388 | "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx", |
---|
369 | | - dst_buf->index, pfb, |
---|
| 389 | + dst_buf->vb2_buf.index, pfb, |
---|
370 | 390 | pfb->base_y.va, &pfb->base_y.dma_addr, |
---|
371 | 391 | &pfb->base_c.dma_addr, pfb->base_y.size); |
---|
372 | 392 | |
---|
.. | .. |
---|
382 | 402 | |
---|
383 | 403 | vdec_if_decode(ctx, NULL, NULL, &res_chg); |
---|
384 | 404 | clean_display_buffer(ctx); |
---|
385 | | - vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 0, 0); |
---|
386 | | - vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 1, 0); |
---|
387 | | - dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_LAST; |
---|
388 | | - v4l2_m2m_buf_done(&dst_buf_info->vb, VB2_BUF_STATE_DONE); |
---|
| 405 | + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0); |
---|
| 406 | + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) |
---|
| 407 | + vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0); |
---|
| 408 | + dst_buf->flags |= V4L2_BUF_FLAG_LAST; |
---|
| 409 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); |
---|
389 | 410 | clean_free_buffer(ctx); |
---|
390 | 411 | v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); |
---|
391 | 412 | return; |
---|
392 | 413 | } |
---|
393 | | - buf.va = vb2_plane_vaddr(src_buf, 0); |
---|
394 | | - buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); |
---|
395 | | - buf.size = (size_t)src_buf->planes[0].bytesused; |
---|
| 414 | + buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); |
---|
| 415 | + buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); |
---|
| 416 | + buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; |
---|
396 | 417 | if (!buf.va) { |
---|
397 | 418 | v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); |
---|
398 | 419 | mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", |
---|
399 | | - ctx->id, src_buf->index); |
---|
| 420 | + ctx->id, src_buf->vb2_buf.index); |
---|
400 | 421 | return; |
---|
401 | 422 | } |
---|
402 | 423 | mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", |
---|
403 | 424 | ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf); |
---|
404 | | - dst_buf_info->vb.vb2_buf.timestamp |
---|
405 | | - = src_buf_info->vb.vb2_buf.timestamp; |
---|
406 | | - dst_buf_info->vb.timecode |
---|
407 | | - = src_buf_info->vb.timecode; |
---|
| 425 | + dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; |
---|
| 426 | + dst_buf->timecode = src_buf->timecode; |
---|
408 | 427 | mutex_lock(&ctx->lock); |
---|
409 | 428 | dst_buf_info->used = true; |
---|
410 | 429 | mutex_unlock(&ctx->lock); |
---|
.. | .. |
---|
416 | 435 | mtk_v4l2_err( |
---|
417 | 436 | " <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>", |
---|
418 | 437 | ctx->id, |
---|
419 | | - src_buf->index, |
---|
| 438 | + src_buf->vb2_buf.index, |
---|
420 | 439 | buf.size, |
---|
421 | | - src_buf_info->vb.vb2_buf.timestamp, |
---|
422 | | - dst_buf->index, |
---|
| 440 | + src_buf->vb2_buf.timestamp, |
---|
| 441 | + dst_buf->vb2_buf.index, |
---|
423 | 442 | ret, res_chg); |
---|
424 | 443 | src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); |
---|
425 | 444 | if (ret == -EIO) { |
---|
.. | .. |
---|
427 | 446 | src_buf_info->error = true; |
---|
428 | 447 | mutex_unlock(&ctx->lock); |
---|
429 | 448 | } |
---|
430 | | - v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR); |
---|
431 | | - } else if (res_chg == false) { |
---|
| 449 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); |
---|
| 450 | + } else if (!res_chg) { |
---|
432 | 451 | /* |
---|
433 | 452 | * we only return src buffer with VB2_BUF_STATE_DONE |
---|
434 | 453 | * when decode success without resolution change |
---|
435 | 454 | */ |
---|
436 | 455 | src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); |
---|
437 | | - v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); |
---|
| 456 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
---|
438 | 457 | } |
---|
439 | 458 | |
---|
440 | 459 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); |
---|
.. | .. |
---|
506 | 525 | mtk_v4l2_debug(1, "Capture stream is off. No need to flush."); |
---|
507 | 526 | return 0; |
---|
508 | 527 | } |
---|
509 | | - v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb); |
---|
| 528 | + v4l2_m2m_buf_queue(ctx->m2m_ctx, |
---|
| 529 | + &ctx->empty_flush_buf->m2m_buf.vb); |
---|
510 | 530 | v4l2_m2m_try_schedule(ctx->m2m_ctx); |
---|
511 | 531 | break; |
---|
512 | 532 | |
---|
.. | .. |
---|
613 | 633 | static int vidioc_vdec_querycap(struct file *file, void *priv, |
---|
614 | 634 | struct v4l2_capability *cap) |
---|
615 | 635 | { |
---|
616 | | - strlcpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver)); |
---|
617 | | - strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); |
---|
618 | | - strlcpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); |
---|
| 636 | + strscpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver)); |
---|
| 637 | + strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); |
---|
| 638 | + strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); |
---|
619 | 639 | |
---|
620 | 640 | return 0; |
---|
621 | 641 | } |
---|
.. | .. |
---|
633 | 653 | } |
---|
634 | 654 | } |
---|
635 | 655 | |
---|
636 | | -static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_video_fmt *fmt) |
---|
| 656 | +static int vidioc_try_fmt(struct v4l2_format *f, |
---|
| 657 | + const struct mtk_video_fmt *fmt) |
---|
637 | 658 | { |
---|
638 | 659 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
---|
639 | 660 | int i; |
---|
.. | .. |
---|
706 | 727 | static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, |
---|
707 | 728 | struct v4l2_format *f) |
---|
708 | 729 | { |
---|
709 | | - struct mtk_video_fmt *fmt; |
---|
| 730 | + const struct mtk_video_fmt *fmt; |
---|
710 | 731 | |
---|
711 | 732 | fmt = mtk_vdec_find_format(f); |
---|
712 | 733 | if (!fmt) { |
---|
.. | .. |
---|
721 | 742 | struct v4l2_format *f) |
---|
722 | 743 | { |
---|
723 | 744 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
---|
724 | | - struct mtk_video_fmt *fmt; |
---|
| 745 | + const struct mtk_video_fmt *fmt; |
---|
725 | 746 | |
---|
726 | 747 | fmt = mtk_vdec_find_format(f); |
---|
727 | 748 | if (!fmt) { |
---|
.. | .. |
---|
815 | 836 | struct v4l2_pix_format_mplane *pix_mp; |
---|
816 | 837 | struct mtk_q_data *q_data; |
---|
817 | 838 | int ret = 0; |
---|
818 | | - struct mtk_video_fmt *fmt; |
---|
| 839 | + const struct mtk_video_fmt *fmt; |
---|
819 | 840 | |
---|
820 | 841 | mtk_v4l2_debug(3, "[%d]", ctx->id); |
---|
821 | 842 | |
---|
.. | .. |
---|
824 | 845 | return -EINVAL; |
---|
825 | 846 | |
---|
826 | 847 | pix_mp = &f->fmt.pix_mp; |
---|
| 848 | + /* |
---|
| 849 | + * Setting OUTPUT format after OUTPUT buffers are allocated is invalid |
---|
| 850 | + * if using the stateful API. |
---|
| 851 | + */ |
---|
827 | 852 | if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && |
---|
828 | 853 | vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) { |
---|
829 | 854 | mtk_v4l2_err("out_q_ctx buffers already requested"); |
---|
830 | 855 | ret = -EBUSY; |
---|
831 | 856 | } |
---|
832 | 857 | |
---|
| 858 | + /* |
---|
| 859 | + * Setting CAPTURE format after CAPTURE buffers are allocated is |
---|
| 860 | + * invalid. |
---|
| 861 | + */ |
---|
833 | 862 | if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) && |
---|
834 | 863 | vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) { |
---|
835 | 864 | mtk_v4l2_err("cap_q_ctx buffers already requested"); |
---|
.. | .. |
---|
848 | 877 | fmt = mtk_vdec_find_format(f); |
---|
849 | 878 | } |
---|
850 | 879 | } |
---|
| 880 | + if (fmt == NULL) |
---|
| 881 | + return -EINVAL; |
---|
851 | 882 | |
---|
852 | 883 | q_data->fmt = fmt; |
---|
853 | 884 | vidioc_try_fmt(f, q_data->fmt); |
---|
.. | .. |
---|
856 | 887 | q_data->coded_width = pix_mp->width; |
---|
857 | 888 | q_data->coded_height = pix_mp->height; |
---|
858 | 889 | |
---|
859 | | - ctx->colorspace = f->fmt.pix_mp.colorspace; |
---|
860 | | - ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; |
---|
861 | | - ctx->quantization = f->fmt.pix_mp.quantization; |
---|
862 | | - ctx->xfer_func = f->fmt.pix_mp.xfer_func; |
---|
| 890 | + ctx->colorspace = pix_mp->colorspace; |
---|
| 891 | + ctx->ycbcr_enc = pix_mp->ycbcr_enc; |
---|
| 892 | + ctx->quantization = pix_mp->quantization; |
---|
| 893 | + ctx->xfer_func = pix_mp->xfer_func; |
---|
863 | 894 | |
---|
864 | 895 | if (ctx->state == MTK_STATE_FREE) { |
---|
865 | 896 | ret = vdec_if_init(ctx, q_data->fmt->fourcc); |
---|
.. | .. |
---|
914 | 945 | |
---|
915 | 946 | static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) |
---|
916 | 947 | { |
---|
917 | | - struct mtk_video_fmt *fmt; |
---|
| 948 | + const struct mtk_video_fmt *fmt; |
---|
918 | 949 | int i, j = 0; |
---|
919 | 950 | |
---|
920 | 951 | for (i = 0; i < NUM_FORMATS; i++) { |
---|
.. | .. |
---|
934 | 965 | |
---|
935 | 966 | fmt = &mtk_video_formats[i]; |
---|
936 | 967 | f->pixelformat = fmt->fourcc; |
---|
| 968 | + f->flags = fmt->flags; |
---|
937 | 969 | |
---|
938 | 970 | return 0; |
---|
939 | 971 | } |
---|
940 | 972 | |
---|
941 | | -static int vidioc_vdec_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, |
---|
942 | | - struct v4l2_fmtdesc *f) |
---|
| 973 | +static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv, |
---|
| 974 | + struct v4l2_fmtdesc *f) |
---|
943 | 975 | { |
---|
944 | 976 | return vidioc_enum_fmt(f, false); |
---|
945 | 977 | } |
---|
946 | 978 | |
---|
947 | | -static int vidioc_vdec_enum_fmt_vid_out_mplane(struct file *file, void *priv, |
---|
948 | | - struct v4l2_fmtdesc *f) |
---|
| 979 | +static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv, |
---|
| 980 | + struct v4l2_fmtdesc *f) |
---|
949 | 981 | { |
---|
950 | 982 | return vidioc_enum_fmt(f, true); |
---|
951 | 983 | } |
---|
.. | .. |
---|
980 | 1012 | * So we just return picinfo yet, and update picinfo in |
---|
981 | 1013 | * stop_streaming hook function |
---|
982 | 1014 | */ |
---|
983 | | - q_data->sizeimage[0] = ctx->picinfo.y_bs_sz + |
---|
984 | | - ctx->picinfo.y_len_sz; |
---|
985 | | - q_data->sizeimage[1] = ctx->picinfo.c_bs_sz + |
---|
986 | | - ctx->picinfo.c_len_sz; |
---|
| 1015 | + q_data->sizeimage[0] = ctx->picinfo.fb_sz[0]; |
---|
| 1016 | + q_data->sizeimage[1] = ctx->picinfo.fb_sz[1]; |
---|
987 | 1017 | q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w; |
---|
988 | 1018 | q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w; |
---|
989 | 1019 | q_data->coded_width = ctx->picinfo.buf_w; |
---|
990 | 1020 | q_data->coded_height = ctx->picinfo.buf_h; |
---|
| 1021 | + ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc; |
---|
991 | 1022 | |
---|
992 | 1023 | /* |
---|
993 | 1024 | * Width and height are set to the dimensions |
---|
.. | .. |
---|
1103 | 1134 | |
---|
1104 | 1135 | static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) |
---|
1105 | 1136 | { |
---|
1106 | | - struct vb2_buffer *src_buf; |
---|
| 1137 | + struct vb2_v4l2_buffer *src_buf; |
---|
1107 | 1138 | struct mtk_vcodec_mem src_mem; |
---|
1108 | 1139 | bool res_chg = false; |
---|
1109 | 1140 | int ret = 0; |
---|
1110 | | - unsigned int dpbsize = 1; |
---|
| 1141 | + unsigned int dpbsize = 1, i = 0; |
---|
1111 | 1142 | struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); |
---|
1112 | 1143 | struct vb2_v4l2_buffer *vb2_v4l2 = NULL; |
---|
1113 | 1144 | struct mtk_video_dec_buf *buf = NULL; |
---|
| 1145 | + struct mtk_q_data *dst_q_data; |
---|
1114 | 1146 | |
---|
1115 | 1147 | mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", |
---|
1116 | 1148 | ctx->id, vb->vb2_queue->type, |
---|
.. | .. |
---|
1120 | 1152 | */ |
---|
1121 | 1153 | if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
---|
1122 | 1154 | vb2_v4l2 = to_vb2_v4l2_buffer(vb); |
---|
1123 | | - buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); |
---|
| 1155 | + buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, |
---|
| 1156 | + m2m_buf.vb); |
---|
1124 | 1157 | mutex_lock(&ctx->lock); |
---|
1125 | | - if (buf->used == false) { |
---|
| 1158 | + if (!buf->used) { |
---|
1126 | 1159 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); |
---|
1127 | 1160 | buf->queued_in_vb2 = true; |
---|
1128 | 1161 | buf->queued_in_v4l2 = true; |
---|
1129 | | - buf->ready_to_display = false; |
---|
1130 | 1162 | } else { |
---|
1131 | 1163 | buf->queued_in_vb2 = false; |
---|
1132 | 1164 | buf->queued_in_v4l2 = true; |
---|
1133 | | - buf->ready_to_display = false; |
---|
1134 | 1165 | } |
---|
1135 | 1166 | mutex_unlock(&ctx->lock); |
---|
1136 | 1167 | return; |
---|
.. | .. |
---|
1149 | 1180 | mtk_v4l2_err("No src buffer"); |
---|
1150 | 1181 | return; |
---|
1151 | 1182 | } |
---|
1152 | | - vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); |
---|
1153 | | - buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); |
---|
| 1183 | + buf = container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb); |
---|
1154 | 1184 | if (buf->lastframe) { |
---|
1155 | 1185 | /* This shouldn't happen. Just in case. */ |
---|
1156 | 1186 | mtk_v4l2_err("Invalid flush buffer."); |
---|
.. | .. |
---|
1158 | 1188 | return; |
---|
1159 | 1189 | } |
---|
1160 | 1190 | |
---|
1161 | | - src_mem.va = vb2_plane_vaddr(src_buf, 0); |
---|
1162 | | - src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); |
---|
1163 | | - src_mem.size = (size_t)src_buf->planes[0].bytesused; |
---|
| 1191 | + src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); |
---|
| 1192 | + src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); |
---|
| 1193 | + src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; |
---|
1164 | 1194 | mtk_v4l2_debug(2, |
---|
1165 | 1195 | "[%d] buf id=%d va=%p dma=%pad size=%zx", |
---|
1166 | | - ctx->id, src_buf->index, |
---|
| 1196 | + ctx->id, src_buf->vb2_buf.index, |
---|
1167 | 1197 | src_mem.va, &src_mem.dma_addr, |
---|
1168 | 1198 | src_mem.size); |
---|
1169 | 1199 | |
---|
1170 | 1200 | ret = vdec_if_decode(ctx, &src_mem, NULL, &res_chg); |
---|
1171 | 1201 | if (ret || !res_chg) { |
---|
1172 | 1202 | /* |
---|
1173 | | - * fb == NULL menas to parse SPS/PPS header or |
---|
| 1203 | + * fb == NULL means to parse SPS/PPS header or |
---|
1174 | 1204 | * resolution info in src_mem. Decode can fail |
---|
1175 | 1205 | * if there is no SPS header or picture info |
---|
1176 | 1206 | * in bs |
---|
.. | .. |
---|
1181 | 1211 | mtk_v4l2_err("[%d] Unrecoverable error in vdec_if_decode.", |
---|
1182 | 1212 | ctx->id); |
---|
1183 | 1213 | ctx->state = MTK_STATE_ABORT; |
---|
1184 | | - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), |
---|
1185 | | - VB2_BUF_STATE_ERROR); |
---|
| 1214 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); |
---|
1186 | 1215 | } else { |
---|
1187 | | - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), |
---|
1188 | | - VB2_BUF_STATE_DONE); |
---|
| 1216 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
---|
1189 | 1217 | } |
---|
1190 | 1218 | mtk_v4l2_debug(ret ? 0 : 1, |
---|
1191 | 1219 | "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", |
---|
1192 | | - ctx->id, src_buf->index, |
---|
| 1220 | + ctx->id, src_buf->vb2_buf.index, |
---|
1193 | 1221 | src_mem.size, ret, res_chg); |
---|
1194 | 1222 | return; |
---|
1195 | 1223 | } |
---|
.. | .. |
---|
1201 | 1229 | } |
---|
1202 | 1230 | |
---|
1203 | 1231 | ctx->last_decoded_picinfo = ctx->picinfo; |
---|
1204 | | - ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] = |
---|
1205 | | - ctx->picinfo.y_bs_sz + |
---|
1206 | | - ctx->picinfo.y_len_sz; |
---|
1207 | | - ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = |
---|
1208 | | - ctx->picinfo.buf_w; |
---|
1209 | | - ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] = |
---|
1210 | | - ctx->picinfo.c_bs_sz + |
---|
1211 | | - ctx->picinfo.c_len_sz; |
---|
1212 | | - ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] = ctx->picinfo.buf_w; |
---|
| 1232 | + dst_q_data = &ctx->q_data[MTK_Q_DATA_DST]; |
---|
| 1233 | + for (i = 0; i < dst_q_data->fmt->num_planes; i++) { |
---|
| 1234 | + dst_q_data->sizeimage[i] = ctx->picinfo.fb_sz[i]; |
---|
| 1235 | + dst_q_data->bytesperline[i] = ctx->picinfo.buf_w; |
---|
| 1236 | + } |
---|
| 1237 | + |
---|
1213 | 1238 | mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", |
---|
1214 | 1239 | ctx->id, |
---|
1215 | 1240 | ctx->picinfo.buf_w, ctx->picinfo.buf_h, |
---|
1216 | 1241 | ctx->picinfo.pic_w, ctx->picinfo.pic_h, |
---|
1217 | | - ctx->q_data[MTK_Q_DATA_DST].sizeimage[0], |
---|
1218 | | - ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]); |
---|
| 1242 | + dst_q_data->sizeimage[0], |
---|
| 1243 | + dst_q_data->sizeimage[1]); |
---|
1219 | 1244 | |
---|
1220 | 1245 | ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); |
---|
1221 | 1246 | if (dpbsize == 0) |
---|
.. | .. |
---|
1236 | 1261 | bool buf_error; |
---|
1237 | 1262 | |
---|
1238 | 1263 | vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); |
---|
1239 | | - buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); |
---|
| 1264 | + buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb); |
---|
1240 | 1265 | mutex_lock(&ctx->lock); |
---|
1241 | 1266 | if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
---|
1242 | 1267 | buf->queued_in_v4l2 = false; |
---|
.. | .. |
---|
1256 | 1281 | struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb, |
---|
1257 | 1282 | struct vb2_v4l2_buffer, vb2_buf); |
---|
1258 | 1283 | struct mtk_video_dec_buf *buf = container_of(vb2_v4l2, |
---|
1259 | | - struct mtk_video_dec_buf, vb); |
---|
| 1284 | + struct mtk_video_dec_buf, m2m_buf.vb); |
---|
1260 | 1285 | |
---|
1261 | 1286 | if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
---|
1262 | 1287 | buf->used = false; |
---|
1263 | | - buf->ready_to_display = false; |
---|
1264 | 1288 | buf->queued_in_v4l2 = false; |
---|
1265 | 1289 | } else { |
---|
1266 | 1290 | buf->lastframe = false; |
---|
.. | .. |
---|
1281 | 1305 | |
---|
1282 | 1306 | static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) |
---|
1283 | 1307 | { |
---|
1284 | | - struct vb2_buffer *src_buf = NULL, *dst_buf = NULL; |
---|
| 1308 | + struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL; |
---|
1285 | 1309 | struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); |
---|
1286 | 1310 | |
---|
1287 | 1311 | mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d", |
---|
.. | .. |
---|
1289 | 1313 | |
---|
1290 | 1314 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
---|
1291 | 1315 | while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) { |
---|
1292 | | - struct vb2_v4l2_buffer *vb2_v4l2 = |
---|
1293 | | - to_vb2_v4l2_buffer(src_buf); |
---|
1294 | 1316 | struct mtk_video_dec_buf *buf_info = container_of( |
---|
1295 | | - vb2_v4l2, struct mtk_video_dec_buf, vb); |
---|
| 1317 | + src_buf, struct mtk_video_dec_buf, m2m_buf.vb); |
---|
1296 | 1318 | if (!buf_info->lastframe) |
---|
1297 | | - v4l2_m2m_buf_done(vb2_v4l2, |
---|
| 1319 | + v4l2_m2m_buf_done(src_buf, |
---|
1298 | 1320 | VB2_BUF_STATE_ERROR); |
---|
1299 | 1321 | } |
---|
1300 | 1322 | return; |
---|
.. | .. |
---|
1323 | 1345 | ctx->state = MTK_STATE_FLUSH; |
---|
1324 | 1346 | |
---|
1325 | 1347 | while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { |
---|
1326 | | - vb2_set_plane_payload(dst_buf, 0, 0); |
---|
1327 | | - vb2_set_plane_payload(dst_buf, 1, 0); |
---|
1328 | | - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), |
---|
1329 | | - VB2_BUF_STATE_ERROR); |
---|
| 1348 | + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0); |
---|
| 1349 | + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) |
---|
| 1350 | + vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0); |
---|
| 1351 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); |
---|
1330 | 1352 | } |
---|
1331 | 1353 | |
---|
1332 | 1354 | } |
---|
.. | .. |
---|
1454 | 1476 | |
---|
1455 | 1477 | .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, |
---|
1456 | 1478 | |
---|
1457 | | - .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane, |
---|
1458 | | - .vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane, |
---|
| 1479 | + .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap, |
---|
| 1480 | + .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out, |
---|
1459 | 1481 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
---|
1460 | 1482 | |
---|
1461 | 1483 | .vidioc_querycap = vidioc_vdec_querycap, |
---|
.. | .. |
---|
1502 | 1524 | dst_vq->dev = &ctx->dev->plat_dev->dev; |
---|
1503 | 1525 | |
---|
1504 | 1526 | ret = vb2_queue_init(dst_vq); |
---|
1505 | | - if (ret) { |
---|
1506 | | - vb2_queue_release(src_vq); |
---|
| 1527 | + if (ret) |
---|
1507 | 1528 | mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)"); |
---|
1508 | | - } |
---|
1509 | 1529 | |
---|
1510 | 1530 | return ret; |
---|
1511 | 1531 | } |
---|