我一直在尝试解码AR的视频流。无人机2.0(http://ardrone2.parrot.com/)暂时没有成功。尽管我一直在密切关注几个例子(我会粘贴链接,但不允许),但我无法避免ffmpeg-libavcodec库中的分段错误。我想,也许我在构建的多线程结构中犯了某种错误,所以我删掉了所有内容,除了连接到无人机所需的最低限度,从无人机中收集一帧,并将其发送到ffmpeg的avcodec_decode_video2()函数。
我编译了ffmpeg源代码(实际上我已经尝试了三个不同的版本!),可以使用ffplay实用程序来显示无人机的视频TCP流。视频明显滞后,但至少我知道无人机并没有让我胡言乱语。
以前有人遇到过这样的问题吗?是什么导致了这个分割错误,我该怎么办?有没有一种方法可以隔离ffmpeg上的测试,这样我就可以确定它是库,而不是我一直在做的事情?
谢谢你抽出时间。
带有我的代码的粘贴框: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,看起来很好。我还是被难住了!
我最终明白了这一点。需要注意的关键是回溯中的特定FFMPEG共享库文件。这不是从库的源版本手动编译的新版本。我没有正确地链接到更新后的文件,而是链接到Ubuntu上的任何默认文件。
修复这个问题需要重新编译FFMPEG,并确保我正确地链接到了正确的共享库。
还有一些其他的记忆问题,但没有什么问题。我解决了一些比较次要的问题,并将结果粘贴在这里:http://pastebin.com/rLEKB5Va
这样可以正确地捕获和显示视频。