How does one deal with the case when an fread callback doesn't have any more data but is going to get more data in the future? In particular, this is an issue when reading an incoming Ogg stream from a socket (icecast2, in this case). The issue is that the fread can't return 0 (that signals EOF and hoses everything), and it doesn't have a negative code that says come back later when you have more data. I can't allow this to block as the system I am using does not have threads (embedded system). A good example of this is to put too much information in the info/comment field that overflows the initial decode. If ov_read can't get enough data to completely decode a packet, things go badly wrong. What do other people do for handling streaming like this? -a
On Thu, Oct 05, 2006 at 09:01:48PM -0700, Andrew Lentvorski wrote:> The issue is that the fread can't return 0 (that signals EOF and hoses > everything), and it doesn't have a negative code that says come back > later when you have more data.No, I think ov_read() is intended to block in such a situation.> I can't allow this to block as the system I am using does not have > threads (embedded system). > > A good example of this is to put too much information in the > info/comment field that overflows the initial decode. If ov_read can't > get enough data to completely decode a packet, things go badly wrong.I don't follow what you mean here. You pretty much have to have the whole packet in memory to parse it, which libvorbis and Tremor both try to do. (Multiple copies in the case of libvorbis.) For the comment header you could change the implementation to skim for just the info you want to display (artist and title, likely) and discard the rest, but it won't be trivial the way the ogg parser is implemented. For other packet types it's unlikely to help all that much. But I'm not sure what you're expecting the decoder to do if your read callback could return EAGAIN. Do you want it to bubble that up for you so ov_read() returns it too, and then you go off and do UI stuff? Without threads or continuations I don't have a good suggestion. Maybe pass the UI state through the datasource pointer and update stuff from inside your read callback while it's waiting for data? Then if the user cancels you return zero and recover after ov_read() returns. Or you could do it the other way, and just return zero when you've blocked too long, and retry decoding later when you do have more data. FWIW, -r
On 10/6/06, Andrew Lentvorski <bsder@allcaps.org> wrote:> How does one deal with the case when an fread callback doesn't have any > more data but is going to get more data in the future? > > In particular, this is an issue when reading an incoming Ogg stream from > a socket (icecast2, in this case). > > The issue is that the fread can't return 0 (that signals EOF and hoses > everything), and it doesn't have a negative code that says come back > later when you have more data. > > I can't allow this to block as the system I am using does not have > threads (embedded system).Vorbisfile is a high-level interface. It's very easy to use if your design matches what it provides... but if it doesn't, it's pretty useless. In your case, I guess it falls into the 'pretty useless' category. You'd be MUCH better off just starting from the lower-level libvorbis, and writing your own higher-level API that can have appropriately non-blocking semantics. You simply can't do what you want with vorbisfile; adding it would be difficult. Mike