ffmpeg V4L2_BUF_FLAG_ERROR的解决方法

news/2024/7/10 21:22:43 标签: ffmpeg, git

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

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

SubmitterOliver Collyer
DateSept. 10, 2016, 10:21 a.m.
Message ID<E8CA02F7-7F3C-4D0A-BAFC-24CAB8A57AEB@mac.com>
Downloadmbox | patch
Permalink/patch/9324933/
StateNew
Headersshow
 

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/

 

转载于:https://www.cnblogs.com/xihong2014/p/6800993.html


http://www.niftyadmin.cn/n/532961.html

相关文章

2019年3月c语言二级成绩,2019年3月计算机二级C语言考试选择题强化练习013

2019年3月计算机二级C语言考试选择题强化练习013浏览次数&#xff1a; 时间&#xff1a;2019/03/20(1)下列关于栈叙述正确的是(  )。A.栈顶元素最先能被删除B.栈顶元素最后才能被删除C.栈底元素永远不能被删除D.栈底元素最先被删除答案&#xff1a;A(2)下列叙述中正确的是…

Unity3D使用经验总结 优点篇

09年还在和其它小伙伴开发引擎的时候&#xff0c;Unity3D就初露头角。 当时就对这种基于组件式的设计结构很不 理解。 觉得拆分过于细致&#xff0c;同时影响效率。 而时至今日&#xff0c;UNITY3D已经成为了众多团队的首选3D引擎。 并且&#xff0c;随着Unity3D 4.3的发布&…

单片机c语言期末考试题及答案,单片机C语言期末考试题..

《单片机C语言期末考试题..》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《单片机C语言期末考试题..(12页珍藏版)》请在人人文库网上搜索。1、单片机C语言期末考试题(A)一、单项选择题&#xff1a;40 分1、MCS-51系列的单片机中片内RAM的字节大小可能的是( )A、128M…

查找子串位置

挪用jdk1.7中String类的indexof方法&#xff1a; public int indexOf(String source, String target) {char[] ssource.toCharArray();char[] ttarget.toCharArray();int sCounts.length;int tCountt.length;char first t[0];int max sCount - tCount;for (int i 0; i < …

TDD在Unity3D游戏项目开发中的实践

关于TDD测试驱动开发的文章已经有很多了&#xff0c;但是在游戏开发尤其是使用Unity3D开发游戏时&#xff0c;却听不 到特别多关于TDD的声音。那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使用U3D 5.3 .X之后版本已经集成的单元测试模块Editor Test Runner。 0x01 你…

smartbi v7 Linux,配置Smartbi

2、系统配置在安装部署完Smartbi后&#xff0c;需要进行一些初始配置。具体步骤如下&#xff1a;2.1 Config登录界面服务器成功部署后&#xff0c;启动应用服务器。如果是首次访问Config界面&#xff0c;需要设置管理员账号、密码&#xff0c;以便下次登录配置界面时验证&#…

C# 获取北京时间 (根据纪元时间(1970/1/1)转换为DateTime)

根据纪元时间(1970/1/1)转换为DateTime WebClient wc new WebClient(); s wc.DownloadString("http://api.time.3023.com/time"); long t Newtonsoft.Json.JsonConvert.DeserializeObject(s).stime; DateTime dt197011 TimeZone.CurrentTimeZone.ToLocalTime(new D…

性能测试 -- 内存过高, 如何定位问题?

1. 查资源内存 查纹理格式 → Android最好是ETC2格式, IOS最好是PVRTC, Windows PC最好是DXT查纹理尺寸 → 1024x1024尺寸的纹理, 占用内存是512x512的4倍查Mipmap → 开启Mipmap会将纹理内存提升1.33倍, 3D场景模型和角色可以开启, 但是UI纹理不建议开启查【Read/Write Enable…