Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GPU acceleration to ld-compress #719

Merged
merged 2 commits into from
Apr 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions scripts/ld-compress
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ modeselection=0
comp=true
uncomp=false
verify=false
gpu=false
setup=false
fileinput_method=cat
level=11
ext=ldf

help_msg () {
echo "Usage: $0 [-c] [-u] [-v] [-p] [-h] [-l <1-12>] [-g] file(s)"; printf -- "\nModes:\n-c Compress (default): Takes one or more .lds files and compresses them to .ldf files in the current directory.\n-u Uncompress: Takes one or more .ldf/.raw.oga files and uncompresses them to .lds files in the current directory.\n-v Verify: Returns md5 checksums of the given .ldf/.raw.oga files and their contained .lds files for verification purposes.\n\nOptions\n-p Progress: displays progress bars - requires pv to be installed.\n-h Help: This dialog.\n-l Compression level 1 - 12. Default is 11. 6 is recommended for faster but fair compression.\n-g Use .raw.oga extension instead of .ldf when compressing.\n\n"
echo "Usage: $0 [-c] [-a] [-u] [-v] [-s] [-p] [-h] [-l <1-12>] [-g] file(s)"; printf -- "\nModes:\n-c Compress (default): Takes one or more .lds files and compresses them to .ldf files in the current directory.\n-u Uncompress: Takes one or more .ldf/.raw.oga files and uncompresses them to .lds files in the current directory.\n-a GPU Acceleration. Uses OpenCL or CUDA to accelerate encoding.\n-v Verify: Returns md5 checksums of the given .ldf/.raw.oga files and their contained .lds files for verification purposes.\n-s Setup: Set up GPU acceleration requirements. Modifies mono for OpenCL support and installs FLACCL.\nOptions\n-p Progress: displays progress bars - requires pv to be installed.\n-h Help: This dialog.\n-l Compression level 1 - 12. Default is 11. 6 is recommended for faster but fair compression.\n-g Use .raw.oga extension instead of .ldf when compressing.\n\n"
}

while getopts ":hcuvpl:g" option; do
while getopts ":hcauvspl:g" option; do
case $option in
h) help_msg ; exit ;;
c) comp=true ; modeselection=$((modeselection+1)) ;;
u) uncomp=true ; comp=false ; modeselection=$((modeselection+1)) ;;
a) gpu=true ; comp=false ; modeselection=$((modeselection+1)) ;;
v) verify=true ; comp=false ; modeselection=$((modeselection+1)) ;;
s) setup=true ; comp=false ; modeselection=$((modeselection+1)) ;;
p) fileinput_method="pv" ;;
l)
level=${OPTARG}
Expand All @@ -40,7 +44,7 @@ done
shift $(( OPTIND - 1 ))

# Check if input files have been entered, and if so, process according to the selected mode.
if [[ $# < 1 ]]
if [[ $# < 1 ]] && [[ "$setup" == false ]]
then
help_msg ; exit
else
Expand All @@ -61,6 +65,20 @@ else
fi
done
fi
if [[ "$gpu" == true ]] # Perform GPU accelerated compression
then
# Increment compression level down by one to compensate for FLACCL's 0-11 compression levels, vs ffmpeg's 1-12
((level=level-1))
for f in "$@" ; do
if [[ "$f" == *.lds ]]
then
echo $level
>&2 echo Compressing \'"$f"\' to \'"$(basename "$f" .lds).$ext"\' && ${fileinput_method} "$f" | ld-lds-converter -r -u | mono /opt/flaccl/CUETools.FLACCL.cmd.exe - --ignore-chunk-sizes -q -"$level" --lax -o "$(basename "$f" .lds).$ext" && >&2 echo \'"$(basename "$f" .lds).$ext"\' written.
else
>&2 echo Error: \'"$f"\' does not appear to be a .lds file. Skipping.
fi
done
fi
if [[ "$uncomp" == true ]] # Perfom uncompression
then
for f in "$@" ; do
Expand All @@ -86,6 +104,24 @@ else
fi
done
fi
if [[ "$setup" == true ]] # Setup GPU acceleration support
then
# Check if /opt/flaccl is present
FLADIR=/opt/flaccl
if [ ! -d "$FLADIR" ]
then
mkdir /opt/flaccl
fi
# Download FLACCL 2.2.1 and install
wget -q https://github.com/gchudov/cuetools.net/releases/download/v2.2.1/CUETools_2.2.1.zip -P /tmp/
unzip -qq -o /tmp/CUETools_2.2.1.zip -d /opt/flaccl
rm /tmp/CUETools_2.2.1.zip
# Check if mono is configured for OpenCL
if ! grep -e '<dllmap dll="opencl.dll" target="libOpenCL.so" />' /etc/mono/config > /dev/null
then
sudo sed -i '$i\ <dllmap dll="opencl.dll" target="libOpenCL.so" />' /etc/mono/config
fi
fi
sleep 1
>&2 echo "Task complete."
fi
14 changes: 13 additions & 1 deletion tools/ld-lds-converter/dataconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@

#include "dataconverter.h"

DataConverter::DataConverter(QString inputFileNameParam, QString outputFileNameParam, bool isPackingParam, QObject *parent) : QObject(parent)
DataConverter::DataConverter(QString inputFileNameParam, QString outputFileNameParam, bool isPackingParam, bool isRIFFParam, QObject *parent) : QObject(parent)
{
// Store the configuration parameters
inputFileName = inputFileNameParam;
outputFileName = outputFileNameParam;
isPacking = isPackingParam;
isRIFF = isRIFFParam;
}

// Method to process the conversion of the file
Expand Down Expand Up @@ -117,9 +118,11 @@ bool DataConverter::openOutputFile(void)
return false;
}
qDebug() << "Writing output data to stdout";

} else {
// Open the output file for writing
outputFileHandle = new QFile(outputFileName);

if (!outputFileHandle->open(QIODevice::WriteOnly)) {
// Failed to open output file
qDebug() << "DataConverter::openOutputFile(): Could not open" << outputFileName << "as output file";
Expand Down Expand Up @@ -225,6 +228,15 @@ void DataConverter::unpackFile(void)
QByteArray outputBuffer;
bool isComplete = false;

// Are we writing a RIFF header?
if (isRIFF) {
// Writes a WAV RIFF header, 44.1k, mono, 16-bit signed
QString riffHex = "52494646FFFFFFFF57415645666D7420100000000100010044AC000088580100020010004C4953541A000000494E464F495346540E0000004C61766635382E32392E3130300064617461FFFFFFFF";
QByteArray riffArray = QByteArray::fromHex(riffHex.toLatin1());
outputFileHandle->write(riffArray);
}


while(!isComplete) {
// Input buffer must be divisible by 5 bytes due to 10-bit data format
qint32 bufferSizeInBytes = (5 * 1024 * 1024) * 4; // 5MiB * 4 = 20MiBytes
Expand Down
3 changes: 2 additions & 1 deletion tools/ld-lds-converter/dataconverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class DataConverter : public QObject
{
Q_OBJECT
public:
explicit DataConverter(QString inputFileNameParam, QString outputFileNameParam, bool isPackingParam, QObject *parent = nullptr);
explicit DataConverter(QString inputFileNameParam, QString outputFileNameParam, bool isPackingParam, bool isRIFFParam, QObject *parent = nullptr);
bool process(void);

signals:
Expand All @@ -44,6 +44,7 @@ public slots:
QString inputFileName;
QString outputFileName;
bool isPacking;
bool isRIFF;

QFile *inputFileHandle;
QFile *outputFileHandle;
Expand Down
18 changes: 17 additions & 1 deletion tools/ld-lds-converter/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ int main(int argc, char *argv[])
QCoreApplication::translate("main", "Pack 16-bit data into 10-bit"));
parser.addOption(showPackOption);

// Option to unpack 10-bit data with RIFF WAV headers (-r)
QCommandLineOption showRIFFOption(QStringList() << "r" << "riff",
QCoreApplication::translate("main", "Unpack 10-bit data into 16-bit with RIFF WAV headers"));
parser.addOption(showRIFFOption);

// Process the command line arguments given by the user
parser.process(a);

Expand All @@ -87,21 +92,32 @@ int main(int argc, char *argv[])
// Get the configured settings from the parser
bool isUnpacking = parser.isSet(showUnpackOption);
bool isPacking = parser.isSet(showPackOption);
bool isRIFF = parser.isSet(showRIFFOption);
QString inputFileName = parser.value(sourceVideoFileOption);
QString outputFileName = parser.value(targetVideoFileOption);

bool modeUnpack = true;
if (isPacking) modeUnpack = false;

bool modeRIFF = false;
if (isRIFF) modeRIFF = true;

// Check that both pack and unpack are not set
if (isUnpacking && isPacking) {
// Quit with error
qCritical("Specify only --unpack (-u) or --pack (-p) - not both!");
return -1;
}

// Check that RIFF option is not set with pack (only unpack)
if (isRIFF && ! isUnpacking) {
// Quit with error
qCritical("You can only write RIFF headers with --unpack (-u)");
return -1;
}

// Initialise the data conversion object
DataConverter dataConverter(inputFileName, outputFileName, !modeUnpack);
DataConverter dataConverter(inputFileName, outputFileName, !modeUnpack, modeRIFF);

// Process the data conversion
dataConverter.process();
Expand Down