利用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. 20145105 《Java程序设计》第1周学习总结

    20145105 <Java程序设计>第1周学习总结 教材学习内容总结 学习了教材的第一章后,我初步了解了Java的发展历程,以及什么是JCP,JSR,JVM.JCP是一个开放性国际组织, ...

  2. RabbitMQ 流程以及一些命令

    流程: producer&Consumer producer指的是消息生产者,consumer消息的消费者. Queue 消息队列,提供了FIFO的处理机制,具有缓存消息的能力.rabbitm ...

  3. UVa 11582 巨大的斐波那契数!(幂取模)

    https://vjudge.net/problem/UVA-11582 题意: 输入两个非负整数a.b和正整数n,你的任务是计算f(a^b)除以n的余数.f[0]=0,f[1]=1,f[i+2]=f ...

  4. python 返回系统名称,系统平台,系统版本

    import platform import os print(os.name) print(platform.system()) print(platform.release())

  5. Android ViewGroup等容器控件的使用

    在Android中,可以自定义类,继承ViewGroup等容器类,以实现自己需要的布局显示.如果你在ViewGroup中增加了控件,却无法显示出 来,那么下面这个例子,就可以用来参考了.(主要是要实现 ...

  6. vue全家桶实现笔记本功能

    一个通过vue实现的练手小项目,数据保存和导出通过node进行处理 成品截图: 安装vue-cli,webpack: cnpm install webpack -g cnpm install vue- ...

  7. java网络编程之Socket编程

    概念 网络编程分为BIO(传统IO).NIO.AIO.Socket编程属于BIO这种传统IO. InetAddress java.net.InetAddress是JAVA中管理IP地址的类,常用 pu ...

  8. 改变VO中的sql

    cuxOptionVO.setFullSqlMode(cuxOptionVO.FULLSQL_MODE_AUGMENTATION); cuxOptionVO.setQuery(null); cuxOp ...

  9. 使用POI设置导出的EXCEL锁定指定的单元格

    注:要锁定单元格需先为此表单设置保护密码,设置之后此表单默认为所有单元格锁定,可使用setLocked(false)为指定单元格设置不锁定. sheet.protectSheet("&quo ...

  10. 007——php字符串中的处理函数(六)

    <?php /** * 一.addslashes() 在预定义字符串前添加反斜杠 * * stripslashes() 把转义字符串前的反斜杠删除 * get_magic_quotes_gpc ...