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