X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fdb%2Futils%2Fdbtv.C;fp=cinelerra-5.1%2Fdb%2Futils%2Fdbtv.C;h=9f820fbdded9dc8dd1cc64d5471d4cde4fb8c1c2;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/db/utils/dbtv.C b/cinelerra-5.1/db/utils/dbtv.C new file mode 100644 index 00000000..9f820fbd --- /dev/null +++ b/cinelerra-5.1/db/utils/dbtv.C @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s.C" + +#define WIDTH 640 +#define HEIGHT 480 + +#define SWIDTH 80 +#define SHEIGHT 45 + +double the_time() +{ + struct timeval tv; + gettimeofday(&tv,NULL); + return tv.tv_sec + tv.tv_usec/1000000.0; +} + +void loadImage(int x, int y, XImage *image, unsigned char *cp, int width, int height) +{ + int i, j, k, b0, bi, npixel, nline; + unsigned long rmask, gmask, bmask; + double rshft, gshft, bshft; + unsigned char r, g, b, *bp, *dp, *data; + unsigned long pix, pixel; + + npixel = image->bits_per_pixel / 8; + /* A, R, G, B or A, B, G, R */ + if( image->byte_order != MSBFirst ) { + bi = 1; b0 = 0; + } + else { + bi = -1; b0 = npixel-1; + } + + rmask = image->red_mask; rshft = rmask/255.0; + gmask = image->green_mask; gshft = gmask/255.0; + bmask = image->blue_mask; bshft = bmask/255.0; + nline = image->bytes_per_line; + data = (unsigned char *)image->data + y*nline + x*npixel; + + for( k=0; k0; pix>>=8 ) { + *bp = pix; bp += bi; + } + dp += npixel; ++cp; + } + data += nline; + } + +} + +int done = -1; +theDb db; + +static void +clientMsg(Display *dpy,Window w,Atom amsg,int fmt) +{ + XClientMessageEvent ev; + memset(&ev,0,sizeof(ev)); + ev.type = ClientMessage; + ev.window = w; + ev.message_type = amsg; + ev.format = fmt; + XSendEvent(dpy,w,False,0,(XEvent *)&ev); +} + +static void +scale0(uint8_t *idata,int iw,int ih,uint8_t *odata,int ow,int oh) +{ + int i, dx, dy; + double iw1 = iw-1; + double ow1 = ow-1; + + int idx[ow]; + for( dx=0; dx=0; *odata++ = bp[i]); + } + } +} + +#if 0 +static void +scale1(uint8_t *idata,int iw,int ih,int rx,int ry,int rw,int rh, + uint8_t *odata,int ow,int oh,int sx,int sy,int sw,int sh) +{ + //if( rw < 3 || rh < 3 || sw < 3 || sh < 3 ) return; + int i, dx, dy; int ibpp = 1, obpp = 1; + int rsz = ibpp * iw, ssz = obpp * ow; + double iw2 = rw-2, ih2 = rh-2; + double ow1 = iw2/(sw-1), oh1 = ih2/(sh-1); + odata += sy*ssz + 4*sx; + + for( dy=0; dy=0; ++cp00, ++cp01, ++cp10, ++cp11 ) + bp[i] = *cp00*a00 + *cp01*a01 + *cp10*a10 + *cp11*a11 + 0.5; + bp += obpp; + } + } +} + + +static void +scale2(uint8_t *idata,int iw,int ih,int rx,int ry,int rw,int rh, + uint8_t *odata,int ow,int oh,int sx,int sy,int sw,int sh) +{ + if( rw < 3 || rh < 3 || sw < 3 || sh < 3 ) return; + const int ibpp=1, obpp=1; + int x, y, dx, dy; + int rsz = ibpp*iw, ssz = obpp*ow; + double rw0=rw, rh0=rh; + double ow0=sw, oh0=sh; + double px = rw0/ow0, py = rh0/oh0; + double pz = (ow0*oh0)/(rw0*rh0); + double ly = 0.0; + odata += sy*ssz + obpp*sx; + + for( dy=1; dy<=sh; ++dy,odata+=ssz ) { + int iy0 = (int)ly; + double yf0 = ly - iy0; + double ny = dy*py + 1e-99; + int iy1 = (int)ny; + double yf1 = ny - iy1; + uint8_t *bp = odata; + double lx = 0.0; + + for( dx=1; dx<=sw; ++dx ) { + int ix0 = (int)lx; + double xf0 = lx - ix0; + double nx = dx*px + 1e-99; + int ix1 = (int)nx; + double xf1 = nx - ix1; + double r=0.0; + for( y=iy0; y<=iy1; ++y ) { + int idy = rsz * (y + ry); + uint8_t *row = &idata[idy]; + double yw = pz; + if( y == iy0 ) yw *= (y==iy1 ? yf1-yf0 : 1.0-yf0); + else if( y == iy1 ) yw *= yf1; + if( yw <= 0.0 ) continue; + for( x=ix0; x<=ix1; ++x ) { + double xyw = yw; + if( x == ix0 ) xyw *= (x==ix1 ? xf1-xf0 : 1.0-xf0); + else if( x == ix1 ) xyw *= xf1; + if( xyw <= 0.0 ) continue; + int idx = ibpp*(x + rx); + uint8_t *cp = &row[idx]; + r += cp[0]*xyw; + } + } + *bp++ = r + 0.5; + xf0 = xf1; + lx = nx; + } + yf0 = yf1; + ly = ny; + } +} + +void write_pbm(uint8_t *tp, int w, int h, const char *fmt, ...) +{ + va_list ap; va_start(ap, fmt); + char fn[256]; vsnprintf(fn, sizeof(fn), fmt, ap); + va_end(ap); + FILE *fp = !strcmp(fn,"-") ? stdout : fopen(fn,"w"); + if( fp ) { + fprintf(fp,"P5\n%d %d\n255\n",w,h); + fwrite(tp,w,h,fp); + fclose(fp); + } +} + +#endif + +int main(int ac,char **av) +{ + Window w, root; + Display *display; + GC gc; + XGCValues gcv; + XEvent xev; + XImage *image; + Visual *visual; + Screen *screen; + Atom aMsg; + char *pixels; + int n, depth, depthfactor; + int client_msg; + + setbuf(stdout,NULL); + if( db.open(av[1]) ) { + fprintf(stderr,"cant open db: %s\n",av[1]); + exit(1); + } + int clip_id = atoi(av[2]); + if( db.clip_set.FindId(clip_id) ) { + printf("cant open clip %d\n",clip_id); + exit(1); + } + double framerate = db.clip_set.Framerate(); + int ret = TimelineLoc::ikey_Sequences(db.timeline,clip_id,0).Locate(); + if( ret || clip_id != (int)db.timeline.Clip_id() ) { + printf("cant access timeline of clip %d\n",clip_id); + exit(1); + } + int frame_no = 0, frame_id = -1; + uint8_t *dat = 0; + + display = XOpenDisplay(NULL); + if( display == NULL ) { + fprintf(stderr,"cant open display\n"); + exit(1); + } + + root = RootWindow(display,0); + screen = DefaultScreenOfDisplay(display); + depth = DefaultDepthOfScreen(screen); + visual = DefaultVisualOfScreen(screen); + client_msg = 0; + + switch( visual->c_class ) { + case TrueColor: + depthfactor = 4; + break; + default: + fprintf(stderr,"bad visual class %d\n",visual->c_class); + exit(1); + } + + w = XCreateSimpleWindow(display, root, 0, 0, WIDTH, HEIGHT, + 0, 0, WhitePixelOfScreen(screen)); + + pixels = (char *) malloc(HEIGHT*WIDTH*depthfactor); + image = XCreateImage( display, visual, depth, ZPixmap, 0, + pixels, WIDTH, HEIGHT, 8, WIDTH*depthfactor); + + XSelectInput(display, w, ExposureMask|StructureNotifyMask|ButtonPressMask); + XMapWindow(display, w); + XFlush(display); + aMsg = XInternAtom(display,"dbtv",False); + gcv.function = GXcopy; + gcv.foreground = BlackPixelOfScreen(DefaultScreenOfDisplay(display)); + gcv.line_width = 1; + gcv.line_style = LineSolid; + n = GCFunction|GCForeground|GCLineWidth|GCLineStyle; + gc = XCreateGC(display,w,n,&gcv); + double start_time = the_time(); + + while( done < 0 ) { + XNextEvent(display,&xev); + /* printf("xev.type = %d/%08x\n",xev.type,xev.xany.window); */ + switch( xev.type ) { + case ButtonPress: + if( xev.xbutton.window != w ) continue; + if( xev.xbutton.button != Button1 ) { + done = 1; + break; + } + done = 0; + break; + + case Expose: + if( client_msg != 0 ) break; + client_msg = 1; /* fall through */ + start_time = the_time(); + + case ClientMessage: + frame_id = db.timeline.Frame_id(); + if( db.video_frame.FindId(frame_id) ) { + printf("cant access frame %d (id %d) in clip %d\n", + frame_no, frame_id, clip_id); done = 1; break; + } + dat = db.video_frame._Frame_data(); + //write_pbm(dat, SWIDTH,SHEIGHT, "%s/f%05d.pbm",av[2], fid); + uint8_t img[WIDTH*HEIGHT]; + scale0(dat,SWIDTH,SHEIGHT, img,WIDTH,HEIGHT); +// scale1(dat, SWIDTH,SHEIGHT, 0,0,SWIDTH,SHEIGHT, +// img, WIDTH, HEIGHT, 0,0,WIDTH, HEIGHT); + loadImage(0,0, image, img, WIDTH, HEIGHT); + while( (int)(1000 * (frame_no/framerate - (the_time()-start_time))) > 0 ) { + usleep(1000); + } + ++frame_no; + XPutImage( display, w, gc, image, 0, 0, 0, 0, WIDTH, HEIGHT); + XFlush(display); + ret = TimelineLoc::rkey_Sequences(db.timeline).Next(); + if( ret || clip_id != (int)db.timeline.Clip_id() ) { done = 1; break; } + clientMsg(display,w,aMsg,32); + break; + + case DestroyNotify: + done = 0; + break; + } + } + + XCloseDisplay(display); + return done; +} +