Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
14th February 2023, 04:00 | #1 | Link |
hlg-tools Maintainer
Join Date: Feb 2008
Posts: 420
|
PGS: Referencing Objects Outside the DisplaySet?
I've done piles of Blu-ray discs with my Rust PGS implementation. But it crashed on Star Trek VI 4K:
"Object referenced by composition not found." This happens when a composition object inside of the PCS references an object not defined within the display set. Now in the movie, it manifests as two captions being visible at the same time. Does anyone who actually knows PGS know if this is a bitstream error on the part of the movie, or if this is actually a thing that PGS does? I'm assuming the object is elsewhere within the epoch... I'd rant about how brain-deficient this format is, but I'm just way too tired right now... EDIT: I'm going to go buy ice cream, root beer, and make a float. Last edited by wswartzendruber; 14th February 2023 at 04:08. |
16th February 2023, 00:26 | #2 | Link |
Registered User
Join Date: Feb 2022
Posts: 125
|
If the PCS of the display set is a normal case, it should be able to use the content in the object buffer defined in previous display sets. Up to the latest acquisition or epoch start.
First time I hear about a PGS being like this. Probably yet another poor engineer that was requested to implement PGS from bad specs and had to experiment, like Avatar 3D subs. Anyhow now you know the right way to flicker a subtitle with PGS. Simply set/unset the composition object in a normal case PCS every other frame :^) |
18th February 2023, 16:25 | #6 | Link |
Registered User
Join Date: Feb 2022
Posts: 125
|
That's the standard way to display two (not synced) objects within an epoch and then undisplaying one after the other.
DS#1 (Epoch start): "Don't catch any bugs!" (Object#0), PDS#0 DS#2 (Normal case): "[laughing]" (Object#1) is displayed along Object#0 using PDS#0 DS#3 (Normal case): Undisplay Object#1 DS#4 (Normal case): Undisplay everything (empty composition list - end of epoch) This would not work if DS#2 was an acquisition point or if there were a third object. The other way is to perform epoch acquisitions. It is easier to follow what's going on on screen using the stream but much more intensive on the hardware decoder: DS#1 (Epoch start): Object#0, PDS#0 DS#2 (Acquisition): Object #0, Object#1, PDS#0 (Object#0 and PDS#0 lost due to acquisition, have to be redefined) DS#3 (Normal case): Undisplay Object#1 <- you can also do an acquisition here where you define again only Object#0 and the second window has no composition. DS#4 (Normal case): Undisplay everything (empty composition list - end of epoch) Also this is the preferred solution when you have complex epochs with many subtitles so you're sure the buffer is flushed frequently. |
20th February 2023, 16:14 | #7 | Link |
hlg-tools Maintainer
Join Date: Feb 2008
Posts: 420
|
I think my Rust implementation is going to continue as-is, at least for now. It's been made under the assumption that PGS has clean abstraction, in other words, that display sets are self-contained (each PCS doesn't reference anything outside of the display set). At this point, I don't even trust epochs to be self-contained (something might not get undisplayed before the next EpochStart).
I've begun work on a .NET Standard 2.0 library. It already handles segments. But in order for the library to be useful, it will need to be intuitive to use. I am thinking of having an event-driven playback mechanic wherein events are executed such as ObjectDisplayed and ObjectRemoved, as well as things like ObjectChanged. PTS and DTS values would be passed by reference and could be modified here, if desired, along with the objects themselves |
9th March 2024, 22:21 | #11 | Link |
Registered User
Join Date: Feb 2022
Posts: 125
|
It is always useful to have the decoder model in mind:
The graphics plane is just a 2 MiB 2D buffer where the uncompressed ODS are copied, as instructed by the composition objects. Then, the 8-bit value of each graphics plane pixel is evaluated in the CLUT block, to fetch the associated palette entry. The CLUT block essentially transforms a WxH array to WxHx4. There is no additional mapping related to object ID, or regioning that maps to one palette or the other in the CLUT block. In short, the objects always share a common palette. This can be annoying when your stream uses Normal Cases to define an object to accompany an already buffered and displayed one: both objects have to be quantized together, despite them being (partially) independant. Interactive Graphics Stream permits to associate a specific palette to a given object, but the rendering process is different and much slower. Last edited by cubicibo; 9th March 2024 at 22:29. |
10th March 2024, 01:32 | #12 | Link |
hlg-tools Maintainer
Join Date: Feb 2008
Posts: 420
|
Thank you, as always. You have yet to post an answer that doesn't make things clearer. I am grateful and my project only benefits.
What is the purpose of CompositionObjects and Windows each being able to declare X and Y values? I see that they typically match, but what if they do not? |
10th March 2024, 10:53 | #13 | Link |
Registered User
Join Date: Feb 2022
Posts: 125
|
Once you have performed an epoch start (= wiped out the graphic plane according to PCS width and height fields), the graphics controller should only have to re-render the active area: the windows.
Writing 1920x1080 pixels requires ~65 miliseconds at 256 Mbps, or 2-3 frames at 23.976 or 29.97. If you want to achieve frame-by-frame effects, with the decoding overhead, you need to convey the relevant screen area of the overlaying process. Composition Objects are also not necessarily the same size. How would you define the area you have to erase? This is why changing windows is forbidden. Some decoders would not erase the graphics plane consistently and left-overs would be displayed. Last edited by cubicibo; 10th March 2024 at 12:32. |
23rd June 2024, 14:32 | #15 | Link |
Registered User
Join Date: Feb 2022
Posts: 125
|
It is forbidden by authoring softwares, the answer is then yes. On reference decoders, the overlap will have the content of the secondly rendered window. No alpha blending between windows is performed: the overlap is simply written twice and the first write is lost.
The is_compliant function in SUPer should answer all of your future interrogations and questions in regard to compliancy. Last edited by cubicibo; 23rd June 2024 at 14:35. |
Thread Tools | Search this Thread |
Display Modes | |
|
|