/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * player.cc * * Mon Mar 6 20:14:25 CET 2006 * Copyright 2006 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of MIaV. * * MIaV is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MIaV is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MIaV; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "player.h" #include "info.h" #include #define DV_FOURCC_YV12 0x32315659 /* 4:2:0 Planar mode: Y + V + U (3 planes) */ #define DV_FOURCC_YUY2 0x32595559 /* 4:2:2 Packed mode: Y0+U0+Y1+V0 (1 plane) */ #include #include #include #include #include #include #include #include Player::Player(VideoWidget *v) { video = v; // dpy = XOpenDisplay(NULL); // Get the deafult display display = video->x11Info().display(); drawable = video->winId(); gc = XCreateGC(display, drawable, 0, 0); // // Check version // unsigned int version, release; unsigned int request_base, event_base, error_base; switch(XvQueryExtension(display, &version, &release, &request_base, &event_base, &error_base)) { case Success: MIaV::info->info("Returned if XvQueryExtension(3X) completed successfully."); break; case XvBadExtension: MIaV::info->info("Returned if the Xv video extension is not available for the named display."); break; case XvBadAlloc: MIaV::info->info("Returned if XvQueryExtension(3X) failed to allocate memory to process the request."); break; } // // Find port // unsigned int adaptors; XvAdaptorInfo *ai; switch(XvQueryAdaptors(display, drawable, &adaptors, &ai)) { case Success: MIaV::info->info("Returned if XvQueryAdaptors(3X) completed successfully."); break; case XvBadExtension: MIaV::info->info("Returned if the Xv video extension is not available for the named display."); break; case XvBadAlloc: MIaV::info->info("Returned if XvQueryAdaptors(3X) failed to allocate memory to process the request."); break; } /* typedef struct { XvPortID base_id; unsigned long num_ports; char type; char *name; unsigned long num_formats; XvFormat *formats; unsigned long num_adaptors; } XvAdaptorInfo; */ if(adaptors == 0) { MIaV::info->error("Unable to find any adapters."); return; } /* check adaptors */ port = 0; for (unsigned int i = 0; i < adaptors; i++) { if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask) && (port == 0)) { port = ai[i].base_id; } } if(port == 0) { MIaV::info->error("Unable to find suitable port."); return; } else { MIaV::info->info("Using port %d.", port); } } Player::~Player() { //XCloseDisplay(dpy); // Close the Display } extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*); void Player::run() { XShmSegmentInfo yuv_shminfo; yuv_shminfo.shmid = shmget(IPC_PRIVATE, 720*576*4, //yuv_image->data_size, IPC_CREAT | 0777); // yuv_shminfo.shmaddr = shmat(yuv_shminfo.shmid, 0, 0); yuv_shminfo.readOnly = False; char pixels[720*576*4][4]; XvImage* xv_image = XvShmCreateImage(display, port, DV_FOURCC_YUY2, // DV_FOURCC_YV12 pixels[0], 720, 576,// dv_dpy->width, dv_dpy->height, &yuv_shminfo); int swidth = 720; int sheight = 576; int lxoff = 0; int lyoff = 0; int lwidth = swidth; int lheight = sheight; XvShmPutImage(display, port, drawable, gc, xv_image, 0, 0, swidth, sheight, lxoff, lyoff, lwidth, lheight, True); XFlush(display); // XvPutStill(display, port, drawable, gc, 0, 0, 320, 200, 0, 0, 320, 200); } // From: // http://cvs.sourceforge.net/viewcvs.py/libmpeg2/MSSG/display_x11.c?rev=1.2 #if 0 #ifdef HAVE_XV xv_port = 0; if (Success == XvQueryExtension(mydisplay,&ver,&rel,&req,&ev,&err)) { /* check for Xvideo support */ if (Success != XvQueryAdaptors(mydisplay,DefaultRootWindow(mydisplay), &adaptors,&ai)) { fprintf(stderr,"Xv: XvQueryAdaptors failed"); exit(1); } /* check adaptors */ for (i = 0; i < adaptors; i++) { if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask) && (xv_port == 0)) { xv_port = ai[i].base_id; } } /* check image formats */ if (xv_port != 0) { fo = XvListImageFormats(mydisplay, xv_port, (int*)&formats); for(i = 0; i < formats; i++) { fprintf(stderr, "Xvideo image format: 0x%x (%4.4s) %s\n", fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); if (0x32315659 == fo[i].id) { xv_format = fo[i].id; break; } } if (i == formats) /* no matching image format not */ xv_port = 0; } if (xv_port != 0) { fprintf(stderr,"using Xvideo port %d for hw scaling\n", xv_port); /* allocate XvImages. FIXME: no error checking, without * mit-shm this will bomb... */ xvimage1 = XvShmCreateImage(mydisplay, xv_port, xv_format, 0, image_width, image_height, &Shminfo1); Shminfo1.shmid = shmget(IPC_PRIVATE, xvimage1->data_size, IPC_CREAT | 0777); Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0); Shminfo1.readOnly = False; xvimage1->data = Shminfo1.shmaddr; XShmAttach(mydisplay, &Shminfo1); XSync(mydisplay, False); shmctl(Shminfo1.shmid, IPC_RMID, 0); /* so we can do grayscale while testing... */ memset(xvimage1->data,128,xvimage1->data_size); /* catch window resizes */ XSelectInput(mydisplay, mywindow, StructureNotifyMask); win_width = image_width; win_height = image_height; /* all done (I hope...) */ X_already_started++; return; } } #endif/* HAVE_XV */ #endif/* 0 */