[Subhandler-devel] Some ideas for architecture
Status: Alpha
Brought to you by:
jsanchez
From: Julio S. <jsa...@us...> - 2003-10-20 17:27:50
|
Hi all, I have been doing some preliminary work. Mostly I have been throwing ideas to the wall to see if any would stick and I think I have much better understanding of what is needed. But I have changed my mind several times over the few days and I cannot rule out further changes. Anyway, if I don't write down right now what I have in mind, I might regret it later. So excuse me if I brain dump on the list. First, let's try to state the problem. We want to provide a library that is able to handle subtitles in a variety of forms to support operations such as input, output, display, multiplexing, format conversion, time shifting/scaling, etc. The library may live as a shared object on its own used by a number of applications but it may also be stripped for direct integration on other applications (some like xine or transcode tend to favor this approach except for very general and well-established libraries). So the library has to be constructed so that it is easy to select a subset of it. For subsetting, an architecture based on some kind of polymorphism seems easier that case switches. For example, a switch example is: switch(subtitle->type) { case TYPE1: do_this; break; case TYPE2: do_that; break; /* and so on */ } This structure is difficult to extend (it requires changes to every module that uses it) but, what is worse, it is difficult to subset. On the other hand, an architecture based on polymorphism such as: subtitle->do_something(...); can be extended easily, because callers do not need to know whether all subtitles implement the same do_something or not, they just need to provide a consistent interface. Of course, this immediately suggests an object-oriented approach. So, why not an OO language, such as C++? Would all applications gladly use the dependency on a C++ compiler? Not sure. Besides, it is possible to get a lot of the benefits of an OO language simply by thinking in the right frame. For example, xine gets some benefit from it and with the help of a few macros it is possible to go a long way. On the other hand it is easy to go overboard with this. I think I have found the right balance, so I think I will progress with C. But I am willing to reconsider at anytime. Anyway, the architecture is classy, i.e. OO-ish. Up to now, I had a couple of class hierarchies: one for subtitles, one for streams. At first I thought subtitles were most important, but that is not really the case. Streams are, by far, more interesting and subtitles are uninteresting, dull objects. Streams are vehicles for input and output and where most interesting things happen. While trying to restructure the thing, I have found there is another kind of objects that need recognition: IO channels and I hope it will be clear later. So, at the top we have a Subhandler_Object class, ancestor to all classes. The general hierarchy would go like this: Subhandler_Object Subhandler_Subtitle Subhandler_Subtitle_Bitmap Subhandler_Subtitle_Text Subhandler_Stream Subhandler_Stream_Submux (subrip/submux) Subhandler_Stream_Philips_IMG Subhandler_Stream_DVD Subhandler_Stream_SVCD Subhandler_Stream_CVD Subhandler_Stream_SRT Subhandler_Stream_PPML Subhandler_Stream_SSA Subhandler_Stream_MicroDVD [etc.] Subhandler_IO Subhandler_IO_Text Subhandler_IO_MPEG_PS Subhandler_IO_MPEG_PES Subhandler_IO_VobSub Subhandler_IO_PS1 Subhandler_IO_Program Up to yesterday, I thought that IO was part of the Stream. But then I found I was not getting enough reuse of code. And I am separating tentatively both concepts to see if I can make sense of that structure. An IO can be seen also as a container. This way it is possible to combine a stream with different IOs (I don't think it is a really good name, conduit might be better). Not all combinations make sense, though. For instance writing a SRT stream inside a VobSub would not produce an useful result. Let's do now the exercise of seeing how some cases would be managed. * Taking the PS1 output from transcode and preparing a SVCD PES for mplex. This would entail associating a Subhandler_IO_PS1 to a Subhandler_Stream_DVD that would be used for input, every subtitle would then be appended to a Subhandler_Stream_SVCD associated to a Subhandler_IO_MPEG_PES. * Taking the output from the Philips authoring tool and prepare output for multiplexing at mplex. We would read form a Subhandler_Stream_Philips_IMG associated to a Subhandler_IO_Text and output would be like in the case below. * Same thing but producing subtitles to accompany a XViD file. In this case, the output would be a Subhandler_Stream_DVD associated to a Subhandler_IO_VobSub. * Likewise, conversions from/to text can be done, but they are harder. Converting from text to bitmap require font rendering but, more important, they frequently require placement decisions. Converting from bitmap to text require OCR. This will not be available soon in the project. * The xine plugin (I have found easier to concentrate on everything else first) would use a Subhandler_IO_Program channel connected to a Subhandler_Stream of the appropriate type. Here, the control flow is inverted and requires some asynchronicity that I working on. * mplex could make use of a few of the components or it might just do the work on its own. Notice how we could select a subset of Stream and IO classes to provide a stripped-down version of the library. Feel free to comment on this. As soon as I have a couple of classes semi operative, I will start commiting. I am concentrating now on cloning the functionality of vobsub/submux (no multiplexing, though, just producing a PES). Best wishes. Julio |