Skip to content

Commit

Permalink
Add option to add (very rough) decoding timestamps in stream for bad …
Browse files Browse the repository at this point in the history
…muxers.
  • Loading branch information
cubicibo committed May 19, 2023
1 parent 587d5df commit 4754daf
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 16 deletions.
50 changes: 35 additions & 15 deletions SUPer/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def optimise(self) -> None:
if self.kwargs.pop('adjust_dropframe', False):
if isinstance(bdn.fps, float):
bdn.fps = round(bdn.fps)
logger.info(f"NTSC NDF flag: using {bdn.fps} for timestamps rather than BDNXML {clip_framerate:.03f}.")
logger.info(f"NTSC timing flag: using {bdn.fps} for timestamps rather than BDNXML {clip_framerate:.03f}.")
else:
logger.warning("Ignored NDF flag with integer framerate.")

Expand Down Expand Up @@ -98,28 +98,48 @@ def optimise(self) -> None:
gc.collect()

if clip_framerate != bdn.fps:
adjustment_ratio = bdn.fps/round(clip_framerate, 2)
for epoch in self._epochs:
for ds in epoch:
for seg in ds:
seg.pts = seg.pts*adjustment_ratio - 3/90e3
self.ndf_shift(bdn, clip_framerate)

scaled_fps = False
if self.kwargs.get('scale_fps', False):
from SUPer.utils import BDVideo
I_LUT_PCS_FPS = {v: k for k, v in BDVideo.LUT_PCS_FPS.items()}
if (new_pcs_fps := BDVideo.LUT_PCS_FPS.get(2*I_LUT_PCS_FPS[self._epochs[0].ds[0].pcs.fps.value], None)):
for epoch in self._epochs:
for ds in epoch.ds:
ds.pcs.fps = new_pcs_fps
scaled_fps = True
else:
logger.error(f"Expexcted 25 or 30 fps for 2x scaling. Got '{I_LUT_PCS_FPS[self._epochs[0].ds[0].pcs.fps.value]}'.")
scaled_fps = self.scale_pcsfps()

if self.kwargs.get('enforce_dts', False):
self.compute_set_dts()

# Final check
is_compliant(self._epochs, bdn.fps * int(1+scaled_fps))
####

def ndf_shift(self, bdn: BDNXML, clip_framerate: float) -> None:
adjustment_ratio = bdn.fps/round(clip_framerate, 2)
for epoch in self._epochs:
for ds in epoch:
for seg in ds:
seg.pts = seg.pts*adjustment_ratio - 3/90e3

def scale_pcsfps(self) -> bool:
from SUPer.utils import BDVideo

I_LUT_PCS_FPS = {v: k for k, v in BDVideo.LUT_PCS_FPS.items()}
if (new_pcs_fps := BDVideo.LUT_PCS_FPS.get(2*I_LUT_PCS_FPS[self._epochs[0].ds[0].pcs.fps.value], None)):
for epoch in self._epochs:
for ds in epoch.ds:
ds.pcs.fps = new_pcs_fps
scaled_fps = True
else:
logger.error(f"Expexcted 25 or 30 fps for 2x scaling. Got '{I_LUT_PCS_FPS[self._epochs[0].ds[0].pcs.fps.value]}'.")
return scaled_fps

def compute_set_dts(self) -> None:
logger.warning("Enforcing decoding timestamps. this should not be necessary...")
prev_ds_pts = 0
for epoch in self._epochs:
for ds in epoch:
for seg in ds: #skip END segment
seg.dts = min(max(seg.pts - 0.66, 0), prev_ds_pts)
prev_ds_pts = seg.dts = seg.pts #enforce == for END segment

def merge(self, input_sup) -> None:
epochs = SUPFile(input_sup).epochs()
if not self._epochs:
Expand Down
7 changes: 6 additions & 1 deletion supergui.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def get_kwargs() -> dict[str, int]:
'kmeans_quant': kmeans_quant.value,
'bt_colorspace': colorspace.value,
'pup_compatibility': compat_mode.value,
'enforce_dts': set_dts.value,
}

def wrapper_mp() -> None:
Expand Down Expand Up @@ -195,12 +196,16 @@ def from_bdnxml(queue: ...) -> None:
scale_fps = CheckBox(app, text="Subsampled BDNXML (e.g. 29.97 BDNXML for 59.94 SUP, ignored if 24p)", grid=[0,pos_v:=pos_v+1,2,1], align='left')

compat_mode = CheckBox(app, text="Compatibility mode for software players (see tooltip)", grid=[0,pos_v:=pos_v+1,2,1], align='left')
tooltip = Hovertip(compat_mode.tk, "Software players don't decode palette updates with two objects correctly.\n"\
compat_tooltip = Hovertip(compat_mode.tk, "Software players don't decode palette updates with two objects correctly.\n"\
"If enabled, SUPer insert instructions for the decoder to redraw the graphic plane.\n"\
"I.e, the decoder re-copy existing objects in the buffer to the graphic plane and apply the new palette.\n"\
"However, hardware decoders can only redraw a portion of the graphic plane per frame.\n"\
"Should be unticked for commercial BDs.")

set_dts = CheckBox(app, text="Set rough DTS in stream, shouldn't be used (see tooltip)", grid=[0,pos_v:=pos_v+1,2,1], align='left')
dts_tooltip = Hovertip(set_dts.tk, "Enforcing a DTS can help some (terrible) transport stream muxers.\n"\
"This should never be necessary. Even Scenarist BD apparently set it to zero at all time.")

bspace = Box(app, layout="grid", grid=[0,pos_v:=pos_v+1,2,1])
Text(bspace, "Color space: ", grid=[0,0], align='right')
colorspace = Combo(bspace, options=["bt709", "bt601", "bt2020"], grid=[1,0], align='left')
Expand Down

0 comments on commit 4754daf

Please sign in to comment.