播放UDP-MJPEG-Stream

时间:2016-05-15 18:00:19

标签: c++ video ffmpeg arm

我正在使用ffmpeg-API读取udp-mjpeg-stream。当我用ARM处理器读取并显示流时,我有两个问题: 1- Applikation太慢,网络摄像头和显示的视频之间存在很大的延迟。 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);

我已经读过,原因可能是ffmpeg-Libs将缓存帧保存在缓存中,但是arm处理器不够快,无法处理它们。在4分钟后,系统崩溃了。

我怎么能解决问题。

一个选项可以是告诉ffmpeg充当帧抓取器,也可以用标志&#34; -re&#34;实时读取帧。如何在c ++源代码中设置此Flag。或者任何人都可以帮助我解决这个问题。

非常感谢

0 个答案:

没有答案