add file: parse module and hal module

Tips: In his version, h264d_test pass via the way of single pthread.

git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@263 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
DingWei
2015-09-13 20:16:23 +00:00
parent f13afd665c
commit 93930b5ef9
38 changed files with 9427 additions and 776 deletions

View File

@@ -16,6 +16,16 @@ set(H264D_HDR
h264d_global.h h264d_global.h
h264d_bitread.h h264d_bitread.h
h264d_parse.h h264d_parse.h
h264d_slice.h
h264d_sps.h
h264d_pps.h
h264d_scalist.h
h264d_sei.h
h264d_dpb.h
h264d_init.h
h264d_fill.h
) )
# h264 decoder sourse # h264 decoder sourse
@@ -25,6 +35,16 @@ set(H264D_SRC
h264d_log.c h264d_log.c
h264d_bitread.c h264d_bitread.c
h264d_parse.c h264d_parse.c
h264d_slice.c
h264d_sps.c
h264d_pps.c
h264d_scalist.c
h264d_sei.c
h264d_dpb.c
h264d_init.c
h264d_fill.c
) )

View File

@@ -23,43 +23,147 @@
#include "h264d_api.h" #include "h264d_api.h"
#include "h264d_global.h" #include "h264d_global.h"
#include "h264d_parse.h" #include "h264d_parse.h"
#include "h264d_sps.h"
#include "h264d_slice.h"
#include "h264d_dpb.h"
#define MODULE_TAG "h264d_api" #define MODULE_TAG "h264d_api"
static void close_log_files(LogEnv_t *env)
{
FCLOSE(env->fp_syn_parse);
FCLOSE(env->fp_run_parse);
}
static MPP_RET open_log_files(LogEnv_t *env, LogFlag_t *pflag)
{
MPP_RET ret = MPP_ERR_UNKNOW;
char fname[128] = { 0 };
INP_CHECK(ret, ctx, !pflag->write_en);
//!< runlog file
if (GetBitVal(env->ctrl, LOG_DEBUG_EN)) {
sprintf(fname, "%s/h264d_parse_runlog.dat", env->outpath);
FLE_CHECK(ret, env->fp_run_parse = fopen(fname, "wb"));
}
//!< read syntax
if ( GetBitVal(env->ctrl, LOG_READ_NALU )
|| GetBitVal(env->ctrl, LOG_READ_SPS )
|| GetBitVal(env->ctrl, LOG_READ_SUBSPS)
|| GetBitVal(env->ctrl, LOG_READ_PPS )
|| GetBitVal(env->ctrl, LOG_READ_SLICE ) ) {
sprintf(fname, "%s/h264d_read_syntax.dat", env->outpath);
FLE_CHECK(ret, env->fp_syn_parse = fopen(fname, "wb"));
}
__RETURN:
return MPP_OK;
__FAILED:
return ret;
}
static MPP_RET logctx_deinit(H264dLogCtx_t *logctx)
{
close_log_files(&logctx->env);
return MPP_OK;
}
static MPP_RET logctx_init(H264dLogCtx_t *logctx, LogCtx_t *logbuf)
{
RK_U8 i = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
LogCtx_t *pcur = NULL;
FUN_CHECK(ret = get_logenv(&logctx->env));
if (logctx->env.help) {
print_env_help(&logctx->env);
}
if (logctx->env.show) {
show_env_flags(&logctx->env);
}
FUN_CHECK(ret = explain_ctrl_flag(logctx->env.ctrl, &logctx->log_flag));
if ( !logctx->log_flag.debug_en
&& !logctx->log_flag.print_en && !logctx->log_flag.write_en ) {
logctx->log_flag.debug_en = 0;
goto __RETURN;
}
logctx->log_flag.level = (1 << logctx->env.level) - 1;
//!< open file
FUN_CHECK(ret = open_log_files(&logctx->env, &logctx->log_flag));
//!< set logctx
while (i < LOG_MAX) {
if (GetBitVal(logctx->env.ctrl, i)) {
pcur = logctx->parr[i] = &logbuf[i];
pcur->tag = logctrl_name[i];
pcur->flag = &logctx->log_flag;
switch (i) {
case RUN_PARSE:
pcur->fp = logctx->env.fp_run_parse;
break;
break;
case LOG_WRITE_SPSPPS:
case LOG_WRITE_RPS:
case LOG_WRITE_SCANLIST:
case LOG_WRITE_STEAM:
case LOG_WRITE_REG:
pcur->fp = logctx->env.fp_syn_hal;
default:
break;
}
}
i++;
}
__RETURN:
return ret = MPP_OK;
__FAILED:
logctx->log_flag.debug_en = 0;
logctx_deinit(logctx);
return ret;
}
static MPP_RET free_input_ctx(H264dInputCtx_t *p_Inp) static MPP_RET free_input_ctx(H264dInputCtx_t *p_Inp)
{ {
INP_CHECK(!p_Inp); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, !p_Inp);
FunctionIn(p_Inp->p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Inp->p_Dec->logctx.parr[RUN_PARSE]);
(void)p_Inp; (void)p_Inp;
FunctionOut(p_Inp->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Inp->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
static MPP_RET init_input_ctx(H264dInputCtx_t *p_Inp, MppParserInitCfg *init) static MPP_RET init_input_ctx(H264dInputCtx_t *p_Inp, MppParserInitCfg *init)
{ {
INP_CHECK(!p_Inp && !init); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, !p_Inp && !init);
FunctionIn(p_Inp->p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Inp->p_Dec->logctx.parr[RUN_PARSE]);
p_Inp->init = *init; p_Inp->init = *init;
FunctionOut(p_Inp->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Inp->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
static MPP_RET free_cur_ctx(H264dCurCtx_t *p_Cur) static MPP_RET free_cur_ctx(H264dCurCtx_t *p_Cur)
{ {
RK_U32 i = 0; RK_U32 i = 0;
INP_CHECK(!p_Cur); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, !p_Cur);
FunctionIn(p_Cur->p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Cur->p_Dec->logctx.parr[RUN_PARSE]);
if (p_Cur) { if (p_Cur) {
//rkv_h264d_recycle_slice(p_Cur->slice); recycle_slice(&p_Cur->slice);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
mpp_free(p_Cur->listP[i]); mpp_free(p_Cur->listP[i]);
mpp_free(p_Cur->listB[i]); mpp_free(p_Cur->listB[i]);
@@ -68,52 +172,70 @@ static MPP_RET free_cur_ctx(H264dCurCtx_t *p_Cur)
} }
FunctionOut(p_Cur->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Cur->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
static MPP_RET init_cur_ctx(H264dCurCtx_t *p_Cur) static MPP_RET init_cur_ctx(H264dCurCtx_t *p_Cur)
{ {
RK_U32 i = 0; RK_U32 i = 0;
INP_CHECK(!p_Cur); MPP_RET ret = MPP_ERR_UNKNOW;
FunctionIn(p_Cur->p_Dec->logctx.parr[RUN_PARSE]);
MEM_CHECK(p_Cur->strm.buf = mpp_malloc_size(RK_U8, NALU_BUF_MAX_SIZE)); INP_CHECK(ret, ctx, !p_Cur);
FunctionIn(p_Cur->p_Dec->logctx.parr[RUN_PARSE]);
p_Cur->strm.buf = mpp_malloc_size(RK_U8, NALU_BUF_MAX_SIZE);
MEM_CHECK(ret, p_Cur->strm.buf);
p_Cur->strm.max_size = NALU_BUF_MAX_SIZE; p_Cur->strm.max_size = NALU_BUF_MAX_SIZE;
p_Cur->strm.prefixdata[0] = 0xff; p_Cur->strm.prefixdata[0] = 0xff;
p_Cur->strm.prefixdata[1] = 0xff; p_Cur->strm.prefixdata[1] = 0xff;
p_Cur->strm.prefixdata[2] = 0xff; p_Cur->strm.prefixdata[2] = 0xff;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
MEM_CHECK(p_Cur->listP[i] = mpp_malloc_size(H264_StorePic_t*, MAX_LIST_SIZE * sizeof(H264_StorePic_t*))); // +1 for reordering p_Cur->listP[i] = mpp_malloc_size(H264_StorePic_t*, MAX_LIST_SIZE * sizeof(H264_StorePic_t*));
MEM_CHECK(p_Cur->listB[i] = mpp_malloc_size(H264_StorePic_t*, MAX_LIST_SIZE * sizeof(H264_StorePic_t*))); // +1 for reordering p_Cur->listB[i] = mpp_malloc_size(H264_StorePic_t*, MAX_LIST_SIZE * sizeof(H264_StorePic_t*));
MEM_CHECK(ret, p_Cur->listP[i] && p_Cur->listB[i]); // +1 for reordering
} }
FunctionOut(p_Cur->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Cur->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
free_cur_ctx(p_Cur); free_cur_ctx(p_Cur);
return MPP_NOK; return ret;
} }
static MPP_RET free_vid_ctx(H264dVideoCtx_t *p_Vid) static MPP_RET free_vid_ctx(H264dVideoCtx_t *p_Vid)
{ {
RK_U32 i = 0; RK_U32 i = 0;
INP_CHECK(!p_Vid); MPP_RET ret = MPP_ERR_UNKNOW;
FunctionIn(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) { INP_CHECK(ret, ctx, !p_Vid);
mpp_free(p_Vid->p_Dpb_layer[i]); FunctionIn(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
}
for (i = 0; i < MAXSPS; i++)
{
recycle_subsps(&p_Vid->subspsSet[i]);
}
for (i = 0; i < MAX_NUM_DPB_LAYERS; i++)
{
free_dpb(p_Vid->p_Dpb_layer[i]);
mpp_free(p_Vid->p_Dpb_layer[i]);
}
free_storable_picture(p_Vid->dec_picture);
//free_frame_store(&p_Vid->out_buffer);
FunctionOut(p_Vid->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
static MPP_RET init_vid_ctx(H264dVideoCtx_t *p_Vid) static MPP_RET init_vid_ctx(H264dVideoCtx_t *p_Vid)
{ {
RK_U32 i = 0; RK_U32 i = 0;
INP_CHECK(!p_Vid); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, !p_Vid);
FunctionIn(p_Vid->p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) { for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) {
MEM_CHECK(p_Vid->p_Dpb_layer[i] = mpp_calloc(H264_DpbBuf_t, 1)); p_Vid->p_Dpb_layer[i] = mpp_calloc(H264_DpbBuf_t, 1);
MEM_CHECK(ret, p_Vid->p_Dpb_layer[i]);
p_Vid->p_Dpb_layer[i]->layer_id = i; p_Vid->p_Dpb_layer[i]->layer_id = i;
p_Vid->p_Dpb_layer[i]->p_Vid = p_Vid; p_Vid->p_Dpb_layer[i]->p_Vid = p_Vid;
p_Vid->p_Dpb_layer[i]->init_done = 0; p_Vid->p_Dpb_layer[i]->init_done = 0;
@@ -140,81 +262,88 @@ static MPP_RET init_vid_ctx(H264dVideoCtx_t *p_Vid)
} }
FunctionOut(p_Vid->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
free_vid_ctx(p_Vid); free_vid_ctx(p_Vid);
return MPP_NOK; return ret;
} }
static MPP_RET free_dxva_ctx(H264dDxvaCtx_t *p_dxva) static MPP_RET free_dxva_ctx(H264dDxvaCtx_t *p_dxva)
{ {
INP_CHECK(!p_dxva); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, NULL == p_dxva);
FunctionIn(p_dxva->p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_dxva->p_Dec->logctx.parr[RUN_PARSE]);
mpp_free(p_dxva->slice_short);
mpp_free(p_dxva->slice_long); mpp_free(p_dxva->slice_long);
mpp_free(p_dxva->bitstream); mpp_free(p_dxva->bitstream);
mpp_free(p_dxva->syn.buf); mpp_free(p_dxva->syn.buf);
FunctionOut(p_dxva->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_dxva->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
static MPP_RET init_dxva_ctx(H264dDxvaCtx_t *p_dxva) static MPP_RET init_dxva_ctx(H264dDxvaCtx_t *p_dxva)
{ {
INP_CHECK(!p_dxva); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, !p_dxva);
FunctionIn(p_dxva->p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_dxva->p_Dec->logctx.parr[RUN_PARSE]);
p_dxva->max_slice_size = MAX_SLICE_SIZE; p_dxva->max_slice_size = MAX_SLICE_SIZE;
MEM_CHECK(p_dxva->slice_short = mpp_calloc(DXVA_Slice_H264_Short, p_dxva->max_slice_size)); p_dxva->max_strm_size = FRAME_BUF_MAX_SIZE;
MEM_CHECK(p_dxva->slice_long = mpp_calloc(DXVA_Slice_H264_Long, p_dxva->max_slice_size)); p_dxva->slice_long = mpp_calloc(DXVA_Slice_H264_Long, p_dxva->max_slice_size);
p_dxva->max_strm_size = FRAME_BUF_MAX_SIZE; MEM_CHECK(ret, p_dxva->slice_long);
MEM_CHECK(p_dxva->bitstream = mpp_malloc(RK_U8, p_dxva->max_strm_size)); p_dxva->bitstream = mpp_malloc(RK_U8, p_dxva->max_strm_size);
MEM_CHECK(p_dxva->syn.buf = mpp_calloc(DXVA2_DecodeBufferDesc, SYNTAX_BUF_SIZE)); p_dxva->syn.buf = mpp_calloc(DXVA2_DecodeBufferDesc, SYNTAX_BUF_SIZE);
MEM_CHECK(ret, p_dxva->bitstream && p_dxva->syn.buf);
FunctionOut(p_dxva->p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_dxva->p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
return MPP_NOK; return ret;
} }
static MPP_RET free_dec_ctx(H264_DecCtx_t *p_Dec) static MPP_RET free_dec_ctx(H264_DecCtx_t *p_Dec)
{ {
RK_U32 i = 0; RK_U32 i = 0;
INP_CHECK(!p_Dec); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, NULL == p_Dec);
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
for (i = 0; i < MAX_TASK_SIZE; i++) { for (i = 0; i < MAX_TASK_SIZE; i++) {
free_dxva_ctx(&p_Dec->dxva_ctx[i]); free_dxva_ctx(&p_Dec->mem->dxva_ctx[i]);
} }
mpp_free(p_Dec->mem); mpp_free(p_Dec->mem);
FunctionOut(p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
static MPP_RET init_dec_ctx(H264_DecCtx_t *p_Dec) static MPP_RET init_dec_ctx(H264_DecCtx_t *p_Dec)
{ {
RK_U32 i = 0; RK_U32 i = 0;
INP_CHECK(!p_Dec); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, !p_Dec);
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
p_Dec->mem = mpp_calloc(H264_DecMem_t, 1);
MEM_CHECK(p_Dec->mem = mpp_calloc(H264_DecMem_t, 1)); MEM_CHECK(ret, p_Dec->mem);
p_Dec->dpb_mark = p_Dec->mem->dpb_mark; //!< for write out, MAX_DPB_SIZE p_Dec->dpb_mark = p_Dec->mem->dpb_mark; //!< for write out, MAX_DPB_SIZE
p_Dec->dpb_info = p_Dec->mem->dpb_info; //!< 16 p_Dec->dpb_info = p_Dec->mem->dpb_info; //!< 16
p_Dec->refpic_info_p = p_Dec->mem->refpic_info_p; //!< 32 p_Dec->refpic_info_p = p_Dec->mem->refpic_info_p; //!< 32
p_Dec->refpic_info[0] = p_Dec->mem->refpic_info[0]; //!< [2][32] p_Dec->refpic_info[0] = p_Dec->mem->refpic_info[0]; //!< [2][32]
p_Dec->refpic_info[1] = p_Dec->mem->refpic_info[1]; //!< [2][32] p_Dec->refpic_info[1] = p_Dec->mem->refpic_info[1]; //!< [2][32]
p_Dec->dxva_ctx = p_Dec->mem->dxva_ctx; //!< MAX_TASK_SIZE //!< MAX_TASK_SIZE
for (i = 0; i < MAX_TASK_SIZE; i++) {
for (i = 0; i < MAX_TASK_SIZE; i++) { p_Dec->mem->dxva_ctx[i].p_Dec = p_Dec;
p_Dec->dxva_ctx[i].p_Dec = p_Dec; FUN_CHECK(ret = init_dxva_ctx(&p_Dec->mem->dxva_ctx[i]));
FUN_CHECK(init_dxva_ctx(&p_Dec->dxva_ctx[i]));
} }
p_Dec->dxva_idx = 0;
p_Dec->dxva_ctx = p_Dec->mem->dxva_ctx;
//!< init Dpb_memory Mark //!< init Dpb_memory Mark
for (i = 0; i < MAX_DPB_SIZE; i++) { for (i = 0; i < MAX_DPB_SIZE; i++) {
p_Dec->dpb_mark[i].index = i; p_Dec->dpb_mark[i].index = i;
@@ -225,12 +354,12 @@ static MPP_RET init_dec_ctx(H264_DecCtx_t *p_Dec)
p_Dec->nalu_ret = NALU_NULL; p_Dec->nalu_ret = NALU_NULL;
p_Dec->first_frame_flag = 1; p_Dec->first_frame_flag = 1;
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
free_dec_ctx(p_Dec); free_dec_ctx(p_Dec);
return MPP_NOK; return ret;
} }
@@ -245,15 +374,18 @@ __FAILED:
MPP_RET h264d_init(void *decoder, MppParserInitCfg *init) MPP_RET h264d_init(void *decoder, MppParserInitCfg *init)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_ERR_UNKNOW;
H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder; H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
INP_CHECK(!p_Dec); INP_CHECK(ret, ctx, !p_Dec);
// init logctx // init logctx
FUN_CHECK(ret = h264d_log_init(&p_Dec->logctx, p_Dec->logctxbuf)); FUN_CHECK(ret = logctx_init(&p_Dec->logctx, p_Dec->logctxbuf));
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
MEM_CHECK(p_Dec->p_Inp = mpp_calloc(H264dInputCtx_t, 1));
MEM_CHECK(p_Dec->p_Cur = mpp_calloc(H264dCurCtx_t, 1)); p_Dec->p_Inp = mpp_calloc(H264dInputCtx_t, 1);
MEM_CHECK(p_Dec->p_Vid = mpp_calloc(H264dVideoCtx_t, 1)); p_Dec->p_Cur = mpp_calloc(H264dCurCtx_t, 1);
p_Dec->p_Vid = mpp_calloc(H264dVideoCtx_t, 1);
MEM_CHECK(ret, p_Dec->p_Inp && p_Dec->p_Cur && p_Dec->p_Vid);
p_Dec->p_Inp->p_Dec = p_Dec; p_Dec->p_Inp->p_Dec = p_Dec;
p_Dec->p_Inp->p_Cur = p_Dec->p_Cur; p_Dec->p_Inp->p_Cur = p_Dec->p_Cur;
p_Dec->p_Inp->p_Vid = p_Dec->p_Vid; p_Dec->p_Inp->p_Vid = p_Dec->p_Vid;
@@ -273,11 +405,11 @@ MPP_RET h264d_init(void *decoder, MppParserInitCfg *init)
FunctionOut(p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
h264d_deinit(decoder); h264d_deinit(decoder);
return MPP_NOK; return ret;
} }
/*! /*!
*********************************************************************** ***********************************************************************
@@ -287,9 +419,10 @@ __FAILED:
*/ */
MPP_RET h264d_deinit(void *decoder) MPP_RET h264d_deinit(void *decoder)
{ {
MPP_RET ret = MPP_ERR_UNKNOW;
H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder; H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
INP_CHECK(!decoder); INP_CHECK(ret, ctx, !decoder);
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
free_input_ctx(p_Dec->p_Inp); free_input_ctx(p_Dec->p_Inp);
@@ -301,9 +434,9 @@ MPP_RET h264d_deinit(void *decoder)
free_dec_ctx(p_Dec); free_dec_ctx(p_Dec);
FunctionOut(p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Dec->logctx.parr[RUN_PARSE]);
h264d_log_deinit(&p_Dec->logctx); logctx_deinit(&p_Dec->logctx);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
/*! /*!
*********************************************************************** ***********************************************************************
@@ -313,11 +446,13 @@ __RETURN:
*/ */
MPP_RET h264d_reset(void *decoder) MPP_RET h264d_reset(void *decoder)
{ {
INP_CHECK(decoder); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, decoder);
(void)decoder; (void)decoder;
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
/*! /*!
@@ -328,11 +463,13 @@ __RETURN:
*/ */
MPP_RET h264d_flush(void *decoder) MPP_RET h264d_flush(void *decoder)
{ {
INP_CHECK(decoder); MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, decoder);
(void)decoder; (void)decoder;
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
} }
/*! /*!
@@ -343,7 +480,9 @@ __RETURN:
*/ */
MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param) MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param)
{ {
MPP_RET ret = MPP_ERR_UNKNOW;
INP_CHECK(ret, ctx, decoder);
(void)decoder; (void)decoder;
@@ -351,7 +490,8 @@ MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param)
(void)param; (void)param;
return MPP_OK; __RETURN:
return ret = MPP_OK;
} }
/*! /*!
@@ -362,28 +502,33 @@ MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param)
*/ */
MPP_RET h264d_parse(void *decoder, MppPacket in_pkt, HalDecTask *in_task) MPP_RET h264d_parse(void *decoder, MppPacket in_pkt, HalDecTask *in_task)
{ {
MPP_RET ret = MPP_ERR_UNKNOW;
H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder; H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
MppPacketImpl *pkt = (MppPacketImpl *)in_pkt; MppPacketImpl *pkt = (MppPacketImpl *)in_pkt;
INP_CHECK(!decoder && !in_pkt && !in_task);
INP_CHECK(ret, ctx, !decoder && !in_pkt && !in_task);
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]); FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
p_Dec->p_Inp->in_buf = (RK_U8 *)pkt->pos;
p_Dec->p_Inp->in_size = &pkt->size;
p_Dec->p_Inp->is_eos = pkt->flag & MPP_PACKET_FLAG_EOS;
FUN_CHECK(ret = parse_loop(p_Dec));
if (p_Dec->parser_end_flag)
{
in_task->valid = 1;
in_task->syntax.number = p_Dec->dxva_ctx->syn.num;
pkt->size = (pkt->size >= 500) ? (pkt->size - 500) : 0; in_task->syntax.data = (void *)p_Dec->dxva_ctx->syn.buf;
FUN_CHECK(ret = update_dpb(p_Dec));
in_task->valid = pkt->size ? 0 : 1; p_Dec->dxva_idx = (p_Dec->dxva_idx + 1) % MAX_TASK_SIZE;
p_Dec->dxva_ctx = &p_Dec->mem->dxva_ctx[p_Dec->dxva_idx];
}
FunctionOut(p_Dec->logctx.parr[RUN_PARSE]); FunctionOut(p_Dec->logctx.parr[RUN_PARSE]);
__RETURN: __RETURN:
return MPP_OK; return ret = MPP_OK;
__FAILED:
return ret;
} }
/*! /*!

View File

@@ -22,9 +22,9 @@
static MPP_RET update_currbyte(BitReadCtx_t *bitctx) static MPP_RET update_currbyte(BitReadCtx_t *bitctx)
{ {
if (bitctx->bytes_left_ < 1) MPP_RET ret = MPP_ERR_UNKNOW;
return MPP_NOK;
VAL_CHECK(ret, bitctx->bytes_left_ > 0);
// Emulation prevention three-byte detection. // Emulation prevention three-byte detection.
// If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03). // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03).
if (*bitctx->data_ == 0x03 && (bitctx->prev_two_bytes_ & 0xffff) == 0) { if (*bitctx->data_ == 0x03 && (bitctx->prev_two_bytes_ & 0xffff) == 0) {
@@ -34,19 +34,17 @@ static MPP_RET update_currbyte(BitReadCtx_t *bitctx)
++bitctx->emulation_prevention_bytes_; ++bitctx->emulation_prevention_bytes_;
// Need another full three bytes before we can detect the sequence again. // Need another full three bytes before we can detect the sequence again.
bitctx->prev_two_bytes_ = 0xffff; bitctx->prev_two_bytes_ = 0xffff;
VAL_CHECK(ret, bitctx->bytes_left_ > 0);
if (bitctx->bytes_left_ < 1)
return MPP_NOK;
} }
// Load a new byte and advance pointers. // Load a new byte and advance pointers.
bitctx->curr_byte_ = *bitctx->data_++ & 0xff; bitctx->curr_byte_ = *bitctx->data_++ & 0xff;
--bitctx->bytes_left_; --bitctx->bytes_left_;
bitctx->num_remaining_bits_in_curr_byte_ = 8; bitctx->num_remaining_bits_in_curr_byte_ = 8;
bitctx->prev_two_bytes_ = (bitctx->prev_two_bytes_ << 8) | bitctx->curr_byte_; bitctx->prev_two_bytes_ = (bitctx->prev_two_bytes_ << 8) | bitctx->curr_byte_;
return MPP_OK; return ret = MPP_OK;
__FAILED:
return ret;
} }
/*! /*!
@@ -60,12 +58,11 @@ static MPP_RET update_currbyte(BitReadCtx_t *bitctx)
MPP_RET read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out) MPP_RET read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_ERR_UNKNOW;
RK_S32 bits_left = num_bits; RK_S32 bits_left = num_bits;
*out = 0; *out = 0;
ASSERT(num_bits <= 31); VAL_CHECK(ret, num_bits < 32);
while (bitctx->num_remaining_bits_in_curr_byte_ < bits_left) { while (bitctx->num_remaining_bits_in_curr_byte_ < bits_left) {
// Take all that's left in current byte, shift to make space for the rest. // Take all that's left in current byte, shift to make space for the rest.
*out |= (bitctx->curr_byte_ << (bits_left - bitctx->num_remaining_bits_in_curr_byte_)); *out |= (bitctx->curr_byte_ << (bits_left - bitctx->num_remaining_bits_in_curr_byte_));
@@ -79,9 +76,9 @@ MPP_RET read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out)
bitctx->num_remaining_bits_in_curr_byte_ -= bits_left; bitctx->num_remaining_bits_in_curr_byte_ -= bits_left;
bitctx->used_bits += num_bits; bitctx->used_bits += num_bits;
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
return ret; return ret = MPP_ERR_READ_BIT;
} }
/*! /*!
*********************************************************************** ***********************************************************************
@@ -101,17 +98,17 @@ MPP_RET read_one_bit(BitReadCtx_t *bitctx, RK_S32 *out)
*/ */
MPP_RET read_ue(BitReadCtx_t *bitctx, RK_U32 *val) MPP_RET read_ue(BitReadCtx_t *bitctx, RK_U32 *val)
{ {
MPP_RET ret = MPP_NOK;
RK_S32 num_bits = -1; RK_S32 num_bits = -1;
RK_S32 bit; RK_S32 bit;
RK_S32 rest; RK_S32 rest;
MPP_RET ret = MPP_ERR_UNKNOW;
// Count the number of contiguous zero bits. // Count the number of contiguous zero bits.
do { do {
FUN_CHECK(ret = read_bits(bitctx, 1, &bit)); FUN_CHECK(ret = read_bits(bitctx, 1, &bit));
num_bits++; num_bits++;
} while (bit == 0); } while (bit == 0);
VAL_CHECK(num_bits < 32); VAL_CHECK(ret, num_bits < 32);
// Calculate exp-Golomb code value of size num_bits. // Calculate exp-Golomb code value of size num_bits.
*val = (1 << num_bits) - 1; *val = (1 << num_bits) - 1;
@@ -120,9 +117,9 @@ MPP_RET read_ue(BitReadCtx_t *bitctx, RK_U32 *val)
*val += rest; *val += rest;
} }
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
return ret; return ret = MPP_ERR_READ_BIT;
} }
/*! /*!
*********************************************************************** ***********************************************************************
@@ -132,8 +129,9 @@ __FAILED:
*/ */
MPP_RET read_se(BitReadCtx_t *bitctx, RK_S32 *val) MPP_RET read_se(BitReadCtx_t *bitctx, RK_S32 *val)
{ {
MPP_RET ret = MPP_NOK; RK_U32 ue;
RK_U32 ue; MPP_RET ret = MPP_ERR_UNKNOW;
FUN_CHECK(ret = read_ue(bitctx, &ue)); FUN_CHECK(ret = read_ue(bitctx, &ue));
if (ue % 2 == 0) { // odd if (ue % 2 == 0) { // odd
@@ -142,9 +140,9 @@ MPP_RET read_se(BitReadCtx_t *bitctx, RK_S32 *val)
*val = (RK_S32)((ue >> 1) + 1); *val = (RK_S32)((ue >> 1) + 1);
} }
return MPP_OK; return ret = MPP_OK;
__FAILED: __FAILED:
return ret; return ret = MPP_ERR_READ_BIT;
} }
/*! /*!

View File

@@ -23,66 +23,59 @@
#include "mpp_err.h" #include "mpp_err.h"
#include "h264d_log.h" #include "h264d_log.h"
#define __BITREAD_ERR __bitread_error
#define WRITE_LOG(bitctx, name)\ #define WRITE_LOG(bitctx, name)\
do {\ do {\
LogInfo(bitctx->ctx, "%s", name);\ LogInfo(bitctx->ctx, "%s", name);\
} while (0) } while (0)
#define SKIP_BITS(bitctx, num_bits)\ #define SKIP_BITS(ret, bitctx, num_bits)\
do {\ do {\
RK_S32 _out;\ RK_S32 _out;\
MPP_RET ret = MPP_NOK;\ ret = read_bits(bitctx, num_bits, &_out);\
ret = read_bits(bitctx, num_bits, &_out);\ LogInfo(bitctx->ctx, "%48s = %10d", "skip", _out);\
LogInfo(bitctx->ctx, "%48s = %10d", "skip", _out);\ if (ret) { ASSERT(0); goto __FAILED; }\
if (ret) { ASSERT(0); goto __FAILED; }\ } while (0)
} while (0)
#define READ_BITS(bitctx, num_bits, out, name)\ #define READ_BITS(ret, bitctx, num_bits, out, name)\
do {\ do {\
RK_S32 _out;\ ret = read_bits(bitctx, num_bits, (RK_S32 *)out);\
MPP_RET ret = MPP_NOK;\ LogInfo(bitctx->ctx, "%48s = %10d", name, *out);\
ret = read_bits(bitctx, num_bits, &_out);\ if (ret) { ASSERT(0); goto __FAILED; }\
LogInfo(bitctx->ctx, "%48s = %10d", name, _out);\ } while (0)
if (ret) { ASSERT(0); goto __FAILED; }\
else { *out = _out; }\
} while (0)
#define READ_ONEBIT(ret, bitctx, out, name)\
#define READ_ONEBIT(bitctx, out, name)\
do {\ do {\
RK_S32 _out;\ ret = read_bits(bitctx, 1, (RK_S32 *)out);\
MPP_RET ret = MPP_NOK;\ LogInfo(bitctx->ctx, "%48s = %10d", name, *out);\
ret = read_bits(bitctx, 1, &_out);\ if (ret) { ASSERT(0); goto __FAILED; }\
LogInfo(bitctx->ctx, "%48s = %10d", name, _out);\
if (ret) { ASSERT(0); goto __FAILED; }\
else { *out = _out; }\
} while (0) } while (0)
#define READ_UE(bitctx, out, name)\ #define READ_UE(ret, bitctx, out, name)\
do {\ do {\
RK_U32 _out;\ ret = read_ue(bitctx, (RK_U32 *)out);\
MPP_RET ret = MPP_NOK;\ LogInfo(bitctx->ctx, "%48s = %10d", name, *out);\
ret = read_ue(bitctx, &_out);\ if (ret) { ASSERT(0); goto __FAILED; }\
LogInfo(bitctx->ctx, "%48s = %10d", name, _out);\ } while (0)
if (ret) { ASSERT(0); goto __FAILED; }\
else { *out = _out; }\
} while (0)
#define READ_SE(bitctx, out, name)\ #define READ_SE(ret, bitctx, out, name)\
do {\ do {\
RK_S32 _out;\ ret = read_se(bitctx, (RK_S32 *)out);\
MPP_RET ret = MPP_NOK;\ LogInfo(bitctx->ctx, "%48s = %10d", name, *out);\
ret = read_se(bitctx, &_out);\ if (ret) { ASSERT(0); goto __FAILED; }\
LogInfo(bitctx->ctx, "%48s = %10d", name, _out);\ } while (0)
if (ret) { ASSERT(0); goto __FAILED; }\
else { *out = _out; }\
} while (0)
#define CHECK_RANGE(ret, bitctx, val, _min, _max)\
do {\
if ((val) < (_min) || (val) > (_max)) {\
LogError(bitctx->ctx, "%d[%d,%d]", val, _min, _max);\
ret = MPP_ERR_VALUE;\
ASSERT(0); goto __FAILED;\
} } while (0)
typedef struct getbit_ctx_t { typedef struct getbit_ctx_t {
@@ -113,7 +106,7 @@ typedef struct getbit_ctx_t {
extern "C" { extern "C" {
#endif #endif
MPP_RET read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); MPP_RET read_bits( BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out);
MPP_RET read_one_bit(BitReadCtx_t *bitctx, RK_S32 *out); MPP_RET read_one_bit(BitReadCtx_t *bitctx, RK_S32 *out);
MPP_RET read_ue(BitReadCtx_t *bitctx, RK_U32* val); MPP_RET read_ue(BitReadCtx_t *bitctx, RK_U32* val);
MPP_RET read_se(BitReadCtx_t *bitctx, RK_S32* val); MPP_RET read_se(BitReadCtx_t *bitctx, RK_S32* val);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_DPB_H_
#define _H264D_DPB_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
void update_ref_list(H264_DpbBuf_t *p_Dpb);
void update_ltref_list(H264_DpbBuf_t *p_Dpb);
void free_storable_picture(H264_StorePic_t *p);
void free_frame_store(H264_FrameStore_t *f);
MPP_RET idr_memory_management(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p);
MPP_RET insert_picture_in_dpb(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs, H264_StorePic_t *p, RK_U8 combine_flag);
MPP_RET init_dpb (H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb, RK_S32 type);
MPP_RET flush_dpb(H264_DpbBuf_t *p_Dpb);
MPP_RET update_dpb(H264_DecCtx_t *p_Dec);
void free_dpb (H264_DpbBuf_t *p_Dpb);
MPP_RET exit_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t **dec_picture);
MPP_RET prepare_init_dpb_info(H264_SLICE_t *currSlice);
RK_U32 get_filed_dpb_combine_flag(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p);
H264_StorePic_t *alloc_storable_picture(H264dVideoCtx_t *p_Vid, RK_S32 structure);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _H264D_DPB_H_ */

View File

@@ -0,0 +1,426 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include "mpp_mem.h"
#include "h264d_log.h"
#include "h264d_fill.h"
#define MODULE_TAG "h264d_fill"
#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
#define ALIGN(x, a) ( ((x) + (a) - 1) & (~((a) - 1)) )
static const RK_U8 start_code[3] = { 0, 0, 1 };
static MPP_RET realloc_slice_list(H264dDxvaCtx_t *dxva_ctx)
{
MPP_RET ret = MPP_ERR_UNKNOW;
dxva_ctx->max_slice_size += ADD_SLICE_SIZE;
dxva_ctx->slice_long = mpp_realloc(dxva_ctx->slice_long, DXVA_Slice_H264_Long, dxva_ctx->max_slice_size);
MEM_CHECK(ret, dxva_ctx->slice_long);
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
static MPP_RET realloc_stream_buffer(H264dDxvaCtx_t *dxva_ctx, RK_U32 stream_add)
{
MPP_RET ret = MPP_ERR_UNKNOW;
if (stream_add > FRAME_BUF_ADD_SIZE)
{
dxva_ctx->max_strm_size += ALIGN(stream_add, 128);
}
else
{
dxva_ctx->max_strm_size += FRAME_BUF_ADD_SIZE;
}
dxva_ctx->bitstream = mpp_realloc(dxva_ctx->bitstream, RK_U8, dxva_ctx->max_strm_size);
MEM_CHECK (ret, dxva_ctx->bitstream);
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
static MPP_RET fill_stream_data(H264dDxvaCtx_t *dxva_ctx, H264_Nalu_t *p_nal)
{
MPP_RET ret = MPP_ERR_UNKNOW;
RK_U32 stream_offset = 0;
RK_U32 streamlen_add = 0;
DXVA_Slice_H264_Long *p_long = NULL;
if (dxva_ctx->slice_count >= dxva_ctx->max_slice_size)
{
FUN_CHECK(ret = realloc_slice_list(dxva_ctx));
}
streamlen_add = p_nal->sodb_len + sizeof(start_code);
stream_offset = dxva_ctx->strm_offset + streamlen_add;
if (stream_offset > dxva_ctx->max_strm_size)
{
FUN_CHECK (ret = realloc_stream_buffer(dxva_ctx, streamlen_add));
}
p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count];
memset(p_long, 0, sizeof(DXVA_Slice_H264_Long));
p_long->BSNALunitDataLocation = dxva_ctx->strm_offset;
p_long->wBadSliceChopping = 0; //!< set to 0 in Rock-Chip RKVDEC IP
memcpy(&dxva_ctx->bitstream[dxva_ctx->strm_offset], start_code, sizeof(start_code));
dxva_ctx->strm_offset += sizeof(start_code);
memcpy(&dxva_ctx->bitstream[dxva_ctx->strm_offset], p_nal->sodb_buf, p_nal->sodb_len);
dxva_ctx->strm_offset += p_nal->sodb_len;
p_long->SliceBytesInBuffer = dxva_ctx->strm_offset - p_long->BSNALunitDataLocation;
return ret = MPP_OK;
__FAILED:
return ret;
}
static void fill_picture_entry(DXVA_PicEntry_H264 *pic, RK_U32 index, RK_U32 flag)
{
ASSERT((index & 0x7f) == index && (flag & 0x01) == flag);
pic->bPicEntry = index | (flag << 7);
}
/*!
***********************************************************************
* \brief
* fill picture parameters
***********************************************************************
*/
//extern "C"
void fill_qmatrix(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm)
{
RK_S32 i = 0, j = 0;
memset(qm, 0, sizeof(DXVA_Qmatrix_H264));
for (i = 0; i < 6; ++i) //!< 4x4, 6 lists
{
for (j = 0; j < H264ScalingList4x4Length; j++)
{
qm->bScalingLists4x4[i][j] = p_Vid->qmatrix[i][j];
}
}
for (i = 6; i < ((p_Vid->active_sps->chroma_format_idc != YUV444) ? 8 : 12); ++i)
{
for (j = 0; j < H264ScalingList8x8Length; j++)
{
qm->bScalingLists8x8[i-6][j] = p_Vid->qmatrix[i][j];
}
}
}
/*!
***********************************************************************
* \brief
* fill picture parameters
***********************************************************************
*/
//extern "C"
void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp)
{
RK_U32 i = 0, j = 0, num_views = 0;
H264_StorePic_t *dec_picture = p_Vid->dec_picture;
H264_DpbInfo_t *dpb_info = p_Vid->p_Dec->dpb_info;
memset(pp, 0, sizeof(DXVA_PicParams_H264_MVC));
//!< Configure current picture
fill_picture_entry(&pp->CurrPic, dec_picture->mem_mark->index, dec_picture->structure == BOTTOM_FIELD);
//!< Configure the set of references
pp->UsedForReferenceFlags = 0;
pp->NonExistingFrameFlags = 0;
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++)
{
if (dpb_info[i].ADDR_Y)
{
fill_picture_entry(&pp->RefFrameList[i], dpb_info[i].mem_mark_idx, dpb_info[i].is_long_term);
pp->FieldOrderCntList[i][0] = dpb_info[i].TOP_POC;
pp->FieldOrderCntList[i][1] = dpb_info[i].BOT_POC;
pp->FrameNumList[i] = dpb_info[i].frame_num_wrap;
if (dpb_info[i].is_used & 0x01) //!< top_field
{
pp->UsedForReferenceFlags |= 1 << (2 * i + 0);
}
if (dpb_info[i].is_used & 0x02) //!< bot_field
{
pp->UsedForReferenceFlags |= 1 << (2 * i + 1);
}
}
else
{
pp->RefFrameList[i].bPicEntry = 0xff;
pp->FieldOrderCntList[i][0] = 0;
pp->FieldOrderCntList[i][1] = 0;
pp->FrameNumList[i] = 0;
}
}
pp->wFrameWidthInMbsMinus1 = p_Vid->active_sps->pic_width_in_mbs_minus1;
pp->wFrameHeightInMbsMinus1 = p_Vid->active_sps->pic_height_in_map_units_minus1;
pp->num_ref_frames = p_Vid->active_sps->max_num_ref_frames;
pp->wBitFields = ((dec_picture->iCodingType == FIELD_CODING) << 0) //!< field_pic_flag
| (dec_picture->mb_aff_frame_flag << 1) //!< MbaffFrameFlag
| (0 << 2) //!< residual_colour_transform_flag
| (0 << 3) //!< sp_for_switch_flag
| (p_Vid->active_sps->chroma_format_idc << 4) //!< chroma_format_idc
| (dec_picture->used_for_reference << 6) //!< RefPicFlag
| (p_Vid->active_pps->constrained_intra_pred_flag << 7) //!< constrained_intra_pred_flag
| (p_Vid->active_pps->weighted_pred_flag << 8) //!< weighted_pred_flag
| (p_Vid->active_pps->weighted_bipred_idc << 9) //!< weighted_bipred_idc
| (1 << 11) //!< MbsConsecutiveFlag
| (p_Vid->active_sps->frame_mbs_only_flag << 12) //!< frame_mbs_only_flag
| (p_Vid->active_pps->transform_8x8_mode_flag << 13) //!< transform_8x8_mode_flag
| ((p_Vid->active_sps->level_idc >= 31) << 14) //!< MinLumaBipredSize8x8Flag
| (1 << 15); //!< IntraPicFlag (Modified if we detect a non-intra slice in dxva2_h264_decode_slice)
pp->bit_depth_luma_minus8 = p_Vid->active_sps->bit_depth_luma_minus8;
pp->bit_depth_chroma_minus8 = p_Vid->active_sps->bit_depth_chroma_minus8;
pp->Reserved16Bits = 3; //!< FIXME is there a way to detect the right mode
pp->StatusReportFeedbackNumber = 1 /*+ ctx->report_id++*/;
pp->CurrFieldOrderCnt[0] = 0;
if (dec_picture->structure == TOP_FIELD || dec_picture->structure == FRAME)
{
pp->CurrFieldOrderCnt[0] = dec_picture->top_poc;
}
pp->CurrFieldOrderCnt[1] = 0;
if (dec_picture->structure == BOTTOM_FIELD || dec_picture->structure == FRAME)
{
pp->CurrFieldOrderCnt[1] = dec_picture->bottom_poc;
}
pp->pic_init_qs_minus26 = p_Vid->active_pps->pic_init_qs_minus26;
pp->chroma_qp_index_offset = p_Vid->active_pps->chroma_qp_index_offset;
pp->second_chroma_qp_index_offset = p_Vid->active_pps->second_chroma_qp_index_offset;
pp->ContinuationFlag = 1;
pp->pic_init_qp_minus26 = p_Vid->active_pps->pic_init_qp_minus26;
pp->num_ref_idx_l0_active_minus1 = p_Vid->active_pps->num_ref_idx_l0_default_active_minus1;
pp->num_ref_idx_l1_active_minus1 = p_Vid->active_pps->num_ref_idx_l1_default_active_minus1;
pp->Reserved8BitsA = 0;
pp->frame_num = dec_picture->frame_num;
pp->log2_max_frame_num_minus4 = p_Vid->active_sps->log2_max_frame_num_minus4;
pp->pic_order_cnt_type = p_Vid->active_sps->pic_order_cnt_type;
if (pp->pic_order_cnt_type == 0)
{
pp->log2_max_pic_order_cnt_lsb_minus4 = p_Vid->active_sps->log2_max_pic_order_cnt_lsb_minus4;
}
else if (pp->pic_order_cnt_type == 1)
{
pp->delta_pic_order_always_zero_flag = p_Vid->active_sps->delta_pic_order_always_zero_flag;
}
pp->direct_8x8_inference_flag = p_Vid->active_sps->direct_8x8_inference_flag;
pp->entropy_coding_mode_flag = p_Vid->active_pps->entropy_coding_mode_flag;
pp->pic_order_present_flag = p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag;
pp->num_slice_groups_minus1 = p_Vid->active_pps->num_slice_groups_minus1;
pp->slice_group_map_type = p_Vid->active_pps->slice_group_map_type;
pp->deblocking_filter_control_present_flag = p_Vid->active_pps->deblocking_filter_control_present_flag;
pp->redundant_pic_cnt_present_flag = p_Vid->active_pps->redundant_pic_cnt_present_flag;
pp->Reserved8BitsB = 0;
pp->slice_group_change_rate_minus1 = 0; //!< XXX not implemented by FFmpeg
//pp->SliceGroupMap[810]; //!< XXX not implemented by FFmpeg
//!< Following are H.264 MVC Specific parameters
if (p_Vid->active_subsps)
{
pp->num_views_minus1 = p_Vid->active_subsps->num_views_minus1;
num_views = 1 + pp->num_views_minus1;
ASSERT(num_views <= 16);
for (i = 0; i < num_views; i++)
{
pp->view_id[i] = p_Vid->active_subsps->view_id[i];
pp->num_anchor_refs_l0[i] = p_Vid->active_subsps->num_anchor_refs_l0[i];
for (j = 0; j < pp->num_anchor_refs_l0[i]; j++)
{
pp->anchor_ref_l0[i][j] = p_Vid->active_subsps->anchor_ref_l0[i][j];
}
pp->num_anchor_refs_l1[i] = p_Vid->active_subsps->num_anchor_refs_l1[i];
for (j = 0; j < pp->num_anchor_refs_l1[i]; j++)
{
pp->anchor_ref_l1[i][j] = p_Vid->active_subsps->anchor_ref_l1[i][j];
}
pp->num_non_anchor_refs_l0[i] = p_Vid->active_subsps->num_non_anchor_refs_l0[i];
for (j = 0; j < pp->num_non_anchor_refs_l0[i]; j++)
{
pp->non_anchor_ref_l0[i][j] = p_Vid->active_subsps->non_anchor_ref_l0[i][j];
}
pp->num_non_anchor_refs_l1[i] = p_Vid->active_subsps->num_non_anchor_refs_l1[i];
for (j = 0; j < pp->num_non_anchor_refs_l1[i]; j++)
{
pp->non_anchor_ref_l1[i][j] = p_Vid->active_subsps->non_anchor_ref_l1[i][j];
}
}
for (i = num_views; i < 16; i++)
{
pp->view_id[i] = 0xffff;
}
}
pp->curr_view_id = dec_picture->view_id;
pp->anchor_pic_flag = dec_picture->anchor_pic_flag;
pp->inter_view_flag = dec_picture->inter_view_flag;
for (i = 0; i < 16; i++)
{
pp->ViewIDList[i] = p_Vid->p_Dec->dpb_info[i].view_id;
}
//!< add in Rock-chip RKVDEC IP
for (i = 0; i < 16; i++)
{
if (p_Vid->p_Dec->dpb_info[i].colmv_is_used)
{
pp->RefPicColmvUsedFlags |= 1 << i;
}
if (p_Vid->p_Dec->dpb_info[i].field_flag)
{
pp->RefPicFiledFlags |= 1 << i;
}
pp->RefPicLayerIdList[i] = p_Vid->p_Dec->dpb_info[i].voidx;
}
if (p_Vid->active_pps->pic_scaling_matrix_present_flag
|| p_Vid->active_sps->seq_scaling_matrix_present_flag)
{
pp->scaleing_list_enable_flag = 1;
}
else
{
pp->scaleing_list_enable_flag = 0;
}
}
/*!
***********************************************************************
* \brief
* fill slice short struct
***********************************************************************
*/
//extern "C"
MPP_RET fill_slice(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx)
{
RK_U32 list = 0, i = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
DXVA_Slice_H264_Long *p_long = NULL;
RK_S32 dpb_idx = 0, dpb_valid = 0, bottom_flag = 0;
FUN_CHECK(ret = fill_stream_data(dxva_ctx, &currSlice->p_Cur->nalu));
p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count];
//!< fill slice long contents
p_long->first_mb_in_slice = currSlice->start_mb_nr;
p_long->NumMbsForSlice = 0; //!< XXX it is set once we have all slices
p_long->slice_type = currSlice->slice_type;
p_long->num_ref_idx_l0_active_minus1 = currSlice->active_pps->num_ref_idx_l0_default_active_minus1;
p_long->num_ref_idx_l1_active_minus1 = currSlice->active_pps->num_ref_idx_l1_default_active_minus1;
p_long->redundant_pic_cnt = currSlice->redundant_pic_cnt;
p_long->direct_spatial_mv_pred_flag = currSlice->direct_spatial_mv_pred_flag;
p_long->slice_id = dxva_ctx->slice_count;
for (i = 0; i < FF_ARRAY_ELEMS(p_long->RefPicList[0]); i++)
{
dpb_idx = currSlice->p_Dec->refpic_info_p[i].dpb_idx;
dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].ADDR_Y ? 1 : 0);
if (dpb_valid)
{
bottom_flag = currSlice->p_Dec->refpic_info_p[i].bottom_flag;
fill_picture_entry(&p_long->RefPicList[0][i], dpb_idx, bottom_flag);
}
else
{
p_long->RefPicList[0][i].bPicEntry = 0xff;
}
}
for (list = 0; list < 2; list++)
{
for (i = 0; i < FF_ARRAY_ELEMS(p_long->RefPicList[list + 1]); i++)
{
dpb_idx = currSlice->p_Dec->refpic_info[list][i].dpb_idx;
dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].ADDR_Y ? 1 : 0);
if (dpb_valid)
{
bottom_flag = currSlice->p_Dec->refpic_info[list][i].bottom_flag;
fill_picture_entry(&p_long->RefPicList[list + 1][i], dpb_idx, bottom_flag);
}
else
{
p_long->RefPicList[list + 1][i].bPicEntry = 0xff;
}
}
}
dxva_ctx->slice_count++;
return ret = MPP_OK;
__FAILED:
return ret;
}
/*!
***********************************************************************
* \brief
* check parser is end and then configure register
***********************************************************************
*/
//extern "C"
void commit_buffer(H264dDxvaCtx_t *dxva_ctx)
{
H264dSyntax_t *p_syn = &dxva_ctx->syn;
DXVA2_DecodeBufferDesc *p_dec = NULL;
p_syn->num = 0;
//!< commit picture paramters
p_dec = &p_syn->buf[p_syn->num++];
memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
p_dec->CompressedBufferType = DXVA2_PictureParametersBufferType;
p_dec->pvPVPState = (void *)&dxva_ctx->pp;
p_dec->DataSize = sizeof(DXVA_PicParams_H264_MVC);
p_dec->NumMBsInBuffer = 0;
//!< commit scanlist Qmatrix
p_dec = &p_syn->buf[p_syn->num++];
memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
p_dec->CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType;
p_dec->pvPVPState = (void *)&dxva_ctx->qm;
p_dec->DataSize = sizeof(DXVA_Qmatrix_H264);
p_dec->NumMBsInBuffer = 0;
//!< commit bitstream
p_dec = &p_syn->buf[p_syn->num++];
memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
p_dec->CompressedBufferType = DXVA2_BitStreamDateBufferType;
p_dec->DataSize = ALIGN(dxva_ctx->strm_offset, 16);
memset(dxva_ctx->bitstream + dxva_ctx->strm_offset, 0, p_dec->DataSize - dxva_ctx->strm_offset);
p_dec->pvPVPState = (void *)dxva_ctx->bitstream;
//!< commit slice control, DXVA_Slice_H264_Long
p_dec = &p_syn->buf[p_syn->num++];
memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
p_dec->CompressedBufferType = DXVA2_SliceControlBufferType;
p_dec->NumMBsInBuffer = (dxva_ctx->pp.wFrameHeightInMbsMinus1 + 1)
* (dxva_ctx->pp.wFrameWidthInMbsMinus1 + 1);
p_dec->pvPVPState = dxva_ctx->slice_long;
p_dec->DataSize = dxva_ctx->slice_count * sizeof(DXVA_Slice_H264_Long);
//!< reset dxva parameters
dxva_ctx->slice_count = 0;
dxva_ctx->strm_offset = 0;
}

View File

@@ -0,0 +1,43 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_FILL_H_
#define _H264D_FILL_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "dxva_syntax.h"
#include "h264d_syntax.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp);
void fill_qmatrix(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm);
void commit_buffer(H264dDxvaCtx_t *dxva);
MPP_RET fill_slice(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _RKV_H264_DECODER_FILL_H_ */

View File

@@ -22,6 +22,8 @@
#include "rk_type.h" #include "rk_type.h"
#include "rk_mpi.h" #include "rk_mpi.h"
#include "mpp_dec.h"
#include "h264d_api.h"
#include "h264d_log.h" #include "h264d_log.h"
#include "h264d_bitread.h" #include "h264d_bitread.h"
#include "h264d_syntax.h" #include "h264d_syntax.h"
@@ -46,6 +48,13 @@
#define NALU_BUF_MAX_SIZE 64//512*1024 #define NALU_BUF_MAX_SIZE 64//512*1024
#define NALU_BUF_ADD_SIZE 32//512 #define NALU_BUF_ADD_SIZE 32//512
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
//!< AVC Profile IDC definitions //!< AVC Profile IDC definitions
typedef enum { typedef enum {
@@ -664,7 +673,7 @@ typedef struct h264_sei_t {
RK_S32 type; RK_S32 type;
RK_S32 payload_size; RK_S32 payload_size;
struct { struct {
RK_S32 recovery_frame_cnt; RK_U32 recovery_frame_cnt;
RK_S32 exact_match_flag; RK_S32 exact_match_flag;
RK_S32 broken_link_flag; RK_S32 broken_link_flag;
RK_S32 changing_slice_group_idc; RK_S32 changing_slice_group_idc;
@@ -796,8 +805,7 @@ typedef struct h264d_dxva_ctx_t {
struct _DXVA_PicParams_H264_MVC pp; struct _DXVA_PicParams_H264_MVC pp;
struct _DXVA_Qmatrix_H264 qm; struct _DXVA_Qmatrix_H264 qm;
RK_U32 max_slice_size; RK_U32 max_slice_size;
RK_U32 slice_count; RK_U32 slice_count;
struct _DXVA_Slice_H264_Short *slice_short; //!< MAX_SLICES
struct _DXVA_Slice_H264_Long *slice_long; //!< MAX_SLICES struct _DXVA_Slice_H264_Long *slice_long; //!< MAX_SLICES
RK_U8 *bitstream; RK_U8 *bitstream;
RK_U32 max_strm_size; RK_U32 max_strm_size;
@@ -806,7 +814,6 @@ typedef struct h264d_dxva_ctx_t {
struct h264_dec_ctx_t *p_Dec; struct h264_dec_ctx_t *p_Dec;
} H264dDxvaCtx_t; } H264dDxvaCtx_t;
//!< input parameter //!< input parameter
typedef struct h264d_input_ctx_t { typedef struct h264d_input_ctx_t {
RK_U8 is_eos; RK_U8 is_eos;
@@ -815,6 +822,14 @@ typedef struct h264d_input_ctx_t {
struct h264d_video_ctx_t *p_Vid; //!< parameters for video decoder struct h264d_video_ctx_t *p_Vid; //!< parameters for video decoder
enum mpp_decmtd_type dec_mtd; enum mpp_decmtd_type dec_mtd;
MppParserInitCfg init; MppParserInitCfg init;
//!< input data
RK_U8 *in_buf;
size_t *in_size;
RK_S64 *in_timestamp;
//!< output data
RK_U8 *out_buf;
RK_U32 *out_length;
} H264dInputCtx_t; } H264dInputCtx_t;
//!< current stream //!< current stream
@@ -920,6 +935,50 @@ typedef struct h264d_mem_t {
struct h264d_dxva_ctx_t dxva_ctx[MAX_TASK_SIZE]; struct h264d_dxva_ctx_t dxva_ctx[MAX_TASK_SIZE];
} H264_DecMem_t; } H264_DecMem_t;
//!< nalu state used in read nalu
typedef enum nalu_state_tpye{
NALU_NULL = 0,
//StreamError,
HaveNoStream,
NaluNotSupport,
//ReadNaluError,
//StartofNalu,
EndofStream,
//ReallocBufError,
MidOfNalu,
EndOfNalu,
StartOfPicture,
StartOfSlice,
SkipNALU,
NALU_SPS,
NALU_SubSPS,
NALU_PPS,
NALU_SEI,
NALU_MAX,
} NALU_STATUS;
//!< slice state used in parse loop
typedef enum slice_state_type {
SliceSTATE_NULL = 0,
SliceSTATE_IDLE,
SliceSTATE_ResetSlice,
SliceSTATE_ReadNalu,
SliceSTATE_ParseNalu,
SliceSTATE_InitPicture,
////SliceSTATE_InitSlice,
SliceSTATE_GetSliceData,
//SliceSTATE_RegisterOneSlice,
SliceSTATE_RegisterOneFrame,
SliceSTATE_Error,
SliceSTATE_MAX,
} SLICE_STATUS;
//!< decoder video parameter //!< decoder video parameter
typedef struct h264_dec_ctx_t { typedef struct h264_dec_ctx_t {
struct h264d_mem_t *mem; struct h264d_mem_t *mem;
@@ -933,10 +992,11 @@ typedef struct h264_dec_ctx_t {
struct h264d_cur_ctx_t *p_Cur; //!< current parameters, use in read nalu struct h264d_cur_ctx_t *p_Cur; //!< current parameters, use in read nalu
struct h264d_video_ctx_t *p_Vid; //!< parameters for video decoder struct h264d_video_ctx_t *p_Vid; //!< parameters for video decoder
RK_U32 spt_decode_mtds; //!< support decoder methods RK_U32 spt_decode_mtds; //!< support decoder methods
RK_S32 nalu_ret; //!< current nalu state NALU_STATUS nalu_ret; //!< current nalu state
RK_S32 next_state; //!< RKV_SLICE_STATUS SLICE_STATUS next_state; //!< RKV_SLICE_STATUS
RK_U8 first_frame_flag; RK_U8 first_frame_flag;
RK_U8 parser_end_flag; RK_U8 parser_end_flag;
RK_U8 dxva_idx;
struct h264d_logctx_t logctx; //!< debug log file struct h264d_logctx_t logctx; //!< debug log file
struct log_ctx_t logctxbuf[LOG_MAX]; struct log_ctx_t logctxbuf[LOG_MAX];
} H264_DecCtx_t; } H264_DecCtx_t;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_INIT_H_
#define _H264D_INIT_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
MPP_RET init_picture (H264_SLICE_t *currSlice);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _RKV_H264_DECODER_INIT_H_ */

View File

@@ -26,7 +26,8 @@
#define LOG_BUF_SIZE 512 #define LOG_BUF_SIZE 512
#define GetBitVal(val, pos) ( ( (val)>>(pos) ) & 0x1 & (val) )
RK_U32 g_nalu_cnt = 0;
const LogEnvStr_t logenv_name = { const LogEnvStr_t logenv_name = {
"h264d_log_help", "h264d_log_help",
@@ -67,8 +68,14 @@ const char *logctrl_name[LOG_MAX] = {
"WRITE_REG ", "WRITE_REG ",
}; };
/*!
***********************************************************************
* \brief
* get log env
***********************************************************************
*/
static MPP_RET get_logenv(LogEnv_t *env) MPP_RET get_logenv(LogEnv_t *env)
{ {
//!< read env //!< read env
mpp_env_get_u32(logenv_name.help, &env->help, 0); mpp_env_get_u32(logenv_name.help, &env->help, 0);
@@ -83,8 +90,13 @@ static MPP_RET get_logenv(LogEnv_t *env)
return MPP_OK; return MPP_OK;
} }
/*!
static void print_env_help(LogEnv_t *env) ***********************************************************************
* \brief
* print env help
***********************************************************************
*/
void print_env_help(LogEnv_t *env)
{ {
RK_U8 i = 0; RK_U8 i = 0;
(void)env; (void)env;
@@ -107,8 +119,13 @@ static void print_env_help(LogEnv_t *env)
} }
fprintf(stdout, "------------------------------------------------- \n"); fprintf(stdout, "------------------------------------------------- \n");
} }
/*!
static void show_env_flags(LogEnv_t *env) ***********************************************************************
* \brief
* show env flags
***********************************************************************
*/
void show_env_flags(LogEnv_t *env)
{ {
RK_U8 i = 0; RK_U8 i = 0;
fprintf(stdout, "------------- h264d debug setting ------------- \n"); fprintf(stdout, "------------- h264d debug setting ------------- \n");
@@ -122,164 +139,31 @@ static void show_env_flags(LogEnv_t *env)
} }
fprintf(stdout, "------------------------------------------------- \n"); fprintf(stdout, "------------------------------------------------- \n");
} }
/*!
static MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag) ***********************************************************************
* \brief
* explain log ctrl flag
***********************************************************************
*/
MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag)
{ {
pflag->print_en = GetBitVal(ctrl_val, LOG_PRINT ); pflag->print_en = GetBitVal(ctrl_val, LOG_PRINT );
pflag->write_en = GetBitVal(ctrl_val, LOG_WRITE ); pflag->write_en = GetBitVal(ctrl_val, LOG_WRITE );
pflag->debug_en = GetBitVal(ctrl_val, LOG_DEBUG_EN ) pflag->debug_en = GetBitVal(ctrl_val, LOG_DEBUG_EN )
&& GetBitVal(ctrl_val, LOG_READ_NALU ) || GetBitVal(ctrl_val, LOG_READ_NALU )
&& GetBitVal(ctrl_val, LOG_READ_SPS ) || GetBitVal(ctrl_val, LOG_READ_SPS )
&& GetBitVal(ctrl_val, LOG_READ_SUBSPS ) || GetBitVal(ctrl_val, LOG_READ_SUBSPS )
&& GetBitVal(ctrl_val, LOG_READ_PPS ) || GetBitVal(ctrl_val, LOG_READ_PPS )
&& GetBitVal(ctrl_val, LOG_READ_SLICE ) || GetBitVal(ctrl_val, LOG_READ_SLICE )
&& GetBitVal(ctrl_val, LOG_WRITE_SPSPPS ) || GetBitVal(ctrl_val, LOG_WRITE_SPSPPS )
&& GetBitVal(ctrl_val, LOG_WRITE_RPS ) || GetBitVal(ctrl_val, LOG_WRITE_RPS )
&& GetBitVal(ctrl_val, LOG_WRITE_SCANLIST) || GetBitVal(ctrl_val, LOG_WRITE_SCANLIST)
&& GetBitVal(ctrl_val, LOG_WRITE_STEAM ) || GetBitVal(ctrl_val, LOG_WRITE_STEAM )
&& GetBitVal(ctrl_val, LOG_WRITE_REG ); || GetBitVal(ctrl_val, LOG_WRITE_REG );
return MPP_OK; return MPP_OK;
} }
static void close_log_files(LogEnv_t *env)
{
FCLOSE(env->fp_driver);
FCLOSE(env->fp_syn_parse);
FCLOSE(env->fp_syn_hal);
FCLOSE(env->fp_run_parse);
FCLOSE(env->fp_run_hal);
}
static MPP_RET open_log_files(LogEnv_t *env, LogFlag_t *pflag)
{
char fname[128] = { 0 };
INP_CHECK(!pflag->write_en);
//!< runlog file
if (GetBitVal(env->ctrl, LOG_DEBUG_EN)) {
sprintf(fname, "%s/h264d_parse_runlog.dat", env->outpath);
FLE_CHECK(env->fp_run_parse = fopen(fname, "wb"));
sprintf(fname, "%s/h264d_hal_runlog.dat", env->outpath);
FLE_CHECK(env->fp_run_hal = fopen(fname, "wb"));
}
//!< fpga drive file
if (GetBitVal(env->ctrl, LOG_FPGA)) {
sprintf(fname, "%s/h264d_driver_data.dat", env->outpath);
FLE_CHECK(env->fp_driver = fopen(fname, "wb"));
}
//!< read syntax
if ( GetBitVal(env->ctrl, LOG_READ_NALU )
|| GetBitVal(env->ctrl, LOG_READ_SPS )
|| GetBitVal(env->ctrl, LOG_READ_SUBSPS)
|| GetBitVal(env->ctrl, LOG_READ_PPS )
|| GetBitVal(env->ctrl, LOG_READ_SLICE ) ) {
sprintf(fname, "%s/h264d_read_syntax.dat", env->outpath);
FLE_CHECK(env->fp_syn_parse = fopen(fname, "wb"));
}
//!< write syntax
if ( GetBitVal(env->ctrl, LOG_WRITE_SPSPPS )
|| GetBitVal(env->ctrl, LOG_WRITE_RPS )
|| GetBitVal(env->ctrl, LOG_WRITE_SCANLIST)
|| GetBitVal(env->ctrl, LOG_WRITE_STEAM )
|| GetBitVal(env->ctrl, LOG_WRITE_REG ) ) {
sprintf(fname, "%s/h264d_write_syntax.dat", env->outpath);
FLE_CHECK(env->fp_syn_hal = fopen(fname, "wb"));
}
__RETURN:
return MPP_OK;
__FAILED:
return MPP_NOK;
}
/*!
***********************************************************************
* \brief
* log deinit
***********************************************************************
*/
MPP_RET h264d_log_deinit(H264dLogCtx_t *logctx)
{
close_log_files(&logctx->env);
return MPP_OK;
}
/*!
***********************************************************************
* \brief
* log init
***********************************************************************
*/
MPP_RET h264d_log_init(H264dLogCtx_t *logctx, LogCtx_t *logbuf)
{
RK_U8 i = 0;
MPP_RET ret = MPP_NOK;
LogCtx_t *pcur = NULL;
FUN_CHECK(ret = get_logenv(&logctx->env));
if (logctx->env.help) {
print_env_help(&logctx->env);
}
if (logctx->env.show) {
show_env_flags(&logctx->env);
}
FUN_CHECK(ret = explain_ctrl_flag(logctx->env.ctrl, &logctx->log_flag));
if ( !logctx->log_flag.debug_en
&& !logctx->log_flag.print_en && !logctx->log_flag.write_en ) {
logctx->log_flag.debug_en = 0;
goto __RETURN;
}
logctx->log_flag.level = (1 << logctx->env.level) - 1;
//!< open file
FUN_CHECK(ret = open_log_files(&logctx->env, &logctx->log_flag));
//!< set logctx
while (i < LOG_MAX) {
if (GetBitVal(logctx->env.ctrl, i)) {
pcur = logctx->parr[i] = &logbuf[i];
pcur->tag = logctrl_name[i];
pcur->flag = &logctx->log_flag;
switch (i) {
case LOG_FPGA:
pcur->fp = logctx->env.fp_driver;
break;
case RUN_PARSE:
pcur->fp = logctx->env.fp_run_parse;
break;
case RUN_HAL:
pcur->fp = logctx->env.fp_run_hal;
break;
case LOG_READ_NALU:
case LOG_READ_SPS:
case LOG_READ_SUBSPS:
case LOG_READ_PPS:
case LOG_READ_SLICE:
pcur->fp = logctx->env.fp_syn_parse;
break;
case LOG_WRITE_SPSPPS:
case LOG_WRITE_RPS:
case LOG_WRITE_SCANLIST:
case LOG_WRITE_STEAM:
case LOG_WRITE_REG:
pcur->fp = logctx->env.fp_syn_hal;
default:
break;
}
}
i++;
}
__RETURN:
return ret = MPP_OK;
__FAILED:
logctx->log_flag.debug_en = 0;
h264d_log_deinit(logctx);
return ret;
}
/*! /*!
*********************************************************************** ***********************************************************************
* \brief * \brief
@@ -305,7 +189,8 @@ void writelog(LogCtx_t *ctx, char *filename, RK_U32 line, char *loglevel, const
printf("[ TAG = %s ], file: %s, line: %d, [ %s ], %s \n", ctx->tag, pfn, line, loglevel, argbuf); printf("[ TAG = %s ], file: %s, line: %d, [ %s ], %s \n", ctx->tag, pfn, line, loglevel, argbuf);
} }
if (ctx->fp && ctx->flag->write_en) { if (ctx->fp && ctx->flag->write_en) {
fprintf(ctx->fp, "[ TAG = %s ], file: %s, line: %d, [ %s ], %s \n", ctx->tag, pfn, line, loglevel, argbuf); fprintf(ctx->fp, "%s \n", argbuf);
//fprintf(ctx->fp, "[ TAG = %s ], file: %s, line: %d, [ %s ], %s \n", ctx->tag, pfn, line, loglevel, argbuf);
fflush(ctx->fp); fflush(ctx->fp);
} }
va_end(argptr); va_end(argptr);

View File

@@ -16,18 +16,388 @@
*/ */
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "mpp_mem.h"
#include "mpp_packet.h"
#include "mpp_packet_impl.h"
#include "hal_task.h"
#include "h264d_parse.h" #include "h264d_parse.h"
#include "h264d_slice.h"
#include "h264d_sps.h"
#include "h264d_pps.h"
#include "h264d_sei.h"
#include "h264d_init.h"
#include "h264d_fill.h"
#define MODULE_TAG "h264d_parse"
static void reset_slice(H264dVideoCtx_t *p_Vid)
{
RK_U32 i = 0, j = 0;
H264_SLICE_t *currSlice = &p_Vid->p_Cur->slice;
FunctionIn(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
memset(currSlice, 0, sizeof(H264_SLICE_t));
//-- re-init parameters
currSlice->view_id = -1;
currSlice->p_Vid = p_Vid;
currSlice->p_Dec = p_Vid->p_Dec;
currSlice->p_Cur = p_Vid->p_Cur;
currSlice->p_Inp = p_Vid->p_Inp;
currSlice->logctx = &p_Vid->p_Dec->logctx;
//--- reset listP listB
for (i = 0; i < 2; i++)
{
currSlice->listP[i] = p_Vid->p_Cur->listP[i];
currSlice->listB[i] = p_Vid->p_Cur->listB[i];
for (j = 0; j < MAX_LIST_SIZE; j++)
{
currSlice->listP[i][j] = NULL;
currSlice->listB[i][j] = NULL;
}
currSlice->listXsizeP[i] = 0;
currSlice->listXsizeB[i] = 0;
}
FunctionOut(p_Vid->p_Dec->logctx.parr[RUN_PARSE]);
}
static MPP_RET realloc_curstrearm_buffer(H264dCurStream_t *p_strm)
{
MPP_RET ret = MPP_ERR_UNKNOW;
p_strm->buf = mpp_realloc(p_strm->buf, RK_U8, p_strm->max_size + NALU_BUF_ADD_SIZE);
MEM_CHECK(ret, p_strm->buf);
p_strm->max_size += NALU_BUF_ADD_SIZE;
return ret = MPP_OK;
__FAILED:
return ret;
}
static void reset_nalu(H264_Nalu_t*p_nal, H264dCurStream_t *p_strm)
{
if (p_strm->endcode_found)
{
p_strm->startcode_found = p_strm->endcode_found;
memset(p_nal, 0, sizeof(H264_Nalu_t));
p_strm->endcode_found = 0;
}
p_nal->sodb_buf = p_strm->buf;
}
static void find_prefix_code(RK_U8 *p_data, H264dCurStream_t *p_strm)
{
p_strm->prefixdata[0] = p_strm->prefixdata[1];
p_strm->prefixdata[1] = p_strm->prefixdata[2];
p_strm->prefixdata[2] = *p_data;
if (p_strm->prefixdata[0] == 0x00
&& p_strm->prefixdata[1] == 0x00
&& p_strm->prefixdata[2] == 0x01)
{
if (p_strm->startcode_found)
{
p_strm->endcode_found = 1;
}
else
{
p_strm->startcode_found = 1;
}
}
}
/*! static MPP_RET read_nalu(H264_SLICE_t *currSlice)
*********************************************************************** {
* \brief MPP_RET ret = MPP_ERR_UNKNOW;
* get current data value, used in read sei syntax RK_U8 *p_curdata = NULL;
*********************************************************************** H264dLogCtx_t *logctx = currSlice->logctx;
*/ H264_DecCtx_t *p_Dec = currSlice->p_Dec;
H264dCurCtx_t *p_Cur = currSlice->p_Cur;
H264dInputCtx_t *p_Inp = currSlice->p_Inp;
FunctionIn(logctx->parr[RUN_PARSE]);
reset_nalu(&p_Cur->nalu, &p_Cur->strm);
while ((*p_Inp->in_size) > 0)
{
p_curdata = &p_Inp->in_buf[p_Cur->strm.offset++];
(*p_Inp->in_size) -= 1;
if (p_Cur->strm.startcode_found)
{
if (p_Cur->nalu.sodb_len >= p_Cur->strm.max_size)
{
FUN_CHECK(ret = realloc_curstrearm_buffer(&p_Cur->strm));
p_Cur->nalu.sodb_buf = p_Cur->strm.buf;
}
p_Cur->nalu.sodb_buf[p_Cur->nalu.sodb_len++] = *p_curdata;
}
find_prefix_code(p_curdata, &p_Cur->strm);
if (p_Cur->strm.endcode_found)
{
p_Cur->nalu.sodb_len -= START_PREFIX_3BYTE;
while (p_Cur->nalu.sodb_buf[p_Cur->nalu.sodb_len - 1] == 0x00) //!< find non-zeros byte
{
p_Cur->nalu.sodb_len--;
}
p_Dec->nalu_ret = EndOfNalu;
break;
}
}
if (!(*p_Inp->in_size)) //!< check input
{
p_Cur->strm.offset = 0;
p_Cur->strm.endcode_found = (p_Inp->is_eos && p_Cur->nalu.sodb_len) ? 1 : p_Cur->strm.endcode_found;
p_Dec->nalu_ret = p_Inp->is_eos ? (p_Cur->nalu.sodb_len ? EndOfNalu : EndofStream) : HaveNoStream;
}
FunctionIn(logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET parser_nalu_header(H264_SLICE_t *currSlice)
{
MPP_RET ret = MPP_ERR_UNKNOW;
H264dLogCtx_t *logctx = currSlice->logctx;
H264dCurCtx_t *p_Cur = currSlice->p_Cur;
BitReadCtx_t *p_bitctx = &p_Cur->bitctx;
H264_Nalu_t *cur_nal = &p_Cur->nalu;
FunctionIn(logctx->parr[RUN_PARSE]);
set_bitread_ctx(p_bitctx, cur_nal->sodb_buf, cur_nal->sodb_len);
set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_NALU]);
WRITE_LOG(p_bitctx, "================== NAL begin ===================");
READ_BITS(ret, p_bitctx, 1, &cur_nal->forbidden_bit, "forbidden_bit");
ASSERT(cur_nal->forbidden_bit == 0);
READ_BITS(ret, p_bitctx, 2, (RK_S32 *)&cur_nal->nal_reference_idc, "nal_ref_idc");
READ_BITS(ret, p_bitctx, 5, (RK_S32 *)&cur_nal->nal_unit_type, "nal_unit_type");
if (g_nalu_cnt == 321)
{
g_nalu_cnt = g_nalu_cnt;
}
cur_nal->ualu_header_bytes = 1;
currSlice->svc_extension_flag = -1; //!< initialize to -1
if ((cur_nal->nal_unit_type == NALU_TYPE_PREFIX) || (cur_nal->nal_unit_type == NALU_TYPE_SLC_EXT))
{
READ_ONEBIT(ret, p_bitctx, &currSlice->svc_extension_flag, "svc_extension_flag");
if (currSlice->svc_extension_flag)
{
FPRINT(logctx->parr[LOG_READ_NALU]->fp, "g_nalu_cnt=%d, nalu_type=%d, len=%d \n", g_nalu_cnt++, cur_nal->nal_unit_type, cur_nal->sodb_len);
currSlice->mvcExt.valid = 0;
LogInfo(logctx->parr[RUN_PARSE], "svc_extension is not supported.");
goto __FAILED;
}
else //!< MVC
{
currSlice->mvcExt.valid = 1;
READ_ONEBIT(ret, p_bitctx, &currSlice->mvcExt.non_idr_flag, "nalu_type");
READ_BITS(ret, p_bitctx, 6, &currSlice->mvcExt.priority_id, "priority_id");
READ_BITS(ret, p_bitctx, 10, &currSlice->mvcExt.view_id, "view_id");
READ_BITS(ret, p_bitctx, 3, &currSlice->mvcExt.temporal_id, "temporal_id");
READ_ONEBIT(ret, p_bitctx, &currSlice->mvcExt.anchor_pic_flag, "anchor_pic_flag");
READ_ONEBIT(ret, p_bitctx, &currSlice->mvcExt.inter_view_flag, "inter_view_flag");
READ_ONEBIT(ret, p_bitctx, &currSlice->mvcExt.reserved_one_bit, "reserved_one_bit");
ASSERT(currSlice->mvcExt.reserved_one_bit == 1);
currSlice->mvcExt.iPrefixNALU = (cur_nal->nal_unit_type == NALU_TYPE_PREFIX) ? 1 : 0;
if (cur_nal->nal_unit_type == NALU_TYPE_SLC_EXT) //!< combine NALU_TYPE_SLC_EXT into NALU_TYPE_SLICE
{
cur_nal->nal_unit_type = NALU_TYPE_SLICE;
}
FPRINT(logctx->parr[LOG_READ_NALU]->fp, "g_nalu_cnt=%d, nalu_type=%d, len=%d \n", g_nalu_cnt++, cur_nal->nal_unit_type, cur_nal->sodb_len);
}
cur_nal->ualu_header_bytes += 3;
}
else
{
FPRINT(logctx->parr[LOG_READ_NALU]->fp, "g_nalu_cnt=%d, nalu_type=%d, len=%d \n", g_nalu_cnt++, cur_nal->nal_unit_type, cur_nal->sodb_len);
}
set_bitread_ctx(p_bitctx, (cur_nal->sodb_buf + cur_nal->ualu_header_bytes), (cur_nal->sodb_len - cur_nal->ualu_header_bytes)); // reset
FunctionOut(logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET parser_nalu(H264_SLICE_t *currSlice)
{
MPP_RET ret = MPP_ERR_UNKNOW;
LogCtx_t *runlog = currSlice->logctx->parr[RUN_PARSE];
FunctionIn(runlog);
FUN_CHECK(ret = parser_nalu_header(currSlice));
//!< nalu_parse
switch (currSlice->p_Cur->nalu.nal_unit_type)
{
case NALU_TYPE_SLICE:
case NALU_TYPE_IDR:
FUN_CHECK(ret = process_slice(currSlice));
if (currSlice->is_new_picture_flag)
{
currSlice->p_Dec->nalu_ret = StartOfPicture;
}
else
{
currSlice->p_Dec->nalu_ret = StartOfSlice;
}
LogTrace(runlog, "nalu_type=SLICE.");
break;
case NALU_TYPE_SPS:
FUN_CHECK(ret = process_sps(currSlice));
currSlice->p_Dec->nalu_ret = NALU_SPS;
LogTrace(runlog, "nalu_type=SPS");
break;
case NALU_TYPE_PPS:
FUN_CHECK(ret = process_pps(currSlice));
currSlice->p_Dec->nalu_ret = NALU_PPS;
LogTrace(runlog, "nalu_type=PPS");
break;
case NALU_TYPE_SUB_SPS:
FUN_CHECK(ret = process_subsps(currSlice));
currSlice->p_Dec->nalu_ret = NALU_SubSPS;
LogTrace(runlog, "nalu_type=SUB_SPS");
break;
case NALU_TYPE_SEI:
FUN_CHECK(ret = process_sei(currSlice));
LogTrace(runlog, "nalu_type=SEI");
currSlice->p_Dec->nalu_ret = NALU_SEI;
break;
case NALU_TYPE_SLC_EXT:
LogTrace(runlog, "Found NALU_TYPE_SLC_EXT.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_PREFIX:
LogTrace(runlog, "Found NALU_TYPE_PREFIX.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_AUD:
LogTrace(runlog, "Found NALU_TYPE_AUD.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_EOSEQ:
LogTrace(runlog, "Found NALU_TYPE_EOSEQ.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_EOSTREAM:
LogTrace(runlog, "Found NALU_TYPE_EOSTREAM.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_FILL:
LogTrace(runlog, "Found NALU_TYPE_FILL.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_VDRD:
LogTrace(runlog, "Found NALU_TYPE_VDRD.");
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
case NALU_TYPE_DPA:
case NALU_TYPE_DPB:
case NALU_TYPE_DPC:
LogError(runlog, "Found NALU_TYPE_DPA DPB DPC, and not supported.");
currSlice->p_Dec->nalu_ret = NaluNotSupport;
break;
default:
currSlice->p_Dec->nalu_ret = SkipNALU;
break;
}
FunctionIn(runlog);
return ret = MPP_OK;
__FAILED:
return ret;
}
/*!
***********************************************************************
* \brief
* loop function for parser
***********************************************************************
*/
MPP_RET parse_loop(H264_DecCtx_t *p_Dec)
{
MPP_RET ret = MPP_ERR_UNKNOW;
RK_U32 while_loop_flag = 1;
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
//!< ==== parse loop ====
while (while_loop_flag)
{
switch (p_Dec->next_state)
{
case SliceSTATE_ResetSlice:
reset_slice(p_Dec->p_Vid);
p_Dec->next_state = SliceSTATE_ReadNalu;
break;
case SliceSTATE_ReadNalu:
(ret = read_nalu(&p_Dec->p_Cur->slice));
if (p_Dec->nalu_ret == EndOfNalu)
{
p_Dec->next_state = SliceSTATE_ParseNalu;
}
else if (p_Dec->nalu_ret == EndofStream)
{
p_Dec->next_state = SliceSTATE_RegisterOneFrame;
}
else if (p_Dec->nalu_ret == HaveNoStream)
{
while_loop_flag = 0;
}
break;
case SliceSTATE_ParseNalu:
(ret = parser_nalu(&p_Dec->p_Cur->slice));
if (p_Dec->nalu_ret == StartOfSlice)
{
p_Dec->next_state = SliceSTATE_GetSliceData;
}
else if (p_Dec->nalu_ret == StartOfPicture)
{
if (p_Dec->first_frame_flag)
{
p_Dec->next_state = SliceSTATE_InitPicture;
p_Dec->first_frame_flag = 0;
}
else
{
p_Dec->next_state = SliceSTATE_RegisterOneFrame;
}
}
else
{
p_Dec->next_state = SliceSTATE_ReadNalu;
}
break;
case SliceSTATE_InitPicture:
(ret = init_picture(&p_Dec->p_Cur->slice));
p_Dec->next_state = SliceSTATE_GetSliceData;
break;
case SliceSTATE_GetSliceData:
(ret = fill_slice(&p_Dec->p_Cur->slice, p_Dec->dxva_ctx));
p_Dec->p_Vid->iNumOfSlicesDecoded++;
p_Dec->next_state = SliceSTATE_ResetSlice;
break;
case SliceSTATE_RegisterOneFrame:
commit_buffer(p_Dec->dxva_ctx);
while_loop_flag = 0;
p_Dec->parser_end_flag = 1;
p_Dec->next_state = SliceSTATE_InitPicture;
break;
default:
ret = MPP_NOK;
goto __FAILED;
}
}
FunctionIn(p_Dec->logctx.parr[RUN_PARSE]);
//__RETURN:
return ret = MPP_OK;
__FAILED:
return ret;
}

View File

@@ -20,58 +20,7 @@
#include "rk_type.h" #include "rk_type.h"
#include "mpp_err.h" #include "mpp_err.h"
#include "h264d_global.h"
typedef enum {
NALU_NULL = 0,
//StreamError,
//HaveNoStream,
//NaluNotSupport,
//ReadNaluError,
//NALU_ERROR,
//NALU_OK,
//StartofNalu,
//EndofStream,
//ReallocBufError,
//MidOfNalu,
//EndOfNalu,
//StartOfPicture,
//StartOfSlice,
//SkipNALU,
//NALU_SPS,
//NALU_SubSPS,
//NALU_PPS,
//NALU_SEI,
NALU_MAX,
} NALU_STATUS;
typedef enum Rkv_slice_state_t {
SliceSTATE_NULL = 0,
SliceSTATE_IDLE,
//SliceSTATE_GetLastSlice,
SliceSTATE_ResetSlice,
//SliceSTATE_ReadNalu,
//SliceSTATE_ParseNalu,
//SliceSTATE_DecodeOneSlice,
//SliceSTATE_InitPicture,
//SliceSTATE_GetOuterDpbMemory,
////SliceSTATE_InitSlice,
//SliceSTATE_GetSliceData,
//SliceSTATE_RegisterOneSlice,
//SliceSTATE_RegisterOneFrame,
//SliceSTATE_ExitPicture,
//SliceSTATE_ErrorMaster,
//SliceSTATE_Return,
SliceSTATE_MAX,
} RKV_SLICE_STATUS;
@@ -80,6 +29,11 @@ extern "C" {
#endif #endif
MPP_RET parse_loop(H264_DecCtx_t *p_Dec);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -0,0 +1,183 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "mpp_err.h"
#include "h264d_log.h"
#include "h264d_bitread.h"
#include "h264d_pps.h"
#include "h264d_scalist.h"
#include "h264d_dpb.h"
#define MODULE_TAG "h264d_pps"
static void reset_curpps_data(H264_PPS_t *cur_pps)
{
memset(cur_pps, 0, sizeof(H264_PPS_t));
cur_pps->seq_parameter_set_id = -1; // reset
cur_pps->pic_parameter_set_id = -1;
}
static MPP_RET parse_pps_calingLists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps, H264_PPS_t *pps)
{
RK_S32 i = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
for (i = 0; i < 6; ++i)
{
READ_ONEBIT(ret, p_bitctx, &pps->pic_scaling_list_present_flag[i], "pic_scaling_list_present_flag");
if (pps->pic_scaling_list_present_flag[i])
{
FUN_CHECK (ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length,
pps->ScalingList4x4[i], &pps->UseDefaultScalingMatrix4x4Flag[i]));
}
}
if (pps->transform_8x8_mode_flag)
{
for (i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i)
{
READ_ONEBIT(ret, p_bitctx, &pps->pic_scaling_list_present_flag[i + 6], "pic_scaling_list_present_flag");
if (pps->pic_scaling_list_present_flag[i + 6])
{
FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length,
pps->ScalingList8x8[i], &pps->UseDefaultScalingMatrix8x8Flag[i]));
}
}
}
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
static MPP_RET parser_pps(BitReadCtx_t *p_bitctx, H264_SPS_t *cur_sps, H264_PPS_t *cur_pps)
{
MPP_RET ret = MPP_ERR_UNKNOW;
WRITE_LOG(p_bitctx, "----------------------------- PPS begin --------------------------------");
READ_UE(ret, p_bitctx, &cur_pps->pic_parameter_set_id, "pic_parameter_set_id");
READ_UE(ret, p_bitctx, &cur_pps->seq_parameter_set_id, "seq_parameter_set_id");
VAL_CHECK(ret, cur_pps->seq_parameter_set_id < 32);
READ_ONEBIT(ret, p_bitctx, &cur_pps->entropy_coding_mode_flag, "entropy_coding_mode_flag");
READ_ONEBIT(ret, p_bitctx, &cur_pps->bottom_field_pic_order_in_frame_present_flag, "bottom_field_pic_order_in_frame_present_flag");
READ_UE(ret, p_bitctx, &cur_pps->num_slice_groups_minus1, "num_slice_groups_minus1");
VAL_CHECK(ret, cur_pps->num_slice_groups_minus1 <= 1);
READ_UE(ret, p_bitctx, &cur_pps->num_ref_idx_l0_default_active_minus1, "num_ref_idx_l0_default_active_minus1");
VAL_CHECK(ret, cur_pps->num_ref_idx_l0_default_active_minus1 < 32);
READ_UE(ret, p_bitctx, &cur_pps->num_ref_idx_l1_default_active_minus1, "num_ref_idx_l1_default_active_minus1");
VAL_CHECK(ret, cur_pps->num_ref_idx_l1_default_active_minus1 < 32);
READ_ONEBIT(ret, p_bitctx, &cur_pps->weighted_pred_flag, "weighted_pred_flag");
READ_BITS(ret, p_bitctx, 2, &cur_pps->weighted_bipred_idc, "weighted_bipred_idc");
VAL_CHECK(ret, cur_pps->weighted_bipred_idc < 3);
READ_SE(ret, p_bitctx, &cur_pps->pic_init_qp_minus26, "pic_init_qp_minus26");
CHECK_RANGE(ret, p_bitctx, cur_pps->pic_init_qp_minus26, -26, 25);
READ_SE(ret, p_bitctx, &cur_pps->pic_init_qs_minus26, "pic_init_qs_minus26");
CHECK_RANGE(ret, p_bitctx, cur_pps->pic_init_qs_minus26, -26, 25);
READ_SE(ret, p_bitctx, &cur_pps->chroma_qp_index_offset, "chroma_qp_index_offset");
CHECK_RANGE(ret, p_bitctx, cur_pps->chroma_qp_index_offset, -12, 12);
cur_pps->second_chroma_qp_index_offset = cur_pps->chroma_qp_index_offset;
READ_ONEBIT(ret, p_bitctx, &cur_pps->deblocking_filter_control_present_flag, "deblocking_filter_control_present_flag");
READ_ONEBIT(ret, p_bitctx, &cur_pps->constrained_intra_pred_flag, "constrained_intra_pred_flag");
READ_ONEBIT(ret, p_bitctx, &cur_pps->redundant_pic_cnt_present_flag, "redundant_pic_cnt_present_flag");
VAL_CHECK(ret ,cur_pps->redundant_pic_cnt_present_flag == 0);
if (has_more_rbsp_data(p_bitctx))
{
READ_ONEBIT(ret, p_bitctx, &cur_pps->transform_8x8_mode_flag, "transform_8x8_mode_flag");
READ_ONEBIT(ret, p_bitctx, &cur_pps->pic_scaling_matrix_present_flag, "pic_scaling_matrix_present_flag");
if (cur_pps->pic_scaling_matrix_present_flag)
{
LogInfo(p_bitctx->ctx, "Picture scaling matrix present.");
FUN_CHECK(ret = parse_pps_calingLists(p_bitctx, cur_sps, cur_pps));
}
READ_SE(ret, p_bitctx, &cur_pps->second_chroma_qp_index_offset, "second_chroma_qp_index_offset");
}
else
{
cur_pps->transform_8x8_mode_flag = 0;
cur_pps->second_chroma_qp_index_offset = cur_pps->chroma_qp_index_offset;
}
cur_pps->Valid = 1;
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
/*!
***********************************************************************
* \brief
* parser pps and process pps
***********************************************************************
*/
//extern "C"
MPP_RET process_pps(H264_SLICE_t *currSlice)
{
MPP_RET ret = MPP_ERR_UNKNOW;
H264dLogCtx_t *logctx = currSlice->logctx;
H264dCurCtx_t *p_Cur = currSlice->p_Cur;
BitReadCtx_t *p_bitctx = &p_Cur->bitctx;
H264_PPS_t *cur_pps = &p_Cur->pps;
FunctionIn(logctx->parr[RUN_PARSE]);
reset_curpps_data(cur_pps);// reset
set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_PPS]);
FUN_CHECK(ret = parser_pps(p_bitctx, &p_Cur->sps, cur_pps));
//!< MakePPSavailable
ASSERT(cur_pps->Valid == 1);
memcpy(&currSlice->p_Vid->ppsSet[cur_pps->pic_parameter_set_id], cur_pps, sizeof(H264_PPS_t));
FunctionOut(logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
return ret;
}
/*!
***********************************************************************
* \brief
* prase sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET activate_pps(H264dVideoCtx_t *p_Vid, H264_PPS_t *pps)
{
MPP_RET ret = MPP_ERR_UNKNOW;
if (p_Vid->active_pps != pps)
{
if (p_Vid->dec_picture)
{
//!< return if the last picture has already been finished
FUN_CHECK(ret = exit_picture(p_Vid, &p_Vid->dec_picture));
}
p_Vid->active_pps = pps;
}
return ret = MPP_OK;
__FAILED:
return ret;
}

View File

@@ -0,0 +1,39 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_PPS_H_
#define _H264D_PPS_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
MPP_RET process_pps(H264_SLICE_t *currSlice);
MPP_RET activate_pps(H264dVideoCtx_t *p_Vid, H264_PPS_t *pps);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _H264D_PPS_H_ */

View File

@@ -496,10 +496,10 @@ static MPP_RET read_next_nalu(InputParams *p_in)
GetBitCtx_t *pStrmData = (GetBitCtx_t *)p_in->bitctx; GetBitCtx_t *pStrmData = (GetBitCtx_t *)p_in->bitctx;
memset(pStrmData, 0, sizeof(GetBitCtx_t)); memset(pStrmData, 0, sizeof(GetBitCtx_t));
set_streamdata(pStrmData, p_in->IO.pNALU, 4); set_streamdata(pStrmData, p_in->IO.pNALU, 4);
read_bits(pStrmData, 1, &forbidden_bit); read_bits( pStrmData, 1, &forbidden_bit);
ASSERT(forbidden_bit == 0); ASSERT(forbidden_bit == 0);
read_bits(pStrmData, 2, &nal_reference_idc); read_bits( pStrmData, 2, &nal_reference_idc);
read_bits(pStrmData, 5, &nal_unit_type); read_bits( pStrmData, 5, &nal_unit_type);
nalu_header_bytes = 1; nalu_header_bytes = 1;
if ((nal_unit_type == NALU_TYPE_PREFIX) || (nal_unit_type == NALU_TYPE_SLC_EXT)) { if ((nal_unit_type == NALU_TYPE_PREFIX) || (nal_unit_type == NALU_TYPE_SLC_EXT)) {
@@ -616,7 +616,7 @@ static void write_driver_bytes(FILE *fp_out, TempDataCtx_t *in_tmpctx, FILE *fp_
fwrite(&in_tmpctx->len, sizeof(RK_U32), 1, fp_out); fwrite(&in_tmpctx->len, sizeof(RK_U32), 1, fp_out);
fwrite(in_tmpctx->data, sizeof(RK_U8), in_tmpctx->len, fp_out); fwrite(in_tmpctx->data, sizeof(RK_U8), in_tmpctx->len, fp_out);
write_bytes(fp_in, &m_tmpctx, fp_out); write_bytes(fp_in, &m_tmpctx, fp_out);
goto __FAILED; return;
default: default:
printf("ERROR: frame_no=%d. \n", frame_no); printf("ERROR: frame_no=%d. \n", frame_no);
ASSERT(0); ASSERT(0);
@@ -625,8 +625,6 @@ static void write_driver_bytes(FILE *fp_out, TempDataCtx_t *in_tmpctx, FILE *fp_
fread(&header, 1, sizeof(RK_U32), fp_in); fread(&header, 1, sizeof(RK_U32), fp_in);
fread(&datasize, 1, sizeof(RK_U32), fp_in); fread(&datasize, 1, sizeof(RK_U32), fp_in);
} }
__FAILED:
return;
} }
@@ -638,8 +636,8 @@ __FAILED:
*/ */
MPP_RET h264d_configure(InputParams *p_in, RK_S32 ac, char *av[]) MPP_RET h264d_configure(InputParams *p_in, RK_S32 ac, char *av[])
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_ERR_UNKNOW;
VAL_CHECK(ac > 1); VAL_CHECK(ret, ac > 1);
display_input_cmd(ac, av); display_input_cmd(ac, av);
FUN_CHECK (ret = parse_command(p_in, ac, av)); FUN_CHECK (ret = parse_command(p_in, ac, av));
@@ -672,20 +670,20 @@ MPP_RET h264d_close_files(InputParams *p_in)
*/ */
MPP_RET h264d_open_files(InputParams *p_in) MPP_RET h264d_open_files(InputParams *p_in)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_ERR_UNKNOW;
FLE_CHECK(p_in->fp_bitstream = fopen(p_in->infile_name, "rb")); FLE_CHECK(ret, p_in->fp_bitstream = fopen(p_in->infile_name, "rb"));
#if defined(_MSC_VER) #if defined(_MSC_VER)
FLE_CHECK(p_in->fp_golden_data = open_file(p_in->cmp_path_dir, p_in->infile_name, "_trunk.dat", "rb")); FLE_CHECK(ret, p_in->fp_golden_data = open_file(p_in->cmp_path_dir, p_in->infile_name, ".dat", "rb"));
FLE_CHECK(p_in->fp_driver_data = open_file(p_in->out_path_dir, p_in->infile_name, "_driver.dat", "wb")); FLE_CHECK(ret, p_in->fp_driver_data = open_file(p_in->out_path_dir, p_in->infile_name, "_fpga.dat", "wb"));
#elif defined(__GNUC__) #elif defined(__GNUC__)
char golden_dir[] = "/home/dw/h264d_fpga/AVC_MVC_ALL_BITSTRAM/h264d_fpga_dat"; char golden_dir[] = "/home/dw/h264d_fpga/AVC_MVC_ALL_BITSTRAM/h264d_fpga_dat";
char dirver_dir[] = "./h264d_dat"; char dirver_dir[] = "./h264d_dat";
if (access(dirver_dir, 0) != 0) if (access(dirver_dir, 0) != 0)
mkdir(dirver_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); mkdir(dirver_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
FLE_CHECK(p_in->fp_golden_data = open_file(golden_dir, p_in->infile_name, ".dat", "rb")); FLE_CHECK(ret, p_in->fp_golden_data = open_file(golden_dir, p_in->infile_name, ".dat", "rb"));
FLE_CHECK(p_in->fp_driver_data = open_file(dirver_dir, p_in->infile_name, "_driver.dat", "wb")); FLE_CHECK(ret, p_in->fp_driver_data = open_file(dirver_dir, p_in->infile_name, "_driver.dat", "wb"));
#endif #endif
return MPP_OK; return MPP_OK;
@@ -720,16 +718,18 @@ MPP_RET h264d_free_frame_buffer(InputParams *p_in)
*/ */
MPP_RET h264d_alloc_frame_buffer(InputParams *p_in) MPP_RET h264d_alloc_frame_buffer(InputParams *p_in)
{ {
MEM_CHECK(p_in->IO.pbuf = mpp_malloc_size(RK_U8, IOBUFSIZE)); MPP_RET ret = MPP_ERR_UNKNOW;
MEM_CHECK(p_in->strm.pbuf = mpp_malloc_size(RK_U8, STMBUFSIZE));
MEM_CHECK(p_in->bitctx = mpp_malloc_size(void, sizeof(GetBitCtx_t)));
p_in->IO.pbuf = mpp_malloc_size(RK_U8, IOBUFSIZE);
p_in->strm.pbuf = mpp_malloc_size(RK_U8, STMBUFSIZE);
p_in->bitctx = mpp_malloc_size(void, sizeof(GetBitCtx_t));
MEM_CHECK(ret, p_in->IO.pbuf && p_in->strm.pbuf && p_in->bitctx);
p_in->is_fist_nalu = 1; p_in->is_fist_nalu = 1;
p_in->is_fist_frame = 1; p_in->is_fist_frame = 1;
return MPP_OK; return MPP_OK;
__FAILED: __FAILED:
return MPP_NOK; return ret;
} }
@@ -755,7 +755,7 @@ MPP_RET h264d_read_one_frame(InputParams *p_in, MppPacket pkt)
read_next_nalu(p_in); read_next_nalu(p_in);
} while (!p_in->is_new_frame && !p_in->is_eof); } while (!p_in->is_new_frame && !p_in->is_eof);
//-- set code input context //-- set code input context
((MppPacketImpl *)pkt)->data = p_in->strm.pbuf; ((MppPacketImpl *)pkt)->pos = p_in->strm.pbuf;
((MppPacketImpl *)pkt)->size = p_in->strm.strmbytes; ((MppPacketImpl *)pkt)->size = p_in->strm.strmbytes;
if (p_in->is_eof) { if (p_in->is_eof) {
mpp_packet_set_eos(pkt); mpp_packet_set_eos(pkt);
@@ -771,21 +771,24 @@ MPP_RET h264d_read_one_frame(InputParams *p_in, MppPacket pkt)
*/ */
MPP_RET h264d_write_fpga_data(InputParams *p_in) MPP_RET h264d_write_fpga_data(InputParams *p_in)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_ERR_UNKNOW;
TempDataCtx_t tmpctx = { 0 }; TempDataCtx_t tmpctx = { 0 };
FILE *fp_log = NULL; FILE *fp_log = NULL;
RK_U32 frame_no = 0; RK_U32 frame_no = 0;
char *out_name = NULL; char *out_name = NULL;
mpp_env_get_str(logenv_name.outpath, &out_name, NULL); mpp_env_get_str(logenv_name.outpath, &out_name, NULL);
FLE_CHECK(p_in->fp_driver_data && p_in->fp_driver_data); FLE_CHECK(ret, p_in->fp_golden_data && p_in->fp_driver_data);
FLE_CHECK(fp_log = fopen(strcat(out_name, "/h264d_driverdata.dat"), "rb")); fp_log = fopen(strcat(out_name, "/h264d_driver_data.dat"), "rb");
MEM_CHECK(tmpctx.data = mpp_calloc_size(RK_U8, 128)); //!< for read golden fpga data FLE_CHECK(ret, fp_log);
do { tmpctx.data = mpp_calloc_size(RK_U8, 128);
MEM_CHECK(ret, tmpctx.data); //!< for read golden fpga data
while (!feof(p_in->fp_golden_data) && !feof(fp_log))
{
read_golden_data (p_in->fp_golden_data, &tmpctx, frame_no); read_golden_data (p_in->fp_golden_data, &tmpctx, frame_no);
write_driver_bytes(p_in->fp_driver_data, &tmpctx, fp_log, frame_no); write_driver_bytes(p_in->fp_driver_data, &tmpctx, fp_log, frame_no);
frame_no++; frame_no++;
} while (!feof(p_in->fp_golden_data) && !feof(fp_log) && (frame_no <= p_in->iFrmdecoded)); }
mpp_free(tmpctx.data); mpp_free(tmpctx.data);
FCLOSE(fp_log); FCLOSE(fp_log);
@@ -796,5 +799,5 @@ __FAILED:
mpp_free(tmpctx.data); mpp_free(tmpctx.data);
FCLOSE(fp_log); FCLOSE(fp_log);
return ret = MPP_NOK; return ret;
} }

View File

@@ -0,0 +1,409 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include "h264d_bitread.h"
#include "h264d_scalist.h"
static RK_U8 ZZ_SCAN[16] =
{ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 };
static RK_U8 ZZ_SCAN8[64] =
{ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 };
static RK_S32 Default4x4Intra[H264ScalingList4x4Length] =
{ 6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42 };
static RK_S32 Default4x4Inter[H264ScalingList4x4Length] =
{ 10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 };
static RK_S32 Default8x8Intra[H264ScalingList8x8Length] =
{ 6, 10, 13, 16, 18, 23, 25, 27, 10, 11, 16, 18, 23, 25, 27, 29,
13, 16, 18, 23, 25, 27, 29, 31, 16, 18, 23, 25, 27, 29, 31, 33,
18, 23, 25, 27, 29, 31, 33, 36, 23, 25, 27, 29, 31, 33, 36, 38,
25, 27, 29, 31, 33, 36, 38, 40, 27, 29, 31, 33, 36, 38, 40, 42 };
static RK_S32 Default8x8Inter[H264ScalingList8x8Length] =
{ 9, 13, 15, 17, 19, 21, 22, 24, 13, 13, 17, 19, 21, 22, 24, 25,
15, 17, 19, 21, 22, 24, 25, 27, 17, 19, 21, 22, 24, 25, 27, 28,
19, 21, 22, 24, 25, 27, 28, 30, 21, 22, 24, 25, 27, 28, 30, 32,
22, 24, 25, 27, 28, 30, 32, 33, 24, 25, 27, 28, 30, 32, 33, 35 };
static RK_S32 Default4x4[16] =
{ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
static RK_S32 Default8x8[64] =
{ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
static void set_sps_scanlist_matrix(H264_SPS_t *sps, H264dVideoCtx_t *p_Vid)
{
RK_S32 i = 0;
for (i = 0; i < 6; ++i)
{
if (!sps->seq_scaling_list_present_flag[i]) // fall-back rule A
{
if (i == 0)
{
p_Vid->qmatrix[i] = Default4x4Intra;
}
else if (i == 3)
{
p_Vid->qmatrix[i] = Default4x4Inter;
}
else
{
p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1];
}
}
else
{
if (sps->UseDefaultScalingMatrix4x4Flag[i])
{
p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter;
}
else
{
p_Vid->qmatrix[i] = sps->ScalingList4x4[i];
}
}
}
for (i = 6; i < ((sps->chroma_format_idc != YUV444) ? 8 : 12); ++i)
{
if (!sps->seq_scaling_list_present_flag[i]) // fall-back rule A
{
if (i == 6)
{
p_Vid->qmatrix[i] = Default8x8Intra;
}
else if (i == 7)
{
p_Vid->qmatrix[i] = Default8x8Inter;
}
else
{
p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2];
}
}
else
{
if (sps->UseDefaultScalingMatrix8x8Flag[i - 6])
{
p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter;
}
else
{
p_Vid->qmatrix[i] = sps->ScalingList8x8[i - 6];
}
}
}
}
static void set_pps_scanlist_matrix(H264_SPS_t *sps, H264_PPS_t *pps, H264dVideoCtx_t *p_Vid)
{
RK_S32 i = 0;
for (i = 0; i < 6; ++i)
{
if (!pps->pic_scaling_list_present_flag[i]) // fall-back rule B
{
if (i == 0)
{
if (!sps->seq_scaling_matrix_present_flag)
{
p_Vid->qmatrix[i] = Default4x4Intra;
}
}
else if (i == 3)
{
if (!sps->seq_scaling_matrix_present_flag)
{
p_Vid->qmatrix[i] = Default4x4Inter;
}
}
else
{
p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1];
}
}
else
{
if (pps->UseDefaultScalingMatrix4x4Flag[i])
{
p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter;
}
else
{
p_Vid->qmatrix[i] = pps->ScalingList4x4[i];
}
}
}
for (i = 6; i < ((sps->chroma_format_idc != YUV444) ? 8 : 12); ++i)
{
if (!pps->pic_scaling_list_present_flag[i]) // fall-back rule B
{
if (i == 6)
{
if (!sps->seq_scaling_matrix_present_flag)
{
p_Vid->qmatrix[i] = Default8x8Intra;
}
}
else if (i == 7)
{
if (!sps->seq_scaling_matrix_present_flag)
p_Vid->qmatrix[i] = Default8x8Inter;
}
else
p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2];
}
else
{
if (pps->UseDefaultScalingMatrix8x8Flag[i - 6])
{
p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter;
}
else
{
p_Vid->qmatrix[i] = pps->ScalingList8x8[i - 6];
}
}
}
}
/*!
***********************************************************************
* \brief
* check profile
***********************************************************************
*/
//extern "C"
RK_U32 is_prext_profile(RK_U32 profile_idc)
{
return (profile_idc >= FREXT_HP || profile_idc == FREXT_CAVLC444) ? 1 : 0;
}
/*!
***********************************************************************
* \brief
* parse sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default)
{
MPP_RET ret = MPP_ERR_UNKNOW;
RK_S32 last_scale = 8;
RK_S32 next_scale = 8;
RK_S32 delta_scale = 0;
RK_S32 j = 0, scanj = 0;
RK_U8 *zz_scan = (size > 16) ? ZZ_SCAN8 : ZZ_SCAN;
*use_default = 0;
for (j = 0; j < size; ++j)
{
scanj = zz_scan[j];
if (next_scale != 0)
{
READ_SE(ret, p_bitctx, &delta_scale, "delta_scale");
CHECK_RANGE(ret, p_bitctx, delta_scale, -128, 127);
next_scale = (last_scale + delta_scale + 256) & 0xff;
*use_default = (scanj == 0 && next_scale == 0) ? 1 : 0;
}
scaling_list[scanj] = (next_scale == 0) ? last_scale : next_scale;
last_scale = scaling_list[scanj];
}
return ret = MPP_OK;
__FAILED:
return ret;
}
/*!
***********************************************************************
* \brief
* parse sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps)
{
RK_S32 size = 0;
RK_S32 pic_size = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
switch (sps->level_idc)
{
case 9:
size = 152064;
break;
case 10:
size = 152064;
break;
case 11:
if (sps->constrained_set3_flag && !is_prext_profile(sps->profile_idc))
{
size = 152064;
}
else
{
size = 345600;
}
break;
case 12:
size = 912384;
break;
case 13:
size = 912384;
break;
case 20:
size = 912384;
break;
case 21:
size = 1824768;
break;
case 22:
size = 3110400;
break;
case 30:
size = 3110400;
break;
case 31:
size = 6912000;
break;
case 32:
size = 7864320;
break;
case 40:
size = 12582912;
break;
case 41:
size = 12582912;
break;
case 42:
size = 13369344;
break;
case 50:
size = 42393600;
break;
case 51:
size = 70778880;
break;
case 52:
size = 70778880;
break;
default:
ASSERT(0); // undefined level
return ret = MPP_NOK;
}
pic_size = (sps->pic_width_in_mbs_minus1 + 1)
* (sps->pic_height_in_map_units_minus1 + 1)
* (sps->frame_mbs_only_flag ? 1 : 2) * 384;
size /= pic_size;
size = min(size, 16);
sps->max_dec_frame_buffering = size;
return ret = MPP_OK;
}
/*!
***********************************************************************
* \brief
* parse sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps)
{
RK_S32 i = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
// Parse scaling_list4x4.
for (i = 0; i < 6; ++i)
{
READ_ONEBIT(ret, p_bitctx, &sps->seq_scaling_list_present_flag[i], "seq_scaling_list_present_flag");
if (sps->seq_scaling_list_present_flag[i])
{
FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length,
sps->ScalingList4x4[i], &sps->UseDefaultScalingMatrix4x4Flag[i]));
}
}
// Parse scaling_list8x8.
for (i = 0; i < ((sps->chroma_format_idc != YUV444) ? 2 : 6); ++i)
{
READ_ONEBIT(ret, p_bitctx, &sps->seq_scaling_list_present_flag[6 + i], "seq_scaling_list_present_flag");
if (sps->seq_scaling_list_present_flag[6 + i])
{
FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length,
sps->ScalingList8x8[i], &sps->UseDefaultScalingMatrix8x8Flag[i]));
}
}
return ret = MPP_OK;
__FAILED:
return ret;
}
/*!
***********************************************************************
* \brief
* prepare scanlist info to register syntax
***********************************************************************
*/
//extern "C"
MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice)
{
RK_S32 i = 0;
H264_SPS_t *sps = currSlice->p_Vid->active_sps;
H264_PPS_t *pps = currSlice->p_Vid->active_pps;
if (!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag)
{
for (i = 0; i < 12; i++)
{
currSlice->p_Vid->qmatrix[i] = (i < 6) ? Default4x4 : Default8x8;
}
}
else
{
if (sps->seq_scaling_matrix_present_flag) // check sps first
{
set_sps_scanlist_matrix(sps, currSlice->p_Vid);
}
if (pps->pic_scaling_matrix_present_flag) // then check pps
{
set_pps_scanlist_matrix(sps, pps, currSlice->p_Vid);
}
}
return MPP_OK;
}

View File

@@ -0,0 +1,41 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_SCALIST_H_
#define _H264D_SCALIST_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
RK_U32 is_prext_profile(RK_U32 profile_idc);
MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps);
MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default);
MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps);
MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _H264D_SCALIST_H_ */

View File

@@ -0,0 +1,410 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "h264d_log.h"
#include "h264d_bitread.h"
#include "h264d_sps.h"
#include "h264d_sei.h"
#define MODULE_TAG "h264d_sei"
static void interpret_spare_pic()
{
}
static void interpret_subsequence_info()
{
}
static void interpret_subsequence_layer_characteristics_info()
{
}
static void interpret_subsequence_characteristics_info()
{
}
static void interpret_scene_information()
{
}
static void interpret_user_data_registered_itu_t_t35_info()
{
}
static void interpret_user_data_unregistered_info()
{
}
static void interpret_pan_scan_rect_info()
{
}
static void interpret_filler_payload_info()
{
}
static void interpret_dec_ref_pic_marking_repetition_info()
{
}
static void interpret_full_frame_freeze_info()
{
}
static void interpret_full_frame_freeze_release_info()
{
}
static void interpret_full_frame_snapshot_info()
{
}
static void interpret_progressive_refinement_start_info()
{
}
static void interpret_progressive_refinement_end_info()
{
}
static void interpret_motion_constrained_slice_group_set_info()
{
}
static void interpret_picture_timing_info()
{
}
static void interpret_film_grain_characteristics_info()
{
}
static void interpret_deblocking_filter_display_preference_info()
{
}
static void interpret_stereo_video_info_info()
{
}
static void interpret_post_filter_hints_info()
{
}
static void interpret_tone_mapping()
{
}
static void interpret_frame_packing_arrangement_info()
{
}
static void interpret_mvc_scalability_info()
{
}
static MPP_RET interpret_recovery_point_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg)
{
MPP_RET ret = MPP_ERR_UNKNOW;
set_bitread_ctx(p_bitctx, payload, size);
READ_UE(ret, p_bitctx, &sei_msg->recovery_point.recovery_frame_cnt, "recovery_frame_cnt");
READ_ONEBIT(ret, p_bitctx, &sei_msg->recovery_point.exact_match_flag, "exact_match_flag");
READ_ONEBIT(ret, p_bitctx, &sei_msg->recovery_point.broken_link_flag, "broken_link_flag");
READ_BITS(ret, p_bitctx, 2, &sei_msg->recovery_point.changing_slice_group_idc, "changing_slice_group_idc");
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET interpret_mvc_scalable_nesting_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg)
{
RK_S32 i;
RK_U32 operation_point_flag;
RK_U32 all_view_components_in_au_flag;
RK_S32 num_view_components_minus1;
RK_S32 sei_view_id;
RK_S32 num_view_components_op_minus1;
RK_S32 sei_op_view_id;
RK_S32 sei_op_temporal_id;
MPP_RET ret = MPP_ERR_UNKNOW;
BitReadCtx_t tmp_strmdata = { 0 };
BitReadCtx_t *p_strm = &tmp_strmdata;
set_bitread_ctx(p_strm, payload, size);
READ_ONEBIT(ret, p_strm, &operation_point_flag, "operation_point_flag");
if (!operation_point_flag)
{
READ_ONEBIT(ret, p_strm, &all_view_components_in_au_flag, "all_view_components_in_au_flag");
READ_UE(ret, p_strm, &num_view_components_minus1, "num_view_components_minus1");
for (i = 0; i <= num_view_components_minus1; i++)
{
READ_BITS(ret, p_strm, 10, &sei_view_id, "sei_view_id");
}
}
else
{
READ_UE(ret, p_strm, &num_view_components_op_minus1, "num_view_components_op_minus1");
for (i = 0; i <= num_view_components_op_minus1; i++)
{
READ_BITS(ret, p_strm, 10, &sei_op_view_id, "sei_op_view_id");
}
READ_BITS(ret, p_strm, 3, &sei_op_temporal_id, "sei_op_temporal_id");
}
p_bitctx->used_bits = p_strm->used_bits;
sei_msg->mvc_scalable_nesting_flag = 1;
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET interpret_buffering_period_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg)
{
MPP_RET ret = MPP_ERR_UNKNOW;
BitReadCtx_t tmp_strmdata = { 0 };
p_bitctx = &tmp_strmdata;
set_bitread_ctx(p_bitctx, payload, size);
READ_UE(ret, p_bitctx, &sei_msg->seq_parameter_set_id, "seq_parameter_set_id");
return ret = MPP_OK;
__FAILED:
return ret;
}
static void interpret_reserved_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg)
{
RK_S32 offset = 0;
RK_U8 payload_byte = 0;
while (offset < size)
{
payload_byte = payload[offset];
offset++;
}
(void)p_bitctx;
(void)sei_msg;
(void)payload_byte;
}
static MPP_RET parserSEI(BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg, RK_U8 *msg)
{
MPP_RET ret = MPP_ERR_UNKNOW;
//!< sei_payload( type, size );
switch (sei_msg->type)
{
case SEI_BUFFERING_PERIOD:
FUN_CHECK(ret = interpret_buffering_period_info(msg, sei_msg->payload_size, p_bitctx, sei_msg));
break;
case SEI_PIC_TIMING:
interpret_picture_timing_info();
break;
case SEI_PAN_SCAN_RECT:
interpret_pan_scan_rect_info();
break;
case SEI_FILLER_PAYLOAD:
interpret_filler_payload_info();
break;
case SEI_USER_DATA_REGISTERED_ITU_T_T35:
interpret_user_data_registered_itu_t_t35_info();
break;
case SEI_USER_DATA_UNREGISTERED:
interpret_user_data_unregistered_info();
break;
case SEI_RECOVERY_POINT:
FUN_CHECK(ret = interpret_recovery_point_info(msg, sei_msg->payload_size, p_bitctx, sei_msg));
break;
case SEI_DEC_REF_PIC_MARKING_REPETITION:
interpret_dec_ref_pic_marking_repetition_info();
break;
case SEI_SPARE_PIC:
interpret_spare_pic();
break;
case SEI_SCENE_INFO:
interpret_scene_information();
break;
case SEI_SUB_SEQ_INFO:
interpret_subsequence_info();
break;
case SEI_SUB_SEQ_LAYER_CHARACTERISTICS:
interpret_subsequence_layer_characteristics_info();
break;
case SEI_SUB_SEQ_CHARACTERISTICS:
interpret_subsequence_characteristics_info();
break;
case SEI_FULL_FRAME_FREEZE:
interpret_full_frame_freeze_info();
break;
case SEI_FULL_FRAME_FREEZE_RELEASE:
interpret_full_frame_freeze_release_info();
break;
case SEI_FULL_FRAME_SNAPSHOT:
interpret_full_frame_snapshot_info();
break;
case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START:
interpret_progressive_refinement_start_info();
break;
case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END:
interpret_progressive_refinement_end_info();
break;
case SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET:
interpret_motion_constrained_slice_group_set_info();
case SEI_FILM_GRAIN_CHARACTERISTICS:
interpret_film_grain_characteristics_info();
break;
case SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE:
interpret_deblocking_filter_display_preference_info();
break;
case SEI_STEREO_VIDEO_INFO:
interpret_stereo_video_info_info();
break;
case SEI_TONE_MAPPING:
interpret_tone_mapping();
break;
case SEI_POST_FILTER_HINTS:
interpret_post_filter_hints_info();
break;
case SEI_FRAME_PACKING_ARRANGEMENT:
interpret_frame_packing_arrangement_info();
break;
case SEI_MVC_SCALABLE_NESTING:
FUN_CHECK(ret = interpret_mvc_scalable_nesting_info(msg, sei_msg->payload_size, p_bitctx, sei_msg));
break;
case SEI_VIEW_SCALABILITY_INFO:
interpret_mvc_scalability_info();
break;
default:
interpret_reserved_info(msg, sei_msg->payload_size, p_bitctx, sei_msg);
break;
}
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET analysisSEI(H264_SLICE_t *cur_slice)
{
H264_SPS_t *sps = NULL;
H264_subSPS_t *subset_sps = NULL;
MPP_RET ret = MPP_ERR_UNKNOW;
H264dVideoCtx_t *p_Vid = cur_slice->p_Vid;
H264_SEI_t *sei_msg = &cur_slice->p_Cur->sei;
switch (sei_msg->type) // sei_payload( type, size )
{
case SEI_BUFFERING_PERIOD:
if (sei_msg->mvc_scalable_nesting_flag)
{
p_Vid->active_mvc_sps_flag = 1;
sps = NULL;
subset_sps = &p_Vid->subspsSet[sei_msg->seq_parameter_set_id];
}
else
{
p_Vid->active_mvc_sps_flag = 0;
sps = &p_Vid->spsSet[sei_msg->seq_parameter_set_id];
subset_sps = NULL;
}
p_Vid->exit_picture_flag = 1;
FUN_CHECK(ret = activate_sps(p_Vid, sps, subset_sps));
break;
default:
break;
}
return ret = MPP_OK;
__FAILED:
return ret;
}
/*!
***********************************************************************
* \brief
* parse SEI information
***********************************************************************
*/
//extern "C"
MPP_RET process_sei(H264_SLICE_t *currSlice)
{
RK_S32 nn = 0;
RK_S32 tmp_byte = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
H264_SEI_t *sei_msg = &currSlice->p_Cur->sei;
BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx;
FunctionIn(currSlice->logctx->parr[RUN_PARSE]);
memset(sei_msg, 0, sizeof(*sei_msg));
sei_msg->mvc_scalable_nesting_flag = 0; //init to false
do
{
sei_msg->type = 0;
READ_BITS(ret, p_bitctx, 8, &tmp_byte, "tmp_byte");
while (tmp_byte == 0xFF)
{
sei_msg->type += 255;
READ_BITS(ret, p_bitctx, 8, &tmp_byte, "tmp_type");
}
sei_msg->type += tmp_byte; // this is the last byte
sei_msg->payload_size = 0;
READ_BITS(ret, p_bitctx, 8, &tmp_byte, "tmp_type");
while (tmp_byte == 0xFF)
{
sei_msg->payload_size += 255;
READ_BITS(ret, p_bitctx, 8, &tmp_byte, "tmp_type");
}
sei_msg->payload_size += tmp_byte; // this is the last byte
//--- read sei info
FUN_CHECK(ret = parserSEI(p_bitctx, sei_msg, p_bitctx->data_));
//--- analysis sei info
FUN_CHECK(ret = analysisSEI(currSlice));
//--- set offset to read next sei nal
if (SEI_MVC_SCALABLE_NESTING == sei_msg->type)
{
sei_msg->payload_size = ((p_bitctx->used_bits + 0x07) >> 3);
}
for (nn = 0; nn < sei_msg->payload_size; nn++) // read bytes
{
READ_BITS(ret, p_bitctx, 8, &tmp_byte, "tmp_byte");
}
} while ((p_bitctx->data_[0] != 0x80) && (p_bitctx->bytes_left_ > 1)); // more_rbsp_data() msg[offset] != 0x80
FunctionOut(currSlice->logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}

View File

@@ -0,0 +1,37 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_SEI_H_
#define _H264D_SEI_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
MPP_RET process_sei(H264_SLICE_t *currSlice);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _H264D_SEI_H_ */

View File

@@ -0,0 +1,659 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mpp_mem.h"
#include "h264d_log.h"
#include "h264d_slice.h"
#include "h264d_sps.h"
#include "h264d_pps.h"
#define MODULE_TAG "h264d_slice"
static void free_slice_drpm_buffer(H264_SLICE_t *currSlice) // dec_ref_pic_marking
{
H264_DRPM_t *tmp_drpm = NULL;
while (currSlice->dec_ref_pic_marking_buffer)
{
tmp_drpm = currSlice->dec_ref_pic_marking_buffer;
currSlice->dec_ref_pic_marking_buffer = tmp_drpm->Next;
mpp_free(tmp_drpm);
}
}
static RK_S32 get_voidx(H264_subSPS_t *subset_spsSet, H264_subSPS_t **subset_sps, RK_S32 iViewId)
{
RK_S32 i = 0, iVOIdx = -1;
RK_S32 *piViewIdMap = NULL;
H264_subSPS_t *active_subset_sps = *subset_sps;
if (active_subset_sps)
{
piViewIdMap = active_subset_sps->view_id;
for (iVOIdx = active_subset_sps->num_views_minus1; iVOIdx >= 0; iVOIdx--)
if (piViewIdMap[iVOIdx] == iViewId)
break;
}
else
{
for (i = 0; i < MAXSPS; i++)
{
if (subset_spsSet[i].num_views_minus1 >= 0 && subset_spsSet[i].sps.Valid)
{
break;
}
}
if (i < MAXSPS)
{
*subset_sps = active_subset_sps = &subset_spsSet[i];
piViewIdMap = active_subset_sps->view_id;
for (iVOIdx = active_subset_sps->num_views_minus1; iVOIdx >= 0; iVOIdx--)
if (piViewIdMap[iVOIdx] == iViewId)
break;
return iVOIdx;
}
else
{
iVOIdx = 0;
}
}
return iVOIdx;
}
static RK_U32 is_new_picture(H264_SLICE_t *currSlice)
{
RK_U32 is_new_pic_flag = 0;
RK_S32 result = 0, result1 = 0;
H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
H264_OldSlice_t *p_old_slice = &currSlice->p_Vid->old_slice;
currSlice->is_new_picture_flag = 0;
if (p_old_slice == NULL) // fist slice
{
is_new_pic_flag = 1;
goto __Updata;
}
else
{
result |= (currSlice->start_mb_nr == 0);
result |= (p_old_slice->pps_id != (RK_S32)currSlice->pic_parameter_set_id);
result |= (p_old_slice->frame_num != currSlice->frame_num);
result |= (p_old_slice->field_pic_flag != currSlice->field_pic_flag);
if (currSlice->field_pic_flag && p_old_slice->field_pic_flag)
{
result |= (p_old_slice->bottom_field_flag != currSlice->bottom_field_flag);
}
if (p_Vid->old_slice.current_mb_nr != 0)
{
if (currSlice->mb_aff_frame_flag)
result |= (currSlice->start_mb_nr << 1) < (p_Vid->old_slice.current_mb_nr);
else
result |= currSlice->start_mb_nr < p_Vid->old_slice.current_mb_nr;
}
result |= (p_old_slice->nal_ref_idc != currSlice->nal_reference_idc)
&& ((p_old_slice->nal_ref_idc == 0) || (currSlice->nal_reference_idc == 0));
result |= (p_old_slice->idr_flag != currSlice->idr_flag);
if (currSlice->idr_flag && p_old_slice->idr_flag)
{
result |= (p_old_slice->idr_pic_id != (RK_S32)currSlice->idr_pic_id);
}
if (p_Vid->active_sps->pic_order_cnt_type == 0)
{
result1 |= (p_old_slice->pic_oder_cnt_lsb != currSlice->pic_order_cnt_lsb);
if (p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag && !currSlice->field_pic_flag)
{
result1 |= (p_old_slice->delta_pic_oder_cnt_bottom != currSlice->delta_pic_order_cnt_bottom);
}
}
else if (p_Vid->active_sps->pic_order_cnt_type == 1)
{
if (!p_Vid->active_sps->delta_pic_order_always_zero_flag)
{
result1 |= (p_old_slice->delta_pic_order_cnt[0] != currSlice->delta_pic_order_cnt[0]);
if (p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag && !currSlice->field_pic_flag)
{
result1 |= (p_old_slice->delta_pic_order_cnt[1] != currSlice->delta_pic_order_cnt[1]);
}
}
}
else
{
result1 |= (p_old_slice->frame_num != currSlice->frame_num);
}
result |= (currSlice->view_id != p_old_slice->view_id);
result |= (currSlice->inter_view_flag != p_old_slice->inter_view_flag);
result |= (currSlice->anchor_pic_flag != p_old_slice->anchor_pic_flag);
result |= (currSlice->layer_id != p_old_slice->layer_id);
}
if (result)
{
is_new_pic_flag = 1;
goto __Updata;
}
else
{
return is_new_pic_flag = 0;
}
__Updata:
currSlice->is_new_picture_flag = 1;
p_old_slice->current_mb_nr = currSlice->current_mb_nr;
p_old_slice->pps_id = currSlice->pic_parameter_set_id;
p_old_slice->frame_num = currSlice->frame_num; //p_Vid->frame_num;
p_old_slice->field_pic_flag = currSlice->field_pic_flag; //p_Vid->field_pic_flag;
if (currSlice->field_pic_flag)
{
p_old_slice->bottom_field_flag = currSlice->bottom_field_flag;
}
p_old_slice->nal_ref_idc = currSlice->nal_reference_idc;
p_old_slice->idr_flag = currSlice->idr_flag;
if (currSlice->idr_flag)
{
p_old_slice->idr_pic_id = currSlice->idr_pic_id;
}
if (p_Vid->active_sps->pic_order_cnt_type == 0)
{
p_old_slice->pic_oder_cnt_lsb = currSlice->pic_order_cnt_lsb;
p_old_slice->delta_pic_oder_cnt_bottom = currSlice->delta_pic_order_cnt_bottom;
}
if (p_Vid->active_sps->pic_order_cnt_type == 1)
{
p_old_slice->delta_pic_order_cnt[0] = currSlice->delta_pic_order_cnt[0];
p_old_slice->delta_pic_order_cnt[1] = currSlice->delta_pic_order_cnt[1];
}
p_old_slice->view_id = currSlice->view_id;
p_old_slice->inter_view_flag = currSlice->inter_view_flag;
p_old_slice->anchor_pic_flag = currSlice->anchor_pic_flag;
p_old_slice->layer_id = currSlice->layer_id;
return is_new_pic_flag;
}
static MPP_RET ref_pic_list_mvc_modification(H264_SLICE_t *currSlice)
{
RK_U32 i = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
RK_U32 modification_of_pic_nums_idc = 0;
RK_U32 abs_diff_pic_num_minus1 = 0;
RK_U32 long_term_pic_idx = 0;
RK_U32 abs_diff_view_idx_minus1 = 0;
BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx;
if ((currSlice->slice_type % 5) != I_SLICE && (currSlice->slice_type % 5) != SI_SLICE)
{
READ_ONEBIT(ret, p_bitctx, &currSlice->ref_pic_list_reordering_flag[LIST_0], "ref_pic_list_reordering_flag");
if (currSlice->ref_pic_list_reordering_flag[LIST_0])
{
i = 0;
do
{
READ_UE(ret, p_bitctx, &modification_of_pic_nums_idc, "modification_of_pic_nums_idc");
if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1)
{
READ_UE(ret, p_bitctx, &abs_diff_pic_num_minus1, "abs_diff_pic_num_minus1_lx");
}
else
{
if (modification_of_pic_nums_idc == 2)
{
READ_UE(ret, p_bitctx, &long_term_pic_idx, "long_term_pic_idx");
}
else if (modification_of_pic_nums_idc == 4 || modification_of_pic_nums_idc == 5)
{
READ_UE(ret, p_bitctx, &abs_diff_view_idx_minus1, "abs_diff_view_idx_minus1");
}
}
i++;
} while (modification_of_pic_nums_idc != 3);
}
}
if (currSlice->slice_type % 5 == B_SLICE)
{
READ_ONEBIT(ret, p_bitctx, &currSlice->ref_pic_list_reordering_flag[LIST_1], "ref_pic_list_reordering_flag");
if (currSlice->ref_pic_list_reordering_flag[LIST_1])
{
i = 0;
do
{
READ_UE(ret, p_bitctx, &modification_of_pic_nums_idc, "modification_of_pic_nums_idc");
if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1)
{
READ_UE(ret, p_bitctx, &abs_diff_pic_num_minus1, "abs_diff_pic_num_minus1_lx");
}
else
{
if (modification_of_pic_nums_idc == 2)
{
READ_UE(ret, p_bitctx, &long_term_pic_idx, "long_term_pic_idx");
}
else if (modification_of_pic_nums_idc == 4 || modification_of_pic_nums_idc == 5)
{
READ_UE(ret, p_bitctx, &abs_diff_view_idx_minus1, "abs_diff_view_idx_minus1");
}
}
i++;
} while (modification_of_pic_nums_idc != 3);
}
}
ASSERT(currSlice->redundant_pic_cnt == 0); //!< not support reference index of redundant slices
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET pred_weight_table(H264_SLICE_t *currSlice)
{
RK_S32 se_tmp = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
RK_U32 i = 0, j = 0, temp = 0;
BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx;
READ_UE(ret, p_bitctx, &temp, "log2_weight_denom");
if (currSlice->active_sps->chroma_format_idc)
{
READ_UE(ret, p_bitctx, &temp, "log2_weight_denom");
}
for (i = 0; i < currSlice->num_ref_idx_active[LIST_0]; i++)
{
READ_ONEBIT(ret, p_bitctx, &temp, "luma_weight_flag_l0");
if (temp)
{
READ_SE(ret, p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_0][i][0]
READ_SE(ret, p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_0][i][0]
}
if (currSlice->active_sps->chroma_format_idc)
{
READ_ONEBIT(ret, p_bitctx, &temp, "chroma_weight_flag_l0");
for (j = 1; j < 3; j++)
{
if (temp) //!< chroma_weight_flag_l0
{
READ_SE(ret, p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_0][i][j]
READ_SE(ret, p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_0][i][j]
}
}
}
}
if ((currSlice->slice_type == B_SLICE) && currSlice->p_Vid->active_pps->weighted_bipred_idc == 1)
{
for (i = 0; i < currSlice->num_ref_idx_active[LIST_1]; i++)
{
READ_ONEBIT(ret, p_bitctx, &temp, "luma_weight_flag_l1");
if (temp)
{
READ_SE(ret, p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_1][i][0]
READ_SE(ret, p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_1][i][0]
}
if (currSlice->active_sps->chroma_format_idc)
{
READ_ONEBIT(ret, p_bitctx, &temp, "chroma_weight_flag_l1");
for (j = 1; j < 3; j++)
{
if (temp) // chroma_weight_flag_l1
{
READ_SE(ret, p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_1][i][j]
READ_SE(ret, p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_1][i][j]
}
}
}
}
}
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET dec_ref_pic_marking(H264_SLICE_t *pSlice)
{
RK_U32 val = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
H264_DRPM_t *tmp_drpm = NULL, *tmp_drpm2 = NULL;
H264dVideoCtx_t *p_Vid = pSlice->p_Vid;
BitReadCtx_t *p_bitctx = &pSlice->p_Cur->bitctx;
//!< free old buffer content
free_slice_drpm_buffer(pSlice);
if (pSlice->idr_flag ||
(pSlice->svc_extension_flag == 0 && pSlice->mvcExt.non_idr_flag == 0))
{
READ_ONEBIT(ret, p_bitctx, &pSlice->no_output_of_prior_pics_flag, "no_output_of_prior_pics_flag");
p_Vid->no_output_of_prior_pics_flag = pSlice->no_output_of_prior_pics_flag;
READ_ONEBIT(ret, p_bitctx, &pSlice->long_term_reference_flag, "long_term_reference_flag");
}
else
{
READ_ONEBIT(ret, p_bitctx, &pSlice->adaptive_ref_pic_buffering_flag, "adaptive_ref_pic_buffering_flag");
if (pSlice->adaptive_ref_pic_buffering_flag)
{
do //!< read Memory Management Control Operation
{
tmp_drpm = mpp_calloc(H264_DRPM_t, 1);
MEM_CHECK(ret, tmp_drpm);
tmp_drpm->Next = NULL;
READ_UE(ret, p_bitctx, &val, "memory_management_control_operation");
tmp_drpm->memory_management_control_operation = val;
if ((val == 1) || (val == 3))
{
READ_UE(ret, p_bitctx, &tmp_drpm->difference_of_pic_nums_minus1, "difference_of_pic_nums_minus1");
}
if (val == 2)
{
READ_UE(ret, p_bitctx, &tmp_drpm->long_term_pic_num, "long_term_pic_num");
}
if ((val == 3) || (val == 6))
{
READ_UE(ret, p_bitctx, &tmp_drpm->long_term_frame_idx, "long_term_frame_idx");
}
if (val == 4)
{
READ_UE(ret, p_bitctx, &tmp_drpm->max_long_term_frame_idx_plus1, "max_long_term_frame_idx_plus1");
}
// add command
if (pSlice->dec_ref_pic_marking_buffer == NULL)
{
pSlice->dec_ref_pic_marking_buffer = tmp_drpm;
}
else
{
tmp_drpm2 = pSlice->dec_ref_pic_marking_buffer;
while (tmp_drpm2->Next != NULL)
{
tmp_drpm2 = tmp_drpm2->Next;
}
tmp_drpm2->Next = tmp_drpm;
}
} while (val != 0);
}
}
return ret = MPP_OK;
__FAILED:
return ret;
}
static void init_slice_parmeters(H264_SLICE_t *currSlice)
{
H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
H264_Nalu_t *cur_nalu = &currSlice->p_Cur->nalu;
//--- init slice syntax
currSlice->idr_flag = ((cur_nalu->nal_unit_type == NALU_TYPE_IDR)
|| (currSlice->mvcExt.valid && !currSlice->mvcExt.non_idr_flag));
currSlice->nal_reference_idc = cur_nalu->nal_reference_idc;
if ((!currSlice->svc_extension_flag) || currSlice->mvcExt.iPrefixNALU) // MVC or have prefixNALU
{
currSlice->view_id = currSlice->mvcExt.view_id;
currSlice->inter_view_flag = currSlice->mvcExt.inter_view_flag;
currSlice->anchor_pic_flag = currSlice->mvcExt.anchor_pic_flag;
}
else if (currSlice->svc_extension_flag == -1) // normal AVC
{
currSlice->view_id = currSlice->mvcExt.valid ? p_Vid->active_subsps->view_id[0] : 0;
currSlice->inter_view_flag = 1;
currSlice->anchor_pic_flag = currSlice->idr_flag;
}
currSlice->layer_id = get_voidx(p_Vid->subspsSet, &p_Vid->active_subsps, currSlice->view_id);
if (currSlice->layer_id >= 0) // if not found, layer_id == -1
{
currSlice->p_Dpb = p_Vid->p_Dpb_layer[currSlice->layer_id];
}
}
static MPP_RET set_slice_user_parmeters(H264_SLICE_t *currSlice)
{
MPP_RET ret = MPP_ERR_UNKNOW;
H264_PPS_t *cur_pps = NULL;
H264_SPS_t *cur_sps = NULL;
H264_subSPS_t *cur_subsps = NULL;
H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
//!< use parameter set
cur_pps = &p_Vid->ppsSet[currSlice->pic_parameter_set_id];
ASSERT(cur_pps != NULL);
if (currSlice->mvcExt.valid)
{
cur_sps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id].sps;
cur_subsps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id];
if (cur_subsps->Valid)
{
if ((RK_S32)currSlice->mvcExt.view_id == cur_subsps->view_id[0]) // combine subsps to sps
{
p_Vid->active_mvc_sps_flag = 0;
cur_subsps = NULL;
cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id];
}
else if ((RK_S32)currSlice->mvcExt.view_id == cur_subsps->view_id[1])
{
p_Vid->active_mvc_sps_flag = 1;
}
}
else
{
p_Vid->active_mvc_sps_flag = 0;
cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id];
cur_subsps = NULL;
}
}
else
{
p_Vid->active_mvc_sps_flag = 0;
cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id];
cur_subsps = NULL;
}
ASSERT(cur_sps->separate_colour_plane_flag == 0);
FUN_CHECK(ret = activate_sps(p_Vid, cur_sps, cur_subsps));
FUN_CHECK(ret = activate_pps(p_Vid, cur_pps));
//!< Set SPS to the subset SPS parameters
if (currSlice->svc_extension_flag == 0)
{
p_Vid->active_subsps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id];
}
currSlice->active_sps = p_Vid->active_sps;
currSlice->active_pps = p_Vid->active_pps;
return MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
/*!
***********************************************************************
* \brief
* parse SEI information
***********************************************************************
*/
//extern "C"
void recycle_slice(H264_SLICE_t *currSlice)
{
if (currSlice)
{
free_slice_drpm_buffer(currSlice);
}
}
/*!
***********************************************************************
* \brief
* parse SEI information
***********************************************************************
*/
//extern "C"
MPP_RET process_slice(H264_SLICE_t *currSlice)
{
RK_U32 temp = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
H264dLogCtx_t *logctx = currSlice->logctx;
H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
H264dCurCtx_t *p_Cur = currSlice->p_Cur;
BitReadCtx_t *p_bitctx = &p_Cur->bitctx;
FunctionIn(logctx->parr[RUN_PARSE]);
//--- initial value ----
currSlice->p_Dpb_layer[0] = p_Vid->p_Dpb_layer[0];
currSlice->p_Dpb_layer[1] = p_Vid->p_Dpb_layer[1];
set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SLICE]);
init_slice_parmeters(currSlice);
WRITE_LOG(p_bitctx, "----------------------------- SLICE begin --------------------------------");
//------- read slice head syntax --------
READ_UE(ret, p_bitctx, &currSlice->start_mb_nr, "first_mb_in_slice");
READ_UE(ret, p_bitctx, &temp, "slice_type");
p_Vid->slice_type = currSlice->slice_type = temp % 5;
READ_UE(ret, p_bitctx, &currSlice->pic_parameter_set_id, "slice_pic_parameter_set_id");
FUN_CHECK(ret = set_slice_user_parmeters(currSlice));
//!< read rest slice header syntax
READ_BITS(ret, p_bitctx, currSlice->active_sps->log2_max_frame_num_minus4 + 4, &currSlice->frame_num, "frame_num");
if (currSlice->active_sps->frame_mbs_only_flag) //!< user in_slice info
{
p_Vid->structure = FRAME;
currSlice->field_pic_flag = 0;
currSlice->bottom_field_flag = 0;
}
else
{
READ_ONEBIT(ret, p_bitctx, &currSlice->field_pic_flag, "field_pic_flag");
if (currSlice->field_pic_flag)
{
READ_ONEBIT(ret, p_bitctx, &currSlice->bottom_field_flag, "field_pic_flag");
p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD;
}
else
{
p_Vid->structure = FRAME;
currSlice->bottom_field_flag = 0;
}
}
currSlice->structure = p_Vid->structure;
currSlice->mb_aff_frame_flag = (currSlice->active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag == 0));
if (currSlice->idr_flag)
{
READ_UE(ret, p_bitctx, &currSlice->idr_pic_id, "idr_pic_id");
}
else if (currSlice->svc_extension_flag == 0 && currSlice->mvcExt.non_idr_flag == 0)
{
READ_UE(ret, p_bitctx, &currSlice->idr_pic_id, "idr_pic_id");
}
if (currSlice->active_sps->pic_order_cnt_type == 0)
{
READ_BITS(ret, p_bitctx, currSlice->active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, &currSlice->pic_order_cnt_lsb, "pic_order_cnt_lsb");
if (currSlice->p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1
&& !currSlice->field_pic_flag)
{
READ_SE(ret, p_bitctx, &currSlice->delta_pic_order_cnt_bottom, "delta_pic_order_cnt_bottom");
}
else
{
currSlice->delta_pic_order_cnt_bottom = 0;
}
}
if (currSlice->active_sps->pic_order_cnt_type == 1)
{
if (!currSlice->active_sps->delta_pic_order_always_zero_flag)
{
READ_SE(ret, p_bitctx, &currSlice->delta_pic_order_cnt[0], "delta_pic_order_cnt[0]");
if (currSlice->p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag)
{
READ_SE(ret, p_bitctx, &currSlice->delta_pic_order_cnt[1], "delta_pic_order_cnt[1]");
}
else
{
currSlice->delta_pic_order_cnt[1] = 0; // set to zero if not in stream
}
}
else
{
currSlice->delta_pic_order_cnt[0] = 0;
currSlice->delta_pic_order_cnt[1] = 0;
}
}
//! redundant_pic_cnt is missing here
ASSERT(currSlice->p_Vid->active_pps->redundant_pic_cnt_present_flag == 0); // add by dw, high 4:2:2 profile not support
if (currSlice->p_Vid->active_pps->redundant_pic_cnt_present_flag)
{
READ_UE(ret, p_bitctx, &currSlice->redundant_pic_cnt, "redundant_pic_cnt");
}
if (currSlice->slice_type == B_SLICE)
{
READ_ONEBIT(ret, p_bitctx, &currSlice->direct_spatial_mv_pred_flag, "direct_spatial_mv_pred_flag");
}
else
{
currSlice->direct_spatial_mv_pred_flag = 0;
}
currSlice->num_ref_idx_active[LIST_0] = currSlice->p_Vid->active_pps->num_ref_idx_l0_default_active_minus1 + 1;
currSlice->num_ref_idx_active[LIST_1] = currSlice->p_Vid->active_pps->num_ref_idx_l1_default_active_minus1 + 1;
if (currSlice->slice_type == P_SLICE
|| currSlice->slice_type == SP_SLICE || currSlice->slice_type == B_SLICE)
{
//!< "direct_spatial_mv_pred_flag"
READ_ONEBIT(ret, p_bitctx, &currSlice->num_ref_idx_override_flag, "num_ref_idx_override_flag");
if (currSlice->num_ref_idx_override_flag)
{
READ_UE(ret, p_bitctx, &currSlice->num_ref_idx_active[LIST_0], "num_ref_idx_active0");
currSlice->num_ref_idx_active[LIST_0] += 1;
if (currSlice->slice_type == B_SLICE)
{
READ_UE(ret, p_bitctx, &currSlice->num_ref_idx_active[LIST_1], "num_ref_idx_active1");
currSlice->num_ref_idx_active[LIST_1] += 1;
}
}
}
if (currSlice->slice_type != B_SLICE)
{
currSlice->num_ref_idx_active[LIST_1] = 0;
}
if (is_new_picture(currSlice))
{
FUN_CHECK(ret = ref_pic_list_mvc_modification(currSlice));
if ((currSlice->p_Vid->active_pps->weighted_pred_flag
&& (currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE))
|| (currSlice->p_Vid->active_pps->weighted_bipred_idc == 1 && (currSlice->slice_type == B_SLICE)))
{
FUN_CHECK(ret = pred_weight_table(currSlice));
}
if (currSlice->nal_reference_idc)
{
FUN_CHECK(ret = dec_ref_pic_marking(currSlice));
}
currSlice->is_new_picture_flag = 1;
}
FunctionOut(logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
recycle_slice(currSlice);
return ret;
}

View File

@@ -0,0 +1,39 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __H264D_SLICE_H__
#define __H264D_SLICE_H__
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
void recycle_slice(H264_SLICE_t *currSlice);
MPP_RET process_slice(H264_SLICE_t *currSlice);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of __H264D_SLICE_H__ */

View File

@@ -0,0 +1,592 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "mpp_mem.h"
#include "h264d_log.h"
#include "h264d_bitread.h"
#include "h264d_sps.h"
#include "h264d_scalist.h"
#include "h264d_dpb.h"
#define MODULE_TAG "h264d_sps"
static void reset_cur_sps_data(H264_SPS_t *cur_sps)
{
memset(cur_sps, 0, sizeof(H264_SPS_t));
cur_sps->seq_parameter_set_id = -1; // reset
}
static void reset_cur_subpps_data(H264_subSPS_t *cur_subpps)
{
memset(cur_subpps, 0, sizeof(H264_subSPS_t));
cur_subpps->sps.seq_parameter_set_id = -1; // reset
cur_subpps->num_views_minus1 = -1;
cur_subpps->num_level_values_signalled_minus1 = -1;
}
static MPP_RET read_hrd_parameters(BitReadCtx_t *p_bitctx, H264_HRD_t *hrd)
{
RK_U32 SchedSelIdx = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
READ_UE(ret, p_bitctx, &hrd->cpb_cnt_minus1, "cpb_cnt_minus1");
READ_BITS(ret, p_bitctx, 4, &hrd->bit_rate_scale, "bit_rate_scale");
READ_BITS(ret, p_bitctx, 4, &hrd->cpb_size_scale, "cpb_size_scale");
for (SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++)
{
READ_UE(ret, p_bitctx, &hrd->bit_rate_value_minus1[SchedSelIdx], "VUI: bit_rate_value_minus1");
READ_UE(ret, p_bitctx, &hrd->cpb_size_value_minus1[SchedSelIdx], "VUI: cpb_size_value_minus1");
READ_ONEBIT(ret, p_bitctx, &hrd->cbr_flag[SchedSelIdx], "VUI: cbr_flag");
}
READ_BITS(ret, p_bitctx, 5, &hrd->initial_cpb_removal_delay_length_minus1, "initial_cpb_removal_delay_length_minus1");
READ_BITS(ret, p_bitctx, 5, &hrd->cpb_removal_delay_length_minus1, "cpb_removal_delay_length_minus1");
READ_BITS(ret, p_bitctx, 5, &hrd->dpb_output_delay_length_minus1, "dpb_output_delay_length_minus1");
READ_BITS(ret, p_bitctx, 5, &hrd->time_offset_length, "time_offset_length");
return ret = MPP_OK;
__FAILED:
return ret;
}
static void init_VUI(H264_VUI_t *vui)
{
vui->matrix_coefficients = 2;
}
static MPP_RET read_VUI(BitReadCtx_t *p_bitctx, H264_VUI_t *vui)
{
MPP_RET ret = MPP_ERR_UNKNOW;
READ_ONEBIT(ret, p_bitctx, &vui->aspect_ratio_info_present_flag, "vui.aspect_ratio_info_present_flag");
if (vui->aspect_ratio_info_present_flag)
{
READ_BITS(ret, p_bitctx, 8, &vui->aspect_ratio_idc, "vui.aspect_ratio_idc");
if (255 == vui->aspect_ratio_idc)
{
READ_BITS(ret, p_bitctx, 16, &vui->sar_width, "VUI: sar_width");
READ_BITS(ret, p_bitctx, 16, &vui->sar_height, "VUI: sar_height");
}
}
READ_ONEBIT(ret, p_bitctx, &vui->overscan_info_present_flag, "VUI: overscan_info_present_flag");
if (vui->overscan_info_present_flag)
{
READ_ONEBIT(ret, p_bitctx, &vui->overscan_appropriate_flag, "VUI: overscan_appropriate_flag");
}
READ_ONEBIT(ret, p_bitctx, &vui->video_signal_type_present_flag, "VUI: video_signal_type_present_flag");
if (vui->video_signal_type_present_flag)
{
READ_BITS(ret, p_bitctx, 3, &vui->video_format, "VUI: video_format");
READ_ONEBIT(ret, p_bitctx, &vui->video_full_range_flag, "VUI: video_full_range_flag");
READ_ONEBIT(ret, p_bitctx, &vui->colour_description_present_flag, "VUI: color_description_present_flag");
if (vui->colour_description_present_flag)
{
READ_BITS(ret, p_bitctx, 8, &vui->colour_primaries, "VUI: colour_primaries");
READ_BITS(ret, p_bitctx, 8, &vui->transfer_characteristics, "VUI: transfer_characteristics");
READ_BITS(ret, p_bitctx, 8, &vui->matrix_coefficients, "VUI: matrix_coefficients");
}
}
READ_ONEBIT(ret, p_bitctx, &vui->chroma_location_info_present_flag, "VUI: chroma_location_info_present_flag");
if (vui->chroma_location_info_present_flag)
{
READ_UE(ret, p_bitctx, &vui->chroma_sample_loc_type_top_field, "VUI: chroma_sample_loc_type_top_field");
READ_UE(ret, p_bitctx, &vui->chroma_sample_loc_type_bottom_field, "VUI: chroma_sample_loc_type_bottom_field");
}
READ_ONEBIT(ret, p_bitctx, &vui->timing_info_present_flag, "VUI: timing_info_present_flag");
if (vui->timing_info_present_flag)
{
READ_BITS(ret, p_bitctx, 16, &vui->num_units_in_tick, "VUI: num_units_in_tick(high 16bit)");
READ_BITS(ret, p_bitctx, 16, &vui->num_units_in_tick, "VUI: num_units_in_tick(low 16bit)");
READ_BITS(ret, p_bitctx, 16, &vui->time_scale, "VUI: time_scale(high 16bit)");
READ_BITS(ret, p_bitctx, 16, &vui->time_scale, "VUI: time_scale(low 16bit)");
READ_ONEBIT(ret, p_bitctx, &vui->fixed_frame_rate_flag, "VUI: fixed_frame_rate_flag");
}
READ_ONEBIT(ret, p_bitctx, &vui->nal_hrd_parameters_present_flag, "VUI: nal_hrd_parameters_present_flag");
if (vui->nal_hrd_parameters_present_flag)
{
FUN_CHECK(ret = read_hrd_parameters(p_bitctx, &vui->nal_hrd_parameters));
}
READ_ONEBIT(ret, p_bitctx, &vui->vcl_hrd_parameters_present_flag, "VUI: vcl_hrd_parameters_present_flag");
if (vui->vcl_hrd_parameters_present_flag)
{
FUN_CHECK(ret = read_hrd_parameters(p_bitctx, &vui->vcl_hrd_parameters));
}
if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag)
{
READ_ONEBIT(ret, p_bitctx, &vui->low_delay_hrd_flag, "VUI: low_delay_hrd_flag");
}
READ_ONEBIT(ret, p_bitctx, &vui->pic_struct_present_flag, "VUI: pic_struct_present_flag");
READ_ONEBIT(ret, p_bitctx, &vui->bitstream_restriction_flag, "VUI: bitstream_restriction_flag");
if (vui->bitstream_restriction_flag)
{
READ_ONEBIT(ret, p_bitctx, &vui->motion_vectors_over_pic_boundaries_flag, "VUI: motion_vectors_over_pic_boundaries_flag");
READ_UE(ret, p_bitctx, &vui->max_bytes_per_pic_denom, "VUI: max_bytes_per_pic_denom");
READ_UE(ret, p_bitctx, &vui->max_bits_per_mb_denom, "VUI: max_bits_per_mb_denom");
READ_UE(ret, p_bitctx, &vui->log2_max_mv_length_horizontal, "VUI: log2_max_mv_length_horizontal");
READ_UE(ret, p_bitctx, &vui->log2_max_mv_length_vertical, "VUI: log2_max_mv_length_vertical");
READ_UE(ret, p_bitctx, &vui->num_reorder_frames, "VUI: num_reorder_frames");
READ_UE(ret, p_bitctx, &vui->max_dec_frame_buffering, "VUI: max_dec_frame_buffering");
}
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET parser_sps(BitReadCtx_t *p_bitctx, H264_SPS_t *cur_sps)
{
RK_S32 i = 0, temp = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
//!< init Fidelity Range Extensions stuff
cur_sps->chroma_format_idc = 1;
cur_sps->bit_depth_luma_minus8 = 0;
cur_sps->bit_depth_chroma_minus8 = 0;
cur_sps->qpprime_y_zero_transform_bypass_flag = 0;
cur_sps->separate_colour_plane_flag = 0;
cur_sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
cur_sps->delta_pic_order_always_zero_flag = 0;
WRITE_LOG(p_bitctx, "----------------------------- SPS begin --------------------------------");
READ_BITS(ret, p_bitctx, 8, &cur_sps->profile_idc, "profile_idc");
VAL_CHECK (ret, (cur_sps->profile_idc == BASELINE) || (cur_sps->profile_idc == H264_MAIN)
|| (cur_sps->profile_idc == EXTENDED) || (cur_sps->profile_idc == FREXT_HP)
|| (cur_sps->profile_idc == FREXT_Hi10P) || (cur_sps->profile_idc == FREXT_Hi422)
|| (cur_sps->profile_idc == FREXT_Hi444) || (cur_sps->profile_idc == FREXT_CAVLC444)
|| (cur_sps->profile_idc == MVC_HIGH) || (cur_sps->profile_idc == STEREO_HIGH)
);
READ_ONEBIT(ret, p_bitctx, &cur_sps->constrained_set0_flag, "constrained_set0_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->constrained_set1_flag, "constrained_set1_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->constrained_set2_flag, "constrained_set2_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->constrained_set3_flag, "constrained_set3_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->constrained_set4_flag, "constrained_set4_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->constrained_set5_flag, "constrained_set5_flag");
READ_BITS(ret, p_bitctx, 2, &temp, "reserved_zero_2bits"); // reserved_zero_2bits
ASSERT(temp == 0);
READ_BITS(ret, p_bitctx, 8, &cur_sps->level_idc, "level_idc");
READ_UE(ret, p_bitctx, &cur_sps->seq_parameter_set_id, "seq_parameter_set_id");
ASSERT(cur_sps->seq_parameter_set_id < 32);
if (cur_sps->profile_idc == 100 || cur_sps->profile_idc == 110
|| cur_sps->profile_idc == 122 || cur_sps->profile_idc == 244
|| cur_sps->profile_idc == 44 || cur_sps->profile_idc == 83
|| cur_sps->profile_idc == 86 || cur_sps->profile_idc == 118
|| cur_sps->profile_idc == 128 || cur_sps->profile_idc == 138)
{
READ_UE(ret, p_bitctx, &cur_sps->chroma_format_idc, "chroma_format_idc");
ASSERT(cur_sps->chroma_format_idc < 4);
if (cur_sps->chroma_format_idc == 3)
{
READ_ONEBIT(ret, p_bitctx, &cur_sps->separate_colour_plane_flag, "separate_colour_plane_flag");
LogError(p_bitctx->ctx, "Not support YUV444 format current.");
}
READ_UE(ret, p_bitctx, &cur_sps->bit_depth_luma_minus8, "bit_depth_luma_minus8");
ASSERT(cur_sps->bit_depth_luma_minus8 < 7);
READ_UE(ret, p_bitctx, &cur_sps->bit_depth_chroma_minus8, "bit_depth_chroma_minus8");
ASSERT(cur_sps->bit_depth_chroma_minus8 < 7);
READ_ONEBIT(ret, p_bitctx, &cur_sps->qpprime_y_zero_transform_bypass_flag, "qpprime_y_zero_transform_bypass_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->seq_scaling_matrix_present_flag, "seq_scaling_matrix_present_flag");
if (cur_sps->seq_scaling_matrix_present_flag)
{
LogInfo(p_bitctx->ctx, "Scaling matrix present.");
if (parse_sps_scalinglists(p_bitctx, cur_sps))
{
LogError(p_bitctx->ctx, "rkv_parse_sps_scalinglists error.");
}
}
}
READ_UE(ret, p_bitctx, &cur_sps->log2_max_frame_num_minus4, "log2_max_frame_num_minus4");
ASSERT(cur_sps->log2_max_frame_num_minus4 < 13);
READ_UE(ret, p_bitctx, &cur_sps->pic_order_cnt_type, "pic_order_cnt_type");
ASSERT(cur_sps->pic_order_cnt_type < 3);
cur_sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
cur_sps->delta_pic_order_always_zero_flag = RET_FALSE;
if (0 == cur_sps->pic_order_cnt_type)
{
READ_UE(ret, p_bitctx, &cur_sps->log2_max_pic_order_cnt_lsb_minus4, "log2_max_pic_order_cnt_lsb_minus4");
ASSERT(cur_sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
}
else if (1 == cur_sps->pic_order_cnt_type)
{
READ_ONEBIT(ret, p_bitctx, &cur_sps->delta_pic_order_always_zero_flag, "delta_pic_order_always_zero_flag");
READ_SE(ret, p_bitctx, &cur_sps->offset_for_non_ref_pic, "offset_for_non_ref_pic");
READ_SE(ret, p_bitctx, &cur_sps->offset_for_top_to_bottom_field, "offset_for_top_to_bottom_field");
READ_UE(ret, p_bitctx, &cur_sps->num_ref_frames_in_pic_order_cnt_cycle, "num_ref_frames_in_pic_order_cnt_cycle");
ASSERT(cur_sps->num_ref_frames_in_pic_order_cnt_cycle < 256);
for (i = 0; i < cur_sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
{
READ_SE(ret, p_bitctx, &cur_sps->offset_for_ref_frame[i], "offset_for_ref_frame");
cur_sps->expected_delta_per_pic_order_cnt_cycle += cur_sps->offset_for_ref_frame[i];
}
}
READ_UE(ret, p_bitctx, &cur_sps->max_num_ref_frames, "max_num_ref_frames");
READ_ONEBIT(ret, p_bitctx, &cur_sps->gaps_in_frame_num_value_allowed_flag, "gaps_in_frame_num_value_allowed_flag");
READ_UE(ret, p_bitctx, &cur_sps->pic_width_in_mbs_minus1, "pic_width_in_mbs_minus1");
READ_UE(ret, p_bitctx, &cur_sps->pic_height_in_map_units_minus1, "pic_height_in_map_units_minus1");
READ_ONEBIT(ret, p_bitctx, &cur_sps->frame_mbs_only_flag, "frame_mbs_only_flag");
if (!cur_sps->frame_mbs_only_flag)
{
READ_ONEBIT(ret, p_bitctx, &cur_sps->mb_adaptive_frame_field_flag, "mb_adaptive_frame_field_flag");
}
READ_ONEBIT(ret, p_bitctx, &cur_sps->direct_8x8_inference_flag, "direct_8x8_inference_flag");
READ_ONEBIT(ret, p_bitctx, &cur_sps->frame_cropping_flag, "frame_cropping_flag");
if (cur_sps->frame_cropping_flag)
{
READ_UE(ret, p_bitctx, &cur_sps->frame_crop_left_offset, "frame_crop_left_offset");
READ_UE(ret, p_bitctx, &cur_sps->frame_crop_right_offset, "frame_crop_right_offset");
READ_UE(ret, p_bitctx, &cur_sps->frame_crop_top_offset, "frame_crop_top_offset");
READ_UE(ret, p_bitctx, &cur_sps->frame_crop_bottom_offset, "frame_crop_bottom_offset");
}
READ_ONEBIT(ret, p_bitctx, &cur_sps->vui_parameters_present_flag, "vui_parameters_present_flag");
init_VUI(&cur_sps->vui_seq_parameters);
if (cur_sps->vui_parameters_present_flag)
{
FUN_CHECK(ret = read_VUI(p_bitctx, &cur_sps->vui_seq_parameters));
}
cur_sps->Valid = 1;
return ret = MPP_OK;
__FAILED:
return ret;
}
static MPP_RET sps_mvc_extension(BitReadCtx_t *p_bitctx, H264_subSPS_t *subset_sps)
{
MPP_RET ret = MPP_ERR_UNKNOW;
RK_S32 i = 0, j = 0, num_views = 0;
READ_UE(ret, p_bitctx, &subset_sps->num_views_minus1, "SPS_MVC_EXT:num_views_minus1");
num_views = 1 + subset_sps->num_views_minus1;
//========================
if (num_views > 0)
{
subset_sps->view_id = mpp_calloc(RK_S32, num_views);
subset_sps->num_anchor_refs_l0 = mpp_calloc(RK_S32, num_views);
subset_sps->num_anchor_refs_l1 = mpp_calloc(RK_S32, num_views);
subset_sps->anchor_ref_l0 = mpp_calloc(RK_S32*, num_views);
subset_sps->anchor_ref_l1 = mpp_calloc(RK_S32*, num_views);
subset_sps->num_non_anchor_refs_l0 = mpp_calloc(RK_S32, num_views);
subset_sps->num_non_anchor_refs_l1 = mpp_calloc(RK_S32, num_views);
subset_sps->non_anchor_ref_l0 = mpp_calloc(RK_S32*, num_views);
subset_sps->non_anchor_ref_l1 = mpp_calloc(RK_S32*, num_views);
MEM_CHECK(ret, subset_sps->view_id && subset_sps->num_anchor_refs_l0
&& subset_sps->num_anchor_refs_l1 && subset_sps->anchor_ref_l0
&& subset_sps->anchor_ref_l1 && subset_sps->num_non_anchor_refs_l0
&& subset_sps->num_non_anchor_refs_l1 && subset_sps->non_anchor_ref_l0
&& subset_sps->non_anchor_ref_l1);
}
for (i = 0; i < num_views; i++)
{
READ_UE(ret, p_bitctx, &subset_sps->view_id[i], "SPS_MVC_EXT: view_id");
}
for (i = 1; i < num_views; i++)
{
READ_UE(ret, p_bitctx, &subset_sps->num_anchor_refs_l0[i], "SPS_MVC_EXT: num_anchor_refs_l0");
if (subset_sps->num_anchor_refs_l0[i])
{
subset_sps->anchor_ref_l0[i] = mpp_calloc(RK_S32, subset_sps->num_anchor_refs_l0[i]);
MEM_CHECK(ret, subset_sps->anchor_ref_l0[i]);
for (j = 0; j < subset_sps->num_anchor_refs_l0[i]; j++)
{
READ_UE(ret, p_bitctx, &subset_sps->anchor_ref_l0[i][j], "SPS_MVC_EXT: anchor_ref_l0");
}
}
READ_UE(ret, p_bitctx, &subset_sps->num_anchor_refs_l1[i], "SPS_MVC_EXT: num_anchor_refs_l1");
if (subset_sps->num_anchor_refs_l1[i])
{
subset_sps->anchor_ref_l1[i] = mpp_calloc(RK_S32, subset_sps->num_anchor_refs_l1[i]);
MEM_CHECK(ret, subset_sps->anchor_ref_l1[i]);
for (j = 0; j < subset_sps->num_anchor_refs_l1[i]; j++)
{
READ_UE(ret, p_bitctx, &subset_sps->anchor_ref_l1[i][j], "SPS_MVC_EXT: anchor_ref_l0");
}
}
}
for (i = 1; i < num_views; i++)
{
READ_UE(ret, p_bitctx, &subset_sps->num_non_anchor_refs_l0[i], "SPS_MVC_EXT: num_non_anchor_refs_l0");
if (subset_sps->num_non_anchor_refs_l0[i])
{
subset_sps->non_anchor_ref_l0[i] = mpp_calloc(RK_S32, subset_sps->num_non_anchor_refs_l0[i]);
MEM_CHECK(ret, subset_sps->non_anchor_ref_l0[i]);
for (j = 0; j < subset_sps->num_non_anchor_refs_l0[i]; j++)
{
READ_UE(ret, p_bitctx, &subset_sps->non_anchor_ref_l0[i][j], "SPS_MVC_EXT: non_anchor_ref_l0");
}
}
READ_UE(ret, p_bitctx, &subset_sps->num_non_anchor_refs_l1[i], "SPS_MVC_EXT: num_non_anchor_refs_l1");
if (subset_sps->num_non_anchor_refs_l1[i])
{
subset_sps->non_anchor_ref_l1[i] = mpp_calloc(RK_S32, subset_sps->num_non_anchor_refs_l1[i]);
MEM_CHECK(ret, subset_sps->non_anchor_ref_l1[i]);
for (j = 0; j < subset_sps->num_non_anchor_refs_l1[i]; j++)
{
READ_UE(ret, p_bitctx, &subset_sps->non_anchor_ref_l1[i][j], "SPS_MVC_EXT: non_anchor_ref_l1");
}
}
}
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
static MPP_RET parser_subsps_ext(BitReadCtx_t *p_bitctx, H264_subSPS_t *cur_subsps)
{
MPP_RET ret = MPP_ERR_UNKNOW;
if ((cur_subsps->sps.profile_idc == MVC_HIGH)
|| (cur_subsps->sps.profile_idc == STEREO_HIGH))
{
READ_ONEBIT(ret, p_bitctx, &cur_subsps->bit_equal_to_one, "bit_equal_to_one");
ASSERT(cur_subsps->bit_equal_to_one == 1);
FUN_CHECK(ret = sps_mvc_extension(p_bitctx, cur_subsps));
READ_ONEBIT(ret, p_bitctx, &cur_subsps->mvc_vui_parameters_present_flag, "mvc_vui_parameters_present_flag");
}
return ret = MPP_OK;
__FAILED:
return ret;
}
static void update_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps)
{
p_Vid->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
p_Vid->PicWidthInMbs = (sps->pic_width_in_mbs_minus1 + 1);
p_Vid->FrameHeightInMbs = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1);
p_Vid->yuv_format = sps->chroma_format_idc;
p_Vid->width = p_Vid->PicWidthInMbs * MB_BLOCK_SIZE;
p_Vid->height = p_Vid->FrameHeightInMbs * MB_BLOCK_SIZE;
if (p_Vid->yuv_format == YUV420)
{
p_Vid->width_cr = (p_Vid->width >> 1);
p_Vid->height_cr = (p_Vid->height >> 1);
}
else if (p_Vid->yuv_format == YUV422)
{
p_Vid->width_cr = (p_Vid->width >> 1);
p_Vid->height_cr = p_Vid->height;
}
}
static RK_U32 video_pars_changed(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, RK_U8 layer_id)
{
RK_U32 ret = 0;
ret |= p_Vid->p_Dpb_layer[layer_id]->num_ref_frames != sps->max_num_ref_frames;
ret |= p_Vid->last_pic_width_in_mbs_minus1[layer_id] != sps->pic_width_in_mbs_minus1;
ret |= p_Vid->last_pic_height_in_map_units_minus1[layer_id] != sps->pic_height_in_map_units_minus1;
ret |= p_Vid->last_profile_idc[layer_id] != sps->profile_idc;
ret |= p_Vid->last_level_idc[layer_id] != sps->level_idc;
ret |= !p_Vid->p_Dpb_layer[layer_id]->init_done;
return ret;
}
static void update_last_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, RK_U8 layer_id)
{
p_Vid->last_pic_width_in_mbs_minus1[layer_id] = sps->pic_width_in_mbs_minus1;
p_Vid->last_pic_height_in_map_units_minus1[layer_id] = sps->pic_height_in_map_units_minus1;
p_Vid->last_profile_idc[layer_id] = sps->profile_idc;
p_Vid->last_level_idc[layer_id] = sps->level_idc;
}
/*!
***********************************************************************
* \brief
* prase sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET process_sps(H264_SLICE_t *currSlice)
{
MPP_RET ret = MPP_ERR_UNKNOW;
H264dLogCtx_t *logctx = currSlice->logctx;
H264dCurCtx_t *p_Cur = currSlice->p_Cur;
BitReadCtx_t *p_bitctx = &p_Cur->bitctx;
H264_SPS_t *cur_sps = &p_Cur->sps;
FunctionIn(logctx->parr[RUN_PARSE]);
reset_cur_sps_data(cur_sps); // reset
set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SPS]);
//!< parse sps
FUN_CHECK(ret = parser_sps(p_bitctx, cur_sps));
//!< decide "max_dec_frame_buffering" for DPB
FUN_CHECK(ret = get_max_dec_frame_buf_size(cur_sps));
//!< make SPS available, copy
if (cur_sps->Valid)
{
memcpy(&currSlice->p_Vid->spsSet[cur_sps->seq_parameter_set_id], cur_sps, sizeof(H264_SPS_t));
}
FunctionOut(logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
ASSERT(0);
return ret;
}
/*!
***********************************************************************
* \brief
* prase sps and process sps
***********************************************************************
*/
//extern "C"
void recycle_subsps(H264_subSPS_t *subset_sps)
{
RK_S32 i = 0, num_views = 0;
num_views = 1 + subset_sps->num_views_minus1;
for (i = 1; i<num_views; i++)
{
if (subset_sps->num_anchor_refs_l0[i] > 0)
{
mpp_free(subset_sps->anchor_ref_l0[i]);
}
if (subset_sps->num_anchor_refs_l1[i] > 0)
{
mpp_free(subset_sps->anchor_ref_l1[i]);
}
if (subset_sps->num_non_anchor_refs_l0[i] > 0)
{
mpp_free(subset_sps->non_anchor_ref_l0[i]);
}
if (subset_sps->num_non_anchor_refs_l1[i] > 0)
{
mpp_free(subset_sps->non_anchor_ref_l1[i]);
}
}
if (num_views > 0)
{
mpp_free(subset_sps->view_id);
mpp_free(subset_sps->num_anchor_refs_l0);
mpp_free(subset_sps->num_anchor_refs_l1);
mpp_free(subset_sps->anchor_ref_l0);
mpp_free(subset_sps->anchor_ref_l1);
mpp_free(subset_sps->num_non_anchor_refs_l0);
mpp_free(subset_sps->num_non_anchor_refs_l1);
mpp_free(subset_sps->non_anchor_ref_l0);
mpp_free(subset_sps->non_anchor_ref_l1);
}
subset_sps->Valid = 0;
}
/*!
***********************************************************************
* \brief
* prase sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET process_subsps(H264_SLICE_t *currSlice)
{
MPP_RET ret = MPP_ERR_UNKNOW;
H264dLogCtx_t *logctx = currSlice->logctx;
BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx;
H264_subSPS_t *cur_subsps = &currSlice->p_Cur->subsps;
H264_subSPS_t *p_subset = NULL;
FunctionIn(logctx->parr[RUN_PARSE]);
reset_cur_subpps_data(cur_subsps); //reset
set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SUBSPS]);
WRITE_LOG(p_bitctx, "----------------------------- subSPS begin --------------------------------");
FUN_CHECK(ret = parser_sps(p_bitctx, &cur_subsps->sps));
FUN_CHECK(ret = parser_subsps_ext(p_bitctx, cur_subsps));
if (cur_subsps->sps.Valid)
{
cur_subsps->Valid = 1;
currSlice->p_Vid->profile_idc = cur_subsps->sps.profile_idc;
}
get_max_dec_frame_buf_size(&cur_subsps->sps);
//!< make subSPS available
p_subset = &currSlice->p_Vid->subspsSet[cur_subsps->sps.seq_parameter_set_id];
if (p_subset->Valid)
{
recycle_subsps(p_subset);
}
memcpy(p_subset, cur_subsps, sizeof(H264_subSPS_t));
FunctionOut(logctx->parr[RUN_PARSE]);
return ret = MPP_OK;
__FAILED:
recycle_subsps(&currSlice->p_Cur->subsps);
//ASSERT(0);
return ret;
}
/*!
***********************************************************************
* \brief
* prase sps and process sps
***********************************************************************
*/
//extern "C"
MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *subset_sps)
{
MPP_RET ret = MPP_ERR_UNKNOW;
if (p_Vid->dec_picture)
{
FUN_CHECK(ret = exit_picture(p_Vid, &p_Vid->dec_picture));
}
if (p_Vid->active_mvc_sps_flag) // layer_id == 1
{
p_Vid->active_sps = &subset_sps->sps;
p_Vid->active_subsps = subset_sps;
p_Vid->active_sps_id[0] = 0;
p_Vid->active_sps_id[1] = subset_sps->sps.seq_parameter_set_id;
if (video_pars_changed(p_Vid, p_Vid->active_sps, 1))
{
FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[1]));
FUN_CHECK(ret = init_dpb(p_Vid, p_Vid->p_Dpb_layer[1], 2));
update_last_video_pars(p_Vid, p_Vid->active_sps, 1);
}
}
else //!< layer_id == 0
{
p_Vid->active_sps = sps;
p_Vid->active_subsps = NULL;
p_Vid->active_sps_id[0] = sps->seq_parameter_set_id;
p_Vid->active_sps_id[1] = 0;
if (video_pars_changed(p_Vid, p_Vid->active_sps, 0))
{
if (!p_Vid->no_output_of_prior_pics_flag)
{
FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[0]));
}
FUN_CHECK(ret = init_dpb(p_Vid, p_Vid->p_Dpb_layer[0], 1));
update_last_video_pars(p_Vid, p_Vid->active_sps, 0);
}
}
update_video_pars(p_Vid, p_Vid->active_sps);
return ret = MPP_OK;
__FAILED:
return ret;
}

View File

@@ -0,0 +1,41 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _H264D_SPS_H_
#define _H264D_SPS_H_
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_global.h"
#ifdef __cplusplus
extern "C" {
#endif
MPP_RET process_sps (H264_SLICE_t *currSlice);
void recycle_subsps(H264_subSPS_t *subset_sps);
MPP_RET process_subsps(H264_SLICE_t *currSlice);
MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *subset_sps);
#ifdef __cplusplus
}
#endif
//========================================
#endif /* end of _H264D_SPS_H_ */

View File

@@ -18,6 +18,8 @@
#define __H264D_LOG_H__ #define __H264D_LOG_H__
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include "rk_type.h" #include "rk_type.h"
#include "mpp_err.h" #include "mpp_err.h"
@@ -34,6 +36,8 @@ typedef enum {
RET_TURE = 1, RET_TURE = 1,
} RET_tpye; } RET_tpye;
//!< get bit value
#define GetBitVal(val, pos) ( ( (val)>>(pos) ) & 0x1 & (val) )
//!< marco //!< marco
#define ASSERT assert #define ASSERT assert
#define FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) #define FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0)
@@ -110,53 +114,111 @@ typedef struct log_env_ctx_t {
FILE *fp_run_hal; FILE *fp_run_hal;
} LogEnv_t; } LogEnv_t;
typedef struct h264d_logctx_t { typedef struct h264d_logctx_t {
LogEnv_t env; LogEnv_t env;
LogFlag_t log_flag; LogFlag_t log_flag;
LogCtx_t *parr[LOG_MAX]; LogCtx_t *parr[LOG_MAX];
} H264dLogCtx_t; } H264dLogCtx_t;
//!< write log //!< write log
#define LogEnable(ctx, loglevel) ( ctx && ctx->flag->debug_en && (ctx->flag->level & loglevel) ) #define LogEnable(ctx, loglevel) ( ctx && ctx->flag->debug_en && (ctx->flag->level & loglevel) )
#define LogTrace(ctx, ...) do{ if(LogEnable(ctx, LOG_LEVEL_TRACE))\ #define LogTrace(ctx, ...)\
writelog(ctx, __FILE__, __LINE__, "TRACE", __VA_ARGS__); }while (0) do{ if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\
#define LogInfo(ctx, ...) do{ if(LogEnable(ctx, LOG_LEVEL_INFO))\ writelog(ctx, __FILE__, __LINE__, "TRACE", __VA_ARGS__);\
writelog(ctx, __FILE__, __LINE__, "INFO", __VA_ARGS__); }while (0) } }while (0)
#define LogWarnning(ctx, ...) do{ if(LogEnable(ctx, LOG_LEVEL_WARNNING))\ #define LogInfo(ctx, ...)\
writelog(ctx, __FILE__, __LINE__, "WARNNING", __VA_ARGS__); }while (0) do{ if(LogEnable(ctx, LOG_LEVEL_INFO)) {\
#define LogError(ctx, ...) do{ if(LogEnable(ctx, LOG_LEVEL_ERROR))\ writelog(ctx, __FILE__, __LINE__, "INFO", __VA_ARGS__);\
writelog(ctx, __FILE__, __LINE__, "ERROR", __VA_ARGS__); ASSERT(0); }while (0) } }while (0)
#define LogFatal(ctx, ...) do{ if(LogEnable(ctx, LOG_LEVEL_ERROR))\
writelog(ctx, __FILE__, __LINE__, "FATAL", __VA_ARGS__); ASSERT(0); }while (0) #define LogWarnning(ctx, ...)\
#define FunctionIn(ctx) do{ if(LogEnable(ctx, LOG_LEVEL_TRACE))\ do{ if(LogEnable(ctx, LOG_LEVEL_WARNNING)) {\
writelog(ctx, __FILE__, __LINE__, "FunIn", __FUNCTION__); } while (0) writelog(ctx, __FILE__, __LINE__, "WARNNING", __VA_ARGS__);\
#define FunctionOut(ctx) do{if(LogEnable(ctx, LOG_LEVEL_TRACE))\ } }while (0)
writelog(ctx, __FILE__, __LINE__, "FunOut", __FUNCTION__); } while (0)
#define LogError(ctx, ...)\
do{ if(LogEnable(ctx, LOG_LEVEL_ERROR)) {\
writelog(ctx, __FILE__, __LINE__, "ERROR", __VA_ARGS__);\
ASSERT(0);\
} }while (0)
#define LogFatal(ctx, ...)\
do{ if(LogEnable(ctx, LOG_LEVEL_ERROR)) {\
writelog(ctx, __FILE__, __LINE__, "FATAL", __VA_ARGS__);\
ASSERT(0);\
} }while (0)
#define FunctionIn(ctx)\
do{ if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\
writelog(ctx, __FILE__, __LINE__, "FunIn", __FUNCTION__);\
} } while (0)
#define FunctionOut(ctx)\
do{if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\
writelog(ctx, __FILE__, __LINE__, "FunOut", __FUNCTION__);\
} } while (0)
#define __RETURN __Ret #define __RETURN __Return
#define __FAILED __failed #define __FAILED __failed
#define VAL_CHECK(val) do{ if(!(val)) goto __FAILED; } while (0) //!< vaule check #define VAL_CHECK(ret, val)\
#define FUN_CHECK(val) do{ if((val)) goto __FAILED; } while (0) //!< function return check do{ if(!(val)){\
#define MEM_CHECK(val) do{ if(!(val)) goto __FAILED; } while (0) //!< memory check ret = MPP_ERR_VALUE;\
#define FLE_CHECK(val) do{ if(!(val)) goto __FAILED; } while (0) //!< file check fprintf(stderr, "ERROR: value error.\n");\
#define INP_CHECK(val) do{ if((val)) goto __RETURN; } while (0) //!< input check goto __FAILED;\
} } while (0) //!< vaule check
//!< memory malloc check
#define MEM_CHECK(ret, val)\
do{ if(!(val)) {\
ret = MPP_ERR_MALLOC;\
fprintf(stderr, "ERROR: malloc buffer.\n");\
ASSERT(0); goto __FAILED;\
} } while (0)
//!< file check
#define FLE_CHECK(ret, val)\
do{ if(!(val)) {\
ret = MPP_ERR_OPEN_FILE;\
fprintf(stderr, "ERROR: open file.\n");\
ASSERT(0); goto __FAILED;\
} } while (0)
//!< input check
#define INP_CHECK(ret, ctx, val)\
do{ if((val)) {\
ret = MPP_ERR_INIT;\
fprintf(stderr, "ERROR: input empty.\n");\
goto __RETURN;\
} } while (0)
//!< function return check
#define FUN_CHECK(val)\
do{ if((val) < 0) {\
goto __FAILED;\
} } while (0)
#define FPRINT(fp, ...) { if (fp) { fprintf(fp, ## __VA_ARGS__); fflush(fp);} }
extern RK_U32 g_nalu_cnt;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern const LogEnvStr_t logenv_name; extern const LogEnvStr_t logenv_name;
extern const char *logctrl_name[LOG_MAX];
extern const char *loglevel_name[LOG_LEVEL_MAX];
MPP_RET h264d_log_init (H264dLogCtx_t *logctx, LogCtx_t *logbuf); MPP_RET get_logenv(LogEnv_t *env);
MPP_RET h264d_log_deinit(H264dLogCtx_t *logctx); void print_env_help(LogEnv_t *env);
void show_env_flags(LogEnv_t *env);
MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag);
void writelog(LogCtx_t *ctx, char *fname, RK_U32 line, char *loglevel, const char *msg, ...); void writelog(LogCtx_t *ctx, char *fname, RK_U32 line, char *loglevel, const char *msg, ...);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -413,7 +413,7 @@ typedef struct _DXVA_PicParams_H264_MVC {
typedef struct h264d_syntax_t { typedef struct h264d_syntax_t {
RK_U32 num; RK_U32 num;
DXVA2_DecodeBufferDesc *buf; DXVA2_DecodeBufferDesc *buf;
} H264D_Syntax_t; } H264dSyntax_t;
#endif /*__H264D_SYNTAX_H__*/ #endif /*__H264D_SYNTAX_H__*/

View File

@@ -19,312 +19,11 @@
#ifndef __HAL_H264D_API_H__ #ifndef __HAL_H264D_API_H__
#define __HAL_H264D_API_H__ #define __HAL_H264D_API_H__
#include "rk_type.h"
#include "mpp_err.h"
#include "mpp_hal.h" #include "mpp_hal.h"
typedef struct h264_mmu_t {
RK_U32 mmu_dte_addr;
struct {
RK_U32 pageing_enabled : 1;
RK_U32 page_fault_active : 1;
RK_U32 stail_active : 1;
RK_U32 mmu_idle : 1;
RK_U32 replay_buffer_empty1 : 1;
RK_U32 page_fault_is_write : 1;
RK_U32 page_fault_bus_id : 5;
RK_U32 reserve : 8;
//RK_U32 field0000 : 1;
} mmu_status;
struct {
RK_U32 mmu_cmd : 3;
RK_U32 field0000 : 1;
} mmu_cmd;
RK_U32 page_fault_addr;
RK_U32 mmu_zap_one_line;
struct int_rawstat {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} raw_stat;
struct int_clear {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} clear;
struct int_mask {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} mask;
struct int_status {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} status;
RK_U32 mmu_auto_gating : 1;
} H264_MMU_t;
typedef struct h264_cache_t {
struct st_version {
RK_U32 version_minor : 8;
RK_U32 version_major : 8;
RK_U32 product_id : 16;
} version;
struct st_size {
RK_U32 line_size : 8;
RK_U32 associativity : 8;
RK_U32 cache_size : 8;
RK_U32 external_bus_width : 8;
} size;
struct st_status {
RK_U32 cmd_busy : 1;
RK_U32 data_busy : 1;
} status;
struct st_command {
RK_U32 command : 4;
RK_U32 sw_addrb_sel : 2;
} command;
RK_U32 clear_page;
RK_U32 max_reads : 5;
struct st_enable {
RK_U32 permit_cacheable_access : 1;
RK_U32 permit_cach_read_allocate : 1;
RK_U32 sw_readbuffer_counter_reject_en : 1;
RK_U32 sw_cache_clk_disgate : 1;
RK_U32 sw_cache_linsize : 1;
} enable;
RK_U32 perfcnt_src0;
RK_U32 perfcnt_val0;
RK_U32 perfcnt_src1;
RK_U32 perfcnt_val1;
} H264_CACHE_t;
typedef struct h264_regs_t {
struct {
RK_U32 minor_ver : 8;
RK_U32 level : 1;
RK_U32 dec_support : 3;
RK_U32 profile : 1;
RK_U32 reserve0 : 1;
RK_U32 codec_flag : 1;
RK_U32 reserve1 : 1;
RK_U32 prod_num : 16;
} swreg0_id;
struct {
RK_U32 sw_dec_e : 1;//0
RK_U32 sw_dec_clkgate_e : 1; // 1
RK_U32 reserve0 : 1;// 2
RK_U32 sw_timeout_mode : 1; // 3
RK_U32 sw_dec_irq_dis : 1;//4 // 4
RK_U32 sw_dec_timeout_e : 1; //5
RK_U32 sw_buf_empty_en : 1; // 6
RK_U32 sw_stmerror_waitdecfifo_empty : 1; // 7
RK_U32 sw_dec_irq : 1; // 8
RK_U32 sw_dec_irq_raw : 1; // 9
RK_U32 reserve2 : 2;
RK_U32 sw_dec_rdy_sta : 1; //12
RK_U32 sw_dec_bus_sta : 1; //13
RK_U32 sw_dec_error_sta : 1; // 14
RK_U32 sw_dec_timeout_sta : 1; //15
RK_U32 sw_dec_empty_sta : 1; // 16
RK_U32 sw_colmv_ref_error_sta : 1; // 17
RK_U32 sw_cabu_end_sta : 1; // 18
RK_U32 sw_h264orvp9_error_mode : 1; //19
RK_U32 sw_softrst_en_p : 1; //20
RK_U32 sw_force_softreset_valid : 1; //21
RK_U32 sw_softreset_rdy : 1; // 22
} swreg1_int;
struct {
RK_U32 sw_in_endian : 1;
RK_U32 sw_in_swap32_e : 1;
RK_U32 sw_in_swap64_e : 1;
RK_U32 sw_str_endian : 1;
RK_U32 sw_str_swap32_e : 1;
RK_U32 sw_str_swap64_e : 1;
RK_U32 sw_out_endian : 1;
RK_U32 sw_out_swap32_e : 1;
RK_U32 sw_out_cbcr_swap : 1;
RK_U32 reserve0 : 1;
RK_U32 sw_rlc_mode_direct_write : 1;
RK_U32 sw_rlc_mode : 1;
RK_U32 sw_strm_start_bit : 7;
RK_U32 reserve1 : 1;
RK_U32 sw_dec_mode : 2;
RK_U32 reserve2 : 2;
RK_U32 sw_h264_rps_mode : 1;
RK_U32 sw_h264_stream_mode : 1;
RK_U32 sw_h264_stream_lastpacket : 1;
RK_U32 sw_h264_firstslice_flag : 1;
RK_U32 sw_h264_frame_orslice : 1;
RK_U32 sw_buspr_slot_disable : 1;
} swreg2_sysctrl;
struct {
RK_U32 sw_y_hor_virstride : 9;
RK_U32 reserve : 2;
RK_U32 sw_slice_num_highbit : 1;
RK_U32 sw_uv_hor_virstride : 9;
RK_U32 sw_slice_num_lowbits : 11;
} swreg3_picpar;
struct {
RK_U32 reverse0 : 4;
RK_U32 sw_strm_rlc_base : 28;
} swreg4_strm_rlc_base;
struct {
RK_U32 sw_stream_len : 27;
} swreg5_stream_rlc_len;
struct {
RK_U32 reverse0 : 4;
RK_U32 sw_cabactbl_base : 28;
} swreg6_cabactbl_prob_base;
struct {
RK_U32 reverse0 : 4;
RK_U32 sw_decout_base : 28;
} swreg7_decout_base;
struct {
RK_U32 sw_y_virstride : 20;
} swreg8_y_virstride;
struct {
RK_U32 sw_yuv_virstride : 21;
} swreg9_yuv_virstride;
struct {
RK_U32 sw_ref_field : 1;
RK_U32 sw_ref_topfield_used : 1;
RK_U32 sw_ref_botfield_used : 1;
RK_U32 sw_ref_colmv_use_flag : 1;
RK_U32 sw_refer_base : 28;
} swreg10_24_refer0_14_base[15];
RK_U32 swreg25_39_refer0_14_poc[15];
struct {
RK_U32 sw_cur_poc : 32;
} swreg40_cur_poc;
struct {
RK_U32 reserve : 3;
RK_U32 sw_rlcwrite_base : 29;
} swreg41_rlcwrite_base;
struct {
RK_U32 reserve : 4;
RK_U32 sw_pps_base : 28;
} swreg42_pps_base;
struct swreg_sw_rps_base {
RK_U32 reserve : 4;
RK_U32 sw_rps_base : 28;
} swreg43_rps_base;
struct swreg_strmd_error_e {
RK_U32 sw_strmd_error_e : 28;
RK_U32 reserve : 4;
} swreg44_strmd_error_en;
struct {
RK_U32 sw_strmd_error_status : 28;
RK_U32 sw_colmv_error_ref_picidx : 4;
} swreg45_strmd_error_status;
struct {
RK_U32 sw_strmd_error_ctu_xoffset : 8;
RK_U32 sw_strmd_error_ctu_yoffset : 8;
RK_U32 sw_streamfifo_space2full : 7;
RK_U32 reserve : 1;
RK_U32 sw_vp9_error_ctu0_en : 1;
} swreg46_strmd_error_ctu;
struct {
RK_U32 sw_saowr_xoffet : 9;
RK_U32 reserve : 7;
RK_U32 sw_saowr_yoffset : 10;
} swreg47_sao_ctu_position;
struct {
RK_U32 sw_ref_field : 1;
RK_U32 sw_ref_topfield_used : 1;
RK_U32 sw_ref_botfield_used : 1;
RK_U32 sw_ref_colmv_use_flag : 1;
RK_U32 sw_refer_base : 28;
} swreg48_refer15_base;
RK_U32 swreg49_63_refer15_29_poc[15];
struct {
RK_U32 sw_performance_cycle : 32;
} swreg64_performance_cycle;
struct {
RK_U32 sw_axi_ddr_rdata : 32;
} swreg65_axi_ddr_rdata;
struct {
RK_U32 sw_axi_ddr_rdata : 32;
} swreg66_axi_ddr_wdata;
struct {
RK_U32 sw_busifd_resetn : 1;
RK_U32 sw_cabac_resetn : 1;
RK_U32 sw_dec_ctrl_resetn : 1;
RK_U32 sw_transd_resetn : 1;
RK_U32 sw_intra_resetn : 1;
RK_U32 sw_inter_resetn : 1;
RK_U32 sw_recon_resetn : 1;
RK_U32 sw_filer_resetn : 1;
} swreg67_fpgadebug_reset;
struct {
RK_U32 perf_cnt0_sel : 6;
RK_U32 reserve0 : 2;
RK_U32 perf_cnt1_sel : 6;
RK_U32 reserve1 : 2;
RK_U32 perf_cnt2_sel : 6;
} swreg68_performance_sel;
struct {
RK_U32 perf_cnt0 : 32;
} swreg69_performance_cnt0;
struct {
RK_U32 perf_cnt1 : 32;
} swreg70_performance_cnt1;
struct {
RK_U32 perf_cnt2 : 32;
} swreg71_performance_cnt2;
RK_U32 swreg72_refer30_poc;
RK_U32 swreg73_refer31_poc;
struct {
RK_U32 sw_h264_cur_poc1 : 32;
} swreg74_h264_cur_poc1;
struct {
RK_U32 reserve : 4;
RK_U32 sw_errorinfo_base : 28;
} swreg75_h264_errorinfo_base;
struct {
RK_U32 sw_slicedec_num : 14;
RK_U32 reserve : 1;
RK_U32 sw_strmd_detect_error_flag : 1;
RK_U32 sw_error_packet_num : 14;
} swreg76_h264_errorinfo_num;
struct {
RK_U32 sw_h264_error_en_highbits : 30;
RK_U32 reserve : 2;
} swreg77_h264_error_e;
RK_U32 compare_len;
} H264_REGS_t;
//typedef struct hal_h264d_logctx_t
//{
// struct rkv_log_flag_t *log_flag;
// struct rkv_log_ctx_t *spspps;
// struct rkv_log_ctx_t *rps;
// struct rkv_log_ctx_t *scanlist;
// struct rkv_log_ctx_t *sodb;
// struct rkv_log_ctx_t *reg;
// struct rkv_log_ctx_t *driver; // fwrite
// struct rkv_log_ctx_t *runlog; // fprintf
//
//}HAL_H264dLogCtx_t;
//typedef struct hal_h264d_initctx_t
//{
// HAL_H264dLogCtx_t *logctx;
//}HAL_H264dInitCtx_t;
//
//
//typedef struct hal_h264d_inctx_t
//{
// struct h264d_syntax_t *syn;
//
//}HAL_H264dInCtx_t;
//
//typedef struct hal_h264d_outctx_t
//{
// H264_REGS_t *reg;
// H264_MMU_t *mmu;
// H264_CACHE_t *cache;
//
//}HAL_H264dOutCtx_t;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@@ -9,13 +9,19 @@ set(HAL_H264D_API
# hal h264 header # hal h264 header
set(HAL_H264D_HDR set(HAL_H264D_HDR
hal_h264d_global.h
hal_h264d_reg.h
hal_h264d_fifo.h
hal_h264d_packet.h
) )
# hal h264 decoder sourse # hal h264 decoder sourse
set(HAL_H264D_SRC set(HAL_H264D_SRC
hal_h264d_api.c hal_h264d_api.c
hal_h264d_reg.c
hal_h264d_fifo.c
hal_h264d_packet.c
) )
add_library(hal_h264d STATIC add_library(hal_h264d STATIC

View File

@@ -14,77 +14,345 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#define MODULE_TAG "hal_h264d"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rk_type.h"
#include "mpp_err.h"
#include "mpp_mem.h"
#include "dxva_syntax.h"
#include "h264d_syntax.h"
#include "h264d_log.h" #include "h264d_log.h"
#include "hal_h264d_global.h"
#include "hal_h264d_reg.h"
#include "hal_h264d_packet.h"
#include "hal_h264d_api.h" #include "hal_h264d_api.h"
#define MODULE_TAG "hal_h264d_api"
static void close_log_files(LogEnv_t *env)
{
FCLOSE(env->fp_driver);
FCLOSE(env->fp_syn_hal);
FCLOSE(env->fp_run_hal);
}
static MPP_RET open_log_files(LogEnv_t *env, LogFlag_t *pflag)
{
MPP_RET ret = MPP_ERR_UNKNOW;
char fname[128] = { 0 };
INP_CHECK(ret, ctx, !pflag->write_en);
//!< runlog file
if (GetBitVal(env->ctrl, LOG_DEBUG_EN)) {
sprintf(fname, "%s/h264d_hal_runlog.dat", env->outpath);
FLE_CHECK(ret, env->fp_run_hal = fopen(fname, "wb"));
}
//!< fpga drive file
if (GetBitVal(env->ctrl, LOG_FPGA)) {
sprintf(fname, "%s/h264d_driver_data.dat", env->outpath);
FLE_CHECK(ret, env->fp_driver = fopen(fname, "wb"));
}
//!< write syntax
if ( GetBitVal(env->ctrl, LOG_WRITE_SPSPPS )
|| GetBitVal(env->ctrl, LOG_WRITE_RPS )
|| GetBitVal(env->ctrl, LOG_WRITE_SCANLIST)
|| GetBitVal(env->ctrl, LOG_WRITE_STEAM )
|| GetBitVal(env->ctrl, LOG_WRITE_REG ) ) {
sprintf(fname, "%s/h264d_write_syntax.dat", env->outpath);
FLE_CHECK(ret, env->fp_syn_hal = fopen(fname, "wb"));
}
__RETURN:
return MPP_OK;
__FAILED:
return ret;
}
static MPP_RET logctx_deinit(H264dLogCtx_t *logctx)
{
close_log_files(&logctx->env);
return MPP_OK;
}
static MPP_RET logctx_init(H264dLogCtx_t *logctx, LogCtx_t *logbuf)
{
RK_U8 i = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
LogCtx_t *pcur = NULL;
FUN_CHECK(ret = get_logenv(&logctx->env));
FUN_CHECK(ret = explain_ctrl_flag(logctx->env.ctrl, &logctx->log_flag));
if ( !logctx->log_flag.debug_en
&& !logctx->log_flag.print_en && !logctx->log_flag.write_en ) {
logctx->log_flag.debug_en = 0;
goto __RETURN;
}
logctx->log_flag.level = (1 << logctx->env.level) - 1;
//!< open file
FUN_CHECK(ret = open_log_files(&logctx->env, &logctx->log_flag));
//!< set logctx
while (i < LOG_MAX) {
if (GetBitVal(logctx->env.ctrl, i)) {
pcur = logctx->parr[i] = &logbuf[i];
pcur->tag = logctrl_name[i];
pcur->flag = &logctx->log_flag;
switch (i) {
case LOG_FPGA:
pcur->fp = logctx->env.fp_driver;
break;
case RUN_HAL:
pcur->fp = logctx->env.fp_run_hal;
break;
case LOG_WRITE_SPSPPS:
case LOG_WRITE_RPS:
case LOG_WRITE_SCANLIST:
case LOG_WRITE_STEAM:
case LOG_WRITE_REG:
pcur->fp = logctx->env.fp_syn_hal;
default:
break;
}
}
i++;
}
__RETURN:
return ret = MPP_OK;
__FAILED:
logctx->log_flag.debug_en = 0;
logctx_deinit(logctx);
return ret;
}
/*!
***********************************************************************
* \brief
* init
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_init(void *hal, MppHalCfg *cfg) MPP_RET hal_h264d_init(void *hal, MppHalCfg *cfg)
{ {
printf("begin=%s \n", logenv_name.begframe); MPP_RET ret = MPP_ERR_UNKNOW;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
INP_CHECK(ret, ctx, NULL == p_hal);
memset(p_hal, 0, sizeof(H264dHalCtx_t));
//!< init logctx
FUN_CHECK(ret = logctx_init(&p_hal->logctx, p_hal->logctxbuf));
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
p_hal->mem = mpp_calloc(H264dHalMem_t, 1);
MEM_CHECK(ret, p_hal->mem);
p_hal->regs = &p_hal->mem->regs;
p_hal->mmu_regs = &p_hal->mem->mmu_regs;
p_hal->cache_regs = &p_hal->mem->cache_regs;
p_hal->pkts = &p_hal->mem->pkts;
FUN_CHECK(ret = alloc_fifo_packet(&p_hal->logctx, p_hal->pkts));
(void)hal; FunctionOut(p_hal->logctx.parr[RUN_HAL]);
(void)cfg; (void)cfg;
__RETURN:
return MPP_OK; return MPP_OK;
} __FAILED:
hal_h264d_deinit(hal);
return ret;
}
/*!
***********************************************************************
* \brief
* deinit
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_deinit(void *hal) MPP_RET hal_h264d_deinit(void *hal)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
return MPP_OK; H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
}
INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
free_fifo_packet(p_hal->pkts);
mpp_free(p_hal->mem);
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
logctx_deinit(&p_hal->logctx);
__RETURN:
return ret = MPP_OK;
}
/*!
***********************************************************************
* \brief
* generate register
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_gen_regs(void *hal, HalTask *task) MPP_RET hal_h264d_gen_regs(void *hal, HalTask *task)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
((HalDecTask*)&task->dec)->valid = 0; INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
explain_input_buffer(hal, &task->dec);
prepare_spspps_packet(hal, &p_hal->pkts->spspps);
prepare_framerps_packet(hal, &p_hal->pkts->rps);
prepare_scanlist_packet(hal, &p_hal->pkts->scanlist);
prepare_stream_packet(hal, &p_hal->pkts->strm);
generate_regs(p_hal, &p_hal->pkts->reg);
printf("++++++++++ hal_h264_decoder, g_framecnt=%d \n", p_hal->g_framecnt++);
((HalDecTask*)&task->dec)->valid = 0;
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
return MPP_OK; __RETURN:
return ret = MPP_OK;
} }
/*!
***********************************************************************
* \brief h
* start hard
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_start(void *hal, HalTask *task) MPP_RET hal_h264d_start(void *hal, HalTask *task)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
(void)task; H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
return MPP_OK;
}
INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
(void)task;
__RETURN:
return ret = MPP_OK;
}
/*!
***********************************************************************
* \brief
* wait hard
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_wait(void *hal, HalTask *task) MPP_RET hal_h264d_wait(void *hal, HalTask *task)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
(void)task; H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
return MPP_OK;
}
INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
(void)task;
__RETURN:
return ret = MPP_OK;
}
/*!
***********************************************************************
* \brief
* reset
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_reset(void *hal) MPP_RET hal_h264d_reset(void *hal)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
return MPP_OK; H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
}
INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
memset(&p_hal->regs, 0, sizeof(H264_REGS_t));
memset(&p_hal->mmu_regs, 0, sizeof(H264_MMU_t));
memset(&p_hal->cache_regs, 0, sizeof(H264_CACHE_t));
reset_fifo_packet(p_hal->pkts);
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
__RETURN:
return ret = MPP_OK;
}
/*!
***********************************************************************
* \brief
* flush
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_flush(void *hal) MPP_RET hal_h264d_flush(void *hal)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
return MPP_OK; H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
}
INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
__RETURN:
return ret = MPP_OK;
}
/*!
***********************************************************************
* \brief
* control
***********************************************************************
*/
//extern "C"
MPP_RET hal_h264d_control(void *hal, RK_S32 cmd_type, void *param) MPP_RET hal_h264d_control(void *hal, RK_S32 cmd_type, void *param)
{ {
(void)hal; MPP_RET ret = MPP_ERR_UNKNOW;
(void)cmd_type; H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
(void)param;
return MPP_OK; INP_CHECK(ret, ctx, NULL == p_hal);
FunctionIn(p_hal->logctx.parr[RUN_HAL]);
FunctionOut(p_hal->logctx.parr[RUN_HAL]);
(void)hal;
(void)cmd_type;
(void)param;
__RETURN:
return ret = MPP_OK;
} }
const MppHalApi hal_api_h264d = { const MppHalApi hal_api_h264d = {
"h264d_rkdec", "h264d_rkdec",
MPP_CTX_DEC, MPP_CTX_DEC,
MPP_VIDEO_CodingAVC, MPP_VIDEO_CodingAVC,
0, sizeof(H264dHalCtx_t),
0, 0,
hal_h264d_init, hal_h264d_init,
hal_h264d_deinit, hal_h264d_deinit,

View File

@@ -0,0 +1,205 @@
/*
* Copyright 2010 Rockchip Electronics S.LSI Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "mpp_mem.h"
#include "h264d_log.h"
#include "hal_h264d_fifo.h"
#define MODULE_TAG "hal_h264d_fifo"
/*!
***********************************************************************
* \brief
* write fifo data to file
***********************************************************************
*/
//extern "C"
void fifo_fwrite(FILE *fp, void *psrc, RK_U32 size)
{
fwrite(psrc, 1, size, fp);
fflush(fp);
}
/*!
***********************************************************************
* \brief
* flush left bytes to fifo
***********************************************************************
*/
//extern "C"
void fifo_flush_bits(FifoCtx_t *pkt)
{
if (pkt->bitpos)
{
fifo_write_bits(pkt, 0, (64 - pkt->bitpos), "flush");
pkt->index++;
pkt->bitpos = 0;
}
}
//void fifo_fwrite_header(FifoCtx_t *pkt, RK_S32 pkt_size)
//{
// if (pkt->fp_data)
// {
// pkt->size = pkt_size;
// fifo_fwrite(pkt->fp_data, &pkt->header, sizeof(RK_U32));
// fifo_fwrite(pkt->fp_data, &pkt->size, sizeof(RK_U32));
// }
//}
/*!
***********************************************************************
* \brief
* fwrite header and data
***********************************************************************
*/
//extern "C"
void fifo_fwrite_data(FifoCtx_t *pkt)
{
RK_U32 pkt_size = 0;
if (pkt->fp_data)
{
pkt_size = pkt->index*sizeof(RK_U64);
fifo_fwrite(pkt->fp_data, &pkt->header, sizeof(RK_U32));
fifo_fwrite(pkt->fp_data, &pkt_size, sizeof(RK_U32));
fifo_fwrite(pkt->fp_data, pkt->pbuf, pkt->index*sizeof(RK_U64));
}
}
/*!
***********************************************************************
* \brief
* write bits to fifo
***********************************************************************
*/
//extern "C"
void fifo_write_bits(FifoCtx_t *pkt, RK_U64 invalue, RK_U8 lbits, const char *name)
{
RK_U8 hbits = 0;
if (!lbits) return;
hbits = 64 - lbits;
invalue = (invalue << hbits) >> hbits;
LogInfo(pkt->logctx, "%48s = %10d (bits=%d)", name, invalue, lbits);
pkt->bvalue |= invalue << pkt->bitpos; // high bits value
if ((pkt->bitpos + lbits) >= 64)
{
pkt->pbuf[pkt->index] = pkt->bvalue;
//printf("pdata[%d]=%16x \n", pkt->index, pkt->bvalue);
pkt->bvalue = invalue >> (64 - pkt->bitpos); // low bits value
pkt->index++;
ASSERT(pkt->index <= pkt->buflen);
}
pkt->pbuf[pkt->index] = pkt->bvalue;
pkt->bitpos = (pkt->bitpos + lbits) & 63;
}
/*!
***********************************************************************
* \brief
* align fifo bits
***********************************************************************
*/
//extern "C"
void fifo_align_bits(FifoCtx_t *pkt, RK_U8 align_bits)
{
RK_U32 word_offset = 0, bits_offset = 0, bitlen = 0;
word_offset = (align_bits >= 64) ? ((pkt->index &(((align_bits & 0xfe0) >> 6) - 1)) << 6) : 0;
bits_offset = (align_bits - (word_offset + (pkt->bitpos % align_bits))) % align_bits;
while (bits_offset > 0)
{
bitlen = (bits_offset >= 8) ? 8 : bits_offset;
fifo_write_bits(pkt, 0, bitlen, "align");
bits_offset -= bitlen;
}
}
/*!
***********************************************************************
* \brief
* write bytes to fifo
***********************************************************************
*/
//extern "C"
void fifo_write_bytes(FifoCtx_t *pkt, void *psrc, RK_U32 size)
{
RK_U8 hbits = 0;
RK_U32 bitslen = 0;
RK_U8 *pdst = NULL;
hbits = 64 - pkt->bitpos;
pkt->pbuf[pkt->index] = pkt->bitpos ? ((pkt->bvalue << hbits) >> hbits) : 0;
if (size)
{
pdst = (RK_U8 *)&pkt->pbuf[pkt->index];
pdst += pkt->bitpos / 8;
memcpy(pdst, psrc, size);
bitslen = size * 8 + pkt->bitpos;
pkt->index += bitslen / 64;
pkt->bitpos = bitslen & 63;
hbits = 64 - pkt->bitpos;
pkt->bvalue = pkt->bitpos ? ((pkt->pbuf[pkt->index] << hbits) >> hbits) : 0;
}
}
void fifo_packet_reset(FifoCtx_t *pkt)
{
pkt->index = 0;
pkt->bitpos = 0;
pkt->bvalue = 0;
pkt->size = 0;
}
/*!
***********************************************************************
* \brief
* init fifo packet
***********************************************************************
*/
//extern "C"
MPP_RET fifo_packet_init(FifoCtx_t *pkt, RK_S32 header, RK_S32 size)
{
MPP_RET ret = MPP_ERR_UNKNOW;
pkt->header = header;
pkt->index = 0;
pkt->bitpos = 0;
pkt->bvalue = 0;
pkt->size = 0;
pkt->buflen = (size + 7) / 8; // align 64bit
pkt->pbuf = NULL;
if (pkt->buflen)
{
pkt->pbuf = mpp_malloc(RK_U64, pkt->buflen);
MEM_CHECK(ret, pkt->pbuf);
}
return MPP_OK;
__FAILED:
return ret;
}

View File

@@ -0,0 +1,46 @@
#ifndef __HAL_H264D_FIFO_H__
#define __HAL_H264D_FIFO_H__
#include "rk_type.h"
#include "mpp_err.h"
#include "h264d_log.h"
typedef struct
{
RK_U32 header;
RK_U32 buflen; //!< max buf length, 64bit uint
RK_U32 index; //!< current uint position
RK_U64 *pbuf; //!< outpacket data
RK_U64 bvalue; //!< buffer value, 64 bit
RK_U8 bitpos; //!< bit pos in 64bit
RK_U32 size; //!< data size,except header
LogCtx_t *logctx; //!< for debug
FILE *fp_data; //!< for fpga
}FifoCtx_t;
#ifdef __cplusplus
extern "C" {
#endif
void fifo_packet_reset (FifoCtx_t *pkt);
void fifo_fwrite_header(FifoCtx_t *pkt, RK_S32 pkt_size);
void fifo_fwrite_data (FifoCtx_t *pkt);
void fifo_write_bits (FifoCtx_t *pkt, RK_U64 invalue, RK_U8 lbits, const char *name);
void fifo_flush_bits (FifoCtx_t *pkt);
void fifo_align_bits (FifoCtx_t *pkt, RK_U8 align_bits);
void fifo_write_bytes (FifoCtx_t *pkt, void *psrc, RK_U32 size);
void fifo_fwrite (FILE *fp, void *psrc, RK_U32 size);
MPP_RET fifo_packet_init (FifoCtx_t *pkt, RK_S32 header, RK_S32 size);
#ifdef __cplusplus
}
#endif
//!<============================
#endif //!<__HAL_H264D_FIFO_H__

View File

@@ -0,0 +1,65 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __HAL_H264D_GLOBAL_H__
#define __HAL_H264D_GLOBAL_H__
#include "mpp_hal.h"
#include "dxva_syntax.h"
#include "h264d_syntax.h"
#include "h264d_log.h"
#include "hal_h264d_reg.h"
#include "hal_h264d_fifo.h"
#include "hal_h264d_packet.h"
typedef struct h264d_hal_mem_t
{
H264_REGS_t regs; //!< for register
H264_MMU_t mmu_regs;
H264_CACHE_t cache_regs;
H264_FifoPkt_t pkts;
}H264dHalMem_t;
typedef struct h264d_hal_ctx_t
{
H264dHalMem_t *mem;
H264_REGS_t *regs;
H264_MMU_t *mmu_regs;
H264_CACHE_t *cache_regs;
H264_FifoPkt_t *pkts;
RK_U8 spt_BitstrmRaw;
RK_U8 set_BitstrmRaw;
DXVA_PicParams_H264_MVC *pp;
DXVA_Qmatrix_H264 *qm;
RK_U32 slice_num;
DXVA_Slice_H264_Short *slice_short; //!< MAX_SLICES
DXVA_Slice_H264_Long *slice_long; //!< MAX_SLICES
RK_U8 *bitstream;
RK_U32 strm_len;
RK_U32 g_framecnt;
H264dLogCtx_t logctx; //!< debug log file
LogCtx_t logctxbuf[LOG_MAX];
}H264dHalCtx_t;
#endif /*__HAL_H264D_REG_H__*/

View File

@@ -0,0 +1,518 @@
/*
* Copyright 2010 Rockchip Electronics S.LSI Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "mpp_mem.h"
#include "hal_task.h"
#include "dxva_syntax.h"
#include "h264d_log.h"
#include "h264d_syntax.h"
#include "hal_h264d_fifo.h"
#include "hal_h264d_api.h"
#include "hal_h264d_packet.h"
#include "hal_h264d_global.h"
#define MODULE_TAG "hal_h264d_packet"
//!< Header
#define H264dREG_HEADER 0x48474552
#define H264dPPS_HEADER 0x48535050
#define H264dSCL_HEADER 0x534c4353
#define H264dRPS_HEADER 0x48535052
#define H264dCRC_HEADER 0x48435243
#define H264dSTM_HEADER 0x4d525453
#define H264dERR_HEADER 0x524f5245
enum {
H264ScalingList4x4Length = 16,
H264ScalingList8x8Length = 64,
} ScalingListLength;
static void write_sps_to_fifo(H264dHalCtx_t *p_hal, FifoCtx_t *pkt)
{
fifo_write_bits(pkt, -1, 4, "seq_parameter_set_id"); //!< not used in hard
fifo_write_bits(pkt, -1, 8, "profile_idc"); //!< not used in hard
fifo_write_bits(pkt, -1, 1, "constraint_set3_flag"); //!< not used in hard
fifo_write_bits(pkt, p_hal->pp->chroma_format_idc, 2, "chroma_format_idc");
fifo_write_bits(pkt, (p_hal->pp->bit_depth_luma_minus8 + 8), 3, "bit_depth_luma");
fifo_write_bits(pkt, (p_hal->pp->bit_depth_chroma_minus8 + 8), 3, "bit_depth_chroma");
fifo_write_bits(pkt, 0, 1, "qpprime_y_zero_transform_bypass_flag"); //!< not supported in hard
fifo_write_bits(pkt, p_hal->pp->log2_max_frame_num_minus4, 4, "log2_max_frame_num_minus4");
fifo_write_bits(pkt, p_hal->pp->num_ref_frames, 5, "max_num_ref_frames");
fifo_write_bits(pkt, p_hal->pp->pic_order_cnt_type, 2, "pic_order_cnt_type");
fifo_write_bits(pkt, p_hal->pp->log2_max_pic_order_cnt_lsb_minus4, 4, "log2_max_pic_order_cnt_lsb_minus4");
fifo_write_bits(pkt, p_hal->pp->delta_pic_order_always_zero_flag, 1, "delta_pic_order_always_zero_flag");
fifo_write_bits(pkt, (p_hal->pp->wFrameWidthInMbsMinus1 + 1), 9, "pic_width_in_mbs");
fifo_write_bits(pkt, (p_hal->pp->wFrameHeightInMbsMinus1 + 1), 9, "pic_height_in_mbs");
fifo_write_bits(pkt, p_hal->pp->frame_mbs_only_flag, 1, "frame_mbs_only_flag");
fifo_write_bits(pkt, p_hal->pp->MbaffFrameFlag, 1, "mb_adaptive_frame_field_flag");
fifo_write_bits(pkt, p_hal->pp->direct_8x8_inference_flag, 1, "direct_8x8_inference_flag");
fifo_write_bits(pkt, 1, 1, "mvc_extension_enable");
fifo_write_bits(pkt, (p_hal->pp->num_views_minus1 + 1), 2, "num_views");
fifo_write_bits(pkt, p_hal->pp->view_id[0], 10, "view_id[2]");
fifo_write_bits(pkt, p_hal->pp->view_id[1], 10, "view_id[2]");
fifo_write_bits(pkt, p_hal->pp->num_anchor_refs_l0[0], 1, "num_anchor_refs_l0");
if (p_hal->pp->num_anchor_refs_l0[0])
{
fifo_write_bits(pkt, p_hal->pp->anchor_ref_l0[0][0], 10, "anchor_ref_l0");
}
else
{
fifo_write_bits(pkt, 0, 10, "anchor_ref_l0");
}
fifo_write_bits(pkt, p_hal->pp->num_anchor_refs_l1[0], 1, "num_anchor_refs_l1");
if (p_hal->pp->num_anchor_refs_l1[0])
{
fifo_write_bits(pkt, p_hal->pp->anchor_ref_l1[0][0], 10, "anchor_ref_l1");
}
else
{
fifo_write_bits(pkt, 0, 10, "anchor_ref_l1");
}
fifo_write_bits(pkt, p_hal->pp->num_non_anchor_refs_l0[0], 1, "num_non_anchor_refs_l0");
if (p_hal->pp->num_non_anchor_refs_l0[0])
{
fifo_write_bits(pkt, p_hal->pp->non_anchor_ref_l0[0][0], 10, "non_anchor_ref_l0");
}
else
{
fifo_write_bits(pkt, 0, 10, "non_anchor_ref_l0");
}
fifo_write_bits(pkt, p_hal->pp->num_non_anchor_refs_l1[0], 1, "num_non_anchor_refs_l1");
if (p_hal->pp->num_non_anchor_refs_l1[0])
{
fifo_write_bits(pkt, p_hal->pp->non_anchor_ref_l1[0][0], 10, "non_anchor_ref_l1");
}
else
{
fifo_write_bits(pkt, 0, 10, "non_anchor_ref_l1");
}
fifo_align_bits(pkt, 32);
}
static void write_pps_to_fifo(H264dHalCtx_t *p_hal, FifoCtx_t *pkt)
{
fifo_write_bits(pkt, -1, 8, "pps_pic_parameter_set_id");
fifo_write_bits(pkt, -1, 5, "pps_seq_parameter_set_id");
fifo_write_bits(pkt, p_hal->pp->entropy_coding_mode_flag, 1, "entropy_coding_mode_flag");
fifo_write_bits(pkt, p_hal->pp->pic_order_present_flag, 1, "bottom_field_pic_order_in_frame_present_flag");
fifo_write_bits(pkt, p_hal->pp->num_ref_idx_l0_active_minus1, 5, "num_ref_idx_l0_default_active_minus1");
fifo_write_bits(pkt, p_hal->pp->num_ref_idx_l1_active_minus1, 5, "num_ref_idx_l1_default_active_minus1");
fifo_write_bits(pkt, p_hal->pp->weighted_pred_flag, 1, "weighted_pred_flag");
fifo_write_bits(pkt, p_hal->pp->weighted_bipred_idc, 2, "weighted_bipred_idc");
fifo_write_bits(pkt, p_hal->pp->pic_init_qp_minus26, 7, "pic_init_qp_minus26");
fifo_write_bits(pkt, p_hal->pp->pic_init_qs_minus26, 6, "pic_init_qs_minus26");
fifo_write_bits(pkt, p_hal->pp->chroma_qp_index_offset, 5, "chroma_qp_index_offset");
fifo_write_bits(pkt, p_hal->pp->deblocking_filter_control_present_flag, 1, "deblocking_filter_control_present_flag");
fifo_write_bits(pkt, p_hal->pp->constrained_intra_pred_flag, 1, "constrained_intra_pred_flag");
fifo_write_bits(pkt, p_hal->pp->redundant_pic_cnt_present_flag, 1, "redundant_pic_cnt_present_flag");
fifo_write_bits(pkt, p_hal->pp->transform_8x8_mode_flag, 1, "transform_8x8_mode_flag");
fifo_write_bits(pkt, p_hal->pp->second_chroma_qp_index_offset, 5, "second_chroma_qp_index_offset");
fifo_write_bits(pkt, p_hal->pp->scaleing_list_enable_flag, 1, "scaleing_list_enable_flag");
fifo_write_bits(pkt, 0/*(RK_U32)p_hal->pkts.scanlist.pbuf*/, 32, "Scaleing_list_address");
}
/*!
***********************************************************************
* \brief
* reset fifo packet
***********************************************************************
*/
//extern "C"
void reset_fifo_packet(H264_FifoPkt_t *pkt)
{
if (pkt)
{
fifo_packet_reset(&pkt->spspps);
fifo_packet_reset(&pkt->rps);
fifo_packet_reset(&pkt->strm);
fifo_packet_reset(&pkt->scanlist);
fifo_packet_reset(&pkt->reg);
}
}
/*!
***********************************************************************
* \brief
* free fifo pakcket
***********************************************************************
*/
//extern "C"
void free_fifo_packet(H264_FifoPkt_t *pkt)
{
if (pkt)
{
mpp_free(pkt->spspps.pbuf);
mpp_free(pkt->rps.pbuf);
mpp_free(pkt->scanlist.pbuf);
mpp_free(pkt->reg.pbuf);
}
}
/*!
***********************************************************************
* \brief
* alloc fifo packet
***********************************************************************
*/
//extern "C"
MPP_RET alloc_fifo_packet(H264dLogCtx_t *logctx, H264_FifoPkt_t *pkts)
{
MPP_RET ret = MPP_ERR_UNKNOW;
LogCtx_t *log_driver = NULL;
RK_U32 pps_size = 256 * 32 + 16;
RK_U32 rps_size = 128 + 16;
RK_U32 strm_size = 0;
RK_U32 sclst_size = 256;
RK_U32 regs_size = 512;
//!< initial packages header and malloc buffer
FUN_CHECK(ret = fifo_packet_init(&pkts->spspps, H264dPPS_HEADER, pps_size));
FUN_CHECK(ret = fifo_packet_init(&pkts->rps, H264dRPS_HEADER, rps_size));
FUN_CHECK(ret = fifo_packet_init(&pkts->strm, H264dSTM_HEADER, strm_size));
FUN_CHECK(ret = fifo_packet_init(&pkts->scanlist, H264dSCL_HEADER, sclst_size));
FUN_CHECK(ret = fifo_packet_init(&pkts->reg, H264dREG_HEADER, regs_size));
//!< set logctx
pkts->spspps.logctx = logctx->parr[LOG_WRITE_SPSPPS];
pkts->rps.logctx = logctx->parr[LOG_WRITE_RPS];
pkts->scanlist.logctx = logctx->parr[LOG_WRITE_SCANLIST];
pkts->reg.logctx = logctx->parr[LOG_WRITE_REG];
//!< set bitstream file output
log_driver = logctx->parr[LOG_FPGA];
if (log_driver && log_driver->flag->write_en)
{
pkts->spspps.fp_data = log_driver->fp;
pkts->rps.fp_data = log_driver->fp;
pkts->scanlist.fp_data = log_driver->fp;
pkts->reg.fp_data = log_driver->fp;
pkts->strm.fp_data = log_driver->fp;
}
else
{
pkts->spspps.fp_data = NULL;
pkts->rps.fp_data = NULL;
pkts->scanlist.fp_data = NULL;
pkts->reg.fp_data = NULL;
pkts->strm.fp_data = NULL;
}
return ret = MPP_OK;
__FAILED:
free_fifo_packet(pkts);
return ret;
}
/*!
***********************************************************************
* \brief
* expalin decoder buffer dest
***********************************************************************
*/
//extern "C"
void explain_input_buffer(void *hal, HalDecTask *task)
{
RK_U32 i = 0;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
DXVA2_DecodeBufferDesc *pdes = (DXVA2_DecodeBufferDesc *)task->syntax.data;
for (i = 0; i < task->syntax.number; i++)
{
switch (pdes[i].CompressedBufferType)
{
case DXVA2_PictureParametersBufferType:
p_hal->pp = (DXVA_PicParams_H264_MVC *)pdes[i].pvPVPState;
break;
case DXVA2_InverseQuantizationMatrixBufferType:
p_hal->qm = (DXVA_Qmatrix_H264 *)pdes[i].pvPVPState;
break;
case DXVA2_SliceControlBufferType:
p_hal->slice_num = pdes[i].DataSize / sizeof(DXVA_Slice_H264_Long);
p_hal->slice_long = (DXVA_Slice_H264_Long *)pdes[i].pvPVPState;
break;
case DXVA2_BitStreamDateBufferType:
p_hal->bitstream = (RK_U8 *)pdes[i].pvPVPState;
p_hal->strm_len = pdes[i].DataSize;
break;
default:
break;
}
}
}
/*!
***********************************************************************
* \brief
* prepare sps_sps packet
***********************************************************************
*/
//extern "C"
void prepare_spspps_packet(void *hal, FifoCtx_t *pkt)
{
RK_S32 i = 0;
RK_S32 is_long_term = 0, voidx = 0;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
fifo_packet_reset(pkt);
LogInfo(pkt->logctx, "------------------ Frame SPS_PPS begin ------------------------");
write_sps_to_fifo(p_hal, pkt);
write_pps_to_fifo(p_hal, pkt);
for (i = 0; i < 16; i++)
{
is_long_term = (p_hal->pp->RefFrameList[i].bPicEntry != 0xff) ? p_hal->pp->RefFrameList[i].AssociatedFlag : 0;
fifo_write_bits(pkt, is_long_term, 1, "is_long_term");
}
for (i = 0; i < 16; i++)
{
voidx = (p_hal->pp->RefFrameList[i].bPicEntry != 0xff) ? p_hal->pp->RefPicLayerIdList[i] : 0;
fifo_write_bits(pkt, voidx, 1, "voidx");
}
fifo_align_bits(pkt, 64);
fifo_fwrite_data(pkt); //!< "PPSH" header 32 bit
}
/*!
***********************************************************************
* \brief
* prepare frame rps packet
***********************************************************************
*/
//extern "C"
void prepare_framerps_packet(void *hal, FifoCtx_t *pkt)
{
RK_S32 i = 0, j = 0;
RK_S32 dpb_idx = 0, voidx = 0;
RK_S32 dpb_valid = 0, bottom_flag = 0;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
fifo_packet_reset(pkt);
LogInfo(pkt->logctx, "------------------ Frame RPS begin ------------------------");
for (i = 0; i < 16; i++)
{
fifo_write_bits(pkt, p_hal->pp->FrameNumList[i], 16, "frame_num_wrap");
}
for (i = 0; i < 16; i++)
{
fifo_write_bits(pkt, 0, 1, "NULL");
}
for (i = 0; i < 16; i++)
{
fifo_write_bits(pkt, p_hal->pp->RefPicLayerIdList[i], 1, "voidx");
}
for (i = 0; i < 32; i++)
{
dpb_valid = (p_hal->slice_long[0].RefPicList[0][i].bPicEntry == 0xff) ? 0 : 1;
dpb_idx = dpb_valid ? p_hal->slice_long[0].RefPicList[0][i].Index7Bits : 0;
bottom_flag = dpb_valid ? p_hal->slice_long[0].RefPicList[0][i].AssociatedFlag : 0;
voidx = dpb_valid ? p_hal->pp->RefPicLayerIdList[dpb_idx] : 0;
fifo_write_bits(pkt, dpb_idx | (dpb_valid << 4), 5, "dpb_idx");
fifo_write_bits(pkt, bottom_flag, 1, "bottom_flag");
fifo_write_bits(pkt, voidx, 1, "voidx");
}
for (j = 1; j < 3; j++)
{
for (i = 0; i < 32; i++)
{
dpb_valid = (p_hal->slice_long[0].RefPicList[j][i].bPicEntry == 0xff) ? 0 : 1;
dpb_idx = dpb_valid ? p_hal->slice_long[0].RefPicList[j][i].Index7Bits : 0;
bottom_flag = dpb_valid ? p_hal->slice_long[0].RefPicList[j][i].AssociatedFlag : 0;
voidx = dpb_valid ? p_hal->pp->RefPicLayerIdList[dpb_idx] : 0;
fifo_write_bits(pkt, dpb_idx | (dpb_valid << 4), 5, "dpb_idx");
fifo_write_bits(pkt, bottom_flag, 1, "bottom_flag");
fifo_write_bits(pkt, voidx, 1, "voidx");
}
}
fifo_align_bits(pkt, 128);
fifo_flush_bits(pkt);
fifo_fwrite_data(pkt); //!< "RPSH" header 32 bit
}
/*!
***********************************************************************
* \brief
* prepare scanlist packet
***********************************************************************
*/
//extern "C"
void prepare_scanlist_packet(void *hal, FifoCtx_t *pkt)
{
RK_S32 i = 0;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
if (p_hal->pp->scaleing_list_enable_flag)
{
fifo_packet_reset(pkt);
LogInfo(pkt->logctx, "------------------ Scanlist begin ------------------------");
for (i = 0; i < 6; ++i) //!< 4x4, 6 lists
{
fifo_write_bytes(pkt, p_hal->qm->bScalingLists4x4[i], H264ScalingList4x4Length);
}
for (i = 0; i < 2; ++i)
{
fifo_write_bytes(pkt, p_hal->qm->bScalingLists8x8[i], H264ScalingList8x8Length);
}
fifo_fwrite_data(pkt); //!< "SCLS" header 32 bit
}
}
/*!
***********************************************************************
* \brief
* prepare stream packet
***********************************************************************
*/
//extern "C"
void prepare_stream_packet(void *hal, FifoCtx_t *pkt)
{
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
fifo_packet_reset(pkt);
pkt->pbuf = (RK_U64 *)p_hal->bitstream;
pkt->index = p_hal->strm_len / 8;
fifo_fwrite_data(pkt); // "STRM" header 32 bit
}
/*!
***********************************************************************
* \brief
* generate register packet
***********************************************************************
*/
//extern "C"
void generate_regs(void *hal, FifoCtx_t *pkt)
{
RK_S32 i = 0;
RK_U8 bit_depth[3] = { 0 };
RK_U32 sw_y_hor_virstride = 0;
RK_U32 sw_uv_hor_virstride = 0;
RK_U32 sw_y_virstride = 0;
RK_U32 yuv_virstride = 0;
RK_U32 pic_h[3] = { 0 }, pic_w[3] = { 0 };
RK_U32 mb_width = 0, mb_height = 0, mv_size = 0;
H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
H264_REGS_t *p_regs = p_hal->regs;
memset(p_regs, 0, sizeof(H264_REGS_t));
if (p_regs->swreg2_sysctrl.sw_rlc_mode == 1)
{
p_regs->swreg5_stream_rlc_len.sw_stream_len = 0;
}
else
{
p_regs->swreg5_stream_rlc_len.sw_stream_len = p_hal->strm_len;
}
//!< caculate the yuv_frame_size and mv_size
mb_width = p_hal->pp->wFrameWidthInMbsMinus1 + 1;
mb_height = (2 - p_hal->pp->frame_mbs_only_flag)*(p_hal->pp->wFrameHeightInMbsMinus1 + 1);
mv_size = mb_width * mb_height * 8; // 64bit per 4x4
bit_depth[0] = p_hal->pp->bit_depth_luma_minus8 + 8;
if (p_hal->pp->chroma_format_idc) // Y420 Y422
{
bit_depth[1] = p_hal->pp->bit_depth_chroma_minus8 + 8;
}
else //!< Y400
{
bit_depth[1] = 0;
}
pic_h[0] = mb_height * 16;
if (p_hal->pp->chroma_format_idc == 2) // Y422
{
pic_h[1] = mb_height * 16;
}
else //!< Y420
{
pic_h[1] = mb_height * 8;
}
pic_w[0] = mb_width * 16;
pic_w[1] = mb_width * 16;
sw_y_hor_virstride = ((pic_w[0] * bit_depth[0] + 127) & (~127)) / 128;
sw_uv_hor_virstride = ((pic_w[1] * bit_depth[1] + 127) & (~127)) / 128;
if (sw_y_hor_virstride > p_regs->swreg3_picpar.sw_y_hor_virstride)
{
p_regs->swreg3_picpar.sw_y_hor_virstride = sw_y_hor_virstride;
}
if (sw_uv_hor_virstride > p_regs->swreg3_picpar.sw_uv_hor_virstride)
{
p_regs->swreg3_picpar.sw_uv_hor_virstride = sw_uv_hor_virstride;
}
sw_y_virstride = pic_h[0] * p_regs->swreg3_picpar.sw_y_hor_virstride;
if (sw_y_virstride > p_regs->swreg8_y_virstride.sw_y_virstride)
{
p_regs->swreg8_y_virstride.sw_y_virstride = sw_y_virstride;
}
if (p_hal->pp->chroma_format_idc == 0) // YUV400
{
yuv_virstride = p_regs->swreg8_y_virstride.sw_y_virstride;
}
else
{
yuv_virstride = pic_h[0] * p_regs->swreg3_picpar.sw_y_hor_virstride +
pic_h[1] * p_regs->swreg3_picpar.sw_uv_hor_virstride;
}
if (yuv_virstride > p_regs->swreg9_yuv_virstride.sw_yuv_virstride)
{
p_regs->swreg9_yuv_virstride.sw_yuv_virstride = yuv_virstride;
}
p_regs->compare_len = (p_regs->swreg9_yuv_virstride.sw_yuv_virstride + mv_size) * 2;
if (p_regs->swreg2_sysctrl.sw_h264_rps_mode) // rps_mode == 1
{
p_regs->swreg43_rps_base.sw_rps_base += 0x8;
}
p_regs->swreg3_picpar.sw_slice_num_lowbits = 0x7ff; // p_Vid->iNumOfSlicesDecoded & 0x7ff
p_regs->swreg3_picpar.sw_slice_num_highbit = 1; // (p_Vid->iNumOfSlicesDecoded >> 11) & 1
//!< set current
p_regs->swreg40_cur_poc.sw_cur_poc = p_hal->pp->CurrFieldOrderCnt[0];
p_regs->swreg74_h264_cur_poc1.sw_h264_cur_poc1 = p_hal->pp->CurrFieldOrderCnt[1];
p_regs->swreg7_decout_base.sw_decout_base = p_hal->pp->CurrPic.Index7Bits;
//!< set reference
for (i = 0; i < 15; i++)
{
p_regs->swreg25_39_refer0_14_poc[i] = (i & 1) ? p_hal->pp->FieldOrderCntList[i / 2][1] : p_hal->pp->FieldOrderCntList[i / 2][0];
p_regs->swreg49_63_refer15_29_poc[i] = (i & 1) ? p_hal->pp->FieldOrderCntList[(i + 15) / 2][0] : p_hal->pp->FieldOrderCntList[(i + 15) / 2][1];
p_regs->swreg10_24_refer0_14_base[i].sw_ref_field = (p_hal->pp->RefPicFiledFlags >> i) & 0x01;
p_regs->swreg10_24_refer0_14_base[i].sw_ref_topfield_used = (p_hal->pp->UsedForReferenceFlags >> (2 * i + 0)) & 0x01;
p_regs->swreg10_24_refer0_14_base[i].sw_ref_botfield_used = (p_hal->pp->UsedForReferenceFlags >> (2 * i + 1)) & 0x01;
p_regs->swreg10_24_refer0_14_base[i].sw_ref_colmv_use_flag = (p_hal->pp->RefPicColmvUsedFlags >> i) & 0x01;
if (p_hal->pp->RefFrameList[i].bPicEntry != 0xff)
{
p_regs->swreg10_24_refer0_14_base[i].sw_refer_base = p_hal->pp->RefFrameList[i].Index7Bits;
}
}
p_regs->swreg72_refer30_poc = p_hal->pp->FieldOrderCntList[i][0];
p_regs->swreg73_refer31_poc = p_hal->pp->FieldOrderCntList[i][1];
p_regs->swreg48_refer15_base.sw_ref_field = (p_hal->pp->RefPicFiledFlags >> 15) & 0x01;
p_regs->swreg48_refer15_base.sw_ref_topfield_used = (p_hal->pp->UsedForReferenceFlags >> 30) & 0x01;
p_regs->swreg48_refer15_base.sw_ref_botfield_used = (p_hal->pp->UsedForReferenceFlags >> 31) & 0x01;
p_regs->swreg48_refer15_base.sw_ref_colmv_use_flag = (p_hal->pp->RefPicColmvUsedFlags >> 15) & 0x01;
if (p_hal->pp->RefFrameList[15].bPicEntry != 0xff)
{
p_regs->swreg48_refer15_base.sw_refer_base = p_hal->pp->RefFrameList[15].Index7Bits;
}
fifo_packet_reset(pkt);
fifo_write_bytes(pkt, (void *)p_hal->regs, sizeof(H264_REGS_t));
fifo_write_bytes(pkt, (void *)p_hal->mmu_regs, sizeof(H264_MMU_t));
fifo_write_bytes(pkt, (void *)p_hal->cache_regs, sizeof(H264_CACHE_t));
fifo_align_bits(pkt, 64);
fifo_flush_bits(pkt);
fifo_fwrite_data(pkt); //!< "REGH" header 32 bit
}

View File

@@ -0,0 +1,45 @@
#ifndef __HAL_H264D_PACKET_H__
#define __HAL_H264D_PACKET_H__
#include "rk_type.h"
#include "mpp_err.h"
#include "hal_task.h"
#include "h264d_log.h"
#include "hal_h264d_fifo.h"
typedef struct h264_fifo_packet_t
{
FifoCtx_t spspps;
FifoCtx_t rps;
FifoCtx_t strm;
FifoCtx_t scanlist;
FifoCtx_t reg;
}H264_FifoPkt_t;
#ifdef __cplusplus
extern "C" {
#endif
void reset_fifo_packet(H264_FifoPkt_t *pkt);
void free_fifo_packet (H264_FifoPkt_t *pkt);
MPP_RET alloc_fifo_packet(H264dLogCtx_t *logctx, H264_FifoPkt_t *pkts);
void explain_input_buffer (void *hal, HalDecTask *task);
void prepare_spspps_packet (void *hal, FifoCtx_t *pkt);
void prepare_framerps_packet(void *hal, FifoCtx_t *pkt);
void prepare_scanlist_packet(void *hal, FifoCtx_t *pkt);
void prepare_stream_packet (void *hal, FifoCtx_t *pkt);
void generate_regs (void *hal, FifoCtx_t *pkt);
#ifdef __cplusplus
}
#endif
//!<============================
#endif // __HAL_H264D_PACKET_H__

View File

@@ -0,0 +1,270 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rk_type.h"
#include "mpp_err.h"
#include "mpp_mem.h"
#include "h264d_log.h"
#include "hal_h264d_reg.h"
#define MODULE_TAG "hal_h264d_reg"
const RK_U8 H264_Cabac_table[] =
{
0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0xe4, 0x7f, 0xe9, 0x68,
0xfa, 0x35, 0xff, 0x36, 0x07, 0x33, 0x17, 0x21, 0x17, 0x02, 0x15, 0x00, 0x01, 0x09, 0x00, 0x31,
0xdb, 0x76, 0x05, 0x39, 0xf3, 0x4e, 0xf5, 0x41, 0x01, 0x3e, 0x0c, 0x31, 0xfc, 0x49, 0x11, 0x32,
0x12, 0x40, 0x09, 0x2b, 0x1d, 0x00, 0x1a, 0x43, 0x10, 0x5a, 0x09, 0x68, 0xd2, 0x7f, 0xec, 0x68,
0x01, 0x43, 0xf3, 0x4e, 0xf5, 0x41, 0x01, 0x3e, 0xfa, 0x56, 0xef, 0x5f, 0xfa, 0x3d, 0x09, 0x2d,
0xfd, 0x45, 0xfa, 0x51, 0xf5, 0x60, 0x06, 0x37, 0x07, 0x43, 0xfb, 0x56, 0x02, 0x58, 0x00, 0x3a,
0xfd, 0x4c, 0xf6, 0x5e, 0x05, 0x36, 0x04, 0x45, 0xfd, 0x51, 0x00, 0x58, 0xf9, 0x43, 0xfb, 0x4a,
0xfc, 0x4a, 0xfb, 0x50, 0xf9, 0x48, 0x01, 0x3a, 0x00, 0x29, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
0xf7, 0x53, 0x04, 0x56, 0x00, 0x61, 0xf9, 0x48, 0x0d, 0x29, 0x03, 0x3e, 0x00, 0x2d, 0xfc, 0x4e,
0xfd, 0x60, 0xe5, 0x7e, 0xe4, 0x62, 0xe7, 0x65, 0xe9, 0x43, 0xe4, 0x52, 0xec, 0x5e, 0xf0, 0x53,
0xea, 0x6e, 0xeb, 0x5b, 0xee, 0x66, 0xf3, 0x5d, 0xe3, 0x7f, 0xf9, 0x5c, 0xfb, 0x59, 0xf9, 0x60,
0xf3, 0x6c, 0xfd, 0x2e, 0xff, 0x41, 0xff, 0x39, 0xf7, 0x5d, 0xfd, 0x4a, 0xf7, 0x5c, 0xf8, 0x57,
0xe9, 0x7e, 0x05, 0x36, 0x06, 0x3c, 0x06, 0x3b, 0x06, 0x45, 0xff, 0x30, 0x00, 0x44, 0xfc, 0x45,
0xf8, 0x58, 0xfe, 0x55, 0xfa, 0x4e, 0xff, 0x4b, 0xf9, 0x4d, 0x02, 0x36, 0x05, 0x32, 0xfd, 0x44,
0x01, 0x32, 0x06, 0x2a, 0xfc, 0x51, 0x01, 0x3f, 0xfc, 0x46, 0x00, 0x43, 0x02, 0x39, 0xfe, 0x4c,
0x0b, 0x23, 0x04, 0x40, 0x01, 0x3d, 0x0b, 0x23, 0x12, 0x19, 0x0c, 0x18, 0x0d, 0x1d, 0x0d, 0x24,
0xf6, 0x5d, 0xf9, 0x49, 0xfe, 0x49, 0x0d, 0x2e, 0x09, 0x31, 0xf9, 0x64, 0x09, 0x35, 0x02, 0x35,
0x05, 0x35, 0xfe, 0x3d, 0x00, 0x38, 0x00, 0x38, 0xf3, 0x3f, 0xfb, 0x3c, 0xff, 0x3e, 0x04, 0x39,
0xfa, 0x45, 0x04, 0x39, 0x0e, 0x27, 0x04, 0x33, 0x0d, 0x44, 0x03, 0x40, 0x01, 0x3d, 0x09, 0x3f,
0x07, 0x32, 0x10, 0x27, 0x05, 0x2c, 0x04, 0x34, 0x0b, 0x30, 0xfb, 0x3c, 0xff, 0x3b, 0x00, 0x3b,
0x16, 0x21, 0x05, 0x2c, 0x0e, 0x2b, 0xff, 0x4e, 0x00, 0x3c, 0x09, 0x45, 0x0b, 0x1c, 0x02, 0x28,
0x03, 0x2c, 0x00, 0x31, 0x00, 0x2e, 0x02, 0x2c, 0x02, 0x33, 0x00, 0x2f, 0x04, 0x27, 0x02, 0x3e,
0x06, 0x2e, 0x00, 0x36, 0x03, 0x36, 0x02, 0x3a, 0x04, 0x3f, 0x06, 0x33, 0x06, 0x39, 0x07, 0x35,
0x06, 0x34, 0x06, 0x37, 0x0b, 0x2d, 0x0e, 0x24, 0x08, 0x35, 0xff, 0x52, 0x07, 0x37, 0xfd, 0x4e,
0x0f, 0x2e, 0x16, 0x1f, 0xff, 0x54, 0x19, 0x07, 0x1e, 0xf9, 0x1c, 0x03, 0x1c, 0x04, 0x20, 0x00,
0x22, 0xff, 0x1e, 0x06, 0x1e, 0x06, 0x20, 0x09, 0x1f, 0x13, 0x1a, 0x1b, 0x1a, 0x1e, 0x25, 0x14,
0x1c, 0x22, 0x11, 0x46, 0x01, 0x43, 0x05, 0x3b, 0x09, 0x43, 0x10, 0x1e, 0x12, 0x20, 0x12, 0x23,
0x16, 0x1d, 0x18, 0x1f, 0x17, 0x26, 0x12, 0x2b, 0x14, 0x29, 0x0b, 0x3f, 0x09, 0x3b, 0x09, 0x40,
0xff, 0x5e, 0xfe, 0x59, 0xf7, 0x6c, 0xfa, 0x4c, 0xfe, 0x2c, 0x00, 0x2d, 0x00, 0x34, 0xfd, 0x40,
0xfe, 0x3b, 0xfc, 0x46, 0xfc, 0x4b, 0xf8, 0x52, 0xef, 0x66, 0xf7, 0x4d, 0x03, 0x18, 0x00, 0x2a,
0x00, 0x30, 0x00, 0x37, 0xfa, 0x3b, 0xf9, 0x47, 0xf4, 0x53, 0xf5, 0x57, 0xe2, 0x77, 0x01, 0x3a,
0xfd, 0x1d, 0xff, 0x24, 0x01, 0x26, 0x02, 0x2b, 0xfa, 0x37, 0x00, 0x3a, 0x00, 0x40, 0xfd, 0x4a,
0xf6, 0x5a, 0x00, 0x46, 0xfc, 0x1d, 0x05, 0x1f, 0x07, 0x2a, 0x01, 0x3b, 0xfe, 0x3a, 0xfd, 0x48,
0xfd, 0x51, 0xf5, 0x61, 0x00, 0x3a, 0x08, 0x05, 0x0a, 0x0e, 0x0e, 0x12, 0x0d, 0x1b, 0x02, 0x28,
0x00, 0x3a, 0xfd, 0x46, 0xfa, 0x4f, 0xf8, 0x55, 0x00, 0x00, 0xf3, 0x6a, 0xf0, 0x6a, 0xf6, 0x57,
0xeb, 0x72, 0xee, 0x6e, 0xf2, 0x62, 0xea, 0x6e, 0xeb, 0x6a, 0xee, 0x67, 0xeb, 0x6b, 0xe9, 0x6c,
0xe6, 0x70, 0xf6, 0x60, 0xf4, 0x5f, 0xfb, 0x5b, 0xf7, 0x5d, 0xea, 0x5e, 0xfb, 0x56, 0x09, 0x43,
0xfc, 0x50, 0xf6, 0x55, 0xff, 0x46, 0x07, 0x3c, 0x09, 0x3a, 0x05, 0x3d, 0x0c, 0x32, 0x0f, 0x32,
0x12, 0x31, 0x11, 0x36, 0x0a, 0x29, 0x07, 0x2e, 0xff, 0x33, 0x07, 0x31, 0x08, 0x34, 0x09, 0x29,
0x06, 0x2f, 0x02, 0x37, 0x0d, 0x29, 0x0a, 0x2c, 0x06, 0x32, 0x05, 0x35, 0x0d, 0x31, 0x04, 0x3f,
0x06, 0x40, 0xfe, 0x45, 0xfe, 0x3b, 0x06, 0x46, 0x0a, 0x2c, 0x09, 0x1f, 0x0c, 0x2b, 0x03, 0x35,
0x0e, 0x22, 0x0a, 0x26, 0xfd, 0x34, 0x0d, 0x28, 0x11, 0x20, 0x07, 0x2c, 0x07, 0x26, 0x0d, 0x32,
0x0a, 0x39, 0x1a, 0x2b, 0x0e, 0x0b, 0x0b, 0x0e, 0x09, 0x0b, 0x12, 0x0b, 0x15, 0x09, 0x17, 0xfe,
0x20, 0xf1, 0x20, 0xf1, 0x22, 0xeb, 0x27, 0xe9, 0x2a, 0xdf, 0x29, 0xe1, 0x2e, 0xe4, 0x26, 0xf4,
0x15, 0x1d, 0x2d, 0xe8, 0x35, 0xd3, 0x30, 0xe6, 0x41, 0xd5, 0x2b, 0xed, 0x27, 0xf6, 0x1e, 0x09,
0x12, 0x1a, 0x14, 0x1b, 0x00, 0x39, 0xf2, 0x52, 0xfb, 0x4b, 0xed, 0x61, 0xdd, 0x7d, 0x1b, 0x00,
0x1c, 0x00, 0x1f, 0xfc, 0x1b, 0x06, 0x22, 0x08, 0x1e, 0x0a, 0x18, 0x16, 0x21, 0x13, 0x16, 0x20,
0x1a, 0x1f, 0x15, 0x29, 0x1a, 0x2c, 0x17, 0x2f, 0x10, 0x41, 0x0e, 0x47, 0x08, 0x3c, 0x06, 0x3f,
0x11, 0x41, 0x15, 0x18, 0x17, 0x14, 0x1a, 0x17, 0x1b, 0x20, 0x1c, 0x17, 0x1c, 0x18, 0x17, 0x28,
0x18, 0x20, 0x1c, 0x1d, 0x17, 0x2a, 0x13, 0x39, 0x16, 0x35, 0x16, 0x3d, 0x0b, 0x56, 0x0c, 0x28,
0x0b, 0x33, 0x0e, 0x3b, 0xfc, 0x4f, 0xf9, 0x47, 0xfb, 0x45, 0xf7, 0x46, 0xf8, 0x42, 0xf6, 0x44,
0xed, 0x49, 0xf4, 0x45, 0xf0, 0x46, 0xf1, 0x43, 0xec, 0x3e, 0xed, 0x46, 0xf0, 0x42, 0xea, 0x41,
0xec, 0x3f, 0x09, 0xfe, 0x1a, 0xf7, 0x21, 0xf7, 0x27, 0xf9, 0x29, 0xfe, 0x2d, 0x03, 0x31, 0x09,
0x2d, 0x1b, 0x24, 0x3b, 0xfa, 0x42, 0xf9, 0x23, 0xf9, 0x2a, 0xf8, 0x2d, 0xfb, 0x30, 0xf4, 0x38,
0xfa, 0x3c, 0xfb, 0x3e, 0xf8, 0x42, 0xf8, 0x4c, 0xfb, 0x55, 0xfa, 0x51, 0xf6, 0x4d, 0xf9, 0x51,
0xef, 0x50, 0xee, 0x49, 0xfc, 0x4a, 0xf6, 0x53, 0xf7, 0x47, 0xf7, 0x43, 0xff, 0x3d, 0xf8, 0x42,
0xf2, 0x42, 0x00, 0x3b, 0x02, 0x3b, 0x15, 0xf3, 0x21, 0xf2, 0x27, 0xf9, 0x2e, 0xfe, 0x33, 0x02,
0x3c, 0x06, 0x3d, 0x11, 0x37, 0x22, 0x2a, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0xe4, 0x7f, 0xe9, 0x68,
0xfa, 0x35, 0xff, 0x36, 0x07, 0x33, 0x16, 0x19, 0x22, 0x00, 0x10, 0x00, 0xfe, 0x09, 0x04, 0x29,
0xe3, 0x76, 0x02, 0x41, 0xfa, 0x47, 0xf3, 0x4f, 0x05, 0x34, 0x09, 0x32, 0xfd, 0x46, 0x0a, 0x36,
0x1a, 0x22, 0x13, 0x16, 0x28, 0x00, 0x39, 0x02, 0x29, 0x24, 0x1a, 0x45, 0xd3, 0x7f, 0xf1, 0x65,
0xfc, 0x4c, 0xfa, 0x47, 0xf3, 0x4f, 0x05, 0x34, 0x06, 0x45, 0xf3, 0x5a, 0x00, 0x34, 0x08, 0x2b,
0xfe, 0x45, 0xfb, 0x52, 0xf6, 0x60, 0x02, 0x3b, 0x02, 0x4b, 0xfd, 0x57, 0xfd, 0x64, 0x01, 0x38,
0xfd, 0x4a, 0xfa, 0x55, 0x00, 0x3b, 0xfd, 0x51, 0xf9, 0x56, 0xfb, 0x5f, 0xff, 0x42, 0xff, 0x4d,
0x01, 0x46, 0xfe, 0x56, 0xfb, 0x48, 0x00, 0x3d, 0x00, 0x29, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
0xf7, 0x53, 0x04, 0x56, 0x00, 0x61, 0xf9, 0x48, 0x0d, 0x29, 0x03, 0x3e, 0x0d, 0x0f, 0x07, 0x33,
0x02, 0x50, 0xd9, 0x7f, 0xee, 0x5b, 0xef, 0x60, 0xe6, 0x51, 0xdd, 0x62, 0xe8, 0x66, 0xe9, 0x61,
0xe5, 0x77, 0xe8, 0x63, 0xeb, 0x6e, 0xee, 0x66, 0xdc, 0x7f, 0x00, 0x50, 0xfb, 0x59, 0xf9, 0x5e,
0xfc, 0x5c, 0x00, 0x27, 0x00, 0x41, 0xf1, 0x54, 0xdd, 0x7f, 0xfe, 0x49, 0xf4, 0x68, 0xf7, 0x5b,
0xe1, 0x7f, 0x03, 0x37, 0x07, 0x38, 0x07, 0x37, 0x08, 0x3d, 0xfd, 0x35, 0x00, 0x44, 0xf9, 0x4a,
0xf7, 0x58, 0xf3, 0x67, 0xf3, 0x5b, 0xf7, 0x59, 0xf2, 0x5c, 0xf8, 0x4c, 0xf4, 0x57, 0xe9, 0x6e,
0xe8, 0x69, 0xf6, 0x4e, 0xec, 0x70, 0xef, 0x63, 0xb2, 0x7f, 0xba, 0x7f, 0xce, 0x7f, 0xd2, 0x7f,
0xfc, 0x42, 0xfb, 0x4e, 0xfc, 0x47, 0xf8, 0x48, 0x02, 0x3b, 0xff, 0x37, 0xf9, 0x46, 0xfa, 0x4b,
0xf8, 0x59, 0xde, 0x77, 0xfd, 0x4b, 0x20, 0x14, 0x1e, 0x16, 0xd4, 0x7f, 0x00, 0x36, 0xfb, 0x3d,
0x00, 0x3a, 0xff, 0x3c, 0xfd, 0x3d, 0xf8, 0x43, 0xe7, 0x54, 0xf2, 0x4a, 0xfb, 0x41, 0x05, 0x34,
0x02, 0x39, 0x00, 0x3d, 0xf7, 0x45, 0xf5, 0x46, 0x12, 0x37, 0xfc, 0x47, 0x00, 0x3a, 0x07, 0x3d,
0x09, 0x29, 0x12, 0x19, 0x09, 0x20, 0x05, 0x2b, 0x09, 0x2f, 0x00, 0x2c, 0x00, 0x33, 0x02, 0x2e,
0x13, 0x26, 0xfc, 0x42, 0x0f, 0x26, 0x0c, 0x2a, 0x09, 0x22, 0x00, 0x59, 0x04, 0x2d, 0x0a, 0x1c,
0x0a, 0x1f, 0x21, 0xf5, 0x34, 0xd5, 0x12, 0x0f, 0x1c, 0x00, 0x23, 0xea, 0x26, 0xe7, 0x22, 0x00,
0x27, 0xee, 0x20, 0xf4, 0x66, 0xa2, 0x00, 0x00, 0x38, 0xf1, 0x21, 0xfc, 0x1d, 0x0a, 0x25, 0xfb,
0x33, 0xe3, 0x27, 0xf7, 0x34, 0xde, 0x45, 0xc6, 0x43, 0xc1, 0x2c, 0xfb, 0x20, 0x07, 0x37, 0xe3,
0x20, 0x01, 0x00, 0x00, 0x1b, 0x24, 0x21, 0xe7, 0x22, 0xe2, 0x24, 0xe4, 0x26, 0xe4, 0x26, 0xe5,
0x22, 0xee, 0x23, 0xf0, 0x22, 0xf2, 0x20, 0xf8, 0x25, 0xfa, 0x23, 0x00, 0x1e, 0x0a, 0x1c, 0x12,
0x1a, 0x19, 0x1d, 0x29, 0x00, 0x4b, 0x02, 0x48, 0x08, 0x4d, 0x0e, 0x23, 0x12, 0x1f, 0x11, 0x23,
0x15, 0x1e, 0x11, 0x2d, 0x14, 0x2a, 0x12, 0x2d, 0x1b, 0x1a, 0x10, 0x36, 0x07, 0x42, 0x10, 0x38,
0x0b, 0x49, 0x0a, 0x43, 0xf6, 0x74, 0xe9, 0x70, 0xf1, 0x47, 0xf9, 0x3d, 0x00, 0x35, 0xfb, 0x42,
0xf5, 0x4d, 0xf7, 0x50, 0xf7, 0x54, 0xf6, 0x57, 0xde, 0x7f, 0xeb, 0x65, 0xfd, 0x27, 0xfb, 0x35,
0xf9, 0x3d, 0xf5, 0x4b, 0xf1, 0x4d, 0xef, 0x5b, 0xe7, 0x6b, 0xe7, 0x6f, 0xe4, 0x7a, 0xf5, 0x4c,
0xf6, 0x2c, 0xf6, 0x34, 0xf6, 0x39, 0xf7, 0x3a, 0xf0, 0x48, 0xf9, 0x45, 0xfc, 0x45, 0xfb, 0x4a,
0xf7, 0x56, 0x02, 0x42, 0xf7, 0x22, 0x01, 0x20, 0x0b, 0x1f, 0x05, 0x34, 0xfe, 0x37, 0xfe, 0x43,
0x00, 0x49, 0xf8, 0x59, 0x03, 0x34, 0x07, 0x04, 0x0a, 0x08, 0x11, 0x08, 0x10, 0x13, 0x03, 0x25,
0xff, 0x3d, 0xfb, 0x49, 0xff, 0x46, 0xfc, 0x4e, 0x00, 0x00, 0xeb, 0x7e, 0xe9, 0x7c, 0xec, 0x6e,
0xe6, 0x7e, 0xe7, 0x7c, 0xef, 0x69, 0xe5, 0x79, 0xe5, 0x75, 0xef, 0x66, 0xe6, 0x75, 0xe5, 0x74,
0xdf, 0x7a, 0xf6, 0x5f, 0xf2, 0x64, 0xf8, 0x5f, 0xef, 0x6f, 0xe4, 0x72, 0xfa, 0x59, 0xfe, 0x50,
0xfc, 0x52, 0xf7, 0x55, 0xf8, 0x51, 0xff, 0x48, 0x05, 0x40, 0x01, 0x43, 0x09, 0x38, 0x00, 0x45,
0x01, 0x45, 0x07, 0x45, 0xf9, 0x45, 0xfa, 0x43, 0xf0, 0x4d, 0xfe, 0x40, 0x02, 0x3d, 0xfa, 0x43,
0xfd, 0x40, 0x02, 0x39, 0xfd, 0x41, 0xfd, 0x42, 0x00, 0x3e, 0x09, 0x33, 0xff, 0x42, 0xfe, 0x47,
0xfe, 0x4b, 0xff, 0x46, 0xf7, 0x48, 0x0e, 0x3c, 0x10, 0x25, 0x00, 0x2f, 0x12, 0x23, 0x0b, 0x25,
0x0c, 0x29, 0x0a, 0x29, 0x02, 0x30, 0x0c, 0x29, 0x0d, 0x29, 0x00, 0x3b, 0x03, 0x32, 0x13, 0x28,
0x03, 0x42, 0x12, 0x32, 0x13, 0xfa, 0x12, 0xfa, 0x0e, 0x00, 0x1a, 0xf4, 0x1f, 0xf0, 0x21, 0xe7,
0x21, 0xea, 0x25, 0xe4, 0x27, 0xe2, 0x2a, 0xe2, 0x2f, 0xd6, 0x2d, 0xdc, 0x31, 0xde, 0x29, 0xef,
0x20, 0x09, 0x45, 0xb9, 0x3f, 0xc1, 0x42, 0xc0, 0x4d, 0xb6, 0x36, 0xd9, 0x34, 0xdd, 0x29, 0xf6,
0x24, 0x00, 0x28, 0xff, 0x1e, 0x0e, 0x1c, 0x1a, 0x17, 0x25, 0x0c, 0x37, 0x0b, 0x41, 0x25, 0xdf,
0x27, 0xdc, 0x28, 0xdb, 0x26, 0xe2, 0x2e, 0xdf, 0x2a, 0xe2, 0x28, 0xe8, 0x31, 0xe3, 0x26, 0xf4,
0x28, 0xf6, 0x26, 0xfd, 0x2e, 0xfb, 0x1f, 0x14, 0x1d, 0x1e, 0x19, 0x2c, 0x0c, 0x30, 0x0b, 0x31,
0x1a, 0x2d, 0x16, 0x16, 0x17, 0x16, 0x1b, 0x15, 0x21, 0x14, 0x1a, 0x1c, 0x1e, 0x18, 0x1b, 0x22,
0x12, 0x2a, 0x19, 0x27, 0x12, 0x32, 0x0c, 0x46, 0x15, 0x36, 0x0e, 0x47, 0x0b, 0x53, 0x19, 0x20,
0x15, 0x31, 0x15, 0x36, 0xfb, 0x55, 0xfa, 0x51, 0xf6, 0x4d, 0xf9, 0x51, 0xef, 0x50, 0xee, 0x49,
0xfc, 0x4a, 0xf6, 0x53, 0xf7, 0x47, 0xf7, 0x43, 0xff, 0x3d, 0xf8, 0x42, 0xf2, 0x42, 0x00, 0x3b,
0x02, 0x3b, 0x11, 0xf6, 0x20, 0xf3, 0x2a, 0xf7, 0x31, 0xfb, 0x35, 0x00, 0x40, 0x03, 0x44, 0x0a,
0x42, 0x1b, 0x2f, 0x39, 0xfb, 0x47, 0x00, 0x18, 0xff, 0x24, 0xfe, 0x2a, 0xfe, 0x34, 0xf7, 0x39,
0xfa, 0x3f, 0xfc, 0x41, 0xfc, 0x43, 0xf9, 0x52, 0xfd, 0x51, 0xfd, 0x4c, 0xf9, 0x48, 0xfa, 0x4e,
0xf4, 0x48, 0xf2, 0x44, 0xfd, 0x46, 0xfa, 0x4c, 0xfb, 0x42, 0xfb, 0x3e, 0x00, 0x39, 0xfc, 0x3d,
0xf7, 0x3c, 0x01, 0x36, 0x02, 0x3a, 0x11, 0xf6, 0x20, 0xf3, 0x2a, 0xf7, 0x31, 0xfb, 0x35, 0x00,
0x40, 0x03, 0x44, 0x0a, 0x42, 0x1b, 0x2f, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0xe4, 0x7f, 0xe9, 0x68,
0xfa, 0x35, 0xff, 0x36, 0x07, 0x33, 0x1d, 0x10, 0x19, 0x00, 0x0e, 0x00, 0xf6, 0x33, 0xfd, 0x3e,
0xe5, 0x63, 0x1a, 0x10, 0xfc, 0x55, 0xe8, 0x66, 0x05, 0x39, 0x06, 0x39, 0xef, 0x49, 0x0e, 0x39,
0x14, 0x28, 0x14, 0x0a, 0x1d, 0x00, 0x36, 0x00, 0x25, 0x2a, 0x0c, 0x61, 0xe0, 0x7f, 0xea, 0x75,
0xfe, 0x4a, 0xfc, 0x55, 0xe8, 0x66, 0x05, 0x39, 0xfa, 0x5d, 0xf2, 0x58, 0xfa, 0x2c, 0x04, 0x37,
0xf5, 0x59, 0xf1, 0x67, 0xeb, 0x74, 0x13, 0x39, 0x14, 0x3a, 0x04, 0x54, 0x06, 0x60, 0x01, 0x3f,
0xfb, 0x55, 0xf3, 0x6a, 0x05, 0x3f, 0x06, 0x4b, 0xfd, 0x5a, 0xff, 0x65, 0x03, 0x37, 0xfc, 0x4f,
0xfe, 0x4b, 0xf4, 0x61, 0xf9, 0x32, 0x01, 0x3c, 0x00, 0x29, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
0xf7, 0x53, 0x04, 0x56, 0x00, 0x61, 0xf9, 0x48, 0x0d, 0x29, 0x03, 0x3e, 0x07, 0x22, 0xf7, 0x58,
0xec, 0x7f, 0xdc, 0x7f, 0xef, 0x5b, 0xf2, 0x5f, 0xe7, 0x54, 0xe7, 0x56, 0xf4, 0x59, 0xef, 0x5b,
0xe1, 0x7f, 0xf2, 0x4c, 0xee, 0x67, 0xf3, 0x5a, 0xdb, 0x7f, 0x0b, 0x50, 0x05, 0x4c, 0x02, 0x54,
0x05, 0x4e, 0xfa, 0x37, 0x04, 0x3d, 0xf2, 0x53, 0xdb, 0x7f, 0xfb, 0x4f, 0xf5, 0x68, 0xf5, 0x5b,
0xe2, 0x7f, 0x00, 0x41, 0xfe, 0x4f, 0x00, 0x48, 0xfc, 0x5c, 0xfa, 0x38, 0x03, 0x44, 0xf8, 0x47,
0xf3, 0x62, 0xfc, 0x56, 0xf4, 0x58, 0xfb, 0x52, 0xfd, 0x48, 0xfc, 0x43, 0xf8, 0x48, 0xf0, 0x59,
0xf7, 0x45, 0xff, 0x3b, 0x05, 0x42, 0x04, 0x39, 0xfc, 0x47, 0xfe, 0x47, 0x02, 0x3a, 0xff, 0x4a,
0xfc, 0x2c, 0xff, 0x45, 0x00, 0x3e, 0xf9, 0x33, 0xfc, 0x2f, 0xfa, 0x2a, 0xfd, 0x29, 0xfa, 0x35,
0x08, 0x4c, 0xf7, 0x4e, 0xf5, 0x53, 0x09, 0x34, 0x00, 0x43, 0xfb, 0x5a, 0x01, 0x43, 0xf1, 0x48,
0xfb, 0x4b, 0xf8, 0x50, 0xeb, 0x53, 0xeb, 0x40, 0xf3, 0x1f, 0xe7, 0x40, 0xe3, 0x5e, 0x09, 0x4b,
0x11, 0x3f, 0xf8, 0x4a, 0xfb, 0x23, 0xfe, 0x1b, 0x0d, 0x5b, 0x03, 0x41, 0xf9, 0x45, 0x08, 0x4d,
0xf6, 0x42, 0x03, 0x3e, 0xfd, 0x44, 0xec, 0x51, 0x00, 0x1e, 0x01, 0x07, 0xfd, 0x17, 0xeb, 0x4a,
0x10, 0x42, 0xe9, 0x7c, 0x11, 0x25, 0x2c, 0xee, 0x32, 0xde, 0xea, 0x7f, 0x04, 0x27, 0x00, 0x2a,
0x07, 0x22, 0x0b, 0x1d, 0x08, 0x1f, 0x06, 0x25, 0x07, 0x2a, 0x03, 0x28, 0x08, 0x21, 0x0d, 0x2b,
0x0d, 0x24, 0x04, 0x2f, 0x03, 0x37, 0x02, 0x3a, 0x06, 0x3c, 0x08, 0x2c, 0x0b, 0x2c, 0x0e, 0x2a,
0x07, 0x30, 0x04, 0x38, 0x04, 0x34, 0x0d, 0x25, 0x09, 0x31, 0x13, 0x3a, 0x0a, 0x30, 0x0c, 0x2d,
0x00, 0x45, 0x14, 0x21, 0x08, 0x3f, 0x23, 0xee, 0x21, 0xe7, 0x1c, 0xfd, 0x18, 0x0a, 0x1b, 0x00,
0x22, 0xf2, 0x34, 0xd4, 0x27, 0xe8, 0x13, 0x11, 0x1f, 0x19, 0x24, 0x1d, 0x18, 0x21, 0x22, 0x0f,
0x1e, 0x14, 0x16, 0x49, 0x14, 0x22, 0x13, 0x1f, 0x1b, 0x2c, 0x13, 0x10, 0x0f, 0x24, 0x0f, 0x24,
0x15, 0x1c, 0x19, 0x15, 0x1e, 0x14, 0x1f, 0x0c, 0x1b, 0x10, 0x18, 0x2a, 0x00, 0x5d, 0x0e, 0x38,
0x0f, 0x39, 0x1a, 0x26, 0xe8, 0x7f, 0xe8, 0x73, 0xea, 0x52, 0xf7, 0x3e, 0x00, 0x35, 0x00, 0x3b,
0xf2, 0x55, 0xf3, 0x59, 0xf3, 0x5e, 0xf5, 0x5c, 0xe3, 0x7f, 0xeb, 0x64, 0xf2, 0x39, 0xf4, 0x43,
0xf5, 0x47, 0xf6, 0x4d, 0xeb, 0x55, 0xf0, 0x58, 0xe9, 0x68, 0xf1, 0x62, 0xdb, 0x7f, 0xf6, 0x52,
0xf8, 0x30, 0xf8, 0x3d, 0xf8, 0x42, 0xf9, 0x46, 0xf2, 0x4b, 0xf6, 0x4f, 0xf7, 0x53, 0xf4, 0x5c,
0xee, 0x6c, 0xfc, 0x4f, 0xea, 0x45, 0xf0, 0x4b, 0xfe, 0x3a, 0x01, 0x3a, 0xf3, 0x4e, 0xf7, 0x53,
0xfc, 0x51, 0xf3, 0x63, 0xf3, 0x51, 0xfa, 0x26, 0xf3, 0x3e, 0xfa, 0x3a, 0xfe, 0x3b, 0xf0, 0x49,
0xf6, 0x4c, 0xf3, 0x56, 0xf7, 0x53, 0xf6, 0x57, 0x00, 0x00, 0xea, 0x7f, 0xe7, 0x7f, 0xe7, 0x78,
0xe5, 0x7f, 0xed, 0x72, 0xe9, 0x75, 0xe7, 0x76, 0xe6, 0x75, 0xe8, 0x71, 0xe4, 0x76, 0xe1, 0x78,
0xdb, 0x7c, 0xf6, 0x5e, 0xf1, 0x66, 0xf6, 0x63, 0xf3, 0x6a, 0xce, 0x7f, 0xfb, 0x5c, 0x11, 0x39,
0xfb, 0x56, 0xf3, 0x5e, 0xf4, 0x5b, 0xfe, 0x4d, 0x00, 0x47, 0xff, 0x49, 0x04, 0x40, 0xf9, 0x51,
0x05, 0x40, 0x0f, 0x39, 0x01, 0x43, 0x00, 0x44, 0xf6, 0x43, 0x01, 0x44, 0x00, 0x4d, 0x02, 0x40,
0x00, 0x44, 0xfb, 0x4e, 0x07, 0x37, 0x05, 0x3b, 0x02, 0x41, 0x0e, 0x36, 0x0f, 0x2c, 0x05, 0x3c,
0x02, 0x46, 0xfe, 0x4c, 0xee, 0x56, 0x0c, 0x46, 0x05, 0x40, 0xf4, 0x46, 0x0b, 0x37, 0x05, 0x38,
0x00, 0x45, 0x02, 0x41, 0xfa, 0x4a, 0x05, 0x36, 0x07, 0x36, 0xfa, 0x4c, 0xf5, 0x52, 0xfe, 0x4d,
0xfe, 0x4d, 0x19, 0x2a, 0x11, 0xf3, 0x10, 0xf7, 0x11, 0xf4, 0x1b, 0xeb, 0x25, 0xe2, 0x29, 0xd8,
0x2a, 0xd7, 0x30, 0xd1, 0x27, 0xe0, 0x2e, 0xd8, 0x34, 0xcd, 0x2e, 0xd7, 0x34, 0xd9, 0x2b, 0xed,
0x20, 0x0b, 0x3d, 0xc9, 0x38, 0xd2, 0x3e, 0xce, 0x51, 0xbd, 0x2d, 0xec, 0x23, 0xfe, 0x1c, 0x0f,
0x22, 0x01, 0x27, 0x01, 0x1e, 0x11, 0x14, 0x26, 0x12, 0x2d, 0x0f, 0x36, 0x00, 0x4f, 0x24, 0xf0,
0x25, 0xf2, 0x25, 0xef, 0x20, 0x01, 0x22, 0x0f, 0x1d, 0x0f, 0x18, 0x19, 0x22, 0x16, 0x1f, 0x10,
0x23, 0x12, 0x1f, 0x1c, 0x21, 0x29, 0x24, 0x1c, 0x1b, 0x2f, 0x15, 0x3e, 0x12, 0x1f, 0x13, 0x1a,
0x24, 0x18, 0x18, 0x17, 0x1b, 0x10, 0x18, 0x1e, 0x1f, 0x1d, 0x16, 0x29, 0x16, 0x2a, 0x10, 0x3c,
0x0f, 0x34, 0x0e, 0x3c, 0x03, 0x4e, 0xf0, 0x7b, 0x15, 0x35, 0x16, 0x38, 0x19, 0x3d, 0x15, 0x21,
0x13, 0x32, 0x11, 0x3d, 0xfd, 0x4e, 0xf8, 0x4a, 0xf7, 0x48, 0xf6, 0x48, 0xee, 0x4b, 0xf4, 0x47,
0xf5, 0x3f, 0xfb, 0x46, 0xef, 0x4b, 0xf2, 0x48, 0xf0, 0x43, 0xf8, 0x35, 0xf2, 0x3b, 0xf7, 0x34,
0xf5, 0x44, 0x09, 0xfe, 0x1e, 0xf6, 0x1f, 0xfc, 0x21, 0xff, 0x21, 0x07, 0x1f, 0x0c, 0x25, 0x17,
0x1f, 0x26, 0x14, 0x40, 0xf7, 0x47, 0xf9, 0x25, 0xf8, 0x2c, 0xf5, 0x31, 0xf6, 0x38, 0xf4, 0x3b,
0xf8, 0x3f, 0xf7, 0x43, 0xfa, 0x44, 0xf6, 0x4f, 0xfd, 0x4e, 0xf8, 0x4a, 0xf7, 0x48, 0xf6, 0x48,
0xee, 0x4b, 0xf4, 0x47, 0xf5, 0x3f, 0xfb, 0x46, 0xef, 0x4b, 0xf2, 0x48, 0xf0, 0x43, 0xf8, 0x35,
0xf2, 0x3b, 0xf7, 0x34, 0xf5, 0x44, 0x09, 0xfe, 0x1e, 0xf6, 0x1f, 0xfc, 0x21, 0xff, 0x21, 0x07,
0x1f, 0x0c, 0x25, 0x17, 0x1f, 0x26, 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0x14, 0xf1, 0x02, 0x36, 0x03, 0x4a, 0xe4, 0x7f, 0xe9, 0x68,
0xfa, 0x35, 0xff, 0x36, 0x07, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
0xf7, 0x53, 0x04, 0x56, 0x00, 0x61, 0xf9, 0x48, 0x0d, 0x29, 0x03, 0x3e, 0x00, 0x0b, 0x01, 0x37,
0x00, 0x45, 0xef, 0x7f, 0xf3, 0x66, 0x00, 0x52, 0xf9, 0x4a, 0xeb, 0x6b, 0xe5, 0x7f, 0xe1, 0x7f,
0xe8, 0x7f, 0xee, 0x5f, 0xe5, 0x7f, 0xeb, 0x72, 0xe2, 0x7f, 0xef, 0x7b, 0xf4, 0x73, 0xf0, 0x7a,
0xf5, 0x73, 0xf4, 0x3f, 0xfe, 0x44, 0xf1, 0x54, 0xf3, 0x68, 0xfd, 0x46, 0xf8, 0x5d, 0xf6, 0x5a,
0xe2, 0x7f, 0xff, 0x4a, 0xfa, 0x61, 0xf9, 0x5b, 0xec, 0x7f, 0xfc, 0x38, 0xfb, 0x52, 0xf9, 0x4c,
0xea, 0x7d, 0xf9, 0x5d, 0xf5, 0x57, 0xfd, 0x4d, 0xfb, 0x47, 0xfc, 0x3f, 0xfc, 0x44, 0xf4, 0x54,
0xf9, 0x3e, 0xf9, 0x41, 0x08, 0x3d, 0x05, 0x38, 0xfe, 0x42, 0x01, 0x40, 0x00, 0x3d, 0xfe, 0x4e,
0x01, 0x32, 0x07, 0x34, 0x0a, 0x23, 0x00, 0x2c, 0x0b, 0x26, 0x01, 0x2d, 0x00, 0x2e, 0x05, 0x2c,
0x1f, 0x11, 0x01, 0x33, 0x07, 0x32, 0x1c, 0x13, 0x10, 0x21, 0x0e, 0x3e, 0xf3, 0x6c, 0xf1, 0x64,
0xf3, 0x65, 0xf3, 0x5b, 0xf4, 0x5e, 0xf6, 0x58, 0xf0, 0x54, 0xf6, 0x56, 0xf9, 0x53, 0xf3, 0x57,
0xed, 0x5e, 0x01, 0x46, 0x00, 0x48, 0xfb, 0x4a, 0x12, 0x3b, 0xf8, 0x66, 0xf1, 0x64, 0x00, 0x5f,
0xfc, 0x4b, 0x02, 0x48, 0xf5, 0x4b, 0xfd, 0x47, 0x0f, 0x2e, 0xf3, 0x45, 0x00, 0x3e, 0x00, 0x41,
0x15, 0x25, 0xf1, 0x48, 0x09, 0x39, 0x10, 0x36, 0x00, 0x3e, 0x0c, 0x48, 0x18, 0x00, 0x0f, 0x09,
0x08, 0x19, 0x0d, 0x12, 0x0f, 0x09, 0x0d, 0x13, 0x0a, 0x25, 0x0c, 0x12, 0x06, 0x1d, 0x14, 0x21,
0x0f, 0x1e, 0x04, 0x2d, 0x01, 0x3a, 0x00, 0x3e, 0x07, 0x3d, 0x0c, 0x26, 0x0b, 0x2d, 0x0f, 0x27,
0x0b, 0x2a, 0x0d, 0x2c, 0x10, 0x2d, 0x0c, 0x29, 0x0a, 0x31, 0x1e, 0x22, 0x12, 0x2a, 0x0a, 0x37,
0x11, 0x33, 0x11, 0x2e, 0x00, 0x59, 0x1a, 0xed, 0x16, 0xef, 0x1a, 0xef, 0x1e, 0xe7, 0x1c, 0xec,
0x21, 0xe9, 0x25, 0xe5, 0x21, 0xe9, 0x28, 0xe4, 0x26, 0xef, 0x21, 0xf5, 0x28, 0xf1, 0x29, 0xfa,
0x26, 0x01, 0x29, 0x11, 0x1e, 0xfa, 0x1b, 0x03, 0x1a, 0x16, 0x25, 0xf0, 0x23, 0xfc, 0x26, 0xf8,
0x26, 0xfd, 0x25, 0x03, 0x26, 0x05, 0x2a, 0x00, 0x23, 0x10, 0x27, 0x16, 0x0e, 0x30, 0x1b, 0x25,
0x15, 0x3c, 0x0c, 0x44, 0x02, 0x61, 0xfd, 0x47, 0xfa, 0x2a, 0xfb, 0x32, 0xfd, 0x36, 0xfe, 0x3e,
0x00, 0x3a, 0x01, 0x3f, 0xfe, 0x48, 0xff, 0x4a, 0xf7, 0x5b, 0xfb, 0x43, 0xfb, 0x1b, 0xfd, 0x27,
0xfe, 0x2c, 0x00, 0x2e, 0xf0, 0x40, 0xf8, 0x44, 0xf6, 0x4e, 0xfa, 0x4d, 0xf6, 0x56, 0xf4, 0x5c,
0xf1, 0x37, 0xf6, 0x3c, 0xfa, 0x3e, 0xfc, 0x41, 0xf4, 0x49, 0xf8, 0x4c, 0xf9, 0x50, 0xf7, 0x58,
0xef, 0x6e, 0xf5, 0x61, 0xec, 0x54, 0xf5, 0x4f, 0xfa, 0x49, 0xfc, 0x4a, 0xf3, 0x56, 0xf3, 0x60,
0xf5, 0x61, 0xed, 0x75, 0xf8, 0x4e, 0xfb, 0x21, 0xfc, 0x30, 0xfe, 0x35, 0xfd, 0x3e, 0xf3, 0x47,
0xf6, 0x4f, 0xf4, 0x56, 0xf3, 0x5a, 0xf2, 0x61, 0x00, 0x00, 0xfa, 0x5d, 0xfa, 0x54, 0xf8, 0x4f,
0x00, 0x42, 0xff, 0x47, 0x00, 0x3e, 0xfe, 0x3c, 0xfe, 0x3b, 0xfb, 0x4b, 0xfd, 0x3e, 0xfc, 0x3a,
0xf7, 0x42, 0xff, 0x4f, 0x00, 0x47, 0x03, 0x44, 0x0a, 0x2c, 0xf9, 0x3e, 0x0f, 0x24, 0x0e, 0x28,
0x10, 0x1b, 0x0c, 0x1d, 0x01, 0x2c, 0x14, 0x24, 0x12, 0x20, 0x05, 0x2a, 0x01, 0x30, 0x0a, 0x3e,
0x11, 0x2e, 0x09, 0x40, 0xf4, 0x68, 0xf5, 0x61, 0xf0, 0x60, 0xf9, 0x58, 0xf8, 0x55, 0xf9, 0x55,
0xf7, 0x55, 0xf3, 0x58, 0x04, 0x42, 0xfd, 0x4d, 0xfd, 0x4c, 0xfa, 0x4c, 0x0a, 0x3a, 0xff, 0x4c,
0xff, 0x53, 0xf9, 0x63, 0xf2, 0x5f, 0x02, 0x5f, 0x00, 0x4c, 0xfb, 0x4a, 0x00, 0x46, 0xf5, 0x4b,
0x01, 0x44, 0x00, 0x41, 0xf2, 0x49, 0x03, 0x3e, 0x04, 0x3e, 0xff, 0x44, 0xf3, 0x4b, 0x0b, 0x37,
0x05, 0x40, 0x0c, 0x46, 0x0f, 0x06, 0x06, 0x13, 0x07, 0x10, 0x0c, 0x0e, 0x12, 0x0d, 0x0d, 0x0b,
0x0d, 0x0f, 0x0f, 0x10, 0x0c, 0x17, 0x0d, 0x17, 0x0f, 0x14, 0x0e, 0x1a, 0x0e, 0x2c, 0x11, 0x28,
0x11, 0x2f, 0x18, 0x11, 0x15, 0x15, 0x19, 0x16, 0x1f, 0x1b, 0x16, 0x1d, 0x13, 0x23, 0x0e, 0x32,
0x0a, 0x39, 0x07, 0x3f, 0xfe, 0x4d, 0xfc, 0x52, 0xfd, 0x5e, 0x09, 0x45, 0xf4, 0x6d, 0x24, 0xdd,
0x24, 0xde, 0x20, 0xe6, 0x25, 0xe2, 0x2c, 0xe0, 0x22, 0xee, 0x22, 0xf1, 0x28, 0xf1, 0x21, 0xf9,
0x23, 0xfb, 0x21, 0x00, 0x26, 0x02, 0x21, 0x0d, 0x17, 0x23, 0x0d, 0x3a, 0x1d, 0xfd, 0x1a, 0x00,
0x16, 0x1e, 0x1f, 0xf9, 0x23, 0xf1, 0x22, 0xfd, 0x22, 0x03, 0x24, 0xff, 0x22, 0x05, 0x20, 0x0b,
0x23, 0x05, 0x22, 0x0c, 0x27, 0x0b, 0x1e, 0x1d, 0x22, 0x1a, 0x1d, 0x27, 0x13, 0x42, 0x1f, 0x15,
0x1f, 0x1f, 0x19, 0x32, 0xef, 0x78, 0xec, 0x70, 0xee, 0x72, 0xf5, 0x55, 0xf1, 0x5c, 0xf2, 0x59,
0xe6, 0x47, 0xf1, 0x51, 0xf2, 0x50, 0x00, 0x44, 0xf2, 0x46, 0xe8, 0x38, 0xe9, 0x44, 0xe8, 0x32,
0xf5, 0x4a, 0x17, 0xf3, 0x1a, 0xf3, 0x28, 0xf1, 0x31, 0xf2, 0x2c, 0x03, 0x2d, 0x06, 0x2c, 0x22,
0x21, 0x36, 0x13, 0x52, 0xfd, 0x4b, 0xff, 0x17, 0x01, 0x22, 0x01, 0x2b, 0x00, 0x36, 0xfe, 0x37,
0x00, 0x3d, 0x01, 0x40, 0x00, 0x44, 0xf7, 0x5c, 0xf2, 0x6a, 0xf3, 0x61, 0xf1, 0x5a, 0xf4, 0x5a,
0xee, 0x58, 0xf6, 0x49, 0xf7, 0x4f, 0xf2, 0x56, 0xf6, 0x49, 0xf6, 0x46, 0xf6, 0x45, 0xfb, 0x42,
0xf7, 0x40, 0xfb, 0x3a, 0x02, 0x3b, 0x15, 0xf6, 0x18, 0xf5, 0x1c, 0xf8, 0x1c, 0xff, 0x1d, 0x03,
0x1d, 0x09, 0x23, 0x14, 0x1d, 0x24, 0x0e, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@@ -0,0 +1,307 @@
/*
*
* Copyright 2015 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __HAL_H264D_REG_H__
#define __HAL_H264D_REG_H__
#include "mpp_hal.h"
typedef struct h264_mmu_t {
RK_U32 mmu_dte_addr;
struct {
RK_U32 pageing_enabled : 1;
RK_U32 page_fault_active : 1;
RK_U32 stail_active : 1;
RK_U32 mmu_idle : 1;
RK_U32 replay_buffer_empty1 : 1;
RK_U32 page_fault_is_write : 1;
RK_U32 page_fault_bus_id : 5;
RK_U32 reserve : 8;
//RK_U32 field0000 : 1;
} mmu_status;
struct {
RK_U32 mmu_cmd : 3;
RK_U32 field0000 : 1;
} mmu_cmd;
RK_U32 page_fault_addr;
RK_U32 mmu_zap_one_line;
struct int_rawstat {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} raw_stat;
struct int_clear {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} clear;
struct int_mask {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} mask;
struct int_status {
RK_U32 page_fault : 1;
RK_U32 read_bus_error : 1;
} status;
RK_U32 mmu_auto_gating : 1;
} H264_MMU_t;
typedef struct h264_cache_t {
struct st_version {
RK_U32 version_minor : 8;
RK_U32 version_major : 8;
RK_U32 product_id : 16;
} version;
struct st_size {
RK_U32 line_size : 8;
RK_U32 associativity : 8;
RK_U32 cache_size : 8;
RK_U32 external_bus_width : 8;
} size;
struct st_status {
RK_U32 cmd_busy : 1;
RK_U32 data_busy : 1;
} status;
struct st_command {
RK_U32 command : 4;
RK_U32 sw_addrb_sel : 2;
} command;
RK_U32 clear_page;
RK_U32 max_reads : 5;
struct st_enable {
RK_U32 permit_cacheable_access : 1;
RK_U32 permit_cach_read_allocate : 1;
RK_U32 sw_readbuffer_counter_reject_en : 1;
RK_U32 sw_cache_clk_disgate : 1;
RK_U32 sw_cache_linsize : 1;
} enable;
RK_U32 perfcnt_src0;
RK_U32 perfcnt_val0;
RK_U32 perfcnt_src1;
RK_U32 perfcnt_val1;
} H264_CACHE_t;
typedef struct h264_regs_t {
struct {
RK_U32 minor_ver : 8;
RK_U32 level : 1;
RK_U32 dec_support : 3;
RK_U32 profile : 1;
RK_U32 reserve0 : 1;
RK_U32 codec_flag : 1;
RK_U32 reserve1 : 1;
RK_U32 prod_num : 16;
} swreg0_id;
struct {
RK_U32 sw_dec_e : 1;//0
RK_U32 sw_dec_clkgate_e : 1; // 1
RK_U32 reserve0 : 1;// 2
RK_U32 sw_timeout_mode : 1; // 3
RK_U32 sw_dec_irq_dis : 1;//4 // 4
RK_U32 sw_dec_timeout_e : 1; //5
RK_U32 sw_buf_empty_en : 1; // 6
RK_U32 sw_stmerror_waitdecfifo_empty : 1; // 7
RK_U32 sw_dec_irq : 1; // 8
RK_U32 sw_dec_irq_raw : 1; // 9
RK_U32 reserve2 : 2;
RK_U32 sw_dec_rdy_sta : 1; //12
RK_U32 sw_dec_bus_sta : 1; //13
RK_U32 sw_dec_error_sta : 1; // 14
RK_U32 sw_dec_timeout_sta : 1; //15
RK_U32 sw_dec_empty_sta : 1; // 16
RK_U32 sw_colmv_ref_error_sta : 1; // 17
RK_U32 sw_cabu_end_sta : 1; // 18
RK_U32 sw_h264orvp9_error_mode : 1; //19
RK_U32 sw_softrst_en_p : 1; //20
RK_U32 sw_force_softreset_valid : 1; //21
RK_U32 sw_softreset_rdy : 1; // 22
} swreg1_int;
struct {
RK_U32 sw_in_endian : 1;
RK_U32 sw_in_swap32_e : 1;
RK_U32 sw_in_swap64_e : 1;
RK_U32 sw_str_endian : 1;
RK_U32 sw_str_swap32_e : 1;
RK_U32 sw_str_swap64_e : 1;
RK_U32 sw_out_endian : 1;
RK_U32 sw_out_swap32_e : 1;
RK_U32 sw_out_cbcr_swap : 1;
RK_U32 reserve0 : 1;
RK_U32 sw_rlc_mode_direct_write : 1;
RK_U32 sw_rlc_mode : 1;
RK_U32 sw_strm_start_bit : 7;
RK_U32 reserve1 : 1;
RK_U32 sw_dec_mode : 2;
RK_U32 reserve2 : 2;
RK_U32 sw_h264_rps_mode : 1;
RK_U32 sw_h264_stream_mode : 1;
RK_U32 sw_h264_stream_lastpacket : 1;
RK_U32 sw_h264_firstslice_flag : 1;
RK_U32 sw_h264_frame_orslice : 1;
RK_U32 sw_buspr_slot_disable : 1;
} swreg2_sysctrl;
struct {
RK_U32 sw_y_hor_virstride : 9;
RK_U32 reserve : 2;
RK_U32 sw_slice_num_highbit : 1;
RK_U32 sw_uv_hor_virstride : 9;
RK_U32 sw_slice_num_lowbits : 11;
} swreg3_picpar;
struct {
RK_U32 reverse0 : 4;
RK_U32 sw_strm_rlc_base : 28;
} swreg4_strm_rlc_base;
struct {
RK_U32 sw_stream_len : 27;
} swreg5_stream_rlc_len;
struct {
RK_U32 reverse0 : 4;
RK_U32 sw_cabactbl_base : 28;
} swreg6_cabactbl_prob_base;
struct {
RK_U32 reverse0 : 4;
RK_U32 sw_decout_base : 28;
} swreg7_decout_base;
struct {
RK_U32 sw_y_virstride : 20;
} swreg8_y_virstride;
struct {
RK_U32 sw_yuv_virstride : 21;
} swreg9_yuv_virstride;
struct {
RK_U32 sw_ref_field : 1;
RK_U32 sw_ref_topfield_used : 1;
RK_U32 sw_ref_botfield_used : 1;
RK_U32 sw_ref_colmv_use_flag : 1;
RK_U32 sw_refer_base : 28;
} swreg10_24_refer0_14_base[15];
RK_U32 swreg25_39_refer0_14_poc[15];
struct {
RK_U32 sw_cur_poc : 32;
} swreg40_cur_poc;
struct {
RK_U32 reserve : 3;
RK_U32 sw_rlcwrite_base : 29;
} swreg41_rlcwrite_base;
struct {
RK_U32 reserve : 4;
RK_U32 sw_pps_base : 28;
} swreg42_pps_base;
struct swreg_sw_rps_base {
RK_U32 reserve : 4;
RK_U32 sw_rps_base : 28;
} swreg43_rps_base;
struct swreg_strmd_error_e {
RK_U32 sw_strmd_error_e : 28;
RK_U32 reserve : 4;
} swreg44_strmd_error_en;
struct {
RK_U32 sw_strmd_error_status : 28;
RK_U32 sw_colmv_error_ref_picidx : 4;
} swreg45_strmd_error_status;
struct {
RK_U32 sw_strmd_error_ctu_xoffset : 8;
RK_U32 sw_strmd_error_ctu_yoffset : 8;
RK_U32 sw_streamfifo_space2full : 7;
RK_U32 reserve : 1;
RK_U32 sw_vp9_error_ctu0_en : 1;
} swreg46_strmd_error_ctu;
struct {
RK_U32 sw_saowr_xoffet : 9;
RK_U32 reserve : 7;
RK_U32 sw_saowr_yoffset : 10;
} swreg47_sao_ctu_position;
struct {
RK_U32 sw_ref_field : 1;
RK_U32 sw_ref_topfield_used : 1;
RK_U32 sw_ref_botfield_used : 1;
RK_U32 sw_ref_colmv_use_flag : 1;
RK_U32 sw_refer_base : 28;
} swreg48_refer15_base;
RK_U32 swreg49_63_refer15_29_poc[15];
struct {
RK_U32 sw_performance_cycle : 32;
} swreg64_performance_cycle;
struct {
RK_U32 sw_axi_ddr_rdata : 32;
} swreg65_axi_ddr_rdata;
struct {
RK_U32 sw_axi_ddr_rdata : 32;
} swreg66_axi_ddr_wdata;
struct {
RK_U32 sw_busifd_resetn : 1;
RK_U32 sw_cabac_resetn : 1;
RK_U32 sw_dec_ctrl_resetn : 1;
RK_U32 sw_transd_resetn : 1;
RK_U32 sw_intra_resetn : 1;
RK_U32 sw_inter_resetn : 1;
RK_U32 sw_recon_resetn : 1;
RK_U32 sw_filer_resetn : 1;
} swreg67_fpgadebug_reset;
struct {
RK_U32 perf_cnt0_sel : 6;
RK_U32 reserve0 : 2;
RK_U32 perf_cnt1_sel : 6;
RK_U32 reserve1 : 2;
RK_U32 perf_cnt2_sel : 6;
} swreg68_performance_sel;
struct {
RK_U32 perf_cnt0 : 32;
} swreg69_performance_cnt0;
struct {
RK_U32 perf_cnt1 : 32;
} swreg70_performance_cnt1;
struct {
RK_U32 perf_cnt2 : 32;
} swreg71_performance_cnt2;
RK_U32 swreg72_refer30_poc;
RK_U32 swreg73_refer31_poc;
struct {
RK_U32 sw_h264_cur_poc1 : 32;
} swreg74_h264_cur_poc1;
struct {
RK_U32 reserve : 4;
RK_U32 sw_errorinfo_base : 28;
} swreg75_h264_errorinfo_base;
struct {
RK_U32 sw_slicedec_num : 14;
RK_U32 reserve : 1;
RK_U32 sw_strmd_detect_error_flag : 1;
RK_U32 sw_error_packet_num : 14;
} swreg76_h264_errorinfo_num;
struct {
RK_U32 sw_h264_error_en_highbits : 30;
RK_U32 reserve : 2;
} swreg77_h264_error_e;
RK_U32 compare_len;
} H264_REGS_t;
#ifdef __cplusplus
extern "C" {
#endif
extern const RK_U8 H264_Cabac_table[];
#ifdef __cplusplus
}
#endif
#endif /*__HAL_H264D_REG_H__*/

View File

@@ -43,7 +43,7 @@ static MPP_RET manual_set_env(void)
#if defined(_MSC_VER) #if defined(_MSC_VER)
mpp_env_set_u32("h264d_log_help", 1 ); mpp_env_set_u32("h264d_log_help", 1 );
mpp_env_set_u32("h264d_log_show", 1 ); mpp_env_set_u32("h264d_log_show", 1 );
mpp_env_set_u32("h264d_log_ctrl", 0xFFFB ); mpp_env_set_u32("h264d_log_ctrl", 0x007B );
mpp_env_set_u32("h264d_log_level", 5 ); mpp_env_set_u32("h264d_log_level", 5 );
mpp_env_set_u32("h264d_log_decframe", 0 ); mpp_env_set_u32("h264d_log_decframe", 0 );
mpp_env_set_u32("h264d_log_begframe", 0 ); mpp_env_set_u32("h264d_log_begframe", 0 );
@@ -74,15 +74,16 @@ static MPP_RET decoder_deinit(MppDec *pApi)
static MPP_RET decoder_init(MppDec *pApi) static MPP_RET decoder_init(MppDec *pApi)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_ERR_UNKNOW;
MppParserInitCfg parser_cfg; MppParserInitCfg parser_cfg;
MppHalCfg hal_cfg; MppHalCfg hal_cfg;
// set decoder // set decoder
pApi->parser_api = &api_h264d_parser; pApi->parser_api = &api_h264d_parser;
MEM_CHECK(pApi->parser_ctx = mpp_calloc_size(void, pApi->parser_api->ctx_size)); pApi->parser_ctx = mpp_calloc_size(void, pApi->parser_api->ctx_size);
MEM_CHECK(ret, pApi->parser_ctx);
// malloc slot // malloc slot
FUN_CHECK(ret = mpp_buf_slot_init(&pApi->slots)); FUN_CHECK(ret = mpp_buf_slot_init(&pApi->slots));
MEM_CHECK(pApi->slots); MEM_CHECK(ret, pApi->slots);
// init parser part // init parser part
memset(&parser_cfg, 0, sizeof(parser_cfg)); memset(&parser_cfg, 0, sizeof(parser_cfg));
parser_cfg.slots = pApi->slots; parser_cfg.slots = pApi->slots;
@@ -106,13 +107,13 @@ __FAILED:
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_ERR_UNKNOW;
InputParams *pIn = mpp_calloc(InputParams, 1); InputParams *pIn = mpp_calloc(InputParams, 1);
MppDec *pApi = mpp_calloc(MppDec, 1); MppDec *pApi = mpp_calloc(MppDec, 1);
MppPacketImpl *pkt = mpp_calloc_size(MppPacketImpl, sizeof(MppPacketImpl)); MppPacketImpl *pkt = mpp_calloc_size(MppPacketImpl, sizeof(MppPacketImpl));
HalTask *task = mpp_calloc_size(HalTask, sizeof(HalTask)); HalTask *task = mpp_calloc_size(HalTask, sizeof(HalTask));
MEM_CHECK(ret, pIn && pApi && pkt && task);
MEM_CHECK(pIn && pApi && pkt && task);
mpp_log("== test start == \n"); mpp_log("== test start == \n");
// set debug mode // set debug mode
FUN_CHECK(ret = manual_set_env()); FUN_CHECK(ret = manual_set_env());
@@ -124,25 +125,23 @@ int main(int argc, char **argv)
// init // init
FUN_CHECK(ret = decoder_init(pApi)); FUN_CHECK(ret = decoder_init(pApi));
do { do {
//if (!pkt->size) if (!pkt->size)
{ {
FUN_CHECK(ret = h264d_read_one_frame(pIn, (MppPacket)pkt)); FUN_CHECK(ret = h264d_read_one_frame(pIn, (MppPacket)pkt));
mpp_log("---- decoder, Frame_no = %d \n", pIn->iFrmdecoded++);
} }
FUN_CHECK(ret = pApi->parser_api->parse(pApi->parser_ctx, pkt, &task->dec)); FUN_CHECK(ret = pApi->parser_api->parse(pApi->parser_ctx, pkt, &task->dec));
if (((HalDecTask*)&task->dec)->valid) { if (((HalDecTask*)&task->dec)->valid) {
FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal_ctx, task)); FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal_ctx, task));
mpp_log("---- decoder, Frame_no = %d \n", pIn->iFrmdecoded++); //mpp_log("---- decoder, Frame_no = %d \n", pIn->iFrmdecoded);
if (((MppPacketImpl *)pkt)->flag & MPP_PACKET_FLAG_EOS) { //!< end of stream
if (!pkt->size && (pkt->flag & MPP_PACKET_FLAG_EOS)) {
break; break;
} }
} pIn->iFrmdecoded++;
if (pIn->is_eof) {
break;
} }
} while (!pIn->iDecFrmNum || (pIn->iFrmdecoded < pIn->iDecFrmNum)); } while (!pIn->iDecFrmNum || (pIn->iFrmdecoded < pIn->iDecFrmNum));
mpp_log("== all test return == \n"); mpp_log("+++++++ all test return +++++++ \n");
ret = MPP_OK; ret = MPP_OK;
__FAILED: __FAILED:
decoder_deinit(pApi); decoder_deinit(pApi);