FFmpeg AVFrame для OpenGL текстуры без мягкого преобразования YUV в RGB - PullRequest
3 голосов
/ 23 февраля 2012

Я хочу декодировать зашифрованный видеофайл H264 на iOS. Я уже перенес наш алгоритм дешифрования, и он работает нормально. Однако мы не можем напрямую использовать аппаратный декодер H264 из-за отсутствия API в SDK.

Поэтому я пытаюсь найти альтернативу декодированию видео H264. Я пытаюсь использовать FFmpeg для декодирования этого видео, даже если есть некоторые возможные проблемы с лицензией LGPL. Я без проблем декодирую видео H264 и рендеринг кадров H264 благодаря текстуре OpenGL ES. Но есть некоторые проблемы с производительностью. Я проинструктировал мой код, и узким местом является масштабирование ffmpeg и преобразование YUV в RGB. Я знаю, что могу использовать шейдеры OpenGL ES 2.0 для преобразования YUV в RGB с ускорением GPU (см. Статью Альтернатива ffmpeg для iOS ). Я также знаю, как составлена ​​структура AVFrame: данные [0] для данных Y, данные [1] для данных U и данные [1] для данных V. Но я не понимаю, как я могу использовать размер строки [x] с данными [x] для передачи данных в текстуру OpenGL.

У кого-нибудь есть пример AVFrame YUV для текстуры OpenGL?

Спасибо, David

1 Ответ

1 голос
/ 15 ноября 2018

1. Первый метод заключается в том, что вы можете использовать libyuv.

2.Вы также можете использовать sws_getCachedContext и sws_scale две функции в libswscale.a модуле ffmpeg, например такпреобразовать AV_PIX_FMT_YUV420P в AV_PIX_FMT_0BGR32:

enum AVPixelFormat dst_format = AV_PIX_FMT_0BGR32;
if (!is->img_convert_ctx)
            is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, sourceFrame->width, sourceFrame->height, sourceFrame->format, sourceFrame->width, sourceFrame->height, dst_format, SWS_BILINEAR, NULL, NULL, NULL);
uint8_t *data[AV_NUM_DATA_POINTERS];
int linesize[AV_NUM_DATA_POINTERS];
av_image_alloc(data, linesize, sourceFrame->width, sourceFrame->height, dst_format, 1);
AVFrame *tempFrame = sourceFrame;
sws_scale(is->img_convert_ctx, (const uint8_t**) tempFrame->data, sourceFrame->linesize, 0, sourceFrame->height, data, linesize);
free(data[0]);

после этого , AV_PIX_FMT_0BGR32 данные находятся в data[0] и linesize[0]

...