Я пытался декодировать видео поток с AR.Drone 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 frameProgram 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, чтобы попытаться получить лучшую картину ошибки сегмента, и получил следующее:
==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
Это правильно захватывает и отображает видео.
Других решений пока нет …