diff -urN dvdauthor-418/src/ifogen.c dvdauthor-418-fully-patched/src/ifogen.c --- dvdauthor-418/src/ifogen.c Sat Oct 4 11:00:36 2003 +++ dvdauthor-418-fully-patched/src/ifogen.c Sat Oct 4 11:19:23 2003 @@ -900,7 +900,7 @@ fprintf(stderr,"\n"); } -void transpose_ts(unsigned char *buf,int tsoffs) +void transpose_ts(unsigned char *buf,int scroffs, int tsoffs) { // pack scr if( buf[0] == 0 && @@ -908,25 +908,52 @@ buf[2] == 1 && buf[3] == 0xba ) { - 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[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+offs+23,readpts(buf+offs+23)+tsoffs); // dts? - 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; +} + int mpa_valid(unsigned char *b) { unsigned int v=(b[0]<<24)|(b[1]<<16)|(b[2]<<8)|b[3]; @@ -1242,6 +1269,7 @@ int FindVobus(char *fbase,struct vob_summary *va,int ismenu) { unsigned char *buf; + unsigned char *buf_copy = (unsigned char*) malloc(2048); FILE *h; int cursect=0,fsect=-1,fnum,pnum,outnum=-ismenu+1; int ispipe,vobid=0; @@ -1257,6 +1285,7 @@ for( fnum=0; fnumnumsources; fnum++ ) { int hadfirstvobu=0,chapterindex=0,backoffs=0,cellid=1; + int generate_vobu=0,copy_packet=0,tsoffs=0; struct source *s=&p->sources[fnum]; if( fnum && p->sources[fnum-1].numvobus ) { struct source *ps=&p->sources[fnum-1]; @@ -1282,13 +1311,12 @@ fsect=-1; } buf=writegrabbuf(); - if( 2048 != fread(buf,1,2048,h) ) { + if (copy_packet == 1) { + memcpy( buf, buf_copy, 2048); + } else if( 2048 != fread(buf,1,2048,h) ) { writeundo(); break; } - if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) - backoffs=readscr(buf+4); - transpose_ts(buf,-backoffs); if( fsect == -1 ) { char newname[200]; fsect=0; @@ -1298,6 +1326,45 @@ 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; + + if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) + backoffs=readscr(buf+4); + + 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); + } + transpose_ts(buf,-backoffs,-tsoffs); + if( buf[14] == 0 && buf[15] == 0 && buf[16] == 1 && @@ -1361,12 +1428,12 @@ if( !(s->numvobus&15) ) printvobustatus(va,cursect); vsi.lastrefsect=-1; - } 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; } @@ -1483,6 +1550,7 @@ } } writeclose(); + free(buf_copy); printvobustatus(va,cursect); fprintf(stderr,"\n"); return 1; @@ -2764,6 +2832,8 @@ char *fbase=0; int curva=1,hadchapter=0,istoc=0,l, usedtocflag=0; // whether the 'istoc' value has been used or not + int inmenu=0; // lets us know if an mpeg file is required before we + // can start another major thingy. #ifdef HAVE_GETOPT_LONG static struct option longopts[]={ {"video",1,0,'v'}, @@ -2823,10 +2893,16 @@ fprintf(stderr,"ERR: already specified menu or title\n"); return 1; } + if (inmenu) + { + fprintf(stderr,"ERR: You must define the menu movie before another menu!\n"); + return 1; + } usedtocflag=1; // force -T to occur before -m va_addpgc(&va[0]); hadchapter=0; curva=0; + inmenu=1; break; case 't': @@ -2834,6 +2910,11 @@ fprintf(stderr,"ERR: TOC cannot have titles\n"); return 1; } + if (inmenu) + { + fprintf(stderr,"ERR: You must define the menu movie before the title!\n"); + return 1; + } usedtocflag=1; va_addpgc(&va[1]); hadchapter=0; @@ -2885,6 +2966,7 @@ MAINDEFPGC; + inmenu=0; // signal we have a video file. c=&vc->pgcs[vc->numpgcs-1]; if( !c->numsources || c->sources[c->numsources-1].fname!=0 ) { c->sources=(struct source *)realloc(c->sources,(c->numsources+1)*sizeof(struct source));