Как вы изменяете размер AVFrame?

Как вы меняете размер AVFrame? я

Вот что я сейчас делаю:

AVFrame* frame = /*...*/;

int width = 600, height = 400;
AVFrame* resizedFrame = av_frame_alloc();

auto format = AVPixelFormat(frame->format);

auto buffer = av_malloc(avpicture_get_size(format, width, height) * sizeof(uint8_t));

avpicture_fill((AVPicture *)resizedFrame, (uint8_t*)buffer, format, width, height);

struct SwsContext* swsContext = sws_getContext(frame->width, frame->height, format,
                                               width,         height,         format,
                                               SWS_BILINEAR,  nullptr,        nullptr,        nullptr);

sws_scale(swsContext, frame->data, frame->linesize, 0, frame->height, resizedFrame->data, resizedFrame->linesize);

Но после этого resizedFrames->widthа также height все еще 0, содержимое AVFrame выглядит как мусор, и я получаю предупреждение, что данные не выровнены, когда я вызываю sws_scale, Примечание: я не хочу менять формат пикселя, и я не хочу жестко кодировать, что это такое.

1 ответ

Решение

Итак, происходит несколько вещей.

  • avpicture_fill () не устанавливает frame->width/height/format. Вы должны установить эти значения самостоятельно.
  • avpicture_get_size () и avpicture_fill () не гарантируют выравнивание. Базовые функции, вызываемые в этих оболочках (например, av_image_get_buffer_size() или av_image_fill_arrays ()), вызываются с align=1, поэтому нет выравнивания буфера между строками. Если вы хотите выравнивание (вы делаете это), вы должны либо напрямую вызывать базовые функции с другим параметром выравнивания, либо вызывать avcodec_align_dimensions2() для width / height и предоставлять выровненные width / height для функций avpicture_*(). Если вы сделаете это, вы также можете рассмотреть возможность использования avpicture_alloc () вместо avpicture_get_size () + av_malloc () + avpicture_fill ().

Я думаю, что если вы последуете этим двум советам, вы обнаружите, что масштабирование работает, как и ожидалось, не выдает предупреждений и дает правильный вывод. Качество может быть не очень хорошим, потому что вы пытаетесь выполнить билинейное масштабирование. Большинство людей используют бикубическое масштабирование ( SWS_BICUBIC).

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