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++;