FFmpeg c api создает кодировщик для сбоя AV_CODEC_ID_H264 в Windows

Я использую ffmpeg (версия 5.1.2) для клипирования видео в формате mp4 на кадр, поэтому мне нужно его декодировать и кодировать. Однако, когда я создаю кодировщик для своего видеопотока, программа всегда вылетает при вызове avio_open2(), после того как H264 выдает это сообщение об ошибке:

[h264_mf @ 0000025C1EBC1900] could not set output type (80004005)

Конфигурация (time_base, pix_fmt, ширина, высота) контекста кодека кодировщика копируется из декодера, и я проверил, поддерживается ли формат пикселей, обнаружив, находится ли он в codec->pix_fmts.

Я обнаружил, что проблема не связана со всеми остальными фрагментами моего кода, потому что эта минимальная программа может дублировать ту же проблему:

extern "C"
{
#include <libavcodec/avcodec.h>
}

int main()
{
    auto codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    auto codec_ctx = avcodec_alloc_context3(codec);

    codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
    codec_ctx->width = 2560;
    codec_ctx->height = 1440;
    codec_ctx->time_base.num = 1; codec_ctx->time_base.den = 180000;

    avcodec_open2(codec_ctx, codec, NULL);

    return 0;
}

Тогда я подозреваю, что это ошибка ffmpeg. Моя среда — Windows 11 64-бит, Visual Studio 2022. Библиотека ffmpeg получена из vcpkg, как показано на следующем рисунке:

Почему вы пытаетесь вызвать другие avcodec_* функции перед avcodec_init()?

genpfault 30.04.2023 06:06

@genpfault Я использую ffmpeg версии 5.1, где мне не нужно вызывать эту функцию. Я упоминал об этом в конце. Я также отредактирую вопрос, чтобы указать версию в начале.

Guanyuming He 30.04.2023 06:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я обнаружил, что проблема вызвана слишком маленькой временной базой.

В частности, я проверил, что если предположить, что числитель равен 1, когда знаменатель <= 172, кодировщик может быть создан без проблем. Однако когда знаменатель > 172, проблема будет возникать всегда.

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

Редактировать: я обнаружил в комментарии AVCodecContext::time_base, что для декодирования он устарел, и я должен использовать частоту кадров для этой цели (т.е. копировать поток r_frame_rate в codec_ctx->framerate). Это значение равно 30/1, а его обратное значение больше предела 1/172. Однако для кодирования это необходимо установить, и это (отчасти) причина моего замешательства. Тем не менее, странно то, что временная база входного потока составляет 1/90000 < 1/127.

Другие вопросы по теме