[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