diff -urN dvdauthor-0.6.11.orig/src/dvdvob.c dvdauthor-0.6.11/src/dvdvob.c --- dvdauthor-0.6.11.orig/src/dvdvob.c 2005-04-25 20:08:16.101361456 -0500 +++ dvdauthor-0.6.11/src/dvdvob.c 2005-04-25 20:17:01.408502632 -0500 @@ -226,7 +226,8 @@ return dflt; } -static void transpose_ts(unsigned char *buf,pts_t tsoffs) + +static void transpose_ts(unsigned char *buf, pts_t scroffs, pts_t tsoffs) { // pack scr if( buf[0] == 0 && @@ -234,25 +235,53 @@ 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; +} + + static int mpa_valid(unsigned char *b) { unsigned int v=(b[0]<<24)|(b[1]<<16)|(b[2]<<8)|b[3]; @@ -534,8 +563,12 @@ if( buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 ) scanvideoptr(va,buf+i,thisvi,cursect,vsi); } + + if( !va->vd.vmpeg ) - 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 ) { @@ -810,6 +843,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; @@ -825,6 +859,8 @@ int i,j; int hadfirstvobu=0; pts_t backoffs=0, lastscr=0; + int generate_vobu=0,copy_packet=0; + pts_t tsoffs=0; struct vob *s=va->vobs[vnum]; int prevvidsect=-1; struct vscani vsi; @@ -852,8 +888,9 @@ } 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)) ) { if( i==-1 ) { fprintf(stderr,"\nERR: Error while reading: %s\n",strerror(errno)); exit(1); @@ -958,6 +995,40 @@ writeundo(); continue; } + + 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; + if( buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) { pts_t newscr=readscr(buf+4); if( newscr < lastscr ) { @@ -968,15 +1039,15 @@ 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); + 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); } if( buf[14] == 0 && buf[15] == 0 && @@ -1022,12 +1093,12 @@ printvobustatus(va,cursect); vsi.lastrefsect=0; vsi.firstgop=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; } @@ -1363,6 +1434,7 @@ } } writeclose(); + free(buf_copy); printvobustatus(va,cursect); fprintf(stderr,"\n"); if (audioDiscontinuityCount > 0)