[theora-dev] forcing eos on last theora packet (was Re: Theora 1.0 RC2)

Romain Beauxis toots at rastageeks.org
Wed Oct 29 01:56:28 PDT 2008

Le Wednesday 29 October 2008 01:50:25 Conrad Parker, vous avez écrit :
> Hi,

	Hi !

> I think a simpler approach might be for you to directly set the eos
> flag on the last ogg page, after you have retrieved it from
> ogg_stream_pageout(). You can use a function like this (copied from
> oggz-chop.c, where it similarly cuts the end of a file):
> static void
> _ogg_page_set_eos (const ogg_page * og)
> {
>   if (og == NULL) return;
>   og->header[5] |= 0x04;
>   ogg_page_checksum_set (og);
> }

I see this has a hack.
Besides, it is exactly the same issue, since you need the last page, which is 
not my case.

What I want to do is:
"Terminal pages may be 'nil' pages, that is, pages containing no content but 
simply a page header with position information and the 'last page of 
bitstream' flag set in the page header."

I don't know how to forge a 'nil' page, since the structure is pretty opaque:
typedef struct {
  unsigned char *header;
  long header_len;
  unsigned char *body;
  long body_len;
} ogg_page;

So the solution to generate a clean 'nil' page is to forge an empty eos 
packet, put it in the ogg stream, and flush the last page. This only needs
packetno and serialno:
typedef struct {
  unsigned char *packet;
  long  bytes;
  long  b_o_s;
  long  e_o_s;

  ogg_int64_t  granulepos;

  ogg_int64_t  packetno;     /* sequence number for decode; the framing
                                knows where there's a hole in the data,
                                but we need coupling so that the codec
                                (which is in a seperate abstraction
                                layer) also knows about the gap */
} ogg_packet;

> > Furthermore, since API claims that the 1-1 correspondance with YUV
> > encoded buffer and ogg packet might not remain in the futur, I believe
> > such function may be usefull in the case when 2, 3 or 4 buffers could be
> > needed to fill a new ogg packet..
> >
> > Patch is attached. I didn't test it yet, but it is mainly packetout's
> > code. I believe it is correct, though I don't know if the granulepos and
> > packetno should be incremented in this case.
> As for these questions regarding your patch, packetno would need to be
> incremented. I think granulepos would probably be the same as that of
> the previous packet (ie. the last actual frame), but the spec doesn't
> define that such an empty packet is valid for theora.

At least ogg specs allows it.
I will do more testings on my patch about packetno and granulepos.

Another alternative would be to have the two variables used to generate then 
available, that is to say pi->CurrentFrame since granulepos is a member of 
the theora_state value.


More information about the theora-dev mailing list