>Since we're talking about radical changes, and since there is a
>repository change in sight, what I'm proposing (and what I *really* like
>to do) is to do a fresh start.
I'm absolutely in favor of that, and agree that it's probably needed
anyway. I try not to think about how many headaches transcode.c gave
me. (:
>By building a processing pipeline using transcode (but this is also true
>in general with minor modifications, e.g. with other multimedia tools)
>we're essentially build an hidden tree of processing stages.
>Each processing stage is implemented by 0+ modules
[...]
>The new model is instead a "pull model".
>Each stage drags frame from upstream as soon as it is ready to process
>it. So, the central framebuffer is gone.
>Each stage talks directly with upstream, so it has to link exactly the
>module, instead of sitting and wait for frames to come in its FIFO.
>
>All this fancy stuff can be implemented fairly efficiently if we require
>that caller provides the *destination* buffer for the upstream.
This sounds like a good way to do it in principle. In fact, I don't think
we even have to think about "stages", since we can just construct a tree
of modules and pass frames down the tree (though it may be useful on the
user-interface side to talk about the demux stage or the encode stage or
whatever). Looking at this:
>typedef struct tcprocessoritem_ TCProcessorItem;
>struct tcprocessoritem_ {
> TCProcessorItem *upstrem;
> TCModule *module;
> TCFrameBuffer *frame;
>
> int (*get_frame)(TCProcessorItem *P, TCFrameBuffer *frame);
>};
[...]
>static int int generic_get_frame(TCProcessorItem *P, TCFrameBuffer *frame)
>{
> int err = TC_OK;
> if(!P->frame) {
> P->frame = tc_framebuffer_alloc(); /* lifetime equals to the
> processor */
> }
> err = P->upstream->get_frame(P->upstream, P->frame);
> if (!err) {
> err = tc_module_process(P->module, P->frame, frame);
> }
> return err;
>}
Do you intend this generic_get_frame() to be part of the core, serving as
a wrapper for each module's processing function? I.e. you'd have one
thread for each module, looping through this function until the module or
its upstream link returns end-of-stream or error?
My main concern is how to handle cases of multiple links in or out. The
obvious case is for muxers or demuxers, though I could also imagine, for
example, an audio module that took a 5.1 PCM stream as input and encoded
it to both 5.1 AAC and plain stereo AAC. For an initial implementation
it would probably suffice to use a pair of frame parameters (video and
audio) for demux and mux modules, and treat everything else as a filter;
but in the long run we'll probably need a way for each module to declare
(dynamically, since e.g. DVDs can have any number of streams) what inputs
and outputs it uses.
>(and don't be afraid to say "you still don't get it!" if it's the
>case ;))
No, I think you got it this time. (: Your method is similar, anyway, and
in fact I think I like it better than the one I proposed.
--Andrew Church
[email protected]
http://achurch.org/