繁体   English   中英

丢视频帧

[英]Dropping video frames

我想我的问题很简单。 而且它更多的是数学而不是编码。 我从网络摄像头每秒接收15帧。 但是我必须删除其中一些。 例如,如果客户要求8 fps-我的确放下了第二帧,就可以了。 但是,如果要求12 fps或6 fps,该如何丢弃?

我认为存在一些用于价值分配的通用算法。 非常感谢!

我看到的完成方式(例如,在gstreamer中)是有两个异步循环,一个异步循环从相机接收帧,另一个向客户端发送帧。 后一个循环仅具有从摄像机获取的最近捕获的帧,因此,客户端未“拾取”的帧会在下一个传入帧覆盖时自动删除。

您需要进行一点同步,以确保您不会读取一半捕获的帧,但除此之外,这是一种直接的解决方案,可以使交换的两侧在任一方向上以不同的速度运行。

基本上,您需要对FPS概念进行更深入的研究。

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

现在有了这些信息,就可以将帧速率转换可视化为解码器解码,以在输入FPS时临时显示,并在输出FPS的最终显示屏上显示采样器的采样器。 采样器从解码器正在更新帧的临时显示器采样帧。 此逻辑应确保解码器和采样器之间的同步,以使采样器不会最终对部分更新的帧进行采样。

此逻辑适用于减少或增加FPS。

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

这将确保屏幕更新是统一的,并且垂直同步会显示最新的可用帧。

如果以15 fps的速度通过每2帧丢掉8 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;
      }
  }
}

具有足够大的环形缓冲区以容纳1整秒的视频。

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

在单独的线程中,使用计时器将时间延迟1000 / desirable_fps(对于12fps,为84ms),然后选择最后写入的帧并发送。

您能对这种解决方案说些什么:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM