丢弃视频帧

时间:2010-11-19 09:45:49

标签: c++ algorithm frames

我认为,我的问题非常简单。它更多的是数学而不是编码。 我从网络摄像头每秒收到15帧。但我不得不放弃其中一些。例如,如果客户端请求8 fps - 我确实丢弃每秒帧,这没关系。但是如果要求12 fps或6 fps,我应该怎么掉?

我认为价值分配有一些共同的算法。非常感谢!

5 个答案:

答案 0 :(得分:3)

我看到这样做的方式(例如在gstreamer中)是有两个异步循环,一个接收来自摄像机的帧,另一个将帧发送到客户端。后一个循环只有最近捕获的相机可用的帧,因此客户端未“拾取”的帧会在下一个输入帧被覆盖时自动丢弃。

您需要进行一些同步,以确保您不会读取一半捕获的帧,但除此之外,它是一个直接的解决方案,并允许交换的两侧以任何方向以不同的速度运行。

答案 1 :(得分:3)

基本上你需要的是深入了解FPS概念。

X的FPS表示每1 / X秒显示一帧,并且在显示屏上保持1 / X秒可见。通常,在显示设备的每个垂直同步时,在显示器上更新帧。

现在有了这些信息,帧速率转换可以看作解码器解码到输入FPS的临时显示和采样器在输出FPS的最终显示器上显示帧。采样器从临时显示器采样帧,解码器正在更新帧上。该逻辑应该确保解码器和采样器之间的同步,使得采样器不会最终采样部分更新的帧。

这种逻辑适用于降低或增加FPS。

这可以实现为具有同步访问的单个缓冲区。现在让解码器在输入FPS处读取此缓冲区,并从该缓冲区中取样器拾取帧并在输出fps处显示。

这将确保屏幕更新一致,并且在垂直同步时显示最新可用帧。

答案 2 :(得分:1)

通过将每第2帧丢弃8 fps,如果你有15 fps,则会引入错误。

这是一个非常简单的算法,适用于所有情况:

#include <iostream>

double t = 0.0;

const double fps1 = 15.0;
const double fps2 = 12.0;

const double t1 = 1.0 / fps1;
const double t2 = 1.0 / fps2;

// true - drop the frame
// false - do NOT drop the frame
bool NextTick()
{
  t += t1;
  if ( t > t2 )
  {
    t -= t2;
    return false;
  }
  return true;
}

int main()
{
  for ( unsigned int i =0;i<20;++i)
  {
      if ( NextTick() )
      {
          std::cout<<"dropping the frame"<<std::endl;
      }
      else
      {
          std::cout<<"display the frame"<<std::endl;
      }
  }
}

答案 3 :(得分:1)

有一个足够大的环形缓冲区可容纳1秒的视频。

进入此缓冲区写入每个视频帧。更新指向写入的变量。

在一个单独的线程中使用一个计时器来延迟1000 / desired_fps(84ms为12fps)的时间段并选择写入的最后一帧并发送它。

答案 4 :(得分:0)

您对此类解决方案有什么看法:

我有15个静态const字节数组,0和1。 1 - 显示框架,0 - 没有。当我收到帧时,我增加计数器cnt = [0..15]并查看它指向的位置 - 零或一。这就是我决定是否显示或丢帧的方式。

我认为这个解决方案比实现新线程更容易,更快。