aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorywan171 <yi.a.wang@intel.com>2014-10-28 17:14:42 +0800
committerPatrick Tjin <pattjin@google.com>2014-10-30 15:12:48 -0700
commitea8f3142b39bef0cbcfd3123446af4d527b10be3 (patch)
tree2f4fb7bd2ab8b6a3b7f23dd4e185b60d8c60dc28
parentb54bdf091833afe2ecb9235a48b87418b2d1e544 (diff)
downloadpsb_video-ea8f3142b39bef0cbcfd3123446af4d527b10be3.tar.gz
psb_video: improve DBP order consitency
enhancement for maintaining the consistent of DBP also fix the CRC issue in previous commit Bug: 17693351 Signed-off-by: ywan171 <yi.a.wang@intel.com> Change-Id: I354dc662085463472a328b680fa01abe01751916
-rwxr-xr-xsrc/pnw_H264.c229
1 files changed, 97 insertions, 132 deletions
diff --git a/src/pnw_H264.c b/src/pnw_H264.c
index d2b0a60..7adc369 100755
--- a/src/pnw_H264.c
+++ b/src/pnw_H264.c
@@ -189,9 +189,8 @@ struct context_H264_s {
struct psb_buffer_s reference_cache;
/* map picture_id to dpbidx consistently between pictures */
- uint32_t dpbidx_not_used_cnt[16];
- uint32_t map_picture_id_to_dpbidx[16];
- uint32_t dpbidx_used_this_pic_flags;
+ uint32_t map_dpbidx_to_picture_id[16];
+ uint32_t map_dpbidx_to_refidx[16];
};
@@ -409,6 +408,7 @@ static VAStatus pnw_H264_CreateContext(
{
VAStatus vaStatus = VA_STATUS_SUCCESS;
context_H264_p ctx;
+ int i = 0;
/* Validate flag */
/* Validate picture dimensions */
//vaStatus = psb__H264_check_legal_picture(obj_context, obj_config);
@@ -426,9 +426,9 @@ static VAStatus pnw_H264_CreateContext(
ctx->dec_ctx.end_slice = psb__H264_end_slice;
ctx->dec_ctx.process_buffer = pnw_H264_process_buffer;
- ctx->dpbidx_used_this_pic_flags = 0;
- memset(ctx->dpbidx_not_used_cnt, 0, sizeof(ctx->dpbidx_not_used_cnt));
- memset(ctx->map_picture_id_to_dpbidx, 0xff, sizeof(ctx->map_picture_id_to_dpbidx));
+ for(i = 0; i < 16; i++) {
+ ctx->map_dpbidx_to_picture_id[i] = VA_INVALID_SURFACE;
+ }
switch (obj_config->profile) {
case VAProfileH264Baseline:
@@ -544,39 +544,6 @@ static void psb__H264_trace_pic_params(VAPictureParameterBufferH264 *p)
P(frame_num);
}
-static uint32_t get_interpic_dpbidx(context_H264_p ctx, uint32_t picture_id)
-{
- uint32_t dpbidx, i ,max_count;
-
- /* check if picture_id is already allocated a dpbidx */
- for (dpbidx = 0; dpbidx < 16; dpbidx++)
- if (ctx->map_picture_id_to_dpbidx[dpbidx] == picture_id)
- break;
-
- /* assign a new picture_id to a new/recycled dpbidx */
- if (16 == dpbidx)
- {
- dpbidx = 0;
- max_count = ctx->dpbidx_not_used_cnt[0];
- for (i = 1; i < 16; i++)
- {
- if (ctx->dpbidx_not_used_cnt[i] > max_count)
- {
- dpbidx = i;
- max_count = ctx->dpbidx_not_used_cnt[i];
- }
- }
- ctx->map_picture_id_to_dpbidx[dpbidx] = picture_id;
- ctx->dpbidx_not_used_cnt[dpbidx] = 0;
- }
-
- /* record this dpbidx is used this pic to update the dpbidx_not_used_cnt later */
- ctx->dpbidx_used_this_pic_flags |= (1 << dpbidx);
-
- return dpbidx;
-}
-
-
static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffer_p obj_buffer)
{
psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
@@ -671,33 +638,91 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe
}
uint32_t i;
- /* update the not_used_cnt from the last picture data */
+ uint32_t dpbidx;
+ uint32_t num_new_pics = 0;
+ uint32_t new_pic_ids[16];
+ uint32_t dpbidx_used_this_pic_flags = 0;
+ ctx->long_term_frame_flags = 0;
+
+ if (pic_params->num_ref_frames > 16) {
+ drv_debug_msg(VIDEO_DEBUG_ERROR, "%s:%d Too many ref frames %d",__FILE__, __LINE__,pic_params->num_ref_frames);
+ // error here
+ pic_params->num_ref_frames = 16;
+ }
+ /* find new reference picture */
+ for (i = 0; i < pic_params->num_ref_frames; i++) {
+ if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) {
+ // warning here
+ continue;
+ }
+ for (dpbidx = 0; dpbidx < 16; dpbidx++) {
+ if (ctx->map_dpbidx_to_picture_id[dpbidx] == pic_params->ReferenceFrames[i].picture_id) {
+ dpbidx_used_this_pic_flags |= (0x1 << dpbidx);
+ break;
+ }
+ }
+ if (16 == dpbidx) {
+ new_pic_ids[num_new_pics] = pic_params->ReferenceFrames[i].picture_id;
+ num_new_pics++;
+ }
+ }
+
+ /* invalidate unused dpb entries */
for (i = 0; i < 16; i++) {
- if (!(ctx->dpbidx_used_this_pic_flags & (1 << i)))
- ctx->dpbidx_not_used_cnt[i]++;
+ if (!(dpbidx_used_this_pic_flags & (1 << i))) {
+ ctx->map_dpbidx_to_picture_id[i] = VA_INVALID_SURFACE;
+ }
}
- ctx->dpbidx_used_this_pic_flags = 0;
- ctx->long_term_frame_flags = 0;
+ /* find an empty dpb location for new entries */
+ dpbidx = 0;
+ for (i = 0; i < num_new_pics; i++) {
+ for (; dpbidx < 16; dpbidx++) {
+ if (VA_INVALID_SURFACE == ctx->map_dpbidx_to_picture_id[dpbidx]) {
+ ctx->map_dpbidx_to_picture_id[dpbidx] = new_pic_ids[i];
+ break;
+ }
+ }
+ if (16 == dpbidx) {
+ drv_debug_msg(VIDEO_DEBUG_ERROR, "%s:%d No empty space for new frame %d (%08x)",__FILE__, __LINE__,i,dpbidx_used_this_pic_flags);
+ // error here
+ break;
+ }
+ }
- if (pic_params->num_ref_frames == 0) {
- ctx->dpbidx_used_this_pic_flags = 0;
- memset(ctx->dpbidx_not_used_cnt, 0, sizeof(ctx->dpbidx_not_used_cnt));
- memset(ctx->map_picture_id_to_dpbidx, 0xff, sizeof(ctx->map_picture_id_to_dpbidx));
+ /* update surfaces with dpbidx */
+ for (dpbidx = 0; dpbidx < 16; dpbidx++) {
+ if (VA_INVALID_SURFACE != ctx->map_dpbidx_to_picture_id[dpbidx]) {
+ object_surface_p ref_surface = SURFACE(ctx->map_dpbidx_to_picture_id[dpbidx]);
+ if (!ref_surface) {
+ drv_debug_msg(VIDEO_DEBUG_ERROR, "%s:%d No surface for refernce frame",__FILE__, __LINE__);
+ // error here
+ continue;
+ }
+ SET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface, dpbidx);
+ }
}
- /* We go from high to low so that we are left with the lowest index */
- for (i = pic_params->num_ref_frames; i--;) {
- uint32_t dpbidx;
+
+ /* get the reference location and long term flag for each dpb location */
+ memset(ctx->map_dpbidx_to_refidx, 0xff, sizeof(ctx->map_dpbidx_to_refidx));
+ for (i = 0; i < pic_params->num_ref_frames; i++) {
if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) {
continue;
}
object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id);
if (ref_surface) {
- dpbidx = get_interpic_dpbidx(ctx, pic_params->ReferenceFrames[i].picture_id);
- if (pic_params->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) {
- ctx->long_term_frame_flags |= 0x01 << dpbidx;
+ dpbidx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
+ if (dpbidx < 16) {
+ ctx->map_dpbidx_to_refidx[dpbidx] = i;
+ if (pic_params->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) {
+ ctx->long_term_frame_flags |= 0x01 << dpbidx;
+ }
+ }
+ else {
+ drv_debug_msg(VIDEO_DEBUG_ERROR, "%s:%d No invalid dpbidx stored with surface %d",__FILE__, __LINE__,dpbidx);
+ // error here
+ continue;
}
- SET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface, dpbidx);
}
}
@@ -964,7 +989,7 @@ static void psb__H264_build_SCA_chunk(context_H264_p ctx)
psb_cmdbuf_rendec_end(cmdbuf);
}
-static void psb__H264_build_picture_order_chunk(context_H264_p ctx, uint32_t * map)
+static void psb__H264_build_picture_order_chunk(context_H264_p ctx)
{
psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
VAPictureParameterBufferH264 *pic_params = ctx->pic_params;
@@ -992,15 +1017,16 @@ static void psb__H264_build_picture_order_chunk(context_H264_p ctx, uint32_t * m
}
for (i = 0; i < 16; i++) {
- if (map[i] < 16) {
+ uint32_t refidx = ctx->map_dpbidx_to_refidx[i];
+ if (refidx < 16) {
reg_value = 0;
REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_TOP_FOC, TOPFIELDORDERCNT,
- SIGNTRUNC(pic_params->ReferenceFrames[map[i]].TopFieldOrderCnt));
+ SIGNTRUNC(pic_params->ReferenceFrames[refidx].TopFieldOrderCnt));
psb_cmdbuf_rendec_write(cmdbuf, reg_value);
reg_value = 0;
REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_BOT_FOC, BOTTOMFIELDORDERCNT,
- SIGNTRUNC(pic_params->ReferenceFrames[map[i]].BottomFieldOrderCnt));
+ SIGNTRUNC(pic_params->ReferenceFrames[refidx].BottomFieldOrderCnt));
psb_cmdbuf_rendec_write(cmdbuf, reg_value);
}
else {
@@ -1160,36 +1186,6 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
uint32_t reg_value;
unsigned int i;
- int picture_id = ctx->obj_context->current_render_target->surface_id;
- for(i = 0; i < 16; i++) {
- if (ctx->map_picture_id_to_dpbidx[i] == (unsigned int)picture_id)
- break;
- }
-
- if (i < 16) {
- ctx->map_picture_id_to_dpbidx[i] = 0xff;
- ctx->dpbidx_not_used_cnt[i] = 0xff00;
- }
-
- /* get the dpbidx for the ref pictures */
- uint32_t map_dpbidx_to_refidx[16];
- memset(map_dpbidx_to_refidx, 0xff, sizeof(map_dpbidx_to_refidx));
-
- if (pic_params->num_ref_frames > 16)
- pic_params->num_ref_frames = 16;
- for (i = 0; i < pic_params->num_ref_frames; i++) {
- if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) {
- continue;
- }
- object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id);
- if (ref_surface) {
- uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
- if (idx < 16) {
- map_dpbidx_to_refidx[idx] = i;
- }
- }
- }
-
/* psb_cmdbuf_rendec_start_block( cmdbuf ); */
/* CHUNK: Entdec back-end profile and level */
@@ -1244,7 +1240,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
/* send Picture Order Counts (b frame only?) */
/* maybe need a state variable to track if this has already been sent for the frame */
if (slice_param->slice_type == ST_B) {
- psb__H264_build_picture_order_chunk(ctx, map_dpbidx_to_refidx);
+ psb__H264_build_picture_order_chunk(ctx);
}
/* CHUNK: BIN */
@@ -1280,46 +1276,13 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
/* send DPB information (for P and B slices?) only needed once per frame */
// if ( sh->slice_type == ST_B || sh->slice_type == ST_P )
if (pic_params->num_ref_frames > 0 && (slice_param->slice_type == ST_B || slice_param->slice_type == ST_P)) {
- IMG_BOOL is_used[16];
psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
- /* Mark all surfaces as unused */
- memset(is_used, 0, sizeof(is_used));
-
- if (slice_param->num_ref_idx_l0_active_minus1 > 31)
- slice_param->num_ref_idx_l0_active_minus1 = 31;
- /* Mark onlys frame that are actualy used */
- for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
- object_surface_p ref_surface = SURFACE(slice_param->RefPicList0[i].picture_id);
- if (ref_surface) {
- uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
- if (idx < 16) {
- is_used[idx] = IMG_TRUE;
- }
- }
- }
-
- if (slice_param->num_ref_idx_l1_active_minus1 > 31)
- slice_param->num_ref_idx_l1_active_minus1 = 31;
-
- /* Mark onlys frame that are actualy used */
- for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
- object_surface_p ref_surface = SURFACE(slice_param->RefPicList1[i].picture_id);
- if (ref_surface) {
- uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
- if (idx < 16) {
- is_used[idx] = IMG_TRUE;
- }
- }
- }
-
- /* Only load used surfaces */
- for (i = 0; i < 16; i++) {
- if (map_dpbidx_to_refidx[i] < 16) {
-// if (pic_params->ReferenceFrames[map_dpbidx_to_refidx[i]].flags == VA_PICTURE_H264_INVALID) {
-// continue;
-// }
- object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[map_dpbidx_to_refidx[i]].picture_id);
+ uint32_t dpbidx = 0;
+ for (dpbidx = 0; dpbidx < 16; dpbidx++) {
+ /* Only load used surfaces */
+ if (VA_INVALID_SURFACE != ctx->map_dpbidx_to_picture_id[dpbidx]) {
+ object_surface_p ref_surface = SURFACE(ctx->map_dpbidx_to_picture_id[dpbidx]);
psb_buffer_p buffer;
if (NULL == ref_surface) {
@@ -1340,7 +1303,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
pic_params->ReferenceFrames[i].BottomFieldOrderCnt,
is_used[i] ? "used" : "");
*/
- if (ref_surface && is_used[i] && buffer) {
+ if (ref_surface && buffer) {
psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
buffer->buffer_ofs);
psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
@@ -1348,13 +1311,15 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
ref_surface->psb_surface->chroma_offset);
buffer->unfence_flag = 1;
} else {
+ // error here
+ drv_debug_msg(VIDEO_DEBUG_ERROR, "%s:%d No valid buffer for DPB",__FILE__, __LINE__);
psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
}
} else {
- psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
- psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
- }
+ psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
+ psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
+ }
}
psb_cmdbuf_rendec_end(cmdbuf);
}