weixin_40992846 2021-12-27 17:27 采纳率: 100%
浏览 163
已结题

ffmpeg arm-linux avformat_find_stream_info函数奔溃问题

第一次运行时,可以正常使用此函数,并完成音视频帧的获取,但关闭文件,再次打开后,运行到此函数,没有提示任何错误就奔溃了。

这里是打开的函数

unsigned char *ffmpegMp4_Openinputfile(char *in_filename,AVFormatContext *out_ifmt_ctx,int stream_v,int stream_a)
{
if(Readframe_ifmt_ctx != NULL){
        printf("AVFormatContext need uninit!!!!\n\n");
        return NULL;
    }

    int ret, i;
    char buf[1024] = {0};

//    av_register_all();
//    avcodec_register_all();
    //Input
    if ((ret = avformat_open_input(&Readframe_ifmt_ctx, in_filename, 0, 0)) < 0) {
        av_strerror(ret,buf,1024);
        MLOGE(RED"avformat_open_input:%s %s\n",in_filename,buf);
        return NULL;
    }
    MLOGD("\n");
    if ((ret = avformat_find_stream_info(Readframe_ifmt_ctx, NULL)) < 0) {//在这里奔溃了
        MLOGE( "Failed to retrieve input stream information");
        av_strerror(ret,buf,1024);
        MLOGE(RED"avformat_find_stream_info:%s\n",buf);
        return NULL;
    }

    MLOGD("\n");
    Readframe_videoindex=-1;
    for(i=0; i<Readframe_ifmt_ctx->nb_streams; i++) {
        if(Readframe_ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
            Readframe_videoindex=i;
        }else if(Readframe_ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
            Readframe_audioindex=i;
        }
    }
    MLOGD("\n");
    //Dump Format------------------
    printf("\nInput Video===========================\n");
    av_dump_format(Readframe_ifmt_ctx, 0, in_filename, 0);
    printf("\n======================================\n");

#if USE_H264BSF
    Readframe_h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb");
#endif

    memcpy(out_ifmt_ctx,Readframe_ifmt_ctx,sizeof(AVFormatContext));
    stream_v = Readframe_videoindex;
    stream_a = Readframe_audioindex;

    return Readframe_ifmt_ctx->filename;
}

这里是读取帧函数

int ffmpegMp4_Readframe(unsigned char *video_data,int *video_size,int *isKeyframe,unsigned long int *timestamp,unsigned char * audio_data,int *audio_size){
    int ret;
    if(Readframe_ifmt_ctx == NULL){
        MLOGE("Mp4 had not open!\n");
        return -1;
    }

    av_init_packet( &Readframe_pkt );
    if(av_read_frame(Readframe_ifmt_ctx, &Readframe_pkt)>=0){

        if(Readframe_pkt.stream_index==Readframe_videoindex){
            *timestamp = Readframe_pkt.pts * av_q2d(Readframe_ifmt_ctx->streams[Readframe_pkt.stream_index]->time_base) * 1000;
#if USE_H264BSF
            av_bitstream_filter_filter(Readframe_h264bsfc, Readframe_ifmt_ctx->streams[Readframe_videoindex]->codec, NULL, &Readframe_pkt.data, &Readframe_pkt.size, Readframe_pkt.data, Readframe_pkt.size, 0);
#endif
            /*handle read video frame*/
            memcpy(video_data,Readframe_pkt.data,Readframe_pkt.size);
            *video_size = Readframe_pkt.size;
            *isKeyframe = Readframe_pkt.flags;


        }else if(Readframe_pkt.stream_index==Readframe_audioindex){
            /*
            AAC in some container format (FLV, MP4, MKV etc.) need to add 7 Bytes
            ADTS Header in front of AVPacket data manually.
            Other Audio Codec (MP3...) works well.
            */
            *timestamp = Readframe_pkt.pts * av_q2d(Readframe_ifmt_ctx->streams[Readframe_pkt.stream_index]->time_base) * 1000;
            /*handle read Audio frame*/
            memcpy(audio_data,Readframe_pkt.data,Readframe_pkt.size);
            *audio_size = Readframe_pkt.size;
            *isKeyframe = -1;
        }
        av_free_packet(&Readframe_pkt);
    }else{
        av_free_packet(&Readframe_pkt);
        return ffmpegMp4_StopReadframe();
    }

    return 0;
}

这里是uninit函数

int ffmpegMp4_StopReadframe(){
    if(Readframe_ifmt_ctx == NULL)
        return STOPLOOP;
//    SeekFrame(Readframe_ifmt_ctx,0);//重置seek位
    int ret;
#if USE_H264BSF
    av_bitstream_filter_close(Readframe_h264bsfc);
#endif
    avformat_close_input(&Readframe_ifmt_ctx);
    Readframe_ifmt_ctx = NULL;
    printf("stop readframe done!\n");
    return STOPLOOP;
}

这里是循环的测试调用

    while(count <= 5){
        ffmpegMp4_Openinputfile("/mnt/mmc/Normal/NO2021-1224-112203.mp4",&ifmt_ctx,videoindex,audioindex);
        while(ffmpegMp4_Readframe(video_buffer,&video_size,&iskeyframe,&timestamp,audio_buffer,&audio_size) == 0);
        ffmpegMp4_StopReadframe();
        printf("break?\n");
        usleep(500 * 1000);
    }

img

结果是打印完break后,就挂掉了

  • 写回答

3条回答 默认 最新

  • weixin_40992846 2021-12-28 14:26
    关注

    发现问题了,是av_bitstream_filter_filter函数没有释放内存问题,可以参考https://xilixili.net/2018/08/20/ffmpeg-got-raw-h264/

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月5日
  • 已采纳回答 12月28日
  • 修改了问题 12月27日
  • 修改了问题 12月27日
  • 展开全部

悬赏问题

  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持