Deriving a program from the DVSDK DM6467 encodedecode demo, it appears that there are FOUR buffer tables being used.
- capture.c creates/gives a table (NUM_CAPTURE_BUFS) to DMAI for capture. It loops to transfer those buffers from DMAI's capture to the capture fifo.
- video.c creates a table (CAPTURE_PIPE_SIZE) to build the above referenced fifo, then transfers buffers from this fifo through the codec to a second fifo
- video.c creates a table (DISPLAY_PIPE_SIZE) to build the second fifo.
- display.c creates/gives a table (NUM_DISPLAY_BUFS) to DMAI for display. It loops to transfer those buffers from the display fifo to DMAI's display.
This seems needlessly complex and has caused other problems with my custom application that I won't discuss right now.
It seems to me that I ought to be able to create a SINGLE table of buffers, and pass [the pointers to buffer handles] around between DMAI capture, codec, and DMAI display. I see no problem with the middle two uses, the fifo's. I'm unsure about the outer two uses, in DMAI capture/display.
Will DMAI allow me to do this?
DETAIL: (You may already have the answer. You may already know you either don't care or don't know. You don't have to read further. You might, however.)
Consider capture. There's Capture_put() and Capture_get(). There isn't more doc than a single line description of these. It seems to me that once I do a Capture_get(), the returned buffer should be free of DMAI capture influence until it is later passed to Capture_put(). During this time of no DMAI capture influence, I should be able to pass that buffer through my custom codec (that works buffer-in-place, not buffer-copying), then on to DMAI display influence for a while, and finally back to DMAI capture influence. Likewise for DMAI display.
Does anyone know if this is possible? Or will it not work, presumably because DMAI capture (or display) doesn't completely release influence upon Capture_put(). An example of lack-of-release would be the following. If DMAI capture uses the buffers in its table in a continuously rolling loop, in spite of Capture_get() and Capture_put() calls. In such a case, it would effectively have two pointers to the circular buffer table. One pointer is the buffer to where the capture is occurring. The other pointer is the buffer(s) subject to Capture_get() (or Capture_put()). With all running smoothly, this example doesn't matter. But if another loop gets log jammed and no Capture_put() occurs for a while, in this scenario the DMAI capture code will roll on forward in the circle, skipping ahead of the Capture_put() and using OLD buffer contents for the duration of the log jam. Lack of input/output video sync can effectively cause such a scenario in the form of a slowly increasing or decreasing "queue", until the "queue" overflows or underflows.
In contrast, perhaps DMAI doesn't use the table as circular, but simply relies on those for which it has control, and then requires continuous Capture_put() calls to keep from running out. This would be a linear list of buffers, that does not circle back, and we have to keep putting new buffers on the bottom before DMAI gets down their and suffers a no-available-capture-buffer condition (in which case I guess the response would be a dropped frame).
So which scenario is it? Or what third scenario?
Note, again, that my desire is to use a single buffer table and manage who gets what, when, on my own. I'm translating different input and output video formats as well as having them NOT synchronized. In the theoretically synchronized world, I want to be able to guide a buffer from capture, through in-place codec, to display, and then back to capture again. I want minimum latency, and I should be able to do this with a single buffer passing through and thus only processing time latency, which would be a fraction of a full frame time. I would use multiple buffers nevertheless, expecting only one to be in use at a time, with a pile in reserve waiting between capture and display as well as between display and capture. THEN, as my input and output are not synchronized, I would from time to time intentionally drop a capture (capture faster than display) or duplicate a capture (capture slower than display), to maintain my latency between 0 and I believe 1 frame. As soon as the latency tries to fall below 0, I duplicate a frame and suddenly have 1 frame latency. As soon as the latency tries to grow above 1, I drop a frame and suddenly have 0 frame latency. In fact, it might all work with only three buffers total, one under DMAI capture influence, one under DMAI display influence, and one being processed by the codec. I cycle those three buffer handle pointers around in a circle, and the drop/duplicate situation occurs naturally at the capture or display get/put whenever I do/don't have a buffer or extra. (We all know how that would be coded in spite of how I've described it!)
BTW, I'm working on stripping out the needless multi-threading of my encodedecode-derived program right now. That's needless complexity, and somewhere a long time ago I read that it was put in their just for example purposes, not for necessity. Once multi-threading is gone, I want to optimize all the buffer shenanigans!
Thanks VERY much for your help,
Helmut
P.S. to self, don't forget Framecopy() for interim use in modifying code in baby steps, keeping it working at every step along the way.