>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
    achu...@achurch.org
    http://achurch.org/

Reply via email to