FFmpeg iOS Получить UIImage из AVFrame - PullRequest
0 голосов
/ 04 марта 2019

У меня проблемы с извлечением UIImage из фреймов, которые я читаю, в мой проект iOS FFmpeg.Мне нужно иметь возможность прочитать кадр, а затем преобразовать его в UIImage, чтобы отобразить кадр в UIImageView.Кажется, мой код читается во фреймах, но я теряюсь в том, как их преобразовать, так как документации о том, как это сделать, немного.Кто-нибудь может помочь?

while (!finished) {
    if (av_read_frame(_formatContext, &packet) >= 0) {
        if (packet.stream_index == _videoStream) {
            int ret = avcodec_send_packet(_codecContext, &packet);
            if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                printf("av_codec_send_packet error ");
            }
            while (ret >= 0) {
                ret = avcodec_receive_frame(_codecContext, _frame);
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                    printf("avcodec_receive_frame error ");
                }



                finished = true;
            }
        }
        av_packet_unref(&packet);
    }
}

1 Ответ

0 голосов
/ 05 марта 2019

Вы должны знать о пиксельных форматах, таких как rgb и yuv.Видео почти всегда использует форматы yuv, такие как yuv420p.Затем изучите структуру AVFrame, вот некоторая информация:

AVFormat.format: пиксельный формат текущего кадра, т.е. AV_PIX_FMT_YUV420P
AVFormat.width: горизонтальная длина текущего кадра (отсюда и ширина): пиксели
AVFormat.height: вертикальная длина текущего кадра (следовательно, высота): пиксели

Теперь, где вы можете спросить фактический буфер кадра, он в AVFormat.data[n] n может быть 0-3.В зависимости от формата, только первый может содержать целый кадр или все 4 из них.Т.е. yuv420p использует 0, 1 и 2. Их линейные размеры (также известные как шаги) можно получить, читая соответствующее значение AVFormat.linesize[n].Что касается yuv420p:
data[0] это плоскость Y
data[1] это плоскость U
data[2] это плоскость V
Если вы умножите linesize[0] на AVFrame.height, вы получите размерэтой плоскости (Y) как число байтов.

Я не знаю о структуре UIImage (или чем-то еще), если он требует определенного формата, такого как RGB, вам нужно преобразовать свой AVFrame в этот форматиспользуя swscale.Вот несколько примеров: https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/scaling_video.c

В libav (ffmpeg) масштабирование (изменение размера) и преобразование формата пикселей выполняются с помощью одной и той же функции.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...