Я получил двоичные файлы последней версии ffmpeg от здесь. Когда я изучаю загрузку ЦП и ГП при воспроизведении видео по его ffplay, я вижу, что ГП используется во время воспроизведения. На это также указывает малое использование процессора. Но когда я получаю исходники последней версии с исходного сайта, я не могу использовать GPU. Чтобы уточнить, я включаю программу тестирования плеера, которую написал до сих пор. Когда я раскомментирую строку, которая включает avcodec_find_decoder_by_name("h264_cuvid"), я получаю ошибку -1. Ошибка происходит в avcodec_open2 с описанием операции не разрешено.
CString format(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
char buf[512];
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return buf;
}
int CplayerDlg::play()
{
FILE *fp = fopen("video_files/1010.brf", "rb");
if (!fp)
{
AfxMessageBox("can't open video file");
return -1;
}
RecordFrame frame;
RecordHeader hdr;
fread(&frame, sizeof(frame), 1, fp);
if (frame.frameType != FRAME_TYPE_HEADER)
{
AfxMessageBox("record file doesn't begin with header");
return -1;
}
fread(&hdr, sizeof(hdr), 1, fp);
GetDlgItem(IDC_DIM)->SetWindowText(format("%dx%d", hdr.width, hdr.height));
GetDlgItem(IDC_CODEC_ID)->SetWindowText(format("%d", hdr.codecId));
GetDlgItem(IDC_PIXEL_FORMAT)->SetWindowText(format("%d", hdr.pixelFormat));
GetDlgItem(IDC_TIMEBASE)->SetWindowText(format("%d/%d", hdr.timebaseNum, hdr.timebaseDen));
AVCodec *pCodec;
#if 0
#define CHECK(decoder)\
pCodec = avcodec_find_decoder_by_name(#decoder);\
AfxMessageBox(pCodec ? #decoder " found" : "can't find " #decoder);
CHECK(h264_cuvid);
#undef CHECK
#endif
pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
//pCodec = avcodec_find_decoder_by_name("h264_cuvid");
if (!pCodec)
{
AfxMessageBox("can't find h264 decoder");
return -1;
}
AVCodecContext *pCodecContext = avcodec_alloc_context3(pCodec);
if (!pCodecContext)
{
AfxMessageBox("can't allocate codec context");
return -1;
}
#if 0
// enumerating available codecs
//av_register_all();
avcodec_register_all();
AVCodec *current_codec = av_codec_next(NULL);
while (current_codec != NULL)
{
TRACE("%s\n", current_codec->name);
current_codec = av_codec_next(current_codec);
}
#endif
int err = avcodec_open2(pCodecContext, pCodec, NULL);
if (err != 0)
{
char buf[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, err);
char buf2[AV_ERROR_MAX_STRING_SIZE];
sprintf(buf2, "%d (%x): %s\n", err, err, buf);
AfxMessageBox(buf2);
return -1;
}
AfxMessageBox("operation completed successfully");
fclose(fp);
return 0;
}
Как я уже сказал, я не настраивал ffmpeg и не делал этого. Я использую готовые бинарники. Но перечисление доступных кодов списков h264_nvenc, venc nvenc_h264, nvenc_hevc и т.д.
Отмечает, что моя видеокарта может быть не nVidia, хотя на nVidia ошибка такая же. Мне нужно, чтобы моя программа запускалась на любых видеокартах. Моя идея заключается в том, что DirectX включен во всех средах Windows.
Ок, меня смутили ваши слова when I get the latest version sources. Теперь я понимаю, что вы сравниваете двоичные файлы, загруженные с ffmpeg.zeranoe.com, и те, что загружены с ffmpeg.org. Я прав ? Может быть, вы могли бы уточнить свой вопрос?
Извините, если я не мог описать лучше. Нет, я действительно думаю, что оба одинаковы. Кто-то в Zeranoe клонировал оригинальные исходники ffmpeg, как и я, и создал библиотеки DLL, которые я использую. Поскольку просто иметь двоичные файлы (DLL) недостаточно, и мне также нужны заголовочные файлы, мне также пришлось сделать git clone. Я имел в виду, что двоичные файлы принадлежат одним и тем же файлам заголовков, и не должно быть несоответствий, которые могли бы вызвать проблему.
См. github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c
Спасибо @Gyan за ссылку. Наконец-то я смог запустить его на Ubuntu и Windows. Я не мог использовать dxva2 в Linux. Может быть, это потому, что DirectX не включен в Linux. Хотя это не моя проблема. Но в Windows я мог запустить его и заставить его работать. :) Но увеличивается загрузка ЦП и ГП. Это естественно? Мне нужен такой пример кода, чтобы не увеличивать загрузку процессора. Что я могу сделать?
Кроме того, выходной файл такой большой и не воспроизводимый.
Закомментировав строки со 110 по 140 файла hw_decode.c, часть, начинающуюся с av_hwframe_transfer_data, куда он записывает результат в файл с помощью fwrite, я смог снизить нагрузку на ЦП и получить то, что хотел. Теперь, как я могу показать декодированный пакет на аппаратной поверхности? Мне нужно, чтобы результат отображался прямо на экране.





Вы пытались скомпилировать с опцией
--enable-nvenc? См. эта тема для получения дополнительной информации.