利用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. HttpClient-RestTemplate-Feign

    如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求. Java有原生的API可用于发送HTTP请求,即java.net.URL.java.net.URLConn ...

  2. [one day one question] 有没有免费接收短信验证用于注册的软件或者平台?

    问题描述: 想要批量注册撸羊毛,有手机短信验证码验证,这怎么破? 解决方案: 免费的肯定没有的,不过"一条短信收费一毛钱"倒是有一个,本人是亲自试用过,该平台收不到短信验证码不收费 ...

  3. Linux学习笔记之Linux通过yum安装桌面

    Centos系统最小化安装以后,进入默认是命令行模式,所以需要进一步安装桌面. 1,本文使用的是CentOS 7 Minimal版本. 2,启动linux操作系统,进入后没有图形界面,但是有时候还是希 ...

  4. Maven聚合项目在eclipse中显示没有层次

    大部分时间都在用idea做maven的项目,今天用eclipse导入了maven项目,果然不出所料,界面有显示问题,各个模块都堆叠在同一层级,根本看不出父项目与子项目之间的层次关系,见下图: 于是找修 ...

  5. object类之toString方法

    object是所有类的基类 如果没有使用extends关键字指明其基类,则默认基类为object类 public class Person{ ........ } 等价于: public class ...

  6. 20145122 《Java程序设计》第5周学习总结

    教材学习内容总结 1.在Java中,异常分为受检查的异常,与运行时异常. 两者都在异常类层次结构中. 2.受检查的异常(checked exceptions),其必须被 try{}catch语句块所捕 ...

  7. kotlin 学习感受

    目录 kotlin 学习感受 特点 优点 屎一样的缺点 总结 kotlin 学习感受 直白的说..很不好,像屎一样,本来对此抱有很大的期望和好感度,但经过一整天的学习,完全失望了,这门语言中间有各种的 ...

  8. UVA 257 Palinwords(hash)题解

    思路:给你字符串,如果他包含至少两个长度大于等于3的回文,并且这些回文不能嵌套(例如aaa嵌套在aaaa,waw嵌套在awawa),如果这个字符串这么牛逼的话,就输出他. 思路:拿到字符串先正序has ...

  9. springboot属性类自动加载配置文件中的值

    springboot属性类自动加载配置文件中的值,如Person类加载在yml中配置的name,age等属性值,可以通过如下步骤获取: 类上添加@ConfigurationProperties注解,p ...

  10. 【日志】修改redis日志路径

    redis默认不记录log文件,需要在Redis.conf文件,找到loglevel notice,在其后的logfile "",双引号中,写redis的路径"/redi ...