oggz_private.h 9.1 KB
Newer Older
andre's avatar
andre committed
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
/*
   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
   Organisation (CSIRO) Australia

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

   - Neither the name of CSIRO Australia nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef __OGGZ_PRIVATE_H__
#define __OGGZ_PRIVATE_H__

conrad's avatar
conrad committed
36
#include <stdio.h>
silvia's avatar
silvia committed
37
#include <sys/types.h>
conrad's avatar
conrad committed
38

andre's avatar
andre committed
39 40
#include <ogg/ogg.h>
#include <oggz/oggz_constants.h>
41 42
#include <oggz/oggz_off_t.h>

43 44
#include "oggz/oggz_packet.h"

conrad's avatar
conrad committed
45
#include "oggz_macros.h"
andre's avatar
andre committed
46
#include "oggz_vector.h"
47
#include "oggz_dlist.h"
48

49 50
#define OGGZ_AUTO_MULT 1000Ull

andre's avatar
andre committed
51
typedef struct _OGGZ OGGZ;
52
typedef struct _OggzComment OggzComment;
53
typedef struct _OggzIO OggzIO;
andre's avatar
andre committed
54 55 56
typedef struct _OggzReader OggzReader;
typedef struct _OggzWriter OggzWriter;

57

58
typedef int (*OggzReadPacket) (OGGZ * oggz, oggz_packet * op, long serialno,
andre's avatar
andre committed
59
			       void * user_data);
60
typedef int (*OggzReadPage) (OGGZ * oggz, const ogg_page * og, long serialno,
61
			     void * user_data);
andre's avatar
andre committed
62

63
/* oggz_stream */
64
#include "oggz_stream_private.h"
65

andre's avatar
andre committed
66 67 68 69 70 71 72 73 74
typedef ogg_int64_t (*OggzMetric) (OGGZ * oggz, long serialno,
				   ogg_int64_t granulepos,
				   void * user_data);

typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target,
			  void * user_data);

typedef int (*OggzWriteHungry) (OGGZ * oggz, int empty, void * user_data);

75 76 77 78 79 80 81
/* oggz_io */
typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n);
typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n);
typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence);
typedef long (*OggzIOTell) (void * user_handle);
typedef int (*OggzIOFlush) (void * user_handle);

82
struct _oggz_stream_t {
andre's avatar
andre committed
83 84
  ogg_stream_state ogg_stream;

85
  /** STATIC INFO */
86
  int content;
87
  int numheaders;
88 89 90
  int preroll;
  ogg_int64_t granulerate_n;
  ogg_int64_t granulerate_d;
91
  ogg_int64_t first_granule;
92 93 94
  ogg_int64_t basegranule;
  int granuleshift;

95 96 97 98
  /* The comments */
  char * vendor;
  OggzVector * comments;

99
  /** CURRENT STATE **/
andre's avatar
andre committed
100 101 102 103 104 105 106 107
  /* non b_o_s packet has been written (not just queued) */
  int delivered_non_b_o_s;

  int b_o_s; /* beginning of stream */
  int e_o_s; /* end of stream */
  ogg_int64_t granulepos;
  ogg_int64_t packetno;

108
  /** CALLBACKS **/
andre's avatar
andre committed
109 110 111 112 113 114 115 116 117
  OggzMetric metric;
  void * metric_user_data;
  int metric_internal;

  OggzOrder order;
  void * order_user_data;

  OggzReadPacket read_packet;
  void * read_user_data;
118 119 120

  OggzReadPage read_page;
  void * read_page_user_data;
121 122 123 124 125

  /* calculated granulepos values, not extracted values */
  ogg_int64_t last_granulepos;
  ogg_int64_t page_granulepos;
  void * calculate_data;
126
  ogg_packet * last_packet;
127
};
andre's avatar
andre committed
128 129 130 131 132 133 134 135 136 137 138

struct _OggzReader {
  ogg_sync_state ogg_sync;

  /* XXX: these two can prolly be removed again :) */
  ogg_stream_state ogg_stream;
  long current_serialno;

  OggzReadPacket read_packet;
  void * read_user_data;

139 140 141
  OggzReadPage read_page;
  void * read_page_user_data;

andre's avatar
andre committed
142
  ogg_int64_t current_unit;
143
  ogg_int64_t current_granulepos;
andre's avatar
andre committed
144

145
  /* Read positioning */
146
  long current_page_bytes;
147

148
  /* Calculation of position */
149 150
  oggz_off_t current_packet_begin_page_offset;
  int current_packet_pages;
151
  int current_packet_begin_segment_index;
152

andre's avatar
andre committed
153
#if 0
154
  oggz_off_t offset_page_end; /* offset of end of current page */
andre's avatar
andre committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
#endif
};

/**
 * Bundle a packet with the stream it is being queued for; used in
 * the packet_queue vector
 */
typedef struct {
  ogg_packet op;
  oggz_stream_t * stream;
  int flush;
  int * guard;
} oggz_writer_packet_t;

enum oggz_writer_state {
  OGGZ_MAKING_PACKETS = 0,
  OGGZ_WRITING_PAGES = 1
};

struct _OggzWriter {
  oggz_writer_packet_t * next_zpacket; /* stashed in case of FLUSH_BEFORE */
conrad's avatar
conrad committed
176
  OggzVector * packet_queue;
andre's avatar
andre committed
177 178 179 180 181 182 183 184 185 186 187

  OggzWriteHungry hungry;
  void * hungry_user_data;
  int hungry_only_when_empty;

  int writing; /* already mid-write; check for recursive writes */
  int state; /* OGGZ_MAKING_PACKETS or OGGZ_WRITING_PAGES */

  int flushing; /* whether current packet is being flushed or just paged out */

#if 0
188
  int eog; /* end of page */
andre's avatar
andre committed
189 190 191 192 193 194 195 196 197 198
  int eop; /* end of packet */
#endif
  int eos; /* end of stream */

  oggz_writer_packet_t * current_zpacket;

  int packet_offset; /* n bytes already copied out of current packet */
  int page_offset; /* n bytes already copied out of current page */

  ogg_stream_state * current_stream;
199 200 201 202

  int no_more_packets; /* used only in the local oggz_write loop to indicate
                          end of stream */

andre's avatar
andre committed
203 204
};

205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
struct _OggzIO {
  OggzIORead read;
  void * read_user_handle;

  OggzIOWrite write;
  void * write_user_handle;

  OggzIOSeek seek;
  void * seek_user_handle;

  OggzIOTell tell;
  void * tell_user_handle;

  OggzIOFlush flush;
  void * flush_user_handle;
};

222 223 224 225 226 227 228 229
struct _OggzComment {
  /** The name of the comment, eg. "AUTHOR" */
  char * name;

  /** The value of the comment, as UTF-8 */
  char * value;
};

andre's avatar
andre committed
230 231
struct _OGGZ {
  int flags;
conrad's avatar
conrad committed
232
  FILE * file;
233
  OggzIO * io;
andre's avatar
andre committed
234 235 236 237

  ogg_packet current_packet;
  ogg_page current_page;

238 239
  oggz_off_t offset; /* offset of current page start */
  oggz_off_t offset_data_begin; /* offset of unit 0 page start */
andre's avatar
andre committed
240

241
  long run_blocksize; /* blocksize to use for oggz_run() */
242 243
  int cb_next;

conrad's avatar
conrad committed
244
  OggzVector * streams;
andre's avatar
andre committed
245 246 247 248 249 250 251 252 253 254 255 256 257
  int all_at_eos; /* all streams are at eos */

  OggzMetric metric;
  void * metric_user_data;
  int metric_internal;

  OggzOrder order;
  void * order_user_data;

  union {
    OggzReader reader;
    OggzWriter writer;
  } x;
258 259

  OggzDList * packet_buffer;
andre's avatar
andre committed
260 261 262 263 264 265
};

OGGZ * oggz_read_init (OGGZ * oggz);
OGGZ * oggz_read_close (OGGZ * oggz);

OGGZ * oggz_write_init (OGGZ * oggz);
266
int oggz_write_flush (OGGZ * oggz);
andre's avatar
andre committed
267 268
OGGZ * oggz_write_close (OGGZ * oggz);

269 270
int oggz_map_return_value_to_error (int cb_ret);

andre's avatar
andre committed
271 272 273
int oggz_get_bos (OGGZ * oggz, long serialno);
ogg_int64_t oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos);

conrad's avatar
conrad committed
274 275
int oggz_set_metric_internal (OGGZ * oggz, long serialno, OggzMetric metric,
			      void * user_data, int internal);
276
int oggz_has_metrics (OGGZ * oggz);
conrad's avatar
conrad committed
277

278 279
int oggz_purge (OGGZ * oggz);

280
/* metric_internal */
conrad's avatar
conrad committed
281

282 283 284 285 286 287 288 289 290 291
int
oggz_set_granulerate (OGGZ * oggz, long serialno, 
                                    ogg_int64_t granule_rate_numerator,
                                    ogg_int64_t granule_rate_denominator);

int
oggz_get_granulerate (OGGZ * oggz, long serialno,
                                    ogg_int64_t * granulerate_n,
                                    ogg_int64_t * granulerate_d);

292 293 294
int oggz_set_granuleshift (OGGZ * oggz, long serialno, int granuleshift);
int oggz_get_granuleshift (OGGZ * oggz, long serialno);

295 296
int oggz_set_first_granule (OGGZ * oggz, long serialno, ogg_int64_t first_granule);

297 298 299
int oggz_set_preroll (OGGZ * oggz, long serialno, int preroll);
int oggz_get_preroll (OGGZ * oggz, long serialno);

300 301 302
/* oggz_auto */
 
int
303 304 305 306
oggz_auto_read_bos_page (OGGZ * oggz, ogg_page * og, long serialno,
                         void * user_data);
int
oggz_auto_read_bos_packet (OGGZ * oggz, ogg_packet * op, long serialno, 
307 308
                           void * user_data);

309 310 311 312
int
oggz_auto_read_comments (OGGZ * oggz, oggz_stream_t * stream, long serialno,
                         ogg_packet * op);

313
int oggz_auto_identify_page (OGGZ *oggz, ogg_page *og, long serialno);
314
int oggz_auto_identify_packet (OGGZ * oggz, ogg_packet * op, long serialno);
315

316 317 318 319 320 321 322 323
/* comments */
int oggz_comments_init (oggz_stream_t * stream);
int oggz_comments_free (oggz_stream_t * stream);
int oggz_comments_decode (OGGZ * oggz, long serialno,
                          unsigned char * comments, long length);
long oggz_comments_encode (OGGZ * oggz, long serialno,
                           unsigned char * buf, long length);

324 325 326 327 328 329 330
/* oggz_io */
size_t oggz_io_read (OGGZ * oggz, void * buf, size_t n);
size_t oggz_io_write (OGGZ * oggz, void * buf, size_t n);
int oggz_io_seek (OGGZ * oggz, long offset, int whence);
long oggz_io_tell (OGGZ * oggz);
int oggz_io_flush (OGGZ * oggz);

331 332 333
/* oggz_read */
OggzDListIterResponse oggz_read_free_pbuffers(void *elem);

andre's avatar
andre committed
334
#endif /* __OGGZ_PRIVATE_H__ */