利用ffmpeg进行视频采集时经常出现“V4L2_BUF_FLAG_ERROR”的错误,并不再进行下帧的采集。通过借鉴下面的方法,对ffmpeg3.0.7版本进行补丁,能解决此类问题。

当某帧出错后,能继续进行后续的采集。

Submitter Oliver Collyer
Date Sept. 10, 2016, 10:21 a.m.
Message ID <E8CA02F7-7F3C-4D0A-BAFC-24CAB8A57AEB@mac.com>
Download mbox | patch
Permalink /patch/9324933/
State New
Headers show
 

Comments

Oliver Collyer - Sept. 10, 2016, 10:21 a.m.
>> I have written a patch for FFmpeg that deals with the problem for both
>> devices so it’s not really an issue for me anymore, but I’m not sure
>> if the patch will get accepted in their master git as it’s a little
>> messy.
>
> Please post this patch here! Here you go, Andrey. This patch basically makes it throw away corrupted buffers and then also the first 8 buffers after the last corrupted buffer. It’s not sufficient just to throw away the corrupted buffers as I have noticed that the first few legitimate buffers appear at slightly irregular time intervals leading to FFmpeg spewing out a bunch of warnings for the duration of the capture. In my tests around 3 buffers have to be ignored but I’ve fixed it at 8 to be on the safe side. It’s a bit ugly though, to be honest, I don’t know how the number of buffers that need to be ignored would depend on the framerate, video size etc, but it works for my 1080i test. With this patch, you get some warnings at the start, for both devices, as it encounters (and recovers from) the corrupted buffers but after that the captures work just fine. --
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Andrey Utkin - Sept. 10, 2016, 10:58 a.m.
On Sat, Sep 10, 2016 at 01:21:10PM +0300, Oliver Collyer wrote:
>
> >> I have written a patch for FFmpeg that deals with the problem for both
> >> devices so it’s not really an issue for me anymore, but I’m not sure
> >> if the patch will get accepted in their master git as it’s a little
> >> messy.
> >
> > Please post this patch here!
>
> Here you go, Andrey. This patch basically makes it throw away corrupted buffers and then also the first 8 buffers after the last corrupted buffer. Thanks a lot for sharing. > It’s not sufficient just to throw away the corrupted buffers as I have noticed that the first few legitimate buffers appear at slightly irregular time intervals leading to FFmpeg spewing out a bunch of warnings for the duration of the capture. In my tests around 3 buffers have to be ignored but I’ve fixed it at 8 to be on the safe side. It’s a bit ugly though, to be honest, I don’t know how the number of buffers that need to be ignored would depend on the framerate, video size etc, but it works for my 1080i test.
>
> With this patch, you get some warnings at the start, for both devices, as it encounters (and recovers from) the corrupted buffers but after that the captures work just fine.
>
>
> diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
> old mode 100644
> new mode 100755
> index ddf331d..7b4a826
> --- a/libavdevice/v4l2.c
> +++ b/libavdevice/v4l2.c
> @@ -79,6 +79,7 @@ struct video_data {
>
> int buffers;
> volatile int buffers_queued;
> + int buffers_ignore;
> void **buf_start;
> unsigned int *buf_len;
> char *standard;
> @@ -519,7 +520,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
> av_log(ctx, AV_LOG_WARNING,
> "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
> buf.bytesused);
> - buf.bytesused = 0;
> + s->buffers_ignore = 8;
> + enqueue_buffer(s, &buf);
> + return FFERROR_REDO;
> } else
> #endif
> {
> @@ -529,14 +532,28 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
> s->frame_size = buf.bytesused;
>
> if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
> - av_log(ctx, AV_LOG_ERROR,
> + av_log(ctx, AV_LOG_WARNING,
> "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
> buf.bytesused, s->frame_size, buf.flags);
> + s->buffers_ignore = 8;
> enqueue_buffer(s, &buf);
> - return AVERROR_INVALIDDATA;
> + return FFERROR_REDO;
> }
> } These two chunks look like legit resilience measure, and maybe could be
even added to upstream ffmpeg, maybe for non-default mode. >
> +
> + /* if we just encounted some corrupted buffers then we ignore the next few
> + * legitimate buffers because they can arrive at irregular intervals, causing
> + * the timestamps of the input and output streams to be out-of-sync and FFmpeg
> + * to continually emit warnings. */
> + if (s->buffers_ignore) {
> + av_log(ctx, AV_LOG_WARNING,
> + "Ignoring dequeued v4l2 buffer due to earlier corruption.\n");
> + s->buffers_ignore --;
> + enqueue_buffer(s, &buf);
> + return FFERROR_REDO;
> + } Not clear exactly happens here so that such workaround is needed... Congratulations, you've ended up with a workaround which works for you,
for such a mysterious issue :) I still don't know what exactly causes this error condition on original
layer (I suppose that's some "panic" in the peripheral device), but I
guess that due to rarity of this condition, V4L2 code developers (in
both kernel and ffmpeg) just haven't had an opportunity to debug such
situations and handled this error condition formally, without experience
of running into it, and knowledge why it happens and how it could be
handled in most resilient way. (Maybe this should NOT be handled in
resilient way in theory, but still works for your case.) So you had to
pave your own way here. Maybe comments from senior V4L2 developers shed more lights on this.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Oliver Collyer - Sept. 10, 2016, 11:11 a.m.
>
> These two chunks look like legit resilience measure, and maybe could be
> even added to upstream ffmpeg, maybe for non-default mode.
> Well I’ve posted it to the FFmpeg dev list for feedback, so we will see. Non-default mode - yes maybe it needs to be optional. And/or only have an effect at the start of the capture; I am concerned that in some situation where a capture momentarily loses signal and delivers a corrupted buffer that my patch would then actually do more than an end user would require by ignoring subsequent buffers and maybe turning it into a bigger issue. >>
>> +
>> + /* if we just encounted some corrupted buffers then we ignore the next few
>> + * legitimate buffers because they can arrive at irregular intervals, causing
>> + * the timestamps of the input and output streams to be out-of-sync and FFmpeg
>> + * to continually emit warnings. */
>> + if (s->buffers_ignore) {
>> + av_log(ctx, AV_LOG_WARNING,
>> + "Ignoring dequeued v4l2 buffer due to earlier corruption.\n");
>> + s->buffers_ignore --;
>> + enqueue_buffer(s, &buf);
>> + return FFERROR_REDO;
>> + }
>
> Not clear exactly happens here so that such workaround is needed…
> Yes, this is the ugly bit. I had it outputting the timestamps of all the buffers received and it clearly showed that 2-3 of them are stamped closer together. It’s as if something is taking extra time to recover from whatever was causing the original problem. --
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
old mode 100644
new mode 100755
index ddf331d..7b4a826
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -79,6 +79,7 @@ struct video_data { int buffers;
volatile int buffers_queued;
+ int buffers_ignore;
void **buf_start;
unsigned int *buf_len;
char *standard;
@@ -519,7 +520,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
av_log(ctx, AV_LOG_WARNING,
"Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
buf.bytesused);
- buf.bytesused = 0;
+ s->buffers_ignore = 8;
+ enqueue_buffer(s, &buf);
+ return FFERROR_REDO;
} else
#endif
{
@@ -529,14 +532,28 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
s->frame_size = buf.bytesused; if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
- av_log(ctx, AV_LOG_ERROR,
+ av_log(ctx, AV_LOG_WARNING,
"Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
buf.bytesused, s->frame_size, buf.flags);
+ s->buffers_ignore = 8;
enqueue_buffer(s, &buf);
- return AVERROR_INVALIDDATA;
+ return FFERROR_REDO;
}
} +
+ /* if we just encounted some corrupted buffers then we ignore the next few
+ * legitimate buffers because they can arrive at irregular intervals, causing
+ * the timestamps of the input and output streams to be out-of-sync and FFmpeg
+ * to continually emit warnings. */
+ if (s->buffers_ignore) {
+ av_log(ctx, AV_LOG_WARNING,
+ "Ignoring dequeued v4l2 buffer due to earlier corruption.\n");
+ s->buffers_ignore --;
+ enqueue_buffer(s, &buf);
+ return FFERROR_REDO;
+ }
+
/* Image is at s->buff_start[buf.index] */
if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
/* when we start getting low on queued buffers, fall back on copying data */
@@ -608,6 +625,7 @@ static int mmap_start(AVFormatContext *ctx)
}
}
s->buffers_queued = s->buffers;
+ s->buffers_ignore = 0; type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {

https://patchwork.kernel.org/patch/9324933/

 

ffmpeg V4L2_BUF_FLAG_ERROR的解决方法的更多相关文章

  1. [转载] FFmpeg 错误 C4996: ‘avcodec_alloc_frame’: 被声明为已否决 解决方法

    在 Visual Studio 2013 下编写 FFmpeg 程序时出错,错误如下: 出错代码如下: 解决方法为:将 avcodec_alloc_frame() 替换为 av_frame_alloc ...

  2. (转)学习ffmpeg官方示例transcoding.c遇到的问题和解决方法

    转自:https://blog.csdn.net/w_z_z_1991/article/details/53002416 Top 最近学习ffmpeg,官网提供的示例代码transcoding.c演示 ...

  3. ffmpeg编解码视频导致噪声增大的一种解决方法

    一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...

  4. ffmpeg按比例缩放--"width / height not divisible by 2" 解决方法

    最近在处理视频的时候,有这么一个需求 如果视频的分辨率宽度大于960的话,就把宽度设为960,而高度按其比例进行缩放 如果视频的分辨率高度大于540的话,就把高度设为540,而宽度按其比例进行缩放 之 ...

  5. MinGW平台 openjpeg-2.1.0 静态编译后未定义引用的解决方法

    undefined reference to __imp_opj_xxx keyword: ffmpeg,openjpeg,OPJ_EXPORTS,OPJ_STATIC,opj_version,__i ...

  6. VS2015编译FFMPEG,修改FFmpeg缓冲区大小解决实时流解码丢包问题,FFmpeg错误rtsp流地址卡死的问题,设置超时

    之前尝试过很多网上利用Windows编译FFmpeg的文章,都没有办法编译X64位的FFmpeg,有些教程中有专门提到编译64位的FFmpeg需要下载mingw-w64-install,但是编译的过程 ...

  7. (大概是最全的解决方法)使用bandicam录制视频导入pr后音画不同步问题

    遇到这个问题大部分都是使用了VBR来录制视频导致的, 搜集了各种能够找到的方法,并没有每个尝试过 一 Handbrake转码 Audio out of sync AFTER importing 解决方 ...

  8. IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法

    直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...

  9. MVVM框架从WPF移植到UWP遇到的问题和解决方法

    MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...

随机推荐

  1. 无界面Ubuntu服务器搭建selenium+chromedriver+VNC运行环境

    搭建背景 有时候我们需要把基于selenium的爬虫放到服务器上跑的时候,就需要这样一套运行环境,其中VNC是虚拟的显示模式,用于排查定位线上问题以及实时运行情况. 搭建流程 安装虚拟输出设备:sud ...

  2. 20145325张梓靖 《Java程序设计》第5周学习总结

    20145325张梓靖 <Java程序设计>第5周学习总结 教材学习内容总结 try catch Java中所有错误都会被打包为对象.如果某个方法声明会抛出Throwable或子类实例,只 ...

  3. lxml.etree去除子节点

    去除etree中的某个子节点有两种方法: 1.parentnode.remove(node) 2.etree.strip_elements(html, 'element_name', with_tag ...

  4. Tinkoff Challenge - Elimination Round B. Igor and his way to work(dfs+优化)

    http://codeforces.com/contest/793/problem/B 题意:一个地图,有起点和终点还有障碍点,求从起点出发到达终点,经过的路径上转弯次数是否能不超过2. 思路: 直接 ...

  5. C++网络通信字节序问题

    htonl(), ntohl(), htons(), ntohs() 函数 在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺序的问题.这是就可能用到htons(), ntohl(), n ...

  6. python 浮点数取绝对值

    import math print(math.fabs(-2.1)) print(math.fabs(-0.0)) print(math.fabs(10.1)) print(math.fabs(0.0 ...

  7. Ubuntu终端常用的快捷键,光标移动到开始位置

    光标操作,实用 Ctrl+a 光标移动到开始位置 Ctrl+e 光标移动到最末尾 删除 Ctrl+k 删除此处至末尾的所有内容 Ctrl+u 删除此处至开始的所有内容 删除单个 Ctrl+d 删除当前 ...

  8. K-Means & Sequential Leader Clustering

    2017-12-31 19:08:37 k-平均算法源于信号处理中的一种向量量化方法,现在则更多地作为一种聚类分析方法流行于数据挖掘领域.k-means的目的是:把样本划分到k个聚类中,使得每个点都属 ...

  9. Tornado源码分析 --- Etag实现

    Etag(URL的Entity Tag): 对于具体Etag是什么,请求流程,实现原理,这里不进行介绍,可以参考下面链接: http://www.oschina.net/question/234345 ...

  10. windows下的IO模型之事件选择(WSAEventSelect)模型

    异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型.事件选择模型和异步选择模型最主要的 ...