[XviD-devel] [TODOLIST ITEM] Bit rate controler module
Edouard Gomez
xvid-devel@xvid.org
Sun, 8 Dec 2002 21:21:48 +0100
suxen_drol (suxen_drol@hotmail.com) wrote:
> okay. i think a 'xvidcore/src/ratecontrol' dir would also be
> appropriate
>
Yes.
I'm having problems convertings my lib to the new design so i have no
code to show yet (hope this will be ready during _this_ week) but here
is the overall design.
My design rationale:
- Allow various RCs to work with a same API
- Modular
- Allow external RCs through a known interface
- Keep simple API
Current API:
int xvidrcInit(xvidrc_control_t *rc);
int xvidrcGetQuant(xvidrc_control_t *rc);
int xvidrcGetType(xvidrc_control_t *rc);
int xvidrcUpdate(xvidrc_control_t *rc, ....stats);
(stats format is not defined atm)
int xvidrcFinish(xvidrc_control_t *rc);
How to use it (how i think it will be used)
- during encoder_init, we get user rc paremeters and copy them to our
xvidrc_control_t (atm i separate user rc and internal rc, but i think
i'll sort all data members so user rc could be copied with a simple
memcpy)
- we initialise the RC lib passing the copied data.
then its use during encoding
- Get the frame type "int type = xvidrcGetType(rc);" (See note 1)
- Do the right thing with this frame (if bframe, buffer it and so no
for p/i frames...)
- Get the quantizer "int quant = xvidGetQuant(rc);" (See note 2)
- Encode the resulting frame.
- Update the rate controler "xvidrcUpdate(rc, ...framesize,quant,...);
The stats format is not fixed yet, could be the xvid_stats or
something else, it's not so important at this stage of the
development
when it's last frame
- xvidrcFinish(); probably called in encoder_destroy or other ending
encoder function
Now internal design:
The RC module structure:
typedef struct _bitrate_controller_t
{
int mode;
const char *description;
xvidrc_init_function_ptr init;
xvidrc_get_quant_function_ptr getquant;
xvidrc_get_type_function_ptr getintra;
xvidrc_update_function_ptr update;
xvidrc_finish_function_ptr finish;
xvidrc_debug_function_ptr debug;
}bitrate_controller_t;
Each RC algorithm defines such a structure symbol and fills it with
local functions (defined static so there's no name pollution on unix
systems, the only exported symbol is the resulting bitrate_controller_t
symbol)
Upper layer, the API direct implementation:
This is just a set of wrapping function. The init function just finds if
it has the user requested bitrate_controller_t in its rc_available array
of bitrate controller, then it binds the resulting rc_controller and
calls its init function.
Then each call to a xvidrcXXX function is just a wrap to call the
underlying rc module functions through the bitrate_controller_t
structure members.
ASCII ART layers:
+--------------------------------------------------------------------+
| USER |
+--------------------------------------------------------------------+
| API |
+--------------------------------------------------------------------+
| API Wrapper |
+--------------------------------------------------------------------+
| Module's structure |
+--------------------------------------------------------------------+
| CBR/ABR | VBR 2Pass 1 | VBR 2pass 2 | VBR Fixed Quant |
+--------------------------------------------------------------------+
What's already done:
- API
- module structure design
What i have still to do:
- fix the user rc structure
- then convert each module to the new structure (all that is not in
the user structure will go in a private area allocated by the module
itself so external code has not to worry how the implmentation is
done, it wil always present the same interface)
Possible flaws in the design:
- how to handle adaptive quant, my design is oriented toward a
"current state defines the global quant to use" while adapt quant is
"let's look at the picture and i distribute quants the way it gives
better results"
Opinion about your code (pete):
- it does not help me, because i had already define the design and
structures were almost fixed (i still have to sort what will be user
land and what will be private land) so it came too late... sorry.
- it is not flexible at the moment, hard coded switch... is the way
you get a nasty, cryptic code like current vfw... imo we should avoid
that in the future (my current 2pass code is the vfw port to ANSI C so
it has altcc and so on, but the overall goal of my work is to provide
the API, and first implementations, we can change the modules
implementations later)
If this mail inspires you, i would be happy to hear your
impressions/questions. I want to avoid duplicated effort... is it worth
to continue my work or is pete's rc api enough ?
--
Edouard Gomez