【问题标题】:AR.Drone 2, ffmpeg avcodec_decode_video2( ) segmentation faultAR.Drone 2, ffmpeg avcodec_decode_video2() 分段错误
【发布时间】:2014-04-05 08:29:44
【问题描述】:

一段时间以来,我一直在尝试从 AR.Drone 2.0 (http://ardrone2.parrot.com/) 解码视频流,但没有成功。尽管我一直在密切关注几个示例(我会粘贴链接,但不允许这样做),但我无法逃避 ffmpeg libavcodec 库中的分段错误。我想也许我在构建的多线程结构中犯了某种错误,所以我删除了除了连接到无人机所需的最低限度之外的所有内容,从无人机收集帧,并将其发送到 ffmpeg avcodec_decode_video2() 函数。

我编译了 ffmpeg 源代码(我实际上尝试了三个不同的版本!)并且可以让 ffplay 实用程序显示无人机的视频 TCP 流。视频明显滞后,但至少我知道无人机没有向我发送完整的胡言乱语。

以前有人遇到过这样的问题吗?什么可能导致此分段错误,我该怎么办?有没有办法隔离 ffmpeg 上的测试,以便我可以确定它是库而不是我一直在做的事情?

感谢您的宝贵时间。

带有我的代码的 pastebin: http://pastebin.com/NYTf0NeT

关于我的 ffmpeg 和编译器设置的一些细节:

ffmpeg version 2.2.git Copyright (c) 2000-2014 the FFmpeg developers
  built on Mar  3 2014 18:05:42 with gcc 4.8 (Ubuntu 4.8.1-2ubuntu1~12.04)
  configuration: 
  libavutil      52. 66.100 / 52. 66.100
  libavcodec     55. 52.102 / 55. 52.102
  libavformat    55. 33.100 / 55. 33.100
  libavdevice    55. 10.100 / 55. 10.100
  libavfilter     4.  2.100 /  4.  2.100
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 18.100 /  0. 18.100

我的代码输出和分段错误的回溯:

*********************** START ***********************



booting...

[h264 @ 0x604040] err{or,}_recognition separate: 1; 1

[h264 @ 0x604040] err{or,}_recognition combined: 1; 1

[h264 @ 0x604040] Unsupported bit depth: 0

asked for 40000 bytes, received packet of 1448 bytes

PaVE synchronized. YIPEEEEEEEEEEEEEEEEEEEEEEEE



---------------------------

Codec : H264

StreamID : 1 

Timestamp : 1031517 ms

Encoded dims : 640 x 368

Display dims : 640 x 360

Header size : 76

Payload size : 17583

Size of SPS inside payload : 14

Size of PPS inside payload : 10

Slices in the frame : 1

Frame Type / Number : IDR-Frame : 31467 : slide 1/1

---------------------------




gathering payload...

asked for 16211 bytes, received packet of 1448 bytes

gathering payload...

asked for 14763 bytes, received packet of 1448 bytes

gathering payload...

asked for 13315 bytes, received packet of 1448 bytes

gathering payload...

asked for 11867 bytes, received packet of 1448 bytes

gathering payload...

asked for 10419 bytes, received packet of 1448 bytes

gathering payload...

asked for 8971 bytes, received packet of 1448 bytes

gathering payload...

asked for 7523 bytes, received packet of 1448 bytes

gathering payload...

asked for 6075 bytes, received packet of 1448 bytes

gathering payload...

asked for 4627 bytes, received packet of 1448 bytes

gathering payload...

asked for 3179 bytes, received packet of 1448 bytes

gathering payload...

asked for 1731 bytes, received packet of 1448 bytes

gathering payload...

asked for 283 bytes, received packet of 283 bytes

payload complete, attempting to decode frame




Program received signal SIGSEGV, Segmentation fault.

0x00007ffff73fccba in ?? () from /usr/lib/x86_64-linux-gnu/libavcodec.so.53

(gdb) bt

#0  0x00007ffff73fccba in ?? () from /usr/lib/x86_64-linux-gnu/libavcodec.so.53

#1  0x00007ffff73fd8f5 in avcodec_decode_video2 () from /usr/lib/x86_64-linux-gnu/libavcodec.so.53

#2  0x000000000040159f in fetch_and_decode(int, parrot_video_encapsulation_t, AVCodecContext*, AVFrame*)

    ()

#3  0x00000000004019c6 in main ()

编辑:我使用 Valgrind 尝试更好地了解 seg 故障,并收到以下信息:

==4730== Invalid read of size 1
==4730==    at 0x5265CBA: ??? (in /usr/lib/x86_64-linux-gnu/libavcodec.so.53.35.0)
==4730==    by 0x52668F4: avcodec_decode_video2 (in /usr/lib/x86_64-linux-gnu/libavcodec.so.53.35.0)
==4730==    by 0x40140E: fetch_and_decode(int, AVCodecContext*, AVFrame*) (main.cpp:176)
==4730==    by 0x401757: main (main.cpp:273)
==4730==  Address 0x280056c46f9 is not stack'd, malloc'd or (recently) free'd
==4730== 
==4730== 
==4730== Process terminating with default action of signal 11 (SIGSEGV)
==4730==  Access not within mapped region at address 0x280056C46F9
==4730==    at 0x5265CBA: ??? (in /usr/lib/x86_64-linux-gnu/libavcodec.so.53.35.0)
==4730==    by 0x52668F4: avcodec_decode_video2 (in /usr/lib/x86_64-linux-gnu/libavcodec.so.53.35.0)
==4730==    by 0x40140E: fetch_and_decode(int, AVCodecContext*, AVFrame*) (main.cpp:176)
==4730==    by 0x401757: main (main.cpp:273)

“无效的读取大小为 1”是指尝试访问数组边界之外的字节。这是否意味着库试图访问我提供的数组范围之外的东西?我已经检查了 AVPkt,这似乎很好。我还是被难住了!

【问题讨论】:

  • 感谢您的回复。您能否详细说明您的意思以及它如何导致段错误?此处对 recv() 的每次调用都是非阻塞的,旨在接收少于请求的数据。每个调用都建立在最后一个调用的基础上,以便最终存储完整的帧。我可以更改此设置,以便我阻塞并休眠,直到我一次收到整个帧有效负载,但它仍然在同一位置出现分段错误。
  • 如果receive 中的第一个fetch_and_decode 调用获得1 个字节怎么办?
  • 是的,我没有考虑到这种可能性,但这与我要问的具体问题有关吗?我可以打印出无人机的“PaVE”特殊标题信息,所以我知道我在第一次通话时至少收到了这么多。我会记住您的评论,以备将来改进。
  • 好的,我会努力解决这个问题。与此同时,鉴于我的代码打印出来,我们可以假设我实际上收到了我的控制台输出说我收到的 1448 个字节吗?
  • 您应该修复该日志消息。您没有收到 1,448 字节的数据包。你只是收到大块的字节。

标签: c++ ffmpeg segmentation-fault video-streaming libavcodec


【解决方案1】:

我最终想通了。需要注意的关键是回溯中特定的 FFMPEG 共享库文件。那不是该库的新的、从源代码手动编译的版本。我没有正确链接到更新的文件,而是链接到 Ubuntu 上的任何默认值。

解决此问题需要重新编译 FFMPEG 并确保我已正确链接到正确的共享库。

还有其他一些内存问题,但没有出现段错误。我熨平了一些较小的东西并将结果粘贴在这里: http://pastebin.com/rLEKB5Va

这会正确捕获并显示视频。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 2013-12-01
    • 2014-01-14
    • 2018-03-27
    相关资源
    最近更新 更多