Changeset 3216
- Timestamp:
- 2007-09-02 21:57:14 (1 year ago)
- Files:
-
- liboggz/trunk/src/liboggz/oggz.c (modified) (1 diff)
- liboggz/trunk/src/liboggz/oggz_auto.c (modified) (4 diffs)
- liboggz/trunk/src/liboggz/oggz_dlist.c (modified) (4 diffs)
- liboggz/trunk/src/liboggz/oggz_private.h (modified) (3 diffs)
- liboggz/trunk/src/liboggz/oggz_read.c (modified) (2 diffs)
- liboggz/trunk/src/liboggz/oggz_stream.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
liboggz/trunk/src/liboggz/oggz.c
r3174 r3216 101 101 oggz->order = NULL; 102 102 oggz->order_user_data = NULL; 103 104 oggz->packet_buffer = oggz_dlist_new (); 103 105 104 106 if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) { liboggz/trunk/src/liboggz/oggz_auto.c
r3205 r3216 444 444 445 445 } 446 447 auto_rcalc_theora(ogg_int64_t next_packet_gp, oggz_stream_t *stream, 448 ogg_packet *this_packet, ogg_packet *next_packet) { 449 450 int keyframe = (int)(next_packet_gp >> stream->granuleshift); 451 int offset = (int)(next_packet_gp - (keyframe << stream->granuleshift)); 452 453 /* assume kf is 60 frames ago. NOTE: This is going to cause problems, 454 * but I can't think of what else to do. The position of the last kf 455 * is fundamentally unknowable. 456 */ 457 if (offset == 0) { 458 return ((keyframe - 60L) << stream->granuleshift) + 59; 459 } 460 else { 461 return (((ogg_int64_t)keyframe) << stream->granuleshift) + (offset - 1); 462 } 463 464 } 465 446 466 447 467 /* … … 722 742 } 723 743 744 ogg_int64_t 745 auto_rcalc_vorbis(ogg_int64_t next_packet_gp, oggz_stream_t *stream, 746 ogg_packet *this_packet, ogg_packet *next_packet) { 747 748 auto_calc_vorbis_info_t *info = 749 (auto_calc_vorbis_info_t *)stream->calculate_data; 750 751 int mode = 752 (this_packet->packet[0] >> 1) & ((1 << info->log2_num_modes) - 1); 753 int this_size = info->mode_sizes[mode] ? info->long_size : info->short_size; 754 int next_size; 755 756 mode = (next_packet->packet[0] >> 1) & ((1 << info->log2_num_modes) - 1); 757 next_size = info->mode_sizes[mode] ? info->long_size : info->short_size; 758 759 return next_packet_gp - ((this_size + next_size) / 4); 760 761 } 762 724 763 /** 725 764 * FLAC … … 839 878 840 879 const oggz_auto_contenttype_t oggz_auto_codec_ident[] = { 841 {"\200theora", 7, "Theora", auto_theora, auto_calc_theora },842 {"\001vorbis", 7, "Vorbis", auto_vorbis, auto_calc_vorbis },843 {"Speex", 5, "Speex", auto_speex, auto_calc_speex },844 {"PCM ", 8, "PCM", auto_oggpcm2, NULL },845 {"CMML\0\0\0\0", 8, "CMML", auto_cmml, NULL },846 {"Annodex", 8, "Annodex", auto_annodex, NULL },847 {"fishead", 7, "Skeleton", auto_fishead, NULL },848 {"fLaC", 4, "Flac0", auto_flac0, auto_calc_flac },849 {"\177FLAC", 4, "Flac", auto_flac, auto_calc_flac },850 {"AnxData", 7, "AnxData", auto_anxdata, NULL },851 {"", 0, "Unknown", NULL, NULL }880 {"\200theora", 7, "Theora", auto_theora, auto_calc_theora, auto_rcalc_theora}, 881 {"\001vorbis", 7, "Vorbis", auto_vorbis, auto_calc_vorbis, auto_rcalc_vorbis}, 882 {"Speex", 5, "Speex", auto_speex, auto_calc_speex, NULL}, 883 {"PCM ", 8, "PCM", auto_oggpcm2, NULL, NULL}, 884 {"CMML\0\0\0\0", 8, "CMML", auto_cmml, NULL, NULL}, 885 {"Annodex", 8, "Annodex", auto_annodex, NULL, NULL}, 886 {"fishead", 7, "Skeleton", auto_fishead, NULL, NULL}, 887 {"fLaC", 4, "Flac0", auto_flac0, auto_calc_flac, NULL}, 888 {"\177FLAC", 4, "Flac", auto_flac, auto_calc_flac, NULL}, 889 {"AnxData", 7, "AnxData", auto_anxdata, NULL, NULL}, 890 {"", 0, "Unknown", NULL, NULL, NULL} 852 891 }; 853 892 … … 893 932 if (oggz_auto_codec_ident[content].calculator != NULL) { 894 933 ogg_int64_t r = oggz_auto_codec_ident[content].calculator(now, stream, op); 895 /*896 * this will cause a hiccough at the end of the first data page if there are897 * more than one packets on that page. In the absence of pervasive access898 * to the packets on a page, though, it might have to do.899 *900 * Why a hiccough? Because there's no granulepos attached to any packets901 * except for the last on a page. If the stream doesn't start at gp 0 (a902 * very common occurrence) then we don't realise until we get to the end of903 * the page. By that time we've already junked the first packets on the904 * page.905 */906 /*907 if (now != -1LL) {908 return op->granulepos;909 }910 */911 934 return r; 912 935 } 913 936 914 937 return now; 915 916 938 } 939 940 ogg_int64_t 941 oggz_auto_calculate_gp_backwards(int content, ogg_int64_t next_packet_gp, 942 oggz_stream_t *stream, ogg_packet *this_packet, ogg_packet *next_packet) { 943 944 if (oggz_auto_codec_ident[content].r_calculator != NULL) { 945 return oggz_auto_codec_ident[content].r_calculator(next_packet_gp, 946 stream, this_packet, next_packet); 947 } 948 949 return 0; 950 917 951 } 918 952 liboggz/trunk/src/liboggz/oggz_dlist.c
r3212 r3216 64 64 dlist->tail = dummy_back; 65 65 66 return dlist; 67 66 68 } 67 69 … … 77 79 free(dlist->tail); 78 80 free(dlist); 81 82 printf("dlist:DELETE complete\n"); 79 83 80 84 } … … 138 142 oggz_dlist_deliter(OggzDList *dlist, OggzDListIterFunc func) { 139 143 140 OggzDListElem *p ;144 OggzDListElem *p, *q; 141 145 142 for (p = dlist->head->next; p != dlist->tail; p = p->next) {146 for (p = dlist->head->next; p != dlist->tail; p = q) { 143 147 if (func(p->data) == DLIST_ITER_CANCEL) { 144 148 break; 145 149 } 146 150 151 q = p->next; 147 152 p->prev->next = p->next; 148 153 p->next->prev = p->prev; … … 156 161 oggz_dlist_reverse_deliter(OggzDList *dlist, OggzDListIterFunc func) { 157 162 158 OggzDListElem *p ;163 OggzDListElem *p, *q; 159 164 160 for (p = dlist->tail->prev; p != dlist->head; p = p->prev) {165 for (p = dlist->tail->prev; p != dlist->head; p = q) { 161 166 if (func(p->data) == DLIST_ITER_CANCEL) { 162 167 break; 163 168 } 164 169 170 q = p->prev; 165 171 p->prev->next = p->next; 166 172 p->next->prev = p->prev; liboggz/trunk/src/liboggz/oggz_private.h
r2957 r3216 43 43 #include "oggz_macros.h" 44 44 #include "oggz_vector.h" 45 45 #include "oggz_dlist.h" 46 46 47 47 typedef struct _OGGZ OGGZ; … … 119 119 ogg_int64_t page_granulepos; 120 120 void * calculate_data; 121 ogg_packet * last_packet; 121 122 }; 122 123 … … 238 239 OggzWriter writer; 239 240 } x; 241 242 OggzDList * packet_buffer; 240 243 }; 241 244 liboggz/trunk/src/liboggz/oggz_read.c
r2886 r3216 237 237 238 238 return ret; 239 } 240 241 typedef struct { 242 ogg_packet packet; 243 ogg_int64_t calced_granulepos; 244 oggz_stream_t * stream; 245 OggzReader * reader; 246 OGGZ * oggz; 247 long serialno; 248 } OggzBufferedPacket; 249 250 OggzBufferedPacket * 251 oggz_read_new_pbuffer_entry(OGGZ *oggz, ogg_packet *packet, 252 ogg_int64_t granulepos, long serialno, oggz_stream_t * stream, 253 OggzReader *reader) { 254 255 OggzBufferedPacket *p = malloc(sizeof(OggzBufferedPacket)); 256 memcpy(&(p->packet), packet, sizeof(ogg_packet)); 257 p->packet.packet = malloc(packet->bytes); 258 memcpy(p->packet.packet, packet->packet, packet->bytes); 259 260 p->calced_granulepos = granulepos; 261 p->stream = stream; 262 p->serialno = serialno; 263 p->reader = reader; 264 p->oggz = oggz; 265 266 return p; 267 } 268 269 void 270 oggz_read_free_pbuffer_entry(OggzBufferedPacket *p) { 271 272 free(p->packet.packet); 273 free(p); 274 275 } 276 277 OggzDListIterResponse 278 oggz_read_update_gp(void *elem) { 279 280 OggzBufferedPacket *p = (OggzBufferedPacket *)elem; 281 282 if (p->calced_granulepos == -1 && p->stream->last_granulepos != -1) { 283 int content = oggz_stream_get_content(p->oggz, p->serialno); 284 p->calced_granulepos = 285 oggz_auto_calculate_gp_backwards(content, p->stream->last_granulepos, 286 p->stream, &(p->packet), p->stream->last_packet); 287 288 p->stream->last_granulepos = p->calced_granulepos; 289 p->stream->last_packet = &(p->packet); 290 } 291 292 return DLIST_ITER_CONTINUE; 293 294 } 295 296 OggzDListIterResponse 297 oggz_read_deliver_packet(void *elem) { 298 299 OggzBufferedPacket *p = (OggzBufferedPacket *)elem; 300 ogg_int64_t gp_stored; 301 long unit_stored; 302 303 if (p->calced_granulepos == -1) { 304 return DLIST_ITER_CANCEL; 305 } 306 307 gp_stored = p->reader->current_granulepos; 308 unit_stored = p->reader->current_unit; 309 310 p->reader->current_granulepos = p->calced_granulepos; 311 312 p->reader->current_unit = 313 oggz_get_unit (p->oggz, p->serialno, p->calced_granulepos); 314 315 if (p->stream->read_packet) { 316 p->stream->read_packet(p->oggz, &(p->packet), p->serialno, 317 p->stream->read_user_data); 318 } else if (p->reader->read_packet) { 319 p->reader->read_packet(p->oggz, &(p->packet), p->serialno, 320 p->reader->read_user_data); 321 } 322 323 p->reader->current_granulepos = gp_stored; 324 p->reader->current_unit = unit_stored; 325 326 oggz_read_free_pbuffer_entry(p); 327 328 return DLIST_ITER_CONTINUE; 239 329 } 240 330 … … 349 439 } 350 440 441 /* 442 * while we are getting invalid granulepos values, store the incoming 443 * packets in a dlist */ 444 if (reader->current_granulepos == -1) { 445 OggzBufferedPacket *p = oggz_read_new_pbuffer_entry( 446 oggz, &packet, reader->current_granulepos, 447 serialno, stream, reader); 448 449 oggz_dlist_append(oggz->packet_buffer, p); 450 continue; 451 } else if (!oggz_dlist_is_empty(oggz->packet_buffer)) { 452 /* 453 * move backward through the list assigning gp values based upon 454 * the granulepos we just recieved. Then move forward through 455 * the list delivering any packets at the beginning with valid 456 * gp values 457 */ 458 ogg_int64_t gp_stored = stream->last_granulepos; 459 stream->last_packet = &packet; 460 oggz_dlist_reverse_iter(oggz->packet_buffer, oggz_read_update_gp); 461 oggz_dlist_deliter(oggz->packet_buffer, oggz_read_deliver_packet); 462 463 /* 464 * fix up the stream granulepos 465 */ 466 stream->last_granulepos = gp_stored; 467 468 if (!oggz_dlist_is_empty(oggz->packet_buffer)) { 469 OggzBufferedPacket *p = oggz_read_new_pbuffer_entry( 470 oggz, &packet, reader->current_granulepos, 471 serialno, stream, reader); 472 473 oggz_dlist_append(oggz->packet_buffer, p); 474 continue; 475 } 476 477 } 478 351 479 if (stream->read_packet) { 352 480 cb_ret = liboggz/trunk/src/liboggz/oggz_stream.h
r2543 r3216 43 43 ogg_int64_t (*calculator)(ogg_int64_t now, oggz_stream_t *stream, 44 44 ogg_packet *op); 45 ogg_int64_t (*r_calculator)(ogg_int64_t next_packet_gp, 46 oggz_stream_t *stream, ogg_packet *this_packet, 47 ogg_packet *next_packet); 45 48 } oggz_auto_contenttype_t; 46 49 … … 58 61 oggz_auto_calculate_granulepos(int content, ogg_int64_t now, 59 62 oggz_stream_t *stream, ogg_packet *op); 63 64 ogg_int64_t 65 oggz_auto_calculate_gp_backwards(int content, ogg_int64_t next_packet_gp, 66 oggz_stream_t *stream, ogg_packet *this_packet, ogg_packet *next_packet); 67 60 68 #endif /* __OGGZ_STREAM_H__ */