Changeset 3216

Show
Ignore:
Timestamp:
2007-09-02 21:57:14 (1 year ago)
Author:
shans
Message:

Code to generate initial granulepos values for packets before the end of the first page.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • liboggz/trunk/src/liboggz/oggz.c

    r3174 r3216  
    101101  oggz->order = NULL; 
    102102  oggz->order_user_data = NULL; 
     103 
     104  oggz->packet_buffer = oggz_dlist_new (); 
    103105 
    104106  if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) { 
  • liboggz/trunk/src/liboggz/oggz_auto.c

    r3205 r3216  
    444444 
    445445} 
     446 
     447auto_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 
    446466 
    447467/* 
     
    722742} 
    723743 
     744ogg_int64_t 
     745auto_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 
    724763/** 
    725764 * FLAC 
     
    839878 
    840879const 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
    852891};  
    853892 
     
    893932  if (oggz_auto_codec_ident[content].calculator != NULL) { 
    894933    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 are 
    897      * more than one packets on that page.  In the absence of pervasive access 
    898      * 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 packets 
    901      * except for the last on a page.  If the stream doesn't start at gp 0 (a 
    902      * very common occurrence) then we don't realise until we get to the end of 
    903      * the page.  By that time we've already junked the first packets on the  
    904      * page. 
    905      */ 
    906     /* 
    907     if (now != -1LL) { 
    908       return op->granulepos; 
    909     } 
    910     */ 
    911934    return r; 
    912935  }  
    913936 
    914937  return now; 
    915    
    916    
     938
     939 
     940ogg_int64_t 
     941oggz_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 
    917951} 
    918952 
  • liboggz/trunk/src/liboggz/oggz_dlist.c

    r3212 r3216  
    6464  dlist->tail = dummy_back; 
    6565 
     66  return dlist; 
     67 
    6668} 
    6769 
     
    7779  free(dlist->tail); 
    7880  free(dlist); 
     81 
     82  printf("dlist:DELETE complete\n"); 
    7983 
    8084} 
     
    138142oggz_dlist_deliter(OggzDList *dlist, OggzDListIterFunc func) { 
    139143 
    140   OggzDListElem *p
     144  OggzDListElem *p, *q
    141145 
    142   for (p = dlist->head->next; p != dlist->tail; p = p->next) { 
     146  for (p = dlist->head->next; p != dlist->tail; p = q) { 
    143147    if (func(p->data) == DLIST_ITER_CANCEL) { 
    144148      break; 
    145149    } 
    146150 
     151    q = p->next; 
    147152    p->prev->next = p->next; 
    148153    p->next->prev = p->prev; 
     
    156161oggz_dlist_reverse_deliter(OggzDList *dlist, OggzDListIterFunc func) { 
    157162 
    158   OggzDListElem *p
     163  OggzDListElem *p, *q
    159164 
    160   for (p = dlist->tail->prev; p != dlist->head; p = p->prev) { 
     165  for (p = dlist->tail->prev; p != dlist->head; p = q) { 
    161166    if (func(p->data) == DLIST_ITER_CANCEL) { 
    162167      break; 
    163168    } 
    164169 
     170    q = p->prev; 
    165171    p->prev->next = p->next; 
    166172    p->next->prev = p->prev; 
  • liboggz/trunk/src/liboggz/oggz_private.h

    r2957 r3216  
    4343#include "oggz_macros.h" 
    4444#include "oggz_vector.h" 
    45  
     45#include "oggz_dlist.h" 
    4646 
    4747typedef struct _OGGZ OGGZ; 
     
    119119  ogg_int64_t page_granulepos; 
    120120  void * calculate_data; 
     121  ogg_packet  * last_packet; 
    121122}; 
    122123 
     
    238239    OggzWriter writer; 
    239240  } x; 
     241 
     242  OggzDList * packet_buffer; 
    240243}; 
    241244 
  • liboggz/trunk/src/liboggz/oggz_read.c

    r2886 r3216  
    237237 
    238238  return ret; 
     239} 
     240 
     241typedef 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 
     250OggzBufferedPacket * 
     251oggz_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 
     269void 
     270oggz_read_free_pbuffer_entry(OggzBufferedPacket *p) { 
     271   
     272  free(p->packet.packet); 
     273  free(p); 
     274 
     275} 
     276 
     277OggzDListIterResponse 
     278oggz_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 
     296OggzDListIterResponse 
     297oggz_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; 
    239329} 
    240330 
     
    349439          } 
    350440 
     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 
    351479          if (stream->read_packet) { 
    352480            cb_ret = 
  • liboggz/trunk/src/liboggz/oggz_stream.h

    r2543 r3216  
    4343  ogg_int64_t     (*calculator)(ogg_int64_t now, oggz_stream_t *stream,  
    4444                  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); 
    4548} oggz_auto_contenttype_t; 
    4649 
     
    5861oggz_auto_calculate_granulepos(int content, ogg_int64_t now,  
    5962                oggz_stream_t *stream, ogg_packet *op); 
     63 
     64ogg_int64_t 
     65oggz_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 
    6068#endif /* __OGGZ_STREAM_H__ */