mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-06 17:46:50 +08:00
[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:
@@ -37,6 +37,7 @@ typedef struct {
|
||||
RK_S32 task_count;
|
||||
RK_U8 *stream;
|
||||
size_t stream_size;
|
||||
size_t left_length;
|
||||
MppPacket task_pkt;
|
||||
RK_S64 task_pts;
|
||||
RK_U32 task_eos;
|
||||
@@ -99,7 +100,7 @@ MPP_RET mpg4d_init(void *dec, ParserCfg *cfg)
|
||||
p->stream_size = stream_size;
|
||||
p->task_pkt = task_pkt;
|
||||
p->parser = parser;
|
||||
|
||||
p->left_length = 0;
|
||||
return MPP_OK;
|
||||
ERR_RET:
|
||||
if (task_pkt) {
|
||||
@@ -145,6 +146,7 @@ MPP_RET mpg4d_reset(void *dec)
|
||||
}
|
||||
|
||||
Mpg4dCtx *p = (Mpg4dCtx *)dec;
|
||||
p->left_length = 0;
|
||||
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);
|
||||
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) {
|
||||
/*
|
||||
@@ -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
|
||||
* 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);
|
||||
mpp_packet_set_pos(p->task_pkt, p->stream);
|
||||
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
|
||||
* 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)) {
|
||||
p->left_length = 0;
|
||||
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_eos = mpp_packet_get_eos(p->task_pkt);
|
||||
@@ -300,6 +296,7 @@ MPP_RET mpg4d_parse(void *dec, HalDecTask *task)
|
||||
task->valid = 0;
|
||||
task->output = -1;
|
||||
mpp_packet_set_length(task->input_packet, 0);
|
||||
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_packet.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "mpp_bitread.h"
|
||||
#include "mpg4d_parser.h"
|
||||
@@ -171,8 +172,8 @@ typedef struct {
|
||||
RK_U32 eos;
|
||||
|
||||
// spliter parameter
|
||||
RK_S32 pos_frm_start; // negtive - not found; non-negtive - position of frame start
|
||||
RK_S32 pos_frm_end; // negtive - not found; non-negtive - position of frame end
|
||||
RK_U32 state;
|
||||
RK_U32 vop_header_found; // flag: visual object plane header found
|
||||
|
||||
// bit read context
|
||||
BitReadCtx_t *bit_ctx;
|
||||
@@ -180,7 +181,6 @@ typedef struct {
|
||||
RK_U32 profile;
|
||||
RK_U32 level;
|
||||
RK_U32 custorm_version;
|
||||
|
||||
// commom buffer for header information
|
||||
/*
|
||||
* 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);
|
||||
p->frame_slots = frame_slots;
|
||||
p->use_internal_pts = 0;
|
||||
p->pos_frm_start = -1;
|
||||
p->pos_frm_end = -1;
|
||||
p->state = -1;
|
||||
p->vop_header_found = 0;
|
||||
p->bit_ctx = bit_ctx;
|
||||
init_mpg4_header(&p->hdr_curr);
|
||||
init_mpg4_header(&p->hdr_ref0);
|
||||
@@ -1162,6 +1162,8 @@ MPP_RET mpp_mpg4_parser_reset(Mpg4dParser ctx)
|
||||
|
||||
p->found_i_vop = 0;
|
||||
p->found_vop = 0;
|
||||
p->state = -1;
|
||||
p->vop_header_found = 0;
|
||||
|
||||
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;
|
||||
Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx;
|
||||
RK_U8 *dst_buf = mpp_packet_get_data(dst);
|
||||
size_t dst_len = mpp_packet_get_length(dst);
|
||||
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_U8 *src_buf = (RK_U8 *)mpp_packet_get_pos(src);
|
||||
RK_U32 src_len = (RK_U32)mpp_packet_get_length(src);
|
||||
RK_U32 src_eos = mpp_packet_get_eos(src);
|
||||
RK_S32 src_pos = 0;
|
||||
RK_U32 state = (RK_U32) - 1;
|
||||
RK_U8 *dst_buf = (RK_U8 *)mpp_packet_get_data(dst);
|
||||
RK_U32 dst_len = (RK_U32)mpp_packet_get_length(dst);
|
||||
RK_U32 src_pos = 0;
|
||||
|
||||
mpg4d_dbg_func("in\n");
|
||||
|
||||
mpp_assert(src_len);
|
||||
|
||||
if (dst_len) {
|
||||
mpp_assert(dst_len >= 4);
|
||||
state = ((RK_U32)(dst_buf[dst_len - 1]) << 0) |
|
||||
((RK_U32)(dst_buf[dst_len - 2]) << 8) |
|
||||
((RK_U32)(dst_buf[dst_len - 3]) << 16) |
|
||||
((RK_U32)(dst_buf[dst_len - 4]) << 24);
|
||||
// find the began of the vop
|
||||
if (!p->vop_header_found) {
|
||||
// add last startcode to the new frame data
|
||||
if ((dst_len < sizeof(p->state))
|
||||
&& ((p->state & 0x00FFFFFF) == 0x000001)) {
|
||||
dst_buf[0] = 0;
|
||||
dst_buf[1] = 0;
|
||||
dst_buf[2] = 1;
|
||||
dst_len = 3;
|
||||
}
|
||||
|
||||
if (pos_frm_start < 0) {
|
||||
// scan for frame start
|
||||
for (src_pos = 0; src_pos < src_len; src_pos++) {
|
||||
state = (state << 8) | src_buf[src_pos];
|
||||
if (state == MPG4_VOP_STARTCODE) {
|
||||
src_pos++;
|
||||
pos_frm_start = src_pos - 4;
|
||||
while (src_pos < src_len) {
|
||||
p->state = (p->state << 8) | src_buf[src_pos];
|
||||
dst_buf[dst_len++] = src_buf[src_pos++];
|
||||
if (p->state == MPG4_VOP_STARTCODE) {
|
||||
p->vop_header_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos_frm_start >= 0) {
|
||||
// scan for frame end
|
||||
for (; src_pos < src_len; src_pos++) {
|
||||
state = (state << 8) | src_buf[src_pos];
|
||||
|
||||
if ((state & 0xFFFFFFFF) == MPG4_VOP_STARTCODE) {
|
||||
pos_frm_end = src_pos - 3;
|
||||
// find the end of the vop
|
||||
if (p->vop_header_found) {
|
||||
while (src_pos < src_len) {
|
||||
p->state = (p->state << 8) | src_buf[src_pos];
|
||||
dst_buf[dst_len++] = src_buf[src_pos++];
|
||||
if ((p->state & 0x00FFFFFF) == 0x000001) {
|
||||
dst_len -= 3;
|
||||
p->vop_header_found = 0;
|
||||
ret = MPP_OK; // split complete
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (src_eos && src_pos == src_len) {
|
||||
pos_frm_end = src_len;
|
||||
}
|
||||
// the last packet
|
||||
if (src_eos && src_pos >= src_len) {
|
||||
mpp_packet_set_eos(dst);
|
||||
}
|
||||
}
|
||||
|
||||
//mpp_log("pkt pos: start %d end %d len: left %d in %d\n",
|
||||
// pos_frm_start, pos_frm_end, dst_len, src_len);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
p->pos_frm_start = pos_frm_start;
|
||||
p->pos_frm_end = pos_frm_end;
|
||||
// reset the src and dst
|
||||
mpp_packet_set_length(dst, dst_len);
|
||||
mpp_packet_set_pos(src, src_buf + src_pos);
|
||||
|
||||
mpg4d_dbg_func("out\n");
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_buffer.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "mpp_device.h"
|
||||
#include "mpp_dec.h"
|
||||
@@ -45,7 +46,7 @@ typedef struct mpeg4d_reg_context {
|
||||
RK_S32 fd_curr;
|
||||
RK_S32 fd_ref0;
|
||||
RK_S32 fd_ref1;
|
||||
|
||||
RK_U32 bitstrm_len;
|
||||
// mv info buffer
|
||||
// NOTE: mv buffer fix to 1080p size for convenience
|
||||
MppBuffer mv_buf;
|
||||
@@ -109,6 +110,7 @@ static void vpu_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx *ctx, MppSyntax syntax)
|
||||
case DXVA2_BitStreamDateBufferType : {
|
||||
stream_length = desc->DataSize;
|
||||
stream_used = desc->DataOffset;
|
||||
ctx->bitstrm_len = stream_length;
|
||||
} break;
|
||||
default : {
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user