FFMPEG - C API - создание GIF - PullRequest
       24

FFMPEG - C API - создание GIF

1 голос
/ 21 февраля 2020

У меня есть конвейер обработки изображений, и в памяти есть изображения, которые я конвертирую в AVFrame, и я пытаюсь создать GIF с ними.

Я начал с этого topi c и я только что заменил часть видео декодера с преобразованием моего изображения в памяти в AVFrame.

Это работает довольно хорошо, но у меня есть проблема с частотой кадров GIF.

В методе init_filters(...) я не понимаю переменные time_base и pixel_aspect структуры аргумента:

    snprintf(args, sizeof(args),
         "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
         width, height, in_fmt, time_base.num, time_base.den,
         pixel_aspect.num, pixel_aspect.den);

Я хотел бы иметь FPS = 12 поэтому я должен определить их следующим образом?

AVRational time_base = AVRational{1, 12};
AVRational pixel_aspect= AVRational{1, 1}; 

Далее, в l oop, где я передаю кадр в буфер фильтра (для палитры), у меня также есть опции, которые я не Я не понимаю, к чему относится AVFrame-> pts?

    // palettegen need a whole stream, just add frame to buffer.
    ret = av_buffersrc_add_frame_flags(buffersrc_ctx, picture_rgb24, AV_BUFFERSRC_FLAG_KEEP_REF);
    if (ret < 0) {
        av_log(nullptr, AV_LOG_ERROR, "error add frame to buffer source %s\n", av_make_error_string(msg_v2, MSG_LEN, ret));
    }

    picture_rgb24->pts += 1; // HERE

Насколько я понимаю, это должна быть метка времени кадра, в моем случае у меня есть GIF, я должен увеличить на 1 каждый раз? или 1000 мс / 12 кадров = 83,33 мс? Я не уверен, я пытался найти информацию, но пока не повезло.

Существует также метод init_muxer(...), в котором можно установить time_base вывода (GIF):

    o_codec_ctx->time_base = AVRational{1, 12};

Так что я немного запутался со всем местом, где мы должны устанавливать частоту кадров.

В данный момент GIF хорошо генерируется (с палитрой) в памяти с использованием FFMPEG C API, Единственная проблема заключается в том, что GIF слишком быстрый и не с правильной частотой кадров.

1 Ответ

1 голос
/ 21 февраля 2020

Наконец я нашел это. Вы должны увеличивать количество точек видео на основе частоты кадров (12) и кода c time_base (1/100 для GIF).

picture_rgb24->pts += av_rescale_q(1, { 1, 12 }, { 1, 100 });

РЕДАКТИРОВАТЬ:

Еще лучше, вместо того, чтобы жестко кодировать свое открытие, я выясняю, что я могу получить к нему доступ с помощью кода c, и в любом случае мне просто нужно вычислить его один раз.

if (ofmt_ctx && ofmt_ctx->nb_streams > 0)
        m_pts_increment = av_rescale_q(1, { 1, m_framerate }, ofmt_ctx->streams[0]->time_base);
    else
        m_pts_increment = av_rescale_q(1, { 1, m_framerate }, { 1, 100 });

и просто нужно сделать (для каждый кадр).

picture_rgb24->pts += m_pts_increment;
...