Commit 4030154e authored by Simon Morlat's avatar Simon Morlat
Browse files

implement glx window_id setting

make self-view really disappear when requested instead of showing last frame frozen forever.
parent bb912b0d
......@@ -230,13 +230,16 @@ static void ogl_display_set_yuv(struct opengles_display* gldisp, mblk_t *yuv, en
return;
}
ms_mutex_lock(&gldisp->yuv_mutex);
if (gldisp->yuv[type])
if (gldisp->yuv[type]){
freemsg(gldisp->yuv[type]);
gldisp->yuv[type] = dupmsg(yuv);
for(j = 0; j < TEXTURE_BUFFER_SIZE; ++j) {
gldisp->new_yuv_image[j][type] = TRUE;
gldisp->yuv[type]=NULL;
}
if (yuv){
gldisp->yuv[type] = dupmsg(yuv);
for(j = 0; j < TEXTURE_BUFFER_SIZE; ++j) {
gldisp->new_yuv_image[j][type] = TRUE;
}
}
ms_mutex_unlock(&gldisp->yuv_mutex);
}
......
......@@ -46,8 +46,10 @@ typedef struct GLXVideo
MSVideoSize wsize; /*wished window size */
Display *display;
Window window_id;
Window subwindow;
GLXContext glContext;
struct opengles_display *glhelper;
int corner;
bool_t show;
bool_t own_window;
bool_t ready;
......@@ -75,7 +77,7 @@ static void glxvideo_init(MSFilter *f){
def_size.width=MS_VIDEO_SIZE_CIF_W;
def_size.height=MS_VIDEO_SIZE_CIF_H;
obj->display=init_display();
obj->own_window=FALSE;
obj->own_window=TRUE;
obj->ready=FALSE;
obj->vsize=def_size; /* the size of the main video*/
obj->wsize=def_size; /* the size of the window*/
......@@ -89,12 +91,17 @@ static void glxvideo_uninit(MSFilter *f){
GLXVideo *obj=(GLXVideo*)f->data;
glxvideo_unprepare(f);
if (obj->glContext) {
glXDestroyContext(obj->display, obj->glContext);
obj->glContext = NULL;
}
if (obj->own_window){
if (obj->glContext) {
glXDestroyContext(obj->display, obj->glContext);
obj->glContext = NULL;
}
XDestroyWindow(obj->display,obj->window_id);
if (obj->window_id)
XDestroyWindow(obj->display,obj->window_id);
}else{
if (obj->subwindow)
XDestroyWindow(obj->display,obj->subwindow);
}
if (obj->display){
XCloseDisplay(obj->display);
......@@ -105,29 +112,30 @@ static void glxvideo_uninit(MSFilter *f){
static void glxvideo_prepare(MSFilter *f){
GLXVideo *s=(GLXVideo*)f->data;
Window window=s->window_id;
XWindowAttributes wa;
if (s->display==NULL) return;
if (s->window_id==0){
if (createX11GLWindow(s->display, s->wsize, &s->glContext, &s->window_id)) {
GLenum err;
s->glhelper = ogl_display_new();
glXMakeCurrent( s->display, s->window_id, s->glContext );
err = glewInit();
if (err != GLEW_OK) {
ms_error("Failed to initialize GLEW");
return;
} else if (!GLEW_VERSION_2_0) {
ms_error("Need OpenGL 2.0+");
return;
} else {
ogl_display_init(s->glhelper, s->wsize.width, s->wsize.height);
}
if (s->window_id==(unsigned long)-1) return;
if (createX11GLWindow(s->display, s->wsize, &s->glContext, &window)) {
GLenum err;
s->subwindow=window;
s->glhelper = ogl_display_new();
glXMakeCurrent( s->display, s->subwindow, s->glContext );
err = glewInit();
if (err != GLEW_OK) {
ms_error("Failed to initialize GLEW");
return;
} else if (!GLEW_VERSION_2_0) {
ms_error("Need OpenGL 2.0+");
return;
} else {
ogl_display_init(s->glhelper, s->wsize.width, s->wsize.height);
}
if (s->window_id==0) return;
s->own_window=TRUE;
}else if (s->own_window==FALSE){
}
if (s->window_id==0) return;
if (s->own_window==FALSE){
/*we need to register for resize events*/
XSelectInput(s->display,s->window_id,StructureNotifyMask);
}
......@@ -163,17 +171,23 @@ static void glxvideo_process(MSFilter *f){
mblk_t *inm;
MSPicture src={0};
bool_t precious=FALSE;
XWindowAttributes wa;
ms_filter_lock(f);
if (obj->window_id==0 || obj->window_id==(Window)-1) goto end;
XGetWindowAttributes(obj->display,obj->window_id,&wa);
if (wa.width!=obj->wsize.width || wa.height!=obj->wsize.height){
ms_warning("Resized to %ix%i", wa.width,wa.height);
obj->wsize.width=wa.width;
obj->wsize.height=wa.height;
ogl_display_init(obj->glhelper, wa.width, wa.height);
if (obj->subwindow!=obj->window_id){
XResizeWindow(obj->display,obj->subwindow, wa.width,wa.height);
}
}
ms_filter_lock(f);
if (!obj->show) {
goto end;
}
......@@ -182,7 +196,7 @@ static void glxvideo_process(MSFilter *f){
goto end;
}
glXMakeCurrent( obj->display, obj->window_id, obj->glContext );
glXMakeCurrent( obj->display, obj->subwindow, obj->glContext );
if (f->inputs[0]!=NULL && (inm=ms_queue_peek_last(f->inputs[0]))!=0) {
if (ms_yuv_buf_init_from_mblk(&src,inm)==0){
MSVideoSize newsize;
......@@ -214,13 +228,15 @@ static void glxvideo_process(MSFilter *f){
}
}
if (f->inputs[1]!=NULL && (inm=ms_queue_peek_last(f->inputs[1]))!=0) {
if (ms_yuv_buf_init_from_mblk(&src,inm)==0){
if (!mblk_get_precious_flag(inm)) ms_yuv_buf_mirror(&src);
ogl_display_set_preview_yuv_to_display(obj->glhelper, inm);
}
if (obj->corner!=-1){
if (ms_yuv_buf_init_from_mblk(&src,inm)==0){
if (!mblk_get_precious_flag(inm)) ms_yuv_buf_mirror(&src);
ogl_display_set_preview_yuv_to_display(obj->glhelper, inm);
}
}else ogl_display_set_preview_yuv_to_display(obj->glhelper,NULL);
}
ogl_display_render(obj->glhelper, 0);
glXSwapBuffers ( obj->display, obj->window_id );
glXSwapBuffers ( obj->display, obj->subwindow );
end:
ms_filter_unlock(f);
......@@ -269,7 +285,26 @@ static int glxvideo_get_native_window_id(MSFilter *f, void*arg){
}
static int glxvideo_set_native_window_id(MSFilter *f, void*arg){
ms_error("MSGLXVideo: cannot change native window");
GLXVideo *s=(GLXVideo*)f->data;
unsigned long id=*(unsigned long*)arg;
ms_filter_lock(f);
if (s->window_id!=id) {
if (s->display && s->subwindow!=0 && s->subwindow!=s->window_id){
/*if the parent window is unset, and using a subwindow, destroy the subwindow*/
XDestroyWindow(s->display, s->subwindow);
XSync(s->display,FALSE);/*required to force immediate removal of the subwindow from its parent.
Otherwise, if the parent is destroyed by a mouse click, it will automatically destroy child window and there will be a
double destroy of the subwindow resulting in "bad match" x error.*/
ms_message("Subwindow destroyed");
s->subwindow=0;
}
glxvideo_unprepare(f);
}
s->window_id=id;
s->own_window=FALSE;
ms_filter_unlock(f);
return 0;
}
......@@ -343,29 +378,44 @@ static bool_t createX11GLWindow(Display* display, MSVideoSize size, GLXContext*
ms_message( "Chosen visual ID = 0x%lu", vi->visualid );
ms_message( "Creating colormap" );
swa.colormap = cmap = XCreateColormap( display,
RootWindow( display, vi->screen ),
vi->visual, AllocNone );
cmap = XCreateColormap( display,
RootWindow( display, vi->screen ),
vi->visual, AllocNone );
swa.colormap = cmap;
swa.background_pixmap = None ;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
ms_message( "Creating window" );
*win = XCreateWindow( display, RootWindow( display, vi->screen ),
200, 200, size.width, size.height, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa );
if ( !(*win) ) {
ms_error( "Failed to create window." );
return FALSE;
if (*win==0){
ms_message( "Creating window" );
*win = XCreateWindow( display, RootWindow( display, vi->screen ),
200, 200, size.width, size.height, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa );
if ( !(*win) ) {
ms_error( "Failed to create window." );
return FALSE;
}
XStoreName( display, *win, "Video" );
ms_message( "Mapping window" );
XMapWindow( display, *win );
}else{
ms_message( "Creating sub window" );
*win = XCreateWindow( display, *win,
0, 0, size.width, size.height, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa );
if ( !(*win) ) {
ms_error( "Failed to create sub window." );
return FALSE;
}
ms_message( "Mapping window subwindow" );
XClearWindow(display, *win);
XMapWindow( display, *win );
}
// Done with the visual info data
XFree( vi );
XStoreName( display, *win, "Video" );
ms_message( "Mapping window" );
XMapWindow( display, *win );
// Get the default screen's GLX extension list
*ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
......@@ -392,6 +442,12 @@ static int glxvideo_enable_autofit(MSFilter *f,void *arg){
return 0;
}
static int glxvideo_set_local_view_mode(MSFilter *f, void *arg){
GLXVideo *s=(GLXVideo*)f->data;
s->corner=*(int*)arg;
return 0;
}
static MSFilterMethod methods[]={
{ MS_FILTER_SET_VIDEO_SIZE , glxvideo_set_vsize },
{ MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID , glxvideo_get_native_window_id },
......@@ -400,6 +456,7 @@ static MSFilterMethod methods[]={
{ MS_VIDEO_DISPLAY_ZOOM , glxvideo_zoom },
{ MS_VIDEO_DISPLAY_ENABLE_MIRRORING , glxvideo_enable_mirroring},
{ MS_VIDEO_DISPLAY_ENABLE_AUTOFIT , glxvideo_enable_autofit },
{ MS_VIDEO_DISPLAY_SET_LOCAL_VIEW_MODE , glxvideo_set_local_view_mode},
{ 0 ,NULL}
};
......
......@@ -373,7 +373,7 @@ static void osx_gl_process(MSFilter* f) {
}
}
}
}
}else ogl_display_set_preview_yuv_to_display(thiz.glLayer->display_helper,NULL);
ms_queue_flush(f->inputs[1]);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment