Hi,

Attached are some patches for transcode I have been using for quite some time,
or rather for some avi tools and/or avilib.

Specifically:
* aviindex: enhance/fix to make ODML (large file) aware, e.g. extract from
existing ODML superindex, or also scan later RIFF chunks when needed (rather
than stopping at a first incomplete idx1), etc
* avikey (1 and 2): fix keyframe determination
(which works mostly now, but not necessarily so with non-transcode avi)
* avidump (tcscan): adjust for 64bit

Mark.
diff -r -u transcode-1.0.2.orig/avilib/avidump.c transcode-1.0.2/avilib/avidump.c
--- transcode-1.0.2.new/avilib/avidump.c	2005-07-04 09:09:31.000000000 +0200
+++ transcode/avilib/avidump.c	2008-07-11 21:36:31.000000000 +0200
@@ -39,6 +39,11 @@
 #include <fcntl.h>
 #include "xio.h"
 
+#if !defined(COMP_MSC)
+#include <unistd.h>
+#include <inttypes.h>
+#endif
+
 #if defined(SYS_UNIX) || defined(COMP_MSC) || defined(SYS_APPLE)
 #define lseek64 lseek
 #endif
@@ -64,8 +69,8 @@
 # define SWAP8(a) (a)
 #endif
 
-typedef unsigned long DWORD;
-typedef unsigned short WORD;
+typedef uint32_t DWORD;
+typedef uint16_t WORD;
 typedef DWORD FOURCC;             /* Type of FOUR Character Codes */
 typedef unsigned char boolean;
 #define TRUE  1
@@ -336,18 +341,18 @@
 	case INT64:
 	    xio_read(fd, &val64, 8);
 	    val64 = SWAP8(val64);
-	    printf("\t%-12s = 0x%016llx\n",names[i].name,val64);
+	    printf("\t%-12s = 0x%016llu\n",names[i].name,(long long)val64);
 	    break;
 	case INT32:
 	    xio_read(fd, &val32, 4);
 	    val32 = SWAP4(val32);
-	    printf("\t%-12s = %ld\n",names[i].name,val32);
+	    printf("\t%-12s = %d\n",names[i].name,val32);
 	    break;
 	case CCODE:
 	    xio_read(fd, &val32,4);
 	    val32 = SWAP4(val32);
 	    if (val32) {
-		printf("\t%-12s = %c%c%c%c (0x%lx)\n",names[i].name,
+		printf("\t%-12s = %c%c%c%c (0x%x)\n",names[i].name,
 		       (int)( val32        & 0xff),
 		       (int)((val32 >>  8) & 0xff),
 		       (int)((val32 >> 16) & 0xff),
@@ -373,7 +378,7 @@
 	case FLAGS:
 	    xio_read(fd, &val32,4);
 	    val32 = SWAP4(val32);
-	    printf("\t%-12s = 0x%lx\n",names[i].name,val32);
+	    printf("\t%-12s = 0x%x\n",names[i].name,val32);
 	    if (names[i].flags) {
 		for (j = 0; names[i].flags[j].bit != 0; j++)
 		    if (names[i].flags[j].bit & val32)
@@ -509,7 +514,7 @@
     printf("(%Lu) %*c  ID:<%s>   Size: %lu\n",
 	    filepos ,(RekDepth+1)*4,' ',tagstr, *chunksize);
 #else
-    printf("(0x%s) %*c  ID:<%s>   Size: 0x%08lx %8lu\n",
+    printf("(0x%s) %*c  ID:<%s>   Size: 0x%08x %8u\n",
 	   off_t_to_char(filepos,16,8),(RekDepth+1)*4,' ',tagstr, *chunksize, *chunksize);
 #endif
 
@@ -623,8 +628,8 @@
 	    size = SWAP4(size);
 	    duration = SWAP4(duration);
 	    if (size!=0)
-	    printf("\t\t [%6ld] 0x%016llx 0x%08lx %8d\n", u++, offset, size,
-		    (int)duration);
+	    printf("\t\t [%6ld] 0x%016llx 0x%08x %8d\n", u++, (long long)offset,
+                    size, (int)duration);
 	    datapos += 16;
 	}
 	break;
@@ -682,17 +687,17 @@
 	    //flag
 	    xio_read(fd, &val32, 4);
 	    val32 = SWAP4(val32);
-	    printf("flags=%02ld ",val32);
+	    printf("flags=%02d ",val32);
 
 	    //pos
 	    xio_read(fd, &val32, 4);
 	    val32 = SWAP4(val32);
-	    printf("0x%08lx",val32);
+	    printf("0x%08x",val32);
 
 	    //size
 	    xio_read(fd, &val32, 4);
 	    val32 = SWAP4(val32);
-	    printf("%8ld\n",val32);
+	    printf("%8d\n",val32);
 
 	    datapos+=16;
 	}
diff -u -p -r transcode-1.0.1-orig/docs/man/aviindex.1 transcode-1.0.1/docs/man/aviindex.1
--- transcode-1.0.1-orig/docs/man/aviindex.1	2004-03-01 08:55:21.000000000 +0100
+++ transcode-1.0.1/docs/man/aviindex.1	2005-10-28 22:15:05.000000000 +0200
@@ -8,7 +8,9 @@ aviindex \- Write and read text files de
 .I ofile
 .B -i
 .I ifile
+.B -f
 .B -n
+.B -x
 .B -v
 .B -h
 ]
@@ -22,8 +24,11 @@ human readable form.
 .PP
 An AVI file can have an optional chunk called "idx1" which contains
 information about keyframes (syncpoints) and locations of video
-frames resp. audio chunks. Movie players use this index to seek in
-files.
+frames resp. audio chunks. Though larger AVI files (>2-4GB), so-called 
+OpenDML AVI or also AVI 2 files, have a more complicated indexing 
+system, which consists of a superindex referring to (possibly) 
+several "standard" indexes, the "indexing principle" is the same.
+Movie players use such indexes to seek in files.
 .PP
 \fBaviindex\fP reads the AVI file \fIifile\fP and writes the index
 into \fIofile\fP. This can either happen in "dumb" mode where
@@ -74,8 +79,14 @@ Specify the name of the output file.
 \fB-i\fP \fIifile\fP
 Specify the name of the input file.
 .TP
+\fB-f\fP
+force the use of the existing index.
+.TP
 \fB-n\fP
-force generating the index.
+force generating the index by scanning the file.
+.TP
+\fB-x\fP
+(implies -n) don't use any existing index to generate keyframes.
 .TP
 \fB-v\fP
 show version.
diff -u -p -r transcode-1.0.1-orig/tools/aviindex.c transcode-1.0.1/tools/aviindex.c
--- transcode-1.0.1-orig/tools/aviindex.c	2005-07-04 09:09:35.000000000 +0200
+++ transcode-1.0.1/tools/aviindex.c	2005-10-23 20:24:38.000000000 +0200
@@ -215,7 +215,7 @@ int mpidx1_to_aviidx1(char *in_file, FIL
 	idx = &((AVIINDEXENTRY *)data)[i];
 	ckid = SWAP(idx->ckid);
 	fprintf(out_fd, 
-		"%.4s %d %d %d %d %d %d 0\n", 
+		"%.4s %d %d %d %u %u %d 0\n", 
 		(char *)&ckid, 
 		avi_stream_nr(idx->ckid),
 		i, 
@@ -264,17 +264,23 @@ int AVI_read_data_fast(avi_t *AVI, char 
       if( xio_read(AVI->fdes,data,8) != 8 ) return 0;
 
       n = PAD_EVEN(str2ulong(data+4));
-
-      if(strncasecmp(data,"LIST",4) == 0) {
-	  continue;
-      }
-
-      if(strncasecmp(data,"movi",4) == 0 ||
-         strncasecmp(data,"rec ",4) == 0) {
-	  xio_lseek(AVI->fdes,-4,SEEK_CUR);
-	  continue;
+  
+      if(strncasecmp(data,"LIST",4) == 0 || 
+	 strncasecmp(data,"RIFF",4) == 0) { // prevents skipping extended RIFF chunks
+	  if( xio_read(AVI->fdes,data,4) != 4 ) return 0;
+	  n -= 4;
+	  // put here tags of lists that need to be looked into
+	  if(strncasecmp(data,"movi",4) == 0 ||
+	     strncasecmp(data,"rec ",4) == 0 ||
+	     strncasecmp(data,"AVI ",4) == 0 ||
+	     strncasecmp(data,"AVIX",4) == 0) {
+	    // xio_lseek(AVI->fdes,-4,SEEK_CUR);
+	    continue; // proceed to look into it
+	  } // otherwise seek over it later on
       }
 
+      // the following list of comparisons should not include list tags;
+      // these should all go in the list above
       if(strncasecmp(data,"IDX1",4) == 0)
       {
 	 // deal with it to extract keyframe info
@@ -474,7 +480,7 @@ int main(int argc, char *argv[])
     aud_ms[i] = 0;
   }
 
-  while ((ch = getopt(argc, argv, "a:vi:o:nf?h")) != -1)
+  while ((ch = getopt(argc, argv, "a:vi:o:nxf?h")) != -1)
     {
 
 	switch (ch) {
@@ -730,7 +736,8 @@ int main(int argc, char *argv[])
 
     AVI_info(avifile1);
 
-    if(avifile1->idx)
+    // idx1 contains only info for first chunk of opendml AVI
+    if(avifile1->idx && !avifile1->is_opendml) 
     {
       off_t pos, len;
 
@@ -759,60 +766,118 @@ int main(int argc, char *argv[])
          }
       }
       /* idx_type remains 0 if neither of the two tests above succeeds */
-   }
-
-   ioff = idx_type == 1 ? 0 : avifile1->movi_start-4;
-   //fprintf(stderr, "index type (%d), ioff (%ld)\n", idx_type, (long)ioff);
-    i=0;
-
-    //printf("nr idx: %d\n", avifile1->n_idx);
-    while (i<avifile1->n_idx) {
-      tc_memcpy(tag, avifile1->idx[i], 4);
-      // tag
-      fprintf(out_fd, "%c%c%c%c", 
-	  avifile1->idx[i][0], avifile1->idx[i][1],
-	  avifile1->idx[i][2], avifile1->idx[i][3]);
-
-      // type, absolute chunk number
-      fprintf(out_fd, " %c %ld", avifile1->idx[i][1]+1, i);
-      
-
-      switch (avifile1->idx[i][1]) {
-	case '0':
-	  fprintf(out_fd, " %d", vid_chunks);
-	  vid_chunks++;
-	  break;
-	case '1': case '2':
-	case '3': case '4':
-	case '5': case '6':
-	case '7': case '8':
-	  // uhoh
-	  ret = avifile1->idx[i][1]-'0';
-	  fprintf(out_fd, " %d", aud_chunks[ret]);
-	  aud_chunks[ret]++;
-	  break;
-	default:
-	  fprintf(out_fd, " %d", -1);
-	  break;
+   
+  
+      ioff = idx_type == 1 ? 0 : avifile1->movi_start-4;
+    //fprintf(stderr, "index type (%d), ioff (%ld)\n", idx_type, (long)ioff);
+      i=0;
+  
+      //printf("nr idx: %d\n", avifile1->n_idx);
+      while (i<avifile1->n_idx) {
+	tc_memcpy(tag, avifile1->idx[i], 4);
+	// tag
+	fprintf(out_fd, "%c%c%c%c", 
+	    avifile1->idx[i][0], avifile1->idx[i][1],
+	    avifile1->idx[i][2], avifile1->idx[i][3]);
+  
+	// type, absolute chunk number
+	fprintf(out_fd, " %c %ld", avifile1->idx[i][1]+1, i);
+	
+  
+	switch (avifile1->idx[i][1]) {
+	  case '0':
+	    fprintf(out_fd, " %d", vid_chunks);
+	    vid_chunks++;
+	    break;
+	  case '1': case '2':
+	  case '3': case '4':
+	  case '5': case '6':
+	  case '7': case '8':
+	    // uhoh
+	    ret = avifile1->idx[i][1]-'0';
+	    fprintf(out_fd, " %d", aud_chunks[ret]);
+	    aud_chunks[ret]++;
+	    break;
+	  default:
+	    fprintf(out_fd, " %d", -1);
+	    break;
+	}
+  
+	pos = str2ulong(avifile1->idx[i]+ 8);
+	pos += ioff;
+	// pos
+	fprintf(out_fd, " %llu", pos);
+	// len
+	fprintf(out_fd, " %lu", str2ulong(avifile1->idx[i]+12));
+	// flags (keyframe?);
+	fprintf(out_fd, " %d", (str2ulong(avifile1->idx[i]+ 4))?1:0);
+  
+	// ms (not available here)
+	fprintf(out_fd, " %.2f", 0.0);
+  
+	fprintf(out_fd, "\n");
+  
+	i++;
       }
+    }
 
-      pos = str2ulong(avifile1->idx[i]+ 8);
-      pos += ioff;
-      // pos
-      fprintf(out_fd, " %llu", pos);
-      // len
-      fprintf(out_fd, " %lu", str2ulong(avifile1->idx[i]+12));
-      // flags (keyframe?);
-      fprintf(out_fd, " %d", (str2ulong(avifile1->idx[i]+ 4))?1:0);
+    else
+    { // try to extract from the index that AVILIB built, 
+      // possibly from OpenDML superindex
+
+      long aud_entry [ AVI_MAX_TRACKS ] = { 0 };
+      long vid_entry = 0;
+      char* tagp;
 
-      // ms (not available here)
-      fprintf(out_fd, " %.2f", 0.0);
+      off_t pos, len;
+      i = chunk = 0;
 
-      fprintf(out_fd, "\n");
 
-      i++;
-    }
+      while (1) {
+	ret = pos = 0;
+	int j = 0;
+	
+	if(vid_entry < avifile1->video_frames) {
+	  pos = avifile1->video_index[vid_entry].pos;
+	  len = avifile1->video_index[vid_entry].len;
+	  key = (avifile1->video_index[vid_entry].key) & 16 ? 1 : 0;
+	  chunk = vid_entry;
+	  ret = 1;
+	}
+	for(j = 0; j < AVI_audio_tracks(avifile1); ++j) {
+	  if(aud_entry[j] < avifile1->track[j].audio_chunks) {
+	    if(!ret || avifile1->track[j].audio_index[aud_entry[j]].pos < pos) {
+	      pos = avifile1->track[j].audio_index[aud_entry[j]].pos;
+	      len = avifile1->track[j].audio_index[aud_entry[j]].len;
+	      key = 0;
+	      chunk = aud_entry[j];
+	      ret = j + 2;
+	    }
+	  }
+	}
+	
+	if(!ret) // end of all index streams
+	  break;
+	
+	if (ret == 1) 
+	{
+	  ++vid_entry;
+	  tagp = avifile1->video_tag;
+	}
+	else
+	{
+	  aud_entry[ret-2]++;
+	  tagp = avifile1->track[ret-2].audio_tag;
+	}
+	
+	// index points to data in chunk, but chunk offset is needed here
+	pos -= 8;
+	fprintf(out_fd, "%.4s %d %ld %ld %lld %lld %lld %.2f\n", tagp, ret, i, chunk, pos, len, key, 0.0);
+	i++;
+	
+      }
 
+    }
 
   }
 
--- transcode-1.0.4/tools/aviindex.c.orig	2007-12-25 21:00:58.000000000 +0100
+++ transcode-1.0.4/tools/aviindex.c	2007-12-25 21:00:58.000000000 +0100
@@ -812,7 +812,7 @@
 	// len
 	fprintf(out_fd, " %lu", str2ulong(avifile1->idx[i]+12));
 	// flags (keyframe?);
-	fprintf(out_fd, " %d", (str2ulong(avifile1->idx[i]+ 4))?1:0);
+	fprintf(out_fd, " %d", (str2ulong(avifile1->idx[i]+ 4) & 0x10)?1:0);
   
 	// ms (not available here)
 	fprintf(out_fd, " %.2f", 0.0);
--- transcode-1.0.4/avilib/avilib.c.orig	2005-11-06 06:57:52.000000000 +0100
+++ transcode-1.0.4/avilib/avilib.c	2007-12-25 20:59:51.000000000 +0100
@@ -3217,7 +3217,7 @@
    if(AVI->video_pos < 0 || AVI->video_pos >= AVI->video_frames) return -1;
    n = AVI->video_index[AVI->video_pos].len;
 
-   *keyframe = (AVI->video_index[AVI->video_pos].key==0x10) ? 1:0;
+   *keyframe = (AVI->video_index[AVI->video_pos].key & 0x10) ? 1:0;
 
    if (vidbuf == NULL) {
      AVI->video_pos++;

Reply via email to