1、目前场景是有5个媒体文件,每个文件大概5s的时长,轮流播放一段时间后,最后一次会出现decode_put_packet送了五帧进去然后报错MPP_ERR_BUFFER_FULL,但是使用decode_get_frame取也都是空帧,之后就一直卡在这个状态,也无法uninit。每次播放文件都会重新init/uninit mpp。
2、参考其他issues已经更新了1.0.11版本,逻辑看着也没有问题,有及时的去取出帧,目前判断问题可能是频繁init/uninit。下面是解码逻辑,麻烦帮忙确认下处理有没有问题。
`int rkmpp_decoder_h26x_process_with_pts(int decoder_id, char *enc_data, uint32_t enc_data_len,char *dst_data, int *dst_data_len,int *format, int64_t pts, rkmpp_decoder_callback_process_with_pts cb)
{
printf("pan:decoder %s,%d------------------\n",func,LINE);
int null_frame_count = 0;
MpiDecCtx *data = &g_rkmpp_decoder[decoder_id].ctx_info->ctx;
RK_U32 pkt_done = 0;
RK_U32 pkt_eos = 0;
RK_U32 err_info = 0;
MPP_RET ret = MPP_OK;
int rett = -1;
MppCtx ctx = data->ctx;
MppApi *mpi = data->mpi;
MppPacket packet = data->packet;
MppFrame frame = NULL;
mpp_packet_set_data(packet, enc_data);
if (enc_data_len > mpp_packet_get_size(packet))
mpp_packet_set_size(packet, enc_data_len);
mpp_packet_set_pos(packet, enc_data);
mpp_packet_set_length(packet, enc_data_len);
mpp_packet_set_dts(packet, pts);
// setup eos flag
if (pkt_eos)
mpp_packet_set_eos(packet);
do {
RK_S32 times = 5;
// send the packet first if packet is not done
if (!pkt_done) {
ret = mpi->decode_put_packet(ctx, packet);
if (MPP_OK == ret) {
pkt_done = 1;
if (!data->first_pkt)
data->first_pkt = mpp_time();
} else {
printf("pan:decode_put_packet failed ret %d %s,%d------------------\n",ret,__func__,__LINE__);
}
}
// then get all available frame and release
do {
RK_S32 get_frm = 0;
RK_U32 frm_eos = 0;
try_again:
ret = mpi->decode_get_frame(ctx, &frame);
printf("pan:ret %d %s,%d------------------pkt_done: %d \n",ret,__func__,__LINE__,pkt_done);
if (MPP_ERR_TIMEOUT == ret) {
if (times > 0) {
times--;
msleep(10);
goto try_again;
}
mpp_err("decode_get_frame failed too much time\n");
}
if (MPP_OK != ret) {
mpp_err("decode_get_frame failed ret %d\n", ret);
printf("pan:MPP_OK != ret %s,%d------------------\n",__func__,__LINE__);
break;
}
if (frame) {
if (mpp_frame_get_info_change(frame)) {
RK_U32 width = mpp_frame_get_width(frame);
RK_U32 height = mpp_frame_get_height(frame);
RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);
RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);
RK_U32 buf_size = mpp_frame_get_buf_size(frame);
printf("decode_get_frame get info changed found\n");
printf("decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d",
width, height, hor_stride, ver_stride, buf_size);
if (NULL == data->frm_grp) {
/* If buffer group is not set create one and limit it */
ret = mpp_buffer_group_get_internal(&data->frm_grp, MPP_BUFFER_TYPE_ION);
if (ret) {
mpp_err("get mpp buffer group failed ret %d\n", ret);
break;
}
/* Set buffer to mpp decoder */
ret = mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, data->frm_grp);
if (ret) {
mpp_err("set buffer group failed ret %d\n", ret);
break;
}
} else {
/* If old buffer group exist clear it */
ret = mpp_buffer_group_clear(data->frm_grp);
if (ret) {
mpp_err("clear buffer group failed ret %d\n", ret);
break;
}
}
/* Use limit config to limit buffer count to 24 with buf_size */
ret = mpp_buffer_group_limit_config(data->frm_grp, buf_size, 24);
if (ret) {
mpp_err("limit buffer group failed ret %d\n", ret);
break;
}
/*
* All buffer group config done. Set info change ready to let
* decoder continue decoding
*/
ret = mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
if (ret) {
mpp_err("info change ready failed ret %d\n", ret);
break;
}
} else {
if (!data->first_frm)
data->first_frm = mpp_time();
err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame);
if (err_info) {
mpp_log("decoder_get_frame get err info:%d discard:%d.\n",
mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame));
}
//printf("decode_get_frame get frame %d\n", data->frame_count);
data->frame_count++;
if (data->fp_output && !err_info)
dump_mpp_frame_to_file(frame, data->fp_output);
if(cb || dst_data)
{
rett = 1;
//printf("==pan decode_get_frame get frame %d ------\n", data->frame_count);
dump_mpp_frame_with_pts(frame,dst_data,dst_data_len,format,cb);
}
}
frm_eos = mpp_frame_get_eos(frame);
mpp_frame_deinit(&frame);
frame = NULL;
get_frm = 1;
} else {
printf("frame is NULL %s,%d------------------\n",__func__,__LINE__);
}
// if last packet is send but last frame is not found continue
if (pkt_eos && pkt_done && !frm_eos) {
msleep(1);
continue;
}
if (frm_eos) {
mpp_log("found last frame\n");
break;
}
if (get_frm)
continue;
break;
} while (g_rkmpp_decoder_is_working[decoder_id]);
if (pkt_done)
break;
/*
* why sleep here:
* mpi->decode_put_packet will failed when packet in internal queue is
* full,waiting the package is consumed .Usually hardware decode one
* frame which resolution is 1080p needs 2 ms,so here we sleep 3ms
* * is enough.
*/
msleep(4);
} while (g_rkmpp_decoder_is_working[decoder_id]);
return rett;
1、目前场景是有5个媒体文件,每个文件大概5s的时长,轮流播放一段时间后,最后一次会出现decode_put_packet送了五帧进去然后报错MPP_ERR_BUFFER_FULL,但是使用decode_get_frame取也都是空帧,之后就一直卡在这个状态,也无法uninit。每次播放文件都会重新init/uninit mpp。
2、参考其他issues已经更新了1.0.11版本,逻辑看着也没有问题,有及时的去取出帧,目前判断问题可能是频繁init/uninit。下面是解码逻辑,麻烦帮忙确认下处理有没有问题。
`int rkmpp_decoder_h26x_process_with_pts(int decoder_id, char *enc_data, uint32_t enc_data_len,char *dst_data, int *dst_data_len,int *format, int64_t pts, rkmpp_decoder_callback_process_with_pts cb)
{
printf("pan:decoder %s,%d------------------\n",func,LINE);
int null_frame_count = 0;
MpiDecCtx *data = &g_rkmpp_decoder[decoder_id].ctx_info->ctx;
RK_U32 pkt_done = 0;
RK_U32 pkt_eos = 0;
RK_U32 err_info = 0;
MPP_RET ret = MPP_OK;
int rett = -1;
MppCtx ctx = data->ctx;
MppApi *mpi = data->mpi;
}`