Skip to content

mpp长时间播放报错MPP_ERR_BUFFER_FULL #70

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions