[h265d]: cut slice header extension data

1. when slice_header_extension_present_flag is 1 in pps segment
2. we should cut the slice header externsion data in slice header segment

Signed-off-by: yandong.lin <yandong.lin@rock-chips.com>
Change-Id: I074e64f6e6c62e4bcc8a12f95c49aa6cf77505c1
This commit is contained in:
yandong.lin
2020-07-13 11:03:12 +08:00
committed by Herman Chen
parent f7e400f8b7
commit ad8be25073
5 changed files with 111 additions and 9 deletions

View File

@@ -1048,14 +1048,18 @@ static RK_S32 hls_slice_header(HEVCContext *s)
}
}
}
#if 0
if (s->pps->slice_header_extension_present_flag) {
//if slice_header_extension_present_flag is 1, we should cut the extension data.
RK_U32 length = 0;
s->start_bit = gb->used_bits;
READ_UE(gb, &length);
for (i = 0; (RK_U32)i < length; i++)
for (i = 0; (RK_U32)i < length; i++) {
SKIP_BITS(gb, 8); // slice_header_extension_data_byte
}
s->end_bit = gb->used_bits;
}
#endif
// Inferred parameters
sh->slice_qp = 26U + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta;
if (sh->slice_qp > 51 ||
@@ -1313,6 +1317,7 @@ static RK_S32 parser_nal_unit(HEVCContext *s, const RK_U8 *nal, int length)
h265d_dbg(H265D_DBG_FUNCTION, "hls_slice_header in");
ret = hls_slice_header(s);
h265d_dbg(H265D_DBG_FUNCTION, "hls_slice_header out");
if (ret < 0) {
mpp_err("hls_slice_header error ret = %d", ret);
return ret;
@@ -1581,12 +1586,44 @@ fail:
return ret;
}
static RK_S32 parser_nal_units(HEVCContext *s)
{
/* parse the NAL units */
RK_S32 i, ret = 0;
RK_S32 i, ret = 0, slice_cnt = 0;
for (i = 0; i < s->nb_nals; i++) {
ret = parser_nal_unit(s, s->nals[i].data, s->nals[i].size);
/* update slice data if slice_header_extension_present_flag is 1*/
if (s->nal_unit_type < 32) {
switch (s->nal_unit_type) {
case NAL_TRAIL_R:
case NAL_TRAIL_N:
case NAL_TSA_N:
case NAL_TSA_R:
case NAL_STSA_N:
case NAL_STSA_R:
case NAL_BLA_W_LP:
case NAL_BLA_W_RADL:
case NAL_BLA_N_LP:
case NAL_IDR_W_RADL:
case NAL_IDR_N_LP:
case NAL_CRA_NUT:
case NAL_RADL_N:
case NAL_RADL_R:
case NAL_RASL_N:
case NAL_RASL_R:
if (s->pps->slice_header_extension_present_flag) {
h265d_dxva2_picture_context_t *temp = (h265d_dxva2_picture_context_t *)s->hal_pic_private;
temp->slice_cut_param[slice_cnt].start_bit = s->start_bit;
temp->slice_cut_param[slice_cnt].end_bit = s->end_bit;
temp->slice_cut_param[slice_cnt].is_enable = 1;
break;
}
default: break;
}
slice_cnt++;
}
if (ret < 0) {
mpp_err("Error parsing NAL unit #%d,error ret = 0xd.\n", i, ret);
goto fail;
@@ -2032,8 +2069,6 @@ MPP_RET h265d_callback(void *ctx, void *err_info)
return MPP_OK;
}
const ParserApi api_h265d_parser = {
.name = "h265d_parse",
.coding = MPP_VIDEO_CodingHEVC,
@@ -2049,4 +2084,3 @@ const ParserApi api_h265d_parser = {
.callback = h265d_callback,
};

View File

@@ -595,6 +595,9 @@ typedef struct HEVCContext {
RK_U8 has_get_eos;
RK_U8 miss_ref_flag;
IOInterruptCB notify_cb;
/*temporary storage for slice_cut_param*/
RK_U32 start_bit;
RK_U32 end_bit;
} HEVCContext;
RK_S32 mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,

View File

@@ -287,6 +287,11 @@ static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
slice->wBadSliceChopping = 0;
}
static void init_slice_cut_param(DXVA_Slice_HEVC_Cut_Param *slice)
{
memset(slice, 0, sizeof(*slice));
}
RK_S32 h265d_parser2_syntax(void *ctx)
{
@@ -364,6 +369,7 @@ RK_S32 h265d_syntax_fill_slice(void *ctx, RK_S32 input_index)
memcpy(current, h->nals[i].data, h->nals[i].size);
// mpp_log("h->nals[%d].size = %d", i, h->nals[i].size);
fill_slice_short(&ctx_pic->slice_short[count], position, h->nals[i].size);
init_slice_cut_param(&ctx_pic->slice_cut_param[count]);
current += h->nals[i].size;
position += h->nals[i].size;
count++;

View File

@@ -198,6 +198,13 @@ typedef struct _DXVA_Slice_HEVC_Short {
USHORT wBadSliceChopping;
} DXVA_Slice_HEVC_Short, *LPDXVA_Slice_HEVC_Short;
/* just use in the case of pps->slice_header_extension_present_flag is 1 */
typedef struct _DXVA_Slice_HEVC_Cut_Param {
UINT start_bit;
UINT end_bit;
USHORT is_enable;
} DXVA_Slice_HEVC_Cut_Param, *LPDXVA_Slice_HEVC_Cut_Param;
typedef struct h265d_dxva2_picture_context {
DXVA_PicParams_HEVC pp;
DXVA_Qmatrix_HEVC qm;
@@ -205,6 +212,7 @@ typedef struct h265d_dxva2_picture_context {
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
const UCHAR *bitstream;
UINT32 bitstream_size;
DXVA_Slice_HEVC_Cut_Param slice_cut_param[MAX_SLICES];
} h265d_dxva2_picture_context_t;
#endif /*__H265D_SYNTAX__*/
#endif /*__H265D_SYNTAX__*/

View File

@@ -1509,7 +1509,8 @@ static RK_S32 hal_h265d_output_pps_packet(void *hal, void *dxva)
mpp_put_bits(&bp, dxva_cxt->pp.pps_tc_offset_div2 , 4);
mpp_put_bits(&bp, dxva_cxt->pp.lists_modification_present_flag , 1);
mpp_put_bits(&bp, dxva_cxt->pp.log2_parallel_merge_level_minus2 + 2 , 3);
mpp_put_bits(&bp, dxva_cxt->pp.slice_segment_header_extension_present_flag , 1);
/*slice_segment_header_extension_present_flag need set 0 */
mpp_put_bits(&bp, 0 , 1);
mpp_put_bits(&bp, 0 , 3);
mpp_put_bits(&bp, dxva_cxt->pp.num_tile_columns_minus1 + 1, 5);
mpp_put_bits(&bp, dxva_cxt->pp.num_tile_rows_minus1 + 1 , 5 );
@@ -1618,6 +1619,53 @@ static RK_S32 hal_h265d_output_pps_packet(void *hal, void *dxva)
return 0;
}
static void update_stream_buffer(MppBuffer streambuf, HalTaskInfo *syn)
{
h265d_dxva2_picture_context_t *dxva_cxt =
(h265d_dxva2_picture_context_t *)syn->dec.syntax.data;
RK_U8 *ptr = (RK_U8*)mpp_buffer_get_ptr(streambuf);
RK_U8 bit_left = 0;
RK_U16 start_byte, end_byte, i = 0;
RK_U32 stream_size = dxva_cxt->bitstream_size;
RK_U8 *buf = NULL;
RK_U8 *temp = NULL;
for (i = 0; i < dxva_cxt->slice_count; i++) {
if (dxva_cxt->slice_cut_param[i].is_enable) {
bit_left = 8 - (dxva_cxt->slice_cut_param[i].start_bit & 0x7);
start_byte = dxva_cxt->slice_cut_param[i].start_bit >> 3;
end_byte = (dxva_cxt->slice_cut_param[i].end_bit + 7) >> 3;
buf = ptr + dxva_cxt->slice_short[i].BSNALunitDataLocation;
stream_size -= dxva_cxt->slice_short[i].BSNALunitDataLocation;
temp = buf + start_byte;
h265h_dbg(H265H_DBG_FUNCTION, "start bit %d start byte[%d] 0x%x end bit %d end byte[%d] 0x%x\n",
dxva_cxt->slice_cut_param[i].start_bit, start_byte, buf[start_byte],
dxva_cxt->slice_cut_param[i].end_bit, end_byte, buf[end_byte]);
if (bit_left < 8) {
*temp = (*temp >> bit_left) << bit_left;
*temp |= 1 << (bit_left - 1);
} else {
*temp = 0x80;
}
if ((dxva_cxt->slice_cut_param[i].end_bit & 0x7) == 0 && buf[end_byte] == 0x80)
end_byte += 1;
h265h_dbg(H265H_DBG_FUNCTION, "i %d location %d count %d SliceBytesInBuffer %d bitstream_size %d\n",
i, dxva_cxt->slice_short[i].BSNALunitDataLocation, dxva_cxt->slice_count,
dxva_cxt->slice_short[i].SliceBytesInBuffer, dxva_cxt->bitstream_size);
memcpy(buf + start_byte + 1, buf + end_byte, stream_size - end_byte);
stream_size -= dxva_cxt->slice_short[i].SliceBytesInBuffer;
dxva_cxt->slice_short[i].SliceBytesInBuffer -= (end_byte - start_byte - 1);
dxva_cxt->bitstream_size -= (end_byte - start_byte - 1);
ptr += dxva_cxt->slice_short[i].SliceBytesInBuffer;
}
}
}
MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn)
{
RK_S32 i = 0;
@@ -1726,6 +1774,9 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn)
mpp_buf_slot_get_prop(reg_cxt->packet_slots, syn->dec.input, SLOT_BUFFER,
&streambuf);
if (dxva_cxt->pp.slice_segment_header_extension_present_flag && !reg_cxt->is_v345) {
update_stream_buffer(streambuf, syn);
}
if ( dxva_cxt->bitstream == NULL) {
dxva_cxt->bitstream = mpp_buffer_get_ptr(streambuf);
}