VideoDecoderAVC: Return the frame info from a multiple frame buffer to decode more.
BZ: 63127
The orignal mix will drop the buffer which contains more than one frame.
Change-Id: I94d59e41a5874eeedae076353e66df479f1a3d48
Signed-off-by: fxiao4X <fengx.xiao@intel.com>
Reviewed-on: http://android.intel.com:8080/72469
Reviewed-by: Wang, Yi A <yi.a.wang@intel.com>
Reviewed-by: Guo, Nana N <nana.n.guo@intel.com>
Reviewed-by: Qiu, Junhai <junhai.qiu@intel.com>
Reviewed-by: Shi, PingX <pingx.shi@intel.com>
Tested-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: lab_cactus <lab_cactus@intel.com>
Tested-by: lab_cactus <lab_cactus@intel.com>
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
index 1bf8ee6..8592e64 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
@@ -1192,7 +1192,6 @@
/* bit offset from NAL start code to the beginning of slice data */
slc_parms->slice_data_bit_offset = bit + byte * 8;
-
if (is_emul)
{
WTRACE("next byte is emulation prevention byte.");
@@ -1571,21 +1570,18 @@
&(cxt->sc_prefix_info));
if (ret == 1)
{
- cubby.phase = 0;
-
if (cxt->list.num_items == 0)
{
cxt->list.data[0].stpos = cubby.sc_end_pos;
}
else
{
- cxt->list.data[cxt->list.num_items - 1].edpos =
- cubby.sc_end_pos + cxt->list.data[cxt->list.num_items - 1].stpos;
-
cxt->list.data[cxt->list.num_items].stpos =
- cxt->list.data[cxt->list.num_items - 1].edpos;
+ cubby.sc_end_pos + cxt->list.data[cxt->list.num_items - 1].stpos;
+ cxt->list.data[cxt->list.num_items - 1].edpos = cxt->list.data[cxt->list.num_items].stpos - cubby.phase; /* offset before start code */
}
+ cubby.phase = 0;
cubby.buf = cxt->parse_cubby.buf +
cxt->list.data[cxt->list.num_items].stpos;
@@ -1690,6 +1686,12 @@
WTRACE("unknown header %d is parsed.", parser->info.nal_unit_type);
break;
}
+
+ if (query_data->num_pictures == MAX_NUM_PICTURES && parser->info.img.field_pic_flag != 1)
+ {
+ WTRACE("more than one frame in the buffer is found(%d)", query_data->num_pictures);
+ return (error == VBP_OK ? VBP_MULTI : error);
+ }
return error;
}
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_loader.h b/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
index 38e2a05..ffeb332 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
@@ -338,7 +338,8 @@
VBP_DONE,
VBP_MEM,
VBP_PARM,
- VBP_PARTIAL
+ VBP_PARTIAL,
+ VBP_MULTI
};
enum _vbp_parser_type
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_utils.c b/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
index 237a02f..42f9c96 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
@@ -388,7 +388,10 @@
/* process parsing result */
error = pcontext->func_process_parsing_result(pcontext, i);
- if (0 != error)
+ if (VBP_MULTI == error) {
+ return VBP_OK;
+ }
+ else if (0 != error)
{
ETRACE("Failed to process parsing result.");
return error;
diff --git a/videodecoder/VideoDecoderAVC.cpp b/videodecoder/VideoDecoderAVC.cpp
index 2ef67c3..8863738 100644
--- a/videodecoder/VideoDecoderAVC.cpp
+++ b/videodecoder/VideoDecoderAVC.cpp
@@ -113,6 +113,12 @@
}
status = decodeFrame(buffer, data);
+ if (status == DECODE_MULTIPLE_FRAME) {
+ buffer->ext = &mExtensionBuffer;
+ mExtensionBuffer.extType = PACKED_FRAME_TYPE;
+ mExtensionBuffer.extSize = sizeof(mPackedFrame);
+ mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
+ }
return status;
}
@@ -228,6 +234,17 @@
return DECODE_PARSER_FAIL;
}
+ if (picIndex > 0 &&
+ (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
+ // it is a packed frame buffer
+ vbp_picture_data_h264 *lastPic = &data->pic_data[picIndex - 1];
+ vbp_slice_data_h264 *sliceData = &(lastPic->slc_data[lastPic->num_slices - 1]);
+ mPackedFrame.offSet = sliceData->slice_size + sliceData->slice_offset;
+ mPackedFrame.timestamp = mCurrentPTS; // use the current time stamp for the packed frame
+ ITRACE("slice data offset= %d, size = %d", sliceData->slice_offset, sliceData->slice_size);
+ return DECODE_MULTIPLE_FRAME;
+ }
+
for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
status = decodeSlice(data, picIndex, sliceIndex);
if (status != DECODE_SUCCESS) {
diff --git a/videodecoder/VideoDecoderAVC.h b/videodecoder/VideoDecoderAVC.h
index 339e05a..799ae2e 100644
--- a/videodecoder/VideoDecoderAVC.h
+++ b/videodecoder/VideoDecoderAVC.h
@@ -77,6 +77,8 @@
uint8_t mToggleDPB; // 0 or 1
bool mErrorConcealment;
uint32_t mLastPictureFlags;
+ VideoExtensionBuffer mExtensionBuffer;
+ PackedFrameData mPackedFrame;
};