Skip to main content
Topic: OGG Vorbis header bits (Read 111790 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

OGG Vorbis header bits

Is someone able to understand the raw bit in a ogg/vorbis header.

I'm able to reverse the tag part (which is good for my needs) but not the preceding header...

The doc states that "the Vorbis text comment header is the second (of three) header packets that begin a Vorbis bitstream" but nowhere in the source can i find a clear answer on the bits composing these headers...

Every ogg files begins with "OggS" (that's for sure) and then some header bits (i guess) [ in my example file :
00000004h: 00 02 00 00 00 00 00 00 00 00 56 24 00 00 00 00
00000014h: 00 00 B9 E4 13 F2 01 1E 01
]

I may interpret it as bitstream description or header description...don't know....

Then a vorbis header begins...
0000001dh: 76 6F 72 62 69 73 00 00 00 00 02 44 AC 00 00 FF ; vorbis.....D¬..ÿ
0000002dh: FF FF FF 00 E2 04 00 FF FF FF FF B8 01                  ; ÿÿÿ.â..ÿÿÿÿ¸.

And some OGG formating
0000003ah: 4F 67 67 53 00 00 00 00 00 00 00 00 00 00 56 24 ; OggS..........V$
0000004ah: 00 00 01 00 00 00 34 3D FE CC 12 FF 03 FF FF FF  ; ......4=þÌ.ÿ.ÿÿÿ
0000005ah: FF FF FF FF FF FF FF FF FF FF FF FF 53 03                ; ÿÿÿÿÿÿÿÿÿÿÿÿS.

And the part, i successfully reverse :
00000068h: 76 6F 72 62 69 73 1D 00 00 00 58 69 70 68 2E 4F ; vorbis....Xiph.O
00000078h: 72 67 20 6C 69 62 56 6F 72 62 69 73 20 49 20 32 ; rg libVorbis I 2
00000088h: 30 30 34 30 36 32 39 0B 00 00 00 0B 00 00 00 54 ; 0040629........T
00000098h: 49 54 4C 45 3D 50 72 6F 75 74 0E 00 00              ; ITLE=Prout...

Which is "vorbis", followed with a 2 byte string length, followed with a UTF8 string description of the vendor name  (is that what the doc means by "8 bit clean"...so obscure...i am not so much a fan of this "bit vector" analogy, i must admit that i really doesn't understand it...), and a 4 byte "number of comments" (n) integer, followed with the same pattern n times : a 2 byte string length and its UTF8 string.

Am i correct.... ?

And what is the first header bit structure ?

Thanks

MaB_fr

OGG Vorbis header bits

Reply #1
The first packet (of every stream) is the stream identification packet which is defined for Vorbis in http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#id2547578

Note that the Vorbis bitstream specification operates on a higher level -- the packet level.  Iv you haven't already, please make yourself familar with the following documents as well which describe how logical streams consisting of packets are encapsulated in Ogg pages:
http://www.xiph.org/vorbis/doc/oggstream.html
http://www.xiph.org/vorbis/doc/framing.html

HTH,
Sebi

OGG Vorbis header bits

Reply #2
Quote
The first packet (of every stream) is the stream identification packet which is defined for Vorbis in http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#id2547578

Note that the Vorbis bitstream specification operates on a higher level -- the packet level.  Iv you haven't already, please make yourself familar with the following documents as well which describe how logical streams consisting of packets are encapsulated in Ogg pages:
http://www.xiph.org/vorbis/doc/oggstream.html
http://www.xiph.org/vorbis/doc/framing.html

HTH,
Sebi
[a href="index.php?act=findpost&pid=341404"][{POST_SNAPBACK}][/a]


I already read that....and was totally disapointed by it. (i must add, that there's a bunch of 404 in those.......)

Is there any strong headers (i mean C language headers) specifiying the API...
I wasn't able to found the #define in ogg.h for simple things like :

"header_type_flag
5  bitflags: 0x01: unset = fresh packet
                 set = continued packet
         0x02: unset = not first page of logical bitstream
                      set = first page of logical bitstream (bos)
         0x04: unset = not last page of logical bitstream
                      set = last page of logical bitstream (eos)
"
and such...

Does they even exist ????
Am i suppose to rely entirely on my own interpretation of this documentation ?


MaB_fr

OGG Vorbis header bits

Reply #3
Quote
I already read that....and was totally disapointed by it. (i must add, that there's a bunch of 404 in those.......)

But those direct links provided do answer your questions...

Quote
Is there any strong headers (i mean C language headers) specifiying the API...
I wasn't able to found the #define in ogg.h for simple things like :

"header_type_flag
5  bitflags: 0x01: unset = fresh packet
                set = continued packet
        0x02: unset = not first page of logical bitstream
                       set = first page of logical bitstream (bos)
        0x04: unset = not last page of logical bitstream
                       set = last page of logical bitstream (eos)
"
and such...

Does they even exist ????

Not in the ogg header, I guess. But when using libogg, you don't need to worry about low-level details like that.

But the above is very easy to map to C code anyway... For example, assuming you have read the byte containing the flags into the variable flag, you could write something like this:

Code: [Select]
if (flag & 0x02)
 /* beginning of stream */

OGG Vorbis header bits

Reply #4
Ok...i doesn't want to go on the philosophic level...so it's not my point to argue about the importance of having constant defined and strong defines in low levels...

My problem is, i have an ogg vorbis file, tagged and all...Correctly read by every taggers and players i tried except.....mine when i use the vorbis library....

When i ov_open my file...i get a OV_ENOTVORBIS error message.....
And i've checked every kind of mistake i could have done...

Code: [Select]
oFile = fopen( lpcFileFullPath, "r" );
if( oFile == NULL )
    return FALSE;
    
if( ov_open( oFile, &ovfFile, NULL, 0 ) != 0 )
{
    if( ov_open( oFile, &ovfFile, NULL, 0 ) == OV_ENOTVORBIS )
    {
 ov_clear( &ovfFile );
 
 oFile = fopen( lpcFileFullPath, "r" );
 return ExtractVorbisRaw( oFile, pMetaTag );
    }
     
    return FALSE;
}
ExtractWithLibVorbis( oFile, &ovfFile, pMetaTag );

I even verified it with an hex editor....

Then what i choose to do, is believing that my version of the vorbis library was not compatible with my oggvorbis tagged file (i repeat, this file works on other taggers...)

So that's where i decided to reverse the data bits of the ogg files....(as you can see when i call ExtractVorbisRaw....which doesn't use any libvorbis function...)

I'd really, REALLY, like to be able to use libvorbis and the vorbisfile API...Except that it DOES NOT WORK....(i use libvorbis-1.1.1 and libogg-1.1.2 source code, first statically linking libogg to libvorbis and then statically linking libvorbis to my dll).

Of course it can be a bug in libvorbis. But as i assume that it is a strong, released library, and i prefer to think that I AM the problem...

I repeat that i already read the ogg doc and was finally able to "understands" it (always hoping i am not misunderstanding anything as it is strongly abstracted...)
It is clear that some of the API choice are unclear to me (like how do you MODIFY a vorbis comment with just ov_comment() function in vorbisfile API)...

But people where able to do it...so should i ... (i hope :-))

And....i've think i've done it...

Rest the problem of my ogg file not being read by libvorbis....

Thanks for answering my call to help

MaB_fr

P.S. : i'm joigning what i think is missing in ogg.h for my kind of needs....may help some people somewhere in the universe

Code: [Select]
typedef struct        stOggHeaderRaw
{
    char      ID[ 4 ];      //must be "OggS"
    unsigned char    StreamVersion;    //0 seems always good (?)
    unsigned char    HeaderTypeFlag;
    unsigned char    Position[ 8 ];
    unsigned char    SerialNumber[ 4 ];
    unsigned char    Counter[ 4 ];
    unsigned char    CheckSum[ 4 ];
    unsigned char    SegmentNumber;
    unsigned char    FirstSegmentSize;
};
#define    OGGRAWHEADER      struct stOggHeader
typedef    struct stOggHeaderRaw    *    LPOGGRAWHEADER;

typedef struct        stVorbisRawCommentsHeader
{
    unsigned char    StreamVersion;    //0 seems always good (?)
    char      ID[ 6 ];      //must be "vorbis"
    unsigned char    VendorStringSize[ 4 ];
};
#define    VORBISRAWCOMMENTSHEADER    struct stVorbisRawCommentsHeader
typedef    struct stVorbisRawCommentsHeader *    LPVORBISRAWCOMMENTSHEADER;

#define    OGG_OGGHEADER_ID      "OggS"
#define    VORBIS_VORBISHEADER_ID      "vorbis"    
 
#define    OGG_FLAG_CONTINUEDPACKET  1
#define    OGG_FLAG_STREAMBEGINNING  1 << 1
#define    OGG_FLAG_STREAMENDING      1 << 2

OGG Vorbis header bits

Reply #5
Shouldn't that be calling ov_open only once and saving the return value? ( And if you did that much wrong in just these dozen lines, I'd hate to see what you've done with the whole program. )

Oh, and since you appear to be using Windows, you should be using binary mode for all files. (ie. "rb" instead of "r")

OGG Vorbis header bits

Reply #6
Quote
Shouldn't that be calling ov_open only once and saving the return value? ( And if you did that much wrong in just these dozen lines, I'd hate to see what you've done with the whole program. )
[a href="index.php?act=findpost&pid=341637"][{POST_SNAPBACK}][/a]


if i call ov_open() twice it's juste because it's doing an unexpected behaviour (saying that my file is not a ogg vorbis file when it actually IS)

and why and doesn't use a if( ( somevar = ov_open() ) == OV_ENOTVORBIS ) is juste because I REALLY WANT the vorbis lib to work and be able to ERASE the code inside the fraudulent 'if'...

It's certainly an incorrect and dirty way of doing thing, but it was a temporary hack until someone can explains where i did wrong before this "if"....

I'd really appreciate if someone can concentrate on my problem, so i reedit my code with a clean way of doing it (just for you, for example, now you will be able to read my code ) :

Code: [Select]
oFile = fopen( lpcFileFullPath, "r" );
if( oFile == NULL )
return FALSE;

ovOpResult = ov_open( oFile, &ovfFile, NULL, 0 )
if( ovOpResult != 0 )
{
  ov_clear( &ovfFile );
 
  if( ovOpResult == OV_ENOTVORBIS )    // unexpected BEHAVIOUR....
  {
     oFile = fopen( lpcFileFullPath, "r" );
     return ExtractVorbisRaw( oFile, pMetaTag );
  }
}

return ExtractWithLibVorbis( oFile, &ovfFile, pMetaTag );

OGG Vorbis header bits

Reply #7
See as I mentioned above. Open the file in binary mode on Windows platforms. fopen( path, "rb" ).

OGG Vorbis header bits

Reply #8
Quote
See as I mentioned above. Open the file in binary mode on Windows platforms. fopen( path, "rb" ).
[a href="index.php?act=findpost&pid=341641"][{POST_SNAPBACK}][/a]


Thank you so much.....it WORKS...

Can explain to me why libvorbis needs a binary mode ? (i'm always curious of the inside...)

And do you know how i'm supposed to use ov_comment() to put modified data in a vorbis file (i read the vorbisfile.c and again....i'm lost) ? Must i use ogg packet control function ?

Thanks again

MaB_fr

OGG Vorbis header bits

Reply #9
The stdio file access functions on Win32 perform line ending translation on the fly, so you need to enable binary mode if you don't want this clobbering your obviously binary (and not text) files. [span style='font-size:4pt;line-height:100%']I hereby revoke your programmer's license and delete your copy of Visual Studio.[/span]

OGG Vorbis header bits

Reply #10
Quote
The stdio file access functions on Win32 perform line ending translation on the fly, so you need to enable binary mode if you don't want this clobbering your obviously binary (and not text) files.
[a href="index.php?act=findpost&pid=341645"][{POST_SNAPBACK}][/a]


Ok, and so as a bitsrteam can contains "line ending" in the data, libogg needs to secure this...

Do you think I may suggest the ogg team to add this part into their docs, or is it "common knowledge" ?

MaB_fr

OGG Vorbis header bits

Reply #11
Quote
Ok, and so as a bitsrteam can contains "line ending" in the data, libogg needs to secure this...

Do you think I may suggest the ogg team to add this part into their docs, or is it "common knowledge" ?

MaB_fr
[a href="index.php?act=findpost&pid=341647"][{POST_SNAPBACK}][/a]

Yes, that is common knowledge.

And if you had looked at the vorbisfile_example.c file included with libvorbis, you could see that it does include code to set binary mode  for stdin/stdout...

Quote
And do you know how i'm supposed to use ov_comment() to put modified data in a vorbis file (i read the vorbisfile.c and again....i'm lost) ? Must i use ogg packet control function ?

The recommended way is to use the functions in the file vcedit.c, part of the vorbiscomment program in the vorbis-tools package.

 

OGG Vorbis header bits

Reply #12
Quote
Byte order: Little-endian
Offset   Length   Contents
[ 0      4 bytes  "OggS"
  4      1 byte   Stream structure version (0x00)
  5      1 byte   Packet flag:
                    bit 0:  true if page continued
                    bit 1:  true if first page
                    bit 2:  true if last page
                    bit 3..7: reserved
  6      8 bytes  The end pcm sample position (64bit integer)
14      4 bytes  Stream serial number
18      4 bytes  Page number
22      4 bytes  Check sum
26      1 byte   Number of segments(s)
27     (s)bytes  Sengment table
27+(s) (b)bytes  Body (b := header[27] + header[27+1] + ... + header[27+s-1])
]*

FROM http://www.onicos.com/staff/iz/formats/ogg.html
It works for me.

 
SimplePortal 1.0.0 RC1 © 2008-2020