[Redbutton-devel] SF.net SVN: redbutton: [56] redbutton-browser/trunk
Brought to you by:
skilvington
|
From: <ski...@us...> - 2006-05-14 09:56:38
|
Revision: 56 Author: skilvington Date: 2006-05-14 02:56:06 -0700 (Sun, 14 May 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=56&view=rev Log Message: ----------- enable video display (too slow to be practical yet) Modified Paths: -------------- redbutton-browser/trunk/MHEGDisplay.c redbutton-browser/trunk/MHEGDisplay.h redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h redbutton-browser/trunk/StreamComponent.c redbutton-browser/trunk/TODO redbutton-browser/trunk/VideoClass.c redbutton-browser/trunk/VideoClass.h redbutton-browser/trunk/add_instance_vars.conf Modified: redbutton-browser/trunk/MHEGDisplay.c =================================================================== --- redbutton-browser/trunk/MHEGDisplay.c 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/MHEGDisplay.c 2006-05-14 09:56:06 UTC (rev 56) @@ -80,6 +80,7 @@ XGCValues gcvals; XRenderPictFormat *pic_format; XRenderPictureAttributes pa; + Pixmap overlay; Pixmap textfg; /* fake argc, argv for XtDisplayInitialize */ int argc = 0; @@ -216,13 +217,21 @@ wm_delete_window = XInternAtom(d->dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(d->dpy, d->win, &wm_delete_window, 1); - /* create an XRender Picture to do the drawing on */ + /* + * create an XRender Picture for the Window contents + * we composite the video frame and the MHEG overlay onto this, then copy it onto the Window + */ + pic_format = XRenderFindVisualFormat(d->dpy, d->vis); d->contents = XCreatePixmap(d->dpy, d->win, d->xres, d->yres, d->depth); - pic_format = XRenderFindVisualFormat(d->dpy, d->vis); d->contents_pic = XRenderCreatePicture(d->dpy, d->contents, pic_format, 0, NULL); + /* create a 32-bit XRender Picture to draw the MHEG objects on */ + pic_format = XRenderFindStandardFormat(d->dpy, PictStandardARGB32); + overlay = XCreatePixmap(d->dpy, d->win, d->xres, d->yres, 32); + d->overlay_pic = XRenderCreatePicture(d->dpy, overlay, pic_format, 0, NULL); + /* a 1x1 Picture to hold the text foreground colour */ - textfg = XCreatePixmap(d->dpy, d->win, 1, 1, d->depth); + textfg = XCreatePixmap(d->dpy, d->win, 1, 1, 32); pa.repeat = True; d->textfg_pic = XRenderCreatePicture(d->dpy, textfg, pic_format, CPRepeat, &pa); @@ -360,6 +369,14 @@ w = (box->x_length * d->xres) / MHEG_XRES; h = (box->y_length * d->yres) / MHEG_YRES; + /* + * if video is being displayed, the current frame will already be in d->contents + * (drawn by the video thread or VideoClass_render) + * overlay the MHEG objects onto the video in d->contents + */ + XRenderComposite(d->dpy, PictOpOver, d->overlay_pic, None, d->contents_pic, x, y, x, y, x, y, w, h); + + /* copy the Window contents onto the screen */ XCopyArea(d->dpy, d->contents, d->win, d->win_gc, x, y, w, h, x, y); return; @@ -397,7 +414,7 @@ printf("TODO: LineStyle %d\n", style); /* draw a rectangle */ - XRenderFillRectangle(d->dpy, PictOpOver, d->contents_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpOver, d->overlay_pic, &rcol, x, y, w, h); return; } @@ -434,7 +451,7 @@ printf("TODO: LineStyle %d\n", style); /* draw a rectangle */ - XRenderFillRectangle(d->dpy, PictOpOver, d->contents_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpOver, d->overlay_pic, &rcol, x, y, w, h); return; } @@ -463,12 +480,36 @@ w = (box->x_length * d->xres) / MHEG_XRES; h = (box->y_length * d->yres) / MHEG_YRES; - XRenderFillRectangle(d->dpy, PictOpOver, d->contents_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpOver, d->overlay_pic, &rcol, x, y, w, h); return; } /* + * explicitly make a transparent rectangle in the MHEG overlay + * MHEGDisplay_fillRectangle() uses PictOpOver => it can't create a transparent box in the output + * this uses PictOpSrc + */ + +void +MHEGDisplay_fillTransparentRectangle(MHEGDisplay *d, XYPosition *pos, OriginalBoxSize *box) +{ + XRenderColor rcol = {0, 0, 0, 0}; + int x, y; + unsigned int w, h; + + /* scale if fullscreen */ + x = (pos->x_position * d->xres) / MHEG_XRES; + y = (pos->y_position * d->yres) / MHEG_YRES; + w = (box->x_length * d->xres) / MHEG_XRES; + h = (box->y_length * d->yres) / MHEG_YRES; + + XRenderFillRectangle(d->dpy, PictOpSrc, d->overlay_pic, &rcol, x, y, w, h); + + return; +} + +/* * coords should be in the range 0-MHEG_XRES, 0-MHEG_YRES */ @@ -494,7 +535,7 @@ dst_x = (dst->x_position * d->xres) / MHEG_XRES; dst_y = (dst->y_position * d->yres) / MHEG_YRES; - XRenderComposite(d->dpy, PictOpOver, bitmap->image_pic, None, d->contents_pic, + XRenderComposite(d->dpy, PictOpOver, bitmap->image_pic, None, d->overlay_pic, src_x, src_y, src_x, src_y, dst_x, dst_y, w, h); @@ -594,7 +635,7 @@ /* round up/down the X coord */ scrn_x = (x * d->xres) / MHEG_XRES; scrn_x = (scrn_x + (face->units_per_EM / 2)) / face->units_per_EM; - XftGlyphRender(d->dpy, PictOpOver, d->textfg_pic, font->font, d->contents_pic, + XftGlyphRender(d->dpy, PictOpOver, d->textfg_pic, font->font, d->overlay_pic, 0, 0, orig_x + scrn_x, y, &glyph, 1); face = XftLockFace(font->font); Modified: redbutton-browser/trunk/MHEGDisplay.h =================================================================== --- redbutton-browser/trunk/MHEGDisplay.h 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/MHEGDisplay.h 2006-05-14 09:56:06 UTC (rev 56) @@ -46,7 +46,8 @@ Visual *vis; /* Visual (ie pixel format) used by the Window */ Colormap cmap; /* None, unless we needed to create a Colormap for our Visual */ Pixmap contents; /* current contents of the Window */ - Picture contents_pic; /* XRender wrapper for the contents, this is what we draw on */ + Picture contents_pic; /* XRender wrapper for the contents, this is what we composite on */ + Picture overlay_pic; /* draw MHEG objects on here and overlay it on any video */ Picture textfg_pic; /* 1x1 solid foreground colour for text */ MHEGKeyMapEntry *keymap; /* keyboard mapping */ } MHEGDisplay; @@ -61,6 +62,7 @@ /* drawing routines */ void MHEGDisplay_drawHoriLine(MHEGDisplay *, XYPosition *, unsigned int, int, int, MHEGColour *); void MHEGDisplay_drawVertLine(MHEGDisplay *, XYPosition *, unsigned int, int, int, MHEGColour *); +void MHEGDisplay_fillTransparentRectangle(MHEGDisplay *, XYPosition *, OriginalBoxSize *); void MHEGDisplay_fillRectangle(MHEGDisplay *, XYPosition *, OriginalBoxSize *, MHEGColour *); void MHEGDisplay_drawBitmap(MHEGDisplay *, XYPosition *, OriginalBoxSize *, MHEGBitmap *, XYPosition *); void MHEGDisplay_drawTextElement(MHEGDisplay *, XYPosition *, MHEGFont *, MHEGTextElement *, bool); Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-05-14 09:56:06 UTC (rev 56) @@ -73,6 +73,7 @@ p->videoq = NULL; pthread_mutex_init(&p->current_frame_lock, NULL); + p->current_frame = NULL; return; } @@ -316,6 +317,9 @@ uint8_t *tmpbuf_data = NULL; unsigned int nframes = 0; + if(!p->have_video) + return NULL; + verbose("MHEGStreamPlayer: video thread started"); /* assert */ @@ -454,8 +458,6 @@ pthread_mutex_lock(&p->current_frame_lock); /* convert the next frame to RGB */ img_convert(&rgb_frame, out_format, yuv_frame, vf->pix_fmt, out_width, out_height); -/* TODO */ -/* overlay any MHEG objects above it */ /* we've finished changing the RGB frame now */ pthread_mutex_unlock(&p->current_frame_lock); /* wait until it's time to display the frame */ @@ -480,11 +482,10 @@ last_pts = vf->pts; //now=av_gettime(); //printf("display frame %d: pts=%f this_time=%lld real_time=%lld (diff=%lld)\n", ++nframes, vf->pts, last_time, now, now-last_time); -/* TODO */ -/* take p->video size/position into account */ -/* redraw objects above the video */ -// disable output until we can overlay the MHEG objects -// XShmPutImage(d->dpy, d->win, d->win_gc, p->current_frame, 0, 0, 0, 0, out_width, out_height, False); + /* draw the current frame */ + MHEGStreamPlayer_drawCurrentFrame(p); + /* redraw objects above the video */ + MHEGDisplay_refresh(d, &p->video->inst.Position, &p->video->inst.BoxSize); /* get it drawn straight away */ XFlush(d->dpy); } @@ -500,9 +501,14 @@ safe_free(tmpbuf_data); } + /* get rid of the current frame */ + pthread_mutex_lock(&p->current_frame_lock); /* the XImage data is our shared memory, make sure XDestroyImage doesn't try to free it */ p->current_frame->data = NULL; XDestroyImage(p->current_frame); + /* make sure no-one tries to use it */ + p->current_frame = NULL; + pthread_mutex_unlock(&p->current_frame_lock); XShmDetach(d->dpy, &shm); shmdt(shm.shmaddr); @@ -513,6 +519,34 @@ return NULL; } +void +MHEGStreamPlayer_drawCurrentFrame(MHEGStreamPlayer *p) +{ + MHEGDisplay *d = MHEGEngine_getDisplay(); + int x, y; + unsigned int out_width; + unsigned int out_height; + + pthread_mutex_lock(&p->current_frame_lock); + if(p->current_frame != NULL) + { +/* TODO */ +/* take p->video size/position into account */ +/* remeber fullscreen scaling */ + x = 0; /* origin of p->video */ + y = 0; + out_width = p->current_frame->width; + out_height = p->current_frame->height; + /* draw it onto the Window contents Pixmap */ + XShmPutImage(d->dpy, d->contents, d->win_gc, p->current_frame, 0, 0, x, y, out_width, out_height, False); + /* get it drawn straight away */ + XFlush(d->dpy); + } + pthread_mutex_unlock(&p->current_frame_lock); + + return; +} + /* * usleep(usecs) * need to make sure the other threads get a go while we are sleeping Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-05-14 09:56:06 UTC (rev 56) @@ -33,7 +33,7 @@ void free_VideoFrameListItem(LIST_TYPE(VideoFrame) *); /* player state */ -typedef struct +typedef struct MHEGStreamPlayer { bool playing; /* true when our threads are active */ bool stop; /* true => stop playback */ @@ -64,4 +64,6 @@ void MHEGStreamPlayer_play(MHEGStreamPlayer *); void MHEGStreamPlayer_stop(MHEGStreamPlayer *); +void MHEGStreamPlayer_drawCurrentFrame(MHEGStreamPlayer *); + #endif /* __MHEGSTREAMPLAYER_H__ */ Modified: redbutton-browser/trunk/StreamComponent.c =================================================================== --- redbutton-browser/trunk/StreamComponent.c 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/StreamComponent.c 2006-05-14 09:56:06 UTC (rev 56) @@ -109,6 +109,7 @@ break; case StreamComponent_video: + VideoClass_setStreamPlayer(&s->u.video, player); MHEGStreamPlayer_setVideoTag(player, &s->u.video, s->u.video.component_tag); break; @@ -127,6 +128,24 @@ void StreamComponent_stop(StreamComponent *s, MHEGStreamPlayer *player) { + switch(s->choice) + { + case StreamComponent_audio: + break; + + case StreamComponent_video: + VideoClass_setStreamPlayer(&s->u.video, NULL); + break; + + case StreamComponent_rtgraphics: + error("RTGraphics streams not supported"); + break; + + default: + error("Unknown StreamComponent type: %d", s->choice); + break; + } + return; } Modified: redbutton-browser/trunk/TODO =================================================================== --- redbutton-browser/trunk/TODO 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/TODO 2006-05-14 09:56:06 UTC (rev 56) @@ -1,3 +1,10 @@ +check if default audio/video PID is 0 in rb-download +if it is, avstream fails + + +print avstream error message in rb-browser if openStream fails + + use -t timeout when searching for initial object to boot Modified: redbutton-browser/trunk/VideoClass.c =================================================================== --- redbutton-browser/trunk/VideoClass.c 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/VideoClass.c 2006-05-14 09:56:06 UTC (rev 56) @@ -354,6 +354,14 @@ } void +VideoClass_setStreamPlayer(VideoClass *t, MHEGStreamPlayer *p) +{ + t->inst.player = p; + + return; +} + +void VideoClass_render(VideoClass *t, MHEGDisplay *d, XYPosition *pos, OriginalBoxSize *box) { XYPosition ins_pos; @@ -364,14 +372,13 @@ if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; -/* TODO */ -//printf("TODO: VideoClass_render; component_tag=%d\n", t->component_tag); -/* so we can see where it is for now */ -{ -MHEGColour col = { 0, 255, 0, 0 }; -MHEGDisplay_fillRectangle(d, &ins_pos, &ins_box, &col); -} + /* draw the video frame onto the Window contents Pixmap */ + if(t->inst.player != NULL) + MHEGStreamPlayer_drawCurrentFrame(t->inst.player); + /* make a transparent hole in the MHEG overlay so we can see the video below it */ + MHEGDisplay_fillTransparentRectangle(d, &ins_pos, &ins_box); + return; } Modified: redbutton-browser/trunk/VideoClass.h =================================================================== --- redbutton-browser/trunk/VideoClass.h 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/VideoClass.h 2006-05-14 09:56:06 UTC (rev 56) @@ -25,6 +25,7 @@ void VideoClass_GetVideoDecodeOffset(VideoClass *, GetVideoDecodeOffset *, OctetString *); void VideoClass_ScaleVideo(VideoClass *, ScaleVideo *, OctetString *); +void VideoClass_setStreamPlayer(VideoClass *, MHEGStreamPlayer *); void VideoClass_render(VideoClass *, MHEGDisplay *, XYPosition *, OriginalBoxSize *); #endif /* __VIDEOCLASS_H__ */ Modified: redbutton-browser/trunk/add_instance_vars.conf =================================================================== --- redbutton-browser/trunk/add_instance_vars.conf 2006-05-12 12:46:29 UTC (rev 55) +++ redbutton-browser/trunk/add_instance_vars.conf 2006-05-14 09:56:06 UTC (rev 56) @@ -175,6 +175,8 @@ /* VideoClass */ /* UK MHEG Profile adds this */ XYPosition VideoDecodeOffset; + /* we add this */ + struct MHEGStreamPlayer *player; } VideoClassInstanceVars; </VideoClass> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |