00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
#include <stdio.h>
00036
#include <string.h>
00037
#include <stdlib.h>
00038
#include <signal.h>
00039
#include <sys/types.h>
00040
#include <libdv/dv_types.h>
00041
#include <pthread.h>
00042
00043
#ifdef HAVE_SDL
00044
#include <SDL/SDL.h>
00045
#include <SDL/SDL_syswm.h>
00046
#endif
00047
00048
#ifdef HAVE_SDL11
00049
#include <SDL11/SDL.h>
00050
#include <SDL11/SDL_syswm.h>
00051
#endif
00052
00053
#include "xdvshow-sdl.h"
00054
#include "xdvshow-shm.h"
00055
#include "xdvshow-flags.h"
00056
#include "xdvshow-defs.h"
00057
00058
#include <postprocess.h>
00059
00060 SDL_Surface *
sdl_screen;
00061 SDL_Overlay *
overlay;
00062 SDL_Overlay *
dstoverlay;
00063 SDL_Rect
rect;
00064
00065 SDL_Event
sdl_event;
00066
00067
#ifndef S_SPLINT_S
00068 static Display *
display;
00069
#endif
00070
00071 int width,
height;
00072
00073 unsigned int res_x = 800, res_y = 600;
00074
00075 pp_context_t *
pp_context;
00076 pp_mode_t *
pp_mode;
00077
00084 int Get_resolution(){
00085
00086
int itemp;
00087
unsigned int utemp;
00088
#ifndef S_SPLINT_S
00089
Window wtemp;
00090 Status temp;
00091
#endif
00092
00093 temp = XGetGeometry(
display, DefaultRootWindow(
display), &wtemp, &itemp, &itemp, &
res_x, &res_y, &utemp, &utemp);
00094
00095
if (XQueryExtension(
display,
"XINERAMA", &itemp, &itemp, &itemp)) {
00096 fprintf(stdout,
"XINERAMA detected but not used in this version\n");
00097 }
00098 printf(
"Display resolution: %d x %d.\n",
res_x, res_y);
00099
00100
if (
flags_stereo)
res_x =
res_x / 2;
00101
00102
return 0;
00103 }
00104
00113 void yuy2yuv(uint8_t **src, uint8_t **dst) {
00114
00115
unsigned char y2y[256];
00116
unsigned char br2br[256];
00117
00118
unsigned char *yuv;
00119
00120
int x, y, i, j, j0, j1, j2, j3, k;
00121
00122
for (i = 0; i < 256; i++) {
00123 j = 16 + i * (236-16) / 255;
00124
#if 0
00125
y2y[i] = j;
00126 br2br[i] = 16 + i * (240-16) / 255;
00127
#else
00128
y2y[i] = i;
00129 br2br[i] = i;
00130
#endif
00131
}
00132
00133 yuv = (
unsigned char *)malloc(2 *
overlay->w *
overlay->h *
sizeof(
unsigned char));
00134
00135
00136
00137
00138 yuv = (
unsigned char *)src;
00139
00140
for (y = 0; y <
overlay->h; y++) {
00141
for (x = 0; x <
overlay->w; x++) {
00142 memcpy(dst, (
unsigned char *)y2y[yuv[2 * (y *
overlay->w + x) + 1]],
sizeof(
unsigned char));
00143 }
00144 }
00145
00146 j0 = 0;
00147 j1 = 2 *
overlay -> w;
00148
00149
for (i = 0; i < 2; i++) {
00150
for (y = 0; y <
overlay->h; y += 2) {
00151 j2 = 0;
00152
if (y%4) j2 =j0;
00153 j3 = j2 + j1;
00154
00155
for (x = 0; x <
overlay->w; x += 2) {
00156 j = 2 * (y *
overlay->w + x + i);
00157 k = (yuv[j + j2] + yuv[j + j3])/2;
00158 memcpy(dst, (
unsigned char *)br2br[k],
sizeof(
unsigned char));
00159 }
00160 }
00161 }
00162
00163 free(yuv);
00164
00165 }
00166
00167
00168
static void _dv_center_window __P((SDL_Surface *));
00169
00178
int
00179 xdvshow_SDL_handle_events(
void) {
00180 pthread_testcancel();
00181
while (SDL_PollEvent(&
sdl_event)) {
00182 pthread_testcancel();
00183
switch (
sdl_event.type) {
00184
case SDL_KEYDOWN:
00185
case SDL_KEYUP:
00186
00187
if (!strcmp(SDL_GetKeyName(
sdl_event.key.keysym.sym),
"q")) {
00188 fprintf(stderr,
"Exiting...\n");
00189 kill(
_xdvshow_shm.
parent_pid, SIGINT);
00190 }
00191
break;
00192
00193
default:
00194
break;
00195 }
00196 }
00197
return(0);
00198 }
00199
00208
int
00209 xdvshow_open_window(
char *window_name,
struct x_params *param)
00210 {
00211
char *pp_name;
00212
00213
int ret;
00214
const SDL_VideoInfo *video_info;
00215
int video_bpp;
00216
00217
switch (param->
dv_format_type) {
00218
case e_dv_system_525_60:
00219
width = 720;
00220
height = 480;
00221
break;
00222
00223
case e_dv_system_625_50:
00224
width = 720;
00225
height = 576;
00226
break;
00227
00228
default:
00229
return(-1);
00230 }
00231
00232
display = XOpenDisplay(NULL);
00233
00234 ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
00235
if (ret < 0) {
00236
return(-1);
00237 }
00238
00239 video_info = SDL_GetVideoInfo();
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 video_bpp = 0;
00254
00255
if (
flags_sdlnooverlay) {
00256
00257 printf(
"Display settings: SDL HW_SURFACE disabled.\n");
00258
00259
if (
flags_fullscreen) {
00260
if (
flags_zoom) {
00261
res_x =
width;
00262 res_y =
height;
00263
sdl_screen = SDL_SetVideoMode(
width,
height, video_bpp, SDL_SWSURFACE | SDL_FULLSCREEN);
00264 }
else {
00265
Get_resolution();
00266
if (
flags_stereo) {
00267
sdl_screen = SDL_SetVideoMode(
res_x, res_y, video_bpp, SDL_SWSURFACE | SDL_NOFRAME);
00268 }
else {
00269
sdl_screen = SDL_SetVideoMode(
res_x, res_y, video_bpp, SDL_SWSURFACE | SDL_FULLSCREEN);
00270 }
00271 }
00272 }
else {
00273
sdl_screen = SDL_SetVideoMode(
width,
height, video_bpp, SDL_SWSURFACE);
00274 }
00275
00276 }
else {
00277
00278
if (
flags_fullscreen) {
00279
if (
flags_zoom) {
00280
res_x =
width;
00281 res_y =
height;
00282
sdl_screen = SDL_SetVideoMode(
width,
height, video_bpp, SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF);
00283 }
else {
00284
Get_resolution();
00285
if (
flags_stereo) {
00286
sdl_screen = SDL_SetVideoMode(
res_x, res_y, video_bpp, SDL_HWSURFACE | SDL_NOFRAME | SDL_DOUBLEBUF);
00287 }
else {
00288
sdl_screen = SDL_SetVideoMode(
res_x, res_y, video_bpp, SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF);
00289 }
00290 }
00291 }
else {
00292
sdl_screen = SDL_SetVideoMode(
width,
height, video_bpp, SDL_HWSURFACE | SDL_DOUBLEBUF);
00293 }
00294
00295 }
00296
00297 SDL_WM_SetCaption(window_name,
"name");
00298
00299 SDL_ShowCursor(SDL_DISABLE);
00300
00301
#define DV_FOURCC_YUY2 0x32595559
00302
#define DV_FOURCC_IYUV 0x56555949
00303
overlay = SDL_CreateYUVOverlay(
width,
height,
DV_FOURCC_YUY2,
sdl_screen);
00304
00305
if (!
overlay) {
00306 fprintf(stderr,
"SDL_overlay initialization failed.\n");
00307 }
00308
00309
if(
flags_deinterlace) {
00310
dstoverlay = SDL_CreateYUVOverlay(
width,
height,
DV_FOURCC_IYUV,
sdl_screen);
00311 }
00312
00313
_dv_center_window(
sdl_screen);
00314
00315
if (
flags_fullscreen) {
00316
if (
flags_scale) {
00317
rect.x = 0;
00318
00319
00320
00321
rect.y = (res_y -((
float)
res_x / (
float)768) *
overlay->h) / 2;
00322
rect.w =
res_x;
00323
00324
rect.h = ((
float)
res_x / (
float)768) *
overlay->h;
00325 }
else {
00326
rect.x = (
res_x -
overlay->w)/2;
00327
rect.y = (res_y -
overlay->h)/2;
00328
rect.w =
overlay->w;
00329
rect.h =
overlay->h;
00330 }
00331 }
else {
00332
rect.x = 0;
00333
rect.y = 0;
00334
rect.w =
overlay->w;
00335
rect.h =
overlay->h;
00336 }
00337
00338 printf(
"Display settings: rect_top: %d x %d; rect_res: %d x %d.\n",
rect.x,
rect.y,
rect.w,
rect.h);
00339
00340 param->
pixels[0] =
overlay->pixels[0];
00341 param->
pixels[1] =
overlay->pixels[1];
00342 param->
pixels[2] =
overlay->pixels[2];
00343 param->
pitches[0] =
overlay->pitches[0];
00344 param->
pitches[1] =
overlay->pitches[1];
00345 param->
pitches[2] =
overlay->pitches[2];
00346
00347 param->
decode_format = e_dv_color_yuv;
00348
00349
00350
if (
flags_deinterlace) {
00351
DPRINT(
"PP init...\n");
00352 pp_name = (
char *)malloc(10);
00353 sprintf(pp_name,
"lb");
00354
00355
00356
pp_context = pp_get_context(
rect.w,
rect.h, PP_CPU_CAPS_MMX);
00357
00358
pp_mode = pp_get_mode_by_name_and_quality(pp_name, PP_QUALITY_MAX);
00359 free(pp_name);
00360
DPRINT(
"PP init... done.\n");
00361 }
00362
00363
return(1);
00364 }
00365
00373
int
00374 xdvshow_close_window(
void)
00375 {
00376
00377
if (
flags_deinterlace) {
00378
DPRINT(
"PP uinit...\n");
00379
if (
pp_mode) pp_free_mode(
pp_mode);
00380
if (
pp_context) pp_free_context(
pp_context);
00381
DPRINT(
"PP uinit... done.\n");
00382 }
00383
00384 printf(
"Quitting SDL.\n");
00385 SDL_Quit();
00386
00387
return(1);
00388 }
00389
00398
int
00399 xdvshow_render(
void)
00400 {
00401
int srcStride[3] = {720, 360, 360};
00402
int dstStride[3] = {720, 360, 360};
00403
00404 pthread_testcancel();
00405 XFlush(
display);
00406 pthread_testcancel();
00407 SDL_UnlockYUVOverlay(
overlay);
00408 pthread_testcancel();
00409
if (
flags_deinterlace) {
00410
00411
00412
yuy2yuv(
overlay->pixels,
dstoverlay->pixels);
00413
00414 pp_postprocess(
overlay->pixels, srcStride,
dstoverlay->pixels, dstStride,
00415
overlay->w,
overlay->h, 0, 0,
pp_mode,
pp_context, 0);
00416 pthread_testcancel();
00417 SDL_DisplayYUVOverlay(
dstoverlay, &
rect);
00418 }
else {
00419 SDL_DisplayYUVOverlay(
overlay, &
rect);
00420 }
00421 pthread_testcancel();
00422 SDL_LockYUVOverlay(
overlay);
00423 pthread_testcancel();
00424
00425
return(1);
00426 }
00427
00434
static void
00435 _dv_center_window(SDL_Surface *screen)
00436 {
00437 SDL_SysWMinfo info;
00438
00439 SDL_VERSION(&info.version);
00440
if ( SDL_GetWMInfo(&info) > 0 ) {
00441
int x, y;
00442
int w, h;
00443
if (info.subsystem == SDL_SYSWM_X11) {
00444 info.info.x11.lock_func();
00445 w = DisplayWidth(info.info.x11.display,
00446 DefaultScreen(info.info.x11.display));
00447 h = DisplayHeight(info.info.x11.display,
00448 DefaultScreen(info.info.x11.display));
00449 x = (w - screen->w)/2;
00450 y = (h - screen->h)/2;
00451 XMoveWindow(info.info.x11.display, info.info.x11.wmwindow, x, y);
00452 info.info.x11.unlock_func();
00453 }
00454 }
00455 }