[cvs-annodex] commit (/annodex): libannodex/trunk/src/importers/anx_import_ogg.c libannodex/trunk/src/libannodex/anx_data_packet.h libannodex/trunk/src/libannodex/anx_read.c libannodex/trunk/src/libannodex/xtag.c

conrad nobody at lists.annodex.net
Fri Feb 11 14:44:38 EST 2005


Update of /annodex (new revision 876)

Modified files:
   libannodex/trunk/src/importers/anx_import_ogg.c
   libannodex/trunk/src/libannodex/anx_data_packet.h
   libannodex/trunk/src/libannodex/anx_read.c
   libannodex/trunk/src/libannodex/xtag.c

Log Message:
add/fix support for reading and importing Annodex v2 streams.
This means that existing v2 files can be served out in v3 format with
proper keyframe accuracy.


Modified: libannodex/trunk/src/importers/anx_import_ogg.c
===================================================================
--- libannodex/trunk/src/importers/anx_import_ogg.c	2005-02-10 23:50:34 UTC (rev 875)
+++ libannodex/trunk/src/importers/anx_import_ogg.c	2005-02-11 03:44:28 UTC (rev 876)
@@ -63,6 +63,9 @@
 #define THEORA_CONTENT_TYPE "video/x-theora"
 #define XVID_CONTENT_TYPE "video/x-xvid"
 
+/** well-defined sizeof(AnxData) binary portion for Annodex v2 */
+#define ANX_DATA_SIZE 28
+
 #undef  USE_THEORA_PRE_ALPHA_3_FORMAT
 
 #define SUBSECONDS 1000.0
@@ -95,6 +98,7 @@
 
 struct _AnxOggTrack {
   AnxSourceTrack source_track;
+  int anxv2_ignore_packet;
   int need_keygranule;
   ogg_int64_t keygranule;
   double keygranule_time;
@@ -256,21 +260,35 @@
   AnxOggPacket * aop;
   AnxSource * m = aod->anx_source;
   AnxSourceTrack * track = NULL;
+  int need_insert = 1;
 
+  aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno);
+  if (aot != NULL) {
+    need_insert = 0;
+    if (aot->anxv2_ignore_packet) {
+      aot->anxv2_ignore_packet = 0;
+      op->b_o_s = 1;
+    }
+  }
+
   if (op->b_o_s) {
-
     if (!strncmp ((char *)header, "CMML", 5)) {
       ogg_int64_t gr_n, gr_d;
 
+      /* Don't insert this into the media */
+      need_insert = 0;
+	
       aod->cmml_serialno = serialno;
-      
       gr_n = INT64_LE_AT(&header[12]);
       gr_d = INT64_LE_AT(&header[20]);
-      aod->cmml_granulerate = gr_n / gr_d;
+      aod->cmml_granulerate = (double)gr_n / (double)gr_d;
     } else {
-      aot = (AnxOggTrack *) anx_malloc (sizeof (AnxOggTrack));
-      memset (aot, 0, sizeof(AnxOggTrack));
-
+      if (aot == NULL) {
+	aot = (AnxOggTrack *) anx_malloc (sizeof (AnxOggTrack));
+	memset (aot, 0, sizeof(AnxOggTrack));
+	need_insert = 1;
+      }
+      
       track = &(aot->source_track);
       track->eos = 0;
 
@@ -288,7 +306,7 @@
 	track->granule_rate_d = 1;
 	track->nr_header_packets = 2 + (ogg_int64_t) INT32_LE_AT(&header[68]);
 	track->basegranule = 0;
-	track->preroll = 0;
+	track->preroll = 3;
 	track->granuleshift = 0;
       } else if (!strncmp ((char *)&op->packet[1], "theora", 6)) {
 	char keyframe_granule_shift = 0;
@@ -313,6 +331,41 @@
 	track->basegranule = 0;
 	track->preroll = 0;
 	track->granuleshift = keyframe_granule_shift;
+      } else if (!strncmp ((char *)&op->packet[0], "AnxData", 7)) {
+	AnxParams * params;
+	long n;
+	char * buf;
+
+	/* Mark this track as anxv2, and don't copy the AnxData packet
+	 * into the bitstream */
+	aot->anxv2_ignore_packet = 1;
+
+	/* Set default values, these will be overwritten if the track
+	 * actually contains a content type we can parse */
+
+	/* Ensure params is NUL terminated */
+	n = op->bytes;
+	buf = anx_malloc (n+1);
+	memcpy (buf, (char *)header + ANX_DATA_SIZE, n);
+	buf[n] = '\0';
+
+	params = anx_params_new_parse (buf, ANX_PARAMS_HEADERS);
+	track->content_type = anx_params_get (params, "Content-Type");
+	anx_free (buf);
+
+	track->granule_rate_n = INT64_LE_AT(&header[8]);
+	track->granule_rate_d = INT64_LE_AT(&header[16]);
+	track->nr_header_packets = INT32_LE_AT(&header[24]);
+	track->preroll = 0;
+	track->granuleshift = 0;
+
+	if (!strcmp (track->content_type, CMML_CONTENT_TYPE)) {
+	  need_insert = 0;
+	  aod->cmml_serialno = serialno;
+	  aod->cmml_granulerate =
+	    (double)track->granule_rate_n / (double)track->granule_rate_d;
+	}
+
       } else if (!strncmp ((char *)&op->packet[1], "video", 5) && 
 		 !strncmp ((char *)&op->packet[9], "XVID", 4)) {
 	track->content_type = XVID_CONTENT_TYPE;
@@ -335,13 +388,15 @@
 	aot->need_keygranule = 1;
       }
 
-      oggz_table_insert (aod->logicals, serialno, track);
+      if (need_insert) {
+	oggz_table_insert (aod->logicals, serialno, aot);
 
 #ifdef DEBUG
-      printf ("anxogg::read_packet: Added track for (%010ld): %ld/%ld, +%d headers\n", serialno,
-	      (long)track->granule_rate_n, (long)track->granule_rate_d,
-	      (int)track->nr_header_packets);
+	printf ("anxogg::read_packet: Added track for (%010ld): %ld/%ld, +%d headers\n", serialno,
+		(long)track->granule_rate_n, (long)track->granule_rate_d,
+		(int)track->nr_header_packets);
 #endif
+      }
 
       /* XXX: fix this for theora */
       if (track->granule_rate_n != 0 && track->granule_rate_d != 0) {
@@ -360,10 +415,12 @@
 	}
       }
 
+      if (need_insert) {
 #ifdef DEBUG
-      printf ("anxogg::read_packet: adding track for %s\n", track->content_type);
+	printf ("anxogg::read_packet: adding track for %s\n", track->content_type);
 #endif
-      m->tracks = anx_list_append (m->tracks, track);
+	m->tracks = anx_list_append (m->tracks, track);
+      }
     }
   } else {
     aod->got_non_bos = 1;
@@ -372,7 +429,7 @@
   if (aod->nr_headers_remaining > 0) {
     aod->nr_headers_remaining--;
   }
-
+  
   if (aod->got_non_bos && aod->nr_headers_remaining == 0) {
     if (m->start_time != 0.0) {
       if (oggz_seek_units (oggz, 0, SEEK_CUR) >= 0) {
@@ -383,7 +440,7 @@
       aod->state = STATE_DATA;
     }
   }
-
+  
   return OGGZ_STOP_OK;
 }
 
@@ -435,14 +492,40 @@
   AnxSource * m = aod->anx_source;
   AnxSourceTrack * track = NULL;
 
-  if (!op->b_o_s) {
+#ifdef DEBUG
+  printf ("anxogg::read_packet_data IN: %010ld, granulepos %llx\n",
+	  serialno, op->granulepos);
+#endif
+
+  if (!(aod->cmml_serialno != -1 && serialno == aod->cmml_serialno)) {
+    aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno);
+    if (aot == NULL) {
+#ifdef DEBUG
+      printf ("anxogg::read_packet_data: %010ld not found\n", serialno);
+#endif
+      return OGGZ_STOP_OK;
+    }
+  }
+
+  if (op->b_o_s) {
+    if (!strncmp ((char *)&op->packet[0], "AnxData", 7)) {
+      /* Mark this track as anxv2, and don't copy the AnxData packet
+       * into the bitstream */
+      if (aot) aot->anxv2_ignore_packet = 1;
+    }
+  } else {
     if (aod->cmml_serialno != -1 && serialno == aod->cmml_serialno) {
       double at_time;
-      
+
+#ifdef DEBUG
+      printf ("aod->cmml_serialno %010ld, op->granulepos %lld\n",
+	      aod->cmml_serialno, op->granulepos);
+#endif
+
       if (op->granulepos == -1) {
 	return OGGZ_STOP_ERR;
       }
-      at_time = op->granulepos / aod->cmml_granulerate;
+      at_time = (double)op->granulepos / (double)aod->cmml_granulerate;
       
 #ifdef DEBUG
       printf ("anxogg::read_packet: got CMML <%c%c%c%c> at %f\n",
@@ -453,15 +536,22 @@
 			  aod->import_user_data);
       return OGGZ_CONTINUE;
     } else {
-      aod->got_non_bos = 1;
+      if (aot->anxv2_ignore_packet) {
+	aot->anxv2_ignore_packet = 0;
+	op->b_o_s = 1;
+      } else {
+	aod->got_non_bos = 1;
+      }
     }
   }
 
-  aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno);
   track = &(aot->source_track);
 
   if (!track) {
-    return OGGZ_STOP_ERR;
+#ifdef DEBUG
+    printf ("anxogg::read_packet: track NULL\n");
+#endif
+    return OGGZ_STOP_OK;
   }
 
   if (aod->nr_headers_remaining == 0 && !aod->got_end && 
@@ -470,9 +560,16 @@
     aod->got_end = 1;
   }
 
-  if (!aod->ignore_media && !aod->got_end &&
+#ifdef DEBUG
+  printf ("anxogg::read_packet: Filter?\n");
+#endif
+
+  if (!aod->ignore_media && !aod->got_end && !aot->anxv2_ignore_packet &&
       (aod->state != STATE_FILTER ||
        filter (aod, aot, serialno, op->granulepos))) {
+#ifdef DEBUG
+    printf ("anxogg::read_packet: no, copy out\n");
+#endif
     aop = anx_malloc (sizeof (AnxOggPacket));
     aop->length = op->bytes;
     aop->data = anx_malloc (op->bytes);

Modified: libannodex/trunk/src/libannodex/anx_data_packet.h
===================================================================
--- libannodex/trunk/src/libannodex/anx_data_packet.h	2005-02-10 23:50:34 UTC (rev 875)
+++ libannodex/trunk/src/libannodex/anx_data_packet.h	2005-02-11 03:44:28 UTC (rev 876)
@@ -60,13 +60,12 @@
 #define ANX_DATA_IDENTIFIER "AnxData"
 
 /** well-defined sizeof(AnxData) binary portion */
-#define ANX_DATA_SIZE 32
+#define ANX_DATA_SIZE 28
 
 typedef struct _AnxData AnxData;
 
 struct _AnxData {
   char identifier[8];
-  ogg_int32_t serialno;
   ogg_int64_t granule_rate_numerator;
   ogg_int64_t granule_rate_denominator;
   ogg_int32_t nr_header_packets;

Modified: libannodex/trunk/src/libannodex/anx_read.c
===================================================================
--- libannodex/trunk/src/libannodex/anx_read.c	2005-02-10 23:50:34 UTC (rev 875)
+++ libannodex/trunk/src/libannodex/anx_read.c	2005-02-11 03:44:28 UTC (rev 876)
@@ -417,20 +417,18 @@
     if (track->serialno == serialno) return 0;
   }
 
-  buf = (char *)data + ANX_DATA_SIZE;
+  /* Ensure params is NUL terminated */
+  buf = anx_malloc (n+1);
+  memcpy (buf, (char *)data + ANX_DATA_SIZE, n);
+  buf[n] = '\0';
+
   params = anx_params_new_parse (buf, ANX_PARAMS_HEADERS);
   content_type = anx_params_get (params, "Content-Type");
   id = anx_params_get (params, "ID");
 
-#ifdef DEBUG
-  printf ("Got ANXDATA granule_rate %ld/%ld\t%d headers\t%s\t%s\n",
-	  (long)anxdata->granule_rate_numerator,
-	  (long)anxdata->granule_rate_denominator,
-	  anxdata->nr_header_packets, content_type, id);
-#endif
+  anx_free (buf);
 
   track = anx_malloc (sizeof (AnxTrack));
-  track->serialno = _le_32 (anxdata->serialno);
   track->id = id;
   track->content_type = content_type;
   track->granule_rate_n = _le_64 (anxdata->granule_rate_numerator);
@@ -440,7 +438,10 @@
   reader->tracks = anx_list_append (reader->tracks, track);
 
 #ifdef DEBUG
-  printf ("\tAnxData for serialno %010ld\n", track->serialno);
+  printf ("\tAnxData for %010ld: granule_rate %lld/%lld\t%d headers\t%s\t%s\n",
+	  serialno,
+	  track->granule_rate_n, track->granule_rate_d,
+	  track->nr_header_packets, content_type, id);
 #endif
 
 #if 0
@@ -460,10 +461,10 @@
   if (annodex->anno_serialno_valid == 0 && content_type &&
       !strncmp (content_type, "text/x-cmml", 15)) {
 #ifdef DEBUG
-    printf ("Got anno track %010ld\n", track->serialno);
+    printf ("Got anno track %010ld\n", serialno);
 #endif
     annodex->anno_serialno_valid = 1;
-    annodex->anno_serialno = track->serialno;
+    annodex->anno_serialno = serialno;
   }
   
   return cb_ret;

Modified: libannodex/trunk/src/libannodex/xtag.c
===================================================================
--- libannodex/trunk/src/libannodex/xtag.c	2005-02-10 23:50:34 UTC (rev 875)
+++ libannodex/trunk/src/libannodex/xtag.c	2005-02-11 03:44:28 UTC (rev 876)
@@ -53,6 +53,10 @@
 
 /*#define DEBUG*/
 
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
 #undef FALSE
 #undef TRUE
 
@@ -479,7 +483,6 @@
     xtag_assert_and_pass (parser, X_CLOSETAG);
   }
 
-
   return tag;
 }
 


-- 
conrad



More information about the cvs-annodex mailing list