Ffmpeg录像的内存泄露问题
< 返回列表时间: 2019-01-10来源:开源中国
HDC调试需求开发(15万预算),能者速来!>>>
下面是使用ffmpeg对rtsp流进行录像的代码,程序运行后,内存一直不停的往上涨,网上查过都说是内存泄露造成的,可是具体哪里泄露了,折腾好久了没找到原因。哪位熟悉ffmpeg的仁兄,帮忙看看,谢过! void saveRtsp() { AVFormatContext *pFormatCtx = nullptr; // FFMPEG所有的操作都要通过这个AVFormatContext来进行 AVCodecContext *pCodecCtx = nullptr; AVCodec *pCodec = nullptr; AVFrame *pFrame = nullptr, *pFrameRGB = nullptr; AVPacket *packet = nullptr; uint8_t *out_buffer = nullptr; struct SwsContext *img_convert_ctx = nullptr; AVDictionary *avdic = nullptr; AVDictionary *params = nullptr; int videoStream, numBytes; long start = 0, finish = 0; int frames = 0; // 保存的packet数量 // 初始化 avformat_network_init(); // 初始化FFmpeg网络模块 av_register_all(); // 初始化FFMPEG 调用了这个才能正常适用编码器和解码器 pFormatCtx = avformat_alloc_context(); // 分配一个AVFormatContext,查找用于输入的设备 av_dict_set(&avdic, "rtsp_transport", "tcp", 0); av_dict_set(&avdic, "max_delay", "100", 0); //av_dict_set(&avdic, "probesize", "32000000", 0); av_dict_set(&avdic, "max_analyze_duration", "1000", 0); av_dict_set(&avdic, "buffer_size", "1024000", 0); av_dict_set(&avdic, "stimeout", "2000000", 0); // 如果没有设置stimeout if (avformat_open_input(&pFormatCtx, rtspMain.c_str(), NULL, &avdic) != 0) { cout<<"打不开视频,请检查路径是否正确:"<<rtspMain<<endl; goto end; } if (avformat_find_stream_info(pFormatCtx, NULL) < 0) { cout<<"找不到视频流的信息:"<<rtspMain<<endl; goto end; } videoStream = -1; for (int i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStream = i; break; } } if (videoStream == -1) { cout<<"无法播放,找不到视频流:"<<rtspMain<<endl; goto end; } pCodecCtx = avcodec_alloc_context3(NULL); avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar); pCodec = avcodec_find_decoder(pCodecCtx->codec_id); //指向AVCodec的指针.查找解码器 pCodecCtx->bit_rate = 0; // 初始化为0 pCodecCtx->time_base.num = 1; // 下面两行:一秒钟25帧 pCodecCtx->time_base.den = 25; pCodecCtx->frame_number = 1; // 每包一个视频帧 if (pCodec == NULL) { cout<<"无法播放,找不到解码器:"<<rtspMain<<endl; goto end; } if(pCodecCtx->codec_id == AV_CODEC_ID_H264) { av_dict_set(¶ms, "preset", "superfast", 0); av_dict_set(¶ms, "tune", "zerolatency", 0); } else if(pCodecCtx->codec_id == AV_CODEC_ID_H265) { av_dict_set(¶ms, "x265-params", "qp=20", 0); av_dict_set(¶ms, "preset", "ultrafast", 0); av_dict_set(¶ms, "tune", "zero-latency", 0); } // 打开解码器 if (avcodec_open2(pCodecCtx, pCodec, ¶ms) < 0) { cout<<"无法播放,无法打开解码器:"<<rtspMain<<endl; goto end; } pFrame = av_frame_alloc(); pFrameRGB = av_frame_alloc(); // 将解码后的YUV数据转换成RGB32 img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL); numBytes = avpicture_get_size(AV_PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height); out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t)); avpicture_fill((AVPicture *) pFrameRGB, out_buffer, AV_PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height); int y_size = pCodecCtx->width * pCodecCtx->height; packet = (AVPacket *) malloc(sizeof(AVPacket)); // 分配一个packet //av_new_packet(packet, y_size); // 分配packet的数据 av_init_packet(packet); cout<<rtspMain<<endl; while (true) { if (av_read_frame(pFormatCtx, packet) < 0) { break; // 这里认为视频读取完了 } if (packet->stream_index == videoStream) { frames++; //fwrite(packet->data, 1, packet->size, fpSave); // 写数据到文件中 } av_packet_unref(packet); av_free_packet(packet); } end: if(packet) { av_packet_unref(packet); av_free_packet(packet); } if(avdic) av_free(avdic); if(params) av_free(params); sws_freeContext(img_convert_ctx); av_free(out_buffer); av_frame_free(&pFrameRGB); av_frame_free(&pFrame); avcodec_close(pCodecCtx); avcodec_free_context(&pCodecCtx); avformat_free_context(pFormatCtx); }
热门排行