[XviD-devel] xvid bframe encoder question

Edouard Gomez ed.gomez at free.fr
Fri Dec 26 21:25:52 CET 2003


Christoph Nägeli (chn at kbw.ch) wrote:
> Let's say the encoder choses to encode following:
> I B B P B B P ...

Yes that is a posible pattern. *But* the encoder output isn't ordered
that way.

Output order is:
I P B B P B B

Now i can explain you the rest...

> Then the first time I call xvid_encore(...), I got the I frame back.
> The next time, the encoder stores the frame in the b-frame queue,
> right?

Yes.
 
> What if the encoder choses that my last frame is a b frame ?
> Then the frame get stuck in the bitstream and I have no data.

No last frame is always turned into a P frame type. But this is not
automatic, as the primary decision is still done by the ME analysis
pass. You need to inform the encoder that you're flushing the last
frames. More just below...
 
> How can I get the data back?

See the flushing code in xvid_encraw.c, it basically consists of
passing a NULL CSP until the encoder returns you no data.
 
> And the following about decoding such a sequence:
> [...]
> decoding this, (please correct my if something's wrong):
> If I like to decode the first frame, then I give it the 22519 bytes to 
> the decoder.
> And what if I like to decode the second frame? I got no data from this 
> frame?

Do you remember the encoded output:
I P B B P B B

And more important i'll mark all frames with their "decoding" output
number (or encoding "feeding" order):
I-1 P-4 B-2 B-3 P-7 B-5 B-6...

So what happens when you give this data back to the decoder ? (i assume
you stired individual frames in the uplaying container)

- First you  feed the decoder  with the Intra  frame, as an  intra frame
does only  depend on  itself, the  decoder can be  telled to  output the
decoded frame w/o delay (low delay flag)

- Then you feed the decoder with the P-4 frame, but the decoder know
this isn't the frame to output as frame #2. It's decoded now because
the following bframes depend on it, but no output is given. As we don't
have a reference frame to switch yet (explained later).

- You feed the decoder with first bframe, as in step 2, the decoder
context contained the two frame references, the decoder can decode this
bframe and output frame #2 from this bframe.

- same for the second bframe.

- then decoder receives P-7, the decoder must know change its reference
  frame in order to have P-4 and p-7 as ref frames for the next couple
  of bframes. As in step 2, the decoder decodes the pframe now, but
  doesn't output it. In fact it will output P-4 that it decoded long
  ago in step 2.

So you end with this output:
step 1 - i-1
step 2 - no output <-- know as bframe lag
step 3 - b-2
step 4 - b-3
step 5 - p-4

When not using the low delay flag, the only changed step is that first
reference frame isn't output immediatly (here the IFrame) so you have
delay before anything else.

To avoid this bframe lag, a known solution is to pack the second ref
frame with the following bframe, and inform the decoder about this.

So you feed the decoder with:
I (PB) B (nothing just a flush request) (PB) B ....

So you obtain:
- I
- B (because the decoder can decode the P ref frame and then,
     immediatly, decode the bframe)
- B 
- P (because you requested it with a flush command)

The problem now lies on the container, because there is no nice solution
on how  to inform  the decoder  frontend it will  feed the  decoder with
packed data and when it has to  flush frames. More or less DXN chose for
us all how  to do this with their packed stream  format...  but there is
no need for you to know about it (yet ;-)).

Hope that helps u.

-- 
Edouard Gomez


More information about the XviD-devel mailing list