AVFrame с форматом NV12 прерывается с использованием аппаратного ускорения D3D11.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 AVFrame с форматом NV12 прерывается с использованием аппаратного ускорения D3D11.

Сообщение Anonymous »

У меня есть видеодекодер ffmpeg-autogen, я пытаюсь использовать D3D11 в качестве аппаратного ускорителя, но кадр, который я получаю в результате (в формате NV12), неверный. Если я делаю то же самое с Vulkan в качестве ускорителя, все работает нормально, но vulkan использует больше ресурсов графической карты.
Для рендеринга я использую OpenTK, полученные кадры я конвертирую в RGB с текстурами и шейдерами.
Ниже инициализация моего декодера.

Код: Выделить всё

public VideoStreamDecoder(AVCodecParameters* parameters, AVCodec* codec)
{
AVCodec* _codec = codec;

_pCodecContext = ffmpeg.avcodec_alloc_context3(_codec);

ffmpeg.av_hwdevice_ctx_create(&_pCodecContext->hw_device_ctx, AVHWDeviceType.AV_HWDEVICE_TYPE_D3D11VA, null, null, 0).ThrowExceptionIfError();

ffmpeg.avcodec_parameters_to_context(_pCodecContext, parameters).ThrowExceptionIfError();
ffmpeg.avcodec_open2(_pCodecContext, _codec, null).ThrowExceptionIfError();

CodecName = ffmpeg.avcodec_get_name(_codec->id);
FrameSize = new Size(_pCodecContext->width, _pCodecContext->height);
PixelFormat = _pCodecContext->pix_fmt;

_pFrame = ffmpeg.av_frame_alloc();
_receivedFrame = ffmpeg.av_frame_alloc();
}
И функция чтения кадров

Код: Выделить всё

public bool TryReadNextFrame(out AVFrame frame, AVPacket packet)
{
int error;

do
{
ffmpeg.avcodec_send_packet(_pCodecContext, &packet).ThrowExceptionIfError();

error = ffmpeg.avcodec_receive_frame(_pCodecContext, _pFrame);

} while (error == ffmpeg.AVERROR(ffmpeg.EAGAIN));

error.ThrowExceptionIfError();

ffmpeg.av_hwframe_transfer_data(_receivedFrame, _pFrame, 0);
//here i get NV12 frame

var clonedFrame = ffmpeg.av_frame_clone(_receivedFrame);

frame = *clonedFrame;

return true;
}
И вот результат, который я получаю с обоими ускорителями: нормально работает
Та же камера, но D3D11
сломанная
Еще один интересный момент момент, это то, что камеры, которые не работают, имеют формат yuv420p, единственная работающая с D3D11 имеет yuvj420.
Я пробовал изменить формат с помощью sws_scale с NV12 на NV12, и это сработало, но оно использует слишком много ресурсов ЦП.
Также попробовал изменить формат на rgb перед функцией av_hwframe_transfer_data и отрендерить его с помощью рендеринга Vulkan, вроде как работает Vulkan, но с D3D11 этого не происходит.
ОБНОВЛЕНИЕ
Я заметил, что размер рамки больше ширины, и попробовал

Код: Выделить всё

_receivedFrame->linesize[0] = _receivedFrame->width;
И это помогло, теперь изображение выглядит лучше, но все еще не идеально.
ОБНОВЛЕНИЕ 2Я тоже пробую

Код: Выделить всё

_receivedFrame->linesize[1] = _receivedFrame->width;
и теперь все работает как надо, у меня ушел целый день на написание двух строчек кода :)

Подробнее здесь: https://stackoverflow.com/questions/786 ... celeration
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Формат NV12 и UV-плоскость
    Anonymous » » в форуме C#
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265
    Anonymous » » в форуме C++
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Как заполнить структуру Avframe, чтобы кодировать видео Yuy2 (или Uyvy) в H265
    Anonymous » » в форуме C++
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Мой рендеринг d3d11 не сразу обновляет ту часть окна, которая была за кадром
    Гость » » в форуме C++
    0 Ответы
    19 Просмотры
    Последнее сообщение Гость
  • Мой рендеринг d3d11 не сразу обновляет ту часть окна, которая была за кадром
    Гость » » в форуме C++
    0 Ответы
    23 Просмотры
    Последнее сообщение Гость

Вернуться в «C#»