From ebad21823a416b94437cce00434287eeb3337630 Mon Sep 17 00:00:00 2001 From: Setsugennoao Date: Sat, 13 Apr 2024 11:09:16 +0200 Subject: [PATCH] Apply some fixes (#29) * idx->nr try, pad missing audio at start and try fix off by one * drop last field if odd --------- Co-authored-by: jsaowji <39271213+jsaowji@users.noreply.github.com> --- vssource/formats/dvd/IsoFileCore.py | 22 +++++++++++----------- vssource/formats/dvd/title.py | 18 +++++++++++++----- vssource/rff.py | 10 ++++++++-- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/vssource/formats/dvd/IsoFileCore.py b/vssource/formats/dvd/IsoFileCore.py index f27dd0e..dffe589 100644 --- a/vssource/formats/dvd/IsoFileCore.py +++ b/vssource/formats/dvd/IsoFileCore.py @@ -122,29 +122,29 @@ def get_vts(self, title_set_nr: int = 1, d2v_our_rff: bool = False) -> vs.VideoN return apply_rff_video(rawnode, staff.rff, staff.tff, staff.prog, staff.progseq) - def get_title(self, title_idx: int = 1, angle_idx: int | None = None, rff_mode: int = 0) -> Title: + def get_title(self, title_nr: int = 1, angle_nr: int | None = None, rff_mode: int = 0) -> Title: """ Gets a title. - :param title_idx: Title index, 1-index based. - :param angle_idx: Angle index, 1-index based. + :param title_nr: Title index, 1-index based. + :param angle_nr: Angle index, 1-index based. :param rff_mode: 0 Apply rff soft telecine (default); 1 Calculate per frame durations based on rff; 2 Set average fps on global clip; """ - # TODO: assert angle_idx range + # TODO: assert angle_nr range disable_rff = rff_mode >= 1 tt_srpt = self.ifo0.tt_srpt - title_idx -= 1 + title_idx = title_nr - 1 if title_idx < 0 or title_idx >= len(tt_srpt): raise CustomValueError('"title_idx" out of range', self.get_title) tt = tt_srpt[title_idx] - if tt.nr_of_angles != 1 and angle_idx is None: - raise CustomValueError('No angle_idx given for multi angle title', self.get_title) + if tt.nr_of_angles != 1 and angle_nr is None: + raise CustomValueError('No angle_nr given for multi angle title', self.get_title) target_vts = self.vts[tt.title_set_nr - 1] target_title = target_vts.vts_ptt_srpt[tt.vts_ttn - 1] @@ -199,7 +199,7 @@ def get_title(self, title_idx: int = 1, angle_idx: int | None = None, rff_mode: take_cell = True angle_start_cell_i = cell_i else: - take_cell = current_angle == angle_idx + take_cell = current_angle == angle_nr if take_cell: vobidcellids_to_take += [(cell_position.vob_id_nr, cell_position.cell_nr)] @@ -250,7 +250,7 @@ def _apply_timecodes(n: int, f: vs.VideoFrame) -> vs.VideoFrame: absolutetime = absolute_time_from_timecode(timecodes) changes = [ - *(i for i, pvob, nvob in zip(count(1), vobids[:-1], vobids[1:]) if nvob != pvob), len(rnode) - 1 + *(i for i, pvob, nvob in zip(count(1), vobids[:-1], vobids[1:]) if nvob != pvob), len(rnode) ] assert len(changes) == len(is_chapter) @@ -276,7 +276,7 @@ def _apply_timecodes(n: int, f: vs.VideoFrame) -> vs.VideoFrame: if rfps.denominator == 1001: dvnavchapters = [a * 1.001 for a in dvnavchapters] - adjusted = [absolutetime[i] for i in output_chapters] # [1:len(output_chapters)-1] ] + adjusted = [absolutetime[i] if i != len(absolutetime) else absolutetime[i-1] + durationcodes[i-1] for i in output_chapters] # [1:len(output_chapters)-1] ] if len(adjusted) != len(dvnavchapters): warnings.warn( 'dvdnavchapters length do not match our chapters ' @@ -307,7 +307,7 @@ def _apply_timecodes(n: int, f: vs.VideoFrame) -> vs.VideoFrame: # you could either always add the end as chapter or stretch the last chapter till the end output_chapters = [0] + output_chapters - lastframe = len(rnode) - 1 + lastframe = len(rnode) if output_chapters[-1] != lastframe: patched_end_chapter = output_chapters[-1] output_chapters[-1] = lastframe diff --git a/vssource/formats/dvd/title.py b/vssource/formats/dvd/title.py index fbdbc40..cb0e43f 100644 --- a/vssource/formats/dvd/title.py +++ b/vssource/formats/dvd/title.py @@ -115,8 +115,12 @@ def __getitem__(self, key: SupportsIndex | slice) -> vs.AudioNode | list[vs.Audi start, end = int(strt), int(endd) - self.cache[i] = anode = anode[start:len(anode) - end] - + if start >= 0: + anode = anode[start:len(anode) - end] + else: + anode = vs.core.std.BlankAudio(anode,length=-start) + anode[:len(anode) - end] + + self.cache[i] = anode total_dura = (self.title._absolute_time[-1] + self.title._duration_times[-1]) delta = abs(total_dura - anode.num_samples / anode.sample_rate) * 1000 @@ -401,18 +405,22 @@ def _cut_fz_v(title: Title, vnode: vs.VideoNode, f: int, t: int) -> vs.VideoNode f = title.chapters[f] t = title.chapters[t] assert f >= 0 - assert t <= len(vnode) - 1 + assert t <= len(vnode) assert f <= t return vnode[f:t] @staticmethod def _cut_fz_a(title: Title, anode: vs.AudioNode, start: int, end: int) -> vs.AudioNode: chapter_idxs = [title.chapters[i] for i in (start, end)] - timecodes = [title._absolute_time[i] for i in chapter_idxs] + timecodes = [title._absolute_time[i] if i != len(title._absolute_time) else title._absolute_time[i-1] + title._duration_times[i-1] for i in chapter_idxs] samples_start, samples_end, *_ = [ min(round(i * anode.sample_rate), anode.num_samples) for i in timecodes ] - return anode[samples_start:samples_end] + if samples_start == samples_end: + #??????? + return anode.std.BlankAudio(length=1) + else: + return anode[samples_start:samples_end] diff --git a/vssource/rff.py b/vssource/rff.py index 721209e..8b9c4da 100644 --- a/vssource/rff.py +++ b/vssource/rff.py @@ -21,7 +21,10 @@ def apply_rff_array(old_array: Sequence[T], rff: Sequence[int], tff: Sequence[in array_double_rate.extend([arr] * repeat_amount) - assert (len(array_double_rate) % 2) == 0 + #assert (len(array_double_rate) % 2) == 0 + if (len(array_double_rate) % 2) != 0: + warnings.warn(f'uneven amount of fields removing last\n') + array_double_rate = array_double_rate[:-1] for i, f1, f2 in zip(count(), array_double_rate[::2], array_double_rate[1::2]): if f1 != f2: @@ -74,7 +77,10 @@ def apply_rff_video( # TODO: mark known progressive frames as progressive - assert (len(fields) % 2) == 0 + #assert (len(fields) % 2) == 0 + if (len(fields) % 2) != 0: + warnings.warn(f'uneven amount of fields removing last\n') + fields = fields[:-1] for a, tf, bf in zip(count(), fields[::2], fields[1::2]): if tf['tf'] == bf['tf']: