Всем привет. Есть необходимость поработать с видеопотоком, кодированным по стандарту h264. Решил использовать библиотеки проекта ffmpeg для этой цели. Собрал ffmpeg по мануалу с официального сайта, статические библиотеки (файлы с расширением .a) легли в /home/username/ffmpeg_build/lib. Решил попробовать скомпилировать кусочек кода из вот этой статьи.
Мой учебный вариант:
#include <iostream>
#ifdef __cplusplus
extern "C"
{
void av_register_all(void);
void avcodec_register_all(void);
unsigned avcodec_get_edge_width(void);
const char * avcodec_license(void);
struct AVFormatContext;
struct AVInputFormat;
struct AVDictionary;
int avformat_open_input(AVFormatContext **, const char *, AVInputFormat *, AVDictionary **);
int avformat_find_stream_info(AVFormatContext *, AVDictionary **);
void av_dump_format(AVFormatContext *, int, const char*, int);
}
#endif
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "usage: %s filename" << std::endl;
return 0;
}
av_register_all();
int error;
const char* filename = argv[1];
struct AVFormatContext* format_context = nullptr;
error = avformat_open_input(&format_context, filename, nullptr, nullptr);
if (error < 0)
{
std::cout << "ffmpeg: unable to open " << argv[1] << std::endl;
return -1;
}
error = avformat_find_stream_info(format_context, nullptr);
if (error < 0)
{
std::cout << "ffmpeg: unable to find stream info" << std::endl;
return -1;
}
std::cout << format_context->video_codec->name << std::endl; // маты компилятора
return 0;
}
Компилирую так:
g++ -L /home/username/ffmpeg_build/lib -o prog prog.cpp -lavformat -lavcodec -lavutil -lswresample -lmp3lame -ltheora -lopus /usr/lib/x86_64-linux-gnu/libtheora.a -lvpx -lvorbis -lvorbisenc -lx264 -lva -logg -pthread -std=c++11 -lz
И компилятор матерится:
prog.cpp:42:29: error: invalid use of incomplete type ‘struct AVFormatContext’
std::cout << format_context->video_codec->name << std::endl;
^
prog.cpp:10:9: error: forward declaration of ‘struct AVFormatContext’
struct AVFormatContext;
Как я понимаю, это связано с тем, что я типа обращаюсь к несуществующему с точки зрения компилятора полю структуры format_context
.
В каталоге ffmpeg_build есть, кроме каталога со статическими либами (lib), еще каталог с заголовочными файлами .h, называющийся include. В одном из которых как раз есть определения структур и прочих типов.
Может мне нужно как-то эти заголовочные файлы прикрутить к программе? Но как именно, я не понимаю. Если указывать их в стиле #include <libavformat/avformat.h>
и добавить в g++ опцию -I /home/username/ffmpeg_build/include
, то компилятор уже ругается на повторные объявления функций в секции extern "C"
. Если эти объявления оттуда убрать, то компилятор перестает «видеть» вызываемые функции, не взирая на то, что через -l перечислены статические библиотеки, содержащие эти функции.
В общем, как сделать так, чтобы все закомпилилось, имея на руках нужные хедеры и статические либы? :-)