FFMPEG如何有效地解码视频框架

ffmpeg how to efficiently decode the video frame?

本文关键字:视频 框架 解码 有效地 FFMPEG      更新时间:2023-10-16

这是我用来解码工作线程中RTSP流的代码:

while(1)
   {
      // Read a frame
      if(av_read_frame(pFormatCtx, &packet)<0)
         break;                             // Frame read failed (e.g. end of stream)
      if(packet.stream_index==videoStream)
      {
         // Is this a packet from the video stream -> decode video frame
         int frameFinished;
         avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);
         // Did we get a video frame?
         if (frameFinished)
         {
             if (LastFrameOk == false)
             {
                 LastFrameOk = true;
             }
             // Convert the image format (init the context the first time)
             int w = pCodecCtx->width;
             int h = pCodecCtx->height;
             img_convert_ctx = ffmpeg::sws_getCachedContext(img_convert_ctx, w, h, pCodecCtx->pix_fmt, w, h, ffmpeg::PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
             if (img_convert_ctx == NULL)
             {
                 printf("Cannot initialize the conversion context!n");
                 return false;
             }
             ffmpeg::sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
             // Convert the frame to QImage
             LastFrame = QImage(w, h, QImage::Format_RGB888);
             for (int y = 0; y < h; y++)
                 memcpy(LastFrame.scanLine(y), pFrameRGB->data[0] + y*pFrameRGB->linesize[0], w * 3);
             LastFrameOk = true;

         }  // frameFinished
      }  // stream_index==videoStream
      av_free_packet(&packet);      // Free the packet that was allocated by av_read_frame
   }

我遵循FFMPEG的教程,并使用了一段时间来读取数据包并解码视频。但是,是否有更有效的方法来执行此操作,例如收到数据包时事件触发的功能?

我还没有看到任何事件驱动的读取帧的方法,但是读取RTSP流的目的是什么?但是我可以提出一些提高性能的建议。首先,您可以在循环中添加非常短的睡眠(例如睡眠(1);)。在您的程序中,如果您的目的是:

  1. 向用户显示图像:不要使用转换为RGB,解码后,所得的帧为YUV420P格式,可以使用GPU直接向用户显示,而无需使用任何CPU。几乎所有图形卡都支持YUV420P(或YV12)格式。转换为RGB是一个高度消耗CPU的操作,尤其是对于大图像。

  2. 记录(保存)到磁盘:我想记录流以稍后播放,无需解码帧。您可以使用OpenRTSP直接记录到磁盘,而无需使用任何CPU。

  3. 处理实时图像:您可能会找到以YUV420P格式而不是RGB处理的替代算法。YUV420P中的Y平面实际上是彩色RGB图像的灰度版本。