Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 播放UDP MJPEG流时ffmpeg内存增加_C++_Video_Ffmpeg_Arm - Fatal编程技术网

C++ 播放UDP MJPEG流时ffmpeg内存增加

C++ 播放UDP MJPEG流时ffmpeg内存增加,c++,video,ffmpeg,arm,C++,Video,Ffmpeg,Arm,我正在用ffmpeg API读取udp mjpeg流。当我使用ARM处理器读取和显示流时,我有两个问题: 1-应用速度太慢,网络摄像头和显示的视频之间存在较大延迟。 2-每次调用函数av_read_frame()时,内存使用量都会增加 源代码 const char *cam1_url = "udp://192.168.1.1:1234"; AVCodec *pCodec; AVFrame *pFrame, *pFrameRGB; AVCodecContext *pCodecCon; AV

我正在用ffmpeg API读取udp mjpeg流。当我使用ARM处理器读取和显示流时,我有两个问题: 1-应用速度太慢,网络摄像头和显示的视频之间存在较大延迟。 2-每次调用函数av_read_frame()时,内存使用量都会增加

源代码

const char *cam1_url = "udp://192.168.1.1:1234";
 AVCodec *pCodec;
 AVFrame *pFrame, *pFrameRGB;
 AVCodecContext *pCodecCon;
 AVDictionary *pUdpStreamOptions = NULL;
 AVInputFormat *pMjpegFormat = av_find_input_format("mjpeg");
 av_dict_set(&pUdpStreamOptions, "fifo_size", "5000000", 0);
 av_register_all();
 avdevice_register_all();
 avcodec_register_all();
 avformat_network_init();
 AVFormatContext *pFormatCont = avformat_alloc_context();
 if(avformat_open_input(&pFormatCont,cam1_url,pMjpegFormat,&pUdpStreamOptions) < 0)
 {
   cout << "!! Error !! - avformat_open_input(): failed to open input URL" << endl;
 }

 if(avformat_find_stream_info(pFormatCont,NULL) < 0)
 {
   cout << "!! Error !! - avformat_find_stream_info(), Failed to retrieve stream info" << endl;
 }

 av_dump_format(pFormatCont, 0, cam1_url, 0);

 int videoStream;
 for(int i=0; i< pFormatCont->nb_streams; i++)
 {
    if(pFormatCont->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
    {
        videoStream=i;
        cout << " videoStream = " << videoStream << endl;
    }
 }
 pCodecCon = pFormatCont->streams[videoStream]->codec;
 pCodec = avcodec_find_decoder(pCodecCon->codec_id);
 if(NULL == pCodec)
 {
   cout << "couldnt find codec" << endl;
   return EXIT_FAILURE;
 }
 if(avcodec_open2(pCodecCon,pCodec,NULL) < 0)
 {
    cout << "!! Error !! - in avcodec_open2()" << endl;
    return EXIT_FAILURE;
 }
 uint8_t *frameBuffer;
 int numRxBytes = 0;
 AVPixelFormat pFormat =AV_PIX_FMT_BGR24;
 int width_rgb = (int)((float)pCodecCon->width);
 int height_rgb = (int)((float)pCodecCon->height);
 numRxBytes = avpicture_get_size(pFormat,width_rgb,height_rgb);
 frameBuffer = (uint8_t *) av_malloc(numRxBytes*sizeof(uint8_t));
 avpicture_fill((AVPicture *) pFrameRGB, frameBuffer, pFormat,width_rgb,height_rgb);
  AVPacket rx_pkt; // received packet
 int frameFinished = 0;
 struct SwsContext *imgConvertCtx;
 av_init_packet(&rx_pkt);
 while(av_read_frame(pFormatCont, &rx_pkt) >= 0)
 {
   if(rx_pkt.stream_index == videoStream)
   {  
      av_frame_free(&pFrame);
      pFrame = av_frame_alloc();

      av_frame_free(&pFrameRGB);
      pFrameRGB = av_frame_alloc();

      avcodec_decode_video2(pCodecCon, pFrame, &frameFinished,&rx_pkt);

      if(frameFinished)
      {

        imgConvertCtx = sws_getCachedContext(NULL, pFrame->width,pFrame->height, AV_PIX_FMT_YUVJ420P,width_rgb,height_rgb,AV_PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL,NULL);

        sws_scale(imgConvertCtx, ((AVPicture*)pFrame)->data, ((AVPicture*)pFrame)->linesize, 0, pCodecCon->height, ((AVPicture *)pFrameRGB)->data, ((AVPicture *)pFrameRGB)->linesize);

        av_frame_unref(pFrame);
        av_frame_unref(pFrameRGB);
      }
   }
   av_free_packet(&rx_pkt);
   av_packet_unref(&rx_pkt);
 }
 //cvDestroyWindow("Cam1Video");
 av_free_packet(&rx_pkt);
 avcodec_close(pCodecCon);
 av_free(pFrame);
 av_free(pFrameRGB);
 avformat_close_input(&pFormatCont);
const char*cam1\u url=”udp://192.168.1.1:1234";
AVCodec*pCodec;
AVFrame*pFrame,*pFrameRGB;
AVCodecContext*pCodecCon;
AVDictionary*pUdpStreamOptions=NULL;
AVInputFormat*pMjpegFormat=av_查找_输入_格式(“mjpeg”);
av_dict_集(&pudpstream选项,“fifo大小”,“5000000”,0);
av_寄存器_all();
avdevice_register_all();
avcodec_寄存器_all();
avformat_network_init();
AVFormatContext*pFormatCont=avformat_alloc_context();
if(avformat_open_输入(&P格式、cam1_url、pMjpegFormat和PUDPStream选项)<0)
{
cout codec_type==AVMEDIA_type_VIDEO)
{
视频流=i;
cout编解码器(u id);
if(NULL==pCodec)
{
cout width,pFrame->height,AV_PIX_FMT_YUVJ420P,width_rgb,height_rgb,AV_PIX_FMT_BGR24,SWS_双三次,NULL,NULL,NULL);
sws_比例(imgConvertCtx,((AVPicture*)pFrame)->数据,((AVPicture*)pFrame)->线宽,0,pCodecCon->高度,((AVPicture*)pFrameRGB)->数据,((AVPicture*)pFrameRGB)->线宽;
av_帧_unref(pFrame);
av帧unref(pFrameRGB);
}
}
av_免费_包(&rx_包);
av_数据包unref(和rx_数据包);
}
//视频窗口(“Cam1Video”);
av_免费_包(&rx_包);
avcodec_close(pCodecCon);
无AVU(pFrame);
无AVU(pFrameRGB);
avformat\u close\u输入(&P格式);
我读过,原因可能是ffmpeg LIB将输入帧保存在缓存中,但arm处理器的处理速度不够快。大约4分钟后,系统崩溃

我怎样才能解决这个问题

一个选项是告诉ffmpeg充当帧抓取器,也可以使用标志“-re”实时读取帧。如何在C++源代码中设置此标志。或者谁能帮我解决这个问题


非常感谢

您在哪台机器上运行此功能(作为比较,我面前有一个“ARM处理器”,它是一个具有1KB RAM的微型微控制器;我还有一个正在工作的机器,它是一个具有128GB的多GHz多核服务器类机箱),以及使用哪种操作系统?看到循环中的alloc/free,我想到了堆碎片——压缩/未压缩帧有多大?我有一个imx6双臂处理器(飞思卡尔的Sabre automotive)和2GB Ram。操作系统是Linux Yocto Poky,内核为3.14。我对ubuntu也有同样的问题。我在没有alloc/free的情况下尝试了它,也只是使用av_free_数据包(&rx_pkt)的函数av_read_frame()。同样的问题。在ubuntu主机系统上,它工作得更好,但在嵌入式系统上却不行。我收到的是1024x768 jpeg FramesOK,因此我们处于“真正的计算机”领域,而不是资源受限的领域——这排除了一整类潜在的问题。您是否在Valgrind下运行它以检查是否有任何明显的泄漏?在真正的计算机上,内存增加到930 MB,然后不再增加。在嵌入式pc上,当我使用两个摄像头时,这太多了。我认为刷新ffmpeg的内部现金(在AVFormatContext中)可以解决这个问题。当我使用avformat\u close\u输入(&P格式)时,内存被释放。是否有任何方法可以查找最后一帧并删除所有其他帧或最小化内存使用?。我读过一些关于这个案例的文章,我认为没有内存泄漏。ffmpeg使用了太多的内存,这很有趣:你在哪台机器上运行它(作为比较,我面前有一个“ARM处理器”,它是一个1KB内存的微型微控制器;我还有一个正在工作的,它是一个128GB的多GHz多核服务器类机箱),以及使用什么类型的操作系统?看到循环中的alloc/free,我想到了堆碎片——压缩/未压缩帧有多大?我有一个imx6双臂处理器(飞思卡尔的Sabre automotive)和2GB Ram。操作系统是Linux Yocto Poky,内核为3.14。我对ubuntu也有同样的问题。我在没有alloc/free的情况下尝试了它,也只是使用av_free_数据包(&rx_pkt)的函数av_read_frame()。同样的问题。在ubuntu主机系统上,它工作得更好,但在嵌入式系统上却不行。我收到的是1024x768 jpeg FramesOK,因此我们处于“真正的计算机”领域,而不是资源受限的领域——这排除了一整类潜在的问题。您是否在Valgrind下运行它以检查是否有任何明显的泄漏?在真正的计算机上,内存增加到930 MB,然后不再增加。在嵌入式pc上,当我使用两个摄像头时,这太多了。我认为刷新ffmpeg的内部现金(在AVFormatContext中)可以解决这个问题。当我使用avformat\u close\u输入(&P格式)时,内存被释放。是否有任何方法可以查找最后一帧并删除所有其他帧或最小化内存使用?。我读过一些关于这个案例的文章,我认为没有内存泄漏。ffmpeg使用了太多有趣的内存: