FFmpeg декодировать и конвертировать RGB sws_scale ошибка - PullRequest
0 голосов
/ 10 января 2019

У меня проблема с моим кодом.

Я хочу преобразовать YUV в RGB, но sws_scale всегда возвращает 0 и данные заполняются 00000000..NULL

Я попробовал поискать в Google, но не смог найти никаких проблем.

Нужно ли мне AVPicture или QImage? Кто-нибудь может указать на мою проблему?

 pVFrame = av_frame_alloc();
 while (av_read_frame(pFormatCtx, &packet) == 0) {
        if (packet.stream_index == VSI) {
            if (bool res = avcodec_send_packet(pVideoCodecCtx, &packet)) {
                printf("avcodec_send_packet failed %d %d %d\n", res, AVERROR(EINVAL), AVERROR(ENOMEM));
            }
            avcodec_receive_frame(pVideoCodecCtx, pVFrame);

            AVFrame* YUV_frame = Con_yuv_YUV420P(pVFrame);
            QFrame->push(Con_yuv_RGB(YUV_frame));
        }
    }
}


AVFrame* Con_yuv_RGB(AVFrame* YUV_frame)
{
AVFrame* RGBFrame = av_frame_alloc();

SwsContext* sws_Context = NULL;
sws_Context = sws_getCachedContext(sws_Context, YUV_frame->width, YUV_frame->height, pVideoCodecCtx->pix_fmt,
    YUV_frame->width, YUV_frame->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);

if (sws_Context == NULL) {
    return false;
}
result = sws_scale(sws_Context, YUV_frame->data, YUV_frame->linesize, 0, (int)YUV_frame->height, RGBFrame->data, RGBFrame->linesize);
if (result < 0)
{
    return false;
}
av_frame_unref(YUV_frame);
if (RGBFrame == NULL) {
    av_frame_unref(RGBFrame);
    return false;
}

sws_freeContext(sws_Context);

return RGBFrame;

В чем проблема?

введите описание изображения здесь

Ссылочная ссылка - https://gist.github.com/nakaly/11eb992ebd134ee08b75e4c67afb5703,

http://codefromabove.com/2014/10/ffmpeg-convert-rgba-to-yuv/,

sws_scale YUV -> искаженное изображение RGB ,

https://www.gamedev.net/forums/topic/464977-sws_scale-problems/

https://ffmpeg.org/doxygen/2.7/group__libsws.html#gae531c9754c9205d90ad6800015046d74

ADD: введите описание изображения здесь

до конвертации. Он должен заполнить буфер.

RGBFrame->width = YUV_frame->width;     RGBFrame->format = AV_PIX_FMT_RGB32;
RGBFrame->height = YUV_frame->height;
int result = av_frame_get_buffer(RGBFrame, 32);
if (result != 0)    return false;

1 Ответ

0 голосов
/ 10 января 2019

Документация ffmpeg покрывает это:

https://www.ffmpeg.org/doxygen/2.3/group__lavu__frame.html#gac700017c5270c79c1e1befdeeb008b2f

AVFrame * av_frame_alloc (void)

Выделите AVFrame и установите для его полей значения по умолчанию.

Полученная структура должна быть освобождена с помощью av_frame_free ().

Возвращает AVFrame, заполненный значениями по умолчанию или NULL при ошибке. Заметка это только распределяет сам AVFrame, но не буферы данных. Те должны быть распределены другими способами, например, с av_frame_get_buffer () или вручную.

https://www.ffmpeg.org/doxygen/2.3/group__lavu__frame.html#ga6b1acbfa82c79bf7fd78d868572f0ceb

int av_frame_get_buffer (AVFrame * frame, int align) Allocate новые буферы для аудио или видео данных.

Следующие поля должны быть установлены во фрейме перед вызовом этого Функция:

Формат

(пиксельный формат для видео, примерный формат для аудио) ширина и высота для видео nb_samples и channel_layout для аудио Эта функция заполнит массивы AVFrame.data и AVFrame.buf и, если необходимо, выделить и заполнить AVFrame.extended_data и AVFrame.extended_buf. За В планарных форматах для каждой плоскости будет выделен один буфер.

...