From 50a3479782b1f34fc70a6eded4c7931ba8a657aa Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Tue, 5 Sep 2017 18:20:15 +0800 Subject: [PATCH] decoder: fixed a issure of the memory leak when the seek. PD#150221: fixed a issure of the memory leak when the seek. Change-Id: Ie11a942f08cfeab59a6e4e7452c82bab62ec5f36 Signed-off-by: Nanxin Qin --- .../media_modules/common/chips/chips.h | 1 - .../common/firmware/firmware_drv.c | 2 +- .../firmware/{firmware.h => firmware_priv.h} | 13 +-- .../frame_provider/decoder/avs/avs.c | 1 + .../frame_provider/decoder/h264/vh264.c | 1 + .../frame_provider/decoder/h264/vh264_4k2k.c | 1 + .../frame_provider/decoder/h264/vh264_mvc.c | 1 + .../decoder/h264_multi/vmh264.c | 57 ++++++------- .../frame_provider/decoder/h265/vh265.c | 78 ++++++++--------- .../frame_provider/decoder/mjpeg/vmjpeg.c | 1 + .../decoder/mjpeg/vmjpeg_multi.c | 38 +++++---- .../frame_provider/decoder/mpeg12/vmpeg12.c | 1 + .../frame_provider/decoder/mpeg4/vmpeg4.c | 1 + .../decoder/mpeg4/vmpeg4_multi.c | 83 ++++++++++--------- .../frame_provider/decoder/real/vreal.c | 1 + .../frame_provider/decoder/utils/amvdec.c | 2 +- .../frame_provider/decoder/utils/firmware.h | 17 ++++ .../frame_provider/decoder/vc1/vvc1.c | 1 + .../frame_provider/decoder/vp9/vvp9.c | 59 ++++++------- .../frame_sink/encoder/h264/encoder.c | 1 + .../stream_input/amports/amports_priv.h | 1 - .../stream_input/amports/amstream.c | 1 - 22 files changed, 187 insertions(+), 175 deletions(-) rename drivers/amlogic/media_modules/common/firmware/{firmware.h => firmware_priv.h} (84%) create mode 100644 drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h diff --git a/drivers/amlogic/media_modules/common/chips/chips.h b/drivers/amlogic/media_modules/common/chips/chips.h index 7a9fabac00b2..34e055d43f8f 100644 --- a/drivers/amlogic/media_modules/common/chips/chips.h +++ b/drivers/amlogic/media_modules/common/chips/chips.h @@ -17,7 +17,6 @@ #ifndef UCODE_MANAGER_HEADER #define UCODE_MANAGER_HEADER -#include "../firmware/firmware.h" #include "../media_clock/clk/clk_priv.h" struct chip_vdec_info_s { diff --git a/drivers/amlogic/media_modules/common/firmware/firmware_drv.c b/drivers/amlogic/media_modules/common/firmware/firmware_drv.c index c80603f90633..35dc29be6840 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware_drv.c +++ b/drivers/amlogic/media_modules/common/firmware/firmware_drv.c @@ -29,7 +29,7 @@ #include #include "../../stream_input/amports/amports_priv.h" #include "../../frame_provider/decoder/utils/vdec.h" -#include "firmware.h" +#include "firmware_priv.h" #include "../chips/chips.h" #include #include diff --git a/drivers/amlogic/media_modules/common/firmware/firmware.h b/drivers/amlogic/media_modules/common/firmware/firmware_priv.h similarity index 84% rename from drivers/amlogic/media_modules/common/firmware/firmware.h rename to drivers/amlogic/media_modules/common/firmware/firmware_priv.h index b7d56d71e6c5..0a9634912755 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware.h +++ b/drivers/amlogic/media_modules/common/firmware/firmware_priv.h @@ -15,15 +15,13 @@ * */ -#ifndef __VIDEO_FIRMWARE_HEADER_ -#define __VIDEO_FIRMWARE_HEADER_ +#ifndef __VIDEO_FIRMWARE_PRIV_HEADER_ +#define __VIDEO_FIRMWARE_PRIV_HEADER_ #include #include #include #include #include "firmware_type.h" -#include - struct firmware_mgr_s { struct list_head head; @@ -67,7 +65,6 @@ struct firmware_s { char data[0]; }; - struct package_header_s { int magic; int size; @@ -98,16 +95,10 @@ struct package_info_s { char data[0]; }; - struct firmware_dev_s { struct cdev cdev; struct device *dev; dev_t dev_no; }; -int get_decoder_firmware_data(enum vformat_e type, - const char *file_name, char *buf, int size); -int get_data_from_name(const char *name, char *buf); -int get_firmware_data(enum firmware_type_e type, char *buf); - #endif diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c index 34dcca6cb03b..8d05ff9a3cea 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c @@ -39,6 +39,7 @@ #include #include "../utils/decoder_mmu_box.h" #include "../utils/decoder_bmmu_box.h" +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_avs" #define MODULE_NAME "amvdec_avs" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c index 70713dbccd4f..7e1b1ac23354 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c @@ -51,6 +51,7 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_h264" #define MODULE_NAME "amvdec_h264" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c index ed0a3ce81878..38cf2d820a0c 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_4k2k.c @@ -36,6 +36,7 @@ #include #include +#include "../utils/firmware.h" #define MEM_NAME "codec_264_4k" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c index 73d825018929..8e1ed38be447 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c @@ -43,6 +43,7 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/firmware.h" #define TIME_TASK_PRINT_ENABLE 0x100 #define PUT_PRINT_ENABLE 0x200 diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index b5a52f7a1ad6..04320e563a6a 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -52,6 +52,7 @@ #include #include "../utils/decoder_mmu_box.h" #include "../utils/decoder_bmmu_box.h" +#include "../utils/firmware.h" #undef pr_info #define pr_info printk @@ -658,6 +659,7 @@ struct vdec_h264_hw_s { u32 ucode_pause_pos; u8 reset_bufmgr_flag; + struct firmware_s *fw; }; @@ -4347,47 +4349,51 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) */ if (!firmwareloaded) { int ret = 0, size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; + int fw_size = 0x1000 * 16; + struct firmware_s *fw = NULL; pr_info("start load orignal firmware ...\n"); - size = get_firmware_data(VIDEO_DEC_H264_MULTI, buf); + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + size = get_firmware_data(VIDEO_DEC_H264_MULTI, fw->data); if (size < 0) { pr_err("get firmware fail.\n"); - vfree(buf); + vfree(fw); return -1; } + fw->len = size; + hw->fw = fw; + /*ret = amvdec_loadmc_ex(VFORMAT_H264, NULL, buf);*/ /*header*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_HEADER, - buf + 0x4000, MC_SWAP_SIZE); + fw->data + 0x4000, MC_SWAP_SIZE); /*data*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_DATA, - buf + 0x2000, MC_SWAP_SIZE); + fw->data + 0x2000, MC_SWAP_SIZE); /*mmco*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MMCO, - buf + 0x6000, MC_SWAP_SIZE); + fw->data + 0x6000, MC_SWAP_SIZE); /*list*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_LIST, - buf + 0x3000, MC_SWAP_SIZE); + fw->data + 0x3000, MC_SWAP_SIZE); /*slice*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_SLICE, - buf + 0x5000, MC_SWAP_SIZE); + fw->data + 0x5000, MC_SWAP_SIZE); /*main*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN, - buf, 0x2000); + fw->data, 0x2000); /*data*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x2000, - buf + 0x2000, 0x1000); + fw->data + 0x2000, 0x1000); /*slice*/ memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x3000, - buf + 0x5000, 0x1000); - - vfree(buf); + fw->data + 0x5000, 0x1000); if (ret < 0) { dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, @@ -4532,6 +4538,9 @@ static int vh264_stop(struct vdec_h264_hw_s *hw) } /* amvdec_disable(); */ + vfree(hw->fw); + hw->fw = NULL; + dpb_print(DECODE_ID(hw), 0, "%s\n", __func__); @@ -4805,10 +4814,7 @@ static void run(struct vdec_s *vdec, { struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - int size, firmware_size; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; + int size; run_count[DECODE_ID(hw)]++; @@ -4834,7 +4840,6 @@ static void run(struct vdec_s *vdec, "vdec_prepare_input: Insufficient data\n"); vdec_schedule_work(&hw->work); - vfree(buf); return; } input_empty[DECODE_ID(hw)] = 0; @@ -4897,26 +4902,16 @@ static void run(struct vdec_s *vdec, start_process_time(hw); - firmware_size = get_firmware_data(VIDEO_DEC_H264_MULTI, buf); - if (firmware_size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return; - } - - if (amvdec_vdec_loadmc_ex(vdec, NULL, buf) < 0) { + if (amvdec_vdec_loadmc_ex(vdec, NULL, hw->fw->data) < 0) { amvdec_enable_flag = false; amvdec_disable(); if (mmu_enable) amhevc_disable(); - vfree(buf); pr_info("%s: Error amvdec_vdec_loadmc fail\n", __func__); return; } - vfree(buf); - if (vh264_hw_ctx_restore(hw) < 0) { vdec_schedule_work(&hw->work); return; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index 23b40fa54f2d..36881860cbfd 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -43,6 +43,7 @@ #include "../utils/decoder_mmu_box.h" #include "../utils/decoder_bmmu_box.h" #include "../utils/config_parser.h" +#include "../utils/firmware.h" /*#define TEST_NO_BUF*/ /*#define HEVC_PIC_STRUCT_SUPPORT*/ @@ -1519,6 +1520,7 @@ struct hevc_state_s { u32 vf_pre_count; u32 vf_get_count; u32 vf_put_count; + struct firmware_s *fw; } /*hevc_stru_t */; #ifdef SUPPORT_10BIT @@ -8492,18 +8494,35 @@ static s32 vh265_init(struct hevc_state_s *hevc) #endif int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; + int fw_size = 0x1000 * 16; + struct firmware_s *fw = NULL; init_timer(&hevc->timer); hevc->stat |= STAT_TIMER_INIT; - if (vh265_local_init(hevc) < 0) { - vfree(buf); + if (vh265_local_init(hevc) < 0) return -EBUSY; - } + INIT_WORK(&hevc->notify_work, vh265_notify_work); + + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + if (mmu_enable && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { + size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data); + hevc_print(hevc, 0, "vh265 mmu ucode loaded!\n"); + } else + size = get_firmware_data(VIDEO_DEC_HEVC, fw->data); + + if (size < 0) { + pr_err("get firmware fail.\n"); + vfree(fw); + return -1; + } + + fw->len = size; + #ifdef MULTI_INSTANCE_SUPPORT if (hevc->m_ins_flag) { hevc->timer.data = (ulong) hevc; @@ -8515,31 +8534,21 @@ static s32 vh265_init(struct hevc_state_s *hevc) hevc->stat |= STAT_TIMER_ARM;*/ INIT_WORK(&hevc->work, vh265_work); - vfree(buf); + + hevc->fw = fw; + return 0; } #endif amhevc_enable(); - if (mmu_enable && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { - size = get_firmware_data(VIDEO_DEC_HEVC_MMU, buf); - hevc_print(hevc, 0, "vh265 mmu ucode loaded!\n"); - } else - size = get_firmware_data(VIDEO_DEC_HEVC, buf); - - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return -1; - } - - if (amhevc_loadmc_ex(VFORMAT_HEVC, NULL, buf) < 0) { + if (amhevc_loadmc_ex(VFORMAT_HEVC, NULL, fw->data) < 0) { amhevc_disable(); - vfree(buf); + vfree(fw); return -EBUSY; } - vfree(buf); + vfree(fw); hevc->stat |= STAT_MC_LOAD; @@ -8726,6 +8735,9 @@ static int vh265_stop(struct hevc_state_s *hevc) uninit_mmu_buffers(hevc); amhevc_disable(); + vfree(hevc->fw); + hevc->fw = NULL; + kfree(gvs); gvs = NULL; @@ -9274,10 +9286,6 @@ static void run(struct vdec_s *vdec, (struct hevc_state_s *)vdec->private; int r; unsigned char check_sum = 0; - int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; run_count[hevc->index]++; hevc->vdec_cb_arg = arg; @@ -9294,7 +9302,6 @@ static void run(struct vdec_s *vdec, "ammvdec_vh265: Insufficient data\n"); vdec_schedule_work(&hevc->work); - vfree(buf); return; } input_empty[hevc->index] = 0; @@ -9341,29 +9348,14 @@ static void run(struct vdec_s *vdec, } } - if (hevc->mmu_enable && - (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { - size = get_firmware_data(VIDEO_DEC_HEVC_MMU, buf); - } else - size = get_firmware_data(VIDEO_DEC_HEVC, buf); - - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return; - } - - if (amhevc_vdec_loadmc_ex(vdec, NULL, buf) < 0) { + if (amhevc_vdec_loadmc_ex(vdec, NULL, hevc->fw->data) < 0) { amhevc_disable(); - vfree(buf); hevc_print(hevc, 0, "%s: Error amvdec_loadmc fail\n", __func__); return; } - vfree(buf); - if (vh265_hw_ctx_restore(hevc) < 0) { vdec_schedule_work(&hevc->work); return; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c index 6b2d45d36531..ade4ab3f55c8 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c @@ -49,6 +49,7 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC); #include "../utils/amvdec.h" +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_mjpeg" #define MODULE_NAME "amvdec_mjpeg" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c index e1d451ac57a3..15917115d0b3 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c @@ -40,6 +40,7 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/firmware.h" #define MEM_NAME "codec_mmjpeg" @@ -139,6 +140,7 @@ struct vdec_mjpeg_hw_s { struct work_struct work; void (*vdec_cb)(struct vdec_s *, void *); void *vdec_cb_arg; + struct firmware_s *fw; }; static void set_frame_info(struct vdec_mjpeg_hw_s *hw, struct vframe_s *vf) @@ -499,9 +501,25 @@ static void vmjpeg_hw_ctx_restore(struct vdec_s *vdec, int index) static s32 vmjpeg_init(struct vdec_s *vdec) { int i; + int size = -1, fw_size = 0x1000 * 16; + struct firmware_s *fw = NULL; struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + size = get_firmware_data(VIDEO_DEC_MJPEG_MULTI, fw->data); + if (size < 0) { + pr_err("get firmware fail."); + vfree(fw); + return -1; + } + + fw->len = size; + hw->fw = fw; + hw->frame_width = hw->vmjpeg_amstream_dec_info.width; hw->frame_height = hw->vmjpeg_amstream_dec_info.height; hw->frame_dur = hw->vmjpeg_amstream_dec_info.rate; @@ -548,10 +566,7 @@ static void run(struct vdec_s *vdec, { struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; - int i,ret = -1,size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; + int i,ret = -1; hw->vdec_cb_arg = arg; hw->vdec_cb = callback; @@ -576,21 +591,11 @@ static void run(struct vdec_s *vdec, hw->dec_result = DEC_RESULT_NONE; - size = get_firmware_data(VIDEO_DEC_MJPEG_MULTI, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return; - } - - if (amvdec_vdec_loadmc_buf_ex(vdec, buf, size) < 0) { + if (amvdec_vdec_loadmc_buf_ex(vdec, hw->fw->data, hw->fw->len) < 0) { pr_err("%s: Error amvdec_loadmc fail\n", __func__); - vfree(buf); return; } - vfree(buf); - vmjpeg_hw_ctx_restore(vdec, i); vdec_enable_input(vdec); @@ -676,6 +681,9 @@ static int amvdec_mjpeg_remove(struct platform_device *pdev) hw->mm_blk_handle = NULL; } + vfree(hw->fw); + hw->fw = NULL; + vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); return 0; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c index dd1ebb59a711..e01184665d31 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c @@ -54,6 +54,7 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC); #include "../utils/amvdec.h" #include "../utils/vdec.h" +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_mpeg12" #define MODULE_NAME "amvdec_mpeg12" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c index a157c49b592f..42afe480a158 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c @@ -58,6 +58,7 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC); #include "../utils/amvdec.h" #include "../utils/vdec.h" +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_mpeg4" #define MODULE_NAME "amvdec_mpeg4" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c index aa6bf819a161..2e34d0280cba 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -40,6 +41,7 @@ #include "../utils/amvdec.h" #include "../utils/vdec_input.h" #include "../utils/vdec.h" +#include "../utils/firmware.h" #define DRIVER_NAME "ammvdec_mpeg4" #define MODULE_NAME "ammvdec_mpeg4" @@ -180,7 +182,7 @@ struct vdec_mpeg4_hw_s { void (*vdec_cb)(struct vdec_s *, void *); void *vdec_cb_arg; - + struct firmware_s *fw; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); @@ -1044,6 +1046,43 @@ static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw) static s32 vmpeg4_init(struct vdec_mpeg4_hw_s *hw) { int trickmode_fffb = 0; + int size = -1, fw_size = 0x1000 * 16; + struct firmware_s *fw = NULL; + + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + if (hw->vmpeg4_amstream_dec_info.format == + VIDEO_DEC_FORMAT_MPEG4_3) { + size = get_firmware_data(VIDEO_DEC_MPEG4_3, fw->data); + + pr_info("load VIDEO_DEC_FORMAT_MPEG4_3\n"); + } else if (hw->vmpeg4_amstream_dec_info.format == + VIDEO_DEC_FORMAT_MPEG4_4) { + size = get_firmware_data(VIDEO_DEC_MPEG4_4, fw->data); + + pr_info("load VIDEO_DEC_FORMAT_MPEG4_4\n"); + } else if (hw->vmpeg4_amstream_dec_info.format == + VIDEO_DEC_FORMAT_MPEG4_5) { + size = get_firmware_data(VIDEO_DEC_MPEG4_5, fw->data); + + pr_info("load VIDEO_DEC_FORMAT_MPEG4_5\n"); + } else if (hw->vmpeg4_amstream_dec_info.format == + VIDEO_DEC_FORMAT_H263) { + size = get_firmware_data(VIDEO_DEC_H263, fw->data); + + pr_info("load VIDEO_DEC_FORMAT_H263\n"); + } + + if (size < 0) { + pr_err("get firmware fail."); + vfree(fw); + return -1; + } + + fw->len = size; + hw->fw = fw; query_video_status(0, &trickmode_fffb); @@ -1071,10 +1110,7 @@ static void run(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *), { struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; int save_reg = READ_VREG(POWER_CTL_VLD); - int ret = -1,size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; + int ret = -1; /* reset everything except DOS_TOP[1] and APB_CBUS[0] */ WRITE_VREG(DOS_SW_RESET0, 0xfffffff0); @@ -1089,7 +1125,6 @@ static void run(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *), pr_debug("amvdec_mpeg4: Input not ready\n"); hw->dec_result = DEC_RESULT_AGAIN; schedule_work(&hw->work); - vfree(buf); return; } @@ -1101,43 +1136,12 @@ static void run(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *), hw->dec_result = DEC_RESULT_NONE; - if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_3) { - size = get_firmware_data(VIDEO_DEC_MPEG4_3, buf); - - pr_info("load VIDEO_DEC_FORMAT_MPEG4_3\n"); - } else if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_4) { - size = get_firmware_data(VIDEO_DEC_MPEG4_4, buf); - - pr_info("load VIDEO_DEC_FORMAT_MPEG4_4\n"); - } else if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_5) { - size = get_firmware_data(VIDEO_DEC_MPEG4_5, buf); - - pr_info("load VIDEO_DEC_FORMAT_MPEG4_5\n"); - } else if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_H263) { - size = get_firmware_data(VIDEO_DEC_H263, buf); - - pr_info("load VIDEO_DEC_FORMAT_H263\n"); - } - - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return; - } - - if (amvdec_vdec_loadmc_buf_ex(vdec, buf, size) < 0) { + if (amvdec_vdec_loadmc_buf_ex(vdec, hw->fw->data, hw->fw->len) < 0) { hw->dec_result = DEC_RESULT_ERROR; schedule_work(&hw->work); - vfree(buf); return; } - vfree(buf); - if (vmpeg4_hw_ctx_restore(hw) < 0) { hw->dec_result = DEC_RESULT_ERROR; pr_err("amvdec_mpeg4: error HW context restore\n"); @@ -1246,6 +1250,9 @@ static int amvdec_mpeg4_remove(struct platform_device *pdev) hw->cma_alloc_count = 0; } + vfree(hw->fw); + hw->fw = NULL; + pr_info("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); pr_info("total frame %d, rate %d\n", hw->total_frame, diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c b/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c index 533d81943fbf..4fed6b7becaa 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c @@ -51,6 +51,7 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_real" #define MODULE_NAME "amvdec_real" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c index 67d80c542eb7..00a17a0abc40 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c @@ -42,7 +42,7 @@ #include #include "amvdec.h" #include -#include "../../../common/firmware/firmware.h" +#include "firmware.h" #define MC_SIZE (4096 * 16) diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h b/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h new file mode 100644 index 000000000000..cf6452181dc9 --- /dev/null +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h @@ -0,0 +1,17 @@ +#ifndef __VIDEO_FIRMWARE_HEADER_ +#define __VIDEO_FIRMWARE_HEADER_ + +#include "../../../common/firmware/firmware_type.h" +#include + +struct firmware_s { + unsigned int len; + char data[0]; +}; + +extern int get_decoder_firmware_data(enum vformat_e type, + const char *file_name, char *buf, int size); +extern int get_data_from_name(const char *name, char *buf); +extern int get_firmware_data(enum firmware_type_e type, char *buf); + +#endif diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c index 64cd6bb5f53b..d66d75cf9fdb 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c @@ -40,6 +40,7 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/firmware.h" #define DRIVER_NAME "amvdec_vc1" #define MODULE_NAME "amvdec_vc1" diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c index 532d80889ba2..fffce3b6a3f3 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c @@ -50,6 +50,7 @@ #include #include #include "../utils/config_parser.h" +#include "../utils/firmware.h" #define MIX_STREAM_SUPPORT #define SUPPORT_4K2K @@ -1313,6 +1314,7 @@ struct VP9Decoder_s { int new_frame_displayed; void *mmu_box; void *bmmu_box; + struct firmware_s *fw; } VP9Decoder; static int vp9_print(struct VP9Decoder_s *pbi, @@ -6592,18 +6594,28 @@ TODO:FOR VERSION static s32 vvp9_init(struct VP9Decoder_s *pbi) { int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; + int fw_size = 0x1000 * 16; + struct firmware_s *fw = NULL; init_timer(&pbi->timer); pbi->stat |= STAT_TIMER_INIT; - if (vvp9_local_init(pbi) < 0) { - vfree(buf); + if (vvp9_local_init(pbi) < 0) return -EBUSY; + + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + size = get_firmware_data(VIDEO_DEC_VP9_MMU, fw->data); + if (size < 0) { + pr_err("get firmware fail.\n"); + vfree(fw); + return -1; } + fw->len = fw_size; + #ifdef MULTI_INSTANCE_SUPPORT if (pbi->m_ins_flag) { pbi->timer.data = (ulong) pbi; @@ -6617,27 +6629,21 @@ static s32 vvp9_init(struct VP9Decoder_s *pbi) INIT_WORK(&pbi->work, vp9_work); - vfree(buf); + pbi->fw = fw; + return 0; } #endif amhevc_enable(); - size = get_firmware_data(VIDEO_DEC_VP9_MMU, buf); - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return -1; - } - - if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, buf) < 0) { + if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, fw->data) < 0) { amhevc_disable(); - vfree(buf); + vfree(fw); return -EBUSY; } - vfree(buf); + vfree(fw); pbi->stat |= STAT_MC_LOAD; @@ -6732,6 +6738,9 @@ static int vvp9_stop(struct VP9Decoder_s *pbi) #endif uninit_mmu_buffers(pbi); + vfree(pbi->fw); + pbi->fw = NULL; + return 0; } @@ -7132,11 +7141,7 @@ static void run(struct vdec_s *vdec, { struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)vdec->private; - int r, size = -1; - - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; + int r; run_count[pbi->index]++; pbi->vdec_cb_arg = arg; @@ -7189,23 +7194,13 @@ static void run(struct vdec_s *vdec, vp9_print_cont(pbi, 0, "\r\n"); } - size = get_firmware_data(VIDEO_DEC_VP9_MMU, buf); - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return; - } - - if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, buf) < 0) { + if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data) < 0) { amhevc_disable(); - vfree(buf); vp9_print(pbi, 0, "%s: Error amvdec_loadmc fail\n", __func__); return; } - vfree(buf); - if (vp9_hw_ctx_restore(pbi) < 0) { vdec_schedule_work(&pbi->work); return; diff --git a/drivers/amlogic/media_modules/frame_sink/encoder/h264/encoder.c b/drivers/amlogic/media_modules/frame_sink/encoder/h264/encoder.c index 9badd5395416..4102fd852847 100644 --- a/drivers/amlogic/media_modules/frame_sink/encoder/h264/encoder.c +++ b/drivers/amlogic/media_modules/frame_sink/encoder/h264/encoder.c @@ -47,6 +47,7 @@ #include "../../../frame_provider/decoder/utils/amvdec.h" #include #include "../../../stream_input/amports/amports_priv.h" +#include "../../../frame_provider/decoder/utils/firmware.h" #include #ifdef CONFIG_AM_JPEG_ENCODER #include "jpegenc.h" diff --git a/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h b/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h index 7ee7859d85b2..08181d19e576 100644 --- a/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h +++ b/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h @@ -20,7 +20,6 @@ #include "../parser/streambuf.h" #include "../../common/media_clock/switch/amports_gate.h" #include -#include "../../common/firmware/firmware.h" #include #include diff --git a/drivers/amlogic/media_modules/stream_input/amports/amstream.c b/drivers/amlogic/media_modules/stream_input/amports/amstream.c index 5277719d3b7b..c9259b56fe39 100644 --- a/drivers/amlogic/media_modules/stream_input/amports/amstream.c +++ b/drivers/amlogic/media_modules/stream_input/amports/amstream.c @@ -75,7 +75,6 @@ #include #include #include -#include "../../common/firmware/firmware.h" #ifdef CONFIG_COMPAT #include #endif