Lines 15-20
Link Here
|
15 |
* |
15 |
* |
16 |
* With many changes by Scott Smith (trckjunky@users.sourceforge.net) |
16 |
* With many changes by Scott Smith (trckjunky@users.sourceforge.net) |
17 |
* |
17 |
* |
|
|
18 |
* Svcd and raw subtitles by Giacomo Comes <encode2mpeg@users.sourceforge.net> |
19 |
* |
18 |
* This program is distributed in the hope that it will be useful, but |
20 |
* This program is distributed in the hope that it will be useful, but |
19 |
* WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
* WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lines 58-63
Link Here
|
58 |
static int have_bits; |
60 |
static int have_bits; |
59 |
static FILE *fdo; |
61 |
static FILE *fdo; |
60 |
|
62 |
|
|
|
63 |
static unsigned char svcd; |
64 |
|
65 |
|
61 |
typedef struct { |
66 |
typedef struct { |
62 |
unsigned char r, g, b, t; |
67 |
unsigned char r, g, b, t; |
63 |
} palt; |
68 |
} palt; |
Lines 127-132
Link Here
|
127 |
return next_bits & 15; |
132 |
return next_bits & 15; |
128 |
} |
133 |
} |
129 |
|
134 |
|
|
|
135 |
static unsigned char get_next_svcdbits() |
136 |
{ |
137 |
switch (have_bits) { |
138 |
case 0: |
139 |
++have_bits; |
140 |
return (sub[++ofs] >> 6); |
141 |
break; |
142 |
case 1: |
143 |
++have_bits; |
144 |
return ( (sub[ofs]&0x30) >> 4); |
145 |
break; |
146 |
case 2: |
147 |
++have_bits; |
148 |
return ( (sub[ofs]&0x0c) >> 2); |
149 |
break; |
150 |
default: |
151 |
have_bits = FALSE; |
152 |
return (sub[ofs]&0x03); |
153 |
break; |
154 |
} |
155 |
} |
156 |
|
130 |
static unsigned int getpts(unsigned char *buf) |
157 |
static unsigned int getpts(unsigned char *buf) |
131 |
{ |
158 |
{ |
132 |
if (!(buf[1] & 0xc0) || |
159 |
if (!(buf[1] & 0xc0) || |
Lines 160-166
Link Here
|
160 |
static int dvddecode() |
187 |
static int dvddecode() |
161 |
{ |
188 |
{ |
162 |
unsigned int io; |
189 |
unsigned int io; |
163 |
uint16_t size, dsize, i, x, y, t; |
190 |
uint16_t size, dsize, i, x, y, t, cmdpointer, nextcmdp; |
164 |
unsigned char c; |
191 |
unsigned char c; |
165 |
struct spu *s; |
192 |
struct spu *s; |
166 |
|
193 |
|
Lines 185-190
Link Here
|
185 |
s->map[0].x2=0x7fffffff; |
212 |
s->map[0].x2=0x7fffffff; |
186 |
s->map[0].y2=0x7fffffff; |
213 |
s->map[0].y2=0x7fffffff; |
187 |
i = dsize + 4; |
214 |
i = dsize + 4; |
|
|
215 |
cmdpointer = dsize ; |
216 |
nextcmdp = read2(sub+cmdpointer+2); |
217 |
if (nextcmdp<dsize) { |
218 |
if (debug > 0) { |
219 |
fprintf(stderr, |
220 |
"invalid control header nextcommand=%d dsize=%d!\n", |
221 |
nextcmdp, dsize); |
222 |
} |
223 |
nextcmdp = cmdpointer; |
224 |
} |
188 |
|
225 |
|
189 |
t = read2(sub+dsize); |
226 |
t = read2(sub+dsize); |
190 |
|
227 |
|
Lines 254-288
Link Here
|
254 |
i += 5; |
291 |
i += 5; |
255 |
break; |
292 |
break; |
256 |
|
293 |
|
257 |
case 0xff: |
294 |
case 0x07: |
258 |
if (i + 5 > size) { |
295 |
fprintf(stderr, "\tcmd(%5d): changing color/contrast\n",i); |
259 |
if (debug > 4) |
296 |
fprintf(stderr, "command not implemented, please write to dvdauthor-users@lists.sourceforge.net\n"); |
260 |
fprintf(stderr,"\tcmd(%5d): end cmd\n",i); |
297 |
return -1; |
|
|
298 |
break; |
261 |
|
299 |
|
|
|
300 |
case 0xff: |
301 |
if (cmdpointer == nextcmdp) { |
302 |
if (debug > 4) { |
303 |
fprintf(stderr, "cmd: last end command\n"); |
304 |
if (i+1 < size) |
305 |
fprintf(stderr, "data present after last command (%d bytes, size=%d)\n",size-(i+1),size); |
306 |
} |
262 |
i = size; |
307 |
i = size; |
263 |
break; |
308 |
break; |
264 |
} |
309 |
} |
265 |
|
310 |
|
266 |
t = read2(sub + i + 1); |
311 |
if (debug > 4) |
267 |
if (debug > 4) { |
|
|
268 |
fprintf(stderr, "\tcmd(%5d): end cmd\n",i); |
312 |
fprintf(stderr, "\tcmd(%5d): end cmd\n",i); |
269 |
fprintf(stderr, "\tBLK(%5d): time offset: %d; next: %d\n", i+1, t, read2(sub+i+3)); |
|
|
270 |
} |
271 |
|
313 |
|
272 |
if ((sub[i + 3] != sub[dsize + 2]) |
314 |
cmdpointer=nextcmdp; |
273 |
|| (sub[i + 4] != sub[dsize + 3])) { |
315 |
nextcmdp = read2(sub+cmdpointer+2); |
|
|
316 |
if (nextcmdp<dsize) { |
274 |
if (debug > 0) { |
317 |
if (debug > 0) { |
275 |
fprintf(stderr, |
318 |
fprintf(stderr, |
276 |
"invalid control header (%02x%02x != %02x%02x) dsize=%d!\n", |
319 |
"invalid control header nextcommand=%d dsize=%d!\n", |
277 |
sub[i + 3], sub[i + 4], sub[dsize + 2], |
320 |
nextcmdp, dsize); |
278 |
sub[dsize + 3], dsize); |
|
|
279 |
} |
321 |
} |
280 |
|
322 |
nextcmdp = cmdpointer; |
281 |
i = size; |
323 |
i = size; |
282 |
break; |
324 |
break; |
283 |
} |
325 |
} |
|
|
326 |
t = read2(sub+cmdpointer); |
284 |
|
327 |
|
285 |
i += 5; |
328 |
if (debug > 4) { |
|
|
329 |
fprintf(stderr, "\tcmd(%5d): end cmd\n",i); |
330 |
fprintf(stderr, "\tBLK(%5d): time offset: %d; next: %d\n", i+1, t, read2(sub+i+3)); |
331 |
} |
332 |
|
333 |
if (debug > 4 && i+1 < cmdpointer) { |
334 |
fprintf(stderr, "next packet jump: %d bytes\n",cmdpointer-(i+1)); |
335 |
} |
336 |
i=cmdpointer+4; |
286 |
break; |
337 |
break; |
287 |
|
338 |
|
288 |
default: |
339 |
default: |
Lines 424-429
Link Here
|
424 |
FILE *fp; |
475 |
FILE *fp; |
425 |
png_structp png_ptr; |
476 |
png_structp png_ptr; |
426 |
png_infop info_ptr; |
477 |
png_infop info_ptr; |
|
|
478 |
unsigned short subwidth; |
427 |
|
479 |
|
428 |
temp = out_buf = malloc(s->xd * s->yd * 4); |
480 |
temp = out_buf = malloc(s->xd * s->yd * 4); |
429 |
nonzero=0; |
481 |
nonzero=0; |
Lines 480-487
Link Here
|
480 |
png_set_compression_window_bits(png_ptr, 15); |
532 |
png_set_compression_window_bits(png_ptr, 15); |
481 |
png_set_compression_method(png_ptr, 8); |
533 |
png_set_compression_method(png_ptr, 8); |
482 |
|
534 |
|
|
|
535 |
if (svcd) |
536 |
subwidth=704; |
537 |
else |
538 |
subwidth=720; |
483 |
if (full_size) { |
539 |
if (full_size) { |
484 |
png_set_IHDR(png_ptr, info_ptr, 720, 576, |
540 |
png_set_IHDR(png_ptr, info_ptr, subwidth, full_size, |
485 |
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, |
541 |
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, |
486 |
PNG_COMPRESSION_TYPE_DEFAULT, |
542 |
PNG_COMPRESSION_TYPE_DEFAULT, |
487 |
PNG_FILTER_TYPE_DEFAULT); |
543 |
PNG_FILTER_TYPE_DEFAULT); |
Lines 502-512
Link Here
|
502 |
if (full_size) { |
558 |
if (full_size) { |
503 |
char *image; |
559 |
char *image; |
504 |
temp = out_buf; |
560 |
temp = out_buf; |
505 |
image = malloc(720 * 576 * 4); |
561 |
image = malloc(subwidth * full_size * 4); |
506 |
memset(image, 0, 720 * 576 * 4); // fill image full transparrent |
562 |
memset(image, 0, subwidth * full_size * 4); // fill image full transparrent |
507 |
// insert image on the correct position |
563 |
// insert image on the correct position |
508 |
for (y = s->y0; y < s->y0 + s->yd; y++) { |
564 |
for (y = s->y0; y < s->y0 + s->yd; y++) { |
509 |
char *to = &image[y * 720 * 4 + s->x0 * 4]; |
565 |
if ( y >= full_size ) { |
|
|
566 |
fprintf(stderr, "WARN: subtitle %s truncated\n", file_name); |
567 |
break; |
568 |
} |
569 |
char *to = &image[y * subwidth * 4 + s->x0 * 4]; |
510 |
for (x = 0; x < s->xd; x++) { |
570 |
for (x = 0; x < s->xd; x++) { |
511 |
*to++ = *temp++; |
571 |
*to++ = *temp++; |
512 |
*to++ = *temp++; |
572 |
*to++ = *temp++; |
Lines 517-524
Link Here
|
517 |
|
577 |
|
518 |
s->y0 = 0; |
578 |
s->y0 = 0; |
519 |
s->x0 = 0; |
579 |
s->x0 = 0; |
520 |
s->yd = 576; |
580 |
s->yd = full_size; |
521 |
s->xd = 720; |
581 |
s->xd = subwidth; |
522 |
free(out_buf); |
582 |
free(out_buf); |
523 |
out_buf = image; |
583 |
out_buf = image; |
524 |
} |
584 |
} |
Lines 682-687
Link Here
|
682 |
|
742 |
|
683 |
#define bps(n,R,G,B) do { bpal[n].r=R; bpal[n].g=G; bpal[n].b=B; } while (0) |
743 |
#define bps(n,R,G,B) do { bpal[n].r=R; bpal[n].g=G; bpal[n].b=B; } while (0) |
684 |
|
744 |
|
|
|
745 |
static int svcddecode() |
746 |
{ |
747 |
unsigned int io; |
748 |
unsigned short int size, i, x, y; |
749 |
unsigned char c; |
750 |
struct spu *s; |
751 |
int n; |
752 |
|
753 |
size = read2(sub); |
754 |
|
755 |
if (debug > 1) |
756 |
fprintf(stderr, "packet: 0x%x bytes\n", size); |
757 |
|
758 |
s=malloc(sizeof(struct spu)); |
759 |
memset(s,0,sizeof(struct spu)); |
760 |
|
761 |
s->subno=subno++; |
762 |
|
763 |
s->pts[0] = spts; |
764 |
s->pts[1] = -1; |
765 |
s->nummap=1; |
766 |
s->map=malloc(sizeof(struct colormap)); |
767 |
memset(s->map,0,sizeof(struct colormap)); |
768 |
s->map[0].x2=0x7ffffff; |
769 |
s->map[0].y2=0x7ffffff; |
770 |
i = 2; |
771 |
|
772 |
if ( sub[i]&0x08 ) { |
773 |
s->pts[1] = spts + read4(sub+i+2); |
774 |
i += 4; |
775 |
} |
776 |
i += 2 ; |
777 |
|
778 |
s->x0 = read2(sub+i) ; |
779 |
s->y0 = read2(sub+i+2) ; |
780 |
s->xd = read2(sub+i+4) ; |
781 |
s->yd = read2(sub+i+6) ; |
782 |
i += 8 ; |
783 |
if (debug > 4) |
784 |
fprintf(stderr, "img ofs: %d,%d size: %d,%d\n", s->x0, s->y0, s->xd, s->yd); |
785 |
|
786 |
for (n=0;n<4;n++) { |
787 |
int r,g,b; |
788 |
|
789 |
r=sub[i+0+n*4]; |
790 |
g=sub[i+1+n*4]; |
791 |
b=sub[i+2+n*4]; |
792 |
ycrcb_to_rgb( &r, &g, &b); |
793 |
bps(n, r, g, b); |
794 |
if (debug > 4) |
795 |
fprintf(stderr, "palette: %02x%02x%02x%02x\n", sub[i+0+n*4], sub[i+1+n*4], sub[i+2+n*4], sub[i+3+n*4]); |
796 |
} |
797 |
s->map[0].color=0x3210; |
798 |
s->map[0].contrast=( (sub[i+3] >>4) + (sub[i+7] & 0xf0) + ((sub[i+11] & 0xf0) <<4) + ((sub[i+15] & 0xf0) <<8) ) ; |
799 |
// s->map[0].color=0x0123; |
800 |
// s->map[0].contrast=((sub[i+3] & 0xf0) <<8) + ((sub[i+7] & 0xf0) <<4) + (sub[i+11] & 0xf0) + (sub[i+15] >>4) ; |
801 |
if (debug > 4) |
802 |
fprintf(stderr, "tpalette: %04x\n", s->map[0].contrast); |
803 |
i += 16; |
804 |
|
805 |
if ( sub[i++] >> 6 ) { |
806 |
if (debug > 4) |
807 |
fprintf(stderr, "cmd: shift (unsupported), direction=%d time=%f\n", (sub[i-1] >> 4) & 0x3, read4(sub)/90000.0); |
808 |
i += 4; |
809 |
} |
810 |
ofs = i+2 - 1; // get_next_svcdbits will increment ofs by 1 |
811 |
ofs1 = ofs + read2(sub+i) ; |
812 |
i += 2 ; |
813 |
if (debug > 4) |
814 |
fprintf(stderr, "cmd: image offsets 0x%x 0x%x\n", ofs, ofs1); |
815 |
|
816 |
|
817 |
have_bits = FALSE; |
818 |
x = y = 0; |
819 |
io = 0; |
820 |
s->img = malloc( s->xd*s->yd); |
821 |
memset(s->img,0,s->xd*s->yd); |
822 |
|
823 |
|
824 |
while ((ofs < size) && (y < s->yd)) { |
825 |
if ( (c = get_next_svcdbits()) ) { |
826 |
s->img[io++] = c; |
827 |
++x; |
828 |
} else { |
829 |
c = get_next_svcdbits() + 1; |
830 |
x += c; |
831 |
io += c; |
832 |
} |
833 |
if (x >= s->xd) { |
834 |
y += 2; |
835 |
x = 0; |
836 |
if ((y >= s->yd) && !(y & 1)) { |
837 |
y = 1; |
838 |
ofs = ofs1; |
839 |
} |
840 |
io = s->xd * y; |
841 |
have_bits = FALSE; |
842 |
} |
843 |
} |
844 |
|
845 |
s->pts[0] += add_offset; |
846 |
if( s->pts[1] != -1 ) |
847 |
s->pts[1] += add_offset; |
848 |
|
849 |
addspu(s); |
850 |
|
851 |
if (debug > 2) |
852 |
fprintf(stderr, "ofs: 0x%x y: %d\n", ofs, y); |
853 |
|
854 |
return 0; |
855 |
} /* end fuction svcd_decode */ |
856 |
|
857 |
void raw_save_shift(unsigned char *cbuf, unsigned short i, unsigned char b0, unsigned char b1, unsigned char b2, unsigned char n, unsigned char stuffsize) |
858 |
{ |
859 |
unsigned short y0, y1, suby1; |
860 |
short delta; |
861 |
unsigned char c; |
862 |
|
863 |
if ( full_size == 480 ) |
864 |
suby1 = 575; |
865 |
else |
866 |
suby1 = 479; |
867 |
if ( svcd ) { |
868 |
y0 = read2(cbuf+i); |
869 |
y1 = y0 + read2(cbuf+i+4) - 1; |
870 |
} else { |
871 |
y0 = b0 * 16 | ( b1 >> 4 ); |
872 |
y1 = ( b1 & 0xf ) * 256 + b2 ; |
873 |
} |
874 |
if ( y0 > suby1 - y1 ) |
875 |
delta = y1 * (full_size / (suby1+1.0) - 1); |
876 |
else |
877 |
delta = y0 * (full_size / (suby1+1.0) - 1); |
878 |
if ( full_size == 480 ) { |
879 |
if ( y1 + delta >= full_size ) |
880 |
delta = full_size - 1 - y1; |
881 |
if ( y0 + delta < 0 ) |
882 |
delta = -y0; |
883 |
} |
884 |
if (debug > 3 ) |
885 |
fprintf(stderr, "raw shift: %hu -> %hu, %hu -> %hu\n", y0,y0+delta,y1,y1+delta); |
886 |
if (debug > 0 && y1 + delta >= full_size ) |
887 |
fprintf(stderr, "WARN: raw shift: subtitle height (%d) exceed %s standard\n", y1 + delta + 1,full_size==480?"NTSC":"PAL"); |
888 |
if ( svcd ) { |
889 |
cbuf[i] = ( y0 + delta ) >> 8 ; |
890 |
cbuf[i+1] = y0 + delta ; |
891 |
cbuf[i+4] = ( y1 + delta - y0 + 1 ) >> 8 ; |
892 |
cbuf[i+5] = y1 + delta - y0 + 1; |
893 |
} else { |
894 |
c = ( y0 + delta ) >> 4 ; |
895 |
if ( n ) { |
896 |
fseek(fdo,-(n+14+stuffsize),SEEK_END); |
897 |
fwrite(&c,1,1,fdo); |
898 |
} else |
899 |
cbuf[i-2] = c ; |
900 |
c = ((( y0 + delta ) & 0xf ) << 4) | (( y1 + delta ) >> 8) ; |
901 |
if ( n > 1 ) |
902 |
fwrite(&c,1,1,fdo); |
903 |
else |
904 |
cbuf[i-1] = c ; |
905 |
if ( n ) |
906 |
fseek(fdo,0,SEEK_END); |
907 |
cbuf[i] = y1 + delta; |
908 |
} |
909 |
} |
910 |
|
685 |
static void usage(void) |
911 |
static void usage(void) |
686 |
{ |
912 |
{ |
687 |
fprintf(stderr, |
913 |
fprintf(stderr, |
Lines 693-702
Link Here
|
693 |
fprintf(stderr, |
919 |
fprintf(stderr, |
694 |
"-v <level> verbosity level [0]\n"); |
920 |
"-v <level> verbosity level [0]\n"); |
695 |
fprintf(stderr, |
921 |
fprintf(stderr, |
696 |
"-f resize images to full size [720x576]\n"); |
922 |
"-f resize images to full PAL size [720x576]\n"); |
|
|
923 |
fprintf(stderr, |
924 |
"-n resize images to full NTSC size [720x480]\n"); |
697 |
fprintf(stderr, |
925 |
fprintf(stderr, |
698 |
"-s <stream> number of the substream to extract [0]\n"); |
926 |
"-s <stream> number of the substream to extract [0]\n"); |
699 |
fprintf(stderr, |
927 |
fprintf(stderr, |
|
|
928 |
"-r raw subtitle extraction\n"); |
929 |
fprintf(stderr, |
700 |
"-p <file> name of file with dvd palette [none]\n"); |
930 |
"-p <file> name of file with dvd palette [none]\n"); |
701 |
fprintf(stderr, " if palette file ends with .rgb\n"); |
931 |
fprintf(stderr, " if palette file ends with .rgb\n"); |
702 |
fprintf(stderr, " treated as a RGB\n"); |
932 |
fprintf(stderr, " treated as a RGB\n"); |
Lines 706-711
Link Here
|
706 |
fprintf(stderr, "\n"); |
936 |
fprintf(stderr, "\n"); |
707 |
} |
937 |
} |
708 |
|
938 |
|
|
|
939 |
void write_raw_pes(unsigned int code, unsigned short length, unsigned char *buf) |
940 |
{ |
941 |
unsigned short a; |
942 |
code=htonl(code); |
943 |
fwrite(&code,4,1,fdo); |
944 |
a=htons(length); |
945 |
fwrite(&a,2,1,fdo); |
946 |
fwrite(buf,1,length,fdo); |
947 |
} |
709 |
|
948 |
|
710 |
int main(int argc, char **argv) |
949 |
int main(int argc, char **argv) |
711 |
{ |
950 |
{ |
Lines 719-724
Link Here
|
719 |
unsigned char cbuf[CBUFSIZE]; |
958 |
unsigned char cbuf[CBUFSIZE]; |
720 |
unsigned char psbuf[PSBUFSIZE]; |
959 |
unsigned char psbuf[PSBUFSIZE]; |
721 |
unsigned char nbuf[256], *palet_file, *iname[256]; |
960 |
unsigned char nbuf[256], *palet_file, *iname[256]; |
|
|
961 |
char raw_stream = FALSE; |
962 |
char issub = FALSE; |
963 |
char haspalette = FALSE; |
964 |
unsigned char packbuf[4+PSBUFSIZE+7]={0,0,0x1,0xba,0,0,0,0,0,0,0,0,0,0,0xff,0xff,0xff,0xff,0xff,0xff,0xff} ; |
965 |
unsigned char sector[2048]; |
722 |
|
966 |
|
723 |
fputs(PACKAGE_HEADER("spuunmux"),stderr); |
967 |
fputs(PACKAGE_HEADER("spuunmux"),stderr); |
724 |
|
968 |
|
Lines 727-733
Link Here
|
727 |
palet_file = 0; |
971 |
palet_file = 0; |
728 |
Inc = inc = 0; |
972 |
Inc = inc = 0; |
729 |
|
973 |
|
730 |
while ((option = getopt(argc, argv, "o:v:fs:p:Vh")) != -1) { |
974 |
while ((option = getopt(argc, argv, "o:v:fnrs:p:Vh")) != -1) { |
731 |
switch (option) { |
975 |
switch (option) { |
732 |
case 'o': |
976 |
case 'o': |
733 |
base_name = optarg; |
977 |
base_name = optarg; |
Lines 736-742
Link Here
|
736 |
debug = atoi(optarg); |
980 |
debug = atoi(optarg); |
737 |
break; |
981 |
break; |
738 |
case 'f': |
982 |
case 'f': |
739 |
full_size = TRUE; |
983 |
full_size = 576; |
|
|
984 |
break; |
985 |
case 'n': |
986 |
full_size = 480; |
987 |
break; |
988 |
case 'r': |
989 |
raw_stream = TRUE; |
740 |
break; |
990 |
break; |
741 |
case 's': |
991 |
case 's': |
742 |
stream_number = atoi(optarg); |
992 |
stream_number = atoi(optarg); |
Lines 806-811
Link Here
|
806 |
|
1056 |
|
807 |
} |
1057 |
} |
808 |
fclose(fdo); |
1058 |
fclose(fdo); |
|
|
1059 |
haspalette = TRUE; |
809 |
} else { |
1060 |
} else { |
810 |
fprintf(stderr, "unable to open %s, using defaults\n", palet_file); |
1061 |
fprintf(stderr, "unable to open %s, using defaults\n", palet_file); |
811 |
} |
1062 |
} |
Lines 817-825
Link Here
|
817 |
return -1; |
1068 |
return -1; |
818 |
} |
1069 |
} |
819 |
|
1070 |
|
|
|
1071 |
if (raw_stream) { |
1072 |
sprintf(nbuf, "%s.spu", base_name); |
1073 |
fdo = fopen(nbuf, "w+"); |
1074 |
} else { |
820 |
sprintf(nbuf, "%s.xml", base_name); |
1075 |
sprintf(nbuf, "%s.xml", base_name); |
821 |
fdo = fopen(nbuf, "w+"); |
1076 |
fdo = fopen(nbuf, "w+"); |
822 |
fprintf(fdo, "<subpictures>\n\t<stream>\n"); |
1077 |
fprintf(fdo, "<subpictures>\n\t<stream>\n"); |
|
|
1078 |
} |
823 |
|
1079 |
|
824 |
pts = 0; |
1080 |
pts = 0; |
825 |
subno = 0; |
1081 |
subno = 0; |
Lines 828-833
Link Here
|
828 |
add_offset = 450; // for rounding purposes |
1084 |
add_offset = 450; // for rounding purposes |
829 |
|
1085 |
|
830 |
while (inc < Inc) { |
1086 |
while (inc < Inc) { |
|
|
1087 |
unsigned short lastdata = FALSE; |
831 |
fd = varied_open(iname[inc], O_RDONLY); |
1088 |
fd = varied_open(iname[inc], O_RDONLY); |
832 |
if (fd.h == 0) { |
1089 |
if (fd.h == 0) { |
833 |
fprintf(stderr, "error opening file %s\n", iname[inc]); |
1090 |
fprintf(stderr, "error opening file %s\n", iname[inc]); |
Lines 841-849
Link Here
|
841 |
inc++; |
1098 |
inc++; |
842 |
|
1099 |
|
843 |
while (fread(&c, 1, 4, fd.h) == 4) { |
1100 |
while (fread(&c, 1, 4, fd.h) == 4) { |
|
|
1101 |
static unsigned int old_system_time = -1; |
844 |
c=ntohl(c); |
1102 |
c=ntohl(c); |
845 |
if (c == 0x000001ba) { // start PS (Program stream) |
1103 |
if (c == 0x000001ba) { // start PS (Program stream) |
846 |
static unsigned int old_system_time = -1; |
|
|
847 |
unsigned int new_system_time; |
1104 |
unsigned int new_system_time; |
848 |
l_01ba: |
1105 |
l_01ba: |
849 |
if (debug > 5) |
1106 |
if (debug > 5) |
Lines 875-880
Link Here
|
875 |
} |
1132 |
} |
876 |
old_system_time = new_system_time; |
1133 |
old_system_time = new_system_time; |
877 |
|
1134 |
|
|
|
1135 |
if (raw_stream) { |
1136 |
for (c = 0; c < PSBUFSIZE; c++) |
1137 |
packbuf[c+4] = psbuf[c]; |
1138 |
if (stream_number == 32) { |
1139 |
fwrite(packbuf,1,PSBUFSIZE+4+(packbuf[13]&0x7),fdo); |
1140 |
} else { |
1141 |
unsigned int scr = old_system_time+add_offset; |
1142 |
|
1143 |
packbuf[4] = ( (scr >> 27) & 0x38 ) | ( (scr >> 28) & 0x3 ) | 0x44 ; |
1144 |
packbuf[5] = (scr >> 20) ; |
1145 |
packbuf[6] = ( (scr >> 12) & 0xf8 ) | ( (scr >> 13) & 0x3 ) | 0x4 ; |
1146 |
packbuf[7] = (scr >> 5) ; |
1147 |
packbuf[8] &= 0x7 ; |
1148 |
packbuf[8] |= (scr << 3) ; |
1149 |
} |
1150 |
issub=FALSE; |
1151 |
} else |
878 |
flushspus(old_system_time); |
1152 |
flushspus(old_system_time); |
879 |
|
1153 |
|
880 |
if (debug > 5) { |
1154 |
if (debug > 5) { |
Lines 926-972
Link Here
|
926 |
if (debug > 5) |
1200 |
if (debug > 5) |
927 |
fprintf(stderr, "tid: %d\n", pts); |
1201 |
fprintf(stderr, "tid: %d\n", pts); |
928 |
|
1202 |
|
929 |
if ( /*(debug > 1) && */ (cbuf[next_word] == 0x70)) |
1203 |
if (cbuf[next_word] == stream_number + 32 || (cbuf[next_word] == 0x70 && cbuf[next_word+1] == stream_number) || |
930 |
fprintf(stderr, "substr: %d\n", |
1204 |
(raw_stream && stream_number == 32 && ( (cbuf[next_word] < 64 && cbuf[next_word] > 31) || cbuf[next_word] == 0x70 ) ) ) { |
931 |
cbuf[next_word + 1]); |
1205 |
if ( cbuf[next_word] == 0x70 ) |
|
|
1206 |
svcd = 4 ; |
1207 |
else |
1208 |
svcd = 0 ; |
932 |
|
1209 |
|
933 |
if (cbuf[next_word] == stream_number + 32) { |
1210 |
if ( /* (debug < 6) && */ (debug > 1)) { |
934 |
if ((debug < 6) && (debug > 1)) { |
|
|
935 |
fprintf(stderr, |
1211 |
fprintf(stderr, |
936 |
"id: 0x%x 0x%x %d tid: %d\n", |
1212 |
"id: 0x%x 0x%x %d tid: %d\n", |
937 |
cbuf[next_word], package_length, |
1213 |
cbuf[next_word], package_length, |
938 |
next_word, pts); |
1214 |
next_word, pts); |
939 |
} |
1215 |
} |
940 |
|
1216 |
|
|
|
1217 |
if ( raw_stream ) { |
1218 |
if ( stream_number != 32 ) { |
1219 |
unsigned char stuffsize; |
1220 |
|
1221 |
if (!svcd && cbuf[2]>4 && haspalette && !lastdata ) { |
1222 |
// write palette info |
1223 |
unsigned char c ; |
1224 |
unsigned int scr = old_system_time+add_offset-147; |
1225 |
|
1226 |
memset(sector,0xff,2048); |
1227 |
for (c=0;c<PSBUFSIZE;c++) |
1228 |
sector[c+4]=psbuf[c]; |
1229 |
sector[0] = 0 ; |
1230 |
sector[1] = 0 ; |
1231 |
sector[2] = 0x1 ; |
1232 |
sector[3] = 0xba ; |
1233 |
sector[4] = ( (scr >> 27) & 0x38 ) | ( (scr >> 28) & 0x3 ) | 0x44 ; |
1234 |
sector[5] = (scr >> 20) ; |
1235 |
sector[6] = ( (scr >> 12) & 0xf8 ) | ( (scr >> 13) & 0x3 ) | 0x4 ; |
1236 |
sector[7] = (scr >> 5) ; |
1237 |
sector[8] &= 0x7 ; |
1238 |
sector[8] |= (scr << 3) ; |
1239 |
sector[13] &= 0xf8 ; |
1240 |
|
1241 |
sector[14] = 0 ; |
1242 |
sector[15] = 0 ; |
1243 |
sector[16] = 0x1 ; |
1244 |
sector[17] = 0xbe ; |
1245 |
sector[18] = ( (2048-6-10-4) >> 8) ; |
1246 |
sector[19] = 2028%256 ; |
1247 |
|
1248 |
strcpy(sector+20,"dvdauthor-data"); |
1249 |
sector[35] = 1 ; |
1250 |
sector[36] = 1 ; |
1251 |
sector[37] = cbuf[next_word] ; |
1252 |
sector[38] = ( (pts+add_offset) >> 24 ) ; |
1253 |
sector[39] = ( (pts+add_offset) >> 16 ) ; |
1254 |
sector[40] = ( (pts+add_offset) >> 8 ) ; |
1255 |
sector[41] = (pts+add_offset) ; |
1256 |
sector[42] = 0xff ; |
1257 |
sector[43] = 0xff ; |
1258 |
sector[44] = 0xff ; |
1259 |
sector[45] = 0xff ; |
1260 |
sector[46] = 1 ; |
1261 |
sector[47] = 16 ; |
1262 |
for (c=0;c<sector[47];c++){ |
1263 |
sector[48+3*c+0] = RGB2Y(bpal[c].r,bpal[c].g,bpal[c].b); |
1264 |
sector[48+3*c+1] = RGB2Cr(bpal[c].r,bpal[c].g,bpal[c].b); |
1265 |
sector[48+3*c+2] = RGB2Cb(bpal[c].r,bpal[c].g,bpal[c].b); |
1266 |
} |
1267 |
|
1268 |
fwrite(sector,2048,1,fdo); |
1269 |
} |
1270 |
stuffsize = packbuf[13]&0x7 ; |
1271 |
fwrite(packbuf,1,PSBUFSIZE+4+stuffsize,fdo); |
1272 |
if ( cbuf[1]&0x80 ) { |
1273 |
cbuf[3] &= 0xf1 ; |
1274 |
cbuf[3] |= (((pts+add_offset) >> 29) & 0xe) ; |
1275 |
cbuf[4] = ((pts+add_offset) >> 22) ; |
1276 |
cbuf[5] = (((pts+add_offset) >> 14) | 0x1) ; |
1277 |
cbuf[6] = ((pts+add_offset) >> 7) ; |
1278 |
cbuf[7] = (((pts+add_offset) << 1) | 0x1) ; |
1279 |
} |
1280 |
if ( full_size ) { // raw shift |
1281 |
static unsigned short subcmd, process; |
1282 |
unsigned short startsub; |
1283 |
unsigned char c; |
1284 |
static unsigned char b0, b1, b2, getbyte; |
1285 |
|
1286 |
startsub = cbuf[2] + 3 + 1 + svcd; |
1287 |
if ( svcd ) { |
1288 |
if (!subi) |
1289 |
raw_save_shift(cbuf, startsub + 6 + ( cbuf[startsub+2]&0x08 ) ? 4 : 0, 0, 0, 0, 0, 0); |
1290 |
} else { |
1291 |
if (!subi) { |
1292 |
process = 1; |
1293 |
subcmd = read2(cbuf + startsub + 2) + 4; |
1294 |
} |
1295 |
if ( getbyte ) { |
1296 |
if ( getbyte == 2 ) |
1297 |
b1 = cbuf[startsub+subcmd++]; |
1298 |
b2 = cbuf[startsub+subcmd++]; |
1299 |
raw_save_shift(cbuf, startsub+subcmd-1, b0, b1, b2, 3-getbyte, stuffsize); |
1300 |
getbyte = 0; |
1301 |
} |
1302 |
while ( subcmd <= package_length - startsub -1 && process ) { |
1303 |
if ( process == 2 ) { |
1304 |
c = 5; |
1305 |
subcmd -= 4; |
1306 |
process = 1; |
1307 |
} else |
1308 |
c = cbuf[startsub+subcmd] ; |
1309 |
switch ( c ) { |
1310 |
case 0: |
1311 |
case 1: |
1312 |
case 2: |
1313 |
++subcmd; |
1314 |
break; |
1315 |
case 3: |
1316 |
case 4: |
1317 |
subcmd += 3; |
1318 |
break; |
1319 |
case 6: |
1320 |
subcmd += 5; |
1321 |
break; |
1322 |
case 5: |
1323 |
subcmd += 4; |
1324 |
if ( subcmd > package_length - startsub - 1 ) { |
1325 |
process = 2; |
1326 |
break; |
1327 |
} |
1328 |
b0 = cbuf[startsub+subcmd++]; |
1329 |
if ( subcmd > package_length - startsub - 1 ) { |
1330 |
getbyte = 2; |
1331 |
break; |
1332 |
} |
1333 |
b1 = cbuf[startsub+subcmd++]; |
1334 |
if ( subcmd > package_length - startsub - 1 ) { |
1335 |
getbyte = 1; |
1336 |
break; |
1337 |
} |
1338 |
b2 = cbuf[startsub+subcmd++]; |
1339 |
raw_save_shift(cbuf, startsub+subcmd-1, b0, b1, b2, 0, stuffsize); |
1340 |
break; |
1341 |
default : |
1342 |
process = 0; |
1343 |
++subcmd; |
1344 |
break; |
1345 |
} /* end switch */ |
1346 |
if (debug > 4 ) |
1347 |
fprintf(stderr, "raw shift: cmd=%u\n", c); |
1348 |
} /* end while */ |
1349 |
subcmd -= package_length - startsub; |
1350 |
} /* end if svcd */ |
1351 |
} /* end if full_size */ |
1352 |
} /* end if stream_number != 32 */ |
1353 |
write_raw_pes(c,package_length,cbuf); |
1354 |
if ( stream_number == 32 ) { |
1355 |
package_length=0; |
1356 |
break; |
1357 |
} |
1358 |
issub=TRUE; |
1359 |
} /* end if raw_stream */ |
1360 |
|
941 |
if (!subi) { |
1361 |
if (!subi) { |
942 |
subs = |
1362 |
subs = |
943 |
((unsigned int) cbuf[next_word + 1] << |
1363 |
((unsigned int) cbuf[next_word + 1 + svcd] << |
944 |
8) + cbuf[next_word + 2]; |
1364 |
8) + cbuf[next_word + 2 + svcd]; |
945 |
|
1365 |
|
946 |
spts = pts; |
1366 |
spts = pts; |
947 |
} |
1367 |
} |
948 |
|
1368 |
|
949 |
memcpy(sub + subi, cbuf + next_word + 1, |
1369 |
memcpy(sub + subi, cbuf + next_word + 1 + svcd, |
950 |
package_length - next_word - 1); |
1370 |
package_length - next_word - 1 - svcd); |
951 |
|
1371 |
|
952 |
if (debug > 1) { |
1372 |
if (debug > 1) { |
953 |
fprintf(stderr, "found %d bytes of data\n", |
1373 |
fprintf(stderr, "found %d bytes of data\n", |
954 |
package_length - next_word - 1); |
1374 |
package_length - next_word - 1 - svcd); |
955 |
} |
1375 |
} |
956 |
|
1376 |
|
957 |
subi += package_length - next_word - 1; |
1377 |
subi += package_length - next_word - 1 - svcd; |
958 |
|
1378 |
|
959 |
if (debug > 2) { |
1379 |
if (debug > 2) { |
960 |
fprintf(stderr, |
1380 |
fprintf(stderr, |
961 |
"subi: %d (0x%x) subs: %d (0x%x) b-a-1: %d (0x%x)\n", |
1381 |
"subi: %d (0x%x) subs: %d (0x%x) b-a-1: %d (0x%x)\n", |
962 |
subi, subi, subs, subs, |
1382 |
subi, subi, subs, subs, |
963 |
package_length - next_word - 1, |
1383 |
package_length - next_word - 1 - svcd, |
964 |
package_length - next_word - 1); |
1384 |
package_length - next_word - 1 - svcd); |
965 |
} |
1385 |
} |
966 |
|
1386 |
|
|
|
1387 |
if (svcd) { |
1388 |
if ( cbuf[next_word+2] & 0x80 ) { |
1389 |
subi = 0; |
1390 |
if (!raw_stream) { |
1391 |
next_word = svcddecode(); |
1392 |
|
1393 |
if (next_word) { |
1394 |
fprintf(stderr, |
1395 |
"found unreadable subtitle at %.2fs, skipping\n", |
1396 |
(double) spts / 90000); |
1397 |
continue; |
1398 |
} |
1399 |
} |
1400 |
} |
1401 |
} else { |
967 |
if (subs == subi) { |
1402 |
if (subs == subi) { |
968 |
subi = 0; |
1403 |
subi = 0; |
969 |
|
1404 |
|
|
|
1405 |
if (!raw_stream) { |
970 |
next_word = dvddecode(); |
1406 |
next_word = dvddecode(); |
971 |
|
1407 |
|
972 |
if (next_word) { |
1408 |
if (next_word) { |
Lines 975-987
Link Here
|
975 |
(double) spts / 90000); |
1411 |
(double) spts / 90000); |
976 |
continue; |
1412 |
continue; |
977 |
} |
1413 |
} |
|
|
1414 |
} |
978 |
} /* end if subs == subi */ |
1415 |
} /* end if subs == subi */ |
979 |
} |
1416 |
} |
|
|
1417 |
} |
980 |
package_length=0; |
1418 |
package_length=0; |
981 |
break; |
1419 |
break; |
982 |
case 0x01e0: |
1420 |
case 0x01e0: |
983 |
if( firstvideo==-1 ) { |
1421 |
if( firstvideo==-1 ) { |
984 |
fread(cbuf, 1, package_length, fd.h); |
1422 |
fread(cbuf, 1, package_length, fd.h); |
|
|
1423 |
if ( raw_stream && stream_number == 32 ) |
1424 |
write_raw_pes(c,package_length,cbuf); |
985 |
firstvideo=getpts(cbuf); |
1425 |
firstvideo=getpts(cbuf); |
986 |
add_offset-=firstvideo; |
1426 |
add_offset-=firstvideo; |
987 |
package_length=0; |
1427 |
package_length=0; |
Lines 1012-1019
Link Here
|
1012 |
fprintf(stderr, "padding stream %d bytes\n", |
1452 |
fprintf(stderr, "padding stream %d bytes\n", |
1013 |
package_length); |
1453 |
package_length); |
1014 |
fread(cbuf, 1, package_length, fd.h); |
1454 |
fread(cbuf, 1, package_length, fd.h); |
1015 |
if( package_length > 30 ) { |
1455 |
if( raw_stream && ( issub || stream_number == 32 ) ) { |
|
|
1456 |
write_raw_pes(c,package_length,cbuf); |
1457 |
} else if( package_length > 30 ) { |
1016 |
int i; |
1458 |
int i; |
|
|
1459 |
unsigned short int length=package_length; |
1017 |
|
1460 |
|
1018 |
package_length=0; |
1461 |
package_length=0; |
1019 |
i=0; |
1462 |
i=0; |
Lines 1022-1027
Link Here
|
1022 |
i=15; |
1465 |
i=15; |
1023 |
if( cbuf[i]!=1 ) |
1466 |
if( cbuf[i]!=1 ) |
1024 |
break; |
1467 |
break; |
|
|
1468 |
if( raw_stream && (cbuf[i+2] == stream_number + 32) ) { |
1469 |
fwrite(packbuf,1,PSBUFSIZE+4+(packbuf[13]&0x7),fdo); |
1470 |
write_raw_pes(c,length,cbuf); |
1471 |
lastdata = 1; |
1472 |
break; |
1473 |
} |
1025 |
switch(cbuf[i+1]) { |
1474 |
switch(cbuf[i+1]) { |
1026 |
case 1: // subtitle/menu color and button information |
1475 |
case 1: // subtitle/menu color and button information |
1027 |
{ |
1476 |
{ |
Lines 1152-1157
Link Here
|
1152 |
goto l_01ba; |
1601 |
goto l_01ba; |
1153 |
} /* end switch */ |
1602 |
} /* end switch */ |
1154 |
fread(cbuf, 1, package_length, fd.h); |
1603 |
fread(cbuf, 1, package_length, fd.h); |
|
|
1604 |
if (lastdata) { |
1605 |
if ( lastdata == 1 ) |
1606 |
lastdata = 2; |
1607 |
else |
1608 |
lastdata = FALSE; |
1609 |
} |
1155 |
} |
1610 |
} |
1156 |
|
1611 |
|
1157 |
} /* end if 0xbd010000 */ |
1612 |
} /* end if 0xbd010000 */ |
Lines 1161-1169
Link Here
|
1161 |
varied_close(fd); |
1616 |
varied_close(fd); |
1162 |
} /* end while inc < Inc */ |
1617 |
} /* end while inc < Inc */ |
1163 |
|
1618 |
|
|
|
1619 |
if (!raw_stream) { |
1164 |
flushspus(0x7fffffff); |
1620 |
flushspus(0x7fffffff); |
1165 |
|
1621 |
|
1166 |
fprintf(fdo, "\t</stream>\n</subpictures>\n"); |
1622 |
fprintf(fdo, "\t</stream>\n</subpictures>\n"); |
|
|
1623 |
} |
1167 |
fclose(fdo); |
1624 |
fclose(fdo); |
1168 |
|
1625 |
|
1169 |
return 0; |
1626 |
return 0; |