...в качестве дополнения к этому посту: Хочется странного: особое отношение C++ного компилятора к структурам, объявленным как extern "C". Попробую вспомнить особенность перехода с FFMPEG 4.4 на FFMPEG 5.1, связанную с AVChannelLayout.
В текущем проекте нужно снимать видео/аудио потоки с камер посредством FFMPEG. В случае с аудио потоками бывает нужно один из них воспроизводить. Так же может потребоваться какие-то из них записывать (если записывать, то вместе с видео).
Приходить аудио может в разных форматах (благо FFMPEG отличается всеядностью), а вот для воспроизведения должен использоваться зафиксированный в коде формат. Для записи также должен использоваться зафиксированный в коде формат, но (ЕМНИП) не такой, как для воспроизведения.
Кроме того, снятые AVFrame протаскиваются через цепочку SObjectizer-овских агентов и i-й агент в цепочке, в принципе, может не иметь всей информации об исходном потоке и его состоянии. Т.е. агент, который напрямую дергает FFMPEG, обнаруживает разрыв и переподключение к камере (соответственно, у него пересоздаются AVCodecContext-ы), а вот последующие агенты могут информацию о переподключениях не получить и не узнать, что новые AVFrame содержат аудио-данные уже в другом формате.
В общем, говоря про код, есть две задачки: a) передать конфигурацию агентам, которые занимаются перекодированием аудио-данных (для воспроизведения или записи) и b) проверять формат аудио-данных в очередном AVFrame чтобы поймать момент внезапной смены формата (если таковая смена вообще происходит).
Для этого была сделана простая структурка, содержащая минимум полей: channel_layout в виде единственного std::int64_t, sample_fmt в виде AVSampleFormat и sample_rate в виде обычного int-а. В общем, тривиальный POD тип с constexpr-конструктором. Экземпляры этого типа используются и для того, чтобы зафиксировать формат аудио для воспроизведения/записи, и для того, чтобы сохранить информацию о параметрах текущего аудио-потока.
Благодаря тому, что описание формата можно было объявлять как constexpr константу, то в нескольких местах кода были сделаны static_assert-ы, для того, чтобы в compile-time проверять, что написанный под определенный аудио-формат код остается актуальным (т.е. если где-то описание формата вдруг поменяли, а код не поправили, то это будет обнаружено компилятором).
Все это хорошо работало потому, что в FFMPEG 4.4 количество и расположение аудио-каналов описывалось, по сути, единственным целым числом -- channel_layout. Иногда этот channel_layout мог быть нулевым (т.е. не заданным явно), тогда значение channel_layout можно было вывести на основании значения nb_channels.
Но вот в FFMPEG 5.1 целочисленное поле channel_layout задеприкейтили (но хотя бы поддерживают), и ввели новый тип данных AVChannelLayout, который является совокупностью из channel_layout+nb_channel из FFMPEG 4.4, но не только. Экземпляр AVChannelLayout теперь может содержать и дополнительную информацию. В том числе и информацию, которая расположена в динамической памяти, т.е. в AVChannelLayout может лежать и вполне себе владеющий указатель.
Поскольку сейчас AVChannelLayout -- это отнюдь не простая структура, то пришлось менять существующий в проекте тип, описывающий формат аудио. Т.е. поле channel_layout типа std::int64_t нужно было заменить на ch_layout типа AVChannelLayout.
И вот здесь как раз начинаются некоторые неудобства. Абсолютно не смертельные, но... Но мимо которых просто так не пройдешь. По крайней мере мне не удалось пройти :)