Re: further debugging of my ogg/theora decoder
salsaman <[email protected]>
| Newsgroups | gmane.comp.multimedia.ogg.theora.devel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Nov 13, 2008 at 2:52 AM, Conrad Parker <[email protected]> wrote: > 2008/11/13 salsaman <[email protected]>: > > > > On Wed, Nov 12, 2008 at 6:36 PM, Ralph Giles <[email protected]> wrote: > >> > >> On Wed, Nov 12, 2008 at 1:13 PM, salsaman <[email protected]> wrote: > >> > >> > suppose I start decoding from a page with granulepos (kframe=x, frame > >> > =y) > >> > and I continue decoding in sequence until I reach the next page with a > >> > non-negative granulepos (kframe=a, frame=b). Is it possible that there > >> > could > >> > be another keyframe between x and a ? In other words, do "hidden" > >> > keyframes > >> > exist in the ogg stream, or is it safe to assume that every keyframe > has > >> > at > >> > least one (non-negative) granulepos ? > >> > >> It's possible, though unlikely. > > (hence it is not safe to assume that every keyframe is represented by > a granulepos in the stream.) > > >> > Let me give an example. Suppose I am seeking for frame 20. I find a > >> > granulepos of (18,22). Good, so I know that the keyframe is 18 + an > >> > offset > >> > of 2. So now I seek again to find the largest granulepos before 18. I > >> > find > >> > (10,12). Great. > >> > So I start decoding from (10,12) and I reach a keyframe. Can I assume > >> > this > >> > keyframe is 18, and then just decode two more frames ? > >> > >> In this case, you know the answer, because if you know by counting > >> whether the keyframe you just found is frame 18, no? Or are you > >> worried about having the backpropagate the (10,12) to earlier packets > >> in that (10,12) page? You do have to do that, you can't assume there > >> isn't a 9,9 in there too. > > > > No, I am not worried about that. But the first keyframe I find could be > 14 > > instead of 18, for example. Then I count two frames, I would end up at 16 > > instead of 20. > > right -- when you found (10,12), the only info that gives you is that > a keyframe exists at frame 10, and interframes 11 and 12 depend on it. > You previously knew that keyframe 18 exists and interframes 19-22 > depend on it. You don't yet know anything about the keyframes and > interframes between 13-17. > > > The only way I can see to be sure is to decode right up to the (18,22) > page > > and make sure there are no more keyframes until then. > > > > This would occur for example, if there were continuation packets up to > frame > > 13, then on the same page 14 (keyframe in this example) begins and the > > packet continues until we get to 18, then 18 continues until 18,22. > > yes > > > So what I really need to know, if a frame/packet completes on a page, and > > then another frame/packet begins on the same page, but continues, would > the > > granulepos be for the completed frame, or would it be a continuation ? > > for the completed frame; the granulepos (which is a field in the page > header) refers to the last completed packet on the page. > > > If > > it's the former then I think I am OK because in case of a keyframe before > > 18, there should always be a completed frame (e.g. 17 with a granulepos > of > > 14,17) before 18 starts, right ? > > No, eg. your next example is possible: > > > The other example I can think of is if 17 is a keyframe, and it completes > on > > the same page as 18, also a keyframe, completes. I guess this might be > > possible for very small, rapidly changing frames, right ? In this case I > > would only need to decode to the end of the page where a keyframe first > > appears, and make sure I got the last keyframe on that page. > > > > I hope this makes some sense. > > If you just want to identify keyframe packets, you can skip the full > decode and use theora_packet_is_keyframe(), which just probes the > packet data for the keyframe flag. > > So in general, you can't make assumptions about keyframe existence > based on granulepos. > > To find the keyframe for a frame you want to render, you should first > try to find the page with the largest granulepos less than the target > keyframe. Let's call that page G, and we'll call the last packet > finishing on it P; ie. packet P has G's granulepos. Once you've found > page G, then scan forwards through all the packets following P > (probing for keyframes, or just counting) until you've found your > target keyframe. > > Note that the next packet after P may begin on G, so you can't just skip G. > > So you need to start by pulling packets out of G, and once you see one > with the same granulepos as G you can start your counter. However if P > is continued on G (ie. it starts on an earlier page), and you just > feed G into ogg_stream_pagein(), then ogg_stream_packetout() will not > give you P, so you won't see any granulepos values and you won't be > able to initialize your counter. You can detect this condition using > libogg as follows (from ogg/src/framing.c): > > /* NOTE: > If a page consists of a packet begun on a previous page, and a new > packet begun (but not completed) on this page, the return will be: > ogg_page_packets(page) ==1, > ogg_page_continued(page) !=0 > */ > > In that case you can assume that the first packet coming out of > ogg_stream_packetout() is P+1. > > Conrad. > Actually I have now realised it`s not that complicated, as you say, just counting frames and not caring about keyframes at all is the way to go. My search runs in 2 passes: pass 1, find largest gpos <= target - this gives us keyframe for target (note that a granulepos with k<= target, f>=target is also acceptable) pass 2, calculate gpos from kframe, search for largest gpos < this then starting from that page: - ignore any packets on that page - count frames starting from the following page - when we reach a page which produces (target -1), we know that is where kframe starts, so store that page offset (this is useful for playing backwards...) - decode the next packet : this is our target frame Does that look correct ? Cheers, Gabriel. _______________________________________________ theora-dev mailing list [email protected] http://lists.xiph.org/mailman/listinfo/theora-dev