Skip to content

Commit

Permalink
Merge pull request #334 from okorach/hw-accel-on-off-auto
Browse files Browse the repository at this point in the history
Hw-accel-on-off-auto
  • Loading branch information
okorach authored Oct 24, 2021
2 parents 9e078c0 + 79f5cde commit 12161fa
Show file tree
Hide file tree
Showing 19 changed files with 134 additions and 73 deletions.
2 changes: 1 addition & 1 deletion batch-files/1.5mpbs-960.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

setlocal enabledelayedexpansion
for %%F in (%*) do (
video-encode -i "%%~F" -p 2mbps --hw_accel --width 960 --vbitrate 1200k -o "%%~F.1mbps.960x.mp4"
video-encode -i "%%~F" -p 2mbps --width 960 --vbitrate 1200k -o "%%~F.1mbps.960x.mp4"
)

:: "E:\Tools\ffmpeg\bin\ffmpeg.exe" -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -vf scale_cuda=1280:720 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
Expand Down
2 changes: 1 addition & 1 deletion batch-files/1080p 60fps.bat
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
setlocal enabledelayedexpansion

for %%F in (%*) do (
video-encode -i "%%~F" -p 1080p --hw_accel --width 1920 --vbitrate 12000k --fps 60 -o "%%~F.1080p.mp4"
video-encode -i "%%~F" -p 1080p --vcodec x265 --width 1920 --aspec 16:9 --vbitrate 6144k --fps 60 -o "%%~F.1080p.mp4"
)
pause
2 changes: 1 addition & 1 deletion batch-files/1080p rush.bat
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
setlocal enabledelayedexpansion

for %%F in (%*) do (
video-encode --hw_accel -i "%%~F" -p 1080p --width 1920 --vbitrate 12000k -o "%%~F.1080p.mp4"
video-encode -i "%%~F" -p 1080p --width 1920 --vbitrate 12000k -o "%%~F.1080p.mp4"
)
2 changes: 1 addition & 1 deletion batch-files/1080p sliced.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@

set /p timeranges=Time ranges ?

video-encode -i %1 -p 1080p --hw_accel -t %timeranges% --fade 2 --vcodec h264 --acodec aac --vbitrate 4096k --abitrate 128k
video-encode -i %1 -p 1080p -t %timeranges% --fade 2 --vcodec h264 --acodec aac --vbitrate 4096k --abitrate 128k

pause
2 changes: 1 addition & 1 deletion batch-files/1080p_x265.bat
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
setlocal enabledelayedexpansion

for %%F in (%*) do (
video-encode -i "%%~F" --hw_accel -p 1080p --vcodec h265 --width 1920 --vbitrate 6144k -o "%%~F.x265.1080p.mp4"
video-encode -i "%%~F" -p 1080p --vcodec h265 --width 1920 --vbitrate 6144k -o "%%~F.x265.1080p.mp4"
)
2 changes: 1 addition & 1 deletion batch-files/1mpbs-720.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@

setlocal enabledelayedexpansion
for %%F in (%*) do (
video-encode -i "%%~F" -p 2mbps --hw_accel --width 720 --vbitrate 1024k -o "%%~F.1mbps.720x.mp4"
video-encode -i "%%~F" -p 2mbps --hw_accel off --width 720 --vbitrate 1024k -o "%%~F.1mbps.720x.mp4"
)
24 changes: 24 additions & 0 deletions batch-files/300kpbs-480.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
::
:: media-tools
:: Copyright (C) 2019-2021 Olivier Korach
:: mailto:olivier.korach AT gmail DOT com
::
:: This program is free software; you can redistribute it and/or
:: modify it under the terms of the GNU Lesser General Public
:: License as published by the Free Software Foundation; either
:: version 3 of the License, or (at your option) any later version.
::
:: This program is distributed in the hope that it will be useful,
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
:: Lesser General Public License for more details.
::
:: You should have received a copy of the GNU Lesser General Public License
:: along with this program; if not, write to the Free Software Foundation,
:: Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
::

setlocal enabledelayedexpansion
for %%F in (%*) do (
video-encode -i "%%~F" -p 2mbps --hw_accel off --width 480 --vbitrate 300k -o "%%~F.1mbps.480x.mp4"
)
2 changes: 1 addition & 1 deletion batch-files/3mbps-1280.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@

setlocal enabledelayedexpansion
for %%F in (%*) do (
video-encode -i "%%~F" --hw_accel -p 2mbps --width 1280 --vbitrate 3072k --vcodec h265 --abitrate 128k --acodec aac -o "%%~F.3mbps.1280x.mp4"
video-encode -i "%%~F" -p 2mbps --width 1280 --vbitrate 3072k --vcodec h265 --abitrate 128k --acodec aac -o "%%~F.3mbps.1280x.mp4"
)
pause
2 changes: 1 addition & 1 deletion batch-files/4mbps-1280.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@

setlocal enabledelayedexpansion
for %%F in (%*) do (
video-encode --hw_accel -i "%%~F" -p 2mbps --vbitrate 4096k --width 1280 -o "%%~F.4mbps.1280x.mp4"
video-encode -i "%%~F" -p 2mbps --vbitrate 4096k --width 1280 -o "%%~F.4mbps.1280x.mp4"
)
2 changes: 1 addition & 1 deletion batch-files/720p2m sliced.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@

set /p timeranges=Time ranges ?

video-encode -i %1 -p 720p2m --hw_accel 4 -t %timeranges% --fade 2
video-encode -i %1 -p 720p2m 4 -t %timeranges% --fade 2

pause
2 changes: 1 addition & 1 deletion batch-files/720p_x265.bat
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@

setlocal enabledelayedexpansion
for %%F in (%*) do (
video-encode --hw_accel -i "%%~F" -p 720p_x265 --vbitrate 3072k --width 1280 -o "%%~F.x265.720p.mp4"
video-encode -i "%%~F" -p 720p_x265 --vbitrate 3072k --width 1280 -o "%%~F.x265.720p.mp4"
)
2 changes: 1 addition & 1 deletion batch-files/actioncam.bat
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
:: Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
::

video-encode -i %1 --hw_accel -p 100fps
video-encode -i %1 -p 100fps

pause
3 changes: 3 additions & 0 deletions mediatools/media-tools.properties
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ default.video.aspect = 16:9
default.video.resolution = 1920x1080
default.video.bitrate = 6144k

# Possible values: auto, on, off
default.hw_accel = auto

default.audio.channels = 2
default.audio.samplerate = 44100
default.audio.codec = aac
Expand Down
53 changes: 52 additions & 1 deletion mediatools/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

DEBUG_LEVEL = 0
DRY_RUN = False
HW_ACCEL = None
HW_ACCEL_PREFIX = "-hwaccel cuda -hwaccel_output_format cuda"

LANGUAGE_MAPPING = {'fre': 'French', 'eng': 'English'}

Expand Down Expand Up @@ -148,7 +150,7 @@ def run_os_cmd(cmd, total_time=None):
line = pipe.stdout.readline().rstrip()
outs, errs = pipe.communicate()
log.logger.debug("Return code = %d", pipe.returncode)
if pipe.returncode != 0:
if pipe.returncode not in (0, 3221225477): # TODO: Better than this ugly hack for ffmpeg
last_error_line = line if last_error_line is None else last_error_line
raise subprocess.CalledProcessError(cmd=cmd, output=last_error_line, returncode=pipe.returncode)
log.logger.info("Successfully completed: %s", cmd)
Expand Down Expand Up @@ -280,6 +282,18 @@ def parse_media_args(parser, args=None):
(kwargs[opt.Option.WIDTH], kwargs[opt.Option.HEIGHT]) = resolve_resolution(**kwargs)
if kwargs.get('timeranges', None) is not None:
kwargs[opt.Option.START], kwargs[opt.Option.STOP] = kwargs['timeranges'].split(',')[0].split('-')
if kwargs.get('hw_accel', None) is None:
kwargs['hw_accel'] = conf.get_property('default.hw_accel')
if kwargs.get('hw_accel', None) is None:
kwargs['hw_accel'] = 'auto'

if kwargs.get('hw_accel', None) == 'on':
kwargs['hw_accel'] = True
elif kwargs.get('hw_accel', None) == 'off':
kwargs['hw_accel'] = False
else:
kwargs['hw_accel'] = use_hardware_accel(**kwargs)
kwargs = remove_nones(kwargs)
log.logger.debug('KW=%s', str(kwargs))
return kwargs

Expand Down Expand Up @@ -468,3 +482,40 @@ def resolve_resolution(**kwargs):
w = int(w) if w != '' else -1
h = int(h) if h != '' else -1
return (w, h)


def use_hardware_accel(**kwargs):
global HW_ACCEL
my_hw_accel = kwargs.get('hw_accel', 'auto')
log.logger.debug("my hw accel = %s", str(my_hw_accel))
if (isinstance(my_hw_accel, bool) and my_hw_accel) or my_hw_accel == 'on':
HW_ACCEL = True
log.logger.info("Hardware acceleration explicitly forced on")
return True
elif (isinstance(my_hw_accel, bool) and not my_hw_accel) or my_hw_accel == 'off':
HW_ACCEL = False
log.logger.info("Hardware acceleration explicitly turned off")
return False

if kwargs.get(opt.Option.DEINTERLACE, False):
# Deinterlacing is incompatible with HW accel
log.logger.info("Turning off hardware acceleration because of deinterlace")
HW_ACCEL = False
if my_hw_accel != 'auto':
HW_ACCEL = False
if HW_ACCEL is not None:
return HW_ACCEL

# Auto mode, test execution with HW acceleration
log.logger.info("Checking if hardware acceleration can be used")
outputfile = get_tmp_file() + '.mp4'
inputfile = str(package_home() / 'video-720p.mp4')
try:
log.logger.debug("Trying to encode 1 second of %s", inputfile)
run_ffmpeg(f'{HW_ACCEL_PREFIX} -ss 0 -i "{inputfile}" -vf scale_cuda=640:-1 -c:a copy -c:v h264_nvenc -to 2 "{outputfile}"')
os.remove(outputfile)
HW_ACCEL = True
except subprocess.CalledProcessError:
HW_ACCEL = False
log.logger.info("Auto hardware acceleration = %s", str(HW_ACCEL))
return HW_ACCEL
2 changes: 1 addition & 1 deletion mediatools/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

MEDIA_TOOLS_VERSION = '0.21'
MEDIA_TOOLS_VERSION = '0.22'
49 changes: 6 additions & 43 deletions mediatools/videofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@

from __future__ import print_function
import re
import os
import subprocess
from mediatools import log
import mediatools.exceptions as ex
import mediatools.resolution as res
Expand All @@ -37,8 +35,6 @@
import mediatools.media_config as conf

FFMPEG_CLASSIC_FMT = '-i "{0}" {1} "{2}"'
HW_ACCEL = None
HW_ACCEL_PREFIX = "-hwaccel cuda -hwaccel_output_format cuda"

class VideoFile(media.MediaFile):
AV_PASSTHROUGH = '-{0} copy -{1} copy -map 0 '.format(opt.OptionFfmpeg.VCODEC, opt.OptionFfmpeg.ACODEC)
Expand Down Expand Up @@ -419,7 +415,7 @@ def __get_video_filters__(self, **kwargs):
vfilters.append(filters.fade_in(start=util.to_seconds(kwargs.get(opt.Option.START, 0)), duration=0.5))
vfilters.append(filters.fade_out(
start=util.to_seconds(kwargs.get(opt.Option.STOP, self.duration)) - 0.5, duration=0.5))
if use_hardware_accel(**kwargs) and kwargs.get(opt.Option.RESOLUTION, None) is not None:
if util.use_hardware_accel(**kwargs) and kwargs.get(opt.Option.RESOLUTION, None) is not None:
vfilters.append(f'scale_cuda={kwargs[opt.Option.WIDTH]}:{kwargs[opt.Option.HEIGHT]}')
log.logger.debug('vfilters = %s', str(vfilters))
return vfilters
Expand All @@ -428,8 +424,8 @@ def __get_input_settings__(self, **kwargs):
log.logger.debug('Input options = %s', str(kwargs))
settings = []
if __must_encode_video__(**kwargs):
if use_hardware_accel(**kwargs):
settings.append(HW_ACCEL_PREFIX)
if util.use_hardware_accel(**kwargs):
settings.append(util.HW_ACCEL_PREFIX)
else:
if opt.Option.START in kwargs and kwargs[opt.Option.START] != '':
settings.append(opt.OPT_FMT.format(opt.OptionFfmpeg.START, kwargs[opt.Option.START]))
Expand All @@ -447,7 +443,7 @@ def __get_output_settings__(self, **kwargs):

settings.append(__get_vcodec__(**kwargs))

if kwargs.get(opt.Option.RESOLUTION, None) is not None and not use_hardware_accel(**kwargs):
if kwargs.get(opt.Option.RESOLUTION, None) is not None and not util.use_hardware_accel(**kwargs):
settings.append(opt.OPT_FMT.format(opt.OptionFfmpeg.RESOLUTION, kwargs[opt.Option.RESOLUTION]))

if kwargs.get(opt.Option.VBITRATE, None) is not None:
Expand All @@ -470,7 +466,6 @@ def __get_output_settings__(self, **kwargs):
if kwargs.get(opt.Option.ABITRATE, None) is not None:
settings.append(opt.OPT_FMT.format(opt.OptionFfmpeg.ABITRATE, kwargs[opt.Option.ABITRATE]))


if __must_encode_video__(**kwargs):
if kwargs.get(opt.Option.START, '') != '':
settings.append(opt.OPT_FMT.format(opt.OptionFfmpeg.START, kwargs[opt.Option.START]))
Expand All @@ -487,7 +482,7 @@ def __get_output_settings__(self, **kwargs):
def __get_vcodec__(**kwargs):
if __must_encode_video__(**kwargs):
vcodec = kwargs.get(opt.Option.VCODEC, conf.get_property('default.video.codec'))
if use_hardware_accel(**kwargs):
if util.use_hardware_accel(**kwargs):
vcodec = opt.HW_ACCEL_CODECS[vcodec]
else:
vcodec = opt.CODECS[vcodec]
Expand Down Expand Up @@ -622,7 +617,7 @@ def add_video_args(parser):
parser.add_argument('--' + opt.Option.VCODEC, required=False, help='Video codec (h264, h265, mpeg2, xvid...)')
parser.add_argument('--' + opt.Option.ACODEC, required=False, help='Audio codec (mp3, aac, ac3...)')

parser.add_argument('--hw_accel', required=False, default=None, dest='hw_accel', action='store_true',
parser.add_argument('--hw_accel', required=False, choices=['auto', 'off', 'on'],
help='Use Nvidia HW acceleration')

parser.add_argument('--' + opt.Option.VBITRATE, required=False, help='Video bitrate eg 1024k')
Expand Down Expand Up @@ -803,35 +798,3 @@ def cut(filename, output=None, start=None, stop=None, timeranges=None, **kwargs)
stop = file_object.duration
output = util.automatic_output_file_name(outfile=output, infile=filename, postfix='cut')
return file_object.encode(target_file=output, start=start, stop=stop, **kwargs)


def use_hardware_accel(**kwargs):
global HW_ACCEL
if 'hw_accel' in kwargs:
if kwargs['hw_accel']:
log.logger.info("Hardware acceleration explicitly forced on")
return True
elif not kwargs['hw_accel']:
log.logger.info("Hardware acceleration explicitly turned off")
return False
elif kwargs.get(opt.Option.DEINTERLACE, False):
# Deinterlacing is incompatible with HW accel
log.logger.info("Turning off hardware acceleration because of deinterlace")
HW_ACCEL = False
if HW_ACCEL is not None:
return HW_ACCEL

if HW_ACCEL is None:
log.logger.info("Checking if hardware acceleration can be used")
outputfile = util.get_tmp_file() + '.mp4'
inputfile = VideoFile(str(util.package_home() / 'video-720p.mp4'))
try:
log.logger.debug("Trying to encode 1 second of %s", inputfile)
util.run_ffmpeg(f'{HW_ACCEL_PREFIX} -i "{inputfile}" -vf scale_cuda=640:-1 -c:a copy -c:v h264_nvenc "{outputfile}"',
inputfile.duration)
os.remove(outputfile)
HW_ACCEL = True
except subprocess.CalledProcessError:
HW_ACCEL = False
log.logger.info("Hardware acceleration = %s", str(HW_ACCEL))
return HW_ACCEL
2 changes: 1 addition & 1 deletion tests/test_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@


def test_main_with_output():
video.HW_ACCEL = False
util.HW_ACCEL = False
v1 = video.VideoFile(VIDEO1).encode(profile='360p', target_file=TMP1)
v2 = video.VideoFile(VIDEO2).encode(profile='360p', target_file=TMP2)
with patch.object(sys, 'argv', [CMD, '-g', '3', '-i', v1, v2, '-o', TMP3]):
Expand Down
Loading

0 comments on commit 12161fa

Please sign in to comment.