[h264e]: Add H.264 sw_reenc pskip path

1. Add pps on slice update for pic_init_qp.
2. Add cabac and cavlc pskip sw encode path.
3. Add dpb rollback for reenc path.

Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: I8d39cfeabcf669f66cd4e4d5ea5e08e4217d3a0e
This commit is contained in:
Herman Chen 2020-09-16 14:46:26 +08:00
parent c182090ddd
commit 4c625f0e3c
5 changed files with 371 additions and 56 deletions

View file

@ -317,10 +317,11 @@ static MPP_RET h264e_proc_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src)
}
}
src->change = 0;
return ret;
}
static MPP_RET h264e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src)
static MPP_RET h264e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src, MppEncH264Cfg *h264)
{
MPP_RET ret = MPP_OK;
RK_U32 change = src->change;
@ -393,6 +394,13 @@ static MPP_RET h264e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src)
ret = MPP_ERR_VALUE;
}
}
if (dst->drop_mode == MPP_ENC_RC_DROP_FRM_PSKIP &&
dst->drop_gap == 0 &&
h264->poc_type == 2) {
mpp_err("poc type 2 is ocnflict with successive non-reference pskip mode\n");
mpp_err("set drop gap to 1\n");
dst->drop_gap = 1;
}
dst->change |= change;
@ -406,6 +414,7 @@ static MPP_RET h264e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src)
}
}
src->change = 0;
return ret;
}
@ -529,6 +538,7 @@ static MPP_RET h264e_proc_h264_cfg(MppEncH264Cfg *dst, MppEncH264Cfg *src)
dst->change |= MPP_ENC_H264_CFG_CHANGE_BASE_LAYER_PID;
}
src->change = 0;
return ret;
}
@ -546,6 +556,7 @@ static MPP_RET h264e_proc_split_cfg(MppEncSliceSplit *dst, MppEncSliceSplit *src
dst->split_arg = src->split_arg;
dst->change |= change;
src->change = 0;
return ret;
}
@ -563,28 +574,23 @@ static MPP_RET h264e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
MppEncCfgImpl *impl = (MppEncCfgImpl *)param;
MppEncCfgSet *src = &impl->cfg;
if (src->prep.change) {
if (src->prep.change)
ret |= h264e_proc_prep_cfg(&cfg->prep, &src->prep);
src->prep.change = 0;
}
if (src->rc.change) {
ret |= h264e_proc_rc_cfg(&cfg->rc, &src->rc);
src->rc.change = 0;
}
if (src->codec.h264.change) {
if (src->codec.h264.change)
ret |= h264e_proc_h264_cfg(&cfg->codec.h264, &src->codec.h264);
src->codec.h264.change = 0;
}
if (src->split.change) {
if (src->rc.change)
ret |= h264e_proc_rc_cfg(&cfg->rc, &src->rc, &cfg->codec.h264);
if (src->split.change)
ret |= h264e_proc_split_cfg(&cfg->split, &src->split);
src->split.change = 0;
}
} break;
case MPP_ENC_SET_PREP_CFG : {
ret = h264e_proc_prep_cfg(&cfg->prep, param);
} break;
case MPP_ENC_SET_RC_CFG : {
ret = h264e_proc_rc_cfg(&cfg->rc, param);
ret = h264e_proc_rc_cfg(&cfg->rc, param, &cfg->codec.h264);
} break;
case MPP_ENC_SET_CODEC_CFG : {
MppEncCodecCfg *codec = (MppEncCodecCfg *)param;
@ -705,7 +711,7 @@ static MPP_RET h264e_proc_dpb(void *ctx, HalEncTask *task)
refr = dpb->refr;
// update slice info
h264e_slice_update(&p->slice, p->cfg, &p->sps, dpb->curr);
h264e_slice_update(&p->slice, p->cfg, &p->sps, &p->pps, dpb->curr);
// update frame usage
frms->seq_idx = curr->seq_idx;
@ -790,6 +796,45 @@ static MPP_RET h264e_proc_hal(void *ctx, HalEncTask *task)
return MPP_OK;
}
static MPP_RET h264e_sw_enc(void *ctx, HalEncTask *task)
{
H264eCtx *p = (H264eCtx *)ctx;
MppEncH264Cfg *h264 = &p->cfg->codec.h264;
EncRcTaskInfo *rc_info = &task->rc_task->info;
MppPacket packet = task->packet;
void *pos = mpp_packet_get_pos(packet);
void *data = mpp_packet_get_data(packet);
size_t size = mpp_packet_get_size(packet);
size_t length = mpp_packet_get_length(packet);
void *base = pos + length;
RK_S32 buf_size = (data + size) - (pos + length);
RK_S32 slice_len = 0;
RK_S32 final_len = 0;
if (h264->prefix_mode || h264->max_tid) {
/* add prefix first */
RK_S32 prefix_bit = h264e_slice_write_prefix_nal_unit_svc(&p->prefix, base, buf_size);
prefix_bit = (prefix_bit + 7) / 8;
base += prefix_bit;
buf_size -= prefix_bit;
final_len += prefix_bit;
}
/* write slice header */
slice_len = h264e_slice_write_pskip(&p->slice, base, buf_size);
slice_len = (slice_len + 7) / 8;
final_len += slice_len;
task->length += final_len;
rc_info->bit_real = task->length;
rc_info->quality_real = rc_info->quality_target;
return MPP_OK;
}
MPP_RET h264e_add_sei(MppPacket pkt, RK_S32 *length, RK_U8 uuid[16],
const void *data, RK_S32 size)
{
@ -816,5 +861,5 @@ const EncImplApi api_h264e = {
h264e_proc_dpb,
h264e_proc_hal,
h264e_add_sei,
NULL,
h264e_sw_enc,
};

View file

@ -120,8 +120,8 @@ MPP_RET h264e_dpb_setup(H264eDpb *dpb, MppEncCfgSet* cfg, H264eSps *sps)
dpb->dpb_size = info->dpb_size;
dpb->total_cnt = info->dpb_size + 1;
dpb->max_frm_num = 1 << log2_max_frm_num;
dpb->max_poc_lsb = 1 << log2_max_poc_lsb;
dpb->poc_msb = (1 << log2_max_poc_lsb);
dpb->max_poc_lsb = (1 << log2_max_poc_lsb);
dpb->poc_type = sps->pic_order_cnt_type;
h264e_dbg_dpb("max ref frm num %d total slot %d\n",
ref_frm_num, dpb->total_cnt);
@ -404,6 +404,7 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
EncFrmStatus *refr = &cpb->refr;
EncFrmStatus *init = cpb->init;
H264eDpbFrm *frames = dpb->frames;
H264eDpbRt *rt = &dpb->rt;
RK_S32 used_size = 0;
RK_S32 seq_idx = curr->seq_idx;
RK_S32 i;
@ -418,6 +419,12 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
dpb->used_size = 0;
dpb->curr_max_lt_idx = 0;
dpb->next_max_lt_idx = 0;
} else {
if (curr->seq_idx == rt->last_seq_idx) {
h264e_dbg_dpb("NOTE: reenc found at %d\n", curr->seq_idx);
memcpy(rt, &dpb->rt_bak, sizeof(*rt));
memcpy(frames, dpb->frm_bak, sizeof(dpb->frm_bak));
}
}
if (h264e_debug & H264E_DBG_DPB)
@ -427,9 +434,13 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
* user defined cpb to hal slot index
*/
for (i = 0; i < MAX_CPB_REFS; i++) {
dpb->map[i] = find_cpb_frame(frames, dpb->total_cnt, &init[i]);
if (dpb->map[i]) {
dpb->map[i]->on_used = 1;
H264eDpbFrm *frm = find_cpb_frame(frames, dpb->total_cnt, &init[i]);
dpb->map[i] = frm;
if (frm) {
if (!frm->on_used)
mpp_err_f("warning frm %d is used by cpb but on not used status\n",
frm->seq_idx);
frm->on_used = 1;
used_size++;
}
}
@ -438,6 +449,10 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
h264e_dbg_dpb("frm %d init cpb used size %d vs %d\n", seq_idx,
used_size, dpb->used_size);
/* backup current runtime status */
memcpy(&dpb->rt_bak, rt, sizeof(dpb->rt_bak));
memcpy(dpb->frm_bak, frames, sizeof(dpb->frm_bak));
/* mark current cpb */
RK_S32 found_curr = 0;
@ -447,6 +462,9 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
h264e_dbg_dpb("frm %d start finding slot for storage\n", seq_idx);
for (i = 0; i < H264E_MAX_REFS_CNT + 1; i++) {
H264eDpbFrm *p = &frames[i];
RK_S32 curr_frm_num = rt->last_frm_num + rt->last_is_ref;
RK_S32 curr_poc_lsb = rt->last_poc_lsb;
RK_S32 curr_poc_msb = rt->last_poc_msb;
RK_S32 valid = 0;
RK_S32 j;
@ -480,24 +498,38 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb)
if (curr->is_idr) {
p->frame_num = 0;
p->poc = 0;
dpb->last_poc_lsb = 0;
dpb->last_poc_msb = 0;
curr_frm_num = 0;
curr_poc_lsb = 0;
curr_poc_msb = 0;
} else {
p->frame_num = dpb->last_frm_num;
p->poc = dpb->last_poc_lsb + dpb->last_poc_msb * dpb->poc_msb;
if (curr_frm_num >= dpb->max_frm_num)
curr_frm_num = 0;
p->frame_num = curr_frm_num;
if (dpb->poc_type == 0)
curr_poc_lsb += 2;
else if (dpb->poc_type == 2)
curr_poc_lsb += 1 + rt->last_is_ref;
else
mpp_err_f("do not support poc type 1\n");
if (curr_poc_lsb >= dpb->max_poc_lsb) {
curr_poc_lsb = 0;
curr_poc_msb++;
}
p->poc = curr_poc_lsb + curr_poc_msb * dpb->max_poc_lsb;
}
p->lt_idx = curr->lt_idx;
p->on_used = 1;
dpb->last_frm_num = p->frame_num + !curr->is_non_ref;
if (dpb->last_frm_num >= dpb->max_frm_num)
dpb->last_frm_num = 0;
dpb->last_poc_lsb += 2;
if (dpb->last_poc_lsb >= dpb->max_poc_lsb) {
dpb->last_poc_lsb = 0;
dpb->last_poc_msb++;
}
rt->last_seq_idx = curr->seq_idx;
rt->last_is_ref = !curr->is_non_ref;
rt->last_frm_num = curr_frm_num;
rt->last_poc_lsb = curr_poc_lsb;
rt->last_poc_msb = curr_poc_msb;
found_curr = 1;
h264e_dbg_dpb("frm %d update slot %d with frame_num %d poc %d\n",
@ -664,4 +696,3 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb)
h264e_dbg_dpb("leave %p\n", dpb);
}

View file

@ -68,6 +68,15 @@ typedef struct H264eDpbFrm_t {
RK_S64 pts;
} H264eDpbFrm;
/* runtime status record */
typedef struct H264eDpbRt_t {
RK_S32 last_seq_idx;
RK_S32 last_is_ref;
RK_S32 last_frm_num;
RK_S32 last_poc_lsb;
RK_S32 last_poc_msb;
} H264eDpbRt;
/*
* dpb frame arrangement
*
@ -92,22 +101,27 @@ typedef struct H264eDpb_t {
RK_S32 dpb_size;
RK_S32 total_cnt;
/* status on dpb rebuild is needed */
RK_S32 max_frm_num;
RK_S32 max_poc_lsb;
RK_S32 poc_msb;
RK_S32 poc_type;
RK_S32 last_frm_num;
RK_S32 last_poc_lsb;
RK_S32 last_poc_msb;
H264eDpbFrm *curr;
H264eDpbFrm *refr;
H264eDpbFrm *list[H264E_MAX_REFS_CNT];
H264eDpbFrm *stref[H264E_MAX_REFS_CNT];
H264eDpbFrm *ltref[H264E_MAX_REFS_CNT];
H264eDpbFrm *map[H264E_MAX_REFS_CNT + 1];
H264eDpbFrm *curr;
H264eDpbFrm *refr;
H264eDpbFrm *list[H264E_MAX_REFS_CNT];
H264eDpbFrm *stref[H264E_MAX_REFS_CNT];
H264eDpbFrm *ltref[H264E_MAX_REFS_CNT];
H264eDpbFrm *map[H264E_MAX_REFS_CNT + 1];
// frame storage
H264eDpbFrm frames[H264E_MAX_REFS_CNT + 1];
H264eDpbRt rt;
H264eDpbRt rt_bak;
H264eDpbFrm frames[H264E_MAX_REFS_CNT + 1];
H264eDpbFrm frm_bak[H264E_MAX_REFS_CNT + 1];
} H264eDpb;
#ifdef __cplusplus

View file

@ -40,16 +40,19 @@ void h264e_slice_init(H264eSlice *slice, H264eReorderInfo *reorder,
}
RK_S32 h264e_slice_update(H264eSlice *slice, MppEncCfgSet *cfg,
H264eSps *sps, H264eDpbFrm *frm)
H264eSps *sps, H264ePps *pps, H264eDpbFrm *frm)
{
MppEncH264Cfg *h264 = &cfg->codec.h264;
RK_S32 is_idr = frm->status.is_idr;
slice->mb_w = sps->pic_width_in_mbs;
slice->mb_h = sps->pic_height_in_mbs;
slice->max_num_ref_frames = sps->num_ref_frames;
slice->log2_max_frame_num = sps->log2_max_frame_num_minus4 + 4;
slice->log2_max_poc_lsb = sps->log2_max_poc_lsb_minus4 + 4;
slice->entropy_coding_mode = h264->entropy_coding_mode;
slice->pic_order_cnt_type = sps->pic_order_cnt_type;
slice->qp_init = pps->pic_init_qp;
slice->nal_reference_idc = (frm->status.is_non_ref) ? (H264_NALU_PRIORITY_DISPOSABLE) :
(is_idr) ? (H264_NALU_PRIORITY_HIGHEST) :
@ -510,20 +513,12 @@ RK_S32 h264e_slice_read(H264eSlice *slice, void *p, RK_S32 size)
return bit_cnt;
}
RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size)
void h264e_slice_write_header(H264eSlice *slice, MppWriteCtx *s)
{
MppWriteCtx stream;
MppWriteCtx *s = &stream;
RK_S32 i;
RK_S32 bitCnt = 0;
H264eMarkingInfo *marking = slice->marking;
H264eRplmo rplmo;
MPP_RET ret = MPP_OK;
mpp_writer_init(s, p, size);
RK_U8 *tmp = (RK_U8 *)s->buffer;
/* nal header */
/* start_code_prefix 00 00 00 01 */
mpp_writer_put_raw_bits(s, 0, 24);
@ -694,6 +689,17 @@ RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size)
}
mpp_writer_flush(s);
}
RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size)
{
MppWriteCtx stream;
MppWriteCtx *s = &stream;
RK_S32 bitCnt = 0;
mpp_writer_init(s, p, size);
h264e_slice_write_header(slice, s);
bitCnt = s->buffered_bits + s->byte_cnt * 8;
@ -702,6 +708,8 @@ RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size)
bitCnt = s->buffered_bits + s->byte_cnt * 8;
if (h264e_debug & H264E_DBG_SLICE) {
RK_S32 i;
RK_U8 *tmp = p;
RK_S32 pos = 0;
char log[256];
@ -716,7 +724,217 @@ RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size)
return bitCnt;
}
static RK_S32 frame_no = 0;
/*
* For software force skip stream writing
* 3 contexts state for skip flag
* end_of_slice flag is equal to write bypass 1
*/
typedef struct H264eCabac_t {
RK_S32 state;
RK_S32 low;
RK_S32 range;
RK_S32 queue;
RK_S32 bytes_outstanding;
MppWriteCtx *s;
} H264eCabac;
static const RK_S8 skip_init_state[3][2] = {
// skip_flag ctx 11
/* model 0 */ { 23, 33 },
/* model 1 */ { 22, 25 },
/* model 2 */ { 29, 16 },
};
static void init_context(H264eCabac *ctx, RK_S32 qp, RK_S32 model, MppWriteCtx *s)
{
const RK_S8 *init = &skip_init_state[model][0];
RK_S32 state = MPP_CLIP3(1, 126, ((init[0] * qp) >> 4) + init[1]);
ctx->state = (MPP_MIN(state, 127 - state) << 1) | (state >> 6);
ctx->low = 0;
ctx->range = 0x01FE;
ctx->queue = -9;
ctx->bytes_outstanding = 0;
ctx->s = s;
}
static inline void h264e_cabac_putbyte(H264eCabac *ctx)
{
if (ctx->queue >= 0) {
RK_S32 out = ctx->low >> (ctx->queue + 10);
ctx->low &= (0x400 << ctx->queue) - 1;
ctx->queue -= 8;
if ((out & 0xff) == 0xff) {
ctx->bytes_outstanding++;
} else {
MppWriteCtx *s = ctx->s;
RK_S32 carry = out >> 8;
RK_S32 bytes_outstanding = ctx->bytes_outstanding;
if (ctx->queue > 0)
mpp_writer_put_bits(s, carry, ctx->queue & 0x7);
while (bytes_outstanding > 0) {
mpp_writer_put_bits(s, carry - 1, 8);
bytes_outstanding--;
}
mpp_writer_put_bits(s, out, MPP_MIN(8, 8 - ctx->queue));
ctx->bytes_outstanding = 0;
}
}
}
static inline void h264e_cabac_renorm(H264eCabac *ctx)
{
static const RK_U8 x264_cabac_renorm_shift[64] = {
6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
RK_S32 shift = x264_cabac_renorm_shift[ctx->range >> 3];
ctx->range <<= shift;
ctx->low <<= shift;
ctx->queue += shift;
h264e_cabac_putbyte(ctx);
}
static void h264e_cabac_write_skip_flag(H264eCabac *ctx)
{
static const RK_U8 h264e_cabac_range_lps[64][4] = {
{ 2, 2, 2, 2}, { 6, 7, 8, 9}, { 6, 7, 9, 10}, { 6, 8, 9, 11},
{ 7, 8, 10, 11}, { 7, 9, 10, 12}, { 7, 9, 11, 12}, { 8, 9, 11, 13},
{ 8, 10, 12, 14}, { 9, 11, 12, 14}, { 9, 11, 13, 15}, { 10, 12, 14, 16},
{ 10, 12, 15, 17}, { 11, 13, 15, 18}, { 11, 14, 16, 19}, { 12, 14, 17, 20},
{ 12, 15, 18, 21}, { 13, 16, 19, 22}, { 14, 17, 20, 23}, { 14, 18, 21, 24},
{ 15, 19, 22, 25}, { 16, 20, 23, 27}, { 17, 21, 25, 28}, { 18, 22, 26, 30},
{ 19, 23, 27, 31}, { 20, 24, 29, 33}, { 21, 26, 30, 35}, { 22, 27, 32, 37},
{ 23, 28, 33, 39}, { 24, 30, 35, 41}, { 26, 31, 37, 43}, { 27, 33, 39, 45},
{ 29, 35, 41, 48}, { 30, 37, 43, 50}, { 32, 39, 46, 53}, { 33, 41, 48, 56},
{ 35, 43, 51, 59}, { 37, 45, 54, 62}, { 39, 48, 56, 65}, { 41, 50, 59, 69},
{ 43, 53, 63, 72}, { 46, 56, 66, 76}, { 48, 59, 69, 80}, { 51, 62, 73, 85},
{ 53, 65, 77, 89}, { 56, 69, 81, 94}, { 59, 72, 86, 99}, { 62, 76, 90, 104},
{ 66, 80, 95, 110}, { 69, 85, 100, 116}, { 73, 89, 105, 122}, { 77, 94, 111, 128},
{ 81, 99, 117, 135}, { 85, 104, 123, 142}, { 90, 110, 130, 150}, { 95, 116, 137, 158},
{100, 122, 144, 166}, {105, 128, 152, 175}, {111, 135, 160, 185}, {116, 142, 169, 195},
{123, 150, 178, 205}, {128, 158, 187, 216}, {128, 167, 197, 227}, {128, 176, 208, 240}
};
static const RK_U8 h264e_cabac_transition[128][2] = {
{ 0, 0}, { 1, 1}, { 2, 50}, { 51, 3}, { 2, 50}, { 51, 3}, { 4, 52}, { 53, 5},
{ 6, 52}, { 53, 7}, { 8, 52}, { 53, 9}, { 10, 54}, { 55, 11}, { 12, 54}, { 55, 13},
{ 14, 54}, { 55, 15}, { 16, 56}, { 57, 17}, { 18, 56}, { 57, 19}, { 20, 56}, { 57, 21},
{ 22, 58}, { 59, 23}, { 24, 58}, { 59, 25}, { 26, 60}, { 61, 27}, { 28, 60}, { 61, 29},
{ 30, 60}, { 61, 31}, { 32, 62}, { 63, 33}, { 34, 62}, { 63, 35}, { 36, 64}, { 65, 37},
{ 38, 66}, { 67, 39}, { 40, 66}, { 67, 41}, { 42, 66}, { 67, 43}, { 44, 68}, { 69, 45},
{ 46, 68}, { 69, 47}, { 48, 70}, { 71, 49}, { 50, 72}, { 73, 51}, { 52, 72}, { 73, 53},
{ 54, 74}, { 75, 55}, { 56, 74}, { 75, 57}, { 58, 76}, { 77, 59}, { 60, 78}, { 79, 61},
{ 62, 78}, { 79, 63}, { 64, 80}, { 81, 65}, { 66, 82}, { 83, 67}, { 68, 82}, { 83, 69},
{ 70, 84}, { 85, 71}, { 72, 84}, { 85, 73}, { 74, 88}, { 89, 75}, { 76, 88}, { 89, 77},
{ 78, 90}, { 91, 79}, { 80, 90}, { 91, 81}, { 82, 94}, { 95, 83}, { 84, 94}, { 95, 85},
{ 86, 96}, { 97, 87}, { 88, 96}, { 97, 89}, { 90, 100}, {101, 91}, { 92, 100}, {101, 93},
{ 94, 102}, {103, 95}, { 96, 104}, {105, 97}, { 98, 104}, {105, 99}, {100, 108}, {109, 101},
{102, 108}, {109, 103}, {104, 110}, {111, 105}, {106, 112}, {113, 107}, {108, 114}, {115, 109},
{110, 116}, {117, 111}, {112, 118}, {119, 113}, {114, 118}, {119, 115}, {116, 122}, {123, 117},
{118, 122}, {123, 119}, {120, 124}, {125, 121}, {122, 126}, {127, 123}, {124, 127}, {126, 125}
};
RK_S32 skip = 1;
RK_S32 state = ctx->state;
RK_S32 range_lps = h264e_cabac_range_lps[state >> 1][(ctx->range >> 6) - 4];
ctx->range -= range_lps;
if (skip != (state & 1) ) {
ctx->low += ctx->range;
ctx->range = range_lps;
}
ctx->state = h264e_cabac_transition[state][skip];
h264e_cabac_renorm(ctx);
}
static void h264e_cabac_terminal(H264eCabac *ctx)
{
ctx->range -= 2;
h264e_cabac_renorm(ctx);
}
static void h264e_cabac_flush(H264eCabac *ctx)
{
/* end_of_slice_flag = 1 */
ctx->low += ctx->range - 2;
ctx->low |= 1;
ctx->low <<= 9;
ctx->queue += 9;
h264e_cabac_putbyte( ctx );
h264e_cabac_putbyte( ctx );
ctx->low <<= -ctx->queue;
ctx->low |= 1 << 10;
ctx->queue = 0;
h264e_cabac_putbyte( ctx );
while (ctx->bytes_outstanding > 0) {
mpp_writer_put_bits(ctx->s, 0xff, 8);
ctx->bytes_outstanding--;
}
}
RK_S32 h264e_slice_write_pskip(H264eSlice *slice, void *p, RK_U32 size)
{
MppWriteCtx stream;
MppWriteCtx *s = &stream;
RK_S32 bitCnt = 0;
mpp_writer_init(s, p, size);
h264e_slice_write_header(slice, s);
if (slice->entropy_coding_mode) {
/* cabac */
H264eCabac ctx;
RK_S32 i;
init_context(&ctx, slice->qp_init, slice->cabac_init_idc, s);
for (i = 0; i < slice->mb_w * slice->mb_h; i++) {
/* end_of_slice_flag = 0 */
if (i)
h264e_cabac_terminal(&ctx);
/* skip flag */
h264e_cabac_write_skip_flag(&ctx);
}
/* end_of_slice_flag = 1 and flush */
h264e_cabac_flush(&ctx);
} else {
/* cavlc */
/* mb skip run */
mpp_writer_put_ue(s, slice->mb_w * slice->mb_h);
h264e_dbg_slice("used bit %d mb_skip_run %d\n",
mpp_writer_bits(s), slice->mb_w * slice->mb_h);
/* rbsp_stop_one_bit */
mpp_writer_trailing(s);
h264e_dbg_slice("used bit %d tailing %d\n", mpp_writer_bits(s));
}
mpp_writer_flush(s);
bitCnt = s->buffered_bits + s->byte_cnt * 8;
return bitCnt;
}
RK_S32 h264e_slice_move(RK_U8 *dst, RK_U8 *src, RK_S32 dst_bit, RK_S32 src_bit, RK_S32 src_size)
{
@ -726,6 +944,7 @@ RK_S32 h264e_slice_move(RK_U8 *dst, RK_U8 *src, RK_S32 dst_bit, RK_S32 src_bit,
RK_S32 src_bit_r = src_bit & 7;
RK_S32 src_len = src_size - src_byte;
RK_S32 diff_len = 0;
static RK_S32 frame_no = 0;
if (src_bit_r == 0 && dst_bit_r == 0) {
// direct copy

View file

@ -21,6 +21,7 @@
#include "h264e_syntax.h"
#include "h264e_sps.h"
#include "h264e_pps.h"
/*
* For H.264 encoder slice header process.
@ -87,11 +88,14 @@ typedef struct H264eMarkingInfo_t {
typedef struct H264eSlice_t {
/* Copy of sps/pps parameter */
RK_S32 mb_w;
RK_S32 mb_h;
RK_U32 max_num_ref_frames;
RK_U32 entropy_coding_mode;
RK_S32 log2_max_frame_num;
RK_S32 log2_max_poc_lsb;
RK_S32 pic_order_cnt_type;
RK_S32 qp_init;
/* Nal parameters */
RK_S32 nal_reference_idc;
@ -159,10 +163,12 @@ MPP_RET h264e_marking_rd_op(H264eMarkingInfo *info, H264eMmco *op);
void h264e_slice_init(H264eSlice *slice, H264eReorderInfo *reorder,
H264eMarkingInfo *marking);
RK_S32 h264e_slice_update(H264eSlice *slice, MppEncCfgSet *cfg,
H264eSps *sps, H264eDpbFrm *frm);
H264eSps *sps, H264ePps *pps,
H264eDpbFrm *frm);
RK_S32 h264e_slice_read(H264eSlice *slice, void *p, RK_S32 size);
RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size);
RK_S32 h264e_slice_write_pskip(H264eSlice *slice, void *p, RK_U32 size);
RK_S32 h264e_slice_move(RK_U8 *dst, RK_U8 *src, RK_S32 dst_bit, RK_S32 src_bit,
RK_S32 src_size);