1 /* 2 Copyright (C) 2003 Commonwealth Scientific and Industrial Research 3 Organisation (CSIRO) Australia 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions 7 are met: 8 9 - Redistributions of source code must retain the above copyright 10 notice, this list of conditions and the following disclaimer. 11 12 - Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 - Neither the name of CSIRO Australia nor the names of its 17 contributors may be used to endorse or promote products derived from 18 this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR 24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef __OGGZ_PRIVATE_H__ 34 #define __OGGZ_PRIVATE_H__ 35 36 #include <stdio.h> 37 #include <sys/types.h> 38 39 #include <ogg/ogg.h> 40 #include <oggz/oggz_constants.h> 41 #include <oggz/oggz_off_t.h> 42 43 #include "oggz/oggz_packet.h" 44 45 #include "oggz_macros.h" 46 #include "oggz_vector.h" 47 #include "oggz_dlist.h" 48 49 #define OGGZ_AUTO_MULT 1000Ull 50 51 typedef struct _OGGZ OGGZ; 52 typedef struct _OggzComment OggzComment; 53 typedef struct _OggzIO OggzIO; 54 typedef struct _OggzReader OggzReader; 55 typedef struct _OggzWriter OggzWriter; 56 57 58 typedef int (*OggzReadPacket) (OGGZ * oggz, oggz_packet * op, long serialno, 59 void * user_data); 60 typedef int (*OggzReadPage) (OGGZ * oggz, const ogg_page * og, long serialno, 61 void * user_data); 62 63 /* oggz_stream */ 64 #include "oggz_stream_private.h" 65 66 typedef ogg_int64_t (*OggzMetric) (OGGZ * oggz, long serialno, 67 ogg_int64_t granulepos, 68 void * user_data); 69 70 typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target, 71 void * user_data); 72 73 typedef int (*OggzWriteHungry) (OGGZ * oggz, int empty, void * user_data); 74 75 /* oggz_io */ 76 typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n); 77 typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n); 78 typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence); 79 typedef long (*OggzIOTell) (void * user_handle); 80 typedef int (*OggzIOFlush) (void * user_handle); 81 82 struct _oggz_stream_t { 83 ogg_stream_state ogg_stream; 84 85 /** STATIC INFO */ 86 int content; 87 int numheaders; 88 int preroll; 89 ogg_int64_t granulerate_n; 90 ogg_int64_t granulerate_d; 91 ogg_int64_t first_granule; 92 ogg_int64_t basegranule; 93 int granuleshift; 94 95 /* The comments */ 96 char * vendor; 97 OggzVector * comments; 98 99 /** CURRENT STATE **/ 100 /* non b_o_s packet has been written (not just queued) */ 101 int delivered_non_b_o_s; 102 103 int b_o_s; /* beginning of stream */ 104 int e_o_s; /* end of stream */ 105 ogg_int64_t granulepos; 106 ogg_int64_t packetno; 107 108 /** CALLBACKS **/ 109 OggzMetric metric; 110 void * metric_user_data; 111 int metric_internal; 112 113 OggzOrder order; 114 void * order_user_data; 115 116 OggzReadPacket read_packet; 117 void * read_user_data; 118 119 OggzReadPage read_page; 120 void * read_page_user_data; 121 122 /* calculated granulepos values, not extracted values */ 123 ogg_int64_t last_granulepos; 124 ogg_int64_t page_granulepos; 125 void * calculate_data; 126 ogg_packet * last_packet; 127 }; 128 129 struct _OggzReader { 130 ogg_sync_state ogg_sync; 131 132 /* XXX: these two can prolly be removed again :) */ 133 ogg_stream_state ogg_stream; 134 long current_serialno; 135 136 OggzReadPacket read_packet; 137 void * read_user_data; 138 139 OggzReadPage read_page; 140 void * read_page_user_data; 141 142 ogg_int64_t current_unit; 143 ogg_int64_t current_granulepos; 144 145 /* Read positioning */ 146 long current_page_bytes; 147 148 /* Calculation of position */ 149 oggz_off_t current_packet_begin_page_offset; 150 int current_packet_pages; 151 int current_packet_begin_segment_index; 152 153 #if 0 154 oggz_off_t offset_page_end; /* offset of end of current page */ 155 #endif 156 }; 157 158 /** 159 * Bundle a packet with the stream it is being queued for; used in 160 * the packet_queue vector 161 */ 162 typedef struct { 163 ogg_packet op; 164 oggz_stream_t * stream; 165 int flush; 166 int * guard; 167 } oggz_writer_packet_t; 168 169 enum oggz_writer_state { 170 OGGZ_MAKING_PACKETS = 0, 171 OGGZ_WRITING_PAGES = 1 172 }; 173 174 struct _OggzWriter { 175 oggz_writer_packet_t * next_zpacket; /* stashed in case of FLUSH_BEFORE */ 176 OggzVector * packet_queue; 177 178 OggzWriteHungry hungry; 179 void * hungry_user_data; 180 int hungry_only_when_empty; 181 182 int writing; /* already mid-write; check for recursive writes */ 183 int state; /* OGGZ_MAKING_PACKETS or OGGZ_WRITING_PAGES */ 184 185 int flushing; /* whether current packet is being flushed or just paged out */ 186 187 #if 0 188 int eog; /* end of page */ 189 int eop; /* end of packet */ 190 #endif 191 int eos; /* end of stream */ 192 193 oggz_writer_packet_t * current_zpacket; 194 195 int packet_offset; /* n bytes already copied out of current packet */ 196 int page_offset; /* n bytes already copied out of current page */ 197 198 ogg_stream_state * current_stream; 199 200 int no_more_packets; /* used only in the local oggz_write loop to indicate 201 end of stream */ 202 203 }; 204 205 struct _OggzIO { 206 OggzIORead read; 207 void * read_user_handle; 208 209 OggzIOWrite write; 210 void * write_user_handle; 211 212 OggzIOSeek seek; 213 void * seek_user_handle; 214 215 OggzIOTell tell; 216 void * tell_user_handle; 217 218 OggzIOFlush flush; 219 void * flush_user_handle; 220 }; 221 222 struct _OggzComment { 223 /** The name of the comment, eg. "AUTHOR" */ 224 char * name; 225 226 /** The value of the comment, as UTF-8 */ 227 char * value; 228 }; 229 230 struct _OGGZ { 231 int flags; 232 FILE * file; 233 OggzIO * io; 234 235 ogg_packet current_packet; 236 ogg_page current_page; 237 238 oggz_off_t offset; /* offset of current page start */ 239 oggz_off_t offset_data_begin; /* offset of unit 0 page start */ 240 241 long run_blocksize; /* blocksize to use for oggz_run() */ 242 int cb_next; 243 244 OggzVector * streams; 245 int all_at_eos; /* all streams are at eos */ 246 247 OggzMetric metric; 248 void * metric_user_data; 249 int metric_internal; 250 251 OggzOrder order; 252 void * order_user_data; 253 254 union { 255 OggzReader reader; 256 OggzWriter writer; 257 } x; 258 259 OggzDList * packet_buffer; 260 }; 261 262 OGGZ * oggz_read_init (OGGZ * oggz); 263 OGGZ * oggz_read_close (OGGZ * oggz); 264 265 OGGZ * oggz_write_init (OGGZ * oggz); 266 int oggz_write_flush (OGGZ * oggz); 267 OGGZ * oggz_write_close (OGGZ * oggz); 268 269 int oggz_map_return_value_to_error (int cb_ret); 270 271 int oggz_get_bos (OGGZ * oggz, long serialno); 272 ogg_int64_t oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos); 273 274 int oggz_set_metric_internal (OGGZ * oggz, long serialno, OggzMetric metric, 275 void * user_data, int internal); 276 int oggz_has_metrics (OGGZ * oggz); 277 278 int oggz_purge (OGGZ * oggz); 279 280 /* metric_internal */ 281 282 int 283 oggz_set_granulerate (OGGZ * oggz, long serialno, 284 ogg_int64_t granule_rate_numerator, 285 ogg_int64_t granule_rate_denominator); 286 287 int 288 oggz_get_granulerate (OGGZ * oggz, long serialno, 289 ogg_int64_t * granulerate_n, 290 ogg_int64_t * granulerate_d); 291 292 int oggz_set_granuleshift (OGGZ * oggz, long serialno, int granuleshift); 293 int oggz_get_granuleshift (OGGZ * oggz, long serialno); 294 295 int oggz_set_first_granule (OGGZ * oggz, long serialno, ogg_int64_t first_granule); 296 297 int oggz_set_preroll (OGGZ * oggz, long serialno, int preroll); 298 int oggz_get_preroll (OGGZ * oggz, long serialno); 299 300 /* oggz_auto */ 301 302 int 303 oggz_auto_read_bos_page (OGGZ * oggz, ogg_page * og, long serialno, 304 void * user_data); 305 int 306 oggz_auto_read_bos_packet (OGGZ * oggz, ogg_packet * op, long serialno, 307 void * user_data); 308 309 int 310 oggz_auto_read_comments (OGGZ * oggz, oggz_stream_t * stream, long serialno, 311 ogg_packet * op); 312 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 /* comments */ 317 int oggz_comments_init (oggz_stream_t * stream); 318 int oggz_comments_free (oggz_stream_t * stream); 319 int oggz_comments_decode (OGGZ * oggz, long serialno, 320 unsigned char * comments, long length); 321 long oggz_comments_encode (OGGZ * oggz, long serialno, 322 unsigned char * buf, long length); 323 324 /* oggz_io */ 325 size_t oggz_io_read (OGGZ * oggz, void * buf, size_t n); 326 size_t oggz_io_write (OGGZ * oggz, void * buf, size_t n); 327 int oggz_io_seek (OGGZ * oggz, long offset, int whence); 328 long oggz_io_tell (OGGZ * oggz); 329 int oggz_io_flush (OGGZ * oggz); 330 331 /* oggz_read */ 332 OggzDListIterResponse oggz_read_free_pbuffers(void *elem); 333 334 #endif /* __OGGZ_PRIVATE_H__ */ 335