Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cue render order for ass/ssa. #2137

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

peerless2012
Copy link

This should fix #2124

  • Add layer in cue and output.
  • Add layer support for ssa parser.

@tonihei
Copy link
Collaborator

tonihei commented Feb 21, 2025

@icbaker Could you take a look? Thanks!

* An {@link Ordering} which sorts cues in ascending layer priority
*/
private static final Ordering<Cue> CUES_LAYER_PRIORITY_COMPARATOR =
Ordering.<Integer>natural().onResultOf(c -> c.layer);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic should be part of CUES_DISPLAY_PRIORITY_COMPARATOR rather than a separate Ordering object

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CUES_DISPLAY_PRIORITY_COMPARATOR with CuesWithTiming, but the layer is in Cue, not in CuesWithTiming.

/**
* The layer for cue, the larger cue will render above the smaller cue.
*/
public final int layer;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: TTML (which has a much more robust & unambiguous spec than SSA) uses the name zIndex for this. It seems to have the same "higher index renders above lower index" semantics.

Shall we use that nomenclature here? So Cue.zIndex

We should keep the layer terminology everywhere in the ssa package.

Copy link
Author

@peerless2012 peerless2012 Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with TTML, but I can change the layer to zIndex, if you think it is more stand.

* Gets the layer for this Cue.
*/
@Pure
public @VerticalType int getLayer() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this isn't needed I suggest we remove it

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this isn't needed I suggest we remove it

Yes, I forget to delete the type annotation.

try {
return Integer.parseInt(intString.trim());
} catch (Exception exception) {
return C.LENGTH_UNSET;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should default to 0 here for layer, same as Cue

That probably means you need to either return null here, or take a default value as a parameter, or don't define this general purpose function and just in-line it for the layer case.

I'd suggest in-lining

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseInt is a general method, and I will set layer to 0 when the result is unset in line 333.

@@ -184,7 +185,8 @@ public void draw(
&& this.parentLeft == cueBoxLeft
&& this.parentTop == cueBoxTop
&& this.parentRight == cueBoxRight
&& this.parentBottom == cueBoxBottom) {
&& this.parentBottom == cueBoxBottom
&& this.cueLayer == cue.layer) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you remove this comparison? It seems a bit surprising you need to store cueLayer into a field and then only use it in this comparison. I think all the other fields being compared here are then later used to compute the layout (hence they need to be checked to see if the layout needs to be invalidated).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to your explain, it seems no need to compair the layer.

@@ -68,7 +75,7 @@ public class CuesWithTiming {

/** Creates an instance. */
public CuesWithTiming(List<Cue> cues, long startTimeUs, long durationUs) {
this.cues = ImmutableList.copyOf(cues);
this.cues = ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, cues);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CuesWithTiming.cues has no documented ordering behaviour wrt layout on screen.

CuesGroup.cue does document how ordering affects layout.

Is this reordering needed here? It seems it shouldn't be, since the field has no ordering guarantee. Maybe this should be moved to a point where a CueGroup is being created?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. That's a good way. and it seems there is no need to modify the MergingCuesResolver.

@icbaker icbaker linked an issue Feb 25, 2025 that may be closed by this pull request
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ASS render in a wrong order.
3 participants