/tags/release-0.5.2.1/player/kxinewidget.cpp
C++ | 3929 lines | 3129 code | 614 blank | 186 comment | 468 complexity | b529aab7b4f5caa1b90f7740683af989 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
- /***************************************************************************
- kxinewidget.cpp
- A KDE/QT API for the xine-lib. Define USE_QT_ONLY if you use QT only.
- -------------------
- begin : Fre Apr 18 2003
- revision : $Revision: 1.48 $
- last modified : $Date: 2005/08/22 19:36:46 $ by $Author: juergenk $
- copyright : (C) 2003-2005 by JĂrgen Kofler
- email : kaffeine@gmx.net
- ***************************************************************************/
- /***************************************************************************
- * *
- * This program 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. *
- * *
- ***************************************************************************/
- #include <qapplication.h>
- #include <qwidget.h>
- #include <qstringlist.h>
- #include <qtimer.h>
- #include <qevent.h>
- #include <qthread.h>
- #include <qdir.h>
- #include <qcursor.h>
- #include <qimage.h>
- #include <qdatetime.h>
- #include <qtextcodec.h>
- #include <xine/xineutils.h>
- #include <math.h>
- #include <string.h>
- #include <stdlib.h>
- #include "kxinewidget.h"
- #ifdef HAVE_XINERAMA
- #include <X11/extensions/Xinerama.h>
- #endif
- #ifndef USE_QT_ONLY
- #include "kxinewidget.moc"
- #include <klocale.h>
- #include <kdebug.h>
- #endif
- #define TIMER_EVENT_PLAYBACK_FINISHED 100
- #define TIMER_EVENT_NEW_CHANNELS 101
- #define TIMER_EVENT_NEW_TITLE 102
- #define TIMER_EVENT_NEW_STATUS 103
- #define TIMER_EVENT_CHANGE_CURSOR 104
- #define TIMER_EVENT_NEW_MRL_REFERENCE 105
- #define TIMER_EVENT_NEW_XINE_MESSAGE 106
- #define TIMER_EVENT_NEW_XINE_ERROR 107
- #define TIMER_EVENT_FRAME_FORMAT_CHANGE 108
- #define TIMER_EVENT_NEW_VOLUME_LEVEL 109
- #define TIMER_EVENT_RESTART_PLAYBACK 200
- #define TIMER_EVENT_RESIZE_PARENT 300
- KXineWidget::KXineWidget(QWidget* parent, const char* name,
- const QString& pathToConfigFile, const QString& pathToLogoFile,
- const QString& audioDriver, const QString& videoDriver,
- bool startManual, bool verbose)
- : QWidget(parent,name), QThread(), m_startXineManual(startManual), m_xineReady(false),
- m_logoFile(pathToLogoFile), m_preferedAudio(audioDriver), m_preferedVideo(videoDriver), m_xineVerbose(verbose),
- m_xineDisplay(NULL), m_xineEngine(NULL), m_audioDriver(NULL), m_videoDriver(NULL), m_xineStream(NULL),
- m_eventQueue(NULL), m_osd(NULL), m_osdUnscaled(false), m_osdShow(false), m_osdSize(0), m_osdFont(NULL),
- m_audioChoices(NULL), m_audioInfo(NULL), m_videoChoices(NULL), m_videoInfo(NULL), m_mixerInfo(NULL),
- m_osdShowInfo(NULL),
- m_osdSizeOptions(NULL), m_osdSizeInfo(NULL), m_osdFontInfo(NULL),
- #ifndef USE_QT_ONLY
- m_videoFiltersEnabled(true), m_audioFiltersEnabled(true), m_deinterlaceFilter(NULL),
- m_deinterlaceEnabled(false),
- m_visualPlugin(NULL),
- #else
- m_xinePost(NULL), m_postAudioSource(NULL), m_postInput(NULL),
- #endif
- m_visualPluginName(QString::null), m_currentSpeed(Normal), m_softwareMixer(false), m_volumeGain(false),
- m_currentZoom(100), m_currentZoomX(100), m_currentZoomY(100), m_currentAudio(0), m_currentSub(0), m_savedPos(0), m_autoresizeEnabled(false)
- {
- setMinimumSize(QSize(20,20)); // set a size hint
- setPaletteBackgroundColor(QColor(0,0,0)); //black
- /* dvb */
- TimeShiftFilename = "";
- dvbHaveVideo = 0;
- dvbOSD = 0;
- dvbColor[0] = 0;
- connect( &dvbOSDHideTimer, SIGNAL(timeout()), this, SLOT(dvbHideOSD()) );
- if (pathToConfigFile.isNull())
- {
- debugOut("Using default config file ~/.xine/config");
- m_configFilePath = QDir::homeDirPath();
- m_configFilePath.append("/.xine/config");
- }
- else
- m_configFilePath = pathToConfigFile;
- if (!m_logoFile.isNull())
- appendToQueue(m_logoFile);
- #ifndef USE_QT_ONLY
- m_videoFilterList.setAutoDelete(true); /*** delete post plugin on removing from list ***/
- m_audioFilterList.setAutoDelete(true); /*** delete post plugin on removing from list ***/
- #endif
- connect(&m_posTimer, SIGNAL(timeout()), this, SLOT(slotSendPosition()));
- connect(&m_lengthInfoTimer, SIGNAL(timeout()), this, SLOT(slotEmitLengthInfo()));
- connect(&m_mouseHideTimer, SIGNAL(timeout()), this, SLOT(slotHideMouse()));
- connect(&m_osdTimer, SIGNAL(timeout()), this, SLOT(slotOSDHide()));
- connect(&m_recentMessagesTimer, SIGNAL(timeout()), this, SLOT(slotNoRecentMessage()));
- setUpdatesEnabled(false);
- setMouseTracking(true);
- }
- KXineWidget::~KXineWidget()
- {
- /* "careful" shutdown, maybe xine initialization was not successful */
- m_xineReady = false;
- /* stop all timers */
- m_posTimer.stop();
- m_mouseHideTimer.stop();
- #ifndef USE_QT_ONLY
- slotRemoveAllAudioFilters();
- slotRemoveAllVideoFilters();
- #endif
- if (m_osd)
- xine_osd_free(m_osd);
- if (m_xineStream)
- xine_close(m_xineStream);
- if (running())
- {
- XEvent ev;
- ev.type = Expose;
- ev.xexpose.display = m_xineDisplay;
- ev.xexpose.window = winId();
- ev.xexpose.x = x();
- ev.xexpose.y = y();
- ev.xexpose.width = width();
- ev.xexpose.height = height();
- ev.xexpose.count = 0;
- XSendEvent( x11Display(), winId(), False, ExposureMask, &ev ); /* send a fake expose event */
- XFlush(x11Display());
- if( !wait(1000) ) /* wait a second for thread exiting */
- {
- warningOut("XEvent thread don't exit. Terminating it...");
- terminate();
- }
- }
- debugOut("Shut down xine engine");
- #ifndef USE_QT_ONLY
- if (m_deinterlaceFilter)
- {
- debugOut("Unwire video filters");
- unwireVideoFilters();
- delete m_deinterlaceFilter;
- m_deinterlaceFilter = NULL;
- }
- if (m_visualPlugin)
- {
- debugOut("Unwire audio filters");
- unwireAudioFilters();
- debugOut(QString("Dispose visual plugin: %1").arg(m_visualPluginName ));
- delete m_visualPlugin;
- m_visualPlugin = NULL;
- }
- #else
- if (m_xinePost)
- {
- debugOut(QString("Dispose visual plugin: %1").arg(m_visualPluginName));
- m_postAudioSource = xine_get_audio_source(m_xineStream);
- xine_post_wire_audio_port(m_postAudioSource, m_audioDriver);
- xine_post_dispose(m_xineEngine, m_xinePost);
- }
- #endif
- if (m_eventQueue)
- {
- debugOut("Dispose event queue");
- xine_event_dispose_queue(m_eventQueue);
- }
- if (m_xineStream)
- {
- debugOut("Dispose stream");
- xine_dispose(m_xineStream);
- }
- if (m_audioDriver)
- {
- debugOut("Close audio driver");
- xine_close_audio_driver(m_xineEngine, m_audioDriver);
- }
- if (m_videoDriver)
- {
- debugOut("Close video driver");
- xine_close_video_driver(m_xineEngine, m_videoDriver);
- }
- if (m_xineEngine)
- {
- saveXineConfig();
- debugOut("Close xine engine");
- xine_exit(m_xineEngine);
- }
- m_xineEngine = NULL;
- /* free xine config strings */
- if (m_osdShowInfo) free(m_osdShowInfo);
- if (m_osdFontInfo) free(m_osdFontInfo);
- if (m_osdFont) free(m_osdFont);
- if (m_osdSizeInfo) free(m_osdSizeInfo);
- if (m_osdSizeOptions)
- {
- int i=0;
- while (m_osdSizeOptions[i])
- {
- free(m_osdSizeOptions[i]);
- i++;
- }
- delete [] m_osdSizeOptions;
- }
- if (m_mixerInfo) free(m_mixerInfo);
- if (m_videoInfo) free(m_videoInfo);
- if (m_videoChoices)
- {
- int i=0;
- while (m_videoChoices[i])
- {
- free(m_videoChoices[i]);
- i++;
- }
- delete [] m_videoChoices;
- }
- if (m_audioInfo) free(m_audioInfo);
- if (m_audioChoices)
- {
- int i=0;
- while (m_audioChoices[i])
- {
- free(m_audioChoices[i]);
- i++;
- }
- delete [] m_audioChoices;
- }
- if (m_xineDisplay)
- {
- debugOut("Close xine display");
- XCloseDisplay(m_xineDisplay); /* close xine display */
- }
- m_xineDisplay = NULL;
- debugOut("xine closed");
- }
- void KXineWidget::saveXineConfig()
- {
- debugOut("Set CD/VCD/DVD path back");
- xine_cfg_entry_t config;
- if (!m_cachedCDPath.isNull())
- {
- xine_config_lookup_entry (m_xineEngine, "input.cdda_device", &config);
- config.str_value = (char*)m_cachedCDPath.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- if (!m_cachedVCDPath.isNull())
- {
- xine_config_lookup_entry (m_xineEngine, "input.vcd_device", &config);
- config.str_value = (char*)m_cachedVCDPath.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- if (!m_cachedDVDPath.isNull())
- {
- xine_config_lookup_entry (m_xineEngine, "input.dvd_device", &config);
- config.str_value = (char*)m_cachedDVDPath.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- debugOut(QString("Save xine config to: %1").arg(m_configFilePath));
- xine_config_save(m_xineEngine, m_configFilePath.ascii());
- }
- /***************************************************
- * CALLBACKS
- ***************************************************/
- void KXineWidget::destSizeCallback(void* p, int /*video_width*/, int /*video_height*/, double /*video_aspect*/,
- int* dest_width, int* dest_height, double* dest_aspect)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- *dest_width = vw->width();
- *dest_height = vw->height();
- *dest_aspect = vw->m_displayRatio;
- }
- void KXineWidget::frameOutputCallback(void* p, int video_width, int video_height, double video_aspect,
- int* dest_x, int* dest_y, int* dest_width, int* dest_height,
- double* dest_aspect, int* win_x, int* win_y)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- *dest_x = 0;
- *dest_y = 0 ;
- *dest_width = vw->width();
- *dest_height = vw->height();
- *win_x = vw->m_globalX;
- *win_y = vw->m_globalY;
- *dest_aspect = vw->m_displayRatio;
- /* give false aspect for audio visualization*/
- if ( !vw->hasVideo() ) {
- *dest_aspect = (video_width*video_aspect)/((vw->width()*video_height/vw->height())-0.5);
- }
- /* correct size with video aspect */
- if (video_aspect >= vw->m_displayRatio)
- video_width = (int) ( (double) (video_width * video_aspect / vw->m_displayRatio + 0.5) );
- else
- video_height = (int) ( (double) (video_height * vw->m_displayRatio / video_aspect) + 0.5);
- /* frame size changed */
- if ( (video_width != vw->m_videoFrameWidth) || (video_height != vw->m_videoFrameHeight) )
- {
- debugOut(QString("New video frame size: %1x%2 - aspect ratio: %3").arg(video_width).arg(video_height).arg(video_aspect));
- vw->m_videoFrameWidth = video_width;
- vw->m_videoFrameHeight = video_height;
- vw->m_videoAspect = video_aspect;
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_FRAME_FORMAT_CHANGE));
- /* auto-resize parent widget */
- if ((vw->m_autoresizeEnabled) && (vw->parentWidget()) && (vw->m_posTimer.isActive()) && (!vw->parentWidget()->isFullScreen())
- && (video_width > 0) && (video_height > 0))
- {
- vw->m_newParentSize = vw->parentWidget()->size() - QSize((vw->width() - video_width), vw->height() - video_height);
- debugOut(QString("Resize video window to: %1x%2").arg(vw->m_newParentSize.width()).arg(vw->m_newParentSize.height()));
- /* we should not do a resize() inside a xine thread,
- but post an event to the main thread */
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_RESIZE_PARENT));
- }
- }
- }
- /*
- * XINE EVENT THREAD
- * only the QT event thread should do GUI operations,
- * we use QApplication::postEvent() and a reimplementation of QObject::timerEvent() to
- * make sure all critical jobs are done within the QT main thread context
- *
- * for more information see http://doc.trolltech.com/3.1/threads.html
- */
- void KXineWidget::xineEventListener(void *p, const xine_event_t* xineEvent)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- switch (xineEvent->type)
- {
- case XINE_EVENT_UI_PLAYBACK_FINISHED:
- {
- debugOut("xine event: playback finished");
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_PLAYBACK_FINISHED ));
- break;
- }
- case XINE_EVENT_UI_CHANNELS_CHANGED: /* new channel informations */
- {
- debugOut("xine event: channels changed");
- int i,j,channels;
- char* lang = new char[128];
- QString num;
- vw->m_audioCh.clear();
- vw->m_audioCh.append(i18n("auto"));
- vw->m_subCh.clear();
- vw->m_subCh.append(i18n("off"));
- /*** get audio channels ***/
- channels = QMAX(10, xine_get_stream_info(vw->m_xineStream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL));
- for(i = 0; i < channels; i++)
- {
- if (xine_get_audio_lang(vw->m_xineStream, i, lang))
- vw->m_audioCh << lang;
- else
- vw->m_audioCh << i18n("Ch ") + num.setNum(i+1);
- }
- /*** get subtitle channels ***/
- channels = QMAX(10, xine_get_stream_info(vw->m_xineStream, XINE_STREAM_INFO_MAX_SPU_CHANNEL));
- for(j = 0; j < channels; j++)
- {
- if (xine_get_spu_lang(vw->m_xineStream, j, lang))
- vw->m_subCh << lang;
- else
- vw->m_subCh << i18n("Ch ") + num.setNum(j+1);
- }
- delete [] lang;
- vw->m_currentAudio = xine_get_param(vw->m_xineStream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) + 1;
- vw->m_currentSub = xine_get_param(vw->m_xineStream, XINE_PARAM_SPU_CHANNEL) + 1;
- if (vw->m_currentAudio > (i-1))
- {
- vw->slotSetAudioChannel(0);
- vw->m_currentAudio = -1;
- }
- if (vw->m_currentSub > (j-1))
- {
- vw->slotSetSubtitleChannel(0);
- vw->m_currentSub = -1;
- }
- //check if stream is seekable
- vw->m_trackIsSeekable = (bool)xine_get_stream_info(vw->m_xineStream, XINE_STREAM_INFO_SEEKABLE);
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_CHANNELS));
- break;
- }
- case XINE_EVENT_UI_SET_TITLE: /* set new title */
- {
- debugOut("xine event: ui set title");
- xine_ui_data_t* xd = (xine_ui_data_t*)xineEvent->data;
- vw->m_trackTitle = QString::fromLocal8Bit( (char*)xd->str );
- vw->m_lengthInfoTries = 0;
- vw->m_lengthInfoTimer.start(1000); /* May be new Length on Changing DVD/VCD titles */
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_TITLE));
- break;
- }
- case XINE_EVENT_PROGRESS:
- {
- debugOut("xine event: progress info");
- xine_progress_data_t* pd = (xine_progress_data_t*)xineEvent->data;
- vw->m_statusString = QString::fromLocal8Bit(pd->description) + " " + QString::number(pd->percent) + "%";
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_STATUS));
- break;
- }
- case XINE_EVENT_DROPPED_FRAMES:
- {
- debugOut("xine event: dropped frames");
- xine_dropped_frames_t* dropped = (xine_dropped_frames_t*)xineEvent->data;
- warningOut(QString("Skipped frames: %1 - discarded frames: %2").arg(dropped->skipped_frames/10).arg(dropped->discarded_frames/10));
- break;
- }
- case XINE_EVENT_SPU_BUTTON:
- {
- debugOut("xine event: spu button");
- xine_spu_button_t* button = (xine_spu_button_t*)xineEvent->data;
- if (button->direction == 1) /* enter a button */
- {
- debugOut("DVD Menu: Mouse entered button");
- vw->m_DVDButtonEntered = true;
- }
- else
- {
- debugOut("DVD Menu: Mouse leaved button");
- vw->m_DVDButtonEntered = false;
- }
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_CHANGE_CURSOR));
- break;
- }
- case XINE_EVENT_UI_NUM_BUTTONS:
- {
- debugOut("xine event: ui num buttons");
- break;
- }
- case XINE_EVENT_MRL_REFERENCE:
- {
- debugOut("xine event: mrl reference");
- xine_mrl_reference_data_t* mrldata = (xine_mrl_reference_data_t*)xineEvent->data;
- vw->m_newMRLReference = mrldata->mrl;
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_MRL_REFERENCE));
- break;
- }
- case XINE_EVENT_FRAME_FORMAT_CHANGE:
- {
- // debugOut("xine event: frame format change");
- // QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_FRAME_FORMAT_CHANGE));
- break;
- }
- case XINE_EVENT_AUDIO_LEVEL:
- {
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_VOLUME_LEVEL));
- break;
- }
- case XINE_EVENT_UI_MESSAGE:
- {
- debugOut("xine event: xine message");
- xine_ui_message_data_t *data = (xine_ui_message_data_t *)xineEvent->data;
- QString message;
- switch(data->type)
- {
- case XINE_MSG_NO_ERROR:
- {
- /* copy strings, and replace '\0' separators by '\n' */
- char* s = data->messages;
- char* d = new char[2000];
- while(s && (*s != '\0') && ((*s + 1) != '\0'))
- {
- switch(*s)
- {
- case '\0':
- {
- *d = '\n';
- break;
- }
- default:
- {
- *d = *s;
- break;
- }
- }
- s++;
- d++;
- }
- *++d = '\0';
- message = d;
- delete [] d;
- break;
- }
- case XINE_MSG_GENERAL_WARNING:
- {
- message = i18n("General Warning: \n");
- if(data->explanation)
- message = message + ((char *) data + data->explanation) + " " + ((char *) data + data->parameters);
- else
- message = message + i18n("No Informations available.");
- break;
- }
- case XINE_MSG_SECURITY:
- {
- message = i18n("Security Warning: \n");
- if(data->explanation)
- message = message + ((char *) data + data->explanation) + " " + ((char *) data + data->parameters);
- break;
- }
- case XINE_MSG_UNKNOWN_HOST:
- {
- message = i18n("The host you're trying to connect is unknown.\nCheck the validity of the specified hostname. ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_UNKNOWN_DEVICE:
- {
- message = i18n("The device name you specified seems invalid. ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_NETWORK_UNREACHABLE:
- {
- message = i18n("The network looks unreachable.\nCheck your network setup and the server name. ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_AUDIO_OUT_UNAVAILABLE:
- {
- message = i18n("Audio output unavailable. Device is busy. ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_CONNECTION_REFUSED:
- {
- message = i18n("The connection was refused.\nCheck the host name. ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_FILE_NOT_FOUND:
- {
- message = i18n("The specified file or url was not found. Please check it. ");
- if(data->explanation)
- message = message + "(" + QString::fromLocal8Bit((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_PERMISSION_ERROR:
- {
- message = i18n("Permission to this source was denied. ");
- // if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_READ_ERROR:
- {
- message = i18n("The source can't be read.\nMaybe you don't have enough rights for this, or source doesn't contain data (e.g: no disc in drive). ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- case XINE_MSG_LIBRARY_LOAD_ERROR:
- {
- message = i18n("A problem occur while loading a library or a decoder: ");
- if(data->explanation)
- message = message + ((char *) data + data->parameters);
- break;
- }
- case XINE_MSG_ENCRYPTED_SOURCE:
- {
- message = i18n("The source seems encrypted, and can't be read. ");
- if (vw->m_trackURL.contains("dvd:/"))
- message = message + i18n("\nYour DVD is probably crypted. According to your country laws, you can or can't use libdvdcss to be able to read this disc. ");
- if(data->explanation)
- message = message + "(" + ((char *) data + data->parameters) + ")";
- break;
- }
- default:
- {
- message = i18n("Unknown error: \n");
- if(data->explanation)
- message = message + ((char *) data + data->explanation) + " " + ((char *) data + data->parameters);
- break;
- }
- }
- vw->m_xineMessage = message;
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_XINE_MESSAGE));
- break;
- }
- default:
- {
- //debugOut("xine event: unhandled type ");
- break;
- }
- }
- }
- void KXineWidget::timerEvent( QTimerEvent* tevent )
- {
- switch ( tevent->timerId() )
- {
- case TIMER_EVENT_PLAYBACK_FINISHED:
- {
- #ifdef XINE_PARAM_GAPLESS_SWITCH
- if ( xine_check_version(1,1,1) )
- xine_set_param( m_xineStream, XINE_PARAM_GAPLESS_SWITCH, 1);
- #endif
- if ( !TimeShiftFilename.isEmpty() )
- {
- QTimer::singleShot(0, this, SLOT(slotPlayTimeShift()));
- break;
- }
- if ( m_trackURL=="DVB" || m_trackURL.contains(".kaxtv.ts") )
- break;
- if (isQueueEmpty())
- {
- if (m_trackURL != m_logoFile)
- emit signalPlaybackFinished();
- else
- xine_stop(m_xineStream);
- }
- else
- QTimer::singleShot(0, this, SLOT(slotPlay()));
- break;
- }
- case TIMER_EVENT_NEW_CHANNELS:
- {
- emit signalNewChannels(m_audioCh, m_subCh, m_currentAudio, m_currentSub);
- break;
- }
- case TIMER_EVENT_NEW_TITLE:
- {
- emit signalTitleChanged();
- break;
- }
- case TIMER_EVENT_FRAME_FORMAT_CHANGE:
- {
- if ((m_trackHasVideo) && (m_trackURL != m_logoFile))
- emit signalVideoSizeChanged();
- break;
- }
- case TIMER_EVENT_NEW_STATUS:
- {
- emit signalXineStatus(m_statusString);
- break;
- }
- case TIMER_EVENT_CHANGE_CURSOR:
- {
- if (m_DVDButtonEntered)
- setCursor(QCursor(Qt::PointingHandCursor));
- else
- setCursor(QCursor(Qt::ArrowCursor));
- break;
- }
- case TIMER_EVENT_NEW_MRL_REFERENCE:
- {
- m_queue.prepend(m_newMRLReference );
- break;
- }
- case TIMER_EVENT_NEW_VOLUME_LEVEL:
- {
- emit signalSyncVolume();
- break;
- }
- case TIMER_EVENT_NEW_XINE_MESSAGE:
- {
- if (!m_recentMessagesTimer.isActive())
- {
- m_recentMessagesTimer.start(1500);
- emit signalXineMessage(m_xineMessage);
- }
- else
- {
- //restart
- warningOut(QString("Message: '%1' was blocked!").arg(m_xineMessage));
- m_recentMessagesTimer.start(1500);
- }
- break;
- }
- case TIMER_EVENT_NEW_XINE_ERROR:
- {
- emit signalXineError(m_xineError);
- break;
- }
- case TIMER_EVENT_RESTART_PLAYBACK:
- {
- appendToQueue(m_trackURL);
- slotPlay();
- break;
- }
- case TIMER_EVENT_RESIZE_PARENT:
- {
- parentWidget()->resize(m_newParentSize);
- break;
- }
- default: break;
- }
- }
- void KXineWidget::slotNoRecentMessage()
- {
- m_recentMessagesTimer.stop();
- }
- /******************* new video driver *********************/
- void KXineWidget::videoDriverChangedCallback(void* p, xine_cfg_entry_t* entry)
- {
- if (p == NULL) return;
- if (entry == NULL) return;
- #ifndef USE_QT_ONLY
- KXineWidget* vw = (KXineWidget*) p;
- xine_video_port_t* oldVideoDriver = vw->m_videoDriver;
- xine_video_port_t* noneVideoDriver;
- int pos, time, length;
- debugOut(QString("New video driver: %1").arg(entry->enum_values[entry->num_value]));
- if (vw->m_osd)
- {
- xine_osd_free(vw->m_osd);
- vw->m_osd = NULL;
- }
- noneVideoDriver = xine_open_video_driver(vw->m_xineEngine, "none",
- XINE_VISUAL_TYPE_NONE, NULL);
- if (!noneVideoDriver)
- {
- errorOut("Can't init Video Driver 'none', operation aborted.");
- return;
- }
- bool playing = false;
- if (vw->isPlaying())
- {
- playing = true;
- vw->m_savedPos = 0;
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(vw->m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( ret != 0 )
- vw->m_savedPos = pos;
- }
- xine_close(vw->m_xineStream);
- /* wire filters to "none" driver so the old one can be safely disposed */
- vw->m_videoDriver = noneVideoDriver;
- vw->unwireVideoFilters();
- vw->wireVideoFilters();
- vw->unwireAudioFilters();
- if (vw->m_visualPlugin)
- {
- debugOut(QString("Dispose visual plugin: %1").arg(vw->m_visualPluginName));
- delete vw->m_visualPlugin;
- vw->m_visualPlugin = NULL;
- }
- xine_event_dispose_queue(vw->m_eventQueue);
- xine_dispose(vw->m_xineStream);
- xine_close_video_driver(vw->m_xineEngine, oldVideoDriver);
- vw->m_videoDriver = xine_open_video_driver(vw->m_xineEngine,
- entry->enum_values[entry->num_value], XINE_VISUAL_TYPE_X11,
- (void *) &(vw->m_x11Visual));
- if (!vw->m_videoDriver)
- {
- vw->m_xineError = i18n("Error: Can't init new Video Driver %1 - using %2!").arg(entry->enum_values[entry->num_value]).arg(vw->m_videoDriverName);
- QApplication::postEvent(vw, new QTimerEvent( TIMER_EVENT_NEW_XINE_ERROR));
- playing = false;
- vw->m_videoDriver = xine_open_video_driver(vw->m_xineEngine,
- vw->m_videoDriverName.ascii(), XINE_VISUAL_TYPE_X11,
- (void *) &(vw->m_x11Visual));
- }
- else
- {
- vw->m_videoDriverName = entry->enum_values[entry->num_value];
- vw->m_statusString = i18n("Using Video Driver: ") + vw->m_videoDriverName;
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_STATUS));
- }
- vw->m_xineStream = xine_stream_new(vw->m_xineEngine, vw->m_audioDriver, vw->m_videoDriver);
- vw->m_eventQueue = xine_event_new_queue (vw->m_xineStream);
- xine_event_create_listener_thread(vw->m_eventQueue, &KXineWidget::xineEventListener, p);
- /* rewire filters to the new driver */
- vw->unwireVideoFilters();
- vw->wireVideoFilters();
- /* "none" can now be disposed too */
- xine_close_video_driver(vw->m_xineEngine, noneVideoDriver);
- vw->initOSD();
- if (playing)
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_RESTART_PLAYBACK));
- #endif
- }
- /*********************** new audio driver *************************/
- void KXineWidget::audioDriverChangedCallback(void* p, xine_cfg_entry_t* entry)
- {
- if (p == NULL) return;
- if (entry == NULL) return;
- #ifndef USE_QT_ONLY
- KXineWidget* vw = (KXineWidget*) p;
- int pos, time, length;
- debugOut(QString("New audio driver: %1").arg(entry->enum_values[entry->num_value]));
- if (vw->m_osd)
- {
- xine_osd_free(vw->m_osd);
- vw->m_osd = NULL;
- }
- vw->unwireVideoFilters();
- bool playing = false;
- if (vw->isPlaying())
- {
- playing = true;
- vw->m_savedPos = 0;
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(vw->m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( ret != 0 )
- vw->m_savedPos = pos;
- }
- xine_close(vw->m_xineStream);
- vw->unwireAudioFilters();
- if (vw->m_visualPlugin)
- {
- debugOut(QString("Dispose visual plugin: %1").arg(vw->m_visualPluginName));
- delete vw->m_visualPlugin;
- vw->m_visualPlugin = NULL;
- }
- xine_event_dispose_queue(vw->m_eventQueue);
- xine_dispose(vw->m_xineStream);
- xine_close_audio_driver(vw->m_xineEngine, vw->m_audioDriver);
- vw->m_audioDriver = NULL;
- vw->m_audioDriver = xine_open_audio_driver(vw->m_xineEngine, entry->enum_values[entry->num_value], NULL);
- if (!vw->m_audioDriver)
- {
- vw->m_xineError = i18n("Error: Can't init new Audio Driver %1 - using %2!").arg(entry->enum_values[entry->num_value]).arg(vw->m_audioDriverName);
- QApplication::postEvent(vw, new QTimerEvent( TIMER_EVENT_NEW_XINE_ERROR));
- playing = false;
- vw->m_audioDriver = xine_open_audio_driver(vw->m_xineEngine, vw->m_audioDriverName.ascii(), NULL);
- }
- else
- {
- vw->m_audioDriverName = entry->enum_values[entry->num_value];
- vw->m_statusString = i18n("Using Audio Driver: ") + vw->m_audioDriverName;
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_NEW_STATUS));
- }
- vw->m_xineStream = xine_stream_new(vw->m_xineEngine, vw->m_audioDriver, vw->m_videoDriver);
- vw->m_eventQueue = xine_event_new_queue (vw->m_xineStream);
- xine_event_create_listener_thread(vw->m_eventQueue, &KXineWidget::xineEventListener, p);
- vw->wireVideoFilters();
- vw->initOSD();
- if (playing)
- QApplication::postEvent(vw, new QTimerEvent(TIMER_EVENT_RESTART_PLAYBACK));
- #endif
- }
- /******** change audio mixer method ****************/
- void KXineWidget::audioMixerMethodChangedCallback(void* p, xine_cfg_entry_t* entry)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- vw->m_softwareMixer = (bool)entry->num_value;
- }
- /******** Callback for OSD configuration ****************/
- void KXineWidget::showOSDMessagesChangedCallback(void* p, xine_cfg_entry_t* entry)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- if (vw->m_osd)
- vw->m_osdShow = (bool)entry->num_value;
- }
- void KXineWidget::sizeForOSDMessagesChangedCallback(void* p, xine_cfg_entry_t* entry)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- const int fontsizetable[] = { 16,20,24,32,48,64 };
- if (entry->num_value >= 6)
- {
- debugOut("Font size not defined: Shouldn't have happened");
- return;
- }
- if (vw->m_osd)
- {
- vw->m_osdSize = entry->num_value;
- xine_osd_set_font(vw->m_osd, vw->m_osdFont, fontsizetable[vw->m_osdSize]);
- }
- }
- void KXineWidget::fontForOSDMessagesChangedCallback(void* p, xine_cfg_entry_t* entry)
- {
- if (p == NULL) return;
- KXineWidget* vw = (KXineWidget*) p;
- const int fontsizetable[] = { 16,20,24,32,48,64 };
- if (vw->m_osd)
- if (entry->str_value)
- {
- free(vw->m_osdFont);
- vw->m_osdFont = strdup(entry->str_value);
- if (!xine_osd_set_font(vw->m_osd, vw->m_osdFont, fontsizetable[vw->m_osdSize]))
- {
- free(vw->m_osdFont);
- vw->m_osdFont = strdup("sans");
- if (!xine_osd_set_font(vw->m_osd, vw->m_osdFont, fontsizetable[vw->m_osdSize]))
- warningOut("Default SANS font not found: shouldn't have happened.");
- }
- }
- }
- /**********************************************
- * EVENT LOOP
- *********************************************/
- void KXineWidget::run()
- {
- debugOut("Start event loop...");
- XEvent event;
- while (isXineReady())
- {
- XNextEvent (m_xineDisplay, &event);
- XLockDisplay(m_xineDisplay);
- if (event.type == Expose)
- {
- if (event.xexpose.count == 0)
- {
- xine_port_send_gui_data(m_videoDriver, XINE_GUI_SEND_EXPOSE_EVENT, &event);
- }
- }
- XUnlockDisplay(m_xineDisplay);
- }
- debugOut("Exiting event loop...");
- }
- /**********************************************************
- * INIT XINE ENGINE
- *********************************************************/
- void KXineWidget::polish()
- {
- if ((!m_startXineManual) && (!isXineReady())) /* start xine engine automatically? */
- {
- initXine();
- }
- }
- bool KXineWidget::initXine()
- {
- if (isXineReady())
- return true;
- emit signalXineStatus(i18n("Init xine..."));
- globalPosChanged(); /* get global pos of the window */
- /**** INIT XINE DISPLAY ****/
- XInitThreads();
- m_xineDisplay = XOpenDisplay( getenv("DISPLAY") );
- if (!m_xineDisplay)
- {
- emit signalXineFatal(i18n("Failed to connect to X-Server!"));
- return false;
- }
- m_xineScreen = DefaultScreen(m_xineDisplay);
- m_xineWindow = winId();
- XLockDisplay(m_xineDisplay);
- XSelectInput(m_xineDisplay, m_xineWindow, ExposureMask);
- /* determine display aspect ratio */
- double resHor = DisplayWidth(m_xineDisplay, m_xineScreen)*1000 / DisplayWidthMM(m_xineDisplay, m_xineScreen);
- double resVer = DisplayHeight(m_xineDisplay, m_xineScreen)*1000 / DisplayHeightMM(m_xineDisplay, m_xineScreen);
- m_displayRatio = resVer / resHor;
- #ifdef HAVE_XINERAMA
- int dummy_event, dummy_error;
- if (XineramaQueryExtension(m_xineDisplay, &dummy_event, &dummy_error))
- {
- int count = 1;
- debugOut("Xinerama extension present");
- XineramaQueryScreens(m_xineDisplay, &count);
- debugOut(QString("%1 screens detected").arg(count));
- if (count > 1)
- /* multihead -> assuming square pixels */
- m_displayRatio = 1.0;
- }
- #endif
- debugOut(QString("Display aspect ratio (v/h): %1").arg(m_displayRatio));
- XUnlockDisplay(m_xineDisplay);
- /**** INIT XINE ENGINE ****/
- debugOut(QString("Using xine version %1").arg(xine_get_version_string()));
- m_xineEngine = xine_new();
- if (!m_xineEngine)
- {
- emit signalXineFatal(i18n("Can't init xine Engine!"));
- return false;
- }
- if (m_xineVerbose)
- xine_engine_set_param(m_xineEngine, XINE_ENGINE_PARAM_VERBOSITY, 99);
- /* load configuration */
- if (!QFile::exists(m_configFilePath))
- warningOut("No config file found, will create one...");
- else
- xine_config_load(m_xineEngine, m_configFilePath.ascii());
- debugOut("Post-init xine engine");
- xine_init(m_xineEngine);
- /** set xine parameters **/
- const char* const* drivers = NULL;
- drivers = xine_list_audio_output_plugins(m_xineEngine);
- int i = 0;
- while (drivers[i] != NULL) i++;
- m_audioChoices = new char*[i+2];
- m_audioChoices[0] = strdup("auto");
- m_audioDriverList << m_audioChoices[0];
- i = 0;
- while(drivers[i])
- {
- m_audioChoices[i+1] = strdup(drivers[i]);
- m_audioDriverList << m_audioChoices[i+1];
- i++;
- }
- m_audioChoices[i+1] = NULL;
- m_audioInfo = strdup(i18n("Audiodriver to use (default: auto)").utf8());
- i = xine_config_register_enum(m_xineEngine, "audio.driver", 0,
- m_audioChoices, m_audioInfo, NULL, 10, &KXineWidget::audioDriverChangedCallback, this);
- if (m_audioDriverList.contains(m_preferedAudio))
- m_audioDriverName = m_preferedAudio;
- else
- m_audioDriverName = m_audioChoices[i];
- debugOut(QString("Use audio driver %1").arg(m_audioDriverName));
- drivers = xine_list_video_output_plugins(m_xineEngine);
- i = 0;
- while (drivers[i] != NULL) i++;
- m_videoChoices = new char*[i+2];
- m_videoChoices[0] = strdup("auto");
- m_videoDriverList << m_videoChoices[0];
- i = 0;
- while(drivers[i])
- {
- m_videoChoices[i+1] = strdup(drivers[i]);
- m_videoDriverList << m_videoChoices[i+1];
- i++;
- }
- m_videoChoices[i+1] = NULL;
- m_videoInfo = strdup(i18n("Videodriver to use (default: auto)").utf8());
- i = xine_config_register_enum(m_xineEngine, "video.driver", 0,
- m_videoChoices, m_videoInfo, NULL, 10, &KXineWidget::videoDriverChangedCallback, this);
- if (m_videoDriverList.contains(m_preferedVideo))
- m_videoDriverName = m_preferedVideo;
- else
- m_videoDriverName = m_videoChoices[i];
- debugOut(QString("Use video driver %1").arg(m_videoDriverName));
- m_mixerInfo = strdup(i18n("Use software audio mixer").utf8());
- m_softwareMixer = (bool)xine_config_register_bool(m_xineEngine, "audio.mixer_software", 1, m_mixerInfo,
- NULL, 10, &KXineWidget::audioMixerMethodChangedCallback, this);
- m_osdShowInfo = strdup(i18n("Show OSD Messages").utf8());
- m_osdShow = (bool)xine_config_register_bool(m_xineEngine, "osd.osd_messages", 1, m_osdShowInfo,
- NULL, 10, &KXineWidget::showOSDMessagesChangedCallback, this);
- m_osdSizeOptions = new char*[7];
- m_osdSizeOptions[0] = strdup("tiny");
- m_osdSizeOptions[1] = strdup("small");
- m_osdSizeOptions[2] = strdup("medium");
- m_osdSizeOptions[3] = strdup("large");
- m_osdSizeOptions[4] = strdup("very large");
- m_osdSizeOptions[5] = strdup("huge");
- m_osdSizeOptions[6] = NULL;
- m_osdSizeInfo = strdup(i18n("Size of OSD text").utf8());
- m_osdSize = (int)xine_config_register_enum(m_xineEngine, "osd.osd_size", 1 /*small - 20P*/, m_osdSizeOptions, m_osdSizeInfo,
- NULL, 10, &KXineWidget::sizeForOSDMessagesChangedCallback, this);
- m_osdFontInfo = strdup(i18n("Font for OSD Messages").utf8());
- m_osdFont = strdup((char*)xine_config_register_string(m_xineEngine, "osd.osd_font", "sans", m_osdFontInfo,
- NULL, 10, &KXineWidget::fontForOSDMessagesChangedCallback, this));
- /* init video driver */
- debugOut("Init video driver");
- m_x11Visual.display = m_xineDisplay;
- m_x11Visual.screen = m_xineScreen;
- m_x11Visual.d = m_xineWindow;
- m_x11Visual.dest_size_cb = &KXineWidget::destSizeCallback;
- m_x11Visual.frame_output_cb = &KXineWidget::frameOutputCallback;
- m_x11Visual.user_data = (void*)this;
- m_videoDriver = xine_open_video_driver(m_xineEngine,
- m_videoDriverName.ascii(), XINE_VISUAL_TYPE_X11,
- (void *) &(m_x11Visual));
- if (!m_videoDriver && m_videoDriverName != "auto")
- {
- emit signalXineError(i18n("Can't init Video Driver '%1' - trying 'auto'...").arg(m_videoDriverName));
- m_videoDriverName = "auto";
- m_videoDriver = xine_open_video_driver(m_xineEngine,
- m_videoDriverName.ascii(), XINE_VISUAL_TYPE_X11,
- (void *) &(m_x11Visual));
- }
- if (!m_videoDriver)
- {
- emit signalXineFatal(i18n("All Video Drivers failed to initialize!"));
- return false;
- }
- /* init audio driver */
- debugOut("Init audio driver");
- m_audioDriver = xine_open_audio_driver(m_xineEngine, m_audioDriverName.ascii(), NULL);
- if (!m_audioDriver && m_audioDriverName != "auto")
- {
- emit signalXineError(i18n("Can't init Audio Driver '%1' - trying 'auto'...").arg(m_audioDriverName));
- m_audioDriverName = "auto";
- m_audioDriver = xine_open_audio_driver (m_xineEngine, m_audioDriverName.ascii(), NULL);
- }
- if (!m_audioDriver)
- {
- emit signalXineFatal(i18n("All Audio Drivers failed to initialize!"));
- return false;
- }
- //debugOut("Open xine stream");
- m_xineStream = xine_stream_new(m_xineEngine, m_audioDriver, m_videoDriver);
- if (!m_xineStream)
- {
- emit signalXineFatal(i18n("Can't create a new xine Stream!"));
- return false;
- }
- #ifdef XINE_PARAM_EARLY_FINISHED_EVENT
- if ( xine_check_version(1,1,1) ) {
- // enable gapless playback
- xine_set_param(m_xineStream, XINE_PARAM_EARLY_FINISHED_EVENT, 1 );
- }
- #endif
- /*** OSD ***/
- initOSD();
- /** event handling **/
- m_eventQueue = xine_event_new_queue (m_xineStream);
- xine_event_create_listener_thread(m_eventQueue, &KXineWidget::xineEventListener, (void*)this);
- //maybe user closed player in muted state
- if (m_softwareMixer)
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_MUTE, 0);
- else
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_MUTE, 0);
- m_xineReady = true;
- start();
- debugOut("xine init successful");
- emit signalXineStatus(i18n("Ready"));
- emit signalXineReady();
- /** something to play? **/
- slotPlay();
- return true;
- }
- void KXineWidget::initOSD()
- {
- debugOut("Init OSD");
- const int fontsizetable[] = { 16,20,24,32,48,64 };
- m_osd = xine_osd_new(m_xineStream, 10, 10, 1000, 200);
- if (m_osd)
- {
- if (!xine_osd_set_font(m_osd, m_osdFont, fontsizetable[m_osdSize]))
- {
- debugOut(QString("Font ->%1<- specified for OSD doesn't exists.").arg(m_osdFont));
- free(m_osdFont);
- m_osdFont = strdup("sans");
- xine_osd_set_font(m_osd, m_osdFont, fontsizetable[m_osdSize]);
- }
- debugOut(QString("Font for OSD: %1").arg(m_osdFont));
- xine_osd_set_text_palette(m_osd, XINE_TEXTPALETTE_WHITE_BLACK_TRANSPARENT, XINE_OSD_TEXT1);
- m_osdUnscaled = (xine_osd_get_capabilities(m_osd) & XINE_OSD_CAP_UNSCALED);
- if (m_osdUnscaled)
- debugOut("Unscaled OSD available");
- }
- else
- warningOut("Initialisation of xine OSD failed.");
- }
- /************************************************
- * PLAY MRL
- ************************************************/
- bool KXineWidget::playDvb()
- {
- #ifndef USE_QT_ONLY
- unwireAudioFilters();
- QPtrList<PostFilter> activeList;
- if (m_audioFilterList.count() && m_audioFiltersEnabled)
- activeList = m_audioFilterList;
- if ( !dvbHaveVideo )
- {
- if (!m_visualPlugin)
- {
- debugOut(QString("Init visual plugin: %1").arg(m_visualPluginName));
- m_visualPlugin = new PostFilter(m_visualPluginName, m_xineEngine, m_audioDriver, m_videoDriver, NULL);
- }
- activeList.insert (0, m_visualPlugin);
- }
- else
- {
- if (m_visualPlugin)
- {
- debugOut(QString("Dispose visual plugin: %1").arg(m_visualPluginName));
- delete m_visualPlugin;
- m_visualPlugin = NULL;
- }
- }
- if (activeList.count())
- {
- xine_post_wire_audio_port(activeList.at(activeList.count()-1)->getOutput(), m_audioDriver);
- for (uint i = activeList.count()-1; i >0; i--)
- {
- xine_post_wire(activeList.at(i-1)->getOutput(), activeList.at(i)->getInput());
- }
- xine_post_wire( xine_get_audio_source(m_xineStream), activeList.at(0)->getInput());
- }
- #endif
- if (!xine_play(m_xineStream, 0,0))
- {
- sendXineError();
- return false;
- }
- m_currentSpeed = Normal;
- m_trackHasChapters = false;
- m_trackArtist = QString::null;
- m_trackAlbum = QString::null;
- m_trackNumber = QString::null;
- m_trackYear = QString::null;
- m_trackComment = QString::null;
- m_trackIsSeekable = false;
- if ( !dvbHaveVideo ) m_trackHasVideo = false;
- else m_trackHasVideo = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_VIDEO);
- if (m_trackHasVideo)
- {
- m_trackVideoCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_VIDEOCODEC);
- m_videoFrameWidth = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_WIDTH);
- m_videoFrameHeight = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_HEIGHT);
- m_trackVideoBitrate = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_BITRATE);
- }
- else
- {
- m_trackVideoCodec = QString::null;
- m_videoFrameWidth = 0;
- m_videoFrameHeight = 0;
- m_trackVideoBitrate = 0;
- }
- m_trackHasAudio = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_AUDIO);
- if (m_trackHasAudio)
- {
- m_trackAudioCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_AUDIOCODEC);
- m_trackAudioBitrate = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_AUDIO_BITRATE);
- }
- else
- {
- m_trackAudioCodec = QString::null;
- m_trackAudioBitrate = 0;
- }
- m_trackLength = getLengthInfo();
- slotSetAudioChannel(0); //refresh channel info
- m_posTimer.start(1000);
- emit signalXinePlaying();
- emit signalXineStatus(i18n("Playing"));
- return true;
- }
- unsigned int KXineWidget::rgb2yuv( unsigned int R, unsigned int G, unsigned int B )
- {
- return ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128));
- }
- void KXineWidget::initDvbPalette()
- {
- if ( dvbColor[0] ) return;
- memset( dvbColor, 0, sizeof(dvbColor) );
- memset( dvbTrans, 0, sizeof(dvbTrans) );
- dvbColor[0]=1;
- unsigned int blueText[11] = {
- rgb2yuv(0,0,0), /* 0 : not used */
- rgb2yuv(0,0,0), /* 1 : font bg */
- rgb2yuv(10,50,40), /* 2 : transition bg->border */
- rgb2yuv(30,100,85), /* 3 */
- rgb2yuv(50,150,130), /* 4 */
- rgb2yuv(70,200,175), /* 5 */
- rgb2yuv(90,255,220), /* 6 : border */
- rgb2yuv(90,255,220), /* 7 : transition border->fg */
- rgb2yuv(90,255,220), /* 8 */
- rgb2yuv(90,255,220), /* 9 */
- rgb2yuv(90,255,220), /* 10 : font fg */
- };
- unsigned int whiteText[11] = {
- rgb2yuv(0,0,0),
- rgb2yuv(0,0,0),
- rgb2yuv(50,50,50),
- rgb2yuv(100,100,100),
- rgb2yuv(150,150,150),
- rgb2yuv(200,200,200),
- rgb2yuv(255,255,255),
- rgb2yuv(255,255,255),
- rgb2yuv(255,255,255),
- rgb2yuv(255,255,255),
- rgb2yuv(255,255,255),
- };
- unsigned int greenText[11] = {
- rgb2yuv(0,0,0),
- rgb2yuv(0,0,0),
- rgb2yuv(30,50,30),
- rgb2yuv(60,100,30),
- rgb2yuv(90,150,90),
- rgb2yuv(120,200,120),
- rgb2yuv(150,255,150),
- rgb2yuv(150,255,150),
- rgb2yuv(150,255,150),
- rgb2yuv(150,255,150),
- rgb2yuv(150,255,150),
- };
- unsigned char textAlpha[11] = { 0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, };
- #define DVB_TEXT_WHITE 100
- #define DVB_TEXT_BLUE 111
- #define DVB_TEXT_GREEN 122
- int a;
- for ( a=DVB_TEXT_BLUE; a<DVB_TEXT_BLUE+11; a++ )
- {
- dvbColor[a]=blueText[a-DVB_TEXT_BLUE];
- dvbTrans[a]=textAlpha[a-DVB_TEXT_BLUE];
- }
- for ( a=DVB_TEXT_GREEN; a<DVB_TEXT_GREEN+11; a++ )
- {
- dvbColor[a]=greenText[a-DVB_TEXT_GREEN];
- dvbTrans[a]=textAlpha[a-DVB_TEXT_GREEN];
- }
- for ( a=DVB_TEXT_WHITE; a<DVB_TEXT_WHITE+11; a++ )
- {
- dvbColor[a]=whiteText[a-DVB_TEXT_WHITE];
- dvbTrans[a]=textAlpha[a-DVB_TEXT_WHITE];
- }
- #define DVB_COLOR_RED 200
- dvbColor[DVB_COLOR_RED] = rgb2yuv(255,0,0); dvbTrans[DVB_COLOR_RED] = 15;
- #define DVB_COLOR_GREEN 201
- dvbColor[DVB_COLOR_GREEN] = rgb2yuv(0,255,0); dvbTrans[DVB_COLOR_GREEN] = 15;
- #define DVB_COLOR_MAGENTA 202
- dvbColor[DVB_COLOR_MAGENTA] = rgb2yuv(255,128,255); dvbTrans[DVB_COLOR_MAGENTA] = 15;
- }
- void KXineWidget::dvbShowOSD()
- {
- if ( m_trackURL!="DVB" )
- return;
- if ( xine_get_status(m_xineStream)!=XINE_STATUS_PLAY )
- return;
- if ( !dvbHaveVideo )
- m_trackHasVideo = false;
- else
- m_trackHasVideo = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_VIDEO);
- if (m_trackHasVideo) {
- m_trackVideoCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_VIDEOCODEC);
- m_videoFrameWidth = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_WIDTH);
- m_videoFrameHeight = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_HEIGHT);
- m_trackVideoBitrate = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_BITRATE);
- }
- else {
- m_trackVideoCodec = QString::null;
- m_videoFrameWidth = 0;
- m_videoFrameHeight = 0;
- m_trackVideoBitrate = 0;
- }
- m_trackHasAudio = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_AUDIO);
- if (m_trackHasAudio) {
- m_trackAudioCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_AUDIOCODEC);
- m_trackAudioBitrate = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_AUDIO_BITRATE);
- }
- else {
- m_trackAudioCodec = QString::null;
- m_trackAudioBitrate = 0;
- }
- if ( dvbOSD ) {
- xine_osd_free( dvbOSD );
- dvbOSD = 0;
- }
- int border=40;
- int w = m_videoFrameWidth;
- int h = m_videoFrameHeight;
- if ( !w || !h )
- return;
- if ( w<800 ) {
- if ( dvbCurrentNext[0]=="E" ) {
- dvbOSDHideTimer.stop();
- dvbOSD = xine_osd_new( m_xineStream, border, border, w-(2*border), h-(2/border) );
- }
- else
- dvbOSD = xine_osd_new( m_xineStream, border, h-border-100, w-(2*border), 100 );
- }
- if ( dvbOSD ) {
- QCString ct, cs;
- if ( !dvbColor[0] ) initDvbPalette();
- //xine_osd_get_palette( dvbOSD, dvbColor, dvbTrans );
- xine_osd_set_palette( dvbOSD, dvbColor, dvbTrans );
- xine_osd_set_font( dvbOSD, m_osdFont, 16 );
- xine_osd_set_encoding( dvbOSD, "utf-8" );
- if ( dvbCurrentNext[0]=="E" )
- xine_osd_draw_rect( dvbOSD, 0, 0, w-(2*border), h-(2*border), DVB_TEXT_WHITE+1, 1 );
- else
- xine_osd_draw_rect( dvbOSD, 0, 0, w-(2*border), 100, DVB_TEXT_WHITE+1, 1 );
- QString t = QTime::currentTime().toString( "hh:mm" );
- int tw, th, len;
- xine_osd_get_text_size(dvbOSD, t.utf8(), &tw, &th);
- len = tw;
- int offset = 5;
- xine_osd_draw_text( dvbOSD, w-(2*border)-tw-offset, 5, t.utf8(), DVB_TEXT_BLUE );
- int i;
- for ( i=0; i<(int)dvbCurrentNext.count(); i++ ) {
- if ( dvbCurrentNext[i]=="R" ) {
- xine_osd_draw_rect( dvbOSD, offset, 5, offset+16, 21, DVB_COLOR_RED, 1 );
- offset+=21;
- }
- else if ( dvbCurrentNext[i]=="T" ) {
- xine_osd_draw_rect( dvbOSD, offset, 5, offset+16, 21, DVB_COLOR_GREEN, 1 );
- offset+=21;
- }
- }
- if (m_dvbChannelName == "")
- t = m_trackTitle;
- else
- t = m_dvbChannelName;
- i=0;
- ct = t.utf8();
- while ( i<(int)t.length() ) {
- xine_osd_get_text_size( dvbOSD, ct, &tw, &th );
- if ( tw<=(w-(2*border)-offset-5-len) ) break;
- ct = ct.remove( ct.length()-1, ct.length() );
- i++;
- }
- xine_osd_draw_text( dvbOSD, offset, 5, ct, DVB_TEXT_BLUE );
- xine_osd_draw_line( dvbOSD, 5, 10+18, w-(2*border)-5, 10+18, DVB_COLOR_MAGENTA );
- QString s, c;
- int y=43;
- int pos;
- if ( dvbCurrentNext[0]=="E" ) {
- if ( dvbCurrentNext.count()<2 ) {
- xine_osd_show( dvbOSD, 0 );
- return;
- }
- if ( !dvbCurrentNext[1].isEmpty() ) {
- s = dvbCurrentNext[1];
- pos = s.find("-");
- c = s.left( pos+1 );
- s = s.right( s.length()-pos-1 );
- t = s;
- xine_osd_draw_text( dvbOSD, 10, y, c.utf8(), DVB_TEXT_GREEN );
- xine_osd_get_text_size( dvbOSD, c.utf8(), &offset, &th );
- i=0;
- cs = s.utf8();
- while ( i<(int)t.length() ) {
- ct = cs.remove( cs.length()-i, cs.length() );
- xine_osd_get_text_size( dvbOSD, ct, &tw, &th );
- if ( tw<=(w-(2*border)-20) ) break;
- i++;
- }
- xine_osd_draw_text( dvbOSD, 10+offset, y, ct, DVB_TEXT_WHITE );
- y+= 40;
- }
- if ( !dvbCurrentNext[2].isEmpty() ) {
- cs = dvbCurrentNext[2].utf8();
- pos = 0;
- while ( pos!=-1 && y<(h-(2*border)-23) ) {
- ct = cs;
- i = 0;
- while ( pos!=-1 ) {
- xine_osd_get_text_size( dvbOSD, ct, &tw, &th );
- if ( tw<=(w-(2*border)-20) ) break;
- pos = ct.findRev(" ");
- ct = ct.left( pos );
- i++;
- }
- xine_osd_draw_text( dvbOSD, 10, y, ct, DVB_TEXT_BLUE );
- if ( !ct.length() || !i ) break;
- cs = cs.right( cs.length()-ct.length()-1 );
- y+= 28;
- }
- y+= 40;
- }
- if ( !dvbCurrentNext[3].isEmpty() ) {
- cs = dvbCurrentNext[3].utf8();
- pos = 0;
- while ( pos!=-1 && y<(h-(2*border)-23) ) {
- ct = cs;
- i = 0;
- while ( pos!=-1 ) {
- xine_osd_get_text_size( dvbOSD, ct, &tw, &th );
- if ( tw<=(w-(2*border)-20) ) break;
- pos = ct.findRev(" ");
- ct = ct.left( pos );
- i++;
- }
- xine_osd_draw_text( dvbOSD, 10, y, ct, DVB_TEXT_WHITE );
- if ( !ct.length() || !i ) break;
- cs = cs.right( cs.length()-ct.length()-1 );
- y+= 28;
- }
- }
- xine_osd_show( dvbOSD, 0 );
- return;
- }
- for ( int j=0; j<(int)dvbCurrentNext.count(); j++ ) {
- if ( (dvbCurrentNext[ j ]=="T") || (dvbCurrentNext[ j ]=="R") ) continue;
- s = dvbCurrentNext[ j ];
- pos = s.find("-");
- c = s.left( pos+1 );
- s = s.right( s.length()-pos-1 );
- ct = cs = s.utf8();
- xine_osd_draw_text( dvbOSD, 10, y, c.utf8(), DVB_TEXT_GREEN );
- xine_osd_get_text_size( dvbOSD, c.utf8(), &offset, &th );
- i=0;
- while ( i<(int)t.length() ) {
- ct = cs.remove( cs.length()-i, cs.length() );
- xine_osd_get_text_size( dvbOSD, ct, &tw, &th );
- if ( tw<=(w-(2*border)-20) ) break;
- i++;
- }
- xine_osd_draw_text( dvbOSD, 10+offset, y, ct, DVB_TEXT_WHITE );
- y+= 28;
- }
- xine_osd_show( dvbOSD, 0 );
- dvbOSDHideTimer.start( 5000, true );
- }
- }
- void KXineWidget::dvbHideOSD()
- {
- if ( dvbOSD ) {
- xine_osd_hide( dvbOSD, 0 );
- xine_osd_free( dvbOSD );
- dvbOSD = 0;
- if (m_dvbChannelName != "")
- m_dvbChannelName = "";
- emit signalDvbOSDHidden();
- }
- }
- void KXineWidget::setDvbCurrentNext( const QString &channelName, const QStringList &list )
- {
- if ( list[0]=="STOP" ) {
- dvbHideOSD();
- return;
- }
- dvbCurrentNext = list;
- m_dvbChannelName = channelName;
- QTimer::singleShot( 0, this, SLOT(dvbShowOSD()) );
- }
- void KXineWidget::setDvb( const QString &pipeName, const QString &chanName, int haveVideo )
- {
- m_trackURL = pipeName;
- m_trackTitle = chanName;
- dvbHaveVideo = haveVideo;
- }
- bool KXineWidget::openDvb()
- {
- if ( dvbOSD ) {
- dvbOSDHideTimer.stop();
- xine_osd_hide( dvbOSD, 0 );
- xine_osd_free( dvbOSD );
- dvbOSD = 0;
- }
- clearQueue();
- m_lengthInfoTimer.stop();
- m_posTimer.stop();
- xine_set_param( m_xineStream, XINE_PARAM_METRONOM_PREBUFFER, 180000);
- if (!xine_open(m_xineStream, m_trackURL.ascii())) {
- sendXineError();
- return false;
- }
- else fprintf(stderr,"xine pipe opened\n");
- m_trackURL = "DVB";
- emit signalXineStatus(i18n("DVB: opening..."));
- QTimer::singleShot( 0, this, SLOT(playDvb()) );
- return true;
- }
- void KXineWidget::slotPlayTimeShift()
- {
- m_lengthInfoTimer.stop();
- m_posTimer.stop();
- xine_set_param( m_xineStream, XINE_PARAM_METRONOM_PREBUFFER, 0);
- if (!xine_open(m_xineStream, TimeShiftFilename.ascii())) {
- sendXineError();
- #ifdef XINE_PARAM_GAPLESS_SWITCH
- if ( xine_check_version(1,1,1) )
- xine_set_param( m_xineStream, XINE_PARAM_GAPLESS_SWITCH, 0);
- #endif
- return;
- }
- if (!xine_play(m_xineStream, 0,0)) {
- sendXineError();
- return;
- }
- m_trackIsSeekable = true;
- m_lengthInfoTimer.start(1000);
- m_posTimer.start(1000);
- }
- void KXineWidget::slotPlay()
- {
- if ((!isXineReady()) || (isQueueEmpty()))
- return;
- if (m_logoFile != NULL && m_trackURL == m_logoFile && isPlaying())
- return;
- /* dvb */
- if ( dvbOSD ) {
- dvbOSDHideTimer.stop();
- xine_osd_hide( dvbOSD, 0 );
- xine_osd_free( dvbOSD );
- dvbOSD = 0;
- }
- m_lengthInfoTimer.stop();
- m_posTimer.stop();
- m_currentSpeed = Normal;
- setCursor(QCursor(Qt::WaitCursor));
- m_trackURL = m_queue.first();
- m_queue.remove(m_queue.find(m_trackURL));
- if (m_trackURL != m_logoFile)
- emit signalXineStatus(i18n("Opening..."));
- /* check for external subtitle file or save url */
- m_trackSubtitleURL = QString::null;
- m_trackSaveURL = QString::null;
- QString ref;
- for (int i = 1; i <= m_trackURL.contains('#'); i++) {
- ref = m_trackURL.section('#', i, i);
- if (ref.section(':', 0, 0) == "subtitle")
- m_trackSubtitleURL = ref.section(':', 1);
- if (ref.section(':', 0, 0) == "save")
- m_trackSaveURL = ref.section(':', 1);
- }
- debugOut(QString("Playing: %1").arg(m_trackURL.local8Bit()));
- xine_set_param( m_xineStream, XINE_PARAM_METRONOM_PREBUFFER, 12000 );
- if (!xine_open(m_xineStream, m_trackURL.local8Bit())) {/** pass mrl local 8Bit encoded **/
- sendXineError();
- setCursor(QCursor(Qt::ArrowCursor));
- #ifdef XINE_PARAM_GAPLESS_SWITCH
- if ( xine_check_version(1,1,1) )
- xine_set_param( m_xineStream, XINE_PARAM_GAPLESS_SWITCH, 0);
- #endif
- return;
- }
- /**** use visualization ? ****/
- #ifndef USE_QT_ONLY
- unwireAudioFilters();
- wireAudioFilters();
- #else
- if ((xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_AUDIO)) &&
- (!xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_VIDEO)))
- {
- if (m_visualPluginName && (!m_xinePost))
- {
- debugOut(QString("Init visual plugin: %1").arg(m_visualPluginName));
- m_xinePost = xine_post_init(m_xineEngine, m_visualPluginName, 0,
- &m_audioDriver,
- &m_videoDriver);
- m_postAudioSource = xine_get_audio_source(m_xineStream);
- m_postInput = (xine_post_in_t*)xine_post_input (m_xinePost, const_cast<char*>("audio in"));
- xine_post_wire(m_postAudioSource, m_postInput);
- }
- }
- else
- {
- if (m_xinePost)
- {
- debugOut(QString("Dispose visual plugin: %1").arg(m_visualPluginName));
- m_postAudioSource = xine_get_audio_source(m_xineStream);
- xine_post_wire_audio_port(m_postAudioSource, m_audioDriver);
- xine_post_dispose(m_xineEngine, m_xinePost);
- m_xinePost = NULL;
- }
- }
- #endif
- /*** play ***/
- int savedPos = m_savedPos;
- m_savedPos = 0;
- if (!xine_play(m_xineStream, savedPos, 0))
- {
- sendXineError();
- setCursor(QCursor(Qt::ArrowCursor));
- return;
- }
- /* do the stream have chapters ? */
- m_trackHasChapters = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_CHAPTERS);
- /** information requirement **/
- m_trackTitle = QString::null;
- bool currentUtf8Locale;
- QTextCodec* testUtf8Local = QTextCodec::codecForLocale();
- if (!strcmp(testUtf8Local->name(),"UTF-8"))
- currentUtf8Locale = true;
- else
- currentUtf8Locale = false;
- QTextCodec *CodecUtf8;
- CodecUtf8 = QTextCodec::codecForName("UTF-8");
- QString infotag;
- infotag = QString::fromLatin1(xine_get_meta_info(m_xineStream, XINE_META_INFO_TITLE));
- if (currentUtf8Locale)
- m_trackTitle = infotag;
- else
- m_trackTitle = QString::fromLocal8Bit(infotag.ascii());
- if (CodecUtf8->heuristicContentMatch(infotag.ascii(), infotag.length()) >= 0)
- m_trackTitle = QString::fromUtf8(infotag.ascii());
- if ((!m_trackTitle.isNull()) && (!m_trackTitle.isEmpty())) /* no meta? */
- {
- QString trackArtist=NULL;
- QString trackAlbum=NULL;
- QString trackComment=NULL;
- trackArtist = QString::fromLatin1(xine_get_meta_info(m_xineStream, XINE_META_INFO_ARTIST));
- trackAlbum = QString::fromLatin1(xine_get_meta_info(m_xineStream, XINE_META_INFO_ALBUM));
- trackComment = QString::fromLatin1(xine_get_meta_info(m_xineStream, XINE_META_INFO_COMMENT));
- if (currentUtf8Locale)
- {
- m_trackArtist = trackArtist;
- m_trackAlbum = trackAlbum;
- m_trackComment = trackComment;
- }
- else
- {
- m_trackArtist = QString::fromLocal8Bit(trackArtist.ascii());
- m_trackAlbum = QString::fromLocal8Bit(trackAlbum.ascii());
- m_trackComment = QString::fromLocal8Bit(trackComment.ascii());
- }
- if (CodecUtf8->heuristicContentMatch(trackArtist.ascii(), trackArtist.length()) >= 0)
- m_trackArtist = QString::fromUtf8(trackArtist.ascii());
- if (CodecUtf8->heuristicContentMatch(trackAlbum.ascii(), trackAlbum.length()) >= 0)
- m_trackAlbum = QString::fromUtf8(trackAlbum.ascii());
- if (CodecUtf8->heuristicContentMatch(trackComment.ascii(), trackComment.length()) >= 0)
- m_trackComment = QString::fromUtf8(trackComment.ascii());
- m_trackYear = xine_get_meta_info(m_xineStream, XINE_META_INFO_YEAR);
- m_trackNumber = xine_get_meta_info(m_xineStream, XINE_META_INFO_TRACK_NUMBER);
- }
- else
- {
- m_trackArtist = QString::null;
- m_trackAlbum = QString::null;
- m_trackNumber = QString::null;
- m_trackYear = QString::null;
- m_trackComment = QString::null;
- }
- m_trackHasVideo = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_VIDEO);
- if (m_trackHasVideo)
- {
- m_trackVideoCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_VIDEOCODEC);
- m_videoFrameWidth = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_WIDTH);
- m_videoFrameHeight = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_HEIGHT);
- m_trackVideoBitrate = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_BITRATE);
- }
- else
- {
- m_trackVideoCodec = QString::null;
- m_videoFrameWidth = 0;
- m_videoFrameHeight = 0;
- m_trackVideoBitrate = 0;
- }
- m_trackHasAudio = (bool)xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_AUDIO);
- if (m_trackHasAudio)
- {
- m_trackAudioCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_AUDIOCODEC);
- m_trackAudioBitrate = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_AUDIO_BITRATE);
- }
- else
- {
- m_trackAudioCodec = QString::null;
- m_trackAudioBitrate = 0;
- }
- /*** we need a little delay for some meta info ***/
- QTimer::singleShot(1000, this, SLOT(slotGetInfoDelayed()));
- m_trackLength = getLengthInfo();
- if ((m_trackLength.isNull()) && (m_trackURL != m_logoFile))
- {
- debugOut("Wait for valid length information");
- m_lengthInfoTries = 0;
- m_lengthInfoTimer.start(1000); /* wait for available track length info */
- }
- if (m_trackTitle.isNull() || m_trackTitle.isEmpty())
- {
- /* no meta info */
- m_trackTitle = m_trackURL;
- }
- slotSetAudioChannel(0); //refresh channel info
- if (m_trackURL != m_logoFile)
- m_posTimer.start(500);
- setCursor(QCursor(Qt::ArrowCursor));
- if (m_trackURL != m_logoFile)
- {
- emit signalXinePlaying();
- if (hasSaveURL())
- emit signalXineStatus(i18n("Recording"));
- else
- emit signalXineStatus(i18n("Playing"));
- }
- }
- int KXineWidget::getVideoWidth()
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_WIDTH);
- }
- int KXineWidget::getVideoHeight()
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_HEIGHT);
- }
- void KXineWidget::slotGetInfoDelayed()
- {
- if (!m_xineStream)
- return;
- if (m_trackHasVideo)
- m_trackVideoCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_VIDEOCODEC);
- if (m_trackHasAudio)
- m_trackAudioCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_AUDIOCODEC);
- }
- /****** error processing ****/
- void KXineWidget::sendXineError()
- {
- QString error;
- int errCode = xine_get_error(m_xineStream);
- QString addInfo;
- QString audioCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_AUDIOCODEC);
- QString videoCodec = xine_get_meta_info(m_xineStream, XINE_META_INFO_VIDEOCODEC);
- if ((!audioCodec.isEmpty()) || (!videoCodec.isEmpty()))
- {
- if (!audioCodec.isEmpty())
- addInfo.append(QString("(") + i18n("Audio Codec") + ": " + audioCodec + ")");
- if (!videoCodec.isEmpty())
- addInfo.append(QString("(") + i18n("Video Codec") + ": " + videoCodec + ")");
- }
- else
- addInfo.append(QString("(") + m_trackURL + ")");
- switch (errCode)
- {
- case XINE_ERROR_NO_INPUT_PLUGIN:
- case XINE_ERROR_NO_DEMUX_PLUGIN:
- {
- error = i18n("No plugin found to handle this resource") + " " + addInfo;
- break;
- }
- case XINE_ERROR_DEMUX_FAILED:
- {
- error = i18n("Resource seems to be broken") + " (" + m_trackURL + ")";
- break;
- }
- case XINE_ERROR_MALFORMED_MRL:
- {
- error = i18n("Requested resource does not exist") + " (" + m_trackURL + ")";
- break;
- }
- case XINE_ERROR_INPUT_FAILED:
- {
- error = i18n("Resource can not be opened") + " (" + m_trackURL + ")";
- break;
- }
- default:
- {
- error = i18n("Generic error") + " (" + m_trackURL + ")";
- break;
- }
- }
- if (isQueueEmpty())
- {
- if (m_trackURL != m_logoFile)
- {
- emit signalXineStatus(i18n("Error"));
- emit signalXineError(error);
- }
- else
- errorOut("Can't find/play logo file!");
- }
- else
- {
- errorOut(error);
- errorOut(QString("Can't play: %1 - trying next").arg(m_trackURL));
- QTimer::singleShot(0, this, SLOT(slotPlay()));
- }
- }
- bool KXineWidget::isPlaying() const
- {
- if (isXineReady())
- return ((xine_get_status(m_xineStream) == XINE_STATUS_PLAY) && (m_trackURL != m_logoFile));
- else
- return false;
- }
- QString KXineWidget::getXineLog() const
- {
- QString logStr;
- int i = 0;
- QTextStream ts(&logStr, IO_WriteOnly);
- const char* const* log = xine_get_log(m_xineEngine, /* XINE_LOG_MSG*/ 0);
- while(log[i])
- {
- ts << QString::fromLocal8Bit(log[i]);
- i++;
- }
- return logStr;
- }
- void KXineWidget::showOSDMessage(const QString& message, uint duration, int priority)
- {
- if ((!m_osd) || (!m_osdShow) || (isHidden()))
- return;
- static int prevOsdPriority = 0;
- if (m_osdTimer.isActive() && prevOsdPriority > priority)
- return;
- prevOsdPriority = priority;
- //debugOut(QString("OSD: draw text: %1").arg(message));
- xine_osd_clear(m_osd);
- xine_osd_draw_text(m_osd, 0, 0, message.local8Bit(), XINE_OSD_TEXT1);
- if (m_osdUnscaled)
- xine_osd_show_unscaled(m_osd, 0);
- else
- xine_osd_show(m_osd, 0);
- m_osdTimer.start(duration);
- }
- void KXineWidget::slotOSDHide()
- {
- xine_osd_hide(m_osd, 0);
- m_osdTimer.stop();
- }
- #ifndef USE_QT_ONLY
- /****************** postprocessing filter management ****************/
- QStringList KXineWidget::getVideoFilterNames() const
- {
- QStringList filters;
- const char* const* plugins = xine_list_post_plugins_typed(m_xineEngine, XINE_POST_TYPE_VIDEO_FILTER);
- for (int i = 0; plugins[i]; i++)
- {
- filters << plugins[i];
- }
- return filters;
- }
- QStringList KXineWidget::getAudioFilterNames() const
- {
- QStringList filters;
- const char* const* plugins = xine_list_post_plugins_typed(m_xineEngine, XINE_POST_TYPE_AUDIO_FILTER);
- for (int i = 0; plugins[i]; i++)
- {
- filters << plugins[i];
- }
- return filters;
- }
- #endif
- void KXineWidget::slotCreateVideoFilter(const QString& name, QWidget* parent)
- {
- #ifndef USE_QT_ONLY
- unwireVideoFilters();
- PostFilter* filter = new PostFilter(name, m_xineEngine, m_audioDriver, m_videoDriver, parent);
- connect(filter, SIGNAL(signalDeleteMe(PostFilter*)), this, SLOT(slotDeleteVideoFilter(PostFilter*)));
- m_videoFilterList.append(filter);
- wireVideoFilters();
- #else
- parent = parent;
- warningOut(QString("Not implemented [CreateVideoFilter %1]").arg(name));
- #endif
- }
- void KXineWidget::slotCreateAudioFilter(const QString& name, QWidget* parent)
- {
- #ifndef USE_QT_ONLY
- unwireAudioFilters();
- PostFilter* filter = new PostFilter(name, m_xineEngine, m_audioDriver, m_videoDriver, parent);
- connect(filter, SIGNAL(signalDeleteMe(PostFilter*)), this, SLOT(slotDeleteAudioFilter(PostFilter*)));
- m_audioFilterList.append(filter);
- wireAudioFilters();
- #else
- parent = parent;
- warningOut(QString("Not implemented [CreateAudioFilter %1]").arg(name));
- #endif
- }
- void KXineWidget::slotRemoveAllVideoFilters()
- {
- #ifndef USE_QT_ONLY
- unwireVideoFilters();
- while (m_videoFilterList.count())
- m_videoFilterList.removeLast();
- wireVideoFilters();
- #else
- warningOut("Not implemented!");
- #endif
- }
- void KXineWidget::slotRemoveAllAudioFilters()
- {
- #ifndef USE_QT_ONLY
- unwireAudioFilters();
- while (m_audioFilterList.count())
- m_audioFilterList.removeLast();
- wireAudioFilters();
- #else
- warningOut("Not implemented!");
- #endif
- }
- void KXineWidget::slotDeleteVideoFilter(PostFilter* filter)
- {
- #ifndef USE_QT_ONLY
- unwireVideoFilters();
- m_videoFilterList.remove(filter);
- wireVideoFilters();
- #else
- filter = filter;
- warningOut("Not implemented!");
- #endif
- }
- void KXineWidget::slotDeleteAudioFilter(PostFilter* filter)
- {
- #ifndef USE_QT_ONLY
- unwireAudioFilters();
- m_audioFilterList.remove(filter);
- wireAudioFilters();
- #else
- filter = filter;
- warningOut("Not implemented!");
- #endif
- }
- #ifndef USE_QT_ONLY
- void KXineWidget::unwireVideoFilters()
- {
- if (m_xineStream && m_videoDriver)
- xine_post_wire_video_port(xine_get_video_source(m_xineStream), m_videoDriver);
- }
- void KXineWidget::wireVideoFilters()
- {
- if (!m_xineStream)
- {
- debugOut("wireVideoFilters() - xine stream not initialized, nothing happend.");
- return;
- }
- QPtrList<PostFilter> activeList;
- if (m_videoFilterList.count() && m_videoFiltersEnabled)
- activeList = m_videoFilterList;
- if (m_deinterlaceFilter && m_deinterlaceEnabled )
- activeList.insert (0, m_deinterlaceFilter);
- if (activeList.count())
- {
- xine_post_wire_video_port(activeList.at(activeList.count()-1)->getOutput(), m_videoDriver);
- for (uint i = activeList.count()-1; i >0; i--)
- {
- xine_post_wire(activeList.at( i-1 )->getOutput(), activeList.at(i)->getInput());
- }
- xine_post_wire( xine_get_video_source(m_xineStream), activeList.at(0)->getInput());
- }
- }
- void KXineWidget::unwireAudioFilters()
- {
- if (m_xineStream && m_audioDriver)
- xine_post_wire_audio_port( xine_get_audio_source (m_xineStream), m_audioDriver);
- }
- void KXineWidget::wireAudioFilters()
- {
- if (!m_xineStream)
- {
- debugOut("wireAudioFilters() - xine stream not initialized, nothing happend.");
- return;
- }
- QPtrList<PostFilter> activeList;
- if (m_audioFilterList.count() && m_audioFiltersEnabled)
- activeList = m_audioFilterList;
- if ((xine_get_stream_info (m_xineStream, XINE_STREAM_INFO_HAS_AUDIO)) &&
- (!xine_get_stream_info (m_xineStream, XINE_STREAM_INFO_HAS_VIDEO)) &&
- m_visualPluginName.ascii())
- {
- if (!m_visualPlugin)
- {
- debugOut(QString("Init visual plugin: %1").arg(m_visualPluginName));
- m_visualPlugin = new PostFilter(m_visualPluginName, m_xineEngine, m_audioDriver, m_videoDriver, NULL);
- }
- activeList.insert (0, m_visualPlugin);
- }
- else
- {
- if (m_visualPlugin)
- {
- debugOut(QString("Dispose visual plugin: %1").arg(m_visualPluginName));
- delete m_visualPlugin;
- m_visualPlugin = NULL;
- }
- }
- if (activeList.count())
- {
- xine_post_wire_audio_port(activeList.at(activeList.count()-1)->getOutput(), m_audioDriver);
- for (uint i = activeList.count()-1; i >0; i--)
- {
- xine_post_wire(activeList.at(i-1)->getOutput(), activeList.at(i)->getInput());
- }
- xine_post_wire( xine_get_audio_source(m_xineStream), activeList.at(0)->getInput());
- }
- }
- #endif
- void KXineWidget::slotEnableVideoFilters(bool enable)
- {
- #ifndef USE_QT_ONLY
- m_videoFiltersEnabled = enable;
- unwireVideoFilters();
- wireVideoFilters();
- #else
- enable = enable;
- warningOut("Not implemented!");
- #endif
- }
- void KXineWidget::slotEnableAudioFilters(bool enable)
- {
- #ifndef USE_QT_ONLY
- m_audioFiltersEnabled = enable;
- unwireAudioFilters();
- wireAudioFilters();
- #else
- enable = enable;
- warningOut("Not implemented!");
- #endif
- }
- #ifndef USE_QT_ONLY
- QStringList KXineWidget::getAudioFilterConfig()
- {
- QStringList configStrings;
- for (uint i=0; i<m_audioFilterList.count(); i++)
- configStrings << m_audioFilterList.at(i)->getConfig();
- return configStrings;
- }
- QStringList KXineWidget::getVideoFilterConfig()
- {
- QStringList configStrings;
- for (uint i=0; i<m_videoFilterList.count(); i++)
- configStrings << m_videoFilterList.at(i)->getConfig();
- return configStrings;
- }
- #endif
- /**** visual plugin **********/
- QStringList KXineWidget::getVisualPlugins() const
- {
- QStringList visuals;
- const char* const* plugins = xine_list_post_plugins_typed(m_xineEngine, XINE_POST_TYPE_AUDIO_VISUALIZATION);
- for (int i = 0; plugins[i]; i++)
- {
- visuals << plugins[i];
- }
- return visuals;
- }
- /**************** change visualization plugin *****************/
- void KXineWidget::slotSetVisualPlugin(const QString& visual)
- {
- if (m_visualPluginName == visual) return;
- debugOut(QString("New visualization plugin: %1").arg(visual));
- #ifndef USE_QT_ONLY
- unwireAudioFilters();
- if(m_visualPlugin)
- {
- delete m_visualPlugin;
- m_visualPlugin = NULL;
- }
- if (visual == "none")
- m_visualPluginName = QString::null;
- else
- m_visualPluginName = visual;
- wireAudioFilters();
- #else
- if (visual == "none")
- m_visualPluginName = QString::null;
- else
- m_visualPluginName = visual;
- if (m_xinePost)
- {
- xine_post_out_t *pp;
- pp = xine_get_audio_source(m_xineStream);
- xine_post_wire_audio_port(pp, m_audioDriver);
- xine_post_dispose(m_xineEngine, m_xinePost);
- m_xinePost = NULL;
- }
- if ( (xine_get_status(m_xineStream ) == XINE_STATUS_PLAY)
- && (!xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_VIDEO)) && (m_visualPluginName) )
- {
- m_xinePost = xine_post_init(m_xineEngine, m_visualPluginName, 0, &m_audioDriver, &m_videoDriver);
- m_postAudioSource = xine_get_audio_source(m_xineStream);
- m_postInput = (xine_post_in_t*)xine_post_input(m_xinePost, const_cast<char*>("audio in"));
- xine_post_wire(m_postAudioSource, m_postInput);
- }
- #endif
- }
- /*****/
- void KXineWidget::getAutoplayPlugins(QStringList& autoPlayList) const
- {
- char** pluginIds = NULL;
- int i = 0;
- pluginIds = (char**)xine_get_autoplay_input_plugin_ids(m_xineEngine);
- while(pluginIds[i])
- {
- autoPlayList << pluginIds[i];
- autoPlayList << xine_get_input_plugin_description(m_xineEngine, pluginIds[i]);
- i++;
- }
- }
- bool KXineWidget::getAutoplayPluginURLS(const QString& plugin, QStringList& list)
- {
- char** urls = NULL;
- int num;
- int i = 0;
- urls = xine_get_autoplay_mrls(m_xineEngine, plugin.ascii(), &num);
- if (urls)
- {
- while (urls[i])
- {
- list << urls[i];
- i++;
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- void KXineWidget::slotSetVolume(int vol)
- {
- if (!isXineReady()) return;
- if (m_softwareMixer)
- {
- //debugOut(QString("Set software amplification level: %1").arg(vol));
- if (m_volumeGain)
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, vol*2);
- else
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, vol);
- }
- else
- {
- //debugOut(QString("Set audio mixer volume: %1").arg(vol));
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_VOLUME, vol);
- }
- emit signalXineStatus(i18n("Volume") + ": " + QString::number(vol) +"%");
- }
- uint KXineWidget::getVolume() const
- {
- if (!isXineReady()) return 0;
- uint vol;
- if (m_softwareMixer)
- {
- vol = xine_get_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL);
- if (vol > 200)
- {
- // when amp is high > 100, xine_get_param sometimes returns incorrect amp level
- errorOut("Amp level returned weird results, set Amp to 100");
- vol = 100;
- }
- if (m_volumeGain) vol = vol/2;
- }
- else
- {
- vol = xine_get_param(m_xineStream, XINE_PARAM_AUDIO_VOLUME);
- }
- return vol;
- }
- void KXineWidget::slotToggleMute()
- {
- int muteParam;
- if (m_softwareMixer)
- muteParam = XINE_PARAM_AUDIO_AMP_MUTE;
- else
- muteParam = XINE_PARAM_AUDIO_MUTE;
- if (xine_get_param(m_xineStream, muteParam))
- {
- xine_set_param(m_xineStream, muteParam, 0); /* mute off */
- emit signalXineStatus(i18n("Mute") + ": " + i18n("Off"));
- }
- else
- {
- xine_set_param(m_xineStream, muteParam, 1); /* mute on */
- emit signalXineStatus(i18n("Mute") + ": " + i18n("On"));
- }
- }
- bool KXineWidget::SoftwareMixing() const
- {
- if (m_softwareMixer)
- return true;
- else
- return false;
- }
- void KXineWidget::mouseMoveEvent(QMouseEvent* mev)
- {
- if (!m_xineReady) return;
- if (cursor().shape() == Qt::BlankCursor)
- {
- setCursor(QCursor(Qt::ArrowCursor));
- }
- x11_rectangle_t rect;
- xine_event_t event;
- xine_input_data_t input;
- rect.x = mev->x();
- rect.y = mev->y();
- rect.w = 0;
- rect.h = 0;
- xine_port_send_gui_data (m_videoDriver, XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO, (void*)&rect);
- event.type = XINE_EVENT_INPUT_MOUSE_MOVE;
- event.data = &input;
- event.data_length = sizeof(input);
- input.button = 0;
- input.x = rect.x;
- input.y = rect.y;
- xine_event_send(m_xineStream, &event);
- mev->ignore();
- }
- void KXineWidget::mousePressEvent(QMouseEvent* mev)
- {
- if (!m_xineReady) return;
- int cur = cursor().shape();
- if (mev->button() == Qt::MidButton)
- {
- emit signalMiddleClick();
- mev->ignore();
- return;
- }
- if (mev->button() == Qt::RightButton)
- {
- if ( (cur == Qt::ArrowCursor) || (cur == Qt::BlankCursor) )
- {
- emit signalRightClick(mev->globalPos());
- mev->accept();
- return;
- }
- }
- if (mev->button() == Qt::LeftButton)
- {
- if ( (cur == Qt::ArrowCursor) || (cur == Qt::BlankCursor) )
- {
- emit signalLeftClick(mev->globalPos());
- mev->ignore();
- return;
- }
- x11_rectangle_t rect;
- xine_event_t event;
- xine_input_data_t input;
- rect.x = mev->x();
- rect.y = mev->y();
- rect.w = 0;
- rect.h = 0;
- xine_port_send_gui_data(m_videoDriver, XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO, (void*)&rect);
- event.type = XINE_EVENT_INPUT_MOUSE_BUTTON;
- event.data = &input;
- event.data_length = sizeof(input);
- input.button = 1;
- input.x = rect.x;
- input.y = rect.y;
- xine_event_send (m_xineStream, &event);
- mev->accept(); /* don't send event to parent */
- }
- }
- void KXineWidget::mouseDoubleClickEvent(QMouseEvent* mev)
- {
- emit signalDoubleClick();
- mev->ignore();
- }
- void KXineWidget::wheelEvent(QWheelEvent* e)
- {
- int oldVal = getPosition();
- if (oldVal == 0) // no valid position
- return;
- float offset = log10( QABS(e->delta()) ) / 0.002;
- int newVal = 0;
- if (e->delta()>0)
- newVal = oldVal - int(offset);
- else
- newVal = oldVal + int(offset);
- if (newVal < 0) newVal = 0;
- slotSeekToPosition(newVal);
- e->accept();
- }
- void KXineWidget::playNextChapter() const
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_NEXT;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::playPreviousChapter() const
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_PREVIOUS;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotStop()
- {
- m_posTimer.stop();
- if ( m_lengthInfoTimer.isActive() ) m_lengthInfoTimer.stop();
- //emit signalNewPosition(0, QTime());
- if ((m_logoFile.isNull()) && (isPlaying()))
- xine_stop(m_xineStream);
- else
- {
- appendToQueue(m_logoFile);
- QTimer::singleShot(0, this, SLOT(slotPlay()));
- }
- emit signalXineStatus(i18n("Stop"));
- }
- void KXineWidget::slotSetAudiocdDevice(const QString& device)
- {
- debugOut(QString("Set AudioCD device to %1").arg(device));
- xine_cfg_entry_t config;
- xine_config_lookup_entry(m_xineEngine, "input.cdda_device", &config);
- if (m_cachedCDPath.isNull())
- m_cachedCDPath = config.str_value;
- config.str_value = (char*)device.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- void KXineWidget::slotSetVcdDevice(const QString& device)
- {
- debugOut(QString("Set VCD device to %1").arg(device));
- xine_cfg_entry_t config;
- xine_config_lookup_entry(m_xineEngine, "input.vcd_device", &config);
- if (m_cachedVCDPath.isNull())
- m_cachedVCDPath = config.str_value;
- config.str_value = (char*)device.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- void KXineWidget::slotSetDvdDevice(const QString& device)
- {
- debugOut(QString("Set DVD device to %1").arg(device));
- xine_cfg_entry_t config;
- xine_config_lookup_entry(m_xineEngine, "input.dvd_device", &config);
- if (m_cachedDVDPath.isNull())
- m_cachedDVDPath = config.str_value;
- config.str_value = (char*)device.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- QString KXineWidget::audiocdDevice() const
- {
- xine_cfg_entry_t config;
- xine_config_lookup_entry(m_xineEngine, "input.cdda_device", &config);
- return QString(config.str_value);
- }
- QString KXineWidget::vcdDevice() const
- {
- xine_cfg_entry_t config;
- xine_config_lookup_entry(m_xineEngine, "input.vcd_device", &config);
- return QString(config.str_value);
- }
- QString KXineWidget::dvdDevice() const
- {
- xine_cfg_entry_t config;
- xine_config_lookup_entry(m_xineEngine, "input.dvd_device", &config);
- return QString(config.str_value);
- }
- #if XINE_MAJOR_VERSION >= 1 && XINE_MINOR_VERSION >= 1
- uint KXineWidget::currentDVDTitleNumber() const
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_DVD_TITLE_NUMBER);
- }
- uint KXineWidget::getDVDTitleCount() const
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_DVD_TITLE_COUNT);
- }
- uint KXineWidget::currentDVDChapterNumber() const
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER);
- }
- uint KXineWidget::getDVDChapterCount() const
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_DVD_CHAPTER_COUNT);
- }
- uint KXineWidget::currentDVDAngleNumber() const
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER);
- }
- uint KXineWidget::getDVDAngleCount() const
- {
- return xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_DVD_ANGLE_COUNT);
- }
- #endif
- void KXineWidget::setStreamSaveDir(const QString& dir)
- {
- xine_cfg_entry_t config;
- if (!xine_config_lookup_entry(m_xineEngine, "misc.save_dir", &config)) return; /* older xine-lib */
- debugOut(QString("Set misc.save_dir to: %1").arg(dir));
- config.str_value = (char*)dir.latin1();
- xine_config_update_entry (m_xineEngine, &config);
- }
- const QString KXineWidget::getStreamSaveDir()
- {
- xine_cfg_entry_t config;
- if (!xine_config_lookup_entry(m_xineEngine, "misc.save_dir", &config)) return QString::null; /* older xine-lib */
- return QString(config.str_value);
- }
- void KXineWidget::setBroadcasterPort(const uint port)
- {
- debugOut(QString("Set broadcaster port to %1").arg(port));
- xine_set_param(m_xineStream, XINE_PARAM_BROADCASTER_PORT, port);
- }
- void KXineWidget::slotSpeedPause()
- {
- if (m_currentSpeed == Pause)
- {
- slotSpeedNormal();
- }
- else if (m_trackURL != m_logoFile) // don't pause logo
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
- m_posTimer.stop();
- if (m_currentSpeed != Undefined)
- emit signalXineStatus(i18n("Pause"));
- m_currentSpeed = Pause;
- }
- }
- void KXineWidget::slotSpeedNormal()
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
- m_posTimer.start(500);
- m_currentSpeed = Normal;
- emit signalXineStatus(i18n("Playing") + " ");
- }
- void KXineWidget::slotSpeedFaster()
- {
- switch (m_currentSpeed)
- {
- case Fast1:
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_FAST_4);
- m_currentSpeed = Fast2;
- emit signalXineStatus(i18n("Fast Forward %1").arg("x2"));
- break;
- }
- case Fast2:
- {
- slotSpeedNormal();
- break;
- }
- case Slow1:
- {
- slotSpeedNormal();
- break;
- }
- case Slow2:
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_2);
- m_currentSpeed = Slow1;
- emit signalXineStatus(i18n("Slow Motion %1").arg("x1"));
- break;
- }
- default:
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_FAST_2);
- m_currentSpeed = Fast1;
- emit signalXineStatus(i18n("Fast Forward %1").arg("x1"));
- break;
- }
- }
- }
- void KXineWidget::slotSpeedSlower()
- {
- switch (m_currentSpeed)
- {
- case Slow1:
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_4);
- m_currentSpeed = Slow2;
- emit signalXineStatus(i18n("Slow Motion %1").arg("x2"));
- break;
- }
- case Slow2:
- {
- slotSpeedNormal();
- break;
- }
- case Fast1:
- {
- slotSpeedNormal();
- break;
- }
- case Fast2:
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_FAST_2);
- m_currentSpeed = Fast1;
- emit signalXineStatus(i18n("Fast Forward %1").arg("x1"));
- break;
- }
- default:
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPEED, XINE_SPEED_SLOW_2);
- m_currentSpeed = Slow1;
- emit signalXineStatus(i18n("Slow Motion %1").arg("x1"));
- break;
- }
- }
- }
- QString KXineWidget::getSupportedExtensions() const
- {
- return xine_get_file_extensions(m_xineEngine);
- }
- void KXineWidget::slotSetAudioChannel(int ch)
- {
- debugOut(QString("Switch to audio channel %1").arg(ch-1));
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, ch-1);
- }
- void KXineWidget::slotSetSubtitleChannel(int ch)
- {
- debugOut(QString("Switch to subtitle channel %1").arg(ch-1));
- xine_set_param(m_xineStream, XINE_PARAM_SPU_CHANNEL, ch-1);
- }
- void KXineWidget::slotSetFileSubtitles(QString url)
- {
- int pos;
- int time;
- int length;
- m_queue.prepend(url);
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( ret == 0 )
- {
- debugOut("No valid stream position information");
- return;
- }
- if (isPlaying())
- xine_stop(m_xineStream);
- m_posTimer.stop();
- slotPlay();
- slotSeekToPosition(pos);
- }
- uint KXineWidget::getPosition() const
- {
- if (!m_xineReady) return 0;
- int pos, time, length;
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( ret == 0 )
- {
- debugOut("No valid stream position information");
- return 0;
- }
- return (uint)pos;
- }
- QTime KXineWidget::getPlaytime() const
- {
- if (!m_xineReady) return QTime();
- int pos, time, length;
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( ret == 0 )
- {
- debugOut("No valid stream position information");
- return QTime();
- }
- return msToTime(time);
- }
- void KXineWidget::slotSendPosition()
- {
- if (!m_xineReady) return;
- int pos, time, length;
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( ret == 0 )
- {
- debugOut("No valid stream position information");
- return;
- }
- emit signalNewPosition(pos, msToTime(time));
- }
- void KXineWidget::slotStartSeeking()
- {
- debugOut("Seeking started");
- m_posTimer.stop();
- }
- void KXineWidget::slotSeekToPosition(int pos)
- {
- if ((!isXineReady()) || (!isPlaying()) || (!isSeekable())) return;
- bool pause = false;
- if (m_currentSpeed == Pause)
- pause = true;
- xine_play(m_xineStream, pos, 0);
- double length = QTime().msecsTo(getLengthInfo());
- length = (length * pos)/65535;
- QTime time = QTime().addMSecs((int)length);
- emit signalNewPosition(pos, time);
- emit signalXineStatus(i18n("Position") + ": " + time.toString("h:mm:ss"));
- if (pause)
- {
- m_currentSpeed = Undefined;
- slotSpeedPause();
- }
- }
- void KXineWidget::slotSeekToTime(const QTime& postime)
- {
- if ((!isXineReady()) || (!isPlaying()) || (!isSeekable())) return;
- bool pause = false;
- if (m_currentSpeed == Pause)
- pause = true;
- xine_play(m_xineStream, 0, QTime().msecsTo(postime));
- double length = QTime().msecsTo(getLengthInfo());
- double posfract = QTime().msecsTo(postime);
- posfract = (posfract / length) * 65535;
- emit signalNewPosition((int)posfract, postime);
- emit signalXineStatus(i18n("Position") + ": " + postime.toString("h:mm:ss"));
- if (pause)
- {
- m_currentSpeed = Undefined;
- slotSpeedPause();
- }
- }
- void KXineWidget::slotStopSeeking()
- {
- debugOut("Seeking stopped");
- m_posTimer.start(500, false);
- }
- void KXineWidget::slotEject()
- {
- xine_eject(m_xineStream);
- }
- void KXineWidget::slotEnableAutoresize(bool enable)
- {
- m_autoresizeEnabled = enable;
- if (!m_autoresizeEnabled)
- {
- m_videoFrameHeight = 0;
- m_videoFrameWidth = 0;
- }
- }
- /***************************************
- * tvtime deinterlacer plugin *
- ***************************************/
- #ifndef USE_QT_ONLY
- void KXineWidget::createDeinterlacePlugin(const QString& config, QWidget* parent)
- {
- m_deinterlaceFilter = new PostFilter(config.section(':',0,0), m_xineEngine, m_audioDriver, m_videoDriver, parent);
- if( !m_deinterlaceFilter->getInput() || !m_deinterlaceFilter->getOutput() )
- {
- delete m_deinterlaceFilter;
- m_deinterlaceFilter = NULL;
- }
- slotSetDeinterlaceConfig(config);
- }
- const QString KXineWidget::getDeinterlaceConfig() const
- {
- if (m_deinterlaceFilter)
- return m_deinterlaceFilter->getConfig();
- return DEFAULT_TVTIME_CONFIG;
- }
- #endif
- void KXineWidget::slotSetDeinterlaceConfig(const QString& config)
- {
- #ifndef USE_QT_ONLY
- if (m_deinterlaceFilter)
- m_deinterlaceFilter->setConfig(config);
- #else
- warningOut(QString ("Not implemented [SetDeinterlaceConfig %1]").arg(config));
- #endif
- }
- void KXineWidget::slotToggleDeinterlace()
- {
- #ifndef USE_QT_ONLY
- QString s;
- if (m_deinterlaceFilter)
- {
- m_deinterlaceEnabled = !m_deinterlaceEnabled;
- debugOut(QString("Deinterlace enabled: %1").arg(m_deinterlaceEnabled));
- if ( m_deinterlaceEnabled ) s = i18n("Deinterlace: on");
- else s = i18n("Deinterlace: off");
- showOSDMessage( s, 2000 );
- unwireVideoFilters();
- wireVideoFilters();
- }
- else
- {
- /* fallback - this method is deprecated */
- if (xine_get_param(m_xineStream, XINE_PARAM_VO_DEINTERLACE))
- xine_set_param(m_xineStream, XINE_PARAM_VO_DEINTERLACE, false);
- else
- xine_set_param(m_xineStream, XINE_PARAM_VO_DEINTERLACE, true);
- }
- #else
- warningOut("Not implemented!");
- #endif
- }
- /**************************/
- void KXineWidget::slotAspectRatioAuto()
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
- emit signalXineStatus(i18n("Aspect Ratio") + ": " + i18n("Auto"));
- }
- void KXineWidget::slotAspectRatio4_3()
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
- emit signalXineStatus(i18n("Aspect Ratio") + ": " + i18n("4:3"));
- }
- void KXineWidget::slotAspectRatioAnamorphic()
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
- emit signalXineStatus(i18n("Aspect Ratio") + ": " + i18n("16:9"));
- }
- void KXineWidget::slotAspectRatioSquare()
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_SQUARE);
- emit signalXineStatus(i18n("Aspect Ratio") + ": " + i18n("1:1"));
- }
- void KXineWidget::slotAspectRatioDVB()
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_DVB);
- emit signalXineStatus(i18n("Aspect Ratio") + ": " + i18n("2.11:1"));
- }
- void KXineWidget::slotZoomOutX()
- {
- if ((m_currentZoomX - 5) >= 100)
- {
- m_currentZoomX -= 5;
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_X, m_currentZoomX);
- emit signalXineStatus(i18n("Zoom X") + ": " + QString::number(m_currentZoomX) + "%");
- }
- }
- void KXineWidget::slotZoomInX()
- {
- if ((m_currentZoomX + 5) <= XINE_VO_ZOOM_MAX)
- {
- m_currentZoomX += 5;
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_X, m_currentZoomX);
- emit signalXineStatus(i18n("Zoom X") + ": " + QString::number(m_currentZoomX) + "%");
- }
- }
- void KXineWidget::slotZoomOutY()
- {
- if ((m_currentZoomY - 5) >= 100)
- {
- m_currentZoomY -= 5;
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_Y, m_currentZoomY);
- emit signalXineStatus(i18n("Zoom Y") + ": " + QString::number(m_currentZoomY) + "%");
- }
- }
- void KXineWidget::slotZoomInY()
- {
- if ((m_currentZoomY + 5) <= XINE_VO_ZOOM_MAX)
- {
- m_currentZoomY += 5;
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_Y, m_currentZoomY);
- emit signalXineStatus(i18n("Zoom Y") + ": " + QString::number(m_currentZoomY) + "%");
- }
- }
- void KXineWidget::slotZoomOut()
- {
- if ((m_currentZoom - 5) >= 100)
- {
- m_currentZoom -= 5;
- m_currentZoomX = m_currentZoomY = m_currentZoom;
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_X, m_currentZoom);
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_Y, m_currentZoom);
- emit signalXineStatus(i18n("Zoom") + ": " + QString::number(m_currentZoom) + "%");
- }
- }
- void KXineWidget::slotZoomIn()
- {
- if ((m_currentZoom + 5) <= XINE_VO_ZOOM_MAX)
- {
- m_currentZoom += 5;
- m_currentZoomX = m_currentZoomY = m_currentZoom;
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_X, m_currentZoom);
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_Y, m_currentZoom);
- emit signalXineStatus(i18n("Zoom") + ": " + QString::number(m_currentZoom) + "%");
- }
- }
- void KXineWidget::slotZoomOff()
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_X, 100);
- xine_set_param(m_xineStream, XINE_PARAM_VO_ZOOM_Y, 100);
- m_currentZoom = 100;
- m_currentZoomX = m_currentZoomY = m_currentZoom;
- emit signalXineStatus(i18n("Zoom") + ": " + QString::number(m_currentZoom) + "%");
- }
- QTime KXineWidget::getLengthInfo()
- {
- int pos, time, length;
- int t = 0, ret = 0;
- while(((ret = xine_get_pos_length(m_xineStream, &pos, &time, &length)) == 0) && (++t < 5))
- xine_usec_sleep(100000);
- if ( (ret != 0) && (length > 0) )
- {
- return msToTime(length);
- }
- return QTime();
- }
- void KXineWidget::slotEmitLengthInfo()
- {
- QTime length = getLengthInfo();
- if (!(length.isNull()))
- {
- if ( m_trackURL!="DVB" ) m_lengthInfoTimer.stop();
- m_trackLength = length;
- emit signalLengthChanged();
- }
- else
- {
- if (m_lengthInfoTries > 10) // wait 10 seconds
- m_lengthInfoTimer.stop();
- else
- {
- debugOut("Wait for valid length information");
- m_lengthInfoTries ++;
- }
- }
- }
- void KXineWidget::globalPosChanged()
- {
- QPoint g = mapToGlobal(QPoint(0,0));
- m_globalX = g.x();
- m_globalY = g.y();
- }
- const xine_t* const KXineWidget::getXineEngine()const
- {
- return m_xineEngine;
- }
- /************ video settings ****************/
- void KXineWidget::getVideoSettings(int& hue, int& sat, int& contrast, int& bright,
- int& avOffset, int& spuOffset) const
- {
- hue = xine_get_param(m_xineStream, XINE_PARAM_VO_HUE);
- sat = xine_get_param(m_xineStream, XINE_PARAM_VO_SATURATION);
- contrast = xine_get_param(m_xineStream, XINE_PARAM_VO_CONTRAST);
- bright = xine_get_param(m_xineStream, XINE_PARAM_VO_BRIGHTNESS);
- avOffset = xine_get_param(m_xineStream, XINE_PARAM_AV_OFFSET);
- spuOffset = xine_get_param(m_xineStream, XINE_PARAM_SPU_OFFSET);
- }
- void KXineWidget::slotSetHue(int hue)
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_HUE, hue);
- emit signalXineStatus(i18n("Hue") + ": " + QString::number((hue*100)/65535) + "%");
- }
- void KXineWidget::slotSetSaturation(int sat)
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_SATURATION, sat);
- emit signalXineStatus(i18n("Saturation") + ": " + QString::number((sat*100)/65535) + "%");
- }
- void KXineWidget::slotSetContrast(int contrast)
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_CONTRAST, contrast);
- emit signalXineStatus(i18n("Contrast") + ": " + QString::number((contrast*100)/65535) + "%");
- }
- void KXineWidget::slotSetBrightness(int bright)
- {
- xine_set_param(m_xineStream, XINE_PARAM_VO_BRIGHTNESS, bright);
- emit signalXineStatus(i18n("Brightness") + ": " + QString::number((bright*100)/65535) + "%");
- }
- void KXineWidget::slotSetAVOffset(int av)
- {
- xine_set_param(m_xineStream, XINE_PARAM_AV_OFFSET, av);
- emit signalXineStatus(i18n("Audio/Video Offset") + ": " + QString::number(av/90) + i18n("msec"));
- }
- void KXineWidget::slotSetSpuOffset(int spu)
- {
- xine_set_param(m_xineStream, XINE_PARAM_SPU_OFFSET, spu);
- emit signalXineStatus(i18n("Subtitle Offset") + ": " + QString::number(spu/90) + i18n("msec"));
- }
- /**************** equalizer *****************/
- void KXineWidget::slotSetEq30(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_30HZ, -val);
- }
- void KXineWidget::slotSetEq60(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_60HZ, -val);
- }
- void KXineWidget::slotSetEq125(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_125HZ, -val);
- }
- void KXineWidget::slotSetEq250(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_250HZ, -val);
- }
- void KXineWidget::slotSetEq500(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_500HZ, -val);
- }
- void KXineWidget::slotSetEq1k(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_1000HZ, -val);
- }
- void KXineWidget::slotSetEq2k(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_2000HZ, -val);
- }
- void KXineWidget::slotSetEq4k(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_4000HZ, -val);
- }
- void KXineWidget::slotSetEq8k(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_8000HZ, -val);
- }
- void KXineWidget::slotSetEq16k(int val)
- {
- xine_set_param(m_xineStream, XINE_PARAM_EQ_16000HZ, -val);
- }
- void KXineWidget::slotSetVolumeGain(bool gain)
- {
- int amp = 0;
- if (gain)
- {
- if (m_softwareMixer)
- amp = getVolume()*2;
- else
- amp = 200;
- }
- else
- {
- if (m_softwareMixer)
- amp = getVolume();
- else
- amp = 100;
- }
- xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, amp);
- m_volumeGain = gain;
- }
- /*************** dvd menus ******************/
- void KXineWidget::slotMenuToggle()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU1;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotMenuTitle()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU2;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotMenuRoot()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU3;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotMenuSubpicture()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU4;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotMenuAudio()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU5;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotMenuAngle()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU6;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotMenuPart()
- {
- xine_event_t xev;
- xev.type = XINE_EVENT_INPUT_MENU7;
- xev.data = NULL;
- xev.data_length = 0;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotDVDMenuLeft()
- {
- xine_event_t xev;
- xev.data = NULL;
- xev.data_length = 0;
- xev.type = XINE_EVENT_INPUT_LEFT;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotDVDMenuRight()
- {
- xine_event_t xev;
- xev.data = NULL;
- xev.data_length = 0;
- xev.type = XINE_EVENT_INPUT_RIGHT;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotDVDMenuUp()
- {
- xine_event_t xev;
- xev.data = NULL;
- xev.data_length = 0;
- xev.type = XINE_EVENT_INPUT_UP;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotDVDMenuDown()
- {
- xine_event_t xev;
- xev.data = NULL;
- xev.data_length = 0;
- xev.type = XINE_EVENT_INPUT_DOWN;
- xine_event_send(m_xineStream, &xev);
- }
- void KXineWidget::slotDVDMenuSelect()
- {
- xine_event_t xev;
- xev.data = NULL;
- xev.data_length = 0;
- xev.type = XINE_EVENT_INPUT_SELECT;
- xine_event_send(m_xineStream, &xev);
- }
- /******** mouse hideing at fullscreen ****/
- void KXineWidget::startMouseHideTimer()
- {
- m_mouseHideTimer.start(5000);
- }
- void KXineWidget::stopMouseHideTimer()
- {
- m_mouseHideTimer.stop();
- }
- void KXineWidget::slotHideMouse()
- {
- if (cursor().shape() == Qt::ArrowCursor)
- {
- setCursor(QCursor(Qt::BlankCursor));
- }
- }
- /************************************************************
- * Take a Screenshot *
- ************************************************************/
- QImage KXineWidget::getScreenshot() const
- {
- uchar *rgbPile = NULL;
- int width, height;
- double scaleFactor;
- getScreenshot(rgbPile, width, height, scaleFactor);
- if (!rgbPile) return QImage();
- QImage screenShot(rgbPile, width, height, 32, 0, 0, QImage::IgnoreEndian);
- if (scaleFactor >= 1.0)
- width = (int)((double) width * scaleFactor + 0.5);
- else
- height = (int)((double) height / scaleFactor + 0.5);
- debugOut(QString("Screenshot: scale picture from %1x%2 to %3x%4").arg(screenShot.width()).arg(screenShot.height()).arg(width).arg(height));
- screenShot = screenShot.smoothScale(width, height);
- delete []rgbPile;
- return screenShot;
- }
- void KXineWidget::getScreenshot(uchar*& rgb32BitData, int& videoWidth, int& videoHeight, double& scaleFactor) const
- {
- uint8_t *yuv = NULL, *y = NULL, *u = NULL, *v =NULL;
- int width, height, ratio, format;
- // double desired_ratio, image_ratio;
- if (!xine_get_current_frame(m_xineStream, &width, &height, &ratio, &format, NULL))
- return;
- yuv = new uint8_t[((width+8) * (height+1) * 2)];
- if (yuv == NULL)
- {
- errorOut("Not enough memory to make screenshot!");
- return;
- }
- xine_get_current_frame(m_xineStream, &width, &height, &ratio, &format, yuv);
- videoWidth = width;
- videoHeight = height;
- /*
- * convert to yv12 if necessary
- */
- switch (format)
- {
- case XINE_IMGFMT_YUY2:
- {
- uint8_t *yuy2 = yuv;
- yuv = new uint8_t[(width * height * 2)];
- if (yuv == NULL)
- {
- errorOut("Not enough memory to make screenshot!");
- return;
- }
- y = yuv;
- u = yuv + width * height;
- v = yuv + width * height * 5 / 4;
- yuy2Toyv12 (y, u, v, yuy2, width, height);
- delete [] yuy2;
- }
- break;
- case XINE_IMGFMT_YV12:
- y = yuv;
- u = yuv + width * height;
- v = yuv + width * height * 5 / 4;
- break;
- default:
- {
- warningOut(QString("Screenshot: Format %1 not supportet!").arg((char*)&format));
- delete [] yuv;
- return;
- }
- }
- /*
- * convert to rgb
- */
- rgb32BitData = yv12ToRgb (y, u, v, width, height);
- // image_ratio = (double) height / (double) width;
- /*
- switch (ratio)
- {
- case XINE_VO_ASPECT_ANAMORPHIC:
- debugOut("Screenshot: got video aspect: anamorphic");
- desired_ratio = 16.0 /9.0;
- break;
- case XINE_VO_ASPECT_DVB:
- debugOut("Screenshot: got video aspect: 2.11:1");
- desired_ratio = 2.11/1.0;
- break;
- case XINE_VO_ASPECT_4_3:
- debugOut("Screenshot: got video aspect: 4:3");
- desired_ratio = 4.0 / 3.0;
- break;
- default:
- warningOut(QString("Screenshot: Unknown aspect ratio: %1 - using 4:3").arg(ratio));
- case XINE_VO_ASPECT_SQUARE:
- debugOut("Screenshot: got video aspect: 1:1");
- desired_ratio = image_ratio;
- break;
- }
- */
- debugOut(QString("Screenshot: using scale factor: %1").arg(m_videoAspect));
- scaleFactor = m_videoAspect;
- delete [] yuv;
- }
- /************************************************
- * HELPER FUNCTIONS *
- ************************************************/
- QTime KXineWidget::msToTime(int msec)
- {
- QTime t;
- t = t.addMSecs(msec);
- return t;
- }
- #ifdef USE_QT_ONLY
- QString KXineWidget::i18n(const char *text)
- {
- return QApplication::tr(text);
- }
- #endif
- void KXineWidget::debugOut (QString qsDebug)
- {
- #ifdef USE_QT_ONLY
- QString qsDebugging = QString ("Debug: ") + qsDebug +"\n";
- printf ((const char *)qsDebugging);
- #else
- kdDebug() << "KXineWidget: " << (const char *)qsDebug.ascii() << "\n";
- #endif
- }
- void KXineWidget::errorOut (QString qsError)
- {
- #ifdef USE_QT_ONLY
- QString qsErroring = QString ("Error: ") + qsError+ "\n";
- printf ((const char *)qsErroring);
- #else
- kdError() << "KXineWidget: " << (const char *)qsError.ascii() << "\n";
- #endif
- }
- void KXineWidget::warningOut (QString qsWarning)
- {
- #ifdef USE_QT_ONLY
- QString qsWarninging = QString ("Warning: ") + qsWarning + "\n";
- printf ((const char *)qsWarninging);
- #else
- kdWarning() << "KXineWidget: " << (const char *)qsWarning.ascii() << "\n";
- #endif
- }
- /************************************************************
- * Helpers to convert yuy and yv12 frames to rgb *
- * code from gxine modified for 32bit output *
- * Copyright (C) 2000-2003 the xine project *
- ************************************************************/
- void KXineWidget::yuy2Toyv12 (uint8_t *y, uint8_t *u, uint8_t *v, uint8_t *input, int width, int height)
- {
- int i, j, w2;
- w2 = width / 2;
- for (i = 0; i < height; i += 2)
- {
- for (j = 0; j < w2; j++)
- {
- /*
- * packed YUV 422 is: Y[i] U[i] Y[i+1] V[i]
- */
- *(y++) = *(input++);
- *(u++) = *(input++);
- *(y++) = *(input++);
- *(v++) = *(input++);
- }
- /*
- * down sampling
- */
- for (j = 0; j < w2; j++)
- {
- /*
- * skip every second line for U and V
- */
- *(y++) = *(input++);
- input++;
- *(y++) = *(input++);
- input++;
- }
- }
- }
- uchar* KXineWidget::yv12ToRgb (uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, int width, int height)
- {
- /*
- * Create rgb data from yv12
- */
- #define clip_8_bit(val) \
- { \
- if (val < 0) \
- val = 0; \
- else \
- if (val > 255) val = 255; \
- }
- int i, j;
- int y, u, v;
- int r, g, b;
- int sub_i_uv;
- int sub_j_uv;
- int uv_width, uv_height;
- uchar *rgb;
- uv_width = width / 2;
- uv_height = height / 2;
- rgb = new uchar[(width * height * 4)]; //qt needs a 32bit align
- if (!rgb)
- {
- // kdError(555) << "Not enough memory!" << endl;
- return NULL;
- }
- for (i = 0; i < height; ++i)
- {
- /*
- * calculate u & v rows
- */
- sub_i_uv = ((i * uv_height) / height);
- for (j = 0; j < width; ++j)
- {
- /*
- * calculate u & v columns
- */
- sub_j_uv = ((j * uv_width) / width);
- /***************************************************
- *
- * Colour conversion from
- * http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC30
- *
- * Thanks to Billy Biggs <vektor@dumbterm.net>
- * for the pointer and the following conversion.
- *
- * R' = [ 1.1644 0 1.5960 ] ([ Y' ] [ 16 ])
- * G' = [ 1.1644 -0.3918 -0.8130 ] * ([ Cb ] - [ 128 ])
- * B' = [ 1.1644 2.0172 0 ] ([ Cr ] [ 128 ])
- *
- * Where in xine the above values are represented as
- *
- * Y' == image->y
- * Cb == image->u
- * Cr == image->v
- *
- ***************************************************/
- y = src_y[(i * width) + j] - 16;
- u = src_u[(sub_i_uv * uv_width) + sub_j_uv] - 128;
- v = src_v[(sub_i_uv * uv_width) + sub_j_uv] - 128;
- r = (int)((1.1644 * (double)y) + (1.5960 * (double)v));
- g = (int)((1.1644 * (double)y) - (0.3918 * (double)u) - (0.8130 * (double)v));
- b = (int)((1.1644 * (double)y) + (2.0172 * (double)u));
- clip_8_bit (r);
- clip_8_bit (g);
- clip_8_bit (b);
- rgb[(i * width + j) * 4 + 0] = b;
- rgb[(i * width + j) * 4 + 1] = g;
- rgb[(i * width + j) * 4 + 2] = r;
- rgb[(i * width + j) * 4 + 3] = 0;
- }
- }
- return rgb;
- }