📄 display.c
字号:
/* display.c, X11 interface */
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
/*
* Disclaimer of Warranty
*
* These software programs are available to the user without any license fee or
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
* any and all warranties, whether express, implied, or statuary, including any
* implied warranties or merchantability or of fitness for a particular
* purpose. In no event shall the copyright-holder be liable for any
* incidental, punitive, or consequential damages of any kind whatsoever
* arising from the use of these programs.
*
* This disclaimer of warranty extends to the user of these programs and user's
* customers, employees, agents, transferees, successors, and assigns.
*
* The MPEG Software Simulation Group does not represent or warrant that the
* programs furnished hereunder are free of infringement of any third-party
* patents.
*
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
* are subject to royalty fees to patent holders. Many of these patents are
* general enough such that they are unavoidable regardless of implementation
* design.
*
*/
#ifdef DISPLAY
/* the Xlib interface is closely modeled after
* mpeg_play 2.0 by the Berkeley Plateau Research Group
*/
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "config.h"
#include "global.h"
/* private prototypes */
static void Display_Image _ANSI_ARGS_((XImage *Ximage_Ptr, unsigned char *Dithered_Image));
static void Dither_Frame _ANSI_ARGS_((unsigned char *src[]));
static void Dither_Top_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
static void Dither_Bottom_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
static void Dither_Top_Field420 _ANSI_ARGS_((unsigned char *src[],
unsigned char *dst));
static void Dither_Bottom_Field420 _ANSI_ARGS_((unsigned char *src[],
unsigned char *dst));
/* local data */
static unsigned char *Dithered_Image, *Dithered_Image2;
static unsigned char Y_Table[256+16];
static unsigned char Cb_Table[128+16];
static unsigned char Cr_Table[128+16];
/* X11 related variables */
static Display *Display_Ptr;
static Window Window_Instance;
static GC GC_Instance;
static XImage *Ximage_Ptr, *Ximage_Ptr2;
static unsigned char Pixel[256];
#ifdef SH_MEM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
static int HandleXError _ANSI_ARGS_((Display *dpy, XErrorEvent *event));
static void InstallXErrorHandler _ANSI_ARGS_((void));
static void DeInstallXErrorHandler _ANSI_ARGS_((void));
static int Shmem_Flag;
static XShmSegmentInfo Shminfo1, Shminfo2;
static int gXErrorFlag;
static int CompletionType = -1;
static int HandleXError(Dpy, Event)
Display *Dpy;
XErrorEvent *Event;
{
gXErrorFlag = 1;
return 0;
}
static void InstallXErrorHandler()
{
XSetErrorHandler(HandleXError);
XFlush(Display_Ptr);
}
static void DeInstallXErrorHandler()
{
XSetErrorHandler(NULL);
XFlush(Display_Ptr);
}
#endif
/* connect to server, create and map window,
* allocate colors and (shared) memory
*/
void Initialize_Display_Process(name)
char *name;
{
int crv, cbu, cgu, cgv;
int Y, Cb, Cr, R, G, B;
int i;
char dummy;
int screen;
Colormap cmap;
int private;
XColor xcolor;
unsigned int fg, bg;
char *hello = "MPEG-2 Display";
XSizeHints hint;
XVisualInfo vinfo;
XEvent xev;
unsigned long tmp_pixel;
XWindowAttributes xwa;
Display_Ptr = XOpenDisplay(name);
if (Display_Ptr == NULL)
Error("Can not open display\n");
screen = DefaultScreen(Display_Ptr);
hint.x = 200;
hint.y = 200;
hint.width = horizontal_size;
hint.height = vertical_size;
hint.flags = PPosition | PSize;
/* Get some colors */
bg = WhitePixel (Display_Ptr, screen);
fg = BlackPixel (Display_Ptr, screen);
/* Make the window */
if (!XMatchVisualInfo(Display_Ptr, screen, 8, PseudoColor, &vinfo))
{
if (!XMatchVisualInfo(Display_Ptr, screen, 8, GrayScale, &vinfo))
;// Error("requires 8 bit display\n");
}
Window_Instance = XCreateSimpleWindow (Display_Ptr, DefaultRootWindow (Display_Ptr),
hint.x, hint.y, hint.width, hint.height, 4, fg, bg);
XSelectInput(Display_Ptr, Window_Instance, StructureNotifyMask);
/* Tell other applications about this window */
XSetStandardProperties (Display_Ptr, Window_Instance, hello, hello, None, NULL, 0, &hint);
/* Map window. */
XMapWindow(Display_Ptr, Window_Instance);
/* Wait for map. */
do
{
XNextEvent(Display_Ptr, &xev);
}
while (xev.type != MapNotify || xev.xmap.event != Window_Instance);
XSelectInput(Display_Ptr, Window_Instance, NoEventMask);
/* matrix coefficients */
crv = Inverse_Table_6_9[matrix_coefficients][0];
cbu = Inverse_Table_6_9[matrix_coefficients][1];
cgu = Inverse_Table_6_9[matrix_coefficients][2];
cgv = Inverse_Table_6_9[matrix_coefficients][3];
/* allocate colors */
GC_Instance = DefaultGC(Display_Ptr, screen);
cmap = DefaultColormap(Display_Ptr, screen);
private = 0;
/* color allocation:
* i is the (internal) 8 bit color number, it consists of separate
* bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
* and yyyy=1111, this leaves 32 colors for other applications
*
* the allocated colors correspond to the following Y, U and V values:
* Y: 24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
* U,V: -48, -16, 16, 48
*
* U and V values span only about half the color space; this gives
* usually much better quality, although highly saturated colors can
* not be displayed properly
*
* translation to R,G,B is implicitly done by the color look-up table
*/
for (i=16; i<240; i++)
{
/* color space conversion */
Y = 16*((i>>4)&15) + 8;
Cb = 32*((i>>2)&3) - 48;
Cr = 32*(i&3) - 48;
Y = 76309 * (Y - 16); /* (255/219)*65536 */
R = Clip[(Y + crv*Cr + 32768)>>16];
G = Clip[(Y - cgu*Cb - cgv*Cr + 32768)>>16];
B = Clip[(Y + cbu*Cb + 32786)>>16];
/* X11 colors are 16 bit */
xcolor.red = R << 8;
xcolor.green = G << 8;
xcolor.blue = B << 8;
if (XAllocColor(Display_Ptr, cmap, &xcolor) != 0)
Pixel[i] = xcolor.pixel;
else
{
/* allocation failed, have to use a private colormap */
if (private)
Error("Couldn't allocate private colormap");
private = 1;
if (!Quiet_Flag)
fprintf(stderr, "Using private colormap (%d colors were available).\n",
i-16);
/* Free colors. */
while (--i >= 16)
{
tmp_pixel = Pixel[i]; /* because XFreeColors expects unsigned long */
XFreeColors(Display_Ptr, cmap, &tmp_pixel, 1, 0);
}
/* i is now 15, this restarts the outer loop */
/* create private colormap */
XGetWindowAttributes(Display_Ptr, Window_Instance, &xwa);
cmap = XCreateColormap(Display_Ptr, Window_Instance, xwa.visual, AllocNone);
XSetWindowColormap(Display_Ptr, Window_Instance, cmap);
}
}
#ifdef SH_MEM
if (XShmQueryExtension(Display_Ptr))
Shmem_Flag = 1;
else
{
Shmem_Flag = 0;
if (!Quiet_Flag)
fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n");
}
if (Shmem_Flag)
CompletionType = XShmGetEventBase(Display_Ptr) + ShmCompletion;
InstallXErrorHandler();
if (Shmem_Flag)
{
Ximage_Ptr = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL,
&Shminfo1,
Coded_Picture_Width, Coded_Picture_Height);
if (!progressive_sequence)
Ximage_Ptr2 = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL,
&Shminfo2,
Coded_Picture_Width, Coded_Picture_Height);
/* If no go, then revert to normal Xlib calls. */
if (Ximage_Ptr==NULL || (!progressive_sequence && Ximage_Ptr2==NULL))
{
if (Ximage_Ptr!=NULL)
XDestroyImage(Ximage_Ptr);
if (!progressive_sequence && Ximage_Ptr2!=NULL)
XDestroyImage(Ximage_Ptr2);
if (!Quiet_Flag)
fprintf(stderr, "Shared memory error, disabling (Ximage error)\n");
goto shmemerror;
}
/* Success here, continue. */
Shminfo1.shmid = shmget(IPC_PRIVATE,
Ximage_Ptr->bytes_per_line * Ximage_Ptr->height,
IPC_CREAT | 0777);
if (!progressive_sequence)
Shminfo2.shmid = shmget(IPC_PRIVATE,
Ximage_Ptr2->bytes_per_line * Ximage_Ptr2->height,
IPC_CREAT | 0777);
if (Shminfo1.shmid<0 || (!progressive_sequence && Shminfo2.shmid<0))
{
XDestroyImage(Ximage_Ptr);
if (!progressive_sequence)
XDestroyImage(Ximage_Ptr2);
if (!Quiet_Flag)
fprintf(stderr, "Shared memory error, disabling (seg id error)\n");
goto shmemerror;
}
Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0);
Shminfo2.shmaddr = (char *) shmat(Shminfo2.shmid, 0, 0);
if (Shminfo1.shmaddr==((char *) -1) ||
(!progressive_sequence && Shminfo2.shmaddr==((char *) -1)))
{
XDestroyImage(Ximage_Ptr);
if (Shminfo1.shmaddr!=((char *) -1))
shmdt(Shminfo1.shmaddr);
if (!progressive_sequence)
{
XDestroyImage(Ximage_Ptr2);
if (Shminfo2.shmaddr!=((char *) -1))
shmdt(Shminfo2.shmaddr);
}
if (!Quiet_Flag)
{
fprintf(stderr, "Shared memory error, disabling (address error)\n");
}
goto shmemerror;
}
Ximage_Ptr->data = Shminfo1.shmaddr;
Dithered_Image = (unsigned char *)Ximage_Ptr->data;
Shminfo1.readOnly = False;
XShmAttach(Display_Ptr, &Shminfo1);
if (!progressive_sequence)
{
Ximage_Ptr2->data = Shminfo2.shmaddr;
Dithered_Image2 = (unsigned char *)Ximage_Ptr2->data;
Shminfo2.readOnly = False;
XShmAttach(Display_Ptr, &Shminfo2);
}
XSync(Display_Ptr, False);
if (gXErrorFlag)
{
/* Ultimate failure here. */
XDestroyImage(Ximage_Ptr);
shmdt(Shminfo1.shmaddr);
if (!progressive_sequence)
{
XDestroyImage(Ximage_Ptr2);
shmdt(Shminfo2.shmaddr);
}
if (!Quiet_Flag)
fprintf(stderr, "Shared memory error, disabling.\n");
gXErrorFlag = 0;
goto shmemerror;
}
else
{
shmctl(Shminfo1.shmid, IPC_RMID, 0);
if (!progressive_sequence)
shmctl(Shminfo2.shmid, IPC_RMID, 0);
}
if (!Quiet_Flag)
{
fprintf(stderr, "Sharing memory.\n");
}
}
else
{
shmemerror:
Shmem_Flag = 0;
#endif
Ximage_Ptr = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy,
Coded_Picture_Width,Coded_Picture_Height,8,0);
if (!(Dithered_Image = (unsigned char *)malloc(Coded_Picture_Width*
Coded_Picture_Height)))
Error("malloc failed");
if (!progressive_sequence)
{
Ximage_Ptr2 = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy,
Coded_Picture_Width,Coded_Picture_Height,8,0);
if (!(Dithered_Image2 = (unsigned char *)malloc(Coded_Picture_Width*
Coded_Picture_Height)))
Error("malloc failed");
}
#ifdef SH_MEM
}
DeInstallXErrorHandler();
#endif
}
void Terminate_Display_Process()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -