[mpg4d]: update spit mode in prepare

1. re-write split mode code.
2. combine realloc buffer code about copy and split mode.
3. add extra 64 bytes in buffer tail, and memset to 0 algin 64.

Change-Id: I88807c2aeb0d1b36a8a81d09c95c66c0babed078
Signed-off-by: leo.ding <leo.ding@rock-chips.com>
This commit is contained in:
leo.ding
2017-08-09 18:19:39 +08:00
committed by Herman Chen
parent 29efa84812
commit 1397e8ca0e
3 changed files with 88 additions and 111 deletions

View File

@@ -37,6 +37,7 @@ typedef struct {
RK_S32 task_count; RK_S32 task_count;
RK_U8 *stream; RK_U8 *stream;
size_t stream_size; size_t stream_size;
size_t left_length;
MppPacket task_pkt; MppPacket task_pkt;
RK_S64 task_pts; RK_S64 task_pts;
RK_U32 task_eos; RK_U32 task_eos;
@@ -99,7 +100,7 @@ MPP_RET mpg4d_init(void *dec, ParserCfg *cfg)
p->stream_size = stream_size; p->stream_size = stream_size;
p->task_pkt = task_pkt; p->task_pkt = task_pkt;
p->parser = parser; p->parser = parser;
p->left_length = 0;
return MPP_OK; return MPP_OK;
ERR_RET: ERR_RET:
if (task_pkt) { if (task_pkt) {
@@ -145,6 +146,7 @@ MPP_RET mpg4d_reset(void *dec)
} }
Mpg4dCtx *p = (Mpg4dCtx *)dec; Mpg4dCtx *p = (Mpg4dCtx *)dec;
p->left_length = 0;
return mpp_mpg4_parser_reset(p->parser); return mpp_mpg4_parser_reset(p->parser);
} }
@@ -209,6 +211,33 @@ MPP_RET mpg4d_prepare(void *dec, MppPacket pkt, HalDecTask *task)
mpp_err("failed to malloc task buffer for hardware with size %d\n", length); mpp_err("failed to malloc task buffer for hardware with size %d\n", length);
return MPP_ERR_UNKNOW; return MPP_ERR_UNKNOW;
} }
mpp_packet_set_length(p->task_pkt, p->left_length);
/*
* Check have enough buffer to store stream
* NOTE: total length is the left size plus the new incoming
* packet length.
*/
size_t total_length = MPP_ALIGN(p->left_length + length, 16) + 64; // add extra 64 bytes in tails
if (total_length > p->stream_size) {
RK_U8 *dst;
do {
p->stream_size <<= 1;
} while (length > p->stream_size);
dst = mpp_malloc_size(RK_U8, p->stream_size);
mpp_assert(dst);
// NOTE: copy remaining stream to new buffer
if (p->left_length > 0) {
memcpy(dst, p->stream, p->left_length);
}
mpp_free(p->stream);
p->stream = dst;
mpp_packet_set_data(p->task_pkt, p->stream);
mpp_packet_set_size(p->task_pkt, p->stream_size);
}
if (!p->need_split) { if (!p->need_split) {
/* /*
@@ -216,19 +245,6 @@ MPP_RET mpg4d_prepare(void *dec, MppPacket pkt, HalDecTask *task)
* Decoder's user will insure each packet is one frame for process * Decoder's user will insure each packet is one frame for process
* Parser will just copy packet to the beginning of stream buffer * Parser will just copy packet to the beginning of stream buffer
*/ */
if (length > p->stream_size) {
// NOTE: here we double the buffer length to reduce frequency of realloc
do {
p->stream_size <<= 1;
} while (length > p->stream_size);
mpp_free(p->stream);
p->stream = mpp_malloc_size(RK_U8, p->stream_size);
mpp_assert(p->stream);
mpp_packet_set_data(p->task_pkt, p->stream);
mpp_packet_set_size(p->task_pkt, p->stream_size);
}
memcpy(p->stream, pos, length); memcpy(p->stream, pos, length);
mpp_packet_set_pos(p->task_pkt, p->stream); mpp_packet_set_pos(p->task_pkt, p->stream);
mpp_packet_set_length(p->task_pkt, length); mpp_packet_set_length(p->task_pkt, length);
@@ -246,32 +262,12 @@ MPP_RET mpg4d_prepare(void *dec, MppPacket pkt, HalDecTask *task)
* Input packet can be any length and no need to be bound of on frame * Input packet can be any length and no need to be bound of on frame
* Parser will do split frame operation to find the beginning and end of one frame * Parser will do split frame operation to find the beginning and end of one frame
*/ */
/*
* NOTE: on split mode total length is the left size plus the new incoming
* packet length.
*/
size_t remain_length = mpp_packet_get_length(p->task_pkt);
size_t total_length = remain_length + length;
if (total_length > p->stream_size) {
RK_U8 *dst;
do {
p->stream_size <<= 1;
} while (length > p->stream_size);
// NOTE; split mode need to copy remaining stream to new buffer
dst = mpp_malloc_size(RK_U8, p->stream_size);
mpp_assert(dst);
memcpy(dst, p->stream, remain_length);
mpp_free(p->stream);
p->stream = dst;
mpp_packet_set_data(p->task_pkt, p->stream);
mpp_packet_set_size(p->task_pkt, p->stream_size);
}
// start parser split
if (MPP_OK == mpp_mpg4_parser_split(p->parser, p->task_pkt, pkt)) { if (MPP_OK == mpp_mpg4_parser_split(p->parser, p->task_pkt, pkt)) {
p->left_length = 0;
task->valid = 1; task->valid = 1;
} else {
task->valid = 0;
p->left_length = mpp_packet_get_length(p->task_pkt);
} }
p->task_pts = mpp_packet_get_pts(p->task_pkt); p->task_pts = mpp_packet_get_pts(p->task_pkt);
p->task_eos = mpp_packet_get_eos(p->task_pkt); p->task_eos = mpp_packet_get_eos(p->task_pkt);
@@ -300,6 +296,7 @@ MPP_RET mpg4d_parse(void *dec, HalDecTask *task)
task->valid = 0; task->valid = 0;
task->output = -1; task->output = -1;
mpp_packet_set_length(task->input_packet, 0); mpp_packet_set_length(task->input_packet, 0);
return MPP_NOK; return MPP_NOK;
} }

View File

@@ -23,6 +23,7 @@
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_mem.h" #include "mpp_mem.h"
#include "mpp_packet.h" #include "mpp_packet.h"
#include "mpp_common.h"
#include "mpp_bitread.h" #include "mpp_bitread.h"
#include "mpg4d_parser.h" #include "mpg4d_parser.h"
@@ -171,8 +172,8 @@ typedef struct {
RK_U32 eos; RK_U32 eos;
// spliter parameter // spliter parameter
RK_S32 pos_frm_start; // negtive - not found; non-negtive - position of frame start RK_U32 state;
RK_S32 pos_frm_end; // negtive - not found; non-negtive - position of frame end RK_U32 vop_header_found; // flag: visual object plane header found
// bit read context // bit read context
BitReadCtx_t *bit_ctx; BitReadCtx_t *bit_ctx;
@@ -180,7 +181,6 @@ typedef struct {
RK_U32 profile; RK_U32 profile;
RK_U32 level; RK_U32 level;
RK_U32 custorm_version; RK_U32 custorm_version;
// commom buffer for header information // commom buffer for header information
/* /*
* NOTE: We assume that quant matrix only used for current frame decoding * NOTE: We assume that quant matrix only used for current frame decoding
@@ -1074,8 +1074,8 @@ MPP_RET mpp_mpg4_parser_init(Mpg4dParser *ctx, MppBufSlots frame_slots)
mpp_buf_slot_setup(frame_slots, 8); mpp_buf_slot_setup(frame_slots, 8);
p->frame_slots = frame_slots; p->frame_slots = frame_slots;
p->use_internal_pts = 0; p->use_internal_pts = 0;
p->pos_frm_start = -1; p->state = -1;
p->pos_frm_end = -1; p->vop_header_found = 0;
p->bit_ctx = bit_ctx; p->bit_ctx = bit_ctx;
init_mpg4_header(&p->hdr_curr); init_mpg4_header(&p->hdr_curr);
init_mpg4_header(&p->hdr_ref0); init_mpg4_header(&p->hdr_ref0);
@@ -1160,8 +1160,10 @@ MPP_RET mpp_mpg4_parser_reset(Mpg4dParser ctx)
hdr_ref1->slot_idx = -1; hdr_ref1->slot_idx = -1;
} }
p->found_i_vop = 0; p->found_i_vop = 0;
p->found_vop = 0; p->found_vop = 0;
p->state = -1;
p->vop_header_found = 0;
mpg4d_dbg_func("out\n"); mpg4d_dbg_func("out\n");
@@ -1172,84 +1174,54 @@ MPP_RET mpp_mpg4_parser_split(Mpg4dParser ctx, MppPacket dst, MppPacket src)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_NOK;
Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx;
RK_U8 *dst_buf = mpp_packet_get_data(dst); RK_U8 *src_buf = (RK_U8 *)mpp_packet_get_pos(src);
size_t dst_len = mpp_packet_get_length(dst); RK_U32 src_len = (RK_U32)mpp_packet_get_length(src);
RK_U8 *src_buf = mpp_packet_get_pos(src);
RK_S32 src_len = (RK_S32)mpp_packet_get_length(src);
RK_S32 pos_frm_start = p->pos_frm_start;
RK_S32 pos_frm_end = p->pos_frm_end;
RK_U32 src_eos = mpp_packet_get_eos(src); RK_U32 src_eos = mpp_packet_get_eos(src);
RK_S32 src_pos = 0; RK_U8 *dst_buf = (RK_U8 *)mpp_packet_get_data(dst);
RK_U32 state = (RK_U32) - 1; RK_U32 dst_len = (RK_U32)mpp_packet_get_length(dst);
RK_U32 src_pos = 0;
mpg4d_dbg_func("in\n"); mpg4d_dbg_func("in\n");
mpp_assert(src_len); // find the began of the vop
if (!p->vop_header_found) {
if (dst_len) { // add last startcode to the new frame data
mpp_assert(dst_len >= 4); if ((dst_len < sizeof(p->state))
state = ((RK_U32)(dst_buf[dst_len - 1]) << 0) | && ((p->state & 0x00FFFFFF) == 0x000001)) {
((RK_U32)(dst_buf[dst_len - 2]) << 8) | dst_buf[0] = 0;
((RK_U32)(dst_buf[dst_len - 3]) << 16) | dst_buf[1] = 0;
((RK_U32)(dst_buf[dst_len - 4]) << 24); dst_buf[2] = 1;
} dst_len = 3;
}
if (pos_frm_start < 0) { while (src_pos < src_len) {
// scan for frame start p->state = (p->state << 8) | src_buf[src_pos];
for (src_pos = 0; src_pos < src_len; src_pos++) { dst_buf[dst_len++] = src_buf[src_pos++];
state = (state << 8) | src_buf[src_pos]; if (p->state == MPG4_VOP_STARTCODE) {
if (state == MPG4_VOP_STARTCODE) { p->vop_header_found = 1;
src_pos++;
pos_frm_start = src_pos - 4;
break; break;
} }
} }
} }
// find the end of the vop
if (pos_frm_start >= 0) { if (p->vop_header_found) {
// scan for frame end while (src_pos < src_len) {
for (; src_pos < src_len; src_pos++) { p->state = (p->state << 8) | src_buf[src_pos];
state = (state << 8) | src_buf[src_pos]; dst_buf[dst_len++] = src_buf[src_pos++];
if ((p->state & 0x00FFFFFF) == 0x000001) {
if ((state & 0xFFFFFFFF) == MPG4_VOP_STARTCODE) { dst_len -= 3;
pos_frm_end = src_pos - 3; p->vop_header_found = 0;
ret = MPP_OK; // split complete
break; break;
} }
} }
if (src_eos && src_pos == src_len) {
pos_frm_end = src_len;
mpp_packet_set_eos(dst);
}
} }
// the last packet
//mpp_log("pkt pos: start %d end %d len: left %d in %d\n", if (src_eos && src_pos >= src_len) {
// pos_frm_start, pos_frm_end, dst_len, src_len); mpp_packet_set_eos(dst);
if (pos_frm_start < 0 || pos_frm_end < 0) {
// do not found frame start or do not found frame end, just copy the hold buffer to dst
memcpy(dst_buf + dst_len, src_buf, src_len);
// update dst buffer length
mpp_packet_set_length(dst, dst_len + src_len);
// set src buffer pos to end to src buffer
mpp_packet_set_pos(src, src_buf + src_len);
} else {
// found both frame start and frame end - only copy frame
memcpy(dst_buf + dst_len, src_buf, pos_frm_end);
mpp_packet_set_length(dst, dst_len + pos_frm_end);
// set src buffer pos to end to src buffer
mpp_packet_set_pos(src, src_buf + pos_frm_end);
mpp_assert((RK_S32)mpp_packet_get_length(src) == (src_len - pos_frm_end));
mpp_packet_set_length(src, src_len - pos_frm_end);
// return ok indicate the frame is ready and reset frame start/end position
ret = MPP_OK;
pos_frm_start = -1;
pos_frm_end = -1;
} }
// reset the src and dst
p->pos_frm_start = pos_frm_start; mpp_packet_set_length(dst, dst_len);
p->pos_frm_end = pos_frm_end; mpp_packet_set_pos(src, src_buf + src_pos);
mpg4d_dbg_func("out\n"); mpg4d_dbg_func("out\n");

View File

@@ -25,6 +25,7 @@
#include "mpp_mem.h" #include "mpp_mem.h"
#include "mpp_env.h" #include "mpp_env.h"
#include "mpp_buffer.h" #include "mpp_buffer.h"
#include "mpp_common.h"
#include "mpp_device.h" #include "mpp_device.h"
#include "mpp_dec.h" #include "mpp_dec.h"
@@ -45,7 +46,7 @@ typedef struct mpeg4d_reg_context {
RK_S32 fd_curr; RK_S32 fd_curr;
RK_S32 fd_ref0; RK_S32 fd_ref0;
RK_S32 fd_ref1; RK_S32 fd_ref1;
RK_U32 bitstrm_len;
// mv info buffer // mv info buffer
// NOTE: mv buffer fix to 1080p size for convenience // NOTE: mv buffer fix to 1080p size for convenience
MppBuffer mv_buf; MppBuffer mv_buf;
@@ -109,6 +110,7 @@ static void vpu_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx *ctx, MppSyntax syntax)
case DXVA2_BitStreamDateBufferType : { case DXVA2_BitStreamDateBufferType : {
stream_length = desc->DataSize; stream_length = desc->DataSize;
stream_used = desc->DataOffset; stream_used = desc->DataOffset;
ctx->bitstrm_len = stream_length;
} break; } break;
default : { default : {
mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType); mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType);
@@ -442,6 +444,12 @@ MPP_RET hal_vpu_mpg4d_gen_regs(void *hal, HalTaskInfo *syn)
/* setup other registers, here will update packet address */ /* setup other registers, here will update packet address */
vpu_mpg4d_setup_regs_by_syntax(ctx, task->syntax); vpu_mpg4d_setup_regs_by_syntax(ctx, task->syntax);
/* memset tails to zero for stream buffer */
{
RK_U8 *ptr = (RK_U8 *)mpp_buffer_get_ptr(buf_pkt);
RK_U32 strm_len = MPP_ALIGN(ctx->bitstrm_len, 16) + 64;
memset(ptr + ctx->bitstrm_len, 0, strm_len - ctx->bitstrm_len);
}
return ret; return ret;
} }