media_modules: merged code from 43177e6a on the amlogic-3.14-dev [2/3]

PD#150739: merged code from 43177e6a on the amlogic-3.14-dev
1.decoder: vmh264, fix multi pic in one packet
2.decoder: add amvdec_stop when error reset
3.clk: switch vdec clk source when suspend

Change-Id: I43b8f5a7a13d880c130505cd21e08c8e1eb4cf38
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
This commit is contained in:
Nanxin Qin
2017-09-08 11:28:41 +08:00
committed by Dongjin Kim
parent 720eaaed05
commit 09bbdb6639
25 changed files with 1241 additions and 369 deletions

View File

View File

View File

@@ -176,6 +176,7 @@ static struct dec_sysinfo vavs_amstream_dec_info;
static struct vdec_info *gvs;
static u32 fr_hint_status;
static struct work_struct notify_work;
static bool is_reset;
#ifdef AVSP_LONG_CABAC
static struct work_struct long_cabac_wd_work;
@@ -778,6 +779,12 @@ int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vavs_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
static int vavs_vdec_info_init(void)
{
gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
@@ -1212,7 +1219,6 @@ static void vavs_fatal_error_handler(struct work_struct *work)
static void vavs_notify_work(struct work_struct *work)
{
pr_info("frame duration changed %d\n", frame_dur);
if (fr_hint_status == VDEC_NEED_HINT) {
vf_notify_receiver(PROVIDER_NAME ,
VFRAME_EVENT_PROVIDER_FR_HINT ,
@@ -1495,10 +1501,11 @@ static s32 vavs_init(void)
#endif
if (vavs_amstream_dec_info.rate != 0) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)
vavs_amstream_dec_info.rate));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)
vavs_amstream_dec_info.rate));
fr_hint_status = VDEC_HINTED;
} else
fr_hint_status = VDEC_NEED_HINT;
@@ -1554,6 +1561,8 @@ static int amvdec_avs_probe(struct platform_device *pdev)
vavs_amstream_dec_info.height, vavs_amstream_dec_info.rate);
pdata->dec_status = vavs_dec_status;
pdata->set_isreset = vavs_set_isreset;
is_reset = 0;
vavs_vdec_info_init();
@@ -1647,7 +1656,7 @@ static int amvdec_avs_remove(struct platform_device *pdev)
}
#endif
if (stat & STAT_VF_HOOK) {
if (fr_hint_status == VDEC_HINTED)
if (fr_hint_status == VDEC_HINTED && !is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
fr_hint_status = VDEC_NO_NEED_HINT;

View File

@@ -52,11 +52,18 @@
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
#include <linux/amlogic/tee.h>
#define DRIVER_NAME "amvdec_h264"
#define MODULE_NAME "amvdec_h264"
#define MEM_NAME "codec_264"
#define HANDLE_H264_IRQ
#if 0
/* currently, only iptv supports this function*/
#define SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
#endif
/* #define DEBUG_PTS */
#if 0 /* MESON_CPU_TYPE <= MESON_CPU_TYPE_MESON6TV */
#define DROP_B_FRAME_FOR_1080P_50_60FPS
@@ -233,6 +240,11 @@ static u32 max_refer_buf = 1;
static u32 decoder_force_reset;
static unsigned int no_idr_error_count;
static unsigned int no_idr_error_max = 60;
#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
/* 0~128*/
static u32 bad_block_scale;
#endif
static unsigned int enable_switch_fense = 1;
#define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k)
#if 0
@@ -245,6 +257,7 @@ static struct vframe_s *p_last_vf;
static s32 iponly_early_mode;
static void *mm_blk_handle;
static int tvp_flag;
static bool is_reset;
/*TODO irq*/
#if 1
@@ -2013,10 +2026,7 @@ static void vh264_isr(void)
fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN;
/* this is fatal error, need restart */
pr_info("fatal error happend\n");
vh264_stream_switching_state = SWITCHING_STATE_ON_CMD3;
amvdec_stop();
pr_info("fatal error switching mode cmd3.\n");
schedule_work(&stream_switching_work);
if (!fatal_error_reset)
schedule_work(&error_wd_work);
} else if ((cpu_cmd & 0xff) == 7) {
@@ -2287,6 +2297,12 @@ int vh264_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
return 0;
}
int vh264_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
static void vh264_prot_init(void)
{
@@ -2332,12 +2348,19 @@ static void vh264_prot_init(void)
WRITE_VREG(AV_SCRATCH_0, 0);
WRITE_VREG(AV_SCRATCH_1, buf_offset);
WRITE_VREG(AV_SCRATCH_G, mc_dma_handle);
if (!is_secload_get())
WRITE_VREG(AV_SCRATCH_G, mc_dma_handle);
WRITE_VREG(AV_SCRATCH_7, 0);
WRITE_VREG(AV_SCRATCH_8, 0);
WRITE_VREG(AV_SCRATCH_9, 0);
WRITE_VREG(AV_SCRATCH_N, 0);
#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
if (bad_block_scale > 128)
bad_block_scale = 128;
WRITE_VREG(AV_SCRATCH_A, bad_block_scale);
#endif
error_recovery_mode_use =
(error_recovery_mode !=
0) ? error_recovery_mode : error_recovery_mode_in;
@@ -2542,7 +2565,12 @@ static s32 vh264_init(void)
query_video_status(0, &trickmode_fffb);
amvdec_enable();
if (!firmwareloaded && is_secload_get()) {
if (tee_load_video_fw((u32)VIDEO_DEC_H264) != 0) {
amvdec_disable();
return -1;
}
} else {
/* -- ucode loading (amrisc and swap code) */
mc_cpu_addr =
dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE,
@@ -2652,6 +2680,7 @@ static s32 vh264_init(void)
return -EBUSY;
}
}
}
stat |= STAT_MC_LOAD;
@@ -2683,9 +2712,10 @@ static s32 vh264_init(void)
#endif
if (frame_dur != 0) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)frame_dur));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)frame_dur));
fr_hint_status = VDEC_HINTED;
} else
fr_hint_status = VDEC_NEED_HINT;
@@ -2738,7 +2768,7 @@ static int vh264_stop(int mode)
if (stat & STAT_VF_HOOK) {
if (mode == MODE_FULL) {
if (fr_hint_status == VDEC_HINTED)
if (fr_hint_status == VDEC_HINTED && !is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
NULL);
@@ -2787,7 +2817,7 @@ static void error_do_work(struct work_struct *work)
* free_irq/deltimer/..and some other.
*/
if (atomic_read(&vh264_active)) {
amvdec_stop();
do {
msleep(20);
} while (vh264_stream_switching_state != SWITCHING_STATE_OFF);
@@ -3001,6 +3031,8 @@ static int amvdec_h264_probe(struct platform_device *pdev)
}
pdata->dec_status = vh264_dec_status;
pdata->set_trickmode = vh264_set_trickmode;
pdata->set_isreset = vh264_set_isreset;
is_reset = 0;
if (vh264_init() < 0) {
pr_info("\namvdec_h264 init failed.\n");
@@ -3163,6 +3195,11 @@ module_param(enable_switch_fense, uint, 0664);
MODULE_PARM_DESC(enable_switch_fense,
"\n enable switch fense\n");
#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
module_param(bad_block_scale, uint, 0664);
MODULE_PARM_DESC(bad_block_scale,
"\n print bad_block_scale\n");
#endif
module_init(amvdec_h264_driver_init_module);
module_exit(amvdec_h264_driver_remove_module);

View File

@@ -1363,8 +1363,9 @@ static s32 vh264_4k2k_init(void)
stat |= STAT_TIMER_INIT;
vh264_4k2k_local_init();
ret = vh264_4k2k_local_init();
if (ret < 0)
return ret;
amvdec_enable();
/* -- ucode loading (amrisc and swap code) */

View File

@@ -44,6 +44,7 @@
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
#include <linux/amlogic/tee.h>
#define TIME_TASK_PRINT_ENABLE 0x100
#define PUT_PRINT_ENABLE 0x200
@@ -1403,45 +1404,52 @@ static s32 vh264mvc_init(void)
amvdec_enable();
/* -- ucode loading (amrisc and swap code) */
mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(),
MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL);
if (!mc_cpu_addr) {
amvdec_disable();
if (is_secload_get()) {
if (tee_load_video_fw((u32)VIDEO_DEC_H264_MVC) != 0) {
amvdec_disable();
return -1;
}
} else {
/* -- ucode loading (amrisc and swap code) */
mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(),
MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL);
if (!mc_cpu_addr) {
amvdec_disable();
vfree(buf);
pr_err("vh264_mvc init: Can not allocate mc memory.\n");
return -ENOMEM;
}
WRITE_VREG(UCODE_START_ADDR, mc_dma_handle);
size = get_firmware_data(VIDEO_DEC_H264_MVC, buf);
if (size < 0) {
pr_err("get firmware fail.");
vfree(buf);
return -1;
}
ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf);
/*header*/
memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000);
/*mmco*/
memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000);
/*slice*/
memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000);
vfree(buf);
pr_err("vh264_mvc init: Can not allocate mc memory.\n");
return -ENOMEM;
if (ret < 0) {
amvdec_disable();
dma_free_coherent(amports_get_dma_device(),
MC_TOTAL_SIZE,
mc_cpu_addr, mc_dma_handle);
mc_cpu_addr = NULL;
return -EBUSY;
}
}
WRITE_VREG(UCODE_START_ADDR, mc_dma_handle);
size = get_firmware_data(VIDEO_DEC_H264_MVC, buf);
if (size < 0) {
pr_err("get firmware fail.");
vfree(buf);
return -1;
}
ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf);
/*header*/
memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000);
/*mmco*/
memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000);
/*slice*/
memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000);
vfree(buf);
if (ret < 0) {
amvdec_disable();
dma_free_coherent(amports_get_dma_device(),
MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle);
mc_cpu_addr = NULL;
return -EBUSY;
}
stat |= STAT_MC_LOAD;
/* enable AMRISC side protocol */

View File

@@ -58,6 +58,7 @@ unsigned char dpb_is_debug(int index, int debug_flag)
"%s(%d): listXsize[%d] %d is larger than max size\r\n",\
__func__, __LINE__, mark, list_size);\
list_size = 0; \
p_H264_Dpb->dpb_error_flag = __LINE__;\
} \
}
@@ -286,11 +287,12 @@ void ref_pic_list_reordering(struct h264_dpb_stru *p_H264_Dpb,
/* set reference index of redundant slices. */
/*
if (currSlice->redundant_pic_cnt && (currSlice->slice_type != I_SLICE))
{
currSlice->redundant_slice_ref_idx =
currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1;
}*/
*if(currSlice->redundant_pic_cnt && (currSlice->slice_type != I_SLICE))
*{
*currSlice->redundant_slice_ref_idx =
* currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1;
*}
*/
}
void slice_prepare(struct h264_dpb_stru *p_H264_Dpb,
@@ -422,10 +424,14 @@ void slice_prepare(struct h264_dpb_stru *p_H264_Dpb,
pSlice->structure,
pSlice->picture_structure_mmco);
#ifdef ERROR_CHECK
if (pSlice->num_ref_idx_active[LIST_0] >= MAX_LIST_SIZE)
if (pSlice->num_ref_idx_active[LIST_0] >= MAX_LIST_SIZE) {
pSlice->num_ref_idx_active[LIST_0] = MAX_LIST_SIZE - 1;
if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE)
p_H264_Dpb->dpb_error_flag = __LINE__;
}
if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE) {
pSlice->num_ref_idx_active[LIST_1] = MAX_LIST_SIZE - 1;
p_H264_Dpb->dpb_error_flag = __LINE__;
}
#endif
#if 1
@@ -973,6 +979,49 @@ static void init_picture(struct h264_dpb_stru *p_H264_Dpb,
}
void dump_pic(struct h264_dpb_stru *p_H264_Dpb)
{
int ii;
struct StorablePicture *pic;
for (ii = 0; ii < MAX_PIC_BUF_NUM; ii++) {
pic = &(p_H264_Dpb->m_PIC[ii]);
if (pic->is_used) {
dpb_print(p_H264_Dpb->decoder_index, 0,
"pic(%d,%d) poc %d is_used %d bufspec %d colbuf %d for_ref %d long_term %d pre_out %d output %d nonexist %d data_flag 0x%x\n",
ii, pic->index,
pic->poc,
pic->is_used,
pic->buf_spec_num,
pic->colocated_buf_index,
pic->used_for_reference,
pic->is_long_term,
pic->pre_output,
pic->is_output,
pic->non_existing,
pic->data_flag);
}
}
}
/*
static void is_pic_used_by_dpb(struct h264_dpb_stru *p_H264_Dpb,
struct StorablePicture *pic)
{
struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
unsigned i;
for (i = 0; i < p_Dpb->used_size; i++) {
if (p_Dpb->fs[i]->top_field == pic ||
p_Dpb->fs[i]->bottom_field == pic ||
p_Dpb->fs[i]->frame == pic
)
break;
}
if (i < p_Dpb->used_size)
return 1;
return 0;
}
*/
static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb,
enum PictureStructure structure, unsigned char is_output)
{
@@ -1029,24 +1078,27 @@ static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb,
s->top_poc = s->bottom_poc = s->poc = 0;
s->seiHasTone_mapping = 0;
s->frame_mbs_only_flag = p_Vid->active_sps->frame_mbs_only_flag;
if (!p_Vid->active_sps->frame_mbs_only_flag &&
structure != FRAME) {
int i, j;
for (j = 0; j < MAX_NUM_SLICES; j++) {
for (i = 0; i < 2; i++) {
/* s->listX[j][i] =
calloc(MAX_LIST_SIZE,
sizeof (struct StorablePicture *));
+1 for reordering ???
if (NULL == s->listX[j][i])
no_mem_exit("alloc_storable_picture:
s->listX[i]"); */
/*
*s->listX[j][i] =
*calloc(MAX_LIST_SIZE,
*sizeof (struct StorablePicture *));
*+1 for reordering ???
*
*if (NULL==s->listX[j][i])
* no_mem_exit("alloc_storable_picture:s->listX[i]");
*/
}
}
}
}
} else
p_H264_Dpb->buf_alloc_fail = 1;
dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
"%s %p\n", __func__, s);
return s;
@@ -1204,16 +1256,16 @@ static void init_dpb(struct h264_dpb_stru *p_H264_Dpb, int type)
p_Dpb->fs_ilref[0] = NULL;
#endif
/*
for (i = 0; i < 6; i++)
{
currSlice->listX[i] =
calloc(MAX_LIST_SIZE, sizeof (struct StorablePicture *));
+1 for reordering
if (NULL == currSlice->listX[i])
no_mem_exit("init_dpb: currSlice->listX[i]");
}
*/
/*
* for (i = 0; i < 6; i++)
* {
* currSlice->listX[i] =
* calloc(MAX_LIST_SIZE, sizeof (struct StorablePicture *));
* +1 for reordering
* if (NULL==currSlice->listX[i])
* no_mem_exit("init_dpb: currSlice->listX[i]");
* }
*/
/* allocate a dummy storable picture */
if (!p_Vid->no_reference_picture) {
p_Vid->no_reference_picture = get_new_pic(p_H264_Dpb,
@@ -1453,7 +1505,7 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
/* rain */
/* p->buf_spec_num = fs->index; */
p->data_flag = data_flag;
fs->data_flag = data_flag;
fs->data_flag |= data_flag;
fs->buf_spec_num = p->buf_spec_num;
fs->colocated_buf_index = p->colocated_buf_index;
#endif
@@ -1633,13 +1685,13 @@ int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb,
return -1;
}
static void update_pic_num(struct Slice *currSlice)
static void update_pic_num(struct h264_dpb_stru *p_H264_Dpb)
{
unsigned int i;
struct Slice *currSlice = &p_H264_Dpb->mSlice;
struct VideoParameters *p_Vid = currSlice->p_Vid;
struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;
struct SPSParameters *active_sps = p_Vid->active_sps;
int add_top = 0, add_bottom = 0;
int max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
@@ -1647,8 +1699,10 @@ static void update_pic_num(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL ||
p_Dpb->fs_ref[i]->frame == NULL)
p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_used == 3) {
if ((p_Dpb->fs_ref[i]->frame->
@@ -1675,8 +1729,10 @@ static void update_pic_num(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ltref[i] == NULL ||
p_Dpb->fs_ltref[i]->frame == NULL)
p_Dpb->fs_ltref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ltref[i]->is_used == 3) {
if (p_Dpb->fs_ltref[i]->frame->is_long_term) {
@@ -1698,8 +1754,10 @@ static void update_pic_num(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference) {
if (p_Dpb->fs_ref[i]->frame_num > currSlice->
@@ -1713,8 +1771,12 @@ static void update_pic_num(struct Slice *currSlice)
}
if (p_Dpb->fs_ref[i]->is_reference & 1) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->top_field == NULL)
if (p_Dpb->fs_ref[i]->top_field
== NULL) {
p_H264_Dpb->dpb_error_flag =
__LINE__;
continue;
}
#endif
p_Dpb->fs_ref[i]->top_field->
pic_num = (2 * p_Dpb->fs_ref[i]->
@@ -1723,8 +1785,11 @@ static void update_pic_num(struct Slice *currSlice)
if (p_Dpb->fs_ref[i]->is_reference & 2) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->bottom_field
== NULL)
== NULL) {
p_H264_Dpb->dpb_error_flag =
__LINE__;
continue;
}
#endif
p_Dpb->fs_ref[i]->bottom_field->
pic_num = (2 * p_Dpb->fs_ref[i]->
@@ -1735,13 +1800,17 @@ static void update_pic_num(struct Slice *currSlice)
/* update long_term_pic_num */
for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ltref[i] == NULL)
if (p_Dpb->fs_ltref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ltref[i]->is_long_term & 1) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ltref[i]->top_field == NULL)
if (p_Dpb->fs_ltref[i]->top_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
p_Dpb->fs_ltref[i]->top_field->
long_term_pic_num = 2 *
@@ -1750,8 +1819,10 @@ static void update_pic_num(struct Slice *currSlice)
}
if (p_Dpb->fs_ltref[i]->is_long_term & 2) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ltref[i]->bottom_field == NULL)
if (p_Dpb->fs_ltref[i]->bottom_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
p_Dpb->fs_ltref[i]->bottom_field->
long_term_pic_num = 2 *
@@ -1797,6 +1868,7 @@ static void remove_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb, int pos)
dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
"invalid frame store type %x", 500);
}
fs->data_flag = 0;
fs->is_used = 0;
fs->is_long_term = 0;
fs->is_reference = 0;
@@ -2050,7 +2122,15 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
#endif
if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0)
p_Dpb->fs[pos]->pre_output = 1;
else {
dpb_print(p_H264_Dpb->decoder_index, 0,
"%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n",
__func__, pos, poc,
p_Dpb->last_output_poc,
p_H264_Dpb->poc_even_odd_flag);
dump_dpb(p_Dpb, 1);
return 0;
}
dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
"%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n",
__func__, pos, poc,
@@ -2259,6 +2339,7 @@ static void idr_memory_management(struct h264_dpb_stru *p_H264_Dpb,
__func__, p_Dpb->ref_frames_in_buffer,
p_Dpb->ltref_frames_in_buffer);
if (p->no_output_of_prior_pics_flag) {
#if 0
/*???*/
@@ -2369,13 +2450,16 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force)
"(");
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
"fn=%d ", p_Dpb->fs[i]->frame_num);
"fn=%d is_used %d ",
p_Dpb->fs[i]->frame_num,
p_Dpb->fs[i]->is_used);
if (p_Dpb->fs[i]->is_used & 1) {
if (p_Dpb->fs[i]->top_field)
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
"T: poc=%d ",
p_Dpb->fs[i]->top_field->poc);
"T: poc=%d pic_num=%d ",
p_Dpb->fs[i]->top_field->poc,
p_Dpb->fs[i]->top_field->pic_num);
else
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
@@ -2386,8 +2470,9 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force)
if (p_Dpb->fs[i]->bottom_field)
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
"B: poc=%d ",
p_Dpb->fs[i]->bottom_field->poc);
"B: poc=%d pic_num=%d ",
p_Dpb->fs[i]->bottom_field->poc,
p_Dpb->fs[i]->bottom_field->pic_num);
else
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
@@ -2397,8 +2482,9 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force)
if (p_Dpb->fs[i]->is_used == 3)
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
"F: poc=%d ",
p_Dpb->fs[i]->frame->poc);
"F: poc=%d pic_num=%d ",
p_Dpb->fs[i]->frame->poc,
p_Dpb->fs[i]->frame->pic_num);
dpb_print_cont(p_H264_Dpb->decoder_index,
0,
"G: poc=%d) ", p_Dpb->fs[i]->poc);
@@ -2443,7 +2529,6 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force)
}
}
/*!
************************************************************************
* \brief
@@ -2475,6 +2560,8 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer
*p_Dpb, struct StorablePicture *p,
int difference_of_pic_nums_minus1)
{
struct h264_dpb_stru *p_H264_Dpb =
container_of(p_Dpb, struct h264_dpb_stru, mDPB);
int picNumX;
unsigned int i;
@@ -2483,15 +2570,19 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p->structure == FRAME) {
if ((p_Dpb->fs_ref[i]->is_reference == 3) &&
(p_Dpb->fs_ref[i]->is_long_term == 0)) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->frame == NULL)
if (p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->frame->pic_num ==
picNumX) {
@@ -2504,8 +2595,10 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer
if ((p_Dpb->fs_ref[i]->is_reference & 1) &&
(!(p_Dpb->fs_ref[i]->is_long_term & 1))) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->top_field == NULL)
if (p_Dpb->fs_ref[i]->top_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->top_field->pic_num ==
picNumX) {
@@ -2526,8 +2619,10 @@ static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer
if ((p_Dpb->fs_ref[i]->is_reference & 2) &&
(!(p_Dpb->fs_ref[i]->is_long_term & 2))) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->bottom_field == NULL)
if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->bottom_field->pic_num ==
picNumX) {
@@ -2758,13 +2853,17 @@ static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb,
if (p->structure == FRAME) {
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference == 3) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->frame == NULL)
if (p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((!p_Dpb->fs_ref[i]->frame->
is_long_term) &&
@@ -2822,13 +2921,17 @@ static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb,
}
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference & 1) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->top_field == NULL)
if (p_Dpb->fs_ref[i]->top_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((!p_Dpb->fs_ref[i]->top_field->
is_long_term) &&
@@ -2877,8 +2980,10 @@ static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb,
}
if (p_Dpb->fs_ref[i]->is_reference & 2) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->bottom_field == NULL)
if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((!p_Dpb->fs_ref[i]->bottom_field->
is_long_term) &&
@@ -2956,13 +3061,17 @@ static void mm_assign_long_term_frame_idx(struct DecodedPictureBuffer *p_Dpb,
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference & 1) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->top_field == NULL)
if (p_Dpb->fs_ref[i]->top_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->top_field->
pic_num == picNumX) {
@@ -2972,8 +3081,10 @@ static void mm_assign_long_term_frame_idx(struct DecodedPictureBuffer *p_Dpb,
}
if (p_Dpb->fs_ref[i]->is_reference & 2) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->bottom_field == NULL)
if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->bottom_field->
pic_num == picNumX) {
@@ -3200,7 +3311,6 @@ void store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
p_Vid->last_has_mmco_5 = 0;
p_Vid->last_pic_bottom_field = (p->structure == BOTTOM_FIELD);
if (p->idr_flag) {
idr_memory_management(p_H264_Dpb, p);
#if 0
@@ -3922,8 +4032,10 @@ static void init_lists_p_slice(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL ||
p_Dpb->fs_ref[i]->frame == NULL)
p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_used == 3) {
if ((p_Dpb->fs_ref[i]->frame->
@@ -3983,8 +4095,10 @@ static void init_lists_p_slice(struct Slice *currSlice)
#endif
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference)
fs_list0[list0idx++] = p_Dpb->fs_ref[i];
@@ -4090,12 +4204,12 @@ static void init_lists_p_slice(struct Slice *currSlice)
*
************************************************************************
*/
static void init_mbaff_lists(struct VideoParameters *p_Vid,
static void init_mbaff_lists(struct h264_dpb_stru *p_H264_Dpb,
struct Slice *currSlice)
{
unsigned j;
int i;
struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
for (i = 2; i < 6; i++) {
for (j = 0; j < MAX_LIST_SIZE; j++)
currSlice->listX[i][j] = p_Vid->no_reference_picture;
@@ -4105,6 +4219,7 @@ static void init_mbaff_lists(struct VideoParameters *p_Vid,
for (i = 0; i < currSlice->listXsize[0]; i++) {
#ifdef ERROR_CHECK
if (currSlice->listX[0][i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
pr_info(
"error currSlice->listX[0][%d] is NULL\r\n", i);
break;
@@ -4125,6 +4240,7 @@ static void init_mbaff_lists(struct VideoParameters *p_Vid,
for (i = 0; i < currSlice->listXsize[1]; i++) {
#ifdef ERROR_CHECK
if (currSlice->listX[1][i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
pr_info(
"error currSlice->listX[1][%d] is NULL\r\n", i);
break;
@@ -4186,8 +4302,10 @@ static void init_lists_b_slice(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL ||
p_Dpb->fs_ref[i]->frame == NULL)
p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((p_Dpb->fs_ref[i]->is_used == 3) &&
((p_Dpb->fs_ref[i]->frame->
@@ -4212,8 +4330,10 @@ static void init_lists_b_slice(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL ||
p_Dpb->fs_ref[i]->frame == NULL)
p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((p_Dpb->fs_ref[i]->is_used == 3) &&
((p_Dpb->fs_ref[i]->frame->
@@ -4344,8 +4464,10 @@ static void init_lists_b_slice(struct Slice *currSlice)
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_used) {
if (currSlice->ThisPOC >=
@@ -4361,8 +4483,10 @@ static void init_lists_b_slice(struct Slice *currSlice)
list0idx_1 = list0idx;
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_used) {
if (currSlice->ThisPOC <
@@ -4558,17 +4682,22 @@ static struct StorablePicture *get_short_term_pic(struct Slice *currSlice,
struct DecodedPictureBuffer *p_Dpb, int picNum)
{
unsigned i;
struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
struct h264_dpb_stru, mDPB);
for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
if (currSlice->structure == FRAME) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference == 3) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->frame == NULL)
if (p_Dpb->fs_ref[i]->frame == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((!p_Dpb->fs_ref[i]->frame->
is_long_term) &&
@@ -4578,13 +4707,17 @@ static struct StorablePicture *get_short_term_pic(struct Slice *currSlice,
}
} else {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i] == NULL)
if (p_Dpb->fs_ref[i] == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if (p_Dpb->fs_ref[i]->is_reference & 1) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->top_field == NULL)
if (p_Dpb->fs_ref[i]->top_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((!p_Dpb->fs_ref[i]->top_field->
is_long_term) &&
@@ -4594,8 +4727,10 @@ static struct StorablePicture *get_short_term_pic(struct Slice *currSlice,
}
if (p_Dpb->fs_ref[i]->is_reference & 2) {
#ifdef ERROR_CHECK
if (p_Dpb->fs_ref[i]->bottom_field == NULL)
if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
p_H264_Dpb->dpb_error_flag = __LINE__;
continue;
}
#endif
if ((!p_Dpb->fs_ref[i]->bottom_field->
is_long_term) &&
@@ -4816,7 +4951,6 @@ static void reorder_ref_pic_list(struct Slice *currSlice, int cur_list)
(char)(num_ref_idx_lX_active_minus1 + 1);
}
static void reorder_lists(struct Slice *currSlice)
{
struct VideoParameters *p_Vid = currSlice->p_Vid;
@@ -4851,11 +4985,11 @@ static void reorder_lists(struct Slice *currSlice)
PRINT_FLAG_DPB_DETAIL,
"listX[0] reorder (PicNum): ");
for (i = 0; i < currSlice->listXsize[0]; i++) {
dpb_print(p_H264_Dpb->decoder_index,
dpb_print_cont(p_H264_Dpb->decoder_index,
PRINT_FLAG_DPB_DETAIL, "%d ",
currSlice->listX[0][i]->pic_num);
}
dpb_print(p_H264_Dpb->decoder_index,
dpb_print_cont(p_H264_Dpb->decoder_index,
PRINT_FLAG_DPB_DETAIL, "\n");
}
}
@@ -4886,11 +5020,11 @@ static void reorder_lists(struct Slice *currSlice)
PRINT_FLAG_DPB_DETAIL,
"listX[1] reorder (PicNum): ");
for (i = 0; i < currSlice->listXsize[1]; i++) {
dpb_print(p_H264_Dpb->decoder_index,
dpb_print_cont(p_H264_Dpb->decoder_index,
PRINT_FLAG_DPB_DETAIL, "%d ",
currSlice->listX[1][i]->pic_num);
}
dpb_print(p_H264_Dpb->decoder_index,
dpb_print_cont(p_H264_Dpb->decoder_index,
PRINT_FLAG_DPB_DETAIL, "\n");
}
}
@@ -5013,8 +5147,10 @@ int allocate_colocate_buf(struct h264_dpb_stru *p_H264_Dpb)
break;
}
}
if (i == p_H264_Dpb->colocated_buf_count)
if (i == p_H264_Dpb->colocated_buf_count) {
i = -1;
p_H264_Dpb->buf_alloc_fail = 1;
}
return i;
}
@@ -5261,7 +5397,8 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb)
#else
new_pic_flag = (p_H264_Dpb->mVideo.dec_picture == NULL);
#endif
p_H264_Dpb->buf_alloc_fail = 0;
p_H264_Dpb->dpb_error_flag = 0;
slice_prepare(p_H264_Dpb, &p_H264_Dpb->mDPB, &p_H264_Dpb->mVideo,
&p_H264_Dpb->mSPS, &p_H264_Dpb->mSlice);
@@ -5338,7 +5475,7 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb)
p_H264_Dpb->mVideo.dec_picture->buf_spec_num = -1;
p_H264_Dpb->mVideo.dec_picture->
colocated_buf_index = -1;
update_pic_num(&p_H264_Dpb->mSlice);
update_pic_num(p_H264_Dpb);
if ((currSlice->structure == TOP_FIELD) ||
(currSlice->structure == BOTTOM_FIELD)) {
@@ -5352,6 +5489,10 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb)
-1) {
p_H264_Dpb->mVideo.dec_picture->buf_spec_num =
get_free_buf_idx(p_H264_Dpb->vdec);
if (p_H264_Dpb->mVideo.dec_picture->buf_spec_num
< 0)
p_H264_Dpb->buf_alloc_fail = 1;
if (p_H264_Dpb->mVideo.dec_picture->
used_for_reference) {
p_H264_Dpb->mVideo.dec_picture->
@@ -5374,10 +5515,90 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb)
reorder_lists(&p_H264_Dpb->mSlice);
if (p_H264_Dpb->mSlice.structure == FRAME)
init_mbaff_lists(&p_H264_Dpb->mVideo, &p_H264_Dpb->mSlice);
init_mbaff_lists(p_H264_Dpb, &p_H264_Dpb->mSlice);
if (new_pic_flag)
return 1;
return 0;
}
enum PictureStructure get_cur_slice_picture_struct(
struct h264_dpb_stru *p_H264_Dpb)
{
struct Slice *currSlice = &p_H264_Dpb->mSlice;
return currSlice->structure;
}
static unsigned char is_pic_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
struct StorablePicture *pic)
{
unsigned char ret = 0;
int i;
struct DecodedPictureBuffer *p_Dpb =
&p_H264_Dpb->mDPB;
for (i = 0; i < p_Dpb->used_size; i++) {
if (p_Dpb->fs[i]->top_field == pic ||
p_Dpb->fs[i]->bottom_field == pic ||
p_Dpb->fs[i]->frame == pic) {
ret = 1;
break;
}
}
return ret;
}
int dpb_check_ref_list_error(
struct h264_dpb_stru *p_H264_Dpb)
{
int i;
/*int j;*/
struct Slice *currSlice = &p_H264_Dpb->mSlice;
if ((currSlice->slice_type != I_SLICE) &&
(currSlice->slice_type != SI_SLICE)) {
for (i = 0; i < currSlice->listXsize[0]; i++) {
/*for (j = i + 1; j < currSlice->listXsize[0]; j++) {
if(currSlice->listX[0][i]->pic_num ==
currSlice->listX[0][j]->pic_num)
return 1;
}*/
if (!is_pic_in_dpb(p_H264_Dpb,
currSlice->listX[0][i]))
return 1;
if (currSlice->listX[0][i]->frame &&
currSlice->listX[0][i]->frame->non_existing)
return 3;
}
}
if (currSlice->slice_type == B_SLICE) {
for (i = 0; i < currSlice->listXsize[1]; i++) {
/*for (j = i + 1; j < currSlice->listXsize[1]; j++) {
if(currSlice->listX[1][i]->pic_num ==
currSlice->listX[1][j]->pic_num)
return 2;
}
for (j = 0; j < currSlice->listXsize[0]; j++) {
if(currSlice->listX[1][i]->pic_num ==
currSlice->listX[0][j]->pic_num)
return 3;
}*/
if (!is_pic_in_dpb(p_H264_Dpb,
currSlice->listX[1][i]))
return 2;
if (currSlice->listX[1][i]->frame &&
currSlice->listX[1][i]->frame->non_existing)
return 4;
#if 0
if (currSlice->listXsize[0] == 1 &&
currSlice->listXsize[1] == 1 &&
currSlice->listX[1][0] ==
currSlice->listX[0][0])
return 3;
#endif
}
}
return 0;
}

View File

@@ -16,6 +16,7 @@
#define PRINT_FRAMEBASE_DATA 0x0100
#define PRINT_FLAG_DEBUG_POC 0x0200
#define RRINT_FLAG_RPM 0x0400
#define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800
#define DISABLE_ERROR_HANDLE 0x10000
#define DEBUG_DUMP_STAT 0x80000
@@ -769,6 +770,8 @@ struct h264_dpb_stru {
unsigned int aspect_ratio_sar_height;
unsigned int dec_dpb_status;
unsigned char buf_alloc_fail;
unsigned int dpb_error_flag;
};
@@ -821,4 +824,11 @@ void print_pic_info(int decindex, const char *info,
int slice_type);
void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force);
void dump_pic(struct h264_dpb_stru *p_H264_Dpb);
enum PictureStructure get_cur_slice_picture_struct(
struct h264_dpb_stru *p_H264_Dpb);
int dpb_check_ref_list_error(
struct h264_dpb_stru *p_H264_Dpb);
#endif

View File

@@ -53,6 +53,7 @@
#include "../utils/decoder_mmu_box.h"
#include "../utils/decoder_bmmu_box.h"
#include "../utils/firmware.h"
#include <linux/amlogic/tee.h>
#undef pr_info
#define pr_info printk
@@ -131,6 +132,7 @@ static unsigned int reference_buf_margin = 4;
static unsigned int max_alloc_buf_count;
static unsigned int decode_timeout_val = 100;
static unsigned int errordata_timeout_val = 50;
static unsigned int get_data_timeout_val = 2000;
static unsigned int frame_max_data_packet = 8;
@@ -206,13 +208,16 @@ static unsigned int i_only_flag;
bit[3] force sliding window ref_frames_in_buffer > num_ref_frames
bit[4] check inactive of receiver
bit[5] reset buffmgr if in deadlock
bit[6] reset buffmgr if bufspec, collocate buf, pic alloc fail
bit[8] check total mbx/mby of decoded frame
bit[9] check ERROR_STATUS_REG
bit[10] check reference list
bit[11] mark error if dpb error
bit[12] i_only when error happen
*/
static unsigned int error_proc_policy = 0x1214; /*0xc;*/
static unsigned int error_proc_policy = 0x1f14; /*0xc;*/
/*
error_skip_count:
@@ -240,14 +245,25 @@ static unsigned int first_i_policy = (15 << 8) | 2;
bit [2], if even poc only, output frame ifthe cuurent poc
is 2 big than the previous poc
*/
static unsigned int fast_output_enable = 3;
static unsigned int fast_output_enable;
static unsigned int enable_itu_t35 = 1;
static unsigned int frmbase_cont_bitlevel = 0x40;
static unsigned int frmbase_cont_bitlevel2 = 0x1;
static void vmh264_dump_state(struct vdec_s *vdec);
#define is_in_parsing_state(status) \
((status == H264_ACTION_SEARCH_HEAD) || \
((status & 0xf0) == 0x80))
#define is_interlace(frame) \
(frame->frame &&\
frame->top_field &&\
frame->bottom_field &&\
(!frame->frame->coded_frame))
static inline bool close_to(int a, int b, int m)
{
return (abs(a - b) < m) ? true : false;
@@ -289,6 +305,7 @@ u32 V_BUF_ADDR_OFFSET = 0x200000;
#define BUFSPEC_POOL_SIZE 64
#define VF_POOL_SIZE 64
#define VF_POOL_NUM 2
#define MAX_VF_BUF_NUM 27
#define BMMU_MAX_BUFFERS (BUFSPEC_POOL_SIZE + 3)
#define BMMU_REF_IDX (BUFSPEC_POOL_SIZE)
@@ -308,8 +325,7 @@ u32 V_BUF_ADDR_OFFSET = 0x200000;
#define SWITCHING_STATE_ON_CMD3 1
#define SWITCHING_STATE_ON_CMD1 2
#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001
#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002
#define INCPTR(p) ptr_atomic_wrap_inc(&p)
@@ -327,6 +343,8 @@ struct buffer_spec_s {
3, in disp queue, isolated,
do not use for dpb when vf_put;
4, to release
5, in disp queue, isolated (but not to release)
do not use for dpb when vf_put;
*/
int used;
unsigned int info0;
@@ -512,7 +530,8 @@ struct vdec_h264_hw_s {
DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
struct vframe_s vfpool[VF_POOL_SIZE];
int cur_pool;
struct vframe_s vfpool[VF_POOL_NUM][VF_POOL_SIZE];
struct buffer_spec_s buffer_spec[BUFSPEC_POOL_SIZE];
struct vframe_s switching_fense_vf;
struct h264_dpb_stru dpb;
@@ -550,7 +569,6 @@ struct vdec_h264_hw_s {
u32 video_signal_from_vui; /*to do .. */
u32 timing_info_present_flag;
u32 fixed_frame_rate_flag;
u32 fixed_frame_rate_check_count;
u32 iframe_count;
u32 aspect_ratio_info;
u32 num_units_in_tick;
@@ -562,9 +580,8 @@ struct vdec_h264_hw_s {
u32 pts_duration;
u32 h264_pts_count;
u32 duration_from_pts_done;
u32 pts_unstable; u32 duration_on_correcting;
u32 pts_unstable;
u32 last_checkout_pts;
u32 fatal_error_flag;
u32 max_refer_buf;
s32 vh264_stream_switching_state;
@@ -572,7 +589,6 @@ struct vdec_h264_hw_s {
u32 last_pts;
u32 last_pts_remainder;
u32 last_duration;
u32 saved_resolution;
u32 last_mb_width, last_mb_height;
bool check_pts_discontinue;
bool pts_discontinue;
@@ -659,6 +675,11 @@ struct vdec_h264_hw_s {
u32 ucode_pause_pos;
u8 reset_bufmgr_flag;
u32 reset_bufmgr_count;
u32 cfg_param1;
u32 cfg_param2;
u32 cfg_param3;
u32 cfg_param4;
struct firmware_s *fw;
};
@@ -1036,10 +1057,11 @@ static void hevc_sao_set_pic_buffer(struct vdec_h264_hw_s *hw,
PRINT_FLAG_MMU_DETAIL,
"release unused buf , used_4k_num %ld index %d\n",
used_4k_num, hw->hevc_cur_buf_idx);
decoder_mmu_box_free_idx_tail(
hw->mmu_box,
hw->hevc_cur_buf_idx,
used_4k_num);
decoder_mmu_box_free_idx_tail(
hw->mmu_box,
hw->hevc_cur_buf_idx,
used_4k_num);
hw->hevc_cur_buf_idx = 0xffff;
}
WRITE_VREG(CURR_CANVAS_CTRL, pic->buf_spec_num << 24);
@@ -1120,11 +1142,15 @@ static void hevc_set_unused_4k_buff_idx(struct vdec_h264_hw_s *hw,
static void hevc_set_frame_done(struct vdec_h264_hw_s *hw)
{
ulong timeout = jiffies + HZ;
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL, "hevc_frame_done...set\n");
while ((READ_VREG(HEVC_SAO_INT_STATUS) & 0x1) == 0) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL, " %s...wait\n", __func__);
if (time_after(jiffies, timeout)) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL, " %s..timeout!\n", __func__);
break;
}
}
WRITE_VREG(HEVC_SAO_INT_STATUS, 0x1);
hw->frame_done = 1;
@@ -1133,19 +1159,28 @@ static void hevc_set_frame_done(struct vdec_h264_hw_s *hw)
static void hevc_sao_wait_done(struct vdec_h264_hw_s *hw)
{
ulong timeout = jiffies + HZ;
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL, "hevc_sao_wait_done...start\n");
while ((READ_VREG(HEVC_SAO_INT_STATUS) >> 31))
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL, "hevc_sao_wait_done...wait\n");
while ((READ_VREG(HEVC_SAO_INT_STATUS) >> 31)) {
if (time_after(jiffies, timeout)) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL,
"hevc_sao_wait_done...wait timeout!\n");
break;
}
}
timeout = jiffies + HZ;
if ((hw->frame_busy == 1) && (hw->frame_done == 1)) {
WRITE_VREG(SYS_COMMAND, H265_ABORT_SAO_4K_SET);
while ((READ_VREG(SYS_COMMAND) & 0xff) !=
H265_ABORT_SAO_4K_SET_DONE) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL,
"hevc_sao_wait_done...wait h265_abort_sao_4k_set_done\n");
if (time_after(jiffies, timeout)) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_MMU_DETAIL,
"wait h265_abort_sao_4k_set_done timeout!\n");
break;
}
}
hw->frame_busy = 0;
hw->frame_done = 0;
@@ -1310,6 +1345,11 @@ int get_free_buf_idx(struct vdec_s *vdec)
dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
"%s, buf_spec_num %d\n", __func__, index);
if (index < 0) {
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
"%s fail\n", __func__);
vmh264_dump_state(vdec);
}
return index;
}
@@ -1367,12 +1407,14 @@ static void config_buf_specs(struct vdec_s *vdec)
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
}
void dealloc_buf_specs(struct vdec_h264_hw_s *hw)
static void dealloc_buf_specs(struct vdec_h264_hw_s *hw,
unsigned char release_all)
{
int i;
unsigned long flags;
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
if (hw->buffer_spec[i].used == 4) {
if (hw->buffer_spec[i].used == 4 ||
release_all) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_DPB_DETAIL,
"%s buf_spec_num %d\n",
@@ -1444,7 +1486,7 @@ unsigned char have_free_buf_spec(struct vdec_s *vdec)
}
if (index >= 0) {
mutex_lock(&vmh264_mutex);
dealloc_buf_specs(hw);
dealloc_buf_specs(hw, 0);
if (max_alloc_buf_count == 0 ||
allocated_count < max_alloc_buf_count) {
if (alloc_one_buf_spec(hw, index) >= 0)
@@ -1492,6 +1534,34 @@ static void update_vf_memhandle(struct vdec_h264_hw_s *hw,
}
return;
}
static int check_force_interlace(struct vdec_h264_hw_s *hw,
struct FrameStore *frame)
{
int bForceInterlace = 0;
if (frame->frame) {
if (frame->frame->coded_frame
&& !frame->frame->frame_mbs_only_flag) {
if (frame->frame->structure == FRAME)
return 1;
}
}
if ((dec_control & DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE)
&& (hw->frame_width == 1920)
&& (hw->frame_height >= 1080)
&& (hw->frame_dur == 3203)) {
bForceInterlace = 1;
} else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE)
&& (hw->frame_width == 720)
&& (hw->frame_height == 576)
&& (hw->frame_dur == 3840)) {
bForceInterlace = 1;
}
return bForceInterlace;
}
int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
{
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
@@ -1499,6 +1569,8 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
int buffer_index = frame->buf_spec_num;
int vf_count = 1;
int i;
int bForceInterlace = 0;
if (buffer_index < 0 || buffer_index >= BUFSPEC_POOL_SIZE) {
dpb_print(DECODE_ID(hw), 0,
"%s, buffer_index 0x%x is beyond range\n",
@@ -1549,13 +1621,13 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
frame->bottom_field, -1);
}
if (frame->frame == NULL ||
frame->top_field == NULL ||
frame->bottom_field == NULL ||
frame->frame->coded_frame)
if (!is_interlace(frame))
vf_count = 1;
else
vf_count = 2;
bForceInterlace = check_force_interlace(hw, frame);
if (bForceInterlace)
vf_count = 2;
hw->buffer_spec[buffer_index].vf_ref = 0;
for (i = 0; i < vf_count; i++) {
if (kfifo_get(&hw->newframe_q, &vf) == 0 ||
@@ -1597,14 +1669,20 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
hw->buffer_spec[buffer_index].used = 2;
hw->buffer_spec[buffer_index].vf_ref++;
if (frame->frame &&
frame->top_field &&
frame->bottom_field &&
(!frame->frame->coded_frame)) {
if (bForceInterlace || is_interlace(frame)) {
vf->type =
VIDTYPE_INTERLACE_FIRST |
VIDTYPE_VIU_NV21;
if (frame->top_field->poc <=
if (bForceInterlace) {
vf->type |= (i == 0 ?
VIDTYPE_INTERLACE_TOP :
VIDTYPE_INTERLACE_BOTTOM);
if (i == 1) {
vf->pts = 0;
vf->pts_us64 = 0;
}
} else if (frame->top_field->poc <=
frame->bottom_field->poc) /*top first*/
vf->type |= (i == 0 ?
VIDTYPE_INTERLACE_TOP :
@@ -2482,9 +2560,12 @@ static struct vframe_s *vh264_vf_get(void *op_arg)
1000*(time - hw->last_frame_time)/HZ;
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_VDEC_STATUS)) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int frame_index = FRAME_INDEX(vf->index);
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s buf_spec_num %d vf %p dur %d pts %d interval %dms\n",
"%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms\n",
__func__, BUFSPEC_INDEX(vf->index), vf,
p_H264_Dpb->mFrameStore[frame_index].poc,
vf->duration, vf->pts, frame_interval);
}
if (hw->last_frame_time > 0) {
@@ -2509,7 +2590,12 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
int frame_index;
if (vf == (&hw->vframe_dummy))
return;
if (vf->index == -1) {
dpb_print(DECODE_ID(hw), 0,
"Warning: %s vf %p invalid index\r\n",
__func__, vf);
return;
}
frame_index = FRAME_INDEX(vf->index);
buf_spec_num = BUFSPEC_INDEX(vf->index);
if (frame_index < 0 ||
@@ -2526,8 +2612,8 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
if (hw->buffer_spec[buf_spec_num].used == 2) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s to fs[%d], poc %d buf_spec_num %d used %d vf_ref %d\n",
__func__, frame_index,
"%s %p to fs[%d], poc %d buf_spec_num %d used %d vf_ref %d\n",
__func__, vf, frame_index,
p_H264_Dpb->mFrameStore[frame_index].poc,
buf_spec_num,
hw->buffer_spec[buf_spec_num].used,
@@ -2538,8 +2624,8 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
} else {
unsigned long flags;
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s isolated vf, buf_spec_num %d used %d vf_ref %d\n",
__func__, buf_spec_num,
"%s %p isolated vf, buf_spec_num %d used %d vf_ref %d\n",
__func__, vf, buf_spec_num,
hw->buffer_spec[buf_spec_num].used,
hw->buffer_spec[buf_spec_num].vf_ref);
spin_lock_irqsave(&hw->bufspec_lock, flags);
@@ -2713,7 +2799,8 @@ static int get_max_dec_frame_buf_size(int level_idc,
return size;
}
static int vh264_set_params(struct vdec_h264_hw_s *hw)
static int vh264_set_params(struct vdec_h264_hw_s *hw,
u32 param1, u32 param2, u32 param3, u32 param4)
{
int i, j;
int mb_width, mb_total;
@@ -2736,8 +2823,8 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw)
used_reorder_dpb_size_margin =
reorder_dpb_size_margin_dv;
#endif
seq_info2 = READ_VREG(AV_SCRATCH_1);
hw->seq_info = READ_VREG(AV_SCRATCH_2);
seq_info2 = param1;
hw->seq_info = param2;
mb_width = seq_info2 & 0xff;
mb_total = (seq_info2 >> 8) & 0xffff;
@@ -2745,7 +2832,9 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw)
mb_width = 256;
mb_height = mb_total/mb_width;
if (mb_width > 0x110 ||
mb_height > 0xa0) {
mb_height > 0xa0 ||
mb_width <= 0 ||
mb_height <= 0) {
dpb_print(DECODE_ID(hw), 0,
"!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
seq_info2,
@@ -2766,6 +2855,11 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw)
if (hw->config_bufmgr_done == 0) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
u32 reg_val;
hw->cfg_param1 = param1;
hw->cfg_param2 = param2;
hw->cfg_param3 = param3;
hw->cfg_param4 = param4;
hw->seq_info2 = seq_info2 & (~0x80000000);
dpb_print(DECODE_ID(hw), 0,
"AV_SCRATCH_1 = %x, AV_SCRATCH_2 %x\r\n",
@@ -2789,11 +2883,12 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw)
/* @AV_SCRATCH_6.31-16 = (left << 8 | right ) << 1
@AV_SCRATCH_6.15-0 = (top << 8 | bottom ) <<
(2 - frame_mbs_only_flag) */
crop_infor = READ_VREG(AV_SCRATCH_6);
crop_infor = param3;
crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag);
crop_right = ((crop_infor >> 16) & 0xff)
>> (2 - frame_mbs_only_flag);
p_H264_Dpb->mSPS.frame_mbs_only_flag = frame_mbs_only_flag;
hw->frame_width = mb_width << 4;
hw->frame_height = mb_height << 4;
if (frame_mbs_only_flag) {
@@ -2836,7 +2931,7 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw)
hevc_mcr_sao_global_hw_init(hw,
hw->frame_width, hw->frame_height);
reg_val = READ_VREG(AV_SCRATCH_B);
reg_val = param4;
level_idc = reg_val & 0xff;
max_reference_size = (reg_val >> 8) & 0xff;
dpb_print(DECODE_ID(hw), 0,
@@ -2960,11 +3055,6 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw)
/*end of config_bufmgr_done */
}
WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
(hw->dpb.mDPB.size<<16) |
(hw->dpb.mDPB.size<<8));
return ret;
}
@@ -3187,6 +3277,10 @@ static bool is_buffer_available(struct vdec_s *vdec)
is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB)
);
buffer_available = 0;
if (dpb_is_debug(DECODE_ID(hw),
DEBUG_DISABLE_RUNREADY_RMBUF))
return buffer_available;
if ((error_proc_policy & 0x4) &&
(error_proc_policy & 0x8)) {
if ((kfifo_len(&hw->display_q) <= 0) &&
@@ -3236,11 +3330,14 @@ static bool is_buffer_available(struct vdec_s *vdec)
static void check_decoded_pic_error(struct vdec_h264_hw_s *hw)
{
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
unsigned mby_mbx = READ_VREG(MBY_MBX);
unsigned mb_total = (hw->seq_info2 >> 8) & 0xffff;
unsigned decode_mb_count =
(((mby_mbx & 0xff) + 1) *
(((mby_mbx >> 8) & 0xff) + 1));
if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME)
mb_total /= 2;
if ((error_proc_policy & 0x100) &&
decode_mb_count != mb_total)
hw->data_flag |= ERROR_FLAG;
@@ -3281,6 +3378,20 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
/*unsigned char is_idr;*/
unsigned short *p = (unsigned short *)hw->lmem_addr;
reset_process_time(hw);
if (input_frame_based(vdec) &&
frmbase_cont_bitlevel2 != 0 &&
READ_VREG(VIFF_BIT_CNT) <
frmbase_cont_bitlevel2 &&
hw->get_data_count >= 0x70000000) {
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s H264_SLICE_HEAD_DONE with small bitcnt %d, goto empty_proc\n",
__func__,
READ_VREG(VIFF_BIT_CNT));
goto empty_proc;
}
dma_sync_single_for_cpu(
amports_get_dma_device(),
hw->lmem_addr_remap,
@@ -3341,7 +3452,14 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
}
}
#endif
if ((first_i_policy & 0x3) != 0) {
if (hw->config_bufmgr_done == 0) {
hw->dec_result = DEC_RESULT_DONE;
vdec_schedule_work(&hw->work);
dpb_print(DECODE_ID(hw),
PRINT_FLAG_UCODE_EVT,
"config_bufmgr not done, discard frame\n");
return IRQ_HANDLED;
} else if ((first_i_policy & 0x3) != 0) {
unsigned char is_i_slice =
(p_H264_Dpb->dpb_param.l.data[SLICE_TYPE]
== I_Slice)
@@ -3391,11 +3509,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt),
val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt));
if (hw->reset_bufmgr_flag) {
h264_reset_bufmgr(hw);
hw->reset_bufmgr_flag = 0;
}
slice_header_process_status =
h264_slice_header_process(p_H264_Dpb);
if (mmu_enable)
@@ -3432,6 +3545,23 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
hw->decode_pic_count+1,
hw->skip_frame_count);
}
if (error_proc_policy & 0x400) {
int ret = dpb_check_ref_list_error(p_H264_Dpb);
if (ret != 0) {
dpb_print(DECODE_ID(hw), 0,
"reference list error %d\n",
ret);
hw->data_flag |= ERROR_FLAG;
}
}
if ((error_proc_policy & 0x800)
&& p_H264_Dpb->dpb_error_flag != 0) {
dpb_print(DECODE_ID(hw), 0,
"dpb error %d\n",
p_H264_Dpb->dpb_error_flag);
hw->data_flag |= ERROR_FLAG;
}
cfg_ret = config_decode_buf(hw,
p_H264_Dpb->mVideo.dec_picture);
if (cfg_ret < 0) {
@@ -3538,7 +3668,23 @@ pic_done_proc:
hw->dec_flag &= (~NODISP_FLAG);
}
}
if (input_frame_based(vdec) &&
frmbase_cont_bitlevel != 0 &&
READ_VREG(VIFF_BIT_CNT) >
frmbase_cont_bitlevel) {
/*handle the case: multi pictures in one packet*/
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n",
__func__,
hw->decode_pic_count,
READ_VREG(VIFF_BIT_CNT));
/*do not DEC_RESULT_GET_DATA*/
hw->get_data_count = 0x7fffffff;
WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD);
decode_frame_count[DECODE_ID(hw)]++;
start_process_time(hw);
return IRQ_HANDLED;
}
amvdec_stop();
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s %s decode slice count %d\n",
@@ -3763,13 +3909,16 @@ send_again:
dpb_print_cont(DECODE_ID(hw), 0,
"\n");
}
if ((udebug_pause_pos == (debug_tag & 0xffff)) &&
if (((udebug_pause_pos & 0xffff)
== (debug_tag & 0xffff)) &&
(udebug_pause_decode_idx == 0 ||
udebug_pause_decode_idx ==
hw->decode_pic_count) &&
(udebug_pause_val == 0 ||
udebug_pause_val == READ_VREG(DEBUG_REG2)))
udebug_pause_val == READ_VREG(DEBUG_REG2))) {
udebug_pause_pos &= 0xffff;
hw->ucode_pause_pos = udebug_pause_pos;
}
else if (debug_tag & 0x20000)
hw->ucode_pause_pos = 0xffffffff;
if (hw->ucode_pause_pos)
@@ -3780,13 +3929,16 @@ send_again:
dpb_print(DECODE_ID(hw), 0,
"dbg%x: %x\n", debug_tag,
READ_VREG(DEBUG_REG2));
if ((udebug_pause_pos == (debug_tag & 0xffff)) &&
if (((udebug_pause_pos & 0xffff)
== (debug_tag & 0xffff)) &&
(udebug_pause_decode_idx == 0 ||
udebug_pause_decode_idx ==
hw->decode_pic_count) &&
(udebug_pause_val == 0 ||
udebug_pause_val == READ_VREG(DEBUG_REG2)))
udebug_pause_val == READ_VREG(DEBUG_REG2))) {
udebug_pause_pos &= 0xffff;
hw->ucode_pause_pos = udebug_pause_pos;
}
if (hw->ucode_pause_pos)
reset_process_time(hw);
else
@@ -3865,7 +4017,7 @@ static void vmh264_dump_state(struct vdec_s *vdec)
);
dpb_print(DECODE_ID(hw), 0,
"is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
"is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d bufmgr_reset_cnt %d\n",
input_frame_based(vdec),
hw->eos,
hw->stat,
@@ -3874,7 +4026,8 @@ static void vmh264_dump_state(struct vdec_s *vdec)
display_frame_count[DECODE_ID(hw)],
run_count[DECODE_ID(hw)],
not_run_ready[DECODE_ID(hw)],
input_empty[DECODE_ID(hw)]
input_empty[DECODE_ID(hw)],
hw->reset_bufmgr_count
);
if (vf_get_receiver(vdec->vf_provider_name)) {
@@ -3905,7 +4058,10 @@ static void vmh264_dump_state(struct vdec_s *vdec)
);
dump_dpb(&p_H264_Dpb->mDPB, 1);
dump_pic(p_H264_Dpb);
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
if (hw->buffer_spec[i].used == -1)
continue;
dpb_print(DECODE_ID(hw), 0,
"bufspec (%d): used %d adr 0x%x canvas(%d) vf_ref(%d) ",
i, hw->buffer_spec[i].used,
@@ -3991,7 +4147,11 @@ static void check_timer_func(unsigned long arg)
{
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)arg;
struct vdec_s *vdec = hw_to_vdec(hw);
int error_skip_frame_count = error_skip_count & 0xfff;
unsigned int timeout_val = decode_timeout_val;
if (timeout_val != 0 &&
hw->no_error_count < error_skip_frame_count)
timeout_val = errordata_timeout_val;
if ((h264_debug_cmd & 0x100) != 0 &&
DECODE_ID(hw) == (h264_debug_cmd & 0xff)) {
hw->dec_result = DEC_RESULT_DONE;
@@ -4001,6 +4161,12 @@ static void check_timer_func(unsigned long arg)
h264_debug_cmd = 0;
return;
}
if ((h264_debug_cmd & 0x200) != 0 &&
DECODE_ID(hw) == (h264_debug_cmd & 0xff)) {
hw->reset_bufmgr_flag = 1;
h264_debug_cmd = 0;
return;
}
if (vdec->next_status == VDEC_STATUS_DISCONNECTED) {
hw->dec_result = DEC_RESULT_FORCE_EXIT;
@@ -4022,10 +4188,10 @@ static void check_timer_func(unsigned long arg)
if ((input_frame_based(vdec) ||
(READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) &&
((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) &&
(decode_timeout_val > 0) &&
(timeout_val > 0) &&
(hw->start_process_time > 0) &&
((1000 * (jiffies - hw->start_process_time) / HZ)
> decode_timeout_val)
> timeout_val)
) {
u32 dpb_status = READ_VREG(DPB_STATUS_REG);
u32 mby_mbx = READ_VREG(MBY_MBX);
@@ -4176,7 +4342,8 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw)
WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count);
WRITE_VREG(AV_SCRATCH_8, hw->buf_offset);
WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle);
if (!is_secload_get())
WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle);
/* hw->error_recovery_mode = (error_recovery_mode != 0) ?
error_recovery_mode : error_recovery_mode_in; */
@@ -4216,6 +4383,14 @@ static unsigned char amvdec_enable_flag;
static void vh264_local_init(struct vdec_h264_hw_s *hw)
{
int i;
hw->init_flag = 0;
hw->eos = 0;
hw->config_bufmgr_done = 0;
hw->start_process_time = 0;
hw->has_i_frame = 0;
hw->no_error_count = 0xfff;
hw->no_error_i_count = 0xf;
hw->decode_timeout_count = 0;
hw->vh264_ratio = hw->vh264_amstream_dec_info.ratio;
@@ -4264,9 +4439,9 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw)
INIT_KFIFO(hw->newframe_q);
for (i = 0; i < VF_POOL_SIZE; i++) {
const struct vframe_s *vf = &hw->vfpool[i];
hw->vfpool[i].index = -1; /* VF_BUF_NUM; */
hw->vfpool[i].bufWidth = 1920;
const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]);
hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
hw->vfpool[hw->cur_pool][i].bufWidth = 1920;
kfifo_put(&hw->newframe_q, vf);
}
@@ -4276,10 +4451,6 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw)
hw->vh264_stream_switching_state = SWITCHING_STATE_OFF;
hw->hevc_cur_buf_idx = 0xffff;
INIT_WORK(&hw->work, vh264_work);
INIT_WORK(&hw->notify_work, vh264_notify_work);
INIT_WORK(&hw->user_data_work, user_data_push_work);
return;
}
@@ -4288,12 +4459,6 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
/* int trickmode_fffb = 0; */
int firmwareloaded = 0;
hw->init_flag = 0;
hw->eos = 0;
hw->config_bufmgr_done = 0;
hw->start_process_time = 0;
hw->has_i_frame = 0;
/* pr_info("\nvh264_init\n"); */
/* init_timer(&hw->recycle_timer); */
@@ -4308,11 +4473,11 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
hw->stat |= STAT_TIMER_ARM;
hw->stat |= STAT_ISR_REG;
hw->duration_on_correcting = 0;
hw->fixed_frame_rate_check_count = 0;
hw->saved_resolution = 0;
vh264_local_init(hw);
INIT_WORK(&hw->work, vh264_work);
INIT_WORK(&hw->notify_work, vh264_notify_work);
INIT_WORK(&hw->user_data_work, user_data_push_work);
if (!amvdec_enable_flag) {
amvdec_enable_flag = true;
amvdec_enable();
@@ -4330,7 +4495,14 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
return -ENOMEM;
}
}
if (is_secload_get() && !firmwareloaded) {
pr_info("VMH264 start load sec firmware ...\n");
if (tee_load_video_fw((u32)VIDEO_DEC_H264_MULTI)
!= 0) {
amvdec_disable();
return -1;
}
} else {
/* -- ucode loading (amrisc and swap code) */
hw->mc_cpu_addr =
dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE,
@@ -4408,7 +4580,7 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
return -EBUSY;
}
}
}
#if 1 /* #ifdef BUFFER_MGR_IN_C */
hw->lmem_addr = __get_free_page(GFP_KERNEL);
if (!hw->lmem_addr) {
@@ -4614,12 +4786,20 @@ static void vh264_work(struct work_struct *work)
READ_VREG(VLD_MEM_VIFIFO_RP));
if (!mmu_enable) {
mutex_lock(&vmh264_mutex);
dealloc_buf_specs(hw);
dealloc_buf_specs(hw, 0);
mutex_unlock(&vmh264_mutex);
}
if (hw->dec_result == DEC_RESULT_CONFIG_PARAM) {
if (vh264_set_params(hw) < 0)
u32 param1 = READ_VREG(AV_SCRATCH_1);
u32 param2 = READ_VREG(AV_SCRATCH_2);
u32 param3 = READ_VREG(AV_SCRATCH_6);
u32 param4 = READ_VREG(AV_SCRATCH_B);
if (vh264_set_params(hw, param1,
param2, param3, param4) < 0)
hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
(hw->dpb.mDPB.size<<16) |
(hw->dpb.mDPB.size<<8));
start_process_time(hw);
return;
} else
@@ -4745,6 +4925,8 @@ result_done:
"%s: force exit\n",
__func__);
amvdec_stop();
if (mmu_enable)
amhevc_stop();
if (hw->stat & STAT_ISR_REG) {
vdec_free_irq(VDEC_IRQ_1, (void *)hw);
hw->stat &= ~STAT_ISR_REG;
@@ -4814,6 +4996,7 @@ static void run(struct vdec_s *vdec,
{
struct vdec_h264_hw_s *hw =
(struct vdec_h264_hw_s *)vdec->private;
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int size;
run_count[DECODE_ID(hw)]++;
@@ -4821,9 +5004,19 @@ static void run(struct vdec_s *vdec,
hw->vdec_cb_arg = arg;
hw->vdec_cb = callback;
if (hw->reset_bufmgr_flag ||
((error_proc_policy & 0x40) &&
p_H264_Dpb->buf_alloc_fail)) {
h264_reset_bufmgr(hw);
hw->reset_bufmgr_flag = 0;
}
if (h264_debug_cmd & 0xf000) {
h264_reconfig(hw);
h264_debug_cmd &= (~0xf000);
if (((h264_debug_cmd >> 12) & 0xf)
== (DECODE_ID(hw) + 1)) {
h264_reconfig(hw);
h264_debug_cmd &= (~0xf000);
}
}
/* hw->chunk = vdec_prepare_input(vdec); */
#ifdef CONFIG_AM_VDEC_DV
@@ -4902,11 +5095,18 @@ static void run(struct vdec_s *vdec,
start_process_time(hw);
if (amvdec_vdec_loadmc_ex(vdec, NULL, hw->fw->data) < 0) {
if (is_secload_get()) {
if (tee_load_video_fw((u32)VIDEO_DEC_H264_MULTI)
!= 0) {
amvdec_enable_flag = false;
amvdec_disable();
pr_info("%s: Error amvdec_vdec_loadmc fail\n",
__func__);
return;
}
} else if (amvdec_vdec_loadmc_ex(vdec, NULL, hw->fw->data) < 0) {
amvdec_enable_flag = false;
amvdec_disable();
if (mmu_enable)
amhevc_disable();
pr_info("%s: Error amvdec_vdec_loadmc fail\n",
__func__);
return;
@@ -5000,6 +5200,7 @@ static void h264_reconfig(struct vdec_h264_hw_s *hw)
static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
{
int i;
#if 0
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int actual_dpb_size, max_reference_size;
int reorder_pic_num;
@@ -5008,19 +5209,9 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
unsigned int colocated_mv_addr_end;
dpb_print(DECODE_ID(hw), 0,
"%s\n", __func__);
/* after calling flush_dpb() and bufmgr_h264_remove_unused_frame(),
all buffers are in display queue (used == 2),
or free (used == 0)
*/
flush_dpb(p_H264_Dpb);
bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
/*make sure buffers not put back to bufmgr when
vf_put is called*/
if (hw->buffer_spec[i].used == 2)
hw->buffer_spec[i].used = 5;
}
for (i = 0; i < VF_POOL_SIZE; i++)
hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
actual_dpb_size = p_H264_Dpb->mDPB.size;
max_reference_size = p_H264_Dpb->max_reference_size;
@@ -5030,6 +5221,23 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
colocated_mv_addr_start = p_H264_Dpb->colocated_mv_addr_start;
colocated_mv_addr_end = p_H264_Dpb->colocated_mv_addr_end;
hw->cur_pool++;
if (hw->cur_pool >= VF_POOL_NUM)
hw->cur_pool = 0;
INIT_KFIFO(hw->display_q);
INIT_KFIFO(hw->newframe_q);
for (i = 0; i < VF_POOL_SIZE; i++) {
const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]);
hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
hw->vfpool[hw->cur_pool][i].bufWidth = 1920;
kfifo_put(&hw->newframe_q, vf);
}
for (i = 0; i < BUFSPEC_POOL_SIZE; i++)
hw->buffer_spec[i].used = 0;
dpb_init_global(&hw->dpb,
DECODE_ID(hw), 0, 0);
p_H264_Dpb->mDPB.size = actual_dpb_size;
@@ -5041,6 +5249,43 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
p_H264_Dpb->colocated_mv_addr_end = colocated_mv_addr_end;
p_H264_Dpb->fast_output_enable = fast_output_enable;
hw->has_i_frame = 0;
#else
dpb_print(DECODE_ID(hw), 0,
"%s\n", __func__);
for (i = 0; i < VF_POOL_SIZE; i++)
hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
hw->cur_pool++;
if (hw->cur_pool >= VF_POOL_NUM)
hw->cur_pool = 0;
if (hw->collocate_cma_alloc_addr) {
decoder_bmmu_box_free_idx(
hw->bmmu_box,
BMMU_REF_IDX);
hw->collocate_cma_alloc_addr = 0;
hw->dpb.colocated_mv_addr_start = 0;
hw->dpb.colocated_mv_addr_end = 0;
}
dealloc_buf_specs(hw, 1);
buf_spec_init(hw);
vh264_local_init(hw);
/*hw->decode_pic_count = 0;
hw->seq_info2 = 0;*/
if (vh264_set_params(hw,
hw->cfg_param1,
hw->cfg_param2,
hw->cfg_param3,
hw->cfg_param4) < 0)
hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
hw->init_flag = 1;
hw->reset_bufmgr_count++;
#endif
}
int ammvdec_h264_mmu_init(struct vdec_h264_hw_s *hw)
@@ -5350,6 +5595,9 @@ MODULE_PARM_DESC(fixed_frame_rate_mode, "\namvdec_h264 fixed_frame_rate_mode\n")
module_param(decode_timeout_val, uint, 0664);
MODULE_PARM_DESC(decode_timeout_val, "\n amvdec_h264 decode_timeout_val\n");
module_param(errordata_timeout_val, uint, 0664);
MODULE_PARM_DESC(errordata_timeout_val, "\n amvdec_h264 errordata_timeout_val\n");
module_param(get_data_timeout_val, uint, 0664);
MODULE_PARM_DESC(get_data_timeout_val, "\n amvdec_h264 get_data_timeout_val\n");
@@ -5428,6 +5676,14 @@ MODULE_PARM_DESC(i_only_flag, "\n amvdec_h264 i_only_flag\n");
module_param(first_i_policy, uint, 0664);
MODULE_PARM_DESC(first_i_policy, "\n amvdec_h264 first_i_policy\n");
module_param(frmbase_cont_bitlevel, uint, 0664);
MODULE_PARM_DESC(frmbase_cont_bitlevel,
"\n amvdec_h264 frmbase_cont_bitlevel\n");
module_param(frmbase_cont_bitlevel2, uint, 0664);
MODULE_PARM_DESC(frmbase_cont_bitlevel2,
"\n amvdec_h264 frmbase_cont_bitlevel\n");
module_param(udebug_flag, uint, 0664);
MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");

View File

@@ -74,6 +74,7 @@
#include <linux/amlogic/media/video_sink/video.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#define SEND_LMEM_WITH_RPM
#define SUPPORT_10BIT
/* #define ERROR_HANDLE_DEBUG */
#if 0/*MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8B*/
@@ -104,7 +105,8 @@
#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
#define DUR2PTS(x) ((x)*90/96)
#define HEVC_SIZE (4096*2304)
#define MAX_SIZE (4096 + 2304)
#define OVER_SIZE(w, h) (MAX_SIZE < (w + h))
static struct semaphore h265_sema;
@@ -306,6 +308,7 @@ static u32 udebug_pause_decode_idx;
static u32 decode_pic_begin;
static uint slice_parse_begin;
static u32 step;
static bool is_reset;
static u32 dynamic_buf_num_margin = 8;
static u32 buf_alloc_width;
@@ -380,6 +383,8 @@ bit 4: 0, set error_mark after reset/recover
1, do not set error_mark after reset/recover
bit 5: 0, check total lcu for every picture
1, do not check total lcu
bit 6: 0, do not check head error
1, check head error
*/
@@ -1496,7 +1501,6 @@ struct hevc_state_s {
unsigned int dec_status;
/* data for SEI_MASTER_DISPLAY_COLOR */
unsigned int primaries[3][2];
unsigned int white_point[2];
@@ -1520,9 +1524,43 @@ struct hevc_state_s {
u32 vf_pre_count;
u32 vf_get_count;
u32 vf_put_count;
u8 head_error_flag;
struct firmware_s *fw;
} /*hevc_stru_t */;
#ifdef SEND_LMEM_WITH_RPM
#define get_lmem_params(hevc, ladr) \
hevc->lmem_ptr[ladr - (ladr & 0x3) + 3 - (ladr & 0x3)]
void check_head_error(struct hevc_state_s *hevc)
{
#define pcm_enabled_flag 0x040
#define pcm_sample_bit_depth_luma 0x041
#define pcm_sample_bit_depth_chroma 0x042
hevc->head_error_flag = 0;
if ((error_handle_policy & 0x40) == 0)
return;
if (get_lmem_params(hevc, pcm_enabled_flag)) {
uint16_t pcm_depth_luma = get_lmem_params(
hevc, pcm_sample_bit_depth_luma);
uint16_t pcm_sample_chroma = get_lmem_params(
hevc, pcm_sample_bit_depth_chroma);
if (pcm_depth_luma >
hevc->bit_depth_luma ||
pcm_sample_chroma >
hevc->bit_depth_chroma) {
hevc_print(hevc, 0,
"error, pcm bit depth %d, %d is greater than normal bit depth %d, %d\n",
pcm_depth_luma,
pcm_sample_chroma,
hevc->bit_depth_luma,
hevc->bit_depth_chroma);
hevc->head_error_flag = 1;
}
}
}
#endif
#ifdef SUPPORT_10BIT
/* Losless compression body buffer size 4K per 64x32 (jt) */
static int compute_losless_comp_body_size(struct hevc_state_s *hevc,
@@ -1811,6 +1849,7 @@ static void hevc_init_stru(struct hevc_state_s *hevc,
hevc->col_pic = NULL;
hevc->wait_buf = 0;
hevc->error_flag = 0;
hevc->head_error_flag = 0;
hevc->error_skip_nal_count = 0;
hevc->have_vps = 0;
hevc->have_sps = 0;
@@ -4738,7 +4777,7 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc,
}
static void check_pic_decoded_lcu_count_pre(struct hevc_state_s *hevc,
static void check_pic_decoded_error_pre(struct hevc_state_s *hevc,
int decoded_lcu)
{
int current_lcu_idx = decoded_lcu;
@@ -4778,11 +4817,16 @@ static void check_pic_decoded_lcu_count_pre(struct hevc_state_s *hevc,
}
}
if (hevc->cur_pic && hevc->head_error_flag) {
hevc->cur_pic->error_mark = 1;
hevc_print(hevc, 0,
"head has error, set error_mark\n");
}
hevc->lcu_x_num_pre = hevc->lcu_x_num;
hevc->lcu_y_num_pre = hevc->lcu_y_num;
}
static void check_pic_decoded_lcu_count(struct hevc_state_s *hevc,
static void check_pic_decoded_error(struct hevc_state_s *hevc,
int decoded_lcu)
{
int current_lcu_idx = decoded_lcu;
@@ -4816,6 +4860,12 @@ static void check_pic_decoded_lcu_count(struct hevc_state_s *hevc,
}
}
if (hevc->cur_pic && hevc->head_error_flag) {
hevc->cur_pic->error_mark = 1;
hevc_print(hevc, 0,
"head has error, set error_mark\n");
}
}
static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
@@ -4894,7 +4944,7 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
#endif
}
if (HEVC_SIZE < hevc->pic_w * hevc->pic_h) {
if (OVER_SIZE(hevc->pic_w, hevc->pic_h)) {
pr_info("over size : %u x %u.\n",
hevc->pic_w, hevc->pic_h);
if (!hevc->m_ins_flag)
@@ -5053,7 +5103,7 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
#ifdef MULTI_INSTANCE_SUPPORT
if (!hevc->m_ins_flag)
#endif
check_pic_decoded_lcu_count_pre(hevc,
check_pic_decoded_error_pre(hevc,
READ_VREG(HEVC_PARSER_LCU_START)
& 0xffffff);
/**/ if (use_cma == 0) {
@@ -7177,8 +7227,8 @@ static void read_decode_info(struct hevc_state_s *hevc)
{
uint32_t decode_info =
READ_HREG(HEVC_DECODE_INFO);
hevc->start_decoding_flag =
decode_info & 0xff;
hevc->start_decoding_flag |=
(decode_info & 0xff);
hevc->rps_set_id = (decode_info >> 8) & 0xff;
}
@@ -7443,7 +7493,7 @@ pic_done:
dolby_get_meta(hevc);
}
#endif
check_pic_decoded_lcu_count(hevc,
check_pic_decoded_error(hevc,
hevc->pic_decoded_lcu_idx);
pic = get_pic_by_POC(hevc, hevc->curr_POC);
hevc->curr_POC = INVALID_POC;
@@ -7637,6 +7687,14 @@ pic_done:
- ii];
}
}
#ifdef SEND_LMEM_WITH_RPM
dma_sync_single_for_cpu(
amports_get_dma_device(),
hevc->lmem_phy_addr,
LMEM_BUF_SIZE,
DMA_FROM_DEVICE);
check_head_error(hevc);
#endif
}
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) {
hevc_print(hevc, 0,
@@ -7934,12 +7992,15 @@ static irqreturn_t vh265_isr(int irq, void *data)
hevc_print_cont(hevc, 0, "\n");
}
if ((udebug_pause_pos == (debug_tag & 0xffff)) &&
if (((udebug_pause_pos & 0xffff)
== (debug_tag & 0xffff)) &&
(udebug_pause_decode_idx == 0 ||
udebug_pause_decode_idx == hevc->decode_idx) &&
(udebug_pause_val == 0 ||
udebug_pause_val == READ_HREG(DEBUG_REG2)))
udebug_pause_val == READ_HREG(DEBUG_REG2))) {
udebug_pause_pos &= 0xffff;
hevc->ucode_pause_pos = udebug_pause_pos;
}
else if (debug_tag & 0x20000)
hevc->ucode_pause_pos = 0xffffffff;
if (hevc->ucode_pause_pos)
@@ -7951,12 +8012,15 @@ static irqreturn_t vh265_isr(int irq, void *data)
"dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
READ_HREG(DEBUG_REG2),
READ_VREG(HEVC_PARSER_LCU_START));
if ((udebug_pause_pos == (debug_tag & 0xffff)) &&
if (((udebug_pause_pos & 0xffff)
== (debug_tag & 0xffff)) &&
(udebug_pause_decode_idx == 0 ||
udebug_pause_decode_idx == hevc->decode_idx) &&
(udebug_pause_val == 0 ||
udebug_pause_val == READ_HREG(DEBUG_REG2)))
udebug_pause_val == READ_HREG(DEBUG_REG2))) {
udebug_pause_pos &= 0xffff;
hevc->ucode_pause_pos = udebug_pause_pos;
}
if (hevc->ucode_pause_pos)
reset_process_time(hevc);
else
@@ -8290,6 +8354,12 @@ int vh265_dec_status(struct vdec_info *vstatus)
return 0;
}
int vh265_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
static int vh265_vdec_info_init(void)
{
gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
@@ -8430,7 +8500,7 @@ static int vh265_local_init(struct hevc_state_s *hevc)
hevc->get_frame_dur = false;
hevc->frame_width = hevc->vh265_amstream_dec_info.width;
hevc->frame_height = hevc->vh265_amstream_dec_info.height;
if (HEVC_SIZE < hevc->frame_width * hevc->frame_height) {
if (OVER_SIZE(hevc->frame_width, hevc->frame_height)) {
pr_info("over size : %u x %u.\n",
hevc->frame_width, hevc->frame_height);
hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
@@ -8574,10 +8644,11 @@ static s32 vh265_init(struct hevc_state_s *hevc)
vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START,
NULL);
if (hevc->frame_dur != 0) {
vf_notify_receiver(hevc->provider_name,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)hevc->frame_dur));
if (!is_reset)
vf_notify_receiver(hevc->provider_name,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)hevc->frame_dur));
fr_hint_status = VDEC_HINTED;
} else
fr_hint_status = VDEC_NEED_HINT;
@@ -8706,7 +8777,7 @@ static int vh265_stop(struct hevc_state_s *hevc)
}
if (hevc->stat & STAT_VF_HOOK) {
if (fr_hint_status == VDEC_HINTED)
if (fr_hint_status == VDEC_HINTED && !is_reset)
vf_notify_receiver(hevc->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
NULL);
@@ -8774,7 +8845,7 @@ static void timeout_process(struct hevc_state_s *hevc)
hevc_print(hevc,
0, "%s decoder timeout\n", __func__);
check_pic_decoded_lcu_count(hevc,
check_pic_decoded_error(hevc,
hevc->pic_decoded_lcu_idx);
hevc->decoded_poc = hevc->curr_POC;
hevc->decoding_pic = NULL;
@@ -9115,7 +9186,7 @@ static void vh265_work(struct work_struct *work)
hevc->used_4k_num = -1;
check_pic_decoded_lcu_count(hevc,
check_pic_decoded_error(hevc,
hevc->pic_decoded_lcu_idx);
#ifdef CONFIG_AM_VDEC_DV
#if 1
@@ -9183,7 +9254,7 @@ static void vh265_work(struct work_struct *work)
READ_VREG(HEVC_AUX_DATA_SIZE) != 0)
dolby_get_meta(hevc);
#endif
check_pic_decoded_lcu_count(hevc,
check_pic_decoded_error(hevc,
hevc->pic_decoded_lcu_idx);
pic = get_pic_by_POC(hevc, hevc->curr_POC);
hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
@@ -9263,6 +9334,10 @@ static bool run_ready(struct vdec_s *vdec)
struct hevc_state_s *hevc =
(struct hevc_state_s *)vdec->private;
bool ret = 0;
if (step == 0x12)
return 0;
else if (step == 0x11)
step = 0x12;
if (hevc->eos)
return 0;
@@ -9509,6 +9584,8 @@ static int amvdec_h265_probe(struct platform_device *pdev)
#ifdef MULTI_INSTANCE_SUPPORT
pdata->private = hevc;
pdata->dec_status = vh265_dec_status;
pdata->set_isreset = vh265_set_isreset;
is_reset = 0;
if (vh265_init(pdata) < 0) {
#else
if (vh265_init(hevc) < 0) {

View File

@@ -122,6 +122,7 @@ static struct timer_list recycle_timer;
static u32 stat;
static u32 buf_size = 32 * 1024 * 1024;
static DEFINE_SPINLOCK(lock);
static bool is_reset;
static inline u32 index2canvas0(u32 index)
{
@@ -430,6 +431,12 @@ int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vmjpeg_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
/****************************************/
static int vmjpeg_canvas_init(void)
{
@@ -763,8 +770,11 @@ static s32 vmjpeg_init(void)
vf_reg_provider(&vmjpeg_vf_prov);
#endif
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)vmjpeg_amstream_dec_info.rate));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)vmjpeg_amstream_dec_info.rate));
stat |= STAT_VF_HOOK;
@@ -803,7 +813,8 @@ static int amvdec_mjpeg_probe(struct platform_device *pdev)
vmjpeg_amstream_dec_info = *pdata->sys_info;
pdata->dec_status = vmjpeg_dec_status;
pdata->set_isreset = vmjpeg_set_isreset;
is_reset = 0;
vmjpeg_vdec_info_init();
if (vmjpeg_init() < 0) {
@@ -841,8 +852,10 @@ static int amvdec_mjpeg_remove(struct platform_device *pdev)
}
if (stat & STAT_VF_HOOK) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
NULL);
vf_unreg_provider(&vmjpeg_vf_prov);
stat &= ~STAT_VF_HOOK;

View File

@@ -186,6 +186,7 @@ static u32 first_i_frame_ready;
static struct work_struct userdata_push_work;
static struct work_struct notify_work;
static struct work_struct reset_work;
static bool is_reset;
static inline int pool_index(struct vframe_s *vf)
{
@@ -516,7 +517,10 @@ static irqreturn_t vmpeg12_isr(int irq, void *dev_id)
#ifdef NV21
vf->type |= VIDTYPE_VIU_NV21;
#endif
vf->duration >>= 1;
if (info & PICINFO_RPT_FIRST)
vf->duration /= 3;
else
vf->duration >>= 1;
vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ?
vf->duration >> 1 : 0;
vf->duration += vf->duration_pulldown;
@@ -562,7 +566,10 @@ static irqreturn_t vmpeg12_isr(int irq, void *dev_id)
#ifdef NV21
vf->type |= VIDTYPE_VIU_NV21;
#endif
vf->duration >>= 1;
if (info & PICINFO_RPT_FIRST)
vf->duration /= 3;
else
vf->duration >>= 1;
vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ?
vf->duration >> 1 : 0;
vf->duration += vf->duration_pulldown;
@@ -611,7 +618,7 @@ static irqreturn_t vmpeg12_isr(int irq, void *dev_id)
#ifdef NV21
vf->type |= VIDTYPE_VIU_NV21;
#endif
vf->duration >>= 1;
vf->duration /= 3;
vf->duration_pulldown =
(info & PICINFO_RPT_FIRST) ?
vf->duration >> 1 : 0;
@@ -819,6 +826,12 @@ int vmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vmpeg12_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
static int vmpeg12_vdec_info_init(void)
{
gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
@@ -1103,11 +1116,12 @@ static s32 vmpeg12_init(void)
vf_reg_provider(&vmpeg_vf_prov);
#endif
if (vmpeg12_amstream_dec_info.rate != 0) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)
vmpeg12_amstream_dec_info.rate));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)
vmpeg12_amstream_dec_info.rate));
fr_hint_status = VDEC_HINTED;
} else
fr_hint_status = VDEC_NEED_HINT;
@@ -1145,6 +1159,8 @@ static int amvdec_mpeg12_probe(struct platform_device *pdev)
vmpeg12_amstream_dec_info = *pdata->sys_info;
pdata->dec_status = vmpeg12_dec_status;
pdata->set_isreset = vmpeg12_set_isreset;
is_reset = 0;
vmpeg12_vdec_info_init();
@@ -1186,7 +1202,7 @@ static int amvdec_mpeg12_remove(struct platform_device *pdev)
}
if (stat & STAT_VF_HOOK) {
if (fr_hint_status == VDEC_HINTED)
if (fr_hint_status == VDEC_HINTED && !is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
fr_hint_status = VDEC_NO_NEED_HINT;

View File

@@ -172,7 +172,7 @@ u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
static struct work_struct reset_work;
static struct work_struct notify_work;
static bool is_reset;
static DEFINE_SPINLOCK(lock);
@@ -752,6 +752,12 @@ int vmpeg4_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vmpeg4_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
static int vmpeg4_vdec_info_init(void)
{
gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
@@ -1070,11 +1076,12 @@ static s32 vmpeg4_init(void)
vf_reg_provider(&vmpeg_vf_prov);
#endif
if (vmpeg4_amstream_dec_info.rate != 0) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)
vmpeg4_amstream_dec_info.rate));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)
vmpeg4_amstream_dec_info.rate));
fr_hint_status = VDEC_HINTED;
} else
fr_hint_status = VDEC_NEED_HINT;
@@ -1110,6 +1117,8 @@ static int amvdec_mpeg4_probe(struct platform_device *pdev)
vmpeg4_amstream_dec_info = *pdata->sys_info;
pdata->dec_status = vmpeg4_dec_status;
pdata->set_isreset = vmpeg4_set_isreset;
is_reset = 0;
INIT_WORK(&reset_work, reset_do_work);
INIT_WORK(&notify_work, vmpeg4_notify_work);
@@ -1144,7 +1153,7 @@ static int amvdec_mpeg4_remove(struct platform_device *pdev)
}
if (stat & STAT_VF_HOOK) {
if (fr_hint_status == VDEC_HINTED)
if (fr_hint_status == VDEC_HINTED && !is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
fr_hint_status = VDEC_NO_NEED_HINT;

View File

@@ -1137,6 +1137,7 @@ static void run(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *),
hw->dec_result = DEC_RESULT_NONE;
if (amvdec_vdec_loadmc_buf_ex(vdec, hw->fw->data, hw->fw->len) < 0) {
pr_err("VIDEO_DEC_FORMAT_MPEG4 ucode loading failed\n");
hw->dec_result = DEC_RESULT_ERROR;
schedule_work(&hw->work);
return;

View File

@@ -150,6 +150,7 @@ static u32 real_err_count;
static u32 fatal_flag;
static s32 wait_buffer_counter;
static bool is_reset;
static DEFINE_SPINLOCK(lock);
@@ -515,6 +516,12 @@ int vreal_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vreal_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
/****************************************/
static int vreal_canvas_init(void)
{
@@ -854,8 +861,9 @@ s32 vreal_init(struct vdec_s *vdec)
vf_reg_provider(&vreal_vf_prov);
#endif
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)vreal_amstream_dec_info.rate));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)vreal_amstream_dec_info.rate));
stat |= STAT_VF_HOOK;
@@ -894,6 +902,8 @@ static int amvdec_real_probe(struct platform_device *pdev)
vreal_amstream_dec_info = *pdata->sys_info;
pdata->dec_status = vreal_dec_status;
pdata->set_isreset = vreal_set_isreset;
is_reset = 0;
if (vreal_init(pdata) < 0) {
pr_info("amvdec_real init failed.\n");
@@ -921,8 +931,9 @@ static int amvdec_real_remove(struct platform_device *pdev)
}
if (stat & STAT_VF_HOOK) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
vf_unreg_provider(&vreal_vf_prov);
stat &= ~STAT_VF_HOOK;

View File

@@ -43,6 +43,7 @@
#include "amvdec.h"
#include <linux/amlogic/media/utils/amports_config.h>
#include "firmware.h"
#include <linux/amlogic/tee.h>
#define MC_SIZE (4096 * 16)
@@ -372,11 +373,68 @@ static s32 amvdec_loadmc(const u32 *p)
return ret;
}
s32 optee_load_fw(enum vformat_e type, const char *name)
{
s32 ret = 0;
switch ((u32)type) {
case VFORMAT_VC1:
ret = tee_load_video_fw((u32)VIDEO_DEC_VC1);
break;
case VFORMAT_AVS:
ret = tee_load_video_fw((u32)VIDEO_DEC_AVS);
break;
case VFORMAT_MPEG12:
ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG12);
break;
case VFORMAT_MJPEG:
ret = tee_load_video_fw((u32)VIDEO_DEC_MJPEG);
break;
case VFORMAT_VP9:
ret = tee_load_video_fw((u32)VIDEO_DEC_VP9_MMU);
break;
case VFORMAT_HEVC:
if (!strcmp(name, "vh265_mc"))
ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC);
else if (!strcmp(name, "vh265_mc_mmu"))
ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_MMU);
break;
case VFORMAT_REAL:
if (!strcmp(name, "vreal_mc_8"))
ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V8);
else if (!strcmp(name, "vreal_mc_9"))
ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V9);
break;
case VFORMAT_MPEG4:
if (!strcmp(name, "vmpeg4_mc_311"))
ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_3);
else if (!strcmp(name, "vmpeg4_mc_4"))
ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_4);
else if (!strcmp(name, "vmpeg4_mc_5"))
ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_5);
else if (!strcmp(name, "h263_mc"))
ret = tee_load_video_fw((u32)VIDEO_DEC_FORMAT_H263);
break;
}
return ret;
}
EXPORT_SYMBOL(optee_load_fw);
s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def)
{
return am_loadmc_ex(type, name, def, &amvdec_loadmc);
if (is_secload_get())
return optee_load_fw(type, name);
else
return am_loadmc_ex(type, name, def, &amvdec_loadmc);
}
EXPORT_SYMBOL(amvdec_loadmc_ex);
s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def)
{
return am_vdec_loadmc_ex(vdec, name, def, &amvdec_loadmc);
@@ -559,11 +617,15 @@ static s32 amhevc_loadmc(const u32 *p)
s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def)
{
if (has_hevc_vdec())
return am_loadmc_ex(type, name, def, &amhevc_loadmc);
if (is_secload_get())
return optee_load_fw(type, name);
else
return am_loadmc_ex(type, name, def, &amhevc_loadmc);
else
return 0;
}
EXPORT_SYMBOL(amhevc_loadmc_ex);
s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def)
{
if (has_hevc_vdec())
@@ -812,7 +874,7 @@ int amvdec_suspend(struct platform_device *dev, pm_message_t event)
if (has_hevc_vdec())
amhevc_pg_enable(false);
/*vdec_set_suspend_clk(1, 0);*//*DEBUG_TMP*/
return 0;
}
EXPORT_SYMBOL(amvdec_suspend);
@@ -830,23 +892,27 @@ int amvdec_resume(struct platform_device *dev)
if (has_hevc_vdec())
amhevc_pg_enable(true);
/* #endif */
/*vdec_set_suspend_clk(0, 0);*//*DEBUG_TMP*/
return 0;
}
EXPORT_SYMBOL(amvdec_resume);
int amhevc_suspend(struct platform_device *dev, pm_message_t event)
{
if (has_hevc_vdec())
if (has_hevc_vdec()) {
amhevc_pg_enable(false);
/*vdec_set_suspend_clk(1, 1);*//*DEBUG_TMP*/
}
return 0;
}
EXPORT_SYMBOL(amhevc_suspend);
int amhevc_resume(struct platform_device *dev)
{
if (has_hevc_vdec())
if (has_hevc_vdec()) {
amhevc_pg_enable(true);
/*vdec_set_suspend_clk(0, 1);*//*DEBUG_TMP*/
}
return 0;
}
EXPORT_SYMBOL(amhevc_resume);

View File

@@ -318,8 +318,10 @@ int decoder_bmmu_box_alloc_buf_phy(
decoder_bmmu_box_get_phy_addr(
handle,
idx);
pr_info("%s malloc buf_idx = %d addr = %ld size = %d\n",
driver_name, idx, *buf_phy_addr, size);
/*
*pr_info("%s malloc buf_idx = %d addr = %ld size = %d\n",
* driver_name, idx, *buf_phy_addr, size);
*/
} else {
pr_info("%s malloc failed %d\n", driver_name, idx);
return -ENOMEM;

View File

@@ -65,6 +65,7 @@
#include <linux/amlogic/media/codec_mm/configs.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include "secprot.h"
#include <linux/amlogic/tee.h>
static DEFINE_MUTEX(vdec_mutex);
@@ -77,7 +78,7 @@ static int keep_vdec_mem;
static unsigned int debug_trace_num = 16 * 20;
static int step_mode;
static unsigned int clk_config;
static int is_secload;
static int hevc_max_reset_count;
#define MAX_INSTANCE_MUN 9
@@ -221,6 +222,16 @@ int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
}
EXPORT_SYMBOL(vdec_set_trickmode);
int vdec_set_isreset(struct vdec_s *vdec, int isreset)
{
vdec->is_reset = isreset;
pr_info("is_reset=%d\n", isreset);
if (vdec->set_isreset)
return vdec->set_isreset(vdec, isreset);
return 0;
}
EXPORT_SYMBOL(vdec_set_isreset);
void vdec_count_info(struct vdec_info *vs, unsigned int err,
unsigned int offset)
{
@@ -1456,10 +1467,12 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k)
if (vdec_core->hint_fr_vdec == vdec) {
if (p->sys_info->rate != 0) {
vf_notify_receiver(p->vf_provider_name,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)p->sys_info->rate));
if (!vdec->is_reset)
vf_notify_receiver(p->vf_provider_name,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)
p->sys_info->rate));
vdec->fr_hint_state = VDEC_HINTED;
} else {
vdec->fr_hint_state = VDEC_NEED_HINT;
@@ -1493,7 +1506,8 @@ void vdec_release(struct vdec_s *vdec)
if (vdec->vframe_provider.name) {
if (!vdec_single(vdec)) {
if (vdec_core->hint_fr_vdec == vdec
&& vdec->fr_hint_state == VDEC_HINTED)
&& vdec->fr_hint_state == VDEC_HINTED
&& !vdec->is_reset)
vf_notify_receiver(
vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
@@ -1679,7 +1693,10 @@ static inline bool vdec_ready_to_run(struct vdec_s *vdec)
if ((vdec->slave || vdec->master) &&
(vdec->sched == 0))
return false;
/* check frame based input underrun */
if (input && input_frame_based(input) &&
(!vdec_input_next_chunk(input)))
return false;
/* check streaming prepare level threshold if not EOS */
if (input && input_stream_based(input) && !input->eos) {
u32 rp, wp, level;
@@ -3019,7 +3036,6 @@ static ssize_t dump_vdec_chunks_show(struct class *class,
return pbuf - buf;
}
#if 0 /*DEBUG_TMP*/
static ssize_t dump_decoder_state_show(struct class *class,
struct class_attribute *attr, char *buf)
{
@@ -3043,7 +3059,35 @@ static ssize_t dump_decoder_state_show(struct class *class,
return pbuf - buf;
}
#endif
int is_secload_get(void)
{
return is_secload;
}
EXPORT_SYMBOL(is_secload_get);
static ssize_t is_secload_show(struct class *cla,
struct class_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", is_secload ? 1 : 0);
}
static ssize_t is_secload_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int value;
r = sscanf(buf, "%d", &value);
if (r != 1)
return -EINVAL;
is_secload = value & tee_enabled();
return count;
}
static struct class_attribute vdec_class_attrs[] = {
__ATTR_RO(amrisc_regs),
@@ -3059,6 +3103,9 @@ static struct class_attribute vdec_class_attrs[] = {
__ATTR_RO(vdec_status),
__ATTR_RO(dump_vdec_blocks),
__ATTR_RO(dump_vdec_chunks),
__ATTR_RO(dump_decoder_state),
__ATTR(is_secload, S_IRUGO | S_IWUSR | S_IWGRP, is_secload_show,
is_secload_store),
__ATTR_NULL
};
@@ -3166,7 +3213,6 @@ static const struct of_device_id amlogic_vdec_dt_match[] = {
};
static struct mconfig vdec_configs[] = {
MC_PI32("debugflags", &debugflags),
MC_PU32("debug_trace_num", &debug_trace_num),
MC_PI32("hevc_max_reset_count", &hevc_max_reset_count),
MC_PU32("clk_config", &clk_config),
@@ -3246,9 +3292,6 @@ module_param(hevc_max_reset_count, int, 0664);
module_param(clk_config, uint, 0664);
module_param(step_mode, int, 0664);
module_param(debugflags, uint, 0664);
MODULE_PARM_DESC(debugflags, "\n vdec debugflags\n");
/*
*module_init(vdec_module_init);
*module_exit(vdec_module_exit);

View File

@@ -193,12 +193,14 @@ struct vdec_s {
bool use_vfm_path;
char config[PAGE_SIZE];
int config_len;
bool is_reset;
/* canvas */
int (*get_canvas)(unsigned int index, unsigned int base);
int (*dec_status)(struct vdec_s *vdec, struct vdec_info *vstatus);
int (*set_trickmode)(struct vdec_s *vdec, unsigned long trickmode);
int (*set_isreset)(struct vdec_s *vdec, int isreset);
bool (*run_ready)(struct vdec_s *vdec);
void (*run)(struct vdec_s *vdec,
@@ -320,6 +322,8 @@ extern int vdec_status(struct vdec_s *vdec, struct vdec_info *vstatus);
extern int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode);
extern int vdec_set_isreset(struct vdec_s *vdec, int isreset);
extern void vdec_set_flag(struct vdec_s *vdec, u32 flag);
extern void vdec_set_eos(struct vdec_s *vdec, bool eos);
@@ -341,8 +345,11 @@ extern bool vdec_need_more_data(struct vdec_s *vdec);
extern void hevc_reset_core(struct vdec_s *vdec);
extern void vdec_set_suspend_clk(int mode, int hevc);
int vdec_get_debug_flags(void);
unsigned char is_mult_inc(unsigned int);
int is_secload_get(void);
#endif /* VDEC_H */

View File

@@ -44,6 +44,7 @@
#define MIN_FRAME_PADDING_SIZE ((u32)(L1_CACHE_BYTES))
#define EXTRA_PADDING_SIZE (16 * SZ_1K) /*HEVC_PADDING_SIZE*/
#define MEM_NAME "VFRAME_INPUT"
static int vdec_input_get_duration_u64(struct vdec_input_s *input);
@@ -149,7 +150,9 @@ static void vframe_block_free_block(struct vframe_block_list_s *block)
if (block->addr) {
codec_mm_free_for_dma(MEM_NAME, block->addr);
}
pr_err("free block %d, size=%d\n", block->id, block->size);
/*
*pr_err("free block %d, size=%d\n", block->id, block->size);
*/
kfree(block);
}
@@ -277,9 +280,11 @@ int vdec_input_dump_blocks(struct vdec_input_s *input,
char sbuf[256];
int s = 0;
if (size <= 0)
return 0;
if (!bufs)
lbuf = sbuf;
s += sprintf(lbuf + s,
s += snprintf(lbuf + s, size - s,
"blocks:vdec-%d id:%d,bufsize=%d,dsize=%d,frames:%d,dur:%dms\n",
input->id,
input->block_nums,
@@ -299,15 +304,21 @@ int vdec_input_dump_blocks(struct vdec_input_s *input,
list_for_each_safe(p, tmp, &input->vframe_block_list) {
struct vframe_block_list_s *block = list_entry(
p, struct vframe_block_list_s, list);
if (bufs != NULL)
if (bufs != NULL) {
lbuf = bufs + s;
if (size - s < 128)
break;
}
s += vdec_input_dump_block_locked(block, lbuf, size - s);
}
list_for_each_safe(p, tmp, &input->vframe_block_free_list) {
struct vframe_block_list_s *block = list_entry(
p, struct vframe_block_list_s, list);
if (bufs != NULL)
if (bufs != NULL) {
lbuf = bufs + s;
if (size - s < 128)
break;
}
s += vdec_input_dump_block_locked(block, lbuf, size - s);
}
vdec_input_unlock(input, flags);
@@ -363,10 +374,11 @@ int vdec_input_dump_chunks(struct vdec_input_s *input,
char *lbuf = bufs;
char sbuf[256];
int s = 0;
if (size <= 0)
return 0;
if (!bufs)
lbuf = sbuf;
s += sprintf(lbuf + s,
snprintf(lbuf + s, size - s,
"blocks:vdec-%d id:%d,bufsize=%d,dsize=%d,frames:%d,maxframe:%d\n",
input->id,
input->block_nums,
@@ -515,11 +527,13 @@ static struct vframe_block_list_s *
vdec_input_add_block(input, block);
pr_info("vdec-%d:new block id=%d, total_blocks:%d, size=%d\n",
input->id,
block->id,
input->block_nums,
block->size);
/*
*pr_info("vdec-%d:new block id=%d, total_blocks:%d, size=%d\n",
* input->id,
* block->id,
* input->block_nums,
* block->size);
*/
if (0 && input->size > VFRAME_BLOCK_MAX_LEVEL * 2) {
/*
used
@@ -726,7 +740,7 @@ int vdec_input_add_frame(struct vdec_input_s *input, const char *buf,
}
if (!block) {/*try new block.*/
int ret = vdec_input_get_free_block(input,
count + need_pading_size,
count + need_pading_size + EXTRA_PADDING_SIZE,
&block);
if (ret < 0)/*no enough block now.*/
return ret;
@@ -899,8 +913,6 @@ void vdec_input_release(struct vdec_input_s *input)
p, struct vframe_chunk_s, list);
vdec_input_release_chunk(input, chunk);
}
/* release input blocks */
list_for_each_safe(p, tmp, &input->vframe_block_list) {
/*should never here.*/
list_move_tail(p, &input->vframe_block_free_list);

View File

@@ -134,6 +134,7 @@ static u32 pts_by_offset = 1;
static u32 total_frame;
static u32 next_pts;
static u64 next_pts_us64;
static bool is_reset;
#ifdef DEBUG_PTS
static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
@@ -735,6 +736,12 @@ int vvc1_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vvc1_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
static int vvc1_vdec_info_init(void)
{
gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
@@ -1072,8 +1079,11 @@ static s32 vvc1_init(void)
vf_reg_provider(&vvc1_vf_prov);
#endif
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)vvc1_amstream_dec_info.rate));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)
((unsigned long)vvc1_amstream_dec_info.rate));
stat |= STAT_VF_HOOK;
@@ -1105,6 +1115,8 @@ static int amvdec_vc1_probe(struct platform_device *pdev)
vvc1_amstream_dec_info = *pdata->sys_info;
pdata->dec_status = vvc1_dec_status;
pdata->set_isreset = vvc1_set_isreset;
is_reset = 0;
vvc1_vdec_info_init();
@@ -1136,8 +1148,10 @@ static int amvdec_vc1_remove(struct platform_device *pdev)
}
if (stat & STAT_VF_HOOK) {
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
NULL);
vf_unreg_provider(&vvc1_vf_prov);
stat &= ~STAT_VF_HOOK;

View File

@@ -362,7 +362,7 @@ typedef unsigned short u16;
#endif
static u32 debug;
static bool is_reset;
/*for debug*/
/*
udebug_flag:
@@ -1314,6 +1314,7 @@ struct VP9Decoder_s {
int new_frame_displayed;
void *mmu_box;
void *bmmu_box;
struct vframe_master_display_colour_s vf_dp;
struct firmware_s *fw;
int max_pic_w;
int max_pic_h;
@@ -1322,7 +1323,7 @@ struct VP9Decoder_s {
static int vp9_print(struct VP9Decoder_s *pbi,
int flag, const char *fmt, ...)
{
#define HEVC_PRINT_BUF 128
#define HEVC_PRINT_BUF 256
unsigned char buf[HEVC_PRINT_BUF];
int len = 0;
if (pbi == NULL ||
@@ -1393,7 +1394,7 @@ static int get_double_write_mode(struct VP9Decoder_s *pbi)
pbi->double_write_mode : double_write_mode;
}
#endif
#define MAX_4K_NUM 0x1200
#ifdef VP9_10B_MMU
int vp9_alloc_mmu(
struct VP9Decoder_s *pbi,
@@ -1410,6 +1411,11 @@ int vp9_alloc_mmu(
picture_size = compute_losless_comp_body_size(pic_width, pic_height,
bit_depth_10);
cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
if (cur_mmu_4k_number > MAX_4K_NUM) {
pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
cur_mmu_4k_number, pic_width, pic_height);
return -1;
}
return decoder_mmu_box_alloc_idx(
pbi->mmu_box,
cur_buf_idx,
@@ -5138,9 +5144,6 @@ static int vp9_local_init(struct VP9Decoder_s *pbi)
pts_unstable = ((unsigned long)(pbi->vvp9_amstream_dec_info.param)
& 0x40) >> 6;
pbi->video_signal_type = 0;
video_signal_type = pbi->video_signal_type;
if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) {
pbi->rpm_addr = kmalloc(RPM_BUF_SIZE, GFP_KERNEL);
if (pbi->rpm_addr == NULL) {
@@ -5338,6 +5341,8 @@ static void set_frame_info(struct VP9Decoder_s *pbi, struct vframe_s *vf)
vf->duration = pbi->frame_dur;
vf->duration_pulldown = 0;
vf->flag = 0;
vf->prop.master_display_colour = pbi->vf_dp;
vf->signal_type = pbi->video_signal_type;
ar = min_t(u32, pbi->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX);
vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
@@ -6446,6 +6451,12 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
return 0;
}
int vvp9_set_isreset(struct vdec_s *vdec, int isreset)
{
is_reset = isreset;
return 0;
}
#if 0
static void VP9_DECODE_INIT(void)
{
@@ -6669,9 +6680,9 @@ static s32 vvp9_init(struct VP9Decoder_s *pbi)
pbi);
vf_reg_provider(&vvp9_vf_prov);
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)pbi->frame_dur));
if (!is_reset)
vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)pbi->frame_dur));
pbi->stat |= STAT_VF_HOOK;
@@ -6722,8 +6733,10 @@ static int vvp9_stop(struct VP9Decoder_s *pbi)
}
if (pbi->stat & STAT_VF_HOOK) {
vf_notify_receiver(pbi->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
if (!is_reset)
vf_notify_receiver(pbi->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
NULL);
vf_unreg_provider(&vvp9_vf_prov);
pbi->stat &= ~STAT_VF_HOOK;
@@ -6859,6 +6872,8 @@ static int amvdec_vp9_probe(struct platform_device *pdev)
cma_dev = pdata->cma_dev;
#endif
pdata->dec_status = vvp9_dec_status;
pdata->set_isreset = vvp9_set_isreset;
is_reset = 0;
if (vvp9_init(pbi) < 0) {
pr_info("\namvdec_vp9 init failed.\n");
@@ -7404,6 +7419,8 @@ static int ammvdec_vp9_probe(struct platform_device *pdev)
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
int ret;
int config_val;
struct vframe_content_light_level_s content_light_level;
struct vframe_master_display_colour_s vf_dp;
struct BUF_s BUF[MAX_BUF_NUM];
struct VP9Decoder_s *pbi = NULL;
@@ -7414,6 +7431,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev)
}
/*pbi = (struct VP9Decoder_s *)devm_kzalloc(&pdev->dev,
sizeof(struct VP9Decoder_s), GFP_KERNEL);*/
memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
pbi = vmalloc(sizeof(struct VP9Decoder_s));
memset(pbi, 0, sizeof(struct VP9Decoder_s));
if (pbi == NULL) {
@@ -7452,6 +7470,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdata);
pbi->platform_dev = pdev;
pbi->video_signal_type = 0;
#if 1
if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 &&
pdata->config && pdata->config_len) {
@@ -7474,6 +7493,44 @@ static int ammvdec_vp9_probe(struct platform_device *pdev)
pbi->max_pic_h = config_val;
}
#endif
if (get_config_int(pdata->config, "HDRStaticInfo",
&vf_dp.present_flag) == 0
&& vf_dp.present_flag == 1) {
get_config_int(pdata->config, "mG.x",
&vf_dp.primaries[0][0]);
get_config_int(pdata->config, "mG.y",
&vf_dp.primaries[0][1]);
get_config_int(pdata->config, "mB.x",
&vf_dp.primaries[1][0]);
get_config_int(pdata->config, "mB.y",
&vf_dp.primaries[1][1]);
get_config_int(pdata->config, "mR.x",
&vf_dp.primaries[2][0]);
get_config_int(pdata->config, "mR.y",
&vf_dp.primaries[2][1]);
get_config_int(pdata->config, "mW.x",
&vf_dp.white_point[0]);
get_config_int(pdata->config, "mW.y",
&vf_dp.white_point[1]);
get_config_int(pdata->config, "mMaxDL",
&vf_dp.luminance[0]);
get_config_int(pdata->config, "mMinDL",
&vf_dp.luminance[1]);
vf_dp.content_light_level.present_flag = 1;
get_config_int(pdata->config, "mMaxCLL",
&content_light_level.max_content);
get_config_int(pdata->config, "mMaxFALL",
&content_light_level.max_pic_average);
vf_dp.content_light_level = content_light_level;
pbi->video_signal_type = (1 << 29)
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (9 << 16) /* 2020 */
| (16 << 8) /* 2084 */
| (9 << 0); /* 2020 */
}
pbi->vf_dp = vf_dp;
} else
#endif
{
@@ -7482,6 +7539,8 @@ static int ammvdec_vp9_probe(struct platform_device *pdev)
pbi->vvp9_amstream_dec_info.rate = 30;*/
pbi->double_write_mode = double_write_mode;
}
video_signal_type = pbi->video_signal_type;
#if 0
pbi->buf_start = pdata->mem_start;
pbi->buf_size = pdata->mem_end - pdata->mem_start + 1;

View File

@@ -66,10 +66,7 @@
#include <linux/amlogic/media/utils/amports_config.h>
#include <linux/amlogic/media/frame_sync/tsync_pcr.h>
#include "../parser/thread_rw.h"
#include <linux/firmware.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/libfdt_env.h>
@@ -91,6 +88,8 @@
u32 amstream_port_num;
u32 amstream_buf_num;
u32 amstream_audio_reset = 0;
#if 0
#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV
#define NO_VDEC2_INIT 1
@@ -557,6 +556,7 @@ static void video_port_release(struct port_priv_s *priv,
{
struct stream_port_s *port = priv->port;
struct vdec_s *vdec = priv->vdec;
struct vdec_s *slave = NULL;
bool is_multidec = !vdec_single(vdec);
switch (release_num) {
@@ -570,8 +570,10 @@ static void video_port_release(struct port_priv_s *priv,
/*fallthrough*/
case 3:
if (vdec->slave)
vdec_release(vdec->slave);
slave = vdec->slave;
vdec_release(vdec);
if (slave)
vdec_release(slave);
priv->vdec = NULL;
/*fallthrough*/
case 2:
@@ -696,6 +698,8 @@ static void audio_port_release(struct stream_port_s *port,
case 1:
;
}
amstream_audio_reset = 0;
return;
}
static int audio_port_reset(struct stream_port_s *port,
@@ -737,7 +741,7 @@ static int audio_port_reset(struct stream_port_s *port,
#endif
pbuf->flag |= BUF_FLAG_IN_USE;
amstream_audio_reset = 1;
pts_start(PTS_TYPE_AUDIO);
return 0;
@@ -818,16 +822,14 @@ static void sub_port_release(struct stream_port_s *port,
static int sub_port_init(struct stream_port_s *port, struct stream_buf_s *pbuf)
{
int r;
r = stbuf_init(pbuf, NULL, false);
if (r < 0)
return r;
if ((port->flag & PORT_FLAG_SID) == 0) {
pr_err("subtitle id not set\n");
return 0;
}
r = stbuf_init(pbuf, NULL, false);
if (r < 0)
return r;
if ((port->sid == 0xffff) &&
((port->type & (PORT_TYPE_MPPS | PORT_TYPE_MPTS)) == 0)) {
/* es sub */
@@ -1652,9 +1654,9 @@ static int amstream_release(struct inode *inode, struct file *file)
{
struct port_priv_s *priv = file->private_data;
struct stream_port_s *port = priv->port;
struct vdec_s *slave = NULL;
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
u32 port_flag = 0;
u32 is_4k = 0;
#endif
if (iminor(inode) >= amstream_port_num)
@@ -1669,13 +1671,11 @@ static int amstream_release(struct inode *inode, struct file *file)
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
port_flag = priv->vdec->port_flag;
#endif
if ((priv->vdec->sys_info->height *
priv->vdec->sys_info->width) > 1920*1088)
is_4k = 1;
if (priv->vdec->slave)
vdec_release(priv->vdec->slave);
slave = priv->vdec->slave;
vdec_release(priv->vdec);
if (slave)
vdec_release(slave);
priv->vdec = NULL;
}
@@ -1714,7 +1714,7 @@ static int amstream_release(struct inode *inode, struct file *file)
#else
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
&& port->vformat == VFORMAT_H264
&& is_4k)
&& bufs[BUF_TYPE_VIDEO].for_4k)
vdec_poweroff(VDEC_HEVC);
if ((port->vformat == VFORMAT_HEVC
@@ -2195,7 +2195,10 @@ static long amstream_ioctl_set(struct port_priv_s *priv, ulong arg)
else
r = -EINVAL;
break;
case AMSTREAM_SET_IS_RESET:
if (priv->vdec)
vdec_set_isreset(priv->vdec, parm.data_32);
break;
default:
r = -ENOIOCTLCMD;
break;
@@ -3805,6 +3808,11 @@ int get_sub_type(void)
return sub_type;
}
u32 get_audio_reset(void)
{
return amstream_audio_reset;
}
/*get pes buffers */
struct stream_buf_s *get_stream_buffer(int id)

View File

@@ -67,8 +67,6 @@ static int demux_skipbyte;
static struct tsdemux_ops *demux_ops;
static DEFINE_SPINLOCK(demux_ops_lock);
#define ENABLE_DEMUX_DRIVER 1
static int enable_demux_driver(void)
{
#ifdef ENABLE_DEMUX_DRIVER
@@ -156,10 +154,8 @@ static int tsdemux_set_vid(int vpid)
int r = 0;
spin_lock_irqsave(&demux_ops_lock, flags);
if (demux_ops && demux_ops->set_vid) {
pr_info("set demux vpid[%d]\r\n", vpid);
if (demux_ops && demux_ops->set_vid)
r = demux_ops->set_vid(vpid);
}
spin_unlock_irqrestore(&demux_ops_lock, flags);
return r;
@@ -171,10 +167,8 @@ static int tsdemux_set_aid(int apid)
int r = 0;
spin_lock_irqsave(&demux_ops_lock, flags);
if (demux_ops && demux_ops->set_aid) {
pr_info("set demux apid[%d]\r\n", apid);
if (demux_ops && demux_ops->set_aid)
r = demux_ops->set_aid(apid);
}
spin_unlock_irqrestore(&demux_ops_lock, flags);
return r;
@@ -186,10 +180,8 @@ static int tsdemux_set_sid(int spid)
int r = 0;
spin_lock_irqsave(&demux_ops_lock, flags);
if (demux_ops && demux_ops->set_sid) {
pr_info("set demux spid[%d]\r\n", spid);
if (demux_ops && demux_ops->set_sid)
r = demux_ops->set_sid(spid);
}
spin_unlock_irqrestore(&demux_ops_lock, flags);
return r;

Binary file not shown.