From 1be0580b7d9d1e2c3e8671a7f78e21b501a61d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maro=C5=A1=20Grego?= Date: Sat, 14 Oct 2023 15:08:22 +0200 Subject: [PATCH] Add an option to export H.264 with VAAPI GPU acceleration This enables exporting H.264 with GPU acceleration on all Intel and AMD GPUs from the past decade. --- .gitignore | 10 +++++++ platform/qt/ExportSettingsDialog.cpp | 1 + platform/qt/ExportSettingsDialog.h | 38 +++++++++++++++----------- platform/qt/ExportSettingsDialog.ui | 5 ++++ platform/qt/MainWindow.cpp | 40 +++++++++++++++++++++++----- 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index ac3f7c2a9..291103111 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,13 @@ osx_installer/create-dmg-master/builder/create-dmg.builder platform/build-MLVApp-Desktop_Qt_5_15_3_clangOMP_64bit-Release/* platform/build-MLVApp-Desktop_Qt_5_15_3_llvm16OMP_64bit-Release/* platform/build-MLVApp-Desktop_Qt_5_15_10_llvm16OMP_64bit-Release/* +platform/qt/.moc/ +platform/qt/.obj/ +platform/qt/.qmake.stash +platform/qt/.rcc/ +platform/qt/.ui/ +platform/qt/*.fpm +platform/qt/Makefile +platform/qt/ffmpeg +platform/qt/pixel_maps +platform/qt/releases diff --git a/platform/qt/ExportSettingsDialog.cpp b/platform/qt/ExportSettingsDialog.cpp index 441f9e382..615ef7e6c 100644 --- a/platform/qt/ExportSettingsDialog.cpp +++ b/platform/qt/ExportSettingsDialog.cpp @@ -278,6 +278,7 @@ void ExportSettingsDialog::on_comboBoxCodec_currentIndexChanged(int index) enableResize = false; } else if( index == CODEC_H264 + || index == CODEC_H264_VAAPI || index == CODEC_H265_8 || index == CODEC_H265_10 || index == CODEC_H265_12 ) diff --git a/platform/qt/ExportSettingsDialog.h b/platform/qt/ExportSettingsDialog.h index b7ee89f1c..e0f1a2663 100644 --- a/platform/qt/ExportSettingsDialog.h +++ b/platform/qt/ExportSettingsDialog.h @@ -22,21 +22,22 @@ #define CODEC_CDNG_LOSSLESS 7 #define CODEC_CDNG_FAST 8 #define CODEC_H264 9 -#define CODEC_H265_8 10 -#define CODEC_H265_10 11 -#define CODEC_H265_12 12 -#define CODEC_TIFF 13 -#define CODEC_PNG 14 -#define CODEC_JPG2K 15 -#define CODEC_MJPEG 16 -#define CODEC_FFVHUFF 17 -#define CODEC_MLV 18 -#define CODEC_DNXHD 19 -#define CODEC_DNXHR 20 -#define CODEC_CINEFORM_10 21 -#define CODEC_CINEFORM_12 22 -#define CODEC_VP9 23 -#define CODEC_AUDIO_ONLY 24 +#define CODEC_H264_VAAPI 10 +#define CODEC_H265_8 11 +#define CODEC_H265_10 12 +#define CODEC_H265_12 13 +#define CODEC_TIFF 14 +#define CODEC_PNG 15 +#define CODEC_JPG2K 16 +#define CODEC_MJPEG 17 +#define CODEC_FFVHUFF 18 +#define CODEC_MLV 19 +#define CODEC_DNXHD 20 +#define CODEC_DNXHR 21 +#define CODEC_CINEFORM_10 22 +#define CODEC_CINEFORM_12 23 +#define CODEC_VP9 24 +#define CODEC_AUDIO_ONLY 25 #define CODEC_AVI_OPTION_YUV420 0 #define CODEC_AVI_OPTION_V210 1 @@ -57,6 +58,13 @@ #define CODEC_H264_M_MKV 5 #define CODEC_H264_AVFOUNDATION 6 +#define CODEC_H264_VAAPI_H_MOV 0 +#define CODEC_H264_VAAPI_H_MP4 1 +#define CODEC_H264_VAAPI_H_MKV 2 +#define CODEC_H264_VAAPI_M_MOV 3 +#define CODEC_H264_VAAPI_M_MP4 4 +#define CODEC_H264_VAAPI_M_MKV 5 + #define CODEC_H265_H_MOV 0 #define CODEC_H265_H_MP4 1 #define CODEC_H265_H_MKV 2 diff --git a/platform/qt/ExportSettingsDialog.ui b/platform/qt/ExportSettingsDialog.ui index 14bd413b9..2a9b78900 100644 --- a/platform/qt/ExportSettingsDialog.ui +++ b/platform/qt/ExportSettingsDialog.ui @@ -204,6 +204,11 @@ H.264 + + + H.264 VAAPI (Intel/AMD GPU) + + H.265 8bit 4:2:0 diff --git a/platform/qt/MainWindow.cpp b/platform/qt/MainWindow.cpp index 0419fa49b..b55f2d0dd 100644 --- a/platform/qt/MainWindow.cpp +++ b/platform/qt/MainWindow.cpp @@ -1763,7 +1763,7 @@ void MainWindow::startExportPipe(QString fileName) #else writeMlvAudioToWaveCut( m_pMlvObject, wavFileName.toLatin1().data(), m_exportQueue.first()->cutIn(), m_exportQueue.first()->cutOut() ); #endif - if( m_codecProfile == CODEC_H264 || m_codecProfile == CODEC_H265_8 || m_codecProfile == CODEC_H265_10 || m_codecProfile == CODEC_H265_12 ) + if( m_codecProfile == CODEC_H264 || m_codecProfile == CODEC_H264_VAAPI || m_codecProfile == CODEC_H265_8 || m_codecProfile == CODEC_H265_10 || m_codecProfile == CODEC_H265_12 ) ffmpegAudioCommand = QString( "-i \"%1\" -c:a aac " ).arg( wavFileName ); else if( m_codecProfile == CODEC_VP9 ) ffmpegAudioCommand = QString( "-i \"%1\" -c:a libopus " ).arg( wavFileName ); else ffmpegAudioCommand = QString( "-i \"%1\" -c:a copy " ).arg( wavFileName ); @@ -1910,13 +1910,19 @@ void MainWindow::startExportPipe(QString fileName) } } + QString hwuploadString = QString( "" ); + if (m_codecProfile == CODEC_H264_VAAPI) { + hwuploadString = QString( ",format=nv12,hwupload," ); + } + //Colorspace conversion (for getting right colors) QString resizeFilter = QString( "" ); //a colorspace conversion is always needed to get right colors - resizeFilter = QString( "-vf %1scale=in_color_matrix=bt601:out_color_matrix=bt709%2%3 " ) + resizeFilter = QString( "-vf %1scale=in_color_matrix=bt601:out_color_matrix=bt709%2%3%4 " ) .arg( moireeFilter ) .arg( hdrString ) - .arg( vidstabString ); + .arg( vidstabString ) + .arg( hwuploadString ); //qDebug() << resizeFilter; //Color tag @@ -2349,6 +2355,26 @@ void MainWindow::startExportPipe(QString fileName) .arg( resizeFilter ) .arg( output ) ); } + else if( m_codecProfile == CODEC_H264_VAAPI ) + { + if( m_codecOption == CODEC_H264_VAAPI_H_MOV || m_codecOption == CODEC_H264_VAAPI_M_MOV ) output.append( QString( ".mov" ) ); + else if( m_codecOption == CODEC_H264_VAAPI_H_MP4 || m_codecOption == CODEC_H264_VAAPI_M_MP4 ) output.append( QString( ".mp4" ) ); + else output.append( QString( ".mkv" ) ); + + int quality; + if( m_codecOption == CODEC_H264_VAAPI_H_MOV || m_codecOption == CODEC_H264_VAAPI_H_MP4 || m_codecOption == CODEC_H264_VAAPI_H_MKV ) + quality = 17; + else + quality = 22; + + program.append( QString( " -init_hw_device vaapi=vaapi0: -filter_hw_device vaapi0 -r %1 -y -f rawvideo -s %2 -pix_fmt rgb48 -i - -c:v h264_vaapi -global_quality %3 -color_primaries %5 -color_trc %5 -colorspace bt709 %6 \"%7\"" ) + .arg( fps ) + .arg( resolution ) + .arg( quality ) + .arg( colorTag ) + .arg( resizeFilter ) + .arg( output ) ); + } else if( m_codecProfile == CODEC_H265_8 || m_codecProfile == CODEC_H265_10 || m_codecProfile == CODEC_H265_12 ) { QString bitdepth; @@ -6539,8 +6565,9 @@ void MainWindow::on_actionExport_triggered() } else { - if( ( m_codecProfile == CODEC_H264 || m_codecProfile == CODEC_H265_8 || m_codecProfile == CODEC_H265_10 || m_codecProfile == CODEC_H265_12 ) - && ( m_codecOption == CODEC_H264_H_MP4 || m_codecOption == CODEC_H265_H_MP4 + if( ( m_codecProfile == CODEC_H264 || m_codecProfile == CODEC_H264_VAAPI || m_codecProfile == CODEC_H265_8 || m_codecProfile == CODEC_H265_10 || m_codecProfile == CODEC_H265_12 ) + && ( m_codecOption == CODEC_H264_VAAPI_H_MP4 || m_codecOption == CODEC_H264_VAAPI_M_MP4 + || m_codecOption == CODEC_H264_H_MP4 || m_codecOption == CODEC_H265_H_MP4 || m_codecOption == CODEC_H264_M_MP4 || m_codecOption == CODEC_H265_M_MP4 ) ) { saveFileName.append( ".mp4" ); @@ -6548,7 +6575,8 @@ void MainWindow::on_actionExport_triggered() fileEnding = ".mp4"; } else if( ( m_codecProfile == CODEC_H264 || m_codecProfile == CODEC_H265_8 || m_codecProfile == CODEC_H265_10 || m_codecProfile == CODEC_H265_12 ) - && ( m_codecOption == CODEC_H264_H_MKV || m_codecOption == CODEC_H265_H_MKV + && ( m_codecOption == CODEC_H264_VAAPI_H_MKV || m_codecOption == CODEC_H264_VAAPI_M_MP4 + || m_codecOption == CODEC_H264_H_MKV || m_codecOption == CODEC_H265_H_MKV || m_codecOption == CODEC_H264_M_MKV || m_codecOption == CODEC_H265_M_MKV) ) { saveFileName.append( ".mkv" );