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