Skip to content

Commit

Permalink
Bus fixes
Browse files Browse the repository at this point in the history
some minor bug fixes
  • Loading branch information
GeoHaber committed Aug 26, 2024
1 parent 60600e2 commit d82800e
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 43 deletions.
97 changes: 65 additions & 32 deletions FFMpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ def ffmpeg_run(input_file: str, ff_com: list, skip_it: bool, execu: str = "ffmpe
"-movflags", "+faststart", # Place moov atom at the beginning for fast start
"-fflags", "+fastseek", # Enable fast seeking
"-fflags", "+genpts", # Generate presentation timestamps
# "-level:v", "4.1", # Set the level for better compatibility
"-keyint_min", "30", # Minimum interval between keyframes
"-g", "60", # Set the GOP (Group of Pictures) size
"-y", out_file,
Expand Down Expand Up @@ -209,9 +208,8 @@ def run_ffm(args, de_bug=False):
return False

except Exception as e:
msj += f" Exception: {e}"
print(f"{msj} Exception: {e}\n{args}\n")
return False
print( msj )

return True
##==============------------------- End -------------------==============##
Expand Down Expand Up @@ -400,29 +398,66 @@ def add_subtl_from_file(input_file: str, de_bug: bool) -> tuple[list, bool]:
if de_bug:
print(" |No External Sub File |")
return [], True

##>>============-------------------< End >------------------==============<<##


# Define a helper function to select the appropriate encoder and options
def get_encoder_options(codec_name, src_pix_fmt, use_hw_accel):
hw_pix_fmt = "p010le" if src_pix_fmt.endswith("10le") else "nv12"
def get_encoder_options(codec_name, src_pix_fmt, use_hw_accel=False):
msj = sys._getframe().f_code.co_name
# Determine if the source is 10-bit
is_10bit = src_pix_fmt.endswith("10le")
# Set base values
target_quality='high'
quality_presets = {
'low': {'bitrate': 2000, 'quality': 26},
'medium': {'bitrate': 3000, 'quality': 24},
'high': {'bitrate': 4000, 'quality': 22},
'higher': {'bitrate': 5000, 'quality': 18},
}
preset = quality_presets[target_quality]
base_target_bitrate = preset['bitrate']
global_quality = preset['quality']
# Adjust for 10-bit content
if is_10bit:
target_bitrate = str(int(base_target_bitrate * 1.25)) + 'k'
else:
target_bitrate = str(base_target_bitrate) + 'k'
# Calculate max_bitrate and bufsize
max_bitrate = str(int(int(target_bitrate.rstrip('k')) * 1.5)) + 'k'
bufsize = str(int(int(max_bitrate.rstrip('k')) * 2)) + 'k'
if use_hw_accel:
# Use hevc_qsv (HEVC) encoder with QSV options
return ['hevc_qsv', '-load_plugin', 'hevc_hw',
'-init_hw_device', 'qsv=qsv:MFX_IMPL_hw_any',
'-filter_hw_device', 'qsv',
'-pix_fmt', hw_pix_fmt,
'-look_ahead', '1', # Enable lookahead
'-look_ahead_depth', '50', # Set lookahead depth to ? 40 frames
'-global_quality', '22', # Use global_quality instead of CRF for QSV
'-preset', 'slower'] # Encoder preset
print(f" {msj} HW accelerated")
hw_pix_fmt = "p010le" if is_10bit else "nv12"
return [
'hevc_qsv',
'-load_plugin', 'hevc_hw',
'-init_hw_device', 'qsv=qsv:MFX_IMPL_hw_any',
'-filter_hw_device', 'qsv',
'-pix_fmt', hw_pix_fmt,
'-b:v', target_bitrate,
'-maxrate', max_bitrate,
'-bufsize', bufsize,
'-look_ahead', '1',
'-look_ahead_depth', '90',
'-global_quality', str(round(global_quality)),
'-rc:v', 'vbr_la', # Use variable bitrate with lookahead
'-preset', 'slow',
]
else:
# Use libx265 (HEVC) or libx264 (H.264) encoder with software options and 10Bit
return ['libx265', '-pix_fmt', 'yuv420p10le', '-crf', '22', '-preset', 'slow']
# return ['libx265', '-pix_fmt', src_pix_fmt, '-crf', '22', '-preset', 'slow']
print(f" {msj} SW")
sw_pix_fmt = "yuv420p10le" if is_10bit else "yuv420p"
return [
'libx265',
'-x265-params', 'bframes=8:psy-rd=1:aq-mode=3:aq-strength=0.8:deblock=1,1',
'-pix_fmt', sw_pix_fmt,
'-crf', str(round(global_quality)),
'-b:v', target_bitrate,
'-maxrate', max_bitrate,
'-bufsize', bufsize,
'-preset', 'slow',
]
##>>============-------------------< End >------------------==============<<##


@perf_monitor
def parse_video(strm_in, de_bug=False, use_hw_accel=True ):
''' Parse and extract data from video streams '''
Expand Down Expand Up @@ -471,15 +506,11 @@ def parse_video(strm_in, de_bug=False, use_hw_accel=True ):
# XXX: Estimate Average bits_per_pixel
glb_totfrms = round(frm_rate * glb_vidolen)

avbpp = round (100000 * _vi_btrt / (glb_totfrms * vid_width * vid_heigh) +1)

max_vid_btrt = 4700000
max_vid_btrt = 5000000

msj = " 8"

if pix_fmt.endswith("10le") :
msj = "10"
avbpp *= 1.25
max_vid_btrt *= 1.25

mins, secs = divmod(glb_vidolen, 60)
Expand All @@ -497,13 +528,13 @@ def parse_video(strm_in, de_bug=False, use_hw_accel=True ):
ff_vid = ['-map', f'0:v:{indx}', f'-c:v:{indx}']
# Determine if codec copy or conversion is needed, and update ff_vid accordingly
if codec_name == 'hevc':
if avbpp < 80 and _vi_btrt < max_vid_btrt :
if _vi_btrt < max_vid_btrt :
extra += ' => Copy'
ff_vid.extend(['copy'])
skip_it = True
else:
extra += f' Reduce BitRate: {hm_sz(max_vid_btrt):>6} '
encoder_options = get_encoder_options(codec_name, this_vid['pix_fmt'], use_hw_accel)
encoder_options = get_encoder_options(codec_name, this_vid['pix_fmt'], use_hw_accel )
ff_vid.extend(encoder_options)
else:
extra += ' => Convert to Hevc'
Expand All @@ -525,11 +556,13 @@ def parse_video(strm_in, de_bug=False, use_hw_accel=True ):
nw = 1920
nh = round( (nw / vid_width) * vid_heigh / 2) * 2 # Ensure nh is always even
ff_vid = [
'-map', f'0:v:{indx}',
f'-c:v:{indx}', 'libx265', # Specify the H.265 codec here
'-pix_fmt', f"{this_vid['pix_fmt']}",
'-crf', '22','-preset', 'slow',
'-vf', f'scale={nw}:{nh}',
'-map', f'0:v:{indx}',
f'-c:v:{indx}', 'libx265', # Specify H.265 codec here
'-vf', f'scale={nw}:{nh}',
'-pix_fmt', "yuv420p10le",
'-crf', '22',
'-b:v', "3500k",
'-preset', 'slow',
]
extra = f' {output} Scale {vid_width}x{vid_heigh} to {nw}x{nh}'
skip_it = False
Expand All @@ -541,7 +574,7 @@ def parse_video(strm_in, de_bug=False, use_hw_accel=True ):
ff_vid.extend([f"-metadata:s:v:{indx}", "handler_name=VideoHandler x265"])
skip_it = False

message = f" |<V:{indx:2}>|{codec_name:^8}|{vid_width:<4}x{vid_heigh:<4}|{aspct_r}|Bit: {msj}|Btrt: {hm_sz(_vi_btrt):>6}|Avbpp: {avbpp:>3}|Fps: {frm_rate:>7}|Tfm: {hm_sz(glb_totfrms,'F'):>8}|{extra}|"
message = f" |<V:{indx:2}>|{codec_name:^8}|{vid_width:<4}x{vid_heigh:<4}|{aspct_r}|Bit: {msj}|Btrt: {hm_sz(_vi_btrt):>6}|Fps: {frm_rate:>7}|Tfm: {hm_sz(glb_totfrms,'F'):>8}|{extra}|"
print(f"\033[91m{message}\033[0m")

ff_video += ff_vid
Expand Down
34 changes: 30 additions & 4 deletions My_Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,19 +290,45 @@ def __init__(self, spin_text="|/-o+\\", indent=0):
self.spin_text = spin_text
self.spin_length = len(spin_text)
self.prefix = " " * indent # Indentation string

self.last_message_length = 0 # To keep track of the length of the last printed message
self.cursor_hidden = False

def hide_cursor(self):
if not self.cursor_hidden:
sys.stderr.write("\033[?25l") # Hide cursor
sys.stderr.flush()
self.cursor_hidden = True
def show_cursor(self):
if self.cursor_hidden:
sys.stderr.write("\033[?25h") # Show cursor
sys.stderr.flush()
self.cursor_hidden = False
def print_spin(self, extra: str = "") -> None:
"""
Prints a spinner in the console to indicate progress.
Args:
extra (str): Additional text to display after the spinner.
"""
self.hide_cursor()
terminal_width = shutil.get_terminal_size().columns
spin_char = self.spin_text[self.spinner_count % self.spin_length]
sys.stderr.write(f"\r{self.prefix}| {spin_char} | {extra}")
message = f"\r{self.prefix}| {spin_char} | {extra}"
if len(message) > terminal_width:
message = message[:terminal_width - 1] # Truncate to fit the terminal width
clear_spaces = max(self.last_message_length - len(message), 0)
sys.stderr.write(f"{message}{' ' * clear_spaces}")
sys.stderr.flush()
self.last_message_length = len(message)
self.spinner_count += 1

def stop(self):
"""
Stops the spinner and shows the cursor.
"""
self.show_cursor()
sys.stderr.write("\n") # Move to the next line after stopping
sys.stderr.flush()
'''
# Example usage:
if __name__ == "__main__":
Expand All @@ -311,13 +337,13 @@ def print_spin(self, extra: str = "") -> None:
spinner_with_indent = Spinner(indent=4)
for _ in range(100): # Simulate a task with 10 iterations
spinner_no_indent.print_spinner(f" {_} Processing without indent...")
spinner_no_indent.print_spin(f" {_} Processing without indent...")
time.sleep(0.1) # Simulate work being done
print("\n")
for _ in range(100): # Simulate a task with 10 iterations
spinner_with_indent.print_spinner(f" {_} Processing with indent...")
spinner_with_indent.print_spin(f" {_} Processing with indent...")
time.sleep(0.1) # Simulate work being done
print("\nTask completed!")
Expand Down
13 changes: 6 additions & 7 deletions Trans_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def scan_folder(root: str, xtnsio: List[str], sort_order: bool, do_clustering: b
str_t = time.perf_counter()
msj = f"{sys._getframe().f_code.co_name} Start: {time.strftime('%H:%M:%S')}"
print(f"Scan: {root}\tSize: {hm_sz(get_tree_size(root))}\n{msj}")
spinner = Spinner(indent=0)

# Ensure xtnsio is a tuple
# if isinstance(xtnsio, str):
Expand Down Expand Up @@ -257,8 +258,9 @@ def process_files(executor=None):
print(f"Skipping inaccessible file: {f_path}")
continue

_, ext = os.path.splitext(one_file.lower())
if ext in xtnsio:
_, ext = os.path.splitext(one_file)
if ext.lower() in xtnsio:
spinner.print_spin(f" {one_file} ")
try:
file_s = os.path.getsize(f_path)
if not os.access(f_path, os.W_OK) or not (os.stat(f_path).st_mode & stat.S_IWUSR):
Expand Down Expand Up @@ -302,8 +304,6 @@ def handle_result(result):
else:
process_files()

end_t = time.perf_counter()
print(f" Scan Done : {time.strftime('%H:%M:%S')}\tTotal: {hm_time(end_t - str_t)}")

if do_clustering:
print(f" Start Clustering : {time.strftime('%H:%M:%S')}")
Expand All @@ -312,11 +312,10 @@ def handle_result(result):
data.append([file_s, duration])
perform_clustering(data, _lst)

order = "Descending >" if sort_order else "Ascending <"
end_t = time.perf_counter()
print(f"\n Scan: Done : {time.strftime('%H:%M:%S')}\tTotal: {hm_time(end_t - str_t)}")
print(f"\n Sort: {order}\n Scan: Done : {time.strftime('%H:%M:%S')}\tTotal: {hm_time(end_t - str_t)}\n")

order = "Descending >" if sort_order else "Ascending <"
print(f" Sort: {order}")

return sorted(_lst, key=lambda item: item[1], reverse=sort_order)

Expand Down

0 comments on commit d82800e

Please sign in to comment.