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 #include "mmsmedia/mmsav.h"
00034 #ifdef __HAVE_DIRECTFB__
00035 #include <directfb_version.h>
00036 #endif
00037 #include <string.h>
00038 #include <stdlib.h>
00039
00040 #include "mmsmedia/mmsgst.h"
00041
00042
00043 MMS_CREATEERROR(MMSAVError);
00044
00045
00046 #ifdef __HAVE_GSTREAMER__
00047
00048 static void* gstPlayRoutine(GST_DISKOVIDEOSINK_DATA *gst_diskovideosink_data) {
00049
00050 printf("uri %s\n", gst_diskovideosink_data->uri.c_str());
00051
00052 if (gst_diskovideosink_data->pipeline) {
00053
00054 mmsGstPlay(gst_diskovideosink_data->pipeline);
00055 }
00056
00057 return NULL;
00058 }
00059
00060 #endif
00061
00062
00063
00064
00065 #ifdef __HAVE_XINE__
00066
00067 #ifdef __HAVE_DIRECTFB__
00068 DFBResult dfbres;
00069 #define THROW_DFB_ERROR(dfbres,msg) {if (dfbres) { string s1 = msg; string s2 = DirectFBErrorString((DFBResult)dfbres); throw MMSAVError(dfbres,s1 + " [" + s2 + "]"); }else{ throw MMSAVError(0,msg); }}
00070 #endif
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 #ifdef __HAVE_DIRECTFB__
00085 static void dfb_output_cb(void *cdata, int width, int height, double ratio,
00086 DFBSurfacePixelFormat format, DFBRectangle* dest_rect) {
00087 VODESC *vodesc = (VODESC *) cdata;
00088 int newH, newW;
00089
00090
00091 if (vodesc->ratio != ratio) {
00092 newW = (int)((double)(vodesc->windsc.height) * ratio + 0.5);
00093 newH = (int)((double)(vodesc->windsc.width) / ratio + 0.5);
00094
00095
00096 if (ratio<1.0) {
00097 if(newW > vodesc->windsc.width) {
00098 vodesc->rect.w = vodesc->windsc.width;
00099 vodesc->rect.h = newH;
00100 } else {
00101 vodesc->rect.w = newW;
00102 vodesc->rect.h = vodesc->windsc.height;
00103 }
00104 vodesc->rect.x = (vodesc->windsc.width - vodesc->rect.w) / 2;
00105 vodesc->rect.y = 0;
00106 } else {
00107 if(newH > vodesc->windsc.height) {
00108 vodesc->rect.h = vodesc->windsc.height;
00109 vodesc->rect.w = newW;
00110 } else {
00111 vodesc->rect.w = vodesc->windsc.width;
00112 vodesc->rect.h = newH;
00113 }
00114 vodesc->rect.x = 0;
00115 vodesc->rect.y = (vodesc->windsc.height - vodesc->rect.h) / 2;
00116 }
00117
00118
00119 vodesc->format = format;
00120 vodesc->ratio = ratio;
00121 vodesc->width = width;
00122 vodesc->height = height;
00123
00124 vodesc->winsurface->clear();
00125 vodesc->winsurface->flip();
00126 vodesc->winsurface->clear();
00127 }
00128
00129
00130 *dest_rect=(DFBRectangle&)vodesc->rect;
00131
00132
00133 }
00134 #endif
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void raw_frame_cb(void *user_data, int frame_format, int frame_width, int frame_height, double frame_aspect, void *data0, void *data1, void *data2) {
00155 MMSRAW_USERDATA *userd =(MMSRAW_USERDATA *)user_data;
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 if(!userd) {
00167
00168 return;
00169 }
00170
00171 if (userd->lastaspect != frame_aspect) {
00172
00173 printf("format change %f\n", frame_aspect);
00174 int newW = (int)((double)(userd->size.h) * frame_aspect + 0.5);
00175 int newH = (int)((double)(userd->size.w) / frame_aspect + 0.5);
00176
00177
00178 if (frame_aspect<1.0) {
00179 if(newW > userd->size.w) {
00180 userd->dest.w = userd->size.w;
00181 userd->dest.h = newH;
00182 } else {
00183 userd->dest.w = newW;
00184 userd->dest.h = userd->size.w;
00185 }
00186
00187 userd->dest.x = (userd->size.w - userd->dest.w) / 2;
00188 userd->dest.y = 0;
00189 } else {
00190 if(newH > userd->size.h) {
00191 userd->dest.h = userd->size.h;
00192 userd->dest.w = newW;
00193 } else {
00194 userd->dest.w = userd->size.w;
00195 userd->dest.h = newH;
00196 }
00197 userd->dest.x = (userd->size.w - userd->dest.w) / 2;;
00198 userd->dest.y = (userd->size.h - userd->dest.h) / 2;
00199 }
00200
00201 userd->lastaspect = frame_aspect;
00202
00203 userd->surf->clear();
00204 userd->surf->flip(NULL);
00205 userd->surf->clear();
00206
00207
00208 userd->dest.w&=~0x01;
00209 userd->dest.h&=~0x01;
00210 userd->dest.x&=~0x01;
00211 userd->dest.y&=~0x01;
00212
00213
00214
00215 if (userd->interim) {
00216 delete userd->interim;
00217 userd->interim = NULL;
00218 }
00219 }
00220
00221
00222
00223
00224 static unsigned char rrrrr_buf[2048*768];
00225 static int rrrrr=0;
00226 if(!rrrrr) {
00227 rrrrr=1;
00228 for (int i = 0; i < sizeof(rrrrr_buf)/4; i++) {
00229 rrrrr_buf[i*4] = 0xff;
00230 rrrrr_buf[i*4+1] = 0x00;
00231 rrrrr_buf[i*4+2] = 0x00;
00232 rrrrr_buf[i*4+3] = 0x00;
00233 }
00234 }
00235 data0 = rrrrr_buf;
00236 frame_format = XINE_VORAW_YUY2;
00237
00238 */
00239
00240 if (userd->surf_pixelformat == MMSFB_PF_YV12) {
00241
00242 if ((frame_format != XINE_VORAW_YV12) && (!userd->interim)) {
00243
00244 switch (frame_format) {
00245 case XINE_VORAW_YUY2:
00246 case XINE_VORAW_RGB:
00247
00248 userd->interim = new MMSFBSurface(frame_width, frame_height, MMSFB_PF_YV12);
00249 break;
00250 }
00251 }
00252
00253 if (userd->interim) {
00254
00255 switch (frame_format) {
00256 case XINE_VORAW_YUY2:
00257
00258 userd->interim->blitBuffer(data0, frame_width*2, MMSFB_PF_YUY2,
00259 frame_width, frame_height, NULL, 0, 0);
00260 break;
00261 case XINE_VORAW_RGB:
00262
00263 userd->interim->blitBuffer(data0, frame_width*3, MMSFB_PF_RGB24,
00264 frame_width, frame_height, NULL, 0, 0);
00265 break;
00266 }
00267 userd->surf->stretchBlit(userd->interim, NULL, &userd->dest);
00268 } else {
00269
00270 MMSFBExternalSurfaceBuffer buf;
00271 buf.ptr = data0;
00272 buf.pitch = frame_width;
00273 buf.ptr2 = data1;
00274 buf.pitch2 = frame_width / 2;
00275 buf.ptr3 = data2;
00276 buf.pitch3 = frame_width / 2;
00277
00278 userd->surf->stretchBlitBuffer(&buf, MMSFB_PF_YV12,
00279 frame_width, frame_height, NULL, &userd->dest);
00280 }
00281 }
00282 else {
00283
00284 if (frame_format == XINE_VORAW_YV12) {
00285
00286 if (!userd->interim) {
00287
00288 userd->interim = new MMSFBSurface(userd->dest.w, userd->dest.h, MMSFB_PF_YV12);
00289 if (userd->interim) userd->interim->setBlittingFlags(MMSFB_BLIT_ANTIALIASING);
00290 }
00291 }
00292
00293 if (userd->interim) {
00294
00295 MMSFBExternalSurfaceBuffer buf;
00296 buf.ptr = data0;
00297 buf.pitch = frame_width;
00298 buf.ptr2 = data1;
00299 buf.pitch2 = frame_width / 2;
00300 buf.ptr3 = data2;
00301 buf.pitch3 = frame_width / 2;
00302 MMSFBRectangle mydest = userd->dest;
00303 mydest.x = 0;
00304 mydest.y = 0;
00305
00306 userd->interim->stretchBlitBuffer(&buf, MMSFB_PF_YV12,
00307 frame_width, frame_height, NULL, &mydest);
00308 userd->surf->blit(userd->interim, NULL, userd->dest.x, userd->dest.y);
00309
00310 } else {
00311
00312 userd->surf->stretchBlitBuffer(data0, frame_width*3, MMSFB_PF_RGB24,
00313 frame_width, frame_height, NULL, &userd->dest);
00314 }
00315 }
00316
00317
00318 if(userd->numOverlays > 0) {
00319 int rw = (userd->dest.w << 10) / frame_width;
00320 int rh = (userd->dest.h << 10) / frame_height;
00321
00322
00323 MMSFBBlittingFlags saved_flags;
00324 userd->surf->getBlittingFlags(&saved_flags);
00325 userd->surf->setBlittingFlags(MMSFB_BLIT_BLEND_ALPHACHANNEL | MMSFB_BLIT_ANTIALIASING);
00326
00327 if (!userd->overlayInterim) {
00328
00329 userd->overlayInterim = new MMSFBSurface(userd->size.w, userd->size.h, MMSFB_PF_ARGB);
00330 }
00331
00332
00333 for (int i = 0; i < userd->numOverlays; ++i) {
00334
00335 raw_overlay_t *ovl = &(userd->overlays[i]);
00336
00337
00338 int x = (ovl->ovl_x * rw) >> 10;
00339 if(userd->size.w > userd->dest.w) {
00340 x += (userd->size.w - userd->dest.w) >> 1;
00341 }
00342 int y = (ovl->ovl_y * rh) >> 10;
00343 if(userd->size.h > userd->dest.h) {
00344 y += (userd->size.h - userd->dest.h) >> 1;
00345 }
00346
00347
00348 MMSFBRectangle dest_rect;
00349 dest_rect.x = 0;
00350 dest_rect.y = 0;
00351 dest_rect.w = (ovl->ovl_w * rw) >> 10;
00352 dest_rect.h = (ovl->ovl_h * rh) >> 10;
00353 userd->overlayInterim->stretchBlitBuffer(ovl->ovl_rgba, ovl->ovl_w * 4, MMSFB_PF_ARGB, ovl->ovl_w, ovl->ovl_h, NULL, &dest_rect);
00354
00355
00356 userd->surf->blit(userd->overlayInterim, &dest_rect, x, y);
00357 }
00358
00359
00360 userd->surf->setBlittingFlags(saved_flags);
00361 }
00362
00363 userd->surf->flip(NULL);
00364 }
00365
00366
00367
00368
00369 void raw_overlay_cb(void *user_data, int num_ovl, raw_overlay_t *overlays_array) {
00370 MMSRAW_USERDATA *userd =(MMSRAW_USERDATA *)user_data;
00371
00372 userd->numOverlays = num_ovl;
00373 userd->overlays = overlays_array;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 #ifdef __HAVE_DIRECTFB__
00385 #if DIRECTFB_MAJOR_VERSION == 1
00386 static void dfb_frame_cb(void *cdata) {
00387 #else
00388 static int dfb_frame_cb(void *cdata) {
00389 #endif
00390 VODESC *vodesc = (VODESC *) cdata;
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 vodesc->winsurface->flip();
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 #if DIRECTFB_MAJOR_VERSION < 1
00444 return 0;
00445 #endif
00446 }
00447 #endif
00448
00449 typedef struct {
00450 xine_stream_t *stream;
00451 int pos;
00452 short *status;
00453 const char *mrl;
00454 pthread_mutex_t *lock;
00455 } internalStreamData;
00456
00457 static void* xinePlayRoutine(void *data) {
00458 if(!data) return NULL;
00459
00460 internalStreamData *streamData = (internalStreamData*)data;
00461
00462 pthread_mutex_lock(streamData->lock);
00463 if(*(streamData->status) == MMSAV::STATUS_PLAYING)
00464 xine_stop(streamData->stream);
00465
00466 if(*(streamData->status) > MMSAV::STATUS_NONE)
00467 xine_close(streamData->stream);
00468
00469 if(!xine_open(streamData->stream, streamData->mrl) || !xine_play(streamData->stream, streamData->pos, 0)) {
00470 switch(xine_get_error(streamData->stream)) {
00471 case XINE_ERROR_NO_INPUT_PLUGIN :
00472 DEBUGMSG("MMSAV", "Error while trying to play stream: No input plugin");
00473 break;
00474 case XINE_ERROR_NO_DEMUX_PLUGIN :
00475 DEBUGMSG("MMSAV", "Error while trying to play stream: No demux plugin");
00476 break;
00477 case XINE_ERROR_DEMUX_FAILED :
00478 DEBUGMSG("MMSAV", "Error while trying to play stream: Error in demux plugin");
00479 break;
00480 case XINE_ERROR_INPUT_FAILED :
00481 DEBUGMSG("MMSAV", "Error while trying to play stream: Error in input plugin");
00482 break;
00483 case XINE_ERROR_MALFORMED_MRL :
00484 DEBUGMSG("MMSAV", "Error while trying to play stream: Malformed MRL");
00485 break;
00486 default:
00487 DEBUGMSG("MMSAV", "Unknown error while trying to play stream");
00488 break;
00489 }
00490 *(streamData->status) = MMSAV::STATUS_NONE;
00491 }
00492 else
00493 *(streamData->status) = MMSAV::STATUS_PLAYING;
00494
00495 pthread_mutex_unlock(streamData->lock);
00496 delete streamData;
00497
00498 return NULL;
00499 }
00500
00501 static void* stopRoutine(void *data) {
00502 if(!data) return NULL;
00503
00504 internalStreamData *streamData = (internalStreamData*)data;
00505 pthread_mutex_lock(streamData->lock);
00506 xine_stop(streamData->stream);
00507 xine_set_param(streamData->stream, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
00508 xine_close(streamData->stream);
00509 *(streamData->status) = MMSAV::STATUS_STOPPED;
00510 pthread_mutex_unlock(streamData->lock);
00511 delete streamData;
00512
00513 return NULL;
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 void MMSAV::xineInit() {
00527
00528 if (!(this->xine = xine_new()))
00529 throw MMSAVError(0, "Cannot get a new xine object");
00530
00531
00532 string cfg;
00533 if(getenv("XINERC"))
00534 cfg = getenv("XINERC");
00535 else {
00536 if (getenv("HOME"))
00537 cfg = string(getenv("HOME")) + "/.xine";
00538 else
00539 cfg = "~/.xine";
00540 mkdir(cfg.c_str(), 755);
00541 cfg = cfg + "/config";
00542 }
00543 xine_config_load(this->xine, cfg.c_str());
00544
00545
00546 xine_init(this->xine);
00547
00548
00549 if(this->verbose)
00550 xine_engine_set_param(this->xine, XINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG);
00551 else
00552 xine_engine_set_param(this->xine, XINE_PARAM_VERBOSITY, XINE_VERBOSITY_NONE);
00553 }
00554
00555
00556 #endif
00557
00558
00559 bool MMSAV::onHandleInput(MMSWindow *window, MMSInputEvent *input) {
00560
00561 return sendEvent(input);
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 void MMSAV::initialize(const bool verbose, MMSWindow *window) {
00582 this->verbose = verbose;
00583 this->window = window;
00584
00585 onHandleInputConnection.disconnect();
00586 if (window)
00587 onHandleInputConnection = window->onHandleInput->connect(sigc::mem_fun(this,&MMSAV::onHandleInput));
00588
00589
00590 if (this->backend == MMSMEDIA_BE_GST) {
00591 #ifdef __HAVE_GSTREAMER__
00592
00593
00594 #endif
00595 }
00596 else {
00597 #ifdef __HAVE_XINE__
00598
00599 DEBUGMSG("MMSMedia", "xineInit()...");
00600
00601
00602 xineInit();
00603
00604
00605 DEBUGMSG("MMSMedia", "xineInit() done.");
00606
00607 memset(&this->userd, 0, sizeof(this->userd));
00608
00609 if (mmsfb->getBackend() != MMSFB_BE_DFB) {
00610 this->rawvisual.raw_output_cb = raw_frame_cb;
00611 this->rawvisual.supported_formats = XINE_VORAW_YV12;
00612 if(window) {
00613 this->rawvisual.user_data = (void *)&(this->userd);
00614 this->rawvisual.raw_overlay_cb = raw_overlay_cb;
00615 } else {
00616 this->rawvisual.user_data = NULL;
00617 }
00618 }
00619 else {
00620 #ifdef __HAVE_DIRECTFB__
00621 this->vodesc.format = DSPF_UNKNOWN;
00622 this->vodesc.ratio = 1.25;
00623 this->vodesc.width = 720;
00624 this->vodesc.height = 576;
00625 this->vodesc.rect.x = 0;
00626 this->vodesc.rect.y = 0;
00627
00628 if(window) {
00629 window->getSurface()->getSize(&(this->vodesc.windsc.width), &(this->vodesc.windsc.height));
00630 this->vodesc.winsurface = window->getSurface();
00631 if(!this->vodesc.winsurface->clear())
00632 THROW_DFB_ERROR(dfbres, "MMSFBSurface::clear() failed");
00633 if(!this->vodesc.winsurface->flip())
00634 THROW_DFB_ERROR(dfbres, "MMSFBSurface::flip() failed");
00635 }
00636 this->vodesc.rect.w = this->vodesc.windsc.width;
00637 this->vodesc.rect.h = (int)((double)(this->vodesc.windsc.width) / this->vodesc.ratio + 0.5);
00638 #endif
00639 }
00640
00641
00642
00643
00644 if (mmsfb->getBackend() != MMSFB_BE_DFB) {
00645 if(window) {
00646 this->userd.surf=window->getSurface();
00647 this->userd.surf->setBlittingFlags(MMSFB_BLIT_ANTIALIASING);
00648 this->userd.surf->getPixelFormat(&this->userd.surf_pixelformat);
00649 int w,h;
00650 this->userd.surf->getSize(&w,&h);
00651 this->userd.size.x=0;
00652 this->userd.size.y=0;
00653 this->userd.size.w=w;
00654 this->userd.size.h=h;
00655 this->userd.lastaspect=0.0;
00656 this->userd.interim = NULL;
00657 this->userd.overlayInterim = NULL;
00658 this->userd.numOverlays = 0;
00659 this->userd.overlays = NULL;
00660 }
00661 DEBUGMSG("MMSMedia", "opening video driver...");
00662
00663 if (!(this->vo = xine_open_video_driver(this->xine, "raw",
00664 XINE_VISUAL_TYPE_RAW, (void*) &this->rawvisual)))
00665 throw MMSAVError(0, "Cannot open the XINE RAW video driver");
00666 }
00667 else {
00668 #ifdef __HAVE_DIRECTFB__
00669 if(window) {
00670 if(((IDirectFBSurface *)vodesc.winsurface->getDFBSurface())->SetBlittingFlags((IDirectFBSurface *)vodesc.winsurface->getDFBSurface(), DSBLIT_NOFX) != DFB_OK)
00671 DEBUGMSG("MMSMedia", "set blitting failed");
00672
00673 this->visual.destination = (IDirectFBSurface *)vodesc.winsurface->getDFBSurface();
00674 }
00675 else
00676 this->visual.destination = NULL;
00677 this->visual.subpicture = NULL;
00678 this->visual.output_cb = dfb_output_cb;
00679 this->visual.output_cdata = (void*) &(this->vodesc);
00680 this->visual.frame_cb = dfb_frame_cb;
00681 this->visual.frame_cdata = (void*) &(this->vodesc);
00682
00683 DEBUGMSG("MMSMedia", "opening video driver...");
00684 if (!(this->vo = xine_open_video_driver(this->xine, "DFB",
00685 XINE_VISUAL_TYPE_DFB, (void*) &this->visual)))
00686 throw MMSAVError(0, "Cannot open the DFB video driver, please install directfb extras!");
00687 #endif
00688 }
00689 DEBUGMSG("MMSMedia", "opening video driver done.");
00690
00691
00692
00693 const char* const *ao_list;
00694 int i = 0;
00695 if(!(ao_list = xine_list_audio_output_plugins(this->xine)) || !*ao_list) {
00696 DEBUGMSG("MMSMedia", "No audio output plugins found");
00697 xine_engine_set_param(this->xine, XINE_PARAM_IGNORE_AUDIO, 1);
00698 this->ao=NULL;
00699 return;
00700 }
00701 do {
00702 DEBUGMSG("MMSMedia", "checking audio output '%s'...", ao_list[i]);
00703
00704
00705 if(strcmp(ao_list[i], "file") == 0) {
00706 i++;
00707 continue;
00708 }
00709 else if(strcmp(ao_list[i], "none") == 0)
00710 {
00711
00712 xine_engine_set_param(this->xine, XINE_PARAM_IGNORE_AUDIO, 1);
00713 DEBUGMSG("MMSMedia", "Could not open audio driver, sound disabled!");
00714 break;
00715 }
00716
00717 DEBUGMSG("MMSMedia", "opening audio output '%s'", ao_list[i]);
00718 }
00719 while(!(this->ao = xine_open_audio_driver(this->xine, ao_list[i++], NULL)));
00720
00721 DEBUGMSG("MMSMedia", "Using audio driver '%s'", ao_list[i-1]);
00722
00723 #endif
00724 }
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 MMSAV::MMSAV(MMSMEDIABackend _backend) :
00741 backend(_backend),
00742 window(NULL),
00743 surface(NULL),
00744 verbose(false),
00745 status(STATUS_NONE),
00746 pos(0)
00747 #ifdef __HAVE_XINE__
00748 , xine(NULL)
00749 , vo(NULL)
00750 , ao(NULL)
00751 , stream(NULL)
00752 , queue(NULL)
00753 #endif
00754 {
00755
00756 this->onError = new sigc::signal<void, string>;
00757 this->onStatusChange = new sigc::signal<void, const unsigned short, const unsigned short>;
00758
00759 switch(this->backend) {
00760 case MMSMEDIA_BE_GST:
00761 #ifdef __HAVE_GSTREAMER__
00762 gst_diskovideosink_data.uri = "";
00763 gst_diskovideosink_data.pipeline = NULL;
00764 break;
00765 #else
00766 cerr << "MMSAV: Disko was build without gstreamer support. Switching to xine." << endl;
00767 this->backend = MMSMEDIA_BE_XINE;
00768 break;
00769 #endif
00770 case MMSMEDIA_BE_XINE:
00771 #ifdef __HAVE_XINE__
00772 pthread_mutex_init(&this->lock, NULL);
00773 #else
00774 cerr << "MMSAV: Disko was build without xine support. Switching to gstreamer." << endl;
00775 this->backend = MMSMEDIA_BE_GST;
00776 break;
00777 #endif
00778 default:
00779
00780 break;
00781 }
00782 }
00783
00784
00785
00786
00787
00788
00789
00790 MMSAV::~MMSAV() {
00791 onHandleInputConnection.disconnect();
00792
00793 if(this->onError) {
00794 this->onError->clear();
00795 delete this->onError;
00796 }
00797
00798 if(this->onStatusChange) {
00799 this->onStatusChange->clear();
00800 delete this->onStatusChange;
00801 }
00802
00803 if (this->backend == MMSMEDIA_BE_GST) {
00804 #ifdef __HAVE_GSTREAMER__
00805 mmsGstFree();
00806 #endif
00807 }
00808 else {
00809 #ifdef __HAVE_XINE__
00810 pthread_mutex_destroy(&this->lock);
00811
00812
00813 if(this->queue)
00814 xine_event_dispose_queue(this->queue);
00815 if(this->stream)
00816 xine_dispose(this->stream);
00817 if(this->ao)
00818 xine_close_audio_driver(this->xine, this->ao);
00819 if(this->vo)
00820 xine_close_video_driver(this->xine, this->vo);
00821
00822
00823 map<string, xine_post_t*>::const_iterator i;
00824 for(i = audioPostPlugins.begin(); i != audioPostPlugins.end(); ++i)
00825 xine_post_dispose(this->xine, i->second);
00826 audioPostPlugins.erase(audioPostPlugins.begin(), audioPostPlugins.end());
00827
00828 for(i = videoPostPlugins.begin(); i != videoPostPlugins.end(); ++i)
00829 xine_post_dispose(this->xine, i->second);
00830 videoPostPlugins.erase(videoPostPlugins.begin(), videoPostPlugins.end());
00831
00832
00833 xine_exit(this->xine);
00834
00835 if (this->userd.interim) {
00836
00837 delete this->userd.interim;
00838 }
00839
00840 if (this->userd.overlayInterim) {
00841
00842 delete this->userd.overlayInterim;
00843 }
00844 #endif
00845 }
00846 }
00847
00848 #ifdef __HAVE_XINE__
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 void MMSAV::xineOpen(xine_event_listener_cb_t queue_cb, void *userData) {
00871 if(this->stream) {
00872 DEBUGMSG("MMSAV", "xine stream already present, skipping xineOpen");
00873 return;
00874 }
00875
00876
00877 if (!(this->stream = xine_stream_new(this->xine, this->ao, this->vo)))
00878 throw MMSAVError(0, "Cannot get a new stream");
00879
00880
00881 for(map<string, xine_post_t*>::const_iterator i = videoPostPlugins.begin(); i != videoPostPlugins.end(); ++i)
00882 xine_post_wire_video_port(xine_get_video_source(stream), i->second->video_input[0]);
00883 for(map<string, xine_post_t*>::const_iterator i = audioPostPlugins.begin(); i != audioPostPlugins.end(); ++i)
00884 xine_post_wire_audio_port(xine_get_audio_source(stream), i->second->audio_input[0]);
00885
00886
00887 if(this->verbose)
00888 xine_set_param(this->stream, XINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG);
00889 else
00890 xine_set_param(this->stream, XINE_PARAM_VERBOSITY, XINE_VERBOSITY_NONE);
00891
00892
00893
00894
00895 if(this->ao) {
00896 xine_set_param(this->stream, XINE_PARAM_AUDIO_MUTE, false);
00897 xine_set_param(this->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -1);
00898 }
00899
00900
00901 if(queue_cb) {
00902 this->queue = xine_event_new_queue(this->stream);
00903 if(this->queue)
00904 xine_event_create_listener_thread(this->queue, queue_cb, userData);
00905 else
00906 DEBUGMSG("MMSMedia", "Could not create event listener");
00907 }
00908 }
00909
00910 #endif
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 bool MMSAV::registerAudioPostPlugin(string name) {
00922 if (this->backend == MMSMEDIA_BE_GST) {
00923 #ifdef __HAVE_GSTREAMER__
00924 return true;
00925 #endif
00926 }
00927 else {
00928 #ifdef __HAVE_XINE__
00929 xine_post_t *p;
00930
00931 if(!(p = xine_post_init(this->xine, name.c_str(), 1, &this->ao, NULL)))
00932 DEBUGMSG("MMSMedia", "Could not initialize audio post plugin %s", name.c_str());
00933 else {
00934 audioPostPlugins[name] = p;
00935 return true;
00936 }
00937
00938 return false;
00939 #endif
00940 }
00941
00942 throw MMSAVError(0, "MMSAV::registerAudioPostPlugin() called but media backend does not match supported backends");
00943 }
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 bool MMSAV::registerVideoPostPlugin(string name) {
00955 if (this->backend == MMSMEDIA_BE_GST) {
00956 #ifdef __HAVE_GSTREAMER__
00957 return true;
00958 #endif
00959 }
00960 else {
00961 #ifdef __HAVE_XINE__
00962 xine_post_t *p;
00963
00964 if(!(p = xine_post_init(this->xine, name.c_str(), 1, NULL, &this->vo)))
00965 DEBUGMSG("MMSMedia", "Could not initialize video post plugin %s", name.c_str());
00966 else {
00967 videoPostPlugins[name] = p;
00968 return true;
00969 }
00970
00971 return false;
00972 #endif
00973 }
00974
00975 throw MMSAVError(0, "MMSAV::registerVideoPostPlugin() called but media backend does not match supported backends");
00976 }
00977
00978 #ifdef __HAVE_XINE__
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 bool MMSAV::setPostPluginParameter(map<string, xine_post_t*> plugins, string name, string parameter, string value) {
00990 xine_post_in_t *postIn;
00991 xine_post_api_t *postApi;
00992 xine_post_api_descr_t *postApiDesc;
00993 xine_post_api_parameter_t *postApiParam;
00994 char *data;
00995
00996
00997 if(!(postIn = (xine_post_in_t *)xine_post_input(plugins[name], "parameters"))) {
00998 DEBUGMSG("MMSMedia", "Could not set parameter for post plugin %s: Plugin not registered", name.c_str());
00999 return false;
01000 }
01001
01002 postApi = (xine_post_api_t *)postIn->data;
01003 postApiDesc = postApi->get_param_descr();
01004 postApiParam = postApiDesc->parameter;
01005 data = new char[postApiDesc->struct_size];
01006 postApi->get_parameters(plugins[name], (void*)data);
01007
01008 while(postApiParam->type != POST_PARAM_TYPE_LAST)
01009 {
01010 if(strToUpr(string(postApiParam->name)) == strToUpr(parameter)) {
01011 if(postApiParam->type == POST_PARAM_TYPE_INT) {
01012 int iValue = atoi(value.c_str());
01013
01014
01015 if(iValue == 0 && value.at(0) != '0') {
01016 for(int i = 0; postApiParam->enum_values[i]; i++) {
01017 if(value == postApiParam->enum_values[i]) {
01018 iValue = i;
01019 break;
01020 }
01021 }
01022 } else {
01023
01024 if(iValue < postApiParam->range_min || iValue > postApiParam->range_max) {
01025 DEBUGMSG("MMSMedia", "Could not set %s's %s to %s: Out of range", name.c_str(), parameter.c_str(), value.c_str());
01026 return false;
01027 }
01028 }
01029
01030
01031 *(int *)(data + postApiParam->offset) = iValue;
01032 DEBUGMSG("MMSMedia", "%s: %s = %s", name.c_str(), parameter.c_str(), postApiParam->enum_values[*(int *)(data + postApiParam->offset)]);
01033 }
01034 else if(postApiParam->type == POST_PARAM_TYPE_DOUBLE) {
01035 double dValue = atof(value.c_str());
01036
01037
01038 if(dValue < postApiParam->range_min || dValue > postApiParam->range_max) {
01039 DEBUGMSG("MMSMedia", "Could not set %s's %s to %s: Out of range", name.c_str(), parameter.c_str(), value.c_str());
01040 return false;
01041 }
01042
01043
01044 *(double *)(data + postApiParam->offset) = dValue;
01045 DEBUGMSG("MMSMedia", "%s: %s = %s", name.c_str(), parameter.c_str(), value.c_str());
01046 }
01047 else if(postApiParam->type == POST_PARAM_TYPE_BOOL) {
01048 bool bValue = false;
01049 if(value == "1" || strToUpr(value) == "TRUE")
01050 bValue = true;
01051 *(bool *)(data + postApiParam->offset) = bValue;
01052 DEBUGMSG("MMSMedia", "%s: = %s", name.c_str(), parameter.c_str(), (bValue ? "true" : "false"));
01053 }
01054 else if(postApiParam->type == POST_PARAM_TYPE_CHAR) {
01055 char cValue = value.at(0);
01056 *(char *)(data + postApiParam->offset) = cValue;
01057 DEBUGMSG("MMSMedia", "%s: %s = %c", name.c_str(), parameter.c_str(), cValue);
01058 }
01059 else if(postApiParam->type == POST_PARAM_TYPE_STRING) {
01060 char *sValue = (char*)value.c_str();
01061 *(char **)(data + postApiParam->offset) = sValue;
01062 DEBUGMSG("MMSMedia", "%s: %s = %s", name.c_str(), parameter.c_str(), sValue);
01063 }
01064 break;
01065 }
01066 postApiParam++;
01067 }
01068
01069 if(!postApi->set_parameters(plugins[name], (void *)data))
01070 DEBUGMSG("MMSMedia", "Error setting post plugin parameter");
01071
01072 delete[] data;
01073
01074 return true;
01075 }
01076 #endif
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 bool MMSAV::setAudioPostPluginParameter(string name, string parameter, string value) {
01091 if (this->backend == MMSMEDIA_BE_GST) {
01092 #ifdef __HAVE_GSTREAMER__
01093 return true;
01094 #endif
01095 }
01096 else {
01097 #ifdef __HAVE_XINE__
01098 return setPostPluginParameter(this->audioPostPlugins, name, parameter, value);
01099 #endif
01100 }
01101
01102 throw MMSAVError(0, "MMSAV::setAudioPostPluginParameter() called but media backend does not match supported backends");
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 bool MMSAV::setVideoPostPluginParameter(string name, string parameter, string value) {
01118 if (this->backend == MMSMEDIA_BE_GST) {
01119 #ifdef __HAVE_GSTREAMER__
01120 return true;
01121 #endif
01122 }
01123 else {
01124 #ifdef __HAVE_XINE__
01125 return setPostPluginParameter(this->videoPostPlugins, name, parameter, value);
01126 #endif
01127 }
01128
01129 throw MMSAVError(0, "MMSAV::setVideoPostPluginParameter() called but media backend does not match supported backends");
01130 }
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144 void MMSAV::setStatus(int status) {
01145 switch(status) {
01146 case STATUS_PLAYING :
01147 if(this->status != this->STATUS_NONE)
01148 this->onStatusChange->emit(this->status, status);
01149 this->status = status;
01150 return;
01151 case STATUS_PAUSED :
01152 case STATUS_STOPPED :
01153 case STATUS_FFWD :
01154 case STATUS_FFWD2 :
01155 case STATUS_SLOW :
01156 case STATUS_SLOW2 :
01157 this->onStatusChange->emit(this->status, status);
01158 this->status = status;
01159 return;
01160 default:
01161 break;
01162 }
01163
01164 this->onStatusChange->emit(status, status);
01165 }
01166
01167
01168
01169
01170
01171
01172 bool MMSAV::isPlaying() {
01173 switch(this->backend) {
01174 case MMSMEDIA_BE_GST:
01175 #ifdef __HAVE_GSTREAMER__
01176 return (this->status == STATUS_PLAYING);
01177 #endif
01178 break;
01179 case MMSMEDIA_BE_XINE:
01180 #ifdef __HAVE_XINE__
01181 if(this->status == STATUS_PLAYING) {
01182 if(xine_get_status(this->stream)!=XINE_STATUS_PLAY) {
01183 this->setStatus(STATUS_STOPPED);
01184 return false;
01185 }
01186 else return true;
01187 }
01188 return false;
01189 #endif
01190 break;
01191 default:
01192
01193 break;
01194 }
01195
01196 throw MMSAVError(0, "MMSAV::isPlaying() called but media backend does not match supported backends");
01197 }
01198
01199
01200
01201
01202
01203
01204 bool MMSAV::isPaused() {
01205 switch(this->backend) {
01206 case MMSMEDIA_BE_GST:
01207 #ifdef __HAVE_GSTREAMER__
01208 return false;
01209 #endif
01210 break;
01211 case MMSMEDIA_BE_XINE:
01212 #ifdef __HAVE_XINE__
01213 if(this->status == STATUS_PAUSED) {
01214 if(xine_get_status(this->stream)!=XINE_STATUS_PLAY) {
01215 this->setStatus(STATUS_STOPPED);
01216 return false;
01217 }
01218 else return true;
01219 }
01220 return false;
01221 #endif
01222 break;
01223 default:
01224
01225 break;
01226 }
01227
01228 throw MMSAVError(0, "MMSAV::isPaused() called but media backend does not match supported backends");
01229 }
01230
01231
01232
01233
01234
01235
01236 bool MMSAV::isStopped() {
01237 return (this->status == STATUS_STOPPED);
01238 }
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251 void MMSAV::startPlaying(const string mrl, const bool cont) {
01252 DEBUGMSG("MMSAV", "currentMRL: %s mrl: %s status: %d", currentMRL.c_str(), mrl.c_str(), status);
01253 if((currentMRL == mrl) && (this->status == this->STATUS_PLAYING)) return;
01254 this->currentMRL = mrl;
01255
01256 if (this->backend == MMSMEDIA_BE_GST) {
01257 #ifdef __HAVE_GSTREAMER__
01258
01259
01260
01261
01262
01263
01264 MMSFBLayer *vl = mmsfbmanager.getVideoLayer();
01265 if (vl != mmsfbmanager.getGraphicsLayer())
01266 vl->releaseLayer();
01267
01268
01269
01270
01271 this->gst_diskovideosink_data.pipeline = mmsGstInit(currentMRL, this->window->getSurface());
01272 if (!this->gst_diskovideosink_data.pipeline)
01273 return;
01274 this->gst_diskovideosink_data.uri = currentMRL;
01275
01276
01277 pthread_t thread;
01278 if(pthread_create(&thread, NULL, (void* (*)(void*))gstPlayRoutine, &this->gst_diskovideosink_data) == 0)
01279 pthread_detach(thread);
01280
01281 #endif
01282 }
01283 else {
01284 #ifdef __HAVE_XINE__
01285
01286 if(!this->stream) this->xineOpen();
01287
01288 if(!cont) this->pos = 0;
01289
01290
01291
01292 internalStreamData *streamData = new internalStreamData;
01293 streamData->stream = this->stream;
01294 streamData->pos = this->pos;
01295 streamData->status = &(this->status);
01296 streamData->mrl = mrl.c_str();
01297 streamData->lock = &(this->lock);
01298
01299
01300
01301 xinePlayRoutine(streamData);
01302
01303 #endif
01304 }
01305 }
01306
01307
01308
01309
01310
01311
01312
01313 void MMSAV::play() {
01314 switch(this->backend) {
01315 case MMSMEDIA_BE_GST:
01316 #ifdef __HAVE_GSTREAMER__
01317 return;
01318 #endif
01319 break;
01320 case MMSMEDIA_BE_XINE:
01321 #ifdef __HAVE_XINE__
01322 if(!this->stream) return;
01323
01324 if(this->status == this->STATUS_PAUSED ||
01325 this->status == this->STATUS_SLOW ||
01326 this->status == this->STATUS_SLOW2 ||
01327 this->status == this->STATUS_FFWD ||
01328 this->status == this->STATUS_FFWD2) {
01329 this->setStatus(this->STATUS_PLAYING);
01330 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
01331 }
01332 return;
01333 #endif
01334 break;
01335 default:
01336
01337 break;
01338 }
01339
01340 throw MMSAVError(0, "MMSAV::play() called but media backend does not match supported backends");
01341 }
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352 void MMSAV::stop(const bool savePosition) {
01353 switch(this->backend) {
01354 case MMSMEDIA_BE_GST:
01355 #ifdef __HAVE_GSTREAMER__
01356 return;
01357 #endif
01358 break;
01359 case MMSMEDIA_BE_XINE: {
01360 #ifdef __HAVE_XINE__
01361 if(!this->stream) return;
01362
01363
01364 if(savePosition)
01365 xine_get_pos_length(this->stream, &this->pos, NULL, NULL);
01366
01367
01368
01369 internalStreamData *streamData = new internalStreamData;
01370 streamData->stream = this->stream;
01371 streamData->status = &(this->status);
01372 streamData->lock = &(this->lock);
01373
01374
01375
01376 stopRoutine(streamData);
01377 return;
01378 #endif
01379 break;
01380 }
01381 default:
01382
01383 break;
01384 }
01385
01386 throw MMSAVError(0, "MMSAV::stop() called but media backend does not match supported backends");
01387 }
01388
01389
01390
01391
01392
01393
01394
01395 void MMSAV::pause() {
01396 switch(this->backend) {
01397 case MMSMEDIA_BE_GST:
01398 #ifdef __HAVE_GSTREAMER__
01399 return;
01400 #endif
01401 break;
01402 case MMSMEDIA_BE_XINE:
01403 #ifdef __HAVE_XINE__
01404 if(this->status == this->STATUS_PLAYING ||
01405 this->status == this->STATUS_SLOW ||
01406 this->status == this->STATUS_SLOW2 ||
01407 this->status == this->STATUS_FFWD ||
01408 this->status == this->STATUS_FFWD2) {
01409 this->setStatus(this->STATUS_PAUSED);
01410 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
01411 xine_set_param(this->stream, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
01412 }
01413 return;
01414 #endif
01415 break;
01416 default:
01417
01418 break;
01419 }
01420
01421 throw MMSAVError(0, "MMSAV::pause() called but media backend does not match supported backends");
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433 void MMSAV::slow() {
01434 switch(this->backend) {
01435 case MMSMEDIA_BE_GST:
01436 #ifdef __HAVE_GSTREAMER__
01437 return;
01438 #endif
01439 break;
01440 case MMSMEDIA_BE_XINE:
01441 #ifdef __HAVE_XINE__
01442 if(this->status == this->STATUS_PLAYING || this->status == this->STATUS_PAUSED) {
01443 this->setStatus(this->STATUS_SLOW);
01444 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_2);
01445 }
01446 else if(this->status == this->STATUS_SLOW) {
01447 this->setStatus(this->STATUS_SLOW2);
01448 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_4);
01449 }
01450 else if(this->status == this->STATUS_FFWD) {
01451 this->setStatus(this->STATUS_PLAYING);
01452 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
01453 }
01454 else if(this->status == this->STATUS_FFWD2) {
01455 this->setStatus(this->STATUS_FFWD);
01456 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_FAST_2);
01457 }
01458 return;
01459 #endif
01460 break;
01461 default:
01462
01463 break;
01464 }
01465
01466 throw MMSAVError(0, "MMSAV::slow() called but media backend does not match supported backends");
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478 void MMSAV::ffwd() {
01479 switch(this->backend) {
01480 case MMSMEDIA_BE_GST:
01481 #ifdef __HAVE_GSTREAMER__
01482
01483
01484 printf("ffwd-------------------------------------\n");
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 return;
01519 #endif
01520 break;
01521 case MMSMEDIA_BE_XINE:
01522 #ifdef __HAVE_XINE__
01523 if(this->status == this->STATUS_PLAYING || this->status == this->STATUS_PAUSED) {
01524 this->setStatus(this->STATUS_FFWD);
01525 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_FAST_2);
01526 }
01527 else if(this->status == this->STATUS_FFWD) {
01528 this->setStatus(this->STATUS_FFWD2);
01529 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_FAST_4);
01530 }
01531 else if(this->status == this->STATUS_SLOW) {
01532 this->setStatus(this->STATUS_PLAYING);
01533 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
01534 }
01535 else if(this->status == this->STATUS_SLOW2) {
01536 this->setStatus(this->STATUS_SLOW);
01537 xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_2);
01538 }
01539 return;
01540 #endif
01541 break;
01542 default:
01543
01544 break;
01545 }
01546
01547 throw MMSAVError(0, "MMSAV::ffwd() called but media backend does not match supported backends");
01548 }
01549
01550
01551
01552
01553
01554
01555
01556
01557 bool MMSAV::getTimes(int *pos, int *length) {
01558 switch(this->backend) {
01559 case MMSMEDIA_BE_GST:
01560 #ifdef __HAVE_GSTREAMER__
01561 return 0;
01562 #endif
01563 break;
01564 case MMSMEDIA_BE_XINE:
01565 #ifdef __HAVE_XINE__
01566 if(!this->stream || !xine_get_pos_length(this->stream, NULL, pos, length)) return false;
01567
01568 if(pos) (*pos) /= 1000;
01569 if(length) (*length) /= 1000;
01570 return true;
01571 #endif
01572 break;
01573 default:
01574
01575 break;
01576 }
01577
01578 throw MMSAVError(0, "MMSAV::getTimes() called but media backend does not match supported backends");
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 void MMSAV::setBrightness(int count) {
01590 switch(this->backend) {
01591 case MMSMEDIA_BE_GST:
01592 #ifdef __HAVE_GSTREAMER__
01593 return;
01594 #endif
01595 break;
01596 case MMSMEDIA_BE_XINE:
01597 #ifdef __HAVE_XINE__
01598 if(this->vo)
01599 xine_set_param(this->stream, XINE_PARAM_VO_BRIGHTNESS, count);
01600 return;
01601 #endif
01602 break;
01603 default:
01604
01605 break;
01606 }
01607
01608 throw MMSAVError(0, "MMSAV::setBrightness() called but media backend does not match supported backends");
01609 }
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619 void MMSAV::brightnessUp(int count) {
01620 switch(this->backend) {
01621 case MMSMEDIA_BE_GST:
01622 #ifdef __HAVE_GSTREAMER__
01623 return;
01624 #endif
01625 break;
01626 case MMSMEDIA_BE_XINE:
01627 #ifdef __HAVE_XINE__
01628 if(this->vo) {
01629 int value = xine_get_param(this->stream, XINE_PARAM_VO_BRIGHTNESS);
01630 xine_set_param(this->stream, XINE_PARAM_VO_BRIGHTNESS, value + count*500);
01631 }
01632 return;
01633 #endif
01634 break;
01635 default:
01636
01637 break;
01638 }
01639
01640 throw MMSAVError(0, "MMSAV::brightnessUp() called but media backend does not match supported backends");
01641 }
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651 void MMSAV::brightnessDown(int count) {
01652 switch(this->backend) {
01653 case MMSMEDIA_BE_GST:
01654 #ifdef __HAVE_GSTREAMER__
01655 return;
01656 #endif
01657 break;
01658 case MMSMEDIA_BE_XINE:
01659 #ifdef __HAVE_XINE__
01660 if(this->vo) {
01661 int value = xine_get_param(this->stream, XINE_PARAM_VO_BRIGHTNESS);
01662 xine_set_param(this->stream, XINE_PARAM_VO_BRIGHTNESS, value - count*500);
01663 }
01664 return;
01665 #endif
01666 break;
01667 default:
01668
01669 break;
01670 }
01671
01672 throw MMSAVError(0, "MMSAV::brightnessDown() called but media backend does not match supported backends");
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 void MMSAV::setContrast(int count) {
01684 switch(this->backend) {
01685 case MMSMEDIA_BE_GST:
01686 #ifdef __HAVE_GSTREAMER__
01687 return;
01688 #endif
01689 break;
01690 case MMSMEDIA_BE_XINE:
01691 #ifdef __HAVE_XINE__
01692 if(this->vo)
01693 xine_set_param(this->stream, XINE_PARAM_VO_CONTRAST, count);
01694 return;
01695 #endif
01696 break;
01697 default:
01698
01699 break;
01700 }
01701
01702 throw MMSAVError(0, "MMSAV::setContrast() called but media backend does not match supported backends");
01703 }
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713 void MMSAV::contrastUp(int count) {
01714 switch(this->backend) {
01715 case MMSMEDIA_BE_GST:
01716 #ifdef __HAVE_GSTREAMER__
01717 return;
01718 #endif
01719 break;
01720 case MMSMEDIA_BE_XINE:
01721 #ifdef __HAVE_XINE__
01722 if(this->vo) {
01723 int value = xine_get_param(this->stream, XINE_PARAM_VO_CONTRAST);
01724 xine_set_param(this->stream, XINE_PARAM_VO_CONTRAST, value + count*500);
01725 }
01726 return;
01727 #endif
01728 break;
01729 default:
01730
01731 break;
01732 }
01733
01734 throw MMSAVError(0, "MMSAV::contrastUp() called but media backend does not match supported backends");
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 void MMSAV::contrastDown(int count) {
01746 switch(this->backend) {
01747 case MMSMEDIA_BE_GST:
01748 #ifdef __HAVE_GSTREAMER__
01749 return;
01750 #endif
01751 break;
01752 case MMSMEDIA_BE_XINE:
01753 #ifdef __HAVE_XINE__
01754 if(this->vo) {
01755 int value = xine_get_param(this->stream, XINE_PARAM_VO_CONTRAST);
01756 xine_set_param(this->stream, XINE_PARAM_VO_CONTRAST, value - count*500);
01757 }
01758 return;
01759 #endif
01760 break;
01761 default:
01762
01763 break;
01764 }
01765
01766 throw MMSAVError(0, "MMSAV::contrastDown() called but media backend does not match supported backends");
01767 }
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 void MMSAV::setSaturation(int count) {
01778 switch(this->backend) {
01779 case MMSMEDIA_BE_GST:
01780 #ifdef __HAVE_GSTREAMER__
01781 return;
01782 #endif
01783 break;
01784 case MMSMEDIA_BE_XINE:
01785 #ifdef __HAVE_XINE__
01786 if(this->vo)
01787 xine_set_param(this->stream, XINE_PARAM_VO_SATURATION, count);
01788 return;
01789 #endif
01790 break;
01791 default:
01792
01793 break;
01794 }
01795
01796 throw MMSAVError(0, "MMSAV::setSaturation() called but media backend does not match supported backends");
01797 }
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807 void MMSAV::saturationUp(int count) {
01808 switch(this->backend) {
01809 case MMSMEDIA_BE_GST:
01810 #ifdef __HAVE_GSTREAMER__
01811 return;
01812 #endif
01813 break;
01814 case MMSMEDIA_BE_XINE:
01815 #ifdef __HAVE_XINE__
01816 if(this->vo) {
01817 int value = xine_get_param(this->stream, XINE_PARAM_VO_SATURATION);
01818 xine_set_param(this->stream, XINE_PARAM_VO_SATURATION, value + count*500);
01819 }
01820 return;
01821 #endif
01822 break;
01823 default:
01824
01825 break;
01826 }
01827
01828 throw MMSAVError(0, "MMSAV::saturationUp() called but media backend does not match supported backends");
01829 }
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 void MMSAV::saturationDown(int count) {
01840 switch(this->backend) {
01841 case MMSMEDIA_BE_GST:
01842 #ifdef __HAVE_GSTREAMER__
01843 return;
01844 #endif
01845 break;
01846 case MMSMEDIA_BE_XINE:
01847 #ifdef __HAVE_XINE__
01848 if(this->vo) {
01849 int value = xine_get_param(this->stream, XINE_PARAM_VO_SATURATION);
01850 xine_set_param(this->stream, XINE_PARAM_VO_SATURATION, value - count*500);
01851 }
01852 return;
01853 #endif
01854 break;
01855 default:
01856
01857 break;
01858 }
01859
01860 throw MMSAVError(0, "MMSAV::saturationDown() called but media backend does not match supported backends");
01861 }
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871 void MMSAV::setHue(int count) {
01872 switch(this->backend) {
01873 case MMSMEDIA_BE_GST:
01874 #ifdef __HAVE_GSTREAMER__
01875 return;
01876 #endif
01877 break;
01878 case MMSMEDIA_BE_XINE:
01879 #ifdef __HAVE_XINE__
01880 if(this->vo)
01881 xine_set_param(this->stream, XINE_PARAM_VO_HUE, count);
01882 return;
01883 #endif
01884 break;
01885 default:
01886
01887 break;
01888 }
01889
01890 throw MMSAVError(0, "MMSAV::setHue() called but media backend does not match supported backends");
01891 }
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901 void MMSAV::hueUp(int count) {
01902 switch(this->backend) {
01903 case MMSMEDIA_BE_GST:
01904 #ifdef __HAVE_GSTREAMER__
01905 return;
01906 #endif
01907 break;
01908 case MMSMEDIA_BE_XINE:
01909 #ifdef __HAVE_XINE__
01910 if(this->vo) {
01911 int value = xine_get_param(this->stream, XINE_PARAM_VO_HUE);
01912 xine_set_param(this->stream, XINE_PARAM_VO_HUE, value + count*500);
01913 }
01914 return;
01915 #endif
01916 break;
01917 default:
01918
01919 break;
01920 }
01921
01922 throw MMSAVError(0,"MMSAV::hueUp() called but media backend does not match supported backends");
01923 }
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933 void MMSAV::hueDown(int count) {
01934 switch(this->backend) {
01935 case MMSMEDIA_BE_GST:
01936 #ifdef __HAVE_GSTREAMER__
01937 return;
01938 #endif
01939 break;
01940 case MMSMEDIA_BE_XINE:
01941 #ifdef __HAVE_XINE__
01942 if(this->vo) {
01943 int value = xine_get_param(this->stream, XINE_PARAM_VO_HUE);
01944 xine_set_param(this->stream, XINE_PARAM_VO_HUE, value - count*500);
01945 }
01946 return;
01947 #endif
01948 break;
01949 default:
01950
01951 break;
01952 }
01953
01954 throw MMSAVError(0, "MMSAV::hueDown() called but media backend does not match supported backends");
01955 }
01956
01957
01958
01959
01960
01961
01962 void MMSAV::setVolume(int percent) {
01963 switch(this->backend) {
01964 case MMSMEDIA_BE_GST:
01965 #ifdef __HAVE_GSTREAMER__
01966 return;
01967 #endif
01968 break;
01969 case MMSMEDIA_BE_XINE:
01970 #ifdef __HAVE_XINE__
01971 if(this->ao)
01972 xine_set_param(this->stream, XINE_PARAM_AUDIO_VOLUME, percent);
01973 return;
01974 #endif
01975 break;
01976 default:
01977
01978 break;
01979 }
01980
01981 throw MMSAVError(0, "MMSAV::setVolume() called but media backend does not match supported backends");
01982 }
01983
01984
01985
01986
01987
01988
01989
01990
01991 void MMSAV::sendEvent(int type, void *data, int datalen) {
01992 switch(this->backend) {
01993 case MMSMEDIA_BE_GST:
01994 #ifdef __HAVE_GSTREAMER__
01995 return;
01996 #endif
01997 break;
01998 case MMSMEDIA_BE_XINE:
01999 #ifdef __HAVE_XINE__
02000 xine_event_t evt;
02001
02002 evt.stream = this->stream;
02003 evt.data = data;
02004 evt.data_length = datalen;
02005 evt.type = type;
02006 xine_event_send(this->stream, &evt);
02007 return;
02008 #endif
02009 break;
02010 default:
02011
02012 break;
02013 }
02014
02015 throw MMSAVError(0, "MMSAV::sendEvent() called but media backend does not match supported backends");
02016 }
02017
02018
02019 bool MMSAV::sendKeyPress(MMSKeySymbol key) {
02020 switch(this->backend) {
02021 case MMSMEDIA_BE_GST: {
02022 #ifdef __HAVE_GSTREAMER__
02023 return mmsGstSendKeyPress(gst_diskovideosink_data.pipeline, key);
02024 #endif
02025 break;
02026 }
02027 case MMSMEDIA_BE_XINE:
02028 #ifdef __HAVE_XINE__
02029 return false;
02030 #endif
02031 break;
02032 default:
02033
02034 break;
02035 }
02036
02037 throw MMSAVError(0, "MMSAV::sendKeyPress() called but media backend does not match supported backends");
02038
02039 return false;
02040 }
02041
02042 bool MMSAV::sendKeyRelease(MMSKeySymbol key) {
02043 switch(this->backend) {
02044 case MMSMEDIA_BE_GST: {
02045 #ifdef __HAVE_GSTREAMER__
02046 return mmsGstSendKeyRelease(gst_diskovideosink_data.pipeline, key);
02047 #endif
02048 break;
02049 }
02050 case MMSMEDIA_BE_XINE:
02051 #ifdef __HAVE_XINE__
02052 return false;
02053 #endif
02054 break;
02055 default:
02056
02057 break;
02058 }
02059
02060 throw MMSAVError(0, "MMSAV::sendKeyRelease() called but media backend does not match supported backends");
02061
02062 return false;
02063 }
02064
02065 bool MMSAV::sendButtonPress(int posx, int posy) {
02066 switch(this->backend) {
02067 case MMSMEDIA_BE_GST: {
02068 #ifdef __HAVE_GSTREAMER__
02069 return mmsGstSendButtonPress(gst_diskovideosink_data.pipeline, posx, posy);
02070 #endif
02071 break;
02072 }
02073 case MMSMEDIA_BE_XINE:
02074 #ifdef __HAVE_XINE__
02075 return false;
02076 #endif
02077 break;
02078 default:
02079
02080 break;
02081 }
02082
02083 throw MMSAVError(0, "MMSAV::sendButtonPress() called but media backend does not match supported backends");
02084
02085 return false;
02086 }
02087
02088 bool MMSAV::sendButtonRelease(int posx, int posy) {
02089 switch(this->backend) {
02090 case MMSMEDIA_BE_GST: {
02091 #ifdef __HAVE_GSTREAMER__
02092 return mmsGstSendButtonRelease(gst_diskovideosink_data.pipeline, posx, posy);
02093 #endif
02094 break;
02095 }
02096 case MMSMEDIA_BE_XINE:
02097 #ifdef __HAVE_XINE__
02098 return false;
02099 #endif
02100 break;
02101 default:
02102
02103 break;
02104 }
02105
02106 throw MMSAVError(0, "MMSAV::sendButtonRelease() called but media backend does not match supported backends");
02107
02108 return false;
02109 }
02110
02111 bool MMSAV::sendAxisMotion(int posx, int posy) {
02112 switch(this->backend) {
02113 case MMSMEDIA_BE_GST: {
02114 #ifdef __HAVE_GSTREAMER__
02115 return mmsGstSendAxisMotion(gst_diskovideosink_data.pipeline, posx, posy);
02116 #endif
02117 break;
02118 }
02119 case MMSMEDIA_BE_XINE:
02120 #ifdef __HAVE_XINE__
02121 return false;
02122 #endif
02123 break;
02124 default:
02125
02126 break;
02127 }
02128
02129 throw MMSAVError(0, "MMSAV::sendAxisMotion() called but media backend does not match supported backends");
02130
02131 return false;
02132 }
02133
02134 bool MMSAV::sendEvent(MMSInputEvent *input) {
02135
02136 switch (input->type) {
02137 case MMSINPUTEVENTTYPE_KEYPRESS:
02138 return sendKeyPress(input->key);
02139 case MMSINPUTEVENTTYPE_KEYRELEASE:
02140 return sendKeyRelease(input->key);
02141 case MMSINPUTEVENTTYPE_BUTTONPRESS:
02142 return sendButtonPress(input->posx, input->posy);
02143 case MMSINPUTEVENTTYPE_BUTTONRELEASE:
02144 return sendButtonRelease(input->posx, input->posy);
02145 case MMSINPUTEVENTTYPE_AXISMOTION:
02146 return sendAxisMotion(input->posx, input->posy);
02147 default:
02148 break;
02149 }
02150
02151 return false;
02152 }
02153
02154
02155
02156
02157
02158
02159 bool MMSAV::hasVideo() {
02160 switch(this->backend) {
02161 case MMSMEDIA_BE_GST:
02162 #ifdef __HAVE_GSTREAMER__
02163 return true;
02164 #endif
02165 break;
02166 case MMSMEDIA_BE_XINE:
02167 #ifdef __HAVE_XINE__
02168 return (xine_get_stream_info(this->stream, XINE_STREAM_INFO_HAS_VIDEO) == 1);
02169 #endif
02170 break;
02171 default:
02172
02173 break;
02174 }
02175
02176 throw MMSAVError(0, "MMSAV::hasVideo() called but media backend does not match supported backends");
02177 }
02178
02179
02180
02181
02182
02183
02184 bool MMSAV::hasAudio() {
02185 switch(this->backend) {
02186 case MMSMEDIA_BE_GST:
02187 #ifdef __HAVE_GSTREAMER__
02188 return false;
02189 #endif
02190 break;
02191 case MMSMEDIA_BE_XINE:
02192 #ifdef __HAVE_XINE__
02193 return (xine_get_stream_info(this->stream, XINE_STREAM_INFO_HAS_AUDIO) == 1);
02194 #endif
02195 break;
02196 default:
02197
02198 break;
02199 }
02200
02201 throw MMSAVError(0, "MMSAV::hasAudio() called but media backend does not match supported backends");
02202 }