diff --git a/sesman/sesman.c b/sesman/sesman.c index 4a294a5e..83db5961 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -143,7 +143,7 @@ main(int argc, char **argv) enum logReturns error; int daemon = 1; int pid; - char pid_s[8]; + char pid_s[32]; char text[256]; char pid_file[256]; char cfg_file[256]; @@ -202,7 +202,8 @@ main(int argc, char **argv) return 1; } - error = g_file_read(fd, pid_s, 7); + g_memset(pid_s, 0, sizeof(pid_s)); + error = g_file_read(fd, pid_s, 31); if (-1 == error) { diff --git a/vrplayer/README.txt b/vrplayer/README.txt index 75903a0e..3584aaec 100644 --- a/vrplayer/README.txt +++ b/vrplayer/README.txt @@ -1,17 +1,32 @@ - A QT based media player that runs on a RDP server and redirects audio/video to the client where it is decoded and rendered locally -To build vrplayer, installl QT 4.x , then run +Required packages to build vrplayer: +------------------------------------ +libqt4-gui +qt4-dev-tools +libavutil-dev +libavformat-dev +to build vrplayer +----------------- +cd ../xrdpvr +make +cd .. qmake make -mint 13 packages -libqt4-gui -qt4-dev-tools +To run vrplayer +--------------- +include xrdpapi/.libs and xrdpvr/.libs in your LD_LIBRARY_PATH + +Example: +-------- +export LD_LIBRARY_PATH=../xrdpapi/.libs:../xrdpvr/.libs +run vrplayer inside the xfreerdp session -To run vrplayer, include xrdpapi/.libs and xrdpvr/.libs in -your LD_LIBRARY_PATH +this is how we run xfreerdp: +---------------------------- +./xfreerdp --sec rdp --plugin xrdpvr 192.168.2.149 diff --git a/vrplayer/demuxmedia.cpp b/vrplayer/demuxmedia.cpp index 7a13619e..ed91b387 100644 --- a/vrplayer/demuxmedia.cpp +++ b/vrplayer/demuxmedia.cpp @@ -88,7 +88,9 @@ void DemuxMedia::startDemuxing() { /* looks like we reached end of file */ delete mediaPkt; + playVideo->onMediaRestarted(); usleep(1000 * 100); + xrdpvr_seek_media(0, 0); continue; } diff --git a/vrplayer/demuxmedia.h b/vrplayer/demuxmedia.h index ecb25462..b83a8857 100644 --- a/vrplayer/demuxmedia.h +++ b/vrplayer/demuxmedia.h @@ -35,6 +35,7 @@ extern "C" class DemuxMedia : public QObject { Q_OBJECT + public: explicit DemuxMedia(QObject *parent = 0, QQueue *audioQueue = 0, QQueue *videoQueue = 0, void *channel = 0, int stream_id = 101); @@ -60,6 +61,9 @@ private: QMutex sendMutex; void startAudioVideoThreads(); + +signals: + void onMediaRestarted(); }; #endif // DEMUXMEDIA_H diff --git a/vrplayer/mainwindow.cpp b/vrplayer/mainwindow.cpp index 43060746..b97da148 100644 --- a/vrplayer/mainwindow.cpp +++ b/vrplayer/mainwindow.cpp @@ -275,7 +275,6 @@ void MainWindow::onBtnPlayClicked(bool) interface->setVcrOp(VCR_PLAY); vcrFlag = VCR_PLAY; } - else if (vcrFlag == VCR_STOP) { /* btn clicked while stopped - enter play mode */ @@ -312,15 +311,13 @@ void MainWindow::onMediaDurationInSeconds(int duration) int secs = 0; char buf[20]; -//return; - /* setup progress bar */ slider->setMinimum(0); slider->setMaximum(duration * 100); /* in hundredth of a sec */ slider->setValue(0); slider->setSliderPosition(0); lblCurrentPos->setText("00:00:00"); - qDebug() << "media_duration=" << duration << " in hundredth of a sec:" << duration * 100; + //qDebug() << "media_duration=" << duration << " in hundredth of a sec:" << duration * 100; /* convert from seconds to hours:minutes:seconds */ hours = duration / 3600; @@ -345,26 +342,24 @@ void MainWindow::onElapsedTime(int val) int hours = 0; int minutes = 0; int secs = 0; - int duration = val / 100; + int duration = 0; char buf[20]; if (vcrFlag == VCR_STOP) - { - qDebug() << "onElapsedTime: not updating slider coz of VCR_STOP"; return; - } /* if slider bar is down, do not update */ if (slider->isSliderDown()) - { - qDebug() << "onElapsedTime: not updating slider coz slider is down"; return; - } /* update progress bar */ + if (val >= slider->maximum()) + val = 0; + slider->setSliderPosition(val); /* convert from seconds to hours:minutes:seconds */ + duration = val / 100; hours = duration / 3600; if (hours) duration -= (hours * 3600); @@ -409,10 +404,3 @@ void MainWindow::onSliderActionTriggered(int action) } } -#if 1 -// LK_TODO delete this -void MainWindow::mouseMoveEvent(QMouseEvent *) -{ - //qDebug() << "mouseMoveEvent: x=" << e->globalX() << "y=" << e->globalY(); -} -#endif diff --git a/vrplayer/mainwindow.h b/vrplayer/mainwindow.h index ceddb683..802fd10d 100644 --- a/vrplayer/mainwindow.h +++ b/vrplayer/mainwindow.h @@ -80,7 +80,6 @@ protected: void resizeEvent(QResizeEvent *e); void closeEvent(QCloseEvent *e); void moveEvent(QMoveEvent *e); - void mouseMoveEvent(QMouseEvent *e); private: Ui::MainWindow *ui; diff --git a/vrplayer/ourinterface.cpp b/vrplayer/ourinterface.cpp index fb4ad3dc..094a84f7 100644 --- a/vrplayer/ourinterface.cpp +++ b/vrplayer/ourinterface.cpp @@ -53,7 +53,7 @@ void OurInterface::initRemoteClient() xrdpvr_play_media(channel, 101, filename.toAscii().data()); xrdpvr_get_media_duration(&start_time, &duration); - qDebug() << "ourInterface:initRemoteClient: emit onMediaDurationInSecs: dur=" << duration; + //qDebug() << "ourInterface:initRemoteClient: emit onMediaDurationInSecs: dur=" << duration; emit onMediaDurationInSeconds(duration); /* LK_TODO this needs to be undone in deinitRemoteClient() */ @@ -180,7 +180,7 @@ void OurInterface::onGeometryChanged(int x, int y, int width, int height) savedGeometry.setWidth(width); savedGeometry.setHeight(height); -#if 1 +#if 0 qDebug() << "OurInterface:signal" << "" << savedGeometry.x() << "" << savedGeometry.y() << @@ -188,8 +188,6 @@ void OurInterface::onGeometryChanged(int x, int y, int width, int height) "" << savedGeometry.height(); #endif - qDebug() << "setting geometry:channel=" << channel; - if (channel) { xrdpvr_set_geometry(channel, 101, savedGeometry.x(), savedGeometry.y(), diff --git a/vrplayer/playvideo.cpp b/vrplayer/playvideo.cpp index 40ddbf29..e1a7ec90 100644 --- a/vrplayer/playvideo.cpp +++ b/vrplayer/playvideo.cpp @@ -105,6 +105,11 @@ label1: } } +void PlayVideo::onMediaRestarted() +{ + elapsedTime = av_gettime(); +} + void PlayVideo::onMediaSeek(int value) { posMutex.lock(); @@ -125,7 +130,7 @@ void PlayVideo::updateMediaPos() posMutex.lock(); if (la_seekPos >= 0) { - qDebug() << "seeking to" << la_seekPos; + //qDebug() << "seeking to" << la_seekPos; xrdpvr_seek_media(la_seekPos, 0); elapsedTime = av_gettime() - la_seekPos * 1000000; la_seekPos = -1; @@ -164,7 +169,7 @@ void DecoderThread::updateSlider() mutex.lock(); if (la_seekPos >= 0) { - qDebug() << "seeking to" << la_seekPos; + //qDebug() << "seeking to" << la_seekPos; //audioTimer->stop(); //videoTimer->stop(); xrdpvr_seek_media(la_seekPos, 0); diff --git a/vrplayer/playvideo.h b/vrplayer/playvideo.h index e5f68b5e..2ae183b5 100644 --- a/vrplayer/playvideo.h +++ b/vrplayer/playvideo.h @@ -43,6 +43,7 @@ public: void onMediaSeek(int value); void setVcrOp(int op); + void onMediaRestarted(); public slots: void play(); diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile index 7373f51a..755af882 100644 --- a/xorg/X11R7.6/rdp/Makefile +++ b/xorg/X11R7.6/rdp/Makefile @@ -4,6 +4,7 @@ INCBASE = $(X11RDPBASE)/include LIBBASE = $(X11RDPBASE)/lib +INSTALL = /usr/bin/install -c XSRCBASE = ../build_dir/xorg-server-1.9.3 OBJS = rdpmain.o rdpdraw.o rdpinput.o rdpmisc.o rdpup.o rdprandr.o \ @@ -12,7 +13,7 @@ rdpPolylines.o rdpPolySegment.o rdpFillSpans.o rdpSetSpans.o \ rdpCopyPlane.o rdpPolyPoint.o rdpPolyArc.o rdpFillPolygon.o \ rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o \ rdpImageText8.o rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o \ -rdpPushPixels.o \ +rdpPushPixels.o rdpxv.o \ miinitext.o \ fbcmap_mi.o @@ -109,3 +110,6 @@ fbcmap.o: ../build_dir/xorg-server-1.9.3/fb/fbcmap.c fbcmap_mi.o: ../build_dir/xorg-server-1.9.3/fb/fbcmap_mi.c $(CC) $(CFLAGS) -c ../build_dir/xorg-server-1.9.3/fb/fbcmap_mi.c + +install: all + $(INSTALL) X11rdp $(X11RDPBASE)/bin/X11rdp diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index ae08f38d..22dcdbf7 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -525,6 +525,9 @@ rdpup_check_dirty_screen(rdpPixmapRec* pDirtyPriv); void rdpScheduleDeferredUpdate(void); +int +rdpXvInit(ScreenPtr pScreen); + #if defined(X_BYTE_ORDER) # if X_BYTE_ORDER == X_LITTLE_ENDIAN # define L_ENDIAN diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c index 2254f128..ffb43d1f 100644 --- a/xorg/X11R7.6/rdp/rdpmain.c +++ b/xorg/X11R7.6/rdp/rdpmain.c @@ -527,6 +527,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) } + //rdpXvInit(pScreen); + ErrorF("rdpScreenInit: ret %d\n", ret); return ret; diff --git a/xorg/X11R7.6/rdp/rdpxv.c b/xorg/X11R7.6/rdp/rdpxv.c new file mode 100644 index 00000000..d0ce8345 --- /dev/null +++ b/xorg/X11R7.6/rdp/rdpxv.c @@ -0,0 +1,448 @@ +/* +Copyright 2013 Jay Sorg + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +XVideo extension + +*/ + +#include "rdp.h" + +#include +#include +#include "xvdix.h" + +#include + +extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ + +static DevPrivateKey g_XvScreenKey; +static char g_xv_adaptor_name[] = "xrdp XVideo adaptor"; +static char g_xv_encoding_name[] = "XV_IMAGE"; + +#define GET_XV_SCREEN(pScreen) \ + ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, g_XvScreenKey)) + +#define LOG_LEVEL 1 +#define LLOG(_level, _args) \ + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) +#define LLOGLN(_level, _args) \ + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + +#define T_NUM_ENCODINGS 1 +static XvEncodingRec g_encodings[T_NUM_ENCODINGS]; + +#define T_NUM_FORMATS 1 +static XvFormatRec g_formats[T_NUM_FORMATS]; + +#define T_NUM_PORTS 1 +static XvPortRec g_ports[T_NUM_PORTS]; + +#define FOURCC_RV15 0x35315652 +#define FOURCC_RV16 0x36315652 +#define FOURCC_RV24 0x34325652 +#define FOURCC_RV32 0x32335652 + +#define T_NUM_IMAGES 8 +static XvImageRec g_images[T_NUM_IMAGES] = +{ + { + FOURCC_RV15,XvRGB,LSBFirst, + {'R','V','1','5',0,0,0,0,0,0,0,0,0,0,0,0}, + 16, XvPacked, 1, 15, 0x001f, 0x03e0, 0x7c00, 0, 0, 0, 0, 0, 0, 0, 0, 0, + {'R','V','B',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { + FOURCC_RV16,XvRGB,LSBFirst, + {'R','V','1','6',0,0,0,0,0,0,0,0,0,0,0,0}, + 16, XvPacked, 1, 16, 0x001f, 0x07e0, 0xf800, 0, 0, 0, 0, 0, 0, 0, 0, 0, + {'R','V','B',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { + FOURCC_RV24,XvRGB,LSBFirst, + {'R','V','2','4',0,0,0,0,0,0,0,0,0,0,0,0}, + 32, XvPacked, 1, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, + {'R','V','B',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { + FOURCC_RV32, XvRGB, LSBFirst, + {'R','V','3','2',0,0,0,0,0,0,0,0,0,0,0,0}, + 32, XvPacked, 1, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, + {'R','V','B',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + XVIMAGE_YV12, + XVIMAGE_YUY2, + XVIMAGE_UYVY, + XVIMAGE_I420 +}; + +/*****************************************************************************/ +static int +rdpXvAllocatePort(unsigned long port, XvPortPtr pPort, XvPortPtr* ppPort) +{ + LLOGLN(0, ("rdpXvAllocatePort:")); + *ppPort = pPort; + return Success; +} + +/*****************************************************************************/ +static int +rdpXvFreePort(XvPortPtr pPort) +{ + LLOGLN(0, ("rdpXvFreePort:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvPutVideo(ClientPtr client, DrawablePtr pDraw, XvPortPtr pPort, GCPtr pGC, + INT16 vid_x, INT16 vid_y, CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) +{ + LLOGLN(0, ("rdpXvPutVideo:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvPutStill(ClientPtr client, DrawablePtr pDraw, XvPortPtr pPort, GCPtr pGC, + INT16 vid_x, INT16 vid_y, CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) +{ + LLOGLN(0, ("rdpXvPutStill:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvGetVideo(ClientPtr client, DrawablePtr pDraw, XvPortPtr pPort, GCPtr pGC, + INT16 vid_x, INT16 vid_y, CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) +{ + LLOGLN(0, ("rdpXvGetVideo:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvGetStill(ClientPtr client, DrawablePtr pDraw, XvPortPtr pPort, GCPtr pGC, + INT16 vid_x, INT16 vid_y, CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) +{ + LLOGLN(0, ("rdpXvGetStill:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvStopVideo(ClientPtr client, XvPortPtr pPort, DrawablePtr pDraw) +{ + LLOGLN(0, ("rdpXvStopVideo:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvSetPortAttribute(ClientPtr client, XvPortPtr pPort, Atom attribute, + INT32 value) +{ + LLOGLN(0, ("rdpXvxSetPortAttribute:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvGetPortAttribute(ClientPtr client, XvPortPtr pPort, Atom attribute, + INT32* p_value) +{ + LLOGLN(0, ("rdpXvGetPortAttribute:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvQueryBestSize(ClientPtr client, XvPortPtr pPort, CARD8 motion, + CARD16 vid_w, CARD16 vid_h, CARD16 drw_w, CARD16 drw_h, + unsigned int *p_w, unsigned int *p_h) +{ + LLOGLN(0, ("rdpXvQueryBestSize:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvPutImage(ClientPtr client, DrawablePtr pDraw, XvPortPtr pPort, GCPtr pGC, + INT16 src_x, INT16 src_y, CARD16 src_w, CARD16 src_h, + INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h, + XvImagePtr format, unsigned char* data, Bool sync, + CARD16 width, CARD16 height) +{ + LLOGLN(0, ("rdpXvPutImage:")); + return Success; +} + +/*****************************************************************************/ +static int +rdpXvPrintFormat(int id) +{ + switch (id) + { + case FOURCC_YV12: + /* big buck bunny 480p h264 */ + /* vob files too */ + LLOGLN(0, ("FOURCC_YV12")); + break; + case FOURCC_I420: + LLOGLN(0, ("FOURCC_I420")); + break; + case FOURCC_RV15: + LLOGLN(0, ("FOURCC_RV15")); + break; + case FOURCC_RV16: + LLOGLN(0, ("FOURCC_RV16")); + break; + case FOURCC_YUY2: + LLOGLN(0, ("FOURCC_YUY2")); + break; + case FOURCC_UYVY: + LLOGLN(0, ("FOURCC_UYVY")); + break; + case FOURCC_RV24: + LLOGLN(0, ("FOURCC_RV24")); + break; + default: + LLOGLN(0, ("other")); + break; + } + return 0; +} + +/*****************************************************************************/ +static int +rdpXvQueryImageAttributes(ClientPtr client, XvPortPtr pPort, XvImagePtr format, + CARD16* width, CARD16* height, int* pitches, + int* offsets) +{ + int size; + int tmp; + + LLOGLN(0, ("rdpXvQueryImageAttributes:")); + + + size = 0; + /* this is same code as all drivers currently have */ + if (*width > 2046) + { + *width = 2046; + } + if (*height > 2046) + { + *height = 2046; + } + /* make w multiple of 4 so that resizing works properly */ + *width = (*width + 3) & ~3; + if (offsets) + { + offsets[0] = 0; + } + LLOGLN(0, ("format %x", format->id)); + rdpXvPrintFormat(format->id); + switch (format->id) + { + case FOURCC_YV12: + case FOURCC_I420: + /* make h be even */ + *height = (*height + 1) & ~1; + /* make w be multiple of 4 (ie. pad it) */ + size = (*width + 3) & ~3; + /* width of a Y row => width of image */ + if (pitches != 0) + { + pitches[0] = size; + } + /* offset of U plane => w*h */ + size *= *height; + if (offsets != 0) + { + offsets[1] = size; + } + /* width of U, V row => width/2 */ + tmp = ((*width >> 1) +3) & ~3; + if (pitches != 0) + { + pitches[1] = pitches[2] = tmp; + } + /* offset of V => Y plane + U plane (w*h + w/2*h/2) */ + tmp *= (*height >> 1); + size += tmp; + size += tmp; + if (offsets != 0) + { + offsets[2] = size; + } + size += tmp; + break; + case FOURCC_RV15: + case FOURCC_RV16: + case FOURCC_YUY2: + case FOURCC_UYVY: + size = (*width) * 2; + if (pitches) + { + pitches[0] = size; + } + size *= *height; + break; + case FOURCC_RV24: + size = (*width) * 3; + if (pitches) + { + pitches[0] = size; + } + size *= *height; + break; + default: + LLOGLN(0, ("rdpXvQueryImageAttributes: error")); + break; + } + return size; +} + +/*****************************************************************************/ +static Bool +rdpXvCloseScreen(int i, ScreenPtr pScreen) +{ + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + + LLOGLN(0, ("rdpXvCloseScreen:")); + free(pxvs->pAdaptors); + return 0; +} + +/*****************************************************************************/ +static int +rdpXvQueryAdaptors(ScreenPtr pScreen, XvAdaptorPtr* p_pAdaptors, + int* p_nAdaptors) +{ + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + + LLOGLN(0, ("rdpXvQueryAdaptors:")); + *p_nAdaptors = pxvs->nAdaptors; + *p_pAdaptors = pxvs->pAdaptors; + return Success; +} + +#ifdef MITSHM +#endif + +/*****************************************************************************/ +static int +rdpXvInitAdaptors(ScreenPtr pScreen) +{ + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + XvAdaptorPtr pAdaptor; + + pAdaptor = malloc(sizeof(XvAdaptorRec)); + memset(pAdaptor, 0, sizeof(XvAdaptorRec)); + pAdaptor->type = XvInputMask | XvOutputMask | XvImageMask | + XvVideoMask | XvStillMask; + pAdaptor->pScreen = pScreen; + + pAdaptor->name = g_xv_adaptor_name; + + pAdaptor->nEncodings = T_NUM_ENCODINGS; + pAdaptor->pEncodings = g_encodings; + + pAdaptor->nFormats = T_NUM_FORMATS; + pAdaptor->pFormats = g_formats; + + pAdaptor->nImages = T_NUM_IMAGES; + pAdaptor->pImages = g_images; + + pAdaptor->nPorts = T_NUM_PORTS; + pAdaptor->pPorts = g_ports; + + pAdaptor->ddAllocatePort = rdpXvAllocatePort; + pAdaptor->ddFreePort = rdpXvFreePort; + pAdaptor->ddPutVideo = rdpXvPutVideo; + pAdaptor->ddPutStill = rdpXvPutStill; + pAdaptor->ddGetVideo = rdpXvGetVideo; + pAdaptor->ddGetStill = rdpXvGetStill; + pAdaptor->ddStopVideo = rdpXvStopVideo; + pAdaptor->ddSetPortAttribute = rdpXvSetPortAttribute; + pAdaptor->ddGetPortAttribute = rdpXvGetPortAttribute; + pAdaptor->ddQueryBestSize = rdpXvQueryBestSize; + pAdaptor->ddPutImage = rdpXvPutImage; + pAdaptor->ddQueryImageAttributes = rdpXvQueryImageAttributes; + + pxvs->pAdaptors = pAdaptor; + + memset(g_encodings, 0, sizeof(g_encodings)); + g_encodings[0].id = FakeClientID(0); + g_encodings[0].pScreen = pScreen; + g_encodings[0].name = g_xv_encoding_name; + g_encodings[0].width = 2046; + g_encodings[0].height = 2046; + g_encodings[0].rate.numerator = 1; + g_encodings[0].rate.denominator = 1; + + memset(g_formats, 0, sizeof(g_formats)); + g_formats[0].depth = g_rdpScreen.depth; + g_formats[0].visual = pScreen->rootVisual; + + memset(g_ports, 0, sizeof(g_ports)); + g_ports[0].id = FakeClientID(0); + g_ports[0].pAdaptor = pAdaptor; + g_ports[0].pNotify = 0; + g_ports[0].pDraw = 0; + g_ports[0].grab.id = 0; + g_ports[0].grab.client = 0; + g_ports[0].time = currentTime; + g_ports[0].devPriv.ptr = 0; + + pAdaptor->base_id = g_ports[0].id; + + AddResource(g_ports[0].id, XvRTPort, g_ports); + + pxvs->nAdaptors = 1; + pxvs->pAdaptors = pAdaptor; + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int +rdpXvInit(ScreenPtr pScreen) +{ + XvScreenPtr pxvs; + + LLOGLN(0, ("rdpXvInit:")); + XvScreenInit(pScreen); + g_XvScreenKey = XvGetScreenKey(); + pxvs = GET_XV_SCREEN(pScreen); + pxvs->nAdaptors = 0; + pxvs->ddCloseScreen = rdpXvCloseScreen; + pxvs->ddQueryAdaptors = rdpXvQueryAdaptors; + rdpXvInitAdaptors(pScreen); + return 0; +}