Add a list of video specifications - perhaps it should go in /sys/lib ? Updated yuv so it uses this to generate its list of valid file sizes. -Steve Reference: /n/sources/patch/applied/video-specs Date: Thu Dec 14 16:31:54 CET 2006 Signed-off-by: steve@quintile.net --- /sys/src/cmd/jpg/readyuv.c Thu Dec 14 16:19:18 2006 +++ /sys/src/cmd/jpg/readyuv.c Thu Dec 14 16:19:13 2006 @@ -24,11 +24,54 @@ */ enum { - PAL = 576, NTSC = 486 }; + pixels = 720, + r601pal = 576, + r601ntsc = 486 +}; static int lsbtab[] = { 6, 4, 2, 0}; +int +looksize(char *file, vlong size, int *pixels, int *lines, int *bits) +{ + Biobuf *bp; + uvlong l, p; + char *s, *a[12]; + + /* + * This may not always work, there could be an alias between file + * sizes of different standards stored in 8bits and 10 bits. + */ + if ((bp = Bopen(file, OREAD)) == nil) + return -1; + while((s = Brdstr(bp, '\n', 1)) != nil){ + if (tokenize(s, a, nelem(a)) < 3) + continue; + if (a[0][0] == '#') + continue; + p = atoll(a[3]); + l = atoll(a[5]); + if (l*p*2 == size){ + *pixels = p; + *lines = l; + *bits = 8; + break; + } + if ((l*p*20)/8 == size){ + *pixels = p; + *lines = l; + *bits = 10; + break; + } + } + Bterm(bp); + if (s == nil) + return -1; + return 0; +} + + static int clip(int x) { @@ -41,18 +84,20 @@ return x; } - Rawimage** Breadyuv(Biobuf *bp, int colourspace) { - Dir * d; - Rawimage * a, **array; - char *e, ebuf[128]; + Dir *d; + uvlong sz; + Rawimage *a, **array; + char *e, ebuf[128]; ushort * mux, *end, *frm; - uchar buf[720 * 2], *r, *g, *b; - int y1, y2, cb, cr, sz, c, l, w, base, bits, lines; + uchar *buf, *r, *g, *b; + int y1, y2, cb, cr, c, l, w, base; + int bits, lines, pixels; - frm = 0; + frm = nil; + buf = nil; if (colourspace != CYCbCr) { errstr(ebuf, sizeof ebuf); /* throw it away */ werrstr("ReadYUV: unknown colour space %d", colourspace); @@ -71,75 +116,63 @@ sz = d->length; free(d); } else { - fprint(2, "cannot stat input, assuming 720x576x10bit\n"); - sz = 720 * PAL * 2L + (720 * PAL / 2L); + fprint(2, "cannot stat input, assuming pixelsx576x10bit\n"); + sz = pixels * r601pal * 2L + (pixels * r601pal / 2L); } - switch (sz) { - case 720 * PAL * 2: // 625 x 8bit - bits = 8; - lines = PAL; - break; - case 720 * NTSC * 2: // 525 x 8bit - bits = 8; - lines = NTSC; - break; - case 720 * PAL * 2 + (720 * PAL / 2) : // 625 x 10bit - bits = 10; - lines = PAL; - break; - case 720 * NTSC * 2 + (720 * NTSC / 2) : // 525 x 10bit - bits = 10; - lines = NTSC; - break; - default: - e = "unknown file size"; + if (looksize("/lib/video.specs", sz, &pixels, &lines, &bits) == -1){ + e = "file size not listed in /lib/video.specs"; goto Error; } - // print("bits=%d pixels=%d lines=%d\n", bits, 720, lines); - // + a->nchans = 3; a->chandesc = CRGB; - a->chanlen = 720 * lines; - a->r = Rect(0, 0, 720, lines); + a->chanlen = pixels * lines; + a->r = Rect(0, 0, pixels, lines); e = "no memory"; - if ((frm = malloc(720 * 2 * lines * sizeof(ushort))) == nil) + if ((frm = malloc(pixels*2*lines*sizeof(ushort))) == nil) goto Error; for (c = 0; c < 3; c++) - if ((a->chans[c] = malloc(720 * lines)) == nil) + if ((a->chans[c] = malloc(pixels*lines)) == nil) goto Error; + if ((buf = malloc(pixels*2)) == nil) + goto Error; + e = "read file"; for (l = 0; l < lines; l++) { - if (Bread(bp, buf, 720 * 2) == -1) + if (Bread(bp, buf, pixels *2) == -1) goto Error; - base = l * 720 * 2; - for (w = 0; w < 720 * 2; w++) + base = l*pixels*2; + for (w = 0; w < pixels *2; w++) frm[base + w] = ((ushort)buf[w]) << 2; } if (bits == 10) for (l = 0; l < lines; l++) { - if (Bread(bp, buf, 720 / 2) == -1) + if (Bread(bp, buf, pixels / 2) == -1) goto Error; - base = l * 720 * 2; - for (w = 0; w < 720 * 2; w++) + base = l * pixels * 2; + for (w = 0; w < pixels * 2; w++) frm[base + w] |= buf[w / 4] >> lsbtab[w % 4]; } mux = frm; - end = frm + 720 * lines * 2; + end = frm + pixels * lines * 2; r = a->chans[0]; g = a->chans[1]; b = a->chans[2]; + /* + * Fixme: fixed colourspace conversion at present + */ while (mux < end) { cb = *mux++ - 512; y1 = (*mux++ - 64) * 76310; @@ -155,12 +188,13 @@ *b++ = clip((132278 * cb) + y2); } free(frm); + free(buf); return array; Error: errstr(ebuf, sizeof ebuf); - if (ebuf[0] == 0) +// if (ebuf[0] == 0) strcpy(ebuf, e); errstr(ebuf, sizeof ebuf); @@ -170,6 +204,7 @@ free(array[0]); free(array); free(frm); + free(buf); return nil; } --- /lib/video.specs Thu Jan 1 00:00:00 1970 +++ /lib/video.specs Thu Dec 14 16:19:42 2006 @@ -0,0 +1,59 @@ +# Video standards +# samples per line +# lines per frame +# sample where active video starts +# number of active video samples +# first line of active video (field 1) +# number of lines of active video (field 1) +# first line of active video (field 2) +# number of lines of active video (field 2) +# sample clock frequency / 1e6 +# colourspace +# aspect ratio +# +# samp lines samp1 Nsamp F1 NF1 F2 NF2 Clock Colour Aspect +858 525 122 720 43 483 0 0 27.0 REC601 4:3 +858 525 122 720 21 243 283 243 13.5 REC601 4:3 +864 625 132 720 23 288 336 288 13.5 REC601 4:3 +864 625 132 720 23 288 336 288 12.96 REC601 16:9 +864 625 132 720 23 288 336 288 12.9470529470529 REC601 16:9 +1144 525 162 960 21 243 283 243 18.0 REC601 16:9 +1152 625 176 960 23 288 336 288 18.0 REC601 16:9 +1650 750 260 1280 26 720 0 0 74.25 SMPTE274 16:9 +1650 750 260 1280 26 720 0 0 74.1758241758242 SMPTE274 16:9 +1650 750 260 720 26 480 0 0 74.25 SMPTE274 4:3 +1650 750 260 720 26 480 0 0 74.1758241758242 SMPTE274 4:3 +1980 750 260 1280 26 720 0 0 74.25 SMPTE274 16:9 +1980 750 260 720 26 576 0 0 74.25 SMPTE274 4:3 +2200 1125 192 1920 41 517 603 518 74.25 SMPTE240 16:9 +2200 1125 192 1920 21 540 584 540 74.1758241758242 SMPTE274 16:9 +2200 1125 192 720 21 480 584 480 74.25 SMPTE274 4:3 +2200 1125 192 720 21 480 584 480 74.1758241758242 SMPTE274 4:3 +2200 1125 192 1920 21 540 584 540 74.25 SMPTE274 16:9 +2200 1125 192 1920 21 540 584 540 74.1758241758242 SMPTE274 16:9 +2200 1125 192 1920 41 517 603 518 74.1758241758242 SMPTE240 16:9 +2200 1125 192 1920 42 1080 0 0 148.5 SMPTE274 16:9 +2200 1125 192 1920 42 1080 0 0 148.351648351648 SMPTE274 16:9 +2200 1125 192 1920 42 1080 0 0 74.1758241758242 SMPTE274 16:9 +2200 1125 192 1920 42 1080 0 0 74.25 SMPTE274 16:9 +2200 1125 192 720 21 288 584 288 74.1758241758242 REC601 4:3 +2200 1125 192 1920 21 540 584 540 74.25 SMPTE274 16:9 +2304 1250 256 1920 45 576 670 576 72.0 REC709 16:9 +2376 1250 309 1920 161 1080 0 0 148.5 SMPTE274 16:9 +2376 1250 309 1920 81 540 706 540 74.25 SMPTE274 16:9 +2640 1125 192 1920 21 540 584 540 74.25 SMPTE274 16:9 +2640 1125 192 1920 42 1080 0 0 148.5 SMPTE274 16:9 +2640 1125 192 1920 21 540 584 540 74.25 SMPTE274 16:9 +2640 1125 192 1920 42 1080 0 0 74.25 SMPTE274 16:9 +2640 1125 192 720 21 288 584 288 74.25 REC601 4:3 +2750 1125 192 1920 42 1080 0 0 74.1758241758242 SMPTE274 16:9 +2750 1125 192 1920 21 540 584 540 74.25 SMPTE274 16:9 +2750 1125 192 1920 42 1080 0 0 74.25 SMPTE274 16:9 +2750 1125 192 720 21 288 584 288 74.25 REC601 16:9 +2750 1125 192 1920 21 540 584 540 74.1758241758242 SMPTE274 16:9 +2750 1125 192 720 21 288 584 288 74.1758241758242 REC601 16:9 +3300 750 260 1280 26 720 0 0 74.25 SMPTE274 16:9 +3300 750 260 1280 26 720 0 0 74.1758241758242 SMPTE274 16:9 +3960 750 260 1280 26 720 0 0 74.25 SMPTE274 16:9 +4125 750 260 1280 26 720 0 0 74.1758241758242 SMPTE274 16:9 +4125 750 260 1280 26 720 0 0 74.25 SMPTE274 16:9