File:dvdauthor-0.6.11-ivtv-patch.txt
From IVTV
What's this?
The following is a patch file that describes a number of changes to the source code for version 0.6.11 of dvdauthor, that enable it successfully to accept direct input from suitably-formatted MPEG-2 streams encoded by IVTV (see my howto).
Note that this patch is largely superseded by a new updated version against dvdauthor 0.6.14 (the latest stable release as of May 2008). You can get the new patch here. This older version is retained however as it is more thoroughly tested and might possibly be more reliable.
How do I use it?
- Download and extract the source tarball for dvdauthor version 0.6.11;
- Copy the content of the section below to a local file called dvdauthor-0.6.11-ivtv-patch.txt;
- Go to the dvdauthor-0.6.11 directory and do patch -p0 < dvdauthor-0.6.11-ivtv-patch.txt;
- Configure, build and install the application as required.
IVTV patch for dvdauthor version 0.6.11
diff -u src/da-internal.h src/da-internal.h
--- src/da-internal.h 2005-02-01 02:26:19.000000000 +0000
+++ src/da-internal.h 2005-04-24 09:31:54.000000000 +0100
@@ -166,6 +166,7 @@
extern char *entries[];
extern int jumppad;
+extern int printWarnings;
extern char *pstypes[];
void write8(unsigned char *p,unsigned char d0,unsigned char d1,
diff -u src/dvdauthor.c src/dvdauthor.c
--- src/dvdauthor.c 2005-02-01 02:26:19.000000000 +0000
+++ src/dvdauthor.c 2005-04-24 13:24:04.000000000 +0100
@@ -38,6 +38,10 @@
// jumping/calling to a wider number of destinations
int jumppad=0;
+// this flag allows the user to turn off any WARNings that we might not
+// want to see. Audio discontinuity and re-muxing come to mind.
+int printWarnings=1;
+
static char *vmpegdesc[4]={"","mpeg1","mpeg2",0};
static char *vresdesc[6]={"","720xfull","704xfull","352xfull","352xhalf",0};
static char *vformatdesc[4]={"","ntsc","pal",0};
@@ -230,7 +234,21 @@
int w;
if( ATTRMATCH(VIDEO_MPEG) ) {
+
+ //MJC DEBUG CODE
+ //fprintf(stderr, "DEBUG: found VIDEO_MPEG attribute\n");
+ //fprintf(stderr, "\tcalling scanandwarnupdate\n");
+ //fprintf(stderr, "\t\toldval = %s\n", vmpegdesc[va->vd.vmpeg]);
+ //fprintf(stderr, "\t\tnewval = %s\n", s);
+ //fprintf(stderr, "\t\twarnval = %s\n", vmpegdesc[va->vdwarn.vmpeg]);
+ //
+
w=scanandwarnupdate(&va->vd.vmpeg,s,&va->vdwarn.vmpeg,"mpeg format",vmpegdesc);
+
+ //MJC DEBUG CODE
+ //fprintf(stderr, "\treturn value was %i\n", w);
+ //
+
if(w) return w-1;
}
@@ -1040,6 +1058,11 @@
jumppad=1;
}
+void dvdauthor_disable_warnings()
+{
+ printWarnings=0;
+}
+
void dvdauthor_vmgm_gen(struct pgc *fpc,struct menugroup *menus,char *fbase)
{
DIR *d;
diff -u src/dvdauthor.h src/dvdauthor.h
--- src/dvdauthor.h 2005-02-01 02:26:19.000000000 +0000
+++ src/dvdauthor.h 2005-04-24 09:31:54.000000000 +0100
@@ -63,6 +63,7 @@
void source_set_filename(struct source *v,const char *s);
void dvdauthor_enable_jumppad();
+void dvdauthor_disable_warnings();
void dvdauthor_vts_gen(struct menugroup *menus,struct pgcgroup *titles,char *fbase);
void dvdauthor_vmgm_gen(struct pgc *fpc,struct menugroup *menus,char *fbase);
diff -u src/dvdcli.c dvdauthor-0.6.11-ivtv/src/dvdcli.c
--- src/dvdcli.c 2005-02-01 02:26:19.000000000 +0000
+++ src/dvdcli.c 2005-04-24 09:31:54.000000000 +0100
@@ -232,6 +232,8 @@
"\n\t-x XMLFILE where XMLFILE is a configuration file describing the\n"
"\t structure of the DVD to create. If you use a config file, then you\n"
"\t do not need to specify any other options, except -o.\n"
+ "\n\t-w will turn off the WARN: messages telling you to re-multiplex\n"
+ "\t the audio and/or video.\n"
"\n\t" LONGOPT("--video=VOPTS or ") "-v VOPTS where VOPTS is a plus (+) separated list of\n"
"\t video options. dvdauthor will try to infer any unspecified options.\n"
"\t\tpal, ntsc, 4:3, 16:9, 720xfull, 720x576, 720x480, 704xfull,\n"
@@ -360,7 +362,7 @@
while(1) {
struct pgcgroup *vc=va[curva];
- int c=GETOPTFUNC(argc,argv,"f:o:v:a:s:hc:Cp:Pmtb:Ti:e:x:");
+ int c=GETOPTFUNC(argc,argv,"f:o:v:a:s:hc:Cp:Pmtb:Ti:e:x:w");
if( c == -1 )
break;
switch(c) {
@@ -492,6 +494,10 @@
source_add_cell(curvob,0,-1,1,0,0);
break;
+ case 'w':
+ dvdauthor_disable_warnings();
+ break;
+
default:
fprintf(stderr,"ERR: getopt returned bad code %d\n",c);
return 1;
diff -u src/dvdvob.c dvdauthor-0.6.11-ivtv/src/dvdvob.c
--- src/dvdvob.c 2005-02-10 20:47:32.000000000 +0000
+++ src/dvdvob.c 2005-04-24 13:23:40.000000000 +0100
@@ -58,20 +58,24 @@
// I assume pts should round down? That seems to be how mplex deals with it
// also see later comment
+//MJC
int fpts=getframepts(va);
int bpframe=(basepts*2-*align+fpts/2)/fpts;
if( (*align+bpframe*fpts)/2 != basepts ) {
if( !*didcomplain ) {
if( cancomplain )
- fprintf(stderr,"WARN: Video PTS does not line up on a multiple of a field.\n");
+ fprintf(stderr,"(MJC override) WARN: Video PTS does not line up on a multiple of a field.\n");
*didcomplain=1;
}
- *align=basepts;
- } else
- nfields += bpframe;
+// *align=basepts;
+// } else nfields += bpframe;
+ } nfields += bpframe;
return (*align+nfields*fpts)/2;
+//MJC
+
}
+
static int findnextvideo(struct vob *va, int cur, int dir)
{
// find next (dir=1) or previous(dir=-1) vobu with video
@@ -225,7 +229,9 @@
return dflt;
}
-static void transpose_ts(unsigned char *buf,pts_t tsoffs)
+
+//static void transpose_ts(unsigned char *buf,pts_t tsoffs)
+static void transpose_ts(unsigned char *buf,int scroffs, int tsoffs)
{
// pack scr
if( buf[0] == 0 &&
@@ -233,25 +239,62 @@
buf[2] == 1 &&
buf[3] == 0xba )
{
- writescr(buf+4,readscr(buf+4)+tsoffs);
+// writescr(buf+4,readscr(buf+4)+tsoffs);
+ int offs = (buf[17] == 0xbb) ? 24 : 0;
+
+ writescr(buf+4,readscr(buf+4)+scroffs);
// video/audio?
// pts?
- if( buf[14] == 0 &&
- buf[15] == 0 &&
- buf[16] == 1 &&
- (buf[17]==0xbd || (buf[17]>=0xc0 && buf[17]<=0xef)) &&
- (buf[21] & 128))
+// if( buf[14] == 0 &&
+// buf[15] == 0 &&
+// buf[16] == 1 &&
+// (buf[17]==0xbd || (buf[17]>=0xc0 && buf[17]<=0xef)) &&
+// (buf[21] & 128))
+ if( buf[offs+14] == 0 &&
+ buf[offs+15] == 0 &&
+ buf[offs+16] == 1 &&
+ (buf[offs+17]==0xbd || (buf[offs+17]>=0xc0 && buf[offs+17]<=0xef)) &&
+ (buf[offs+21] & 128))
{
- writepts(buf+23,readpts(buf+23)+tsoffs);
+// writepts(buf+23,readpts(buf+23)+tsoffs);
+ writepts(buf+offs+23,readpts(buf+offs+23)+tsoffs);
// dts?
- if( buf[21] & 64 ) {
- writepts(buf+28,readpts(buf+28)+tsoffs);
+// if( buf[21] & 64 ) {
+// writepts(buf+28,readpts(buf+28)+tsoffs);
+ if( buf[offs+21] & 64 ) {
+ writepts(buf+offs+28,readpts(buf+offs+28)+tsoffs);
}
}
}
}
+int find_gop(unsigned char *buf)
+{
+ if (buf[14] == 0 &&
+ buf[15] == 0 &&
+ buf[16] == 1 &&
+ buf[17] == 0xbb &&
+ buf[38] == 0 &&
+ buf[39] == 0 &&
+ buf[40] == 1 &&
+ buf[41] == 0xe0)
+ {
+ int i = 42;
+ while (i < 1024)
+ {
+ if (buf[i] == 0 &&
+ buf[i+1] == 0 &&
+ buf[i+2] == 1 &&
+ buf[i+3] == 0xb8)
+ return 1;
+ i += 4;
+ }
+ }
+ return 0;
+}
+
+
static int mpa_valid(unsigned char *b)
{
unsigned int v=(b[0]<<24)|(b[1]<<16)|(b[2]<<8)|b[3];
@@ -533,8 +576,14 @@
if( buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 )
scanvideoptr(va,buf+i,thisvi,cursect,vsi);
}
+
+
+//MJC: change default behaviour here to avoid incorrect missed detection of format in ivtv streams
if( !va->vd.vmpeg )
- vobgroup_set_video_attr(va,VIDEO_MPEG,"mpeg1");
+ //vobgroup_set_video_attr(va,VIDEO_MPEG,"mpeg1");
+ vobgroup_set_video_attr(va,VIDEO_MPEG,"mpeg2");
+
+
// if the mpeg version changed, then rerun scanvideoframe, because
// scanvideoptr updates the aspect ratio in the sequence header
if( mpf != va->vd.vmpeg ) {
@@ -809,6 +858,7 @@
int FindVobus(char *fbase,struct vobgroup *va,int ismenu)
{
unsigned char *buf;
+ unsigned char *buf_copy = (unsigned char*) malloc(2048);;
FILE *h;
int cursect=0,fsect=-1,vnum,outnum=-ismenu+1;
int ispipe,vobid=0;
@@ -823,6 +873,7 @@
int i,j;
int hadfirstvobu=0;
pts_t backoffs=0, lastscr=0;
+ int generate_vobu=0,copy_packet=0,tsoffs=0;
struct vob *s=va->vobs[vnum];
int prevvidsect=-1;
struct vscani vsi;
@@ -850,8 +901,12 @@
}
buf=writegrabbuf();
- i=fread(buf,1,2048,h);
- if( i!=2048 ) {
+ if (copy_packet == 1 ) {
+ memcpy( buf, buf_copy, 2048);
+ } else if( 2048 != (i=fread(buf,1,2048,h)) ) {
+
+// i=fread(buf,1,2048,h);
+// if( i!=2048 ) {
if( i==-1 ) {
fprintf(stderr,"\nERR: Error while reading: %s\n",strerror(errno));
exit(1);
@@ -956,6 +1011,42 @@
writeundo();
continue;
}
+
+// new section from patch
+ if( fsect == -1 ) {
+ char newname[200];
+ fsect=0;
+ if( outnum >= 0)
+ sprintf(newname, "%s_%d.VOB", fbase,outnum);
+ else
+ strcpy(newname,fbase);
+ writeopen(newname);
+ }
+
+ // we should get a VOBU before a video with GOP
+ if( (generate_vobu == 1 || hadfirstvobu == 0) &&
+ copy_packet == 0 && find_gop(buf) )
+ {
+ // create VOBU
+ // fprintf(stderr,"Found GOP with no VOBU, creating VOBU...\n");
+ generate_vobu = 1;
+ copy_packet = 1;
+ memcpy( buf_copy, buf, 2048);
+
+ buf[41] = 0xbf;
+ buf[42] = 0x03;
+ buf[43] = 0xd4;
+ buf[44] = 0x81;
+ memset( buf+45, 0, 2048-45);
+ buf[1026] = 1;
+ buf[1027] = 0xbf;
+ buf[1028] = 0x03;
+ buf[1029] = 0xfa;
+ buf[1030] = 0x81;
+ } else if (copy_packet == 1)
+ copy_packet = 0;
+// end of new section
+
if( buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) {
pts_t newscr=readscr(buf+4);
if( newscr < lastscr ) {
@@ -966,15 +1057,27 @@
if( !hadfirstvobu )
backoffs=newscr;
}
- transpose_ts(buf,-backoffs);
- if( fsect == -1 ) {
- char newname[200];
- fsect=0;
- if( outnum>=0 )
- sprintf(newname,"%s_%d.VOB",fbase,outnum);
- else
- strcpy(newname,fbase);
- writeopen(newname);
+// transpose_ts(buf,-backoffs);
+// if( fsect == -1 ) {
+// char newname[200];
+// fsect=0;
+// if( outnum>=0 )
+// sprintf(newname,"%s_%d.VOB",fbase,outnum);
+// else
+// strcpy(newname,fbase);
+// writeopen(newname);
+
+// new section from patch
+ if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba )
+ {
+ int offs = (buf[17] == 0xbb) ? 24 : 0;
+ if( buf[offs+14] == 0 &&
+ buf[offs+15] == 0 &&
+ buf[offs+16] == 1 &&
+ (buf[offs+17]==0xbd || (buf[offs+17]>=0xc0 && buf[offs+17]<=0xef)) &&
+ (buf[offs+21] & 128))
+ tsoffs = readpts(buf+offs+23);
+// end of new section
}
if( buf[14] == 0 &&
buf[15] == 0 &&
@@ -1020,12 +1123,13 @@
printvobustatus(va,cursect);
vsi.lastrefsect=0;
vsi.firstgop=1;
- } else {
+// } else {
+ } else if (generate_vobu == 0 || copy_packet == 1) {
fprintf(stderr,"WARN: System header found, but PCI/DSI information is not where expected\n\t(make sure your system header is 18 bytes!)\n");
}
}
if( !hadfirstvobu ) {
- fprintf(stderr,"WARN: Skipping sector, waiting for first VOBU...\n");
+// fprintf(stderr,"WARN: Skipping sector, waiting for first VOBU...\n");
writeundo();
continue;
}
@@ -1155,20 +1259,48 @@
if( ach->audpts[ach->numaudpts-1].pts[1]<pts0 ) {
if( audch>=32 )
goto noshow;
- fprintf(stderr,"WARN: Discontinuity in audio channel %d; please remultiplex input.\n",audch);
- } else if( ach->audpts[ach->numaudpts-1].pts[1]>pts0 )
- fprintf(stderr,"WARN: Audio pts for channel %d moves backwards; please remultiplex input.\n",audch);
+
+// fprintf(stderr,"WARN: Discontinuity in audio channel %d; please remultiplex input.\n",audch);
+// } else if( ach->audpts[ach->numaudpts-1].pts[1]>pts0 )
+// fprintf(stderr,"WARN: Audio pts for channel %d moves backwards; please remultiplex input.\n",audch);
+
+// new section from patch
+ if (printWarnings)
+ fprintf(stderr,"WARN: Discontinuity in audio channel %d; please remultiplex input.\n",audch);
+ } else if( ach->audpts[ach->numaudpts-1].pts[1]>pts0 ) {
+ if (printWarnings)
+ fprintf(stderr,"WARN: Audio pts for channel %d moves backwards; please remultiplex input.\n",audch);
+ }
+// end of new section
+
+
else
goto noshow;
- fprintf(stderr,"WARN: Previous sector: ");
- printpts(ach->audpts[ach->numaudpts-1].pts[0]);
- fprintf(stderr," - ");
- printpts(ach->audpts[ach->numaudpts-1].pts[1]);
- fprintf(stderr,"\nWARN: Current sector: ");
- printpts(pts0);
- fprintf(stderr," - ");
- printpts(pts1);
- fprintf(stderr,"\n");
+// fprintf(stderr,"WARN: Previous sector: ");
+// printpts(ach->audpts[ach->numaudpts-1].pts[0]);
+// fprintf(stderr," - ");
+// printpts(ach->audpts[ach->numaudpts-1].pts[1]);
+// fprintf(stderr,"\nWARN: Current sector: ");
+// printpts(pts0);
+// fprintf(stderr," - ");
+// printpts(pts1);
+// fprintf(stderr,"\n");
+
+// new section from patch
+ if (printWarnings)
+ {
+ fprintf(stderr,"WARN: Previous sector: ");
+ printpts(ach->audpts[ach->numaudpts-1].pts[0]);
+ fprintf(stderr," - ");
+ printpts(ach->audpts[ach->numaudpts-1].pts[1]);
+ fprintf(stderr,"\nWARN: Current sector: ");
+ printpts(pts0);
+ fprintf(stderr," - ");
+ printpts(pts1);
+ fprintf(stderr,"\n");
+ }
+// end of new section
+
ach->audpts[ach->numaudpts-1].pts[1]=pts0;
}
noshow:
@@ -1342,6 +1474,7 @@
}
}
writeclose();
+ free(buf_copy);
printvobustatus(va,cursect);
fprintf(stderr,"\n");
free(crs);
@@ -1640,10 +1773,16 @@
if( s>=0 ) {
s=s-vi->sector;
if( s > 0x1fff || s < -(0x1fff)) {
- fprintf(stderr,"\nWARN: audio sector out of range: %d (vobu #%d, pts ",s,i);
- printpts(vi->sectpts[0]);
- fprintf(stderr,")\n");
- s=0;
+
+// new and potantially dangerous override
+ if(printWarnings) {
+ fprintf(stderr,"\nWARN: audio sector out of range: %d (vobu #%d, pts ",s,i);
+ printpts(vi->sectpts[0]);
+ fprintf(stderr,")\n");
+ s=0;
+ }
+//
+
}
if( s < 0 )
s=(-s)|0x8000;
