Changeset 3742

Show
Ignore:
Timestamp:
2008-10-27 01:45:04 (2 months ago)
Author:
conrad
Message:

anx_import_ogg: re-order functions into separate sections for setup, read, open

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libannodex/trunk/src/importers/anx_import_ogg.c

    r3741 r3742  
    279279 
    280280/*********************************************************** 
    281  *  
     281 * Setup 
    282282 */ 
    283 static double 
    284 anxogg_seek_update (AnxSource * source) 
    285 
    286   AnxOggData * aod = (AnxOggData *)source->custom_data; 
    287   double seek_offset; 
    288   ogg_int64_t units, units_at; 
    289   double offset; 
    290  
    291   if (aod->use_granule_seek) { 
    292     seek_offset = aod->min_granule_seek; 
    293 #ifdef DEBUG 
    294     fprintf(aod->df, "anxogg_seek_update: using min_granule_seek %f\n",  
    295             seek_offset); 
    296 #endif 
    297   } else { 
    298     seek_offset = source->start_time; 
    299 #ifdef DEBUG 
    300     fprintf(aod->df, "anxogg_seek_update: using start time %f\n", seek_offset); 
    301 #endif 
    302   } 
    303   seek_offset -= 1.0; 
    304   if (seek_offset < 0.0) seek_offset = 0.0; 
    305  
    306   units = (ogg_int64_t)(SUBSECONDS * seek_offset); 
    307   units_at = oggz_seek_units (aod->oggz, units, SEEK_SET); 
    308  
    309   if (units_at == -1) { 
    310 #ifdef DEBUG 
    311     fprintf (aod->df, "anxogg_seek_update: oggz_seek_units FAIL\n"); 
    312 #endif 
    313     return -1.0; 
    314   } 
    315  
    316   offset = ((double)units_at) / SUBSECONDS; 
    317  
    318   aod->need_seek = NEED_SEEK_DONE; 
    319  
    320 #ifdef DEBUG 
    321   fprintf (aod->df, 
    322            "anxogg: seek_update to %lld (wanted %lld (%f))\n", units_at, 
    323           units, seek_offset); 
    324 #endif 
    325  
    326   if (source->end_time != -1.0 && offset >= source->end_time) { 
    327 #ifdef DEBUG 
    328     fprintf (aod->df, 
    329              "anxoggg: seek update > end_time %f\n", source->end_time); 
    330 #endif 
    331     aod->got_end = 1; 
    332   } 
    333  
    334   return offset; 
    335 
    336  
    337 /*********************************************************** 
    338  * Parse Ogg BOS packet headers and fill in track info. 
    339  */ 
     283 
     284/* Parse Ogg BOS packet headers and fill in track info. */ 
    340285static int 
    341286read_packet_headers (OGGZ * oggz, ogg_packet * op, long serialno, 
     
    587532} 
    588533 
    589 /*********************************************************** 
    590  * A filter predicate, used between the min seek granule 
    591  * and the start time (ie. the bit between the prior keyframe 
    592  * and the chop time) to filter packets which should be 
    593  * included in the output. 
    594  * \returns 0 Do not include \a op 
    595  * \returns 1 Do include \a op 
    596  */ 
    597 static int 
    598 filter (AnxOggData * aod, AnxOggTrack * aot, long serialno, ogg_packet * op) { 
    599  
    600   AnxSourceTrack * track = &(aot->source_track); 
    601   double timestamp; 
    602  
    603 #ifdef DEBUG 
    604   fprintf(aod->df, "state %s got_keygranule %d gp %llx keygranule %llx\n",  
    605     aod->state == STATE_FILTER ? "FILTER" : "NOFILTER",  
    606     aot->filter_got_keygranule, op->granulepos, aot->keygranule); 
    607 #endif 
    608  
    609   /* TRUE if we're not in state FILTER */ 
    610   if (aod->state != STATE_FILTER) return 1; 
    611  
    612   /* TRUE if we haven't done the seek yet */ 
    613   if (aod->need_seek == NEED_SEEK_PENDING) return 1; 
    614  
    615   timestamp = gp_to_time (aod->oggz, serialno, op->granulepos); 
    616  
    617 #ifdef DEBUG   
    618   fprintf(aod->df, "timestamp %f start_time %f\n", timestamp,  
    619             aod->anx_source->start_time); 
    620 #endif 
    621  
    622   /* TRUE if we're beyond the start time */ 
    623   if (timestamp-TOLERANCE >= aod->anx_source->start_time) { 
    624     aod->state = STATE_DATA; 
    625     return 1; 
    626   } 
    627  
    628   /* from here, we know we're filtering */ 
    629  
    630   /* FALSE if we're not using granule_seek at all */ 
    631   if (!aod->use_granule_seek) return 0; 
    632  
    633   /* FALSE if this track doesn't use granuleshift */ 
    634   if (track->granuleshift == 0) return 0; 
    635  
    636   /* TRUE if we're beyond the keygranule for this track */ 
    637   if (aot->filter_got_keygranule) return 1; 
    638  
    639   if (op->granulepos >= aot->keygranule) { 
    640     aot->filter_got_keygranule = 1; 
    641     return 1; 
    642   } 
    643  
    644   /* TRUE if we're after the keygranule time */ 
    645 #if 0 
    646   if (op->granulepos != -1 && timestamp+TOLERANCE >= aot->keygranule_time) { 
    647     aot->filter_got_keygranule = 1; 
    648     return 1; 
    649   } 
    650  
    651   /* XXX: TRUE if a theora from a keyframe, even if no granulepos */ 
    652   if (!strcmp (track->content_type, THEORA_CONTENT_TYPE) && 
    653       op->bytes > 0 && !(op->packet[0] & 0xC0)) { 
    654 #ifdef DEBUG 
    655     fprintf (aod->df, 
    656              "anxogg::FILTER got Theora keyframe\n"); 
    657 #endif 
    658  
    659     aot->filter_got_keygranule = 1; 
    660     return 1; 
    661   } 
    662  
    663 #endif 
    664  
    665   /* FALSE otherwise */ 
    666   return 0; 
    667  
    668 #if 0 
    669   /* FALSE if this track uses keygranules, and we're before its time */ 
    670   if (granulepos != -1 && timestamp+TOLERANCE < aot->keygranule_time) return 0; 
    671  
    672   /* TRUE otherwise */ 
    673   return 1; 
    674 #endif 
    675 } 
    676  
    677 static int 
    678 read_packet_data (OGGZ * oggz, ogg_packet * op, long serialno, 
    679                   void * user_data) 
    680 { 
    681   AnxOggData * aod = (AnxOggData *)user_data; 
    682   AnxOggTrack * aot = NULL; 
    683   AnxOggPacket * aop; 
    684   AnxSource * m = aod->anx_source; 
    685   AnxSourceTrack * track = NULL; 
    686   anx_int64_t gp = oggz_tell_granulepos(oggz); 
    687    
    688   op->granulepos = gp; 
    689  
    690 #ifdef DEBUG 
    691   fprintf (aod->df, "anxogg::read_packet_data IN: %010ld, granulepos %llx\n", 
    692           serialno, gp); 
    693 #endif 
    694  
    695   if (!(aod->cmml_serialno != -1 && serialno == aod->cmml_serialno)) { 
    696     aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno); 
    697     if (aot == NULL) { 
    698 #ifdef DEBUG 
    699       fprintf (aod->df, 
    700                "anxogg::read_packet_data: %010ld not found\n", serialno); 
    701 #endif 
    702       return OGGZ_STOP_OK; 
    703     } 
    704   } 
    705  
    706   if (op->b_o_s) { 
    707     if (!strncmp ((char *)&op->packet[0], "AnxData", 7)) { 
    708       /* Mark this track as anxv2, and don't copy the AnxData packet 
    709        * into the bitstream */ 
    710       if (aot) aot->anxv2_ignore_packet = 1; 
    711     } 
    712   } else { 
    713     if (aod->cmml_serialno != -1 && serialno == aod->cmml_serialno) { 
    714       double at_time; 
    715  
    716 #ifdef DEBUG 
    717       fprintf (aod->df, "aod->cmml_serialno %010ld, op->granulepos %lld\n", 
    718               aod->cmml_serialno, gp); 
    719 #endif 
    720  
    721       if (gp == -1) { 
    722               return OGGZ_STOP_ERR; 
    723       } 
    724       at_time = gp_to_time (aod->oggz, serialno, gp); 
    725        
    726 #ifdef DEBUG 
    727       { 
    728         char * header = (char *)op->packet; 
    729         fprintf (aod->df, 
    730                   "anxogg::read_packet_data: got CMML <%c%c%c%c> at %f\n", 
    731                   header[1], header[2], header[3], header[4], at_time); 
    732       } 
    733 #endif 
    734  
    735       /* If this content doesn't use cmml_granuleshift, and this clip is 
    736        * before the start_time, drop it */ 
    737       if  
    738       ( 
    739         aod->cmml_granuleshift == 0 && op->bytes > 6  
    740         && 
    741         !strncmp ((char *)op->packet, "<clip", 5)  
    742         && 
    743               at_time < aod->anx_source->start_time-TOLERANCE 
    744       )  
    745       { 
    746 #ifdef DEBUG 
    747               fprintf (aod->df, 
    748                             "anxogg::read_packet_data: CMML clip too early, dropping\n"); 
    749 #endif 
    750         return OGGZ_STOP_OK; 
    751       } 
    752  
    753       if (aod->import_cmml) { 
    754         aod->import_cmml ((char *)op->packet, op->bytes, at_time, 
    755                                               aod->import_user_data); 
    756       } 
    757       return OGGZ_CONTINUE; 
    758     } else { 
    759       if (aot->anxv2_ignore_packet) { 
    760         aot->anxv2_ignore_packet = 0; 
    761         op->b_o_s = 1; 
    762       } else { 
    763         aod->got_non_bos = 1; 
    764       } 
    765     } 
    766   } 
    767  
    768   track = &(aot->source_track); 
    769  
    770   if (!track) { 
    771 #ifdef DEBUG 
    772     fprintf (aod->df, "anxogg::read_packet: track NULL\n"); 
    773 #endif 
    774     return OGGZ_STOP_OK; 
    775   } 
    776  
    777   if (aod->nr_headers_remaining == 0 && !aod->got_end &&  
    778       (m->end_time != -1.0) && (gp != -1)) { 
    779         ogg_int64_t granule = gp_to_granule (oggz, serialno, gp); 
    780     if (granule >= track->end_granule) { 
    781 #ifdef DEBUG 
    782       fprintf (aod->df, "anxogg::read_packet_data: got_end\n"); 
    783 #endif 
    784       aod->got_end = 1; 
    785     } 
    786   } 
    787  
    788 #ifdef DEBUG 
    789   fprintf (aod->df, "anxogg::read_packet: Filter? (%s)\n",  
    790         aod->state == STATE_FILTER ? "USE_FN" : "NO_FN"); 
    791 #endif 
    792  
    793   if (!aod->ignore_media && !aod->got_end && !aot->anxv2_ignore_packet && 
    794       (aod->state != STATE_FILTER || 
    795        filter (aod, aot, serialno, op))) { 
    796 #ifdef DEBUG 
    797     fprintf (aod->df, "anxogg::read_packet_data: no, copy out\n"); 
    798 #endif 
    799     aop = anx_malloc (sizeof (AnxOggPacket)); 
    800     aop->length = op->bytes; 
    801     aop->data = anx_malloc (op->bytes); 
    802     aop->granulepos = op->granulepos; 
    803     aop->current_time = ((double)oggz_tell_units (oggz)) / SUBSECONDS; 
    804     aop->source_track = track; 
    805     aop->eos = op->e_o_s; 
    806  
    807 #if 0 
    808     if (aod->nr_headers_remaining == 0 && aop->granulepos != -1) { 
    809       aop->granulepos -= track->start_granule; 
    810     } 
    811 #endif 
    812  
    813     memcpy (aop->data, op->packet, op->bytes); 
    814      
    815     aod->media_packets = anx_list_append (aod->media_packets, aop); 
    816      
    817     if (aot->nr_headers_remaining > 0) { 
    818       aod->nr_headers_remaining--; 
    819       aot->nr_headers_remaining--; 
    820  
    821 #ifdef DEBUG 
    822       fprintf (aod->df, 
    823                "anxogg::read_packet_data: nr_headers_remaining = %d, start_time = %f\n", 
    824               aod->nr_headers_remaining, m->start_time); 
    825 #endif 
    826     } 
    827  
    828     if  
    829     ( 
    830       aod->need_seek == NEED_SEEK_PENDING  
    831       && 
    832             aod->nr_headers_remaining == 0  
    833       && 
    834             m->start_time != 0.0 
    835     )  
    836     { 
    837       if (oggz_seek_units (oggz, 0, SEEK_CUR) >= 0) { 
    838 #ifdef DEBUG 
    839         fprintf (aod->df, "anxogg::read_packet_data NEED seek\n"); 
    840 #endif 
    841         aod->need_seek = NEED_SEEK; 
    842         return OGGZ_CONTINUE; 
    843       } 
    844     } 
    845   } 
    846  
    847   return OGGZ_STOP_OK; 
    848 } 
    849  
    850534static int 
    851535granuleinfo_update_state (AnxOggData * aod) 
     
    1005689} 
    1006690 
     691 
    1007692static int 
    1008693anxogg_setup (AnxOggData * aod) 
     
    1114799} 
    1115800 
     801/*********************************************************** 
     802 * Read: Pass data packets to the writer 
     803 */ 
     804 
     805static double 
     806anxogg_seek_update (AnxSource * source) 
     807{ 
     808  AnxOggData * aod = (AnxOggData *)source->custom_data; 
     809  double seek_offset; 
     810  ogg_int64_t units, units_at; 
     811  double offset; 
     812 
     813  if (aod->use_granule_seek) { 
     814    seek_offset = aod->min_granule_seek; 
     815#ifdef DEBUG 
     816    fprintf(aod->df, "anxogg_seek_update: using min_granule_seek %f\n",  
     817            seek_offset); 
     818#endif 
     819  } else { 
     820    seek_offset = source->start_time; 
     821#ifdef DEBUG 
     822    fprintf(aod->df, "anxogg_seek_update: using start time %f\n", seek_offset); 
     823#endif 
     824  } 
     825  seek_offset -= 1.0; 
     826  if (seek_offset < 0.0) seek_offset = 0.0; 
     827 
     828  units = (ogg_int64_t)(SUBSECONDS * seek_offset); 
     829  units_at = oggz_seek_units (aod->oggz, units, SEEK_SET); 
     830 
     831  if (units_at == -1) { 
     832#ifdef DEBUG 
     833    fprintf (aod->df, "anxogg_seek_update: oggz_seek_units FAIL\n"); 
     834#endif 
     835    return -1.0; 
     836  } 
     837 
     838  offset = ((double)units_at) / SUBSECONDS; 
     839 
     840  aod->need_seek = NEED_SEEK_DONE; 
     841 
     842#ifdef DEBUG 
     843  fprintf (aod->df, 
     844           "anxogg: seek_update to %lld (wanted %lld (%f))\n", units_at, 
     845          units, seek_offset); 
     846#endif 
     847 
     848  if (source->end_time != -1.0 && offset >= source->end_time) { 
     849#ifdef DEBUG 
     850    fprintf (aod->df, 
     851             "anxoggg: seek update > end_time %f\n", source->end_time); 
     852#endif 
     853    aod->got_end = 1; 
     854  } 
     855 
     856  return offset; 
     857} 
     858 
     859static long 
     860anxogg_read_update (AnxSource * media) 
     861{ 
     862  AnxOggData * aod = (AnxOggData *)media->custom_data; 
     863 
     864 do_read: 
     865 
     866  while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); 
     867 
     868  if (aod->need_seek == NEED_SEEK && aod->nr_headers_remaining == 0) { 
     869    anxogg_seek_update (media); 
     870    goto do_read; 
     871  } 
     872 
     873  return 0; 
     874} 
     875 
     876/*********************************************************** 
     877 * A filter predicate, used between the min seek granule 
     878 * and the start time (ie. the bit between the prior keyframe 
     879 * and the chop time) to filter packets which should be 
     880 * included in the output. 
     881 * \returns 0 Do not include \a op 
     882 * \returns 1 Do include \a op 
     883 */ 
     884static int 
     885filter (AnxOggData * aod, AnxOggTrack * aot, long serialno, ogg_packet * op) { 
     886 
     887  AnxSourceTrack * track = &(aot->source_track); 
     888  double timestamp; 
     889 
     890#ifdef DEBUG 
     891  fprintf(aod->df, "state %s got_keygranule %d gp %llx keygranule %llx\n",  
     892    aod->state == STATE_FILTER ? "FILTER" : "NOFILTER",  
     893    aot->filter_got_keygranule, op->granulepos, aot->keygranule); 
     894#endif 
     895 
     896  /* TRUE if we're not in state FILTER */ 
     897  if (aod->state != STATE_FILTER) return 1; 
     898 
     899  /* TRUE if we haven't done the seek yet */ 
     900  if (aod->need_seek == NEED_SEEK_PENDING) return 1; 
     901 
     902  timestamp = gp_to_time (aod->oggz, serialno, op->granulepos); 
     903 
     904#ifdef DEBUG   
     905  fprintf(aod->df, "timestamp %f start_time %f\n", timestamp,  
     906            aod->anx_source->start_time); 
     907#endif 
     908 
     909  /* TRUE if we're beyond the start time */ 
     910  if (timestamp-TOLERANCE >= aod->anx_source->start_time) { 
     911    aod->state = STATE_DATA; 
     912    return 1; 
     913  } 
     914 
     915  /* from here, we know we're filtering */ 
     916 
     917  /* FALSE if we're not using granule_seek at all */ 
     918  if (!aod->use_granule_seek) return 0; 
     919 
     920  /* FALSE if this track doesn't use granuleshift */ 
     921  if (track->granuleshift == 0) return 0; 
     922 
     923  /* TRUE if we're beyond the keygranule for this track */ 
     924  if (aot->filter_got_keygranule) return 1; 
     925 
     926  if (op->granulepos >= aot->keygranule) { 
     927    aot->filter_got_keygranule = 1; 
     928    return 1; 
     929  } 
     930 
     931  /* TRUE if we're after the keygranule time */ 
     932#if 0 
     933  if (op->granulepos != -1 && timestamp+TOLERANCE >= aot->keygranule_time) { 
     934    aot->filter_got_keygranule = 1; 
     935    return 1; 
     936  } 
     937 
     938  /* XXX: TRUE if a theora from a keyframe, even if no granulepos */ 
     939  if (!strcmp (track->content_type, THEORA_CONTENT_TYPE) && 
     940      op->bytes > 0 && !(op->packet[0] & 0xC0)) { 
     941#ifdef DEBUG 
     942    fprintf (aod->df, 
     943             "anxogg::FILTER got Theora keyframe\n"); 
     944#endif 
     945 
     946    aot->filter_got_keygranule = 1; 
     947    return 1; 
     948  } 
     949 
     950#endif 
     951 
     952  /* FALSE otherwise */ 
     953  return 0; 
     954 
     955#if 0 
     956  /* FALSE if this track uses keygranules, and we're before its time */ 
     957  if (granulepos != -1 && timestamp+TOLERANCE < aot->keygranule_time) return 0; 
     958 
     959  /* TRUE otherwise */ 
     960  return 1; 
     961#endif 
     962} 
     963 
     964static int 
     965read_packet_data (OGGZ * oggz, ogg_packet * op, long serialno, 
     966                  void * user_data) 
     967{ 
     968  AnxOggData * aod = (AnxOggData *)user_data; 
     969  AnxOggTrack * aot = NULL; 
     970  AnxOggPacket * aop; 
     971  AnxSource * m = aod->anx_source; 
     972  AnxSourceTrack * track = NULL; 
     973  anx_int64_t gp = oggz_tell_granulepos(oggz); 
     974   
     975  op->granulepos = gp; 
     976 
     977#ifdef DEBUG 
     978  fprintf (aod->df, "anxogg::read_packet_data IN: %010ld, granulepos %llx\n", 
     979          serialno, gp); 
     980#endif 
     981 
     982  if (!(aod->cmml_serialno != -1 && serialno == aod->cmml_serialno)) { 
     983    aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno); 
     984    if (aot == NULL) { 
     985#ifdef DEBUG 
     986      fprintf (aod->df, 
     987               "anxogg::read_packet_data: %010ld not found\n", serialno); 
     988#endif 
     989      return OGGZ_STOP_OK; 
     990    } 
     991  } 
     992 
     993  if (op->b_o_s) { 
     994    if (!strncmp ((char *)&op->packet[0], "AnxData", 7)) { 
     995      /* Mark this track as anxv2, and don't copy the AnxData packet 
     996       * into the bitstream */ 
     997      if (aot) aot->anxv2_ignore_packet = 1; 
     998    } 
     999  } else { 
     1000    if (aod->cmml_serialno != -1 && serialno == aod->cmml_serialno) { 
     1001      double at_time; 
     1002 
     1003#ifdef DEBUG 
     1004      fprintf (aod->df, "aod->cmml_serialno %010ld, op->granulepos %lld\n", 
     1005              aod->cmml_serialno, gp); 
     1006#endif 
     1007 
     1008      if (gp == -1) { 
     1009              return OGGZ_STOP_ERR; 
     1010      } 
     1011      at_time = gp_to_time (aod->oggz, serialno, gp); 
     1012       
     1013#ifdef DEBUG 
     1014      { 
     1015        char * header = (char *)op->packet; 
     1016        fprintf (aod->df, 
     1017                  "anxogg::read_packet_data: got CMML <%c%c%c%c> at %f\n", 
     1018                  header[1], header[2], header[3], header[4], at_time); 
     1019      } 
     1020#endif 
     1021 
     1022      /* If this content doesn't use cmml_granuleshift, and this clip is 
     1023       * before the start_time, drop it */ 
     1024      if  
     1025      ( 
     1026        aod->cmml_granuleshift == 0 && op->bytes > 6  
     1027        && 
     1028        !strncmp ((char *)op->packet, "<clip", 5)  
     1029        && 
     1030              at_time < aod->anx_source->start_time-TOLERANCE 
     1031      )  
     1032      { 
     1033#ifdef DEBUG 
     1034              fprintf (aod->df, 
     1035                            "anxogg::read_packet_data: CMML clip too early, dropping\n"); 
     1036#endif 
     1037        return OGGZ_STOP_OK; 
     1038      } 
     1039 
     1040      if (aod->import_cmml) { 
     1041        aod->import_cmml ((char *)op->packet, op->bytes, at_time, 
     1042                                              aod->import_user_data); 
     1043      } 
     1044      return OGGZ_CONTINUE; 
     1045    } else { 
     1046      if (aot->anxv2_ignore_packet) { 
     1047        aot->anxv2_ignore_packet = 0; 
     1048        op->b_o_s = 1; 
     1049      } else { 
     1050        aod->got_non_bos = 1; 
     1051      } 
     1052    } 
     1053  } 
     1054 
     1055  track = &(aot->source_track); 
     1056 
     1057  if (!track) { 
     1058#ifdef DEBUG 
     1059    fprintf (aod->df, "anxogg::read_packet: track NULL\n"); 
     1060#endif 
     1061    return OGGZ_STOP_OK; 
     1062  } 
     1063 
     1064  if (aod->nr_headers_remaining == 0 && !aod->got_end &&  
     1065      (m->end_time != -1.0) && (gp != -1)) { 
     1066        ogg_int64_t granule = gp_to_granule (oggz, serialno, gp); 
     1067    if (granule >= track->end_granule) { 
     1068#ifdef DEBUG 
     1069      fprintf (aod->df, "anxogg::read_packet_data: got_end\n"); 
     1070#endif 
     1071      aod->got_end = 1; 
     1072    } 
     1073  } 
     1074 
     1075#ifdef DEBUG 
     1076  fprintf (aod->df, "anxogg::read_packet: Filter? (%s)\n",  
     1077        aod->state == STATE_FILTER ? "USE_FN" : "NO_FN"); 
     1078#endif 
     1079 
     1080  if (!aod->ignore_media && !aod->got_end && !aot->anxv2_ignore_packet && 
     1081      (aod->state != STATE_FILTER || 
     1082       filter (aod, aot, serialno, op))) { 
     1083#ifdef DEBUG 
     1084    fprintf (aod->df, "anxogg::read_packet_data: no, copy out\n"); 
     1085#endif 
     1086    aop = anx_malloc (sizeof (AnxOggPacket)); 
     1087    aop->length = op->bytes; 
     1088    aop->data = anx_malloc (op->bytes); 
     1089    aop->granulepos = op->granulepos; 
     1090    aop->current_time = ((double)oggz_tell_units (oggz)) / SUBSECONDS; 
     1091    aop->source_track = track; 
     1092    aop->eos = op->e_o_s; 
     1093 
     1094#if 0 
     1095    if (aod->nr_headers_remaining == 0 && aop->granulepos != -1) { 
     1096      aop->granulepos -= track->start_granule; 
     1097    } 
     1098#endif 
     1099 
     1100    memcpy (aop->data, op->packet, op->bytes); 
     1101     
     1102    aod->media_packets = anx_list_append (aod->media_packets, aop); 
     1103     
     1104    if (aot->nr_headers_remaining > 0) { 
     1105      aod->nr_headers_remaining--; 
     1106      aot->nr_headers_remaining--; 
     1107 
     1108#ifdef DEBUG 
     1109      fprintf (aod->df, 
     1110               "anxogg::read_packet_data: nr_headers_remaining = %d, start_time = %f\n", 
     1111              aod->nr_headers_remaining, m->start_time); 
     1112#endif 
     1113    } 
     1114 
     1115    if  
     1116    ( 
     1117      aod->need_seek == NEED_SEEK_PENDING  
     1118      && 
     1119            aod->nr_headers_remaining == 0  
     1120      && 
     1121            m->start_time != 0.0 
     1122    )  
     1123    { 
     1124      if (oggz_seek_units (oggz, 0, SEEK_CUR) >= 0) { 
     1125#ifdef DEBUG 
     1126        fprintf (aod->df, "anxogg::read_packet_data NEED seek\n"); 
     1127#endif 
     1128        aod->need_seek = NEED_SEEK; 
     1129        return OGGZ_CONTINUE; 
     1130      } 
     1131    } 
     1132  } 
     1133 
     1134  return OGGZ_STOP_OK; 
     1135} 
     1136 
     1137static AnxOggPacket * 
     1138anxogg_packet_free (AnxOggPacket * aop) 
     1139{ 
     1140  anx_free (aop->data); 
     1141  anx_free (aop); 
     1142  return NULL; 
     1143} 
     1144 
     1145static long 
     1146anxogg_read (AnxSource * media, char * buf, long n, long bound) 
     1147{ 
     1148  AnxOggData * aod = (AnxOggData *)media->custom_data; 
     1149  AnxOggPacket * aop; 
     1150  AnxList * head; 
     1151  long bytes_to_read; 
     1152 
     1153  if (aod->ignore_media) return -1; 
     1154 
     1155  anxogg_read_update (media); 
     1156 
     1157  head = aod->media_packets; 
     1158  if (head == NULL) { 
     1159    media->eos = 1; 
     1160    return 0; 
     1161  } 
     1162 
     1163  aop = (AnxOggPacket *)head->data; 
     1164  bytes_to_read = MIN (n, aop->length - aod->current_offset); 
     1165 
     1166  memcpy (buf, &aop->data[aod->current_offset], bytes_to_read); 
     1167 
     1168  aod->current_offset += bytes_to_read; 
     1169 
     1170  if (aod->headers_unread > 0) aod->headers_unread--; 
     1171  if (aod->headers_unread == 0) media->written_secondaries = 1; 
     1172 
     1173  media->current_track = aop->source_track; 
     1174 
     1175#ifdef DEBUG_VERBOSE 
     1176  fprintf (aod->df, "anxogg: reading from stream %s\n", 
     1177          media->current_track->content_type); 
     1178#endif 
     1179 
     1180  media->current_track->current_granule = aop->granulepos; 
     1181  media->current_track->eos = aop->eos; 
     1182 
     1183  /* If that's finished this media packet, advance to the next one */ 
     1184  if (aod->current_offset >= aop->length) { 
     1185    aod->media_packets = 
     1186      anx_list_remove (aod->media_packets, head); 
     1187 
     1188    aop = anxogg_packet_free (aop); 
     1189    anx_free (head); 
     1190 
     1191    aod->current_offset = 0; 
     1192 
     1193    anxogg_read_update (media); 
     1194 
     1195    if (aod->media_packets != NULL) 
     1196      aop = (AnxOggPacket *)aod->media_packets->data; 
     1197  } 
     1198 
     1199  /* Set current time to the current time of the next packet that would 
     1200   * be served */ 
     1201  if (aop && aop->current_time != -1) 
     1202    media->current_time = aop->current_time;    
     1203 
     1204  return bytes_to_read; 
     1205} 
     1206 
     1207static long 
     1208anxogg_sizeof_next_read (AnxSource * media, long bound) 
     1209{ 
     1210  AnxOggData * aod = (AnxOggData *)media->custom_data; 
     1211  AnxOggPacket * aop; 
     1212  long bytes_to_read; 
     1213 
     1214  if (aod->ignore_media) return -1; 
     1215 
     1216  while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); 
     1217 
     1218  if (aod->media_packets == NULL) { 
     1219    media->eos = 1; 
     1220    return 0; 
     1221  } 
     1222 
     1223  aop = (AnxOggPacket *)aod->media_packets->data; 
     1224  bytes_to_read = aop->length - aod->current_offset; 
     1225 
     1226  return bytes_to_read; 
     1227} 
     1228 
     1229/*********************************************************** 
     1230 * Open 
     1231 */ 
     1232 
    11161233static AnxOggData * 
    11171234aod_new (void) 
     
    12221339} 
    12231340 
    1224 static long 
    1225 anxogg_read_update (AnxSource * media) 
    1226 
    1227   AnxOggData * aod = (AnxOggData *)media->custom_data; 
    1228  
    1229  do_read: 
    1230  
    1231   while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); 
    1232  
    1233   if (aod->need_seek == NEED_SEEK && aod->nr_headers_remaining == 0) { 
    1234     anxogg_seek_update (media); 
    1235     goto do_read; 
    1236   } 
    1237  
    1238   return 0; 
    1239 
    1240  
    1241 static AnxOggPacket * 
    1242 anxogg_packet_free (AnxOggPacket * aop) 
    1243 
    1244   anx_free (aop->data); 
    1245   anx_free (aop); 
    1246   return NULL; 
    1247 
    1248  
    1249 static long 
    1250 anxogg_read (AnxSource * media, char * buf, long n, long bound) 
    1251 
    1252   AnxOggData * aod = (AnxOggData *)media->custom_data; 
    1253   AnxOggPacket * aop; 
    1254   AnxList * head; 
    1255   long bytes_to_read; 
    1256  
    1257   if (aod->ignore_media) return -1; 
    1258  
    1259   anxogg_read_update (media); 
    1260  
    1261   head = aod->media_packets; 
    1262   if (head == NULL) { 
    1263     media->eos = 1; 
    1264     return 0; 
    1265   } 
    1266  
    1267   aop = (AnxOggPacket *)head->data; 
    1268   bytes_to_read = MIN (n, aop->length - aod->current_offset); 
    1269  
    1270   memcpy (buf, &aop->data[aod->current_offset], bytes_to_read); 
    1271  
    1272   aod->current_offset += bytes_to_read; 
    1273  
    1274   if (aod->headers_unread > 0) aod->headers_unread--; 
    1275   if (aod->headers_unread == 0) media->written_secondaries = 1; 
    1276  
    1277   media->current_track = aop->source_track; 
    1278  
    1279 #ifdef DEBUG_VERBOSE 
    1280   fprintf (aod->df, "anxogg: reading from stream %s\n", 
    1281           media->current_track->content_type); 
    1282 #endif 
    1283  
    1284   media->current_track->current_granule = aop->granulepos; 
    1285   media->current_track->eos = aop->eos; 
    1286  
    1287   /* If that's finished this media packet, advance to the next one */ 
    1288   if (aod->current_offset >= aop->length) { 
    1289     aod->media_packets = 
    1290       anx_list_remove (aod->media_packets, head); 
    1291  
    1292     aop = anxogg_packet_free (aop); 
    1293     anx_free (head); 
    1294  
    1295     aod->current_offset = 0; 
    1296  
    1297     anxogg_read_update (media); 
    1298  
    1299     if (aod->media_packets != NULL) 
    1300       aop = (AnxOggPacket *)aod->media_packets->data; 
    1301   } 
    1302  
    1303   /* Set current time to the current time of the next packet that would 
    1304    * be served */ 
    1305   if (aop && aop->current_time != -1) 
    1306     media->current_time = aop->current_time;    
    1307  
    1308   return bytes_to_read; 
    1309 
    1310  
    1311 static long 
    1312 anxogg_sizeof_next_read (AnxSource * media, long bound) 
    1313 
    1314   AnxOggData * aod = (AnxOggData *)media->custom_data; 
    1315   AnxOggPacket * aop; 
    1316   long bytes_to_read; 
    1317  
    1318   if (aod->ignore_media) return -1; 
    1319  
    1320   while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); 
    1321  
    1322   if (aod->media_packets == NULL) { 
    1323     media->eos = 1; 
    1324     return 0; 
    1325   } 
    1326  
    1327   aop = (AnxOggPacket *)aod->media_packets->data; 
    1328   bytes_to_read = aop->length - aod->current_offset; 
    1329  
    1330   return bytes_to_read; 
    1331 
    1332  
     1341/*********************************************************** 
     1342 * Close 
     1343 */ 
    13331344static int 
    13341345anxogg_close (AnxSource * source) 
     
    13701381} 
    13711382 
     1383/*********************************************************** 
     1384 * Importer instances 
     1385 */ 
    13721386static struct _AnxImporter anx_ogg_importer = { 
    13731387  (AnxImporterOpenFunc)anxogg_open,