📄 video_output_x11.c
字号:
default: break; } } if(cursor_visible == True) { clocktime_get(&cur_time); timesub(&cur_time, &cur_time, &prev_time); if(TIME_S(cur_time) >= 2) { hide_cursor(mydisplay, window.win); cursor_visible = False; } }}void display(yuv_image_t *current_image){ static int sar_frac_n, sar_frac_d; if(aspect_mode == AspectModeSrcMPEG) { /* New source aspect ratio? */ if(current_image->info->picture.sar_frac_n != sar_frac_n || current_image->info->picture.sar_frac_d != sar_frac_d) { sar_frac_n = current_image->info->picture.sar_frac_n; sar_frac_d = current_image->info->picture.sar_frac_d; display_adjust_size(current_image, -1, -1); //TODO move this XClearArea(mydisplay, window.win, 0, 0, window.window_area.width, window.window_area.height, False); } } if(aspect_mode == AspectModeSrcVM) { /* New VM aspect ratio? */ if(aspect_new_frac_n != sar_frac_n || aspect_new_frac_d != sar_frac_d) { sar_frac_n = aspect_new_frac_n; sar_frac_d = aspect_new_frac_d; display_adjust_size(current_image, -1, -1); //TODO move this XClearArea(mydisplay, window.win, 0, 0, window.window_area.width, window.window_area.height, False); } } if((new_view_area.x != src_view_area.x || new_view_area.y != src_view_area.y || new_view_area.width != src_view_area.width || new_view_area.height != src_view_area.height) && view_area_mode != 2) { display_adjust_size(current_image, -1, -1); //TODO move this XClearArea(mydisplay, window.win, 0, 0, window.window_area.width, window.window_area.height, False); } if(((window.win_state == WINDOW_STATE_NORMAL) && (zoom_mode == ZoomModeFullScreen)) || ((window.win_state == WINDOW_STATE_FULLSCREEN) && (zoom_mode == ZoomModeResizeAllowed))) { display_toggle_fullscreen(current_image); } window.image = current_image; check_x_events(current_image); if(use_xv) draw_win_xv(&window); else draw_win_x11(&window); return;}void display_poll(yuv_image_t *current_image){ check_x_events(current_image);}void display_exit(void) { // FIXME TODO $$$ X isn't async signal safe.. cant free/detach things here.. // Need to add some test to se if we can detatch/free/destroy things if(mydisplay) { XSync(mydisplay,True); if(use_xshm) XShmDetach(mydisplay, &shm_info); if(window.ximage != 0) XDestroyImage(window.ximage); if(shm_info.shmaddr > 0) shmdt(shm_info.shmaddr); if(shm_info.shmid > 0) { shmctl(shm_info.shmid, IPC_RMID, 0); } } display_process_exit();}static Bool predicate(Display *dpy, XEvent *ev, XPointer arg){ if(ev->type == CompletionType) { return True; } else { return False; }}static void draw_win_x11(window_info *dwin){ int sar_frac_n = 0, sar_frac_d = 0; /* initialize to shut up compiler */ char *address = dwin->ximage->data; #ifdef HAVE_MLIB int dest_size = dwin->ximage->bytes_per_line * dwin->ximage->height; int source_size = (dwin->image->info->picture.padded_width*(pixel_stride/8) * dwin->image->info->picture.padded_height); mlib_image *mimage_s; mlib_image *mimage_d; /* Put the decode rgb data close to the end of the data segment. */ // Because mlib_YUV* reads out of bounds we need to make sure that the end // of the picture isn't on the pageboundary for in the last page allocated // There is also something strange with the mlib_ImageZoom in NEAREST mode. int offs = dest_size - source_size - 4096; if(offs > 0) address += offs;#endif /* HAVE_MLIB */ if(screenshot || screenshot_spu) { if(aspect_mode == AspectModeSrcVM) { sar_frac_n // hack = aspect_new_frac_d * dwin->image->info->picture.horizontal_size; sar_frac_d // hack = aspect_new_frac_n * dwin->image->info->picture.vertical_size; } /* Use the stream aspect */ else /* if(aspect_mode == AspectModeSrcMPEG) also default */ { sar_frac_n = dwin->image->info->picture.sar_frac_n; sar_frac_d = dwin->image->info->picture.sar_frac_d; } } /*** sun ffb2 ***/ if(use_ffb2_yuv2rgb) { int stride; int m; unsigned char *y; unsigned char *u; unsigned char *v; area_t fb_area; area_t src_area; rect_t fb_rect; rect_t clip_rect; window.video_area.width = dwin->image->info->picture.horizontal_size; window.video_area.height = dwin->image->info->picture.vertical_size; window.video_area.x = (int)(window.window_area.width - window.video_area.width) / 2; window.video_area.y = (int)(window.window_area.height - window.video_area.height) / 2; stride = dwin->image->info->picture.padded_width; y = dwin->image->y; u = dwin->image->u; v = dwin->image->v; /* fprintf(stderr, "win.x: %d, win.y: %d, win.w: %u, win.h: %u\n", window.window_area.x, window.window_area.y, window.window_area.width, window.window_area.height); fprintf(stderr, "vid.x: %d, vid.y: %d, vid.w: %u, vid.h: %u\n", window.video_area.x, window.video_area.y, window.video_area.width, window.video_area.height); */ fb_rect.x0 = window.window_area.x+window.video_area.x; fb_rect.y0 = window.window_area.y+window.video_area.y; fb_rect.x1 = fb_rect.x0 + window.video_area.width; fb_rect.y1 = fb_rect.y0 + window.video_area.height; clip_rect.x0 = window.window_area.x; clip_rect.y0 = window.window_area.y; clip_rect.x1 = clip_rect.x0 + window.window_area.width; clip_rect.y1 = clip_rect.y0 + window.window_area.height; fb_rect = clip(&fb_rect, &clip_rect); clip_rect.x0 = 0; clip_rect.y0 = 0; DpyInfoGetResolution(mydisplay, screen_nr, &clip_rect.x1, &clip_rect.y1); fb_rect = clip(&fb_rect, &clip_rect); fb_area.x = fb_rect.x0; fb_area.y = fb_rect.y0; fb_area.width = fb_rect.x1 - fb_rect.x0; fb_area.height = fb_rect.y1 - fb_rect.y0; if(fb_area.width > 0 && fb_area.height > 0) { src_area.x = fb_area.x - (window.window_area.x+window.video_area.x); src_area.y = fb_area.y - (window.window_area.y+window.video_area.y); src_area.width = fb_area.width; src_area.height = fb_area.height; /* fprintf(stderr, "===: fb.x: %d fb.y: %d fb.w: %u fb.h: %u\n", fb_area.x, fb_area.y, fb_area.width, fb_area.height); fprintf(stderr, "===: src.x: %d src.y: %d src.w: %u src.h: %u\n", src_area.x, src_area.y, src_area.width, src_area.height); */#ifdef USE_SPARCASM for(m = 0; m < src_area.height; m+=2) { uint8_t *yp; uint8_t *up; uint8_t *vp; y = dwin->image->y+(src_area.y+m)*stride; u = dwin->image->u+(src_area.y+m)/2*stride/2; v = dwin->image->v+(src_area.y+m)/2*stride/2; yp = &y[src_area.x]; up = &u[src_area.x/2]; vp = &v[src_area.x/2]; yuv_plane_to_yuyv_packed(yp, up, vp, &yuyv_fb[(fb_area.y+m)*1024+(fb_area.x/4)*2], src_area.width); }#else /* USE_SPARCASM */ for(m = 0; m < src_area.height; m++) { int n; y = dwin->image->y+(src_area.y+m)*stride; u = dwin->image->u+(src_area.y+m)/2*stride/2; v = dwin->image->v+(src_area.y+m)/2*stride/2; for(n = 0; n < src_area.width/2; n++) { unsigned int pixel_data; pixel_data = (y[src_area.x+n*2]<<24) | (u[src_area.x/2+n]<<16) | (y[src_area.x+n*2+1]<<8) | (v[src_area.x/2+n]); yuyv_fb[(fb_area.y+m)*1024+(fb_area.x/2+n)] = pixel_data; } }#endif /* USE_SPARCASM */ #ifdef SPU if(msgqid != -1) { mix_subpicture_rgb((char *)&rgb_fb[fb_area.y*2048+fb_area.x], 2048, fb_area.height); }#endif } return; } /*** end sun ffb2 ***/ /* We must some how guarantee that the ximage isn't used by X11. This is done by the XIfEvent at the bottom */ yuv2rgb(address, dwin->image->y, dwin->image->u, dwin->image->v, dwin->image->info->picture.padded_width, dwin->image->info->picture.padded_height, dwin->image->info->picture.padded_width*(pixel_stride/8), dwin->image->info->picture.padded_width, dwin->image->info->picture.padded_width/2); #ifdef SPU if(msgqid != -1) { mix_subpicture_rgb(address, dwin->image->info->picture.padded_width, dwin->image->info->picture.padded_height); }#endif if(screenshot_spu) { screenshot_spu = 0; screenshot_rgb_jpg(address, dwin->image->info->picture.padded_width, dwin->image->info->picture.padded_height, sar_frac_n, sar_frac_d); } #ifdef HAVE_MLIB if((scale.image_width != dwin->image->info->picture.horizontal_size) || (scale.image_height != dwin->image->info->picture.vertical_size)) { /* Destination image */ mimage_d = mlib_ImageCreateStruct(MLIB_BYTE, 4, scale.image_width, scale.image_height, dwin->ximage->bytes_per_line, dwin->ximage->data); /* Source image */ mimage_s = mlib_ImageCreateStruct(MLIB_BYTE, 4, src_view_area.width, src_view_area.height, dwin->image->info->picture.padded_width*4, address+4*src_view_area.x+dwin->image->info->picture.padded_width*4*src_view_area.y); /* Extra fast 2x Zoom */ if((scale.image_width == 2 * src_view_area.width) && (scale.image_height == 2 * src_view_area.height)) { mlib_ImageZoomIn2X(mimage_d, mimage_s, scalemode, MLIB_EDGE_DST_FILL_ZERO); } else { mlib_ImageZoom (mimage_d, mimage_s, (double)scale.image_width/(double)src_view_area.width, (double)scale.image_height/(double)src_view_area.height, scalemode, MLIB_EDGE_DST_FILL_ZERO); } mlib_ImageDelete(mimage_s); mlib_ImageDelete(mimage_d); }#endif /* HAVE_MLIB */ if(screenshot) { screenshot = 0; screenshot_yuv_jpg(dwin->image, dwin->ximage, sar_frac_n, sar_frac_d); } window.video_area.width = scale.image_width; window.video_area.height = scale.image_height; window.video_area.x = (window.window_area.width - window.video_area.width) / 2; window.video_area.y = (window.window_area.height - window.video_area.height) / 2; /* fprintf(stderr, "dwin->win: %d, mygc: %d, dwin->ximage: %d, 0, 0,\n", dwin->win, mygc, dwin->ximage); fprintf(stderr, "x: %d %x, y: %d %x, w: %d %x, h: %d %x\n", window.video_area.x, window.video_area.x, window.video_area.y, window.video_area.y, window.video_area.width, window.video_area.width, window.video_area.height, window.video_area.height); */ /* DNOTE("window.video_area. x:%d, y: %d, w:%d, h:%d\n", window.video_area.x, window.video_area.y, window.video_area.width, window.video_area.height); */ if(use_ffb2_rgb) { int y; for(y = 0; y < dwin->ximage->height; y++) { //int x;#ifdef HAVE_MLIB mlib_memcpy(&rgb_fb[y*2048], &dwin->ximage->data[y*dwin->ximage->bytes_per_line], dwin->ximage->width*4); #else memcpy(&rgb_fb[y*2048], &dwin->ximage->data[y*dwin->ximage->bytes_per_line], dwin->ximage->width*4); #endif /* for(x = 0; x < dwin->ximage->width; x++) { uint32_t pixel_data; pixel_data = *((uint32_t *)&dwin->ximage->data[y*dwin->ximage->bytes_per_line+x*4]); rgb_fb[y*2048+x] = pixel_data; } */ } } else if(use_xshm) { XShmPutImage(mydisplay, dwin->win, mygc, dwin->ximage, 0, 0, window.video_area.x, window.video_area.y, window.video_area.width, window.video_area.height, True); { XEvent ev; /* this is to make sure that we are free to use the image again It waits for an XShmCompletionEvent */ XIfEvent(mydisplay, &ev, predicate, NULL); } } else { XPutImage(mydisplay, dwin->win, mygc, dwin->ximage, 0, 0, window.video_area.x, window.video_area.y, window.video_area.width, window.video_area.height); XSync(mydisplay, False); }}static void draw_win_xv(window_info *dwin){#ifdef HAVE_XV yuv_image_t *draw_image; int sar_frac_n = 0, sar_frac_d = 0; /* initialize to shut up compiler */ /* Set the source of the xv_image to the source of the image that we want drawn. */ draw_image = dwin->image; if(screenshot || screenshot_spu) { if(aspect_mode == AspectModeSrcVM) { sar_frac_n // hack = aspect_new_frac_d * draw_image->info->picture.horizontal_size; sar_frac_d // hack = aspect_new_frac_n * draw_image->info->picture.vertical_size; } /* Use the stream aspect */ else /* if(aspect_mode == AspectModeSrcMPEG) also default */ { sar_frac_n = draw_image->info->picture.sar_frac_n; sar_frac_d = draw_image->info->picture.sar_frac_d; } } if(screenshot) { screenshot = 0; screenshot_yuv_jpg(draw_image, dwin->ximage, sar_frac_n, sar_frac_d); }#ifdef SPU if(msgqid != -1) { //ugly hack if(mix_subpicture_yuv(draw_image, cur_data_q->reserv_image)) { draw_image = cur_data_q->reserv_image; } }#endif xv_image->data = draw_image->y; if(screenshot_spu) { screenshot_spu = 0; screenshot_yuv_jpg(draw_image, dwin->ximage, sar_frac_n, sar_frac_d); } window.video_area.width = scale.image_width; window.video_area.height = scale.image_height; window.video_area.x = (int)(window.window_area.width - window.video_area.width) / 2; window.video_area.y = (int)(window.window_area.height - window.video_area.height) / 2; if(use_xshm) { XvShmPutImage(mydisplay, xv_port, dwin->win, mygc, xv_image, src_view_area.x, src_view_area.y, src_view_area.width, src_view_area.height, window.video_area.x, window.video_area.y, window.video_area.width, window.video_area.height, True); } else { XvPutImage(mydisplay, xv_port, dwin->win, mygc, xv_image, src_view_area.x, src_view_area.y, src_view_area.width, src_view_area.height, window.video_area.x, window.video_area.y, window.video_area.width, window.video_area.height); XFlush(mydisplay); } //XFlush(mydisplay); ?? if(use_xshm) { XEvent ev; XEvent *e; e = &ev; /* this is to make sure that we are free to use the image again It waits for an XShmCompletionEvent */ XIfEvent(mydisplay, &ev, predicate, NULL); }#endif /* HAVE_XV */}void display_reset_screensaver(void){ XResetScreenSaver(mydisplay);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -