1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*C
(c) 2005 bl0rg.net
**/
#ifndef OGG_H__
#define OGG_H__
#include "buf.h"
#include "crc32.h"
#include "file.h"
/* ogg header:
0 'O'
1 'g'
2 'g'
3 'S'
4 0x00
5 bit 1 = 0 (fresh), 1 (set)
bit 2 = 0 (not first page), 1 (first page)
bit 3 = 0 (not last page), 1 (last page)
6-13 absolute granule position
14-17 stream serial number
18-21 page sequence no
22-25 page checksum
26 page_segments
27... page segment_table
*/
#define OGG_SYNC_HDR_SIZE 4
#define OGG_HDR_MIN_SIZE 27
#define OGG_CRC32_POLY (0x04c11db7)
#define OGG_SYNC_HDR_BYTE1 'O'
#define OGG_SYNC_HDR_BYTE2 'g'
#define OGG_SYNC_HDR_BYTE3 'g'
#define OGG_SYNC_HDR_BYTE4 'S'
#define OGG_MAX_SYNC 40
typedef struct ogg_page_bits_s {
/*M
If set, the page contains a continued packet.
**/
unsigned int continuation :1;
/*M
If set, the page is the first page of the logical bitstream.
**/
unsigned int first :1;
/*M
If set, the page is the last page of the logical bitstream.
**/
unsigned int last :1;
} ogg_page_bits_t;
typedef struct ogg_page_s {
/*M
Page flags.
**/
ogg_page_bits_t b;
/*M
Absolute granule position.
(This is packed in the same way the rest of Ogg data is packed;
LSb of LSB first. Note that the 'position' data specifies a
'sample' number (eg, in a CD quality sample is four octets, 16
bits for left and 16 bits for right; in video it would likely be
the frame number. It is up to the specific codec in use to define
the semantic meaning of the granule position value). The position
specified is the total samples encoded after including all packets
finished on this page (packets begun on this page but continuing
on to the next page do not count). The rationale here is that the
position specified in the frame header of the last page tells how
long the data coded by the bitstream is. A truncated stream will
still return the proper number of samples that can be decoded
fully.
A special value of '-1' (in two's complement) indicates that no
packets finish on this page.
**/
unsigned char position[8];
/*M
Stream serial number.
Ogg allows for separate logical bitstreams to be mixed at page
granularity in a physical bitstream. The most common case would
be sequential arrangement, but it is possible to interleave pages
for two separate bitstreams to be decoded concurrently. The
serial number is the means by which pages physical pages are
associated with a particular logical stream. Each logical stream
must have a unique serial number within a physical stream:
**/
unsigned long stream;
/*M
Page sequence number.
Page counter: lets us know if a page is lost (useful where
packets span page boundaries.
**/
unsigned long page_no;
/*M
Page checksum.
32 bit CRC value (direct algorith, initial val and final XOR = 0,
generator polynomial = 0x04c11db7). The value is computed over
the entire header (with the CRC field in the header set to zero)
and then continued over the page. The CRC field is then filled
with the computed value.
**/
unsigned long page_cksum;
/*M
Page segments.
The number of segment entries to appear in the segment table. The
maximum number of 255 segments (255 bytes each) sets the maximum
possible physical page size at 65307 bytes or just under 64kB
(thus we know that a header corrupted so as destroy
sizing/alignment information will not cause a runaway bitstream.
We'll read in the page according to the corrupted size information
that's guaranteed to be a reasonable size regardless, notice the
checksum mismatch, drop sync and then look for recapture).
**/
unsigned char page_segments;
/*M
Segment table (containing packet lacing values).
XXX: do we need the whole table? We could do with the lacing
value of the last segment.
**/
unsigned char lacing_values[255];
unsigned long size;
buf_t raw;
} ogg_page_t;
void ogg_page_init(ogg_page_t *page);
void ogg_page_destroy(ogg_page_t *page);
int ogg_write_page(file_t *ogg, ogg_page_t *page);
int ogg_next_page(file_t *ogg, ogg_page_t *page);
extern crc32_t ogg_crc32;
void ogg_init(void);
unsigned char *ogg_segment(ogg_page_t *page, int num);
unsigned long ogg_position_to_msecs(ogg_page_t *page,
unsigned long sample_rate);
#endif /* OGG_H__ */
/*C
**/
|