| .. | .. |
|---|
| 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 | | - * 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 as |
|---|
| 7 | | - * 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 | 5 | */ |
|---|
| 14 | 6 | |
|---|
| 15 | 7 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 37 | 29 | #define H264_MAX_FB_NUM 17 |
|---|
| 38 | 30 | #define HDR_PARSING_BUF_SZ 1024 |
|---|
| 39 | 31 | |
|---|
| 32 | +#define DEC_ERR_RET(ret) ((ret) >> 16) |
|---|
| 33 | +#define H264_ERR_NOT_VALID 3 |
|---|
| 34 | + |
|---|
| 40 | 35 | /** |
|---|
| 41 | 36 | * struct h264_fb - h264 decode frame buffer information |
|---|
| 42 | 37 | * @vdec_fb_va : virtual address of struct vdec_fb |
|---|
| .. | .. |
|---|
| 55 | 50 | |
|---|
| 56 | 51 | /** |
|---|
| 57 | 52 | * struct h264_ring_fb_list - ring frame buffer list |
|---|
| 58 | | - * @fb_list : frame buffer arrary |
|---|
| 53 | + * @fb_list : frame buffer array |
|---|
| 59 | 54 | * @read_idx : read index |
|---|
| 60 | 55 | * @write_idx : write index |
|---|
| 61 | 56 | * @count : buffer count in list |
|---|
| .. | .. |
|---|
| 72 | 67 | /** |
|---|
| 73 | 68 | * struct vdec_h264_dec_info - decode information |
|---|
| 74 | 69 | * @dpb_sz : decoding picture buffer size |
|---|
| 75 | | - * @resolution_changed : resoltion change happen |
|---|
| 70 | + * @resolution_changed : resolution change happen |
|---|
| 76 | 71 | * @realloc_mv_buf : flag to notify driver to re-allocate mv buffer |
|---|
| 77 | 72 | * @reserved : for 8 bytes alignment |
|---|
| 78 | 73 | * @bs_dma : Input bit-stream buffer dma address |
|---|
| .. | .. |
|---|
| 253 | 248 | *pic = inst->vsi->pic; |
|---|
| 254 | 249 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", |
|---|
| 255 | 250 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); |
|---|
| 256 | | - mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, |
|---|
| 257 | | - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); |
|---|
| 251 | + mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", |
|---|
| 252 | + pic->fb_sz[0], pic->fb_sz[1]); |
|---|
| 258 | 253 | } |
|---|
| 259 | 254 | |
|---|
| 260 | 255 | static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) |
|---|
| .. | .. |
|---|
| 274 | 269 | mtk_vcodec_debug(inst, "sz=%d", *dpb_sz); |
|---|
| 275 | 270 | } |
|---|
| 276 | 271 | |
|---|
| 277 | | -static int vdec_h264_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec) |
|---|
| 272 | +static int vdec_h264_init(struct mtk_vcodec_ctx *ctx) |
|---|
| 278 | 273 | { |
|---|
| 279 | 274 | struct vdec_h264_inst *inst = NULL; |
|---|
| 280 | 275 | int err; |
|---|
| .. | .. |
|---|
| 286 | 281 | inst->ctx = ctx; |
|---|
| 287 | 282 | |
|---|
| 288 | 283 | inst->vpu.id = IPI_VDEC_H264; |
|---|
| 289 | | - inst->vpu.dev = ctx->dev->vpu_plat_dev; |
|---|
| 290 | 284 | inst->vpu.ctx = ctx; |
|---|
| 291 | | - inst->vpu.handler = vpu_dec_ipi_handler; |
|---|
| 292 | 285 | |
|---|
| 293 | 286 | err = vpu_dec_init(&inst->vpu); |
|---|
| 294 | 287 | if (err) { |
|---|
| .. | .. |
|---|
| 303 | 296 | |
|---|
| 304 | 297 | mtk_vcodec_debug(inst, "H264 Instance >> %p", inst); |
|---|
| 305 | 298 | |
|---|
| 306 | | - *h_vdec = (unsigned long)inst; |
|---|
| 299 | + ctx->drv_handle = inst; |
|---|
| 307 | 300 | return 0; |
|---|
| 308 | 301 | |
|---|
| 309 | 302 | error_deinit: |
|---|
| .. | .. |
|---|
| 314 | 307 | return err; |
|---|
| 315 | 308 | } |
|---|
| 316 | 309 | |
|---|
| 317 | | -static void vdec_h264_deinit(unsigned long h_vdec) |
|---|
| 310 | +static void vdec_h264_deinit(void *h_vdec) |
|---|
| 318 | 311 | { |
|---|
| 319 | 312 | struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; |
|---|
| 320 | 313 | |
|---|
| .. | .. |
|---|
| 339 | 332 | return -1; |
|---|
| 340 | 333 | } |
|---|
| 341 | 334 | |
|---|
| 342 | | -static int vdec_h264_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, |
|---|
| 335 | +static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, |
|---|
| 343 | 336 | struct vdec_fb *fb, bool *res_chg) |
|---|
| 344 | 337 | { |
|---|
| 345 | 338 | struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; |
|---|
| .. | .. |
|---|
| 365 | 358 | buf = (unsigned char *)bs->va; |
|---|
| 366 | 359 | buf_sz = bs->size; |
|---|
| 367 | 360 | nal_start_idx = find_start_code(buf, buf_sz); |
|---|
| 368 | | - if (nal_start_idx < 0) |
|---|
| 361 | + if (nal_start_idx < 0) { |
|---|
| 362 | + mtk_vcodec_err(inst, "invalid nal start code"); |
|---|
| 363 | + err = -EIO; |
|---|
| 369 | 364 | goto err_free_fb_out; |
|---|
| 365 | + } |
|---|
| 370 | 366 | |
|---|
| 371 | 367 | nal_start = buf[nal_start_idx]; |
|---|
| 372 | 368 | nal_type = NAL_TYPE(buf[nal_start_idx]); |
|---|
| .. | .. |
|---|
| 390 | 386 | data[0] = buf_sz; |
|---|
| 391 | 387 | data[1] = nal_start; |
|---|
| 392 | 388 | err = vpu_dec_start(vpu, data, 2); |
|---|
| 393 | | - if (err) |
|---|
| 389 | + if (err) { |
|---|
| 390 | + if (err > 0 && (DEC_ERR_RET(err) == H264_ERR_NOT_VALID)) { |
|---|
| 391 | + mtk_vcodec_err(inst, "- error bitstream - err = %d -", |
|---|
| 392 | + err); |
|---|
| 393 | + err = -EIO; |
|---|
| 394 | + } |
|---|
| 394 | 395 | goto err_free_fb_out; |
|---|
| 396 | + } |
|---|
| 395 | 397 | |
|---|
| 396 | 398 | *res_chg = inst->vsi->dec.resolution_changed; |
|---|
| 397 | 399 | if (*res_chg) { |
|---|
| .. | .. |
|---|
| 459 | 461 | list->count--; |
|---|
| 460 | 462 | } |
|---|
| 461 | 463 | |
|---|
| 462 | | -static int vdec_h264_get_param(unsigned long h_vdec, |
|---|
| 463 | | - enum vdec_get_param_type type, void *out) |
|---|
| 464 | +static int vdec_h264_get_param(void *h_vdec, enum vdec_get_param_type type, |
|---|
| 465 | + void *out) |
|---|
| 464 | 466 | { |
|---|
| 465 | 467 | struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; |
|---|
| 466 | 468 | |
|---|
| .. | .. |
|---|
| 493 | 495 | return 0; |
|---|
| 494 | 496 | } |
|---|
| 495 | 497 | |
|---|
| 496 | | -static struct vdec_common_if vdec_h264_if = { |
|---|
| 498 | +const struct vdec_common_if vdec_h264_if = { |
|---|
| 497 | 499 | .init = vdec_h264_init, |
|---|
| 498 | 500 | .decode = vdec_h264_decode, |
|---|
| 499 | 501 | .get_param = vdec_h264_get_param, |
|---|
| 500 | 502 | .deinit = vdec_h264_deinit, |
|---|
| 501 | 503 | }; |
|---|
| 502 | | - |
|---|
| 503 | | -struct vdec_common_if *get_h264_dec_comm_if(void); |
|---|
| 504 | | - |
|---|
| 505 | | -struct vdec_common_if *get_h264_dec_comm_if(void) |
|---|
| 506 | | -{ |
|---|
| 507 | | - return &vdec_h264_if; |
|---|
| 508 | | -} |
|---|