Hi there. 1.1.0 is on the road again, so green light for HEAD hacking :)
I wrote down how the sliding window approach for the export buffer (cfr "psu mode problem with 1.1" thread for the background) and in the end the document was simple enough. I made a few tests (on paper) and everything seems to work. Ready to code it. However, I learned a few tricks in those years while hacking transcode, and before to declare the spec finished, and post it here, I digged again into the source code, looking for corner cases, quirks and so on. And I found a few of them. So, the idea is: we're rewriting (again) a core part, so let's take this chance and let's clean the much cruft as is possible. But let's proceed in order first. The problem I found is simple: skipped frames. If a filter mark a frame as IS_SKIPPED (and 'til now it was absolutely fine -see filter_modfps and friend- and I see no reason for change that), the processing pipeline downstream will not see that frame. Never ever. In the end, that frame will not be pushed into export buffer, so we get a hole into frame id sequence. And that is no good for sliding window, because the sliding window code can't (yet?) distinguish those two cases: 1. the next frame isn't yet arrived. 2. the next frame will never arrive. In both cases the get() function will sit and wait for someone filling the hole. Well, it can wait forever, and that's not good :) In general, the current sliding window approach has an implicit assertion: -> no holes into sequence of frame IDs. Wile looking for issues, I stumbled again into the current handling of cloned frames, which is IMHO a bit clumsy. The problem for cloned frames is simple: -> only the import loop can set the frame ID while the problem with current approach is -> a frame can be cloned only once and -> the current way to handle cloned frame is poor (it's a poor man TTL, in the end). Last but not least, this is also a good chance to review/cleanup/change/powerup the *frame_list_t/TCFrame* data structures. An handful of fields can safely be dropped (prev/next/clone_flag) since they are already or will become obsolete with new framebuffer code in place. +++ OK, enough issues, let's talk about solutions now. :) The *frame_list_t/TCFrame* thing is big enough to deserve a separate discussion (modulo the fields needed for the other problems listed). So, I'll dismiss for the rest of this email. Problem #1: Skipped Frames/holes into frame ID sequence. -------------------------------------------------------- * Solution #1.A: mark a frame as skipped, but let it go down instead of discarding it as soon as is possible. All the processing step downstream will skip this frame (so doing so has minimal impact), in the end the encoder will dispose it as usual. ** Comment: Doable, but feels clumsy too. Maybe it's just me. * Solution #1.B: power up the sliding window code so it can handle the holes. ** Comment: Doable (I'll bet so) can be fragile? My gut feeling said so. * Solution #1.C: switch to heap/priority queue data structure. They are insensitive to holes as long as the sequence ID is monotonically increasing (always true, the world will end otherwise). ** Comment: Looks robust and I like it, maybe I'm the only one :) Problem #2: The handling of cloned frames. ------------------------------------------ * Preamble: this is interwined with the fact that only import loop can set the frame ID. * Solution #2.A: Leave things as they are. ** Comment: Hey, It's a solution too! * Solution #2.B: change the ID assignement. In theory, a frame gets an ID when it come to life (hykes!). But a cloned frame start to exist when someone (e.g. filter) clones it, so the cloning procedure should be able to assign frame ID as well as import loop does. ** Comment: In theory it is nice. In practice, there can be subtle problems. What happens when a filter clones frame #N when the import already emitted a frame #N+M? * Solution #2.C: Add a real TTL to frame. A regular frame has TTL=M. Cloning a frame means TTL++. When a frame it's extracted from a pool, TTL--. If TTL>0, the frame will be reinjected into the originating pool; otherwise, it will be discarded. ** Comment: No problem in sight with sliding window/heap, but what if a PRE_S_PROCESS filter clones a frame? the WAIT pool needs to use sliding window/heap too. No big deal, however. * Solution #2.D: Add a subid field to frames. The new ID becomes id#subid (# being concatenation operator). Regular frames gets subid=0; cloned frames get subid>0 for any frame duplicated from the originating one. ** Comment: Requires enlargement of the NULL pool (at least in theory), and minimal changes to the heap/sliding window approach. I've no particular feelings about that. If I'd to choose right now, I'll like to go with #1.B (and switch to #1.C if the former becomes too complicated or plain impossible) and #2.C. Discussion very welcome. Bests, -- Francesco Romani // Ikitt http://fromani.exit1.org ::: transcode homepage http://tcforge.berlios.de ::: transcode experimental forge