ошибка: «avcodec_send_packet» не был объявлен в этой области

Следующий фрагмент кода на основе ffmpeg создается и работает в Windows VC2012, VC20155, VC2017.

С gcc в Ubuntu LTS 16.04 это вызывает у меня проблемы, в частности, он не распознает avcodec_send_packet, avcodec_receive_frame и struct AVCodecParameters и, возможно, больше функций и структур, которые я в настоящее время не использую.

ошибка: «AVCodecParameters» не был объявлен в этой области ошибка: «avcodec_send_packet» не был объявлен в этой области ошибка: «avcodec_receive_frame» не был объявлен в этой области

Фрагмент кода:

// the includes are actually in a precompiled header, included in cmake
extern "C" {

#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavfilter/avfilter.h>
#include <libpostproc/postprocess.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>   
#include <libavutil/avassert.h>
#include <libavutil/avstring.h>
#include <libavutil/bprint.h>
#include <libavutil/display.h>
#include <libavutil/mathematics.h>  
#include <libavutil/imgutils.h>
//#include <libavutil/libm.h>
#include <libavutil/parseutils.h>
#include <libavutil/pixdesc.h>
#include <libavutil/eval.h>
#include <libavutil/dict.h>
#include <libavutil/opt.h>
#include <libavutil/cpu.h>
#include <libavutil/ffversion.h>
#include <libavutil/version.h>

}

//
... 
{
    if (av_read_frame(m_FormatContext, m_Packet) < 0) {
        av_packet_unref(m_Packet);
        m_AllPacketsSent = true;
    } else {
        if (m_Packet->stream_index == m_StreamIndex) {                  
            avcodec_send_packet(m_CodecContext, m_Packet);
        }
    }
}
...

Я прочитал историю ffmpeg и узнал, что в системах на основе Debian в какой-то момент они следовали ветвь libavutil, когда это произошло, а затем недавно некоторые платформы снова переключились на ветку ffmpeg из-за того, что ffmpeg гораздо активнее поддерживался с точки зрения исправлений, функций и поддерживать. В результате некоторые интерфейсы, возможно, были сломаны.

Я видел исправления git в библиотеке под названием mediatombs, которые, похоже, столкнулись с теми же, если не очень похожими проблемами с codecpar (которые у меня изначально также были и исправлены таким же образом):

https://github.com/gerbera/gerbera/issues/52

https://github.com/gerbera/gerbera/commit/32efd463f138557c54535225d84136df95bab3dd#diff-af3b638bc2a3e6c650974192a53c7291

Здесь фиксация, кажется, решает их конкретную проблему, обертывая поле codecpar, которое переименовывается, обратно в кодек, который я также применил и работает.

Интересно, знает ли кто-нибудь, какие функции можно использовать для ошибок, указанных выше, поскольку на самом деле эти функции сами заменяют устаревшие функции в соответствии с комментариями заголовка ffmpeg avcodec.h. (https://www.ffmpeg.org/doxygen/trunk/avcodec_8h_source.html). Надеюсь, это не означает, что мне придется вернуться к функциям типа avcodec_encode_video2()?

Обновление:

Для справки: похоже, он также появился здесь: https://github.com/Motion-Project/motion/issues/338. Проблема, кажется, решена, если вы можете перестроить свой стек ffmpeg.

Обновление:

Чтобы устранить смешение версий API, я удалил все ссылки на ffmpeg и перестроил ffmpeg из исходников. Это, кажется, продвигает вещи дальше в правильном направлении; У меня правильно компилируется исходный код, но что-то не так с тем, как я связываю вещи вместе.

Кроме того, я использую CMake для настройки своих make-файлов и использую find_package для некоторых зависимостей и рукописный материал find_path/find_library для всего остального. Я видел, как другие люди жалуются на следующую проблему со ссылками и массу ответов по конкретным случаям, но ни один из них на самом деле не пролил свет на то, в чем заключается настоящая проблема. Моя установленная версия ALSA для Ubuntu — 1.1.xx, но я все еще получаю жалобы на версию 0.9, которую я якобы связываю. Кто-нибудь знает, что с этим не так?

Кроме того, мой libasound.so символически связан с libasound.so.2.0.0, если это что-то проясняет. (Надеюсь, что путь с двойной косой чертой в конце тоже правильный).

/usr/bin/ld: /usr/lib/ffmpeg/libavdevice.a(alsa.o): undefined reference to symbol 'snd_pcm_hw_params_any@@ALSA_0.9' //usr/lib/x86_64-linux-gnu/libasound.so.2: 

person StarShine    schedule 26.04.2018    source источник
comment
У вас есть разрешение на создание собственных библиотек ffmpeg вместо libavcoded-dev apt? Я всегда строю его сам на Ubuntu.   -  person halfelf    schedule 26.04.2018
comment
На самом деле да, но я немного сомневаюсь и хочу еще больше не смешивать вещи.   -  person StarShine    schedule 26.04.2018
comment
Это похоже на разницу между библиотеками, поскольку я думаю, что эти функции заменили старые из тега ffmpeg 3.3. вперед. Вы должны иметь возможность перечислить версию libavcodec и сравнить. Вы можете получить версии из этих констант: ffmpeg.org/doxygen/3.3/libavcodec_2version_8h.html   -  person Andrew    schedule 27.04.2018
comment
Вау, спасибо, да, это начинает иметь смысл, я сравню и проверю, не находится ли моя установка в каком-то подвешенном состоянии.   -  person StarShine    schedule 27.04.2018


Ответы (1)


Таким образом, проблема действительно заключалась в смешении версий исходных кодов avcodec и ffmpeg, где я мог ссылаться на правильную библиотеку, но скомпилировал ее с неправильным исходным пакетом. Я узнал об этом, следуя совету Эндрю проверить версии API в заголовке.

Решение, как предложил halfelf, состояло в том, чтобы удалить и ffmpeg, и avcodec, а затем вручную загрузить исходный ствол из последней версии репозитория ffmpeg и выполнить сборку из исходного кода. Это довольно трудоемкий процесс, но все получилось и проблема с линковкой была решена.

person StarShine    schedule 04.07.2018