隽 徐
2006-Aug-30 01:39 UTC
[Vorbis-dev] Continued:How can I seek in Ogg Vorbis file, but not using Vorbisfile library?
Hello, All. First, I want to thank Ian Malone and Ralph Giles, thanks for your kind replies. But I still have problems about seek. As you suggested, I could use ov_open_callbacks() to supply my own read/write/seek functions. So, can you give me an example? I?m sorry for my ignorance, because I haven?t used callbacks before. I analyzed the vorbisfile.c in Tremor, and I think I need more specific information about the seek algorithm. As far as I know, I could use ogg_sync_pageseek() function to find the next page; if it returns 0, that means I need to read more data; if it returns n, that means the page was synced at the current location with a page length of n bytes, so the location is where the ?Oggs? is, am I right? And if it returns -n, does it mean I already skipped n bytes from the start point or I need to skip back n bytes to get the sync page? Also, if I find the sync page, I must update the decode engine, the structures, like ogg_page, ogg_packet, etc need to get a new value, is that right? Then, there is another problem. I might have passed several segments of a packet, but the packet is not finished, so the next page starts with segments of the last packet. Can these segments be decoded? Or I must find the next packet? If so, how can I do it? I think granulepos is not very helpful in this case. Hope you can give me more information. Thank you all. Best wishes, Susan --------------------------------- Mp3???-??????? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/vorbis-dev/attachments/20060830/86d613de/attachment.htm
Ian Malone
2006-Aug-30 04:00 UTC
[Vorbis-dev] Continued:How can I seek in Ogg Vorbis file, but not using Vorbisfile library?
On 30/08/06, ? ? <china_xujun@yahoo.com.cn> wrote:> > Hello, All. > > First, I want to thank Ian Malone and Ralph Giles, thanks for your kind > replies. But I still have problems about seek. > > As you suggested, I could use ov_open_callbacks() to supply my own > read/write/seek functions. So, can you give me an example? I'm sorry for my > ignorance, because I haven't used callbacks before. >Have a look at how ov_open is implemented by calling ov_open_callbacks in vorbisfile.c and at the comments for ov_callbacks in vorbisfile.h: /* The function prototypes for the callbacks are basically the same as for * the stdio functions fread, fseek, fclose, ftell. * The one difference is that the FILE * arguments have been replaced with * a void * - this is to be used as a pointer to whatever internal data these * functions might need. In the stdio case, it's just a FILE * cast to a void * * * If you use other functions, check the docs for these functions and return * the right values. For seek_func(), you *MUST* return -1 if the stream is * unseekable */ What I'd do would be to make my own struct containing the buffer, it's length and current read position (either as a pointer or an offset), then check the documentation for fread, fseek, fclose and ftell and implement functions to do equivalent things to the buffer. The simplest one is my_tell: long my_tell(struct my_struct_t *my_struct) { /* Assuming that current and start are both type char * and doing the obvious. If you were storing length you'd just return that. */ return (long) (my_struct->current - my_struct->start); } I think strictly it would be better to define it as taking void *datasource (which is what it will be given) and casting it to my_struct_t. In any case be sure to replicate the documented functionality of the f* functions (including the above fseek return -1 if not seekable). _get_data may need you to set errno with my_read, I'm not sure how good an idea that is. Then add them to the callbacks list either altogether as done in ov_open or one at a time like: struct ov_callbacks callbacks; callbacks.tell_func = my_tell; callbacks.read_func = my_read; etc. As far as I can tell the next two questions relate to going down the do it yourself route?> I analyzed the vorbisfile.c in Tremor, and I think I need more specific > information about the seek algorithm. As far as I know, I could use > ogg_sync_pageseek() function to find the next page; if it returns 0, that > means I need to read more data; if it returns n, that means the page was > synced at the current location with a page length of n bytes, so the > location is where the "Oggs" is, am I right? And if it returns -n, does it > mean I already skipped n bytes from the start point or I need to skip back n > bytes to get the sync page?As far as I can tell from the documentation -n is the amount you've skipped from the last submitted block of data to the current one. n indicates you've got a page length n, so you've submitted all the data for that page (and possibly some for the next one, the only way to know the difference is to submit a byte at a time).> > Also, if I find the sync page, I must update the decode engine, the > structures, like ogg_page, ogg_packet, etc need to get a new value, is that > right? Then, there is another problem. I might have passed several segments > of a packet, but the packet is not finished, so the next page starts with > segments of the last packet. Can these segments be decoded? Or I must find > the next packet? If so, how can I do it? I think granulepos is not very > helpful in this case. >I'm not quite sure of the answer offhand, ov_raw_seek looks enlightening. What I can tell you is that you have a page, you can now do the ogg_stream_pagein/ogg_stream_packetout cycle until you get the next packet, any segments from a previous packet running over page boundaries will be dropped. To get the previous packet you'd have to go backwards to get to the page it started on (with Vorbis that will probably be the previous page). -- imalone
隽 徐
2006-Sep-01 04:09 UTC
[Vorbis-dev] Continued:How can I seek in Ogg Vorbis file, but not using Vorbisfile library?
Hello, All. Thanks, Ian Malone, thank you for your help. I have a better understanding about the Ogg Vorbis decoding now. You are so kind to give me the example about callbacks, but unfortunately, I am not allowed to use the file like operations. So, I can only use the API provided by libogg and libvorbis. I put part of the Ogg Voribis file in a buffer, then seek in the buffer, and I can find the page with a complete packet, but I don?t know how to get the exactly location of the page or the packet. I want to use the ogg_page_granulepos() function, but according to the documentation provided by xiph.org, it is an absolute position within the original uncompressed data. If I can get bytes number before this page, then how can I get the packet location? Thank you. Best wishes, Susan --------------------------------- Mp3???-??????? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/vorbis-dev/attachments/20060901/eae90035/attachment.htm