[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."
http://xiph.org/ogg/doc/oggstream.html
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.
Romain
More information about the theora-dev
mailing list