Changeset 2341
- Timestamp:
- 2006-06-20 23:32:36 (2 years ago)
- Files:
-
- liboggz/trunk/include/oggz/oggz_seek.h (modified) (1 diff)
- liboggz/trunk/src/liboggz/Version_script.in (modified) (1 diff)
- liboggz/trunk/src/liboggz/oggz.c (modified) (3 diffs)
- liboggz/trunk/src/liboggz/oggz_auto.c (modified) (4 diffs)
- liboggz/trunk/src/liboggz/oggz_private.h (modified) (2 diffs)
- liboggz/trunk/src/liboggz/oggz_read.c (modified) (3 diffs)
- liboggz/trunk/src/liboggz/oggz_stream.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
liboggz/trunk/include/oggz/oggz_seek.h
r1338 r2341 107 107 108 108 /** 109 * Provide the exact stored granulepos (from the page header) if relevant to 110 * the current packet, or a constructed granulepos if the stored granulepos 111 * does not belong to this packet, or -1 if this codec does not have support 112 * for granulepos interpolation 113 * \param oggz An OGGZ handle 114 * \returns the granulepos of the \a current packet (if available) 115 */ 116 ogg_int64_t 117 oggz_tell_granulepos (OGGZ * oggz); 118 119 /** 109 120 * Query the file offset in bytes corresponding to the data read. 110 121 * \param oggz An OGGZ handle liboggz/trunk/src/liboggz/Version_script.in
r2339 r2341 40 40 41 41 oggz_tell; 42 oggz_tell_granulepos; 42 43 oggz_tell_units; 43 44 oggz_seek; liboggz/trunk/src/liboggz/oggz.c
r2027 r2341 174 174 oggz_free (stream->metric_user_data); 175 175 176 if (stream->calculate_data != NULL) 177 oggz_free (stream->calculate_data); 178 176 179 oggz_free (stream); 177 180 … … 235 238 if (OGGZ_CONFIG_READ) { 236 239 return reader->current_unit; 240 } else { 241 return OGGZ_ERR_DISABLED; 242 } 243 } 244 245 ogg_int64_t 246 oggz_tell_granulepos (OGGZ * oggz) 247 { 248 if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; 249 250 if (oggz->flags & OGGZ_WRITE) { 251 return OGGZ_ERR_INVALID; 252 } 253 254 if (OGGZ_CONFIG_READ) { 255 return oggz->x.reader.current_granulepos; 237 256 } else { 238 257 return OGGZ_ERR_DISABLED; … … 320 339 stream->read_page_user_data = NULL; 321 340 341 stream->calculate_data = NULL; 342 322 343 oggz_vector_insert_p (oggz->streams, stream); 323 344 liboggz/trunk/src/liboggz/oggz_auto.c
r2339 r2341 43 43 #include <string.h> 44 44 45 #include <oggz/oggz.h> 46 #include "oggz_auto.h" 45 #include "oggz_private.h" 47 46 #include "oggz_byteorder.h" 48 #include "oggz_macros.h"49 #include "oggz_stream.h"50 47 51 48 /*#define DEBUG*/ … … 318 315 } 319 316 317 static ogg_int64_t 318 auto_calc_speex(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { 319 320 /* 321 * on the first (b_o_s) packet, set calculate_data to be the number 322 * of speex frames per packet 323 */ 324 if (stream->calculate_data == NULL) { 325 stream->calculate_data = malloc(sizeof(int)); 326 *(int *)stream->calculate_data = 327 (*(int *)(op->packet + 64)) * (*(int *)(op->packet + 56)); 328 } 329 330 if (now > -1) 331 return now; 332 333 /* 334 * the first data packet has smaller-than-usual granulepos to account 335 * for the fact that several of the output samples from the beginning 336 * of this packet need to be thrown away. We calculate the granulepos 337 * by taking the mod of the page's granulepos with respect to the increment 338 * between packets. 339 */ 340 if (stream->last_granulepos == 0) { 341 return stream->page_granulepos % *(int *)(stream->calculate_data); 342 } 343 344 return stream->last_granulepos + *(int *)(stream->calculate_data); 345 } 346 347 static ogg_int64_t 348 auto_calc_theora(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { 349 350 long keyframe_no; 351 int keyframe_shift; 352 unsigned char first_byte; 353 354 if (now > (ogg_int64_t)(-1)) 355 return now; 356 357 first_byte = op->packet[0]; 358 359 if (first_byte & 0x80) 360 { 361 /* header packet */ 362 return (ogg_int64_t)0; 363 } 364 365 if (first_byte & 0x40) 366 { 367 /* inter-coded packet */ 368 return stream->last_granulepos + 1; 369 } 370 371 /* intra-coded packet */ 372 if (stream->last_granulepos == 0) 373 { 374 /* first intra-coded packet */ 375 return (ogg_int64_t)0; 376 } 377 378 keyframe_shift = stream->granuleshift; 379 /* 380 * retrieve last keyframe number 381 */ 382 keyframe_no = (int)(stream->last_granulepos >> keyframe_shift); 383 /* 384 * add frames since last keyframe number 385 */ 386 keyframe_no += (stream->last_granulepos & ((1 << keyframe_shift) - 1)) + 1; 387 return ((ogg_int64_t)keyframe_no) << keyframe_shift; 388 389 390 } 391 320 392 const oggz_auto_contenttype_t oggz_auto_codec_ident[] = { 321 {"\200theora", 7, "Theora", auto_theora },322 {"\001vorbis", 7, "Vorbis", auto_vorbis },323 {"Speex", 5, "Speex", auto_speex },324 {"PCM ", 8, "PCM", auto_oggpcm2 },325 {"CMML\0\0\0\0", 8, "CMML", auto_cmml },326 {"Annodex", 8, "Annodex", auto_annodex },327 {"fishead", 7, "Skeleton", auto_fishead },328 {"fLaC", 4, "Flac0", auto_flac0 },329 {"\177FLAC", 4, "Flac", auto_flac },330 {"AnxData", 7, "AnxData", auto_anxdata },331 {"", 0, "Unknown" }393 {"\200theora", 7, "Theora", auto_theora, auto_calc_theora}, 394 {"\001vorbis", 7, "Vorbis", auto_vorbis, NULL}, 395 {"Speex", 5, "Speex", auto_speex, auto_calc_speex}, 396 {"PCM ", 8, "PCM", auto_oggpcm2, NULL}, 397 {"CMML\0\0\0\0", 8, "CMML", auto_cmml, NULL}, 398 {"Annodex", 8, "Annodex", auto_annodex, NULL}, 399 {"fishead", 7, "Skeleton", auto_fishead, NULL}, 400 {"fLaC", 4, "Flac0", auto_flac0, NULL}, 401 {"\177FLAC", 4, "Flac", auto_flac, NULL}, 402 {"AnxData", 7, "AnxData", auto_anxdata, NULL}, 403 {"", 0, "Unknown", NULL} 332 404 }; 333 405 … … 355 427 int 356 428 oggz_auto_get_granulerate (OGGZ * oggz, ogg_packet * op, long serialno, 357 void * user_data) 358 { 429 void * user_data) { 359 430 OggzReadPacket read_packet; 360 431 int content = 0; … … 370 441 } 371 442 443 ogg_int64_t 444 oggz_auto_calculate_granulepos(int content, ogg_int64_t now, 445 oggz_stream_t *stream, ogg_packet *op) { 446 if (oggz_auto_codec_ident[content].calculator != NULL) { 447 return oggz_auto_codec_ident[content].calculator(now, stream, op); 448 } else { 449 return now; 450 } 451 452 } 453 372 454 #endif /* OGGZ_CONFIG_READ */ liboggz/trunk/src/liboggz/oggz_private.h
r2339 r2341 107 107 OggzReadPage read_page; 108 108 void * read_page_user_data; 109 110 /* calculated granulepos values, not extracted values */ 111 ogg_int64_t last_granulepos; 112 ogg_int64_t page_granulepos; 113 void * calculate_data; 109 114 }; 110 115 … … 123 128 124 129 ogg_int64_t current_unit; 130 ogg_int64_t current_granulepos; 125 131 126 132 #if 0 liboggz/trunk/src/liboggz/oggz_read.c
r2339 r2341 291 291 292 292 if(result > 0){ 293 int content; 294 293 295 /* got a packet. process it */ 294 296 granulepos = op->granulepos; 295 297 296 /* 297 * need to call oggz_auto to process Anx v2 streams which were headed 298 * with AnxData packets. This enables the AnxData-provided granulerate 299 * to be overridden by the stream's rate if present 300 */ 298 content = oggz_stream_get_content(oggz, serialno); 299 301 300 if 302 301 ( 303 ( 304 !stream->metric 305 || 306 (oggz_stream_get_content(oggz, serialno) == OGGZ_CONTENT_SKELETON) 307 ) 302 (!stream->metric || (content == OGGZ_CONTENT_SKELETON)) 308 303 && 309 304 (oggz->flags & OGGZ_AUTO) … … 313 308 } 314 309 310 /* attempt to determine granulepos for this packet */ 311 if (oggz->flags & OGGZ_AUTO) { 312 reader->current_granulepos = oggz_auto_calculate_granulepos (content, 313 granulepos, stream, op); 314 } else { 315 reader->current_granulepos = granulepos; 316 } 317 stream->last_granulepos = reader->current_granulepos; 318 315 319 /* set unit on last packet of page */ 316 320 if ((oggz->metric || stream->metric) && granulepos != -1) { … … 366 370 367 371 granulepos = ogg_page_granulepos (&og); 372 stream->page_granulepos = granulepos; 368 373 369 374 if ((oggz->metric || stream->metric) && granulepos != -1) { liboggz/trunk/src/liboggz/oggz_stream.h
r2339 r2341 34 34 #define __OGGZ_STREAM_H__ 35 35 36 typedef struct _oggz_stream_t oggz_stream_t; 37 36 38 typedef struct { 37 39 const char *bos_str; … … 39 41 const char *content_type; 40 42 OggzReadPacket reader; 43 ogg_int64_t (*calculator)(ogg_int64_t now, oggz_stream_t *stream, 44 ogg_packet *op); 41 45 } oggz_auto_contenttype_t; 42 46 43 47 extern const oggz_auto_contenttype_t oggz_auto_codec_ident[]; 44 48 45 typedef struct _oggz_stream_t oggz_stream_t;46 49 47 50 oggz_stream_t * oggz_get_stream (OGGZ * oggz, long serialno);