[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