Skip to content

mpp长时间播放报错MPP_ERR_BUFFER_FULL #926

@yxmstar

Description

@yxmstar

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;

}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions