Changeset 2341

Show
Ignore:
Timestamp:
2006-06-20 23:32:36 (2 years ago)
Author:
shans
Message:

Added oggz_tell_granulepos function to query liboggz for granulepos values.
Added calculation of lost granulepos values for packets that are not on end of
page (theora and speex codecs only at this point).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • liboggz/trunk/include/oggz/oggz_seek.h

    r1338 r2341  
    107107 
    108108/** 
     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 */ 
     116ogg_int64_t 
     117oggz_tell_granulepos (OGGZ * oggz); 
     118 
     119/** 
    109120 * Query the file offset in bytes corresponding to the data read. 
    110121 * \param oggz An OGGZ handle 
  • liboggz/trunk/src/liboggz/Version_script.in

    r2339 r2341  
    4040 
    4141                oggz_tell; 
     42                oggz_tell_granulepos; 
    4243                oggz_tell_units; 
    4344                oggz_seek; 
  • liboggz/trunk/src/liboggz/oggz.c

    r2027 r2341  
    174174    oggz_free (stream->metric_user_data); 
    175175 
     176  if (stream->calculate_data != NULL) 
     177    oggz_free (stream->calculate_data); 
     178   
    176179  oggz_free (stream); 
    177180 
     
    235238  if (OGGZ_CONFIG_READ) { 
    236239    return reader->current_unit; 
     240  } else { 
     241    return OGGZ_ERR_DISABLED; 
     242  } 
     243} 
     244 
     245ogg_int64_t 
     246oggz_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; 
    237256  } else { 
    238257    return OGGZ_ERR_DISABLED; 
     
    320339  stream->read_page_user_data = NULL; 
    321340 
     341  stream->calculate_data = NULL; 
     342   
    322343  oggz_vector_insert_p (oggz->streams, stream); 
    323344 
  • liboggz/trunk/src/liboggz/oggz_auto.c

    r2339 r2341  
    4343#include <string.h> 
    4444 
    45 #include <oggz/oggz.h> 
    46 #include "oggz_auto.h" 
     45#include "oggz_private.h" 
    4746#include "oggz_byteorder.h" 
    48 #include "oggz_macros.h" 
    49 #include "oggz_stream.h" 
    5047 
    5148/*#define DEBUG*/ 
     
    318315} 
    319316 
     317static ogg_int64_t  
     318auto_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   
     347static ogg_int64_t  
     348auto_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 
    320392const 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
    332404};  
    333405 
     
    355427int 
    356428oggz_auto_get_granulerate (OGGZ * oggz, ogg_packet * op, long serialno,  
    357                 void * user_data) 
    358 
     429                void * user_data) { 
    359430  OggzReadPacket read_packet; 
    360431  int content = 0; 
     
    370441} 
    371442 
     443ogg_int64_t  
     444oggz_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 
    372454#endif /* OGGZ_CONFIG_READ */ 
  • liboggz/trunk/src/liboggz/oggz_private.h

    r2339 r2341  
    107107  OggzReadPage read_page; 
    108108  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; 
    109114}; 
    110115 
     
    123128 
    124129  ogg_int64_t current_unit; 
     130  ogg_int64_t current_granulepos; 
    125131 
    126132#if 0 
  • liboggz/trunk/src/liboggz/oggz_read.c

    r2339 r2341  
    291291 
    292292      if(result > 0){ 
     293        int content; 
     294         
    293295        /* got a packet.  process it */ 
    294296        granulepos = op->granulepos; 
    295297 
    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         
    301300        if  
    302301        ( 
    303           ( 
    304             !stream->metric  
    305             ||  
    306             (oggz_stream_get_content(oggz, serialno) == OGGZ_CONTENT_SKELETON) 
    307           )  
     302          (!stream->metric || (content == OGGZ_CONTENT_SKELETON))  
    308303          &&  
    309304          (oggz->flags & OGGZ_AUTO) 
     
    313308        } 
    314309 
     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         
    315319        /* set unit on last packet of page */ 
    316320        if ((oggz->metric || stream->metric) && granulepos != -1) { 
     
    366370 
    367371      granulepos = ogg_page_granulepos (&og); 
     372      stream->page_granulepos = granulepos; 
    368373 
    369374      if ((oggz->metric || stream->metric) && granulepos != -1) { 
  • liboggz/trunk/src/liboggz/oggz_stream.h

    r2339 r2341  
    3434#define __OGGZ_STREAM_H__ 
    3535 
     36typedef struct _oggz_stream_t oggz_stream_t; 
     37 
    3638typedef struct { 
    3739  const char      *bos_str; 
     
    3941  const char      *content_type; 
    4042  OggzReadPacket  reader; 
     43  ogg_int64_t     (*calculator)(ogg_int64_t now, oggz_stream_t *stream,  
     44                  ogg_packet *op); 
    4145} oggz_auto_contenttype_t; 
    4246 
    4347extern const oggz_auto_contenttype_t oggz_auto_codec_ident[]; 
    4448 
    45 typedef struct _oggz_stream_t oggz_stream_t; 
    4649 
    4750oggz_stream_t * oggz_get_stream (OGGZ * oggz, long serialno);