[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
|