Initial multi core encoding support

This commit is contained in:
Bas Stottelaar
2014-02-23 20:13:19 +01:00
parent f0b4f2f3c8
commit 1c3132b3aa
2 changed files with 46 additions and 5 deletions

View File

@@ -218,6 +218,8 @@ ENCODEROUTPUTFORMAT = None
ENCODERQUALITY = None
ENCODERVBRCBR = None
ENCODERLOSSLESS = False
ENCODER_MULTICORE = False
ENCODER_MULTICORE_COUNT = 0
DELETE_LOSSLESS_FILES = False
PROWL_ENABLED = True
PROWL_PRIORITY = 1
@@ -337,7 +339,7 @@ def initialize():
NZBSORG, NZBSORG_UID, NZBSORG_HASH, NZBSRUS, NZBSRUS_UID, NZBSRUS_APIKEY, OMGWTFNZBS, OMGWTFNZBS_UID, OMGWTFNZBS_APIKEY, \
NZB_DOWNLOADER, TORRENT_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, LASTFM_USERNAME, \
INTERFACE, FOLDER_PERMISSIONS, FILE_PERMISSIONS, ENCODERFOLDER, ENCODER_PATH, ENCODER, XLDPROFILE, BITRATE, SAMPLINGFREQUENCY, \
MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, ENCODERLOSSLESS, DELETE_LOSSLESS_FILES, \
MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, ENCODERLOSSLESS, ENCODER_MULTICORE, ENCODER_MULTICORE_COUNT, DELETE_LOSSLESS_FILES, \
PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, PUSHOVER_ENABLED, PUSHOVER_PRIORITY, PUSHOVER_KEYS, PUSHOVER_ONSNATCH, MIRRORLIST, \
TWITTER_ENABLED, TWITTER_ONSNATCH, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \
PUSHBULLET_ENABLED, PUSHBULLET_APIKEY, PUSHBULLET_DEVICEID, PUSHBULLET_ONSNATCH, \
@@ -534,6 +536,8 @@ def initialize():
ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr', 'cbr')
ENCODERLOSSLESS = bool(check_setting_int(CFG, 'General', 'encoderlossless', 1))
ENCODER_MULTICORE = bool(check_setting_int(CFG, 'General', 'encoder_multicore', 0))
ENCODER_MULTICORE_COUNT = max(0, check_setting_int(CFG, 'General', 'encoder_multicore_count', 0))
DELETE_LOSSLESS_FILES = bool(check_setting_int(CFG, 'General', 'delete_lossless_files', 1))
PROWL_ENABLED = bool(check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0))
@@ -1006,6 +1010,8 @@ def config_write():
new_config['General']['encoderquality'] = ENCODERQUALITY
new_config['General']['encodervbrcbr'] = ENCODERVBRCBR
new_config['General']['encoderlossless'] = int(ENCODERLOSSLESS)
new_config['General']['encoder_multicore'] = int(ENCODER_MULTICORE)
new_config['General']['encoder_multicore_count'] = int(ENCODER_MULTICORE_COUNT)
new_config['General']['delete_lossless_files'] = int(DELETE_LOSSLESS_FILES)
new_config['General']['mirror'] = MIRROR

View File

@@ -17,6 +17,7 @@ import os
import headphones
import shutil
import time
import multiprocessing
import subprocess
from headphones import logger
@@ -100,6 +101,7 @@ def encode(albumPath):
i=0
encoder_failed = False
jobs = []
for music in musicFiles:
infoMusic=MediaFile(music)
@@ -131,15 +133,45 @@ def encode(albumPath):
encode = True
# encode
if encode:
if not command(encoder,music,musicTempFiles[i],albumPath):
encoder_failed = True
break
job = (encoder, music, musicTempFiles[i], albumPath)
jobs.append(job)
else:
musicFiles[i] = None
musicTempFiles[i] = None
i=i+1
# Encode music files
if len(jobs) > 0:
if headphones.ENCODER_MULTICORE:
if headphones.ENCODER_MULTICORE_COUNT == 0:
processes = multiprocessing.cpu_count()
else:
processes = headphones.ENCODER_MULTICORE_COUNT
logger.debug("Multi-core encoding enabled, %d processes" % processes)
else:
processes = 1
# Use multiprocessing only if it's worth the overhead. and if it is
# enabled. If not, then use the old fashioned way.
if processes > 1:
pool = multiprocessing.Pool(processes=processes)
results = pool.map_async(command_map, jobs)
# No new processes will be created, so close it and wait for all
# processes to finish
pool.close()
pool.join()
# Retrieve the results
results = results.get()
else:
results = map(command_map, jobs)
# The results are either True or False, so determine if one is False
encoder_failed = not all(results)
musicFiles = filter(None, musicFiles)
musicTempFiles = filter(None, musicTempFiles)
@@ -187,7 +219,10 @@ def encode(albumPath):
logger.info('Encoding for folder %s is not required' % (albumPath.decode(headphones.SYS_ENCODING, 'replace')))
return musicFinalFiles
def command_map(args):
return command(*args)
def command(encoder,musicSource,musicDest,albumPath):
cmd=[]