qtmobility/plugins/multimedia/directshow/player/directshowplayerservice.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    47 #include "directshowplayercontrol.h"
    47 #include "directshowplayercontrol.h"
    48 #include "directshowvideooutputcontrol.h"
    48 #include "directshowvideooutputcontrol.h"
    49 #include "directshowvideorenderercontrol.h"
    49 #include "directshowvideorenderercontrol.h"
    50 #include "vmr9videowindowcontrol.h"
    50 #include "vmr9videowindowcontrol.h"
    51 
    51 
    52 #include <qmediacontent.h>
    52 #include "../../src/multimedia/qmediacontent.h"
    53 
    53 
    54 #include <QtCore/qcoreapplication.h>
    54 #include <QtCore/qcoreapplication.h>
    55 #include <QtCore/qdatetime.h>
    55 #include <QtCore/qdatetime.h>
    56 #include <QtCore/qthread.h>
    56 #include <QtCore/qthread.h>
    57 #include <QtCore/qvarlengtharray.h>
    57 #include <QtCore/qvarlengtharray.h>
    58 
    58 
    59 #include <uuids.h>
    59 Q_GLOBAL_STATIC(DirectShowEventLoop, qt_directShowEventLoop)
    60 
       
    61 
    60 
    62 class DirectShowPlayerServiceThread : public QThread
    61 class DirectShowPlayerServiceThread : public QThread
    63 {
    62 {
    64 public:
    63 public:
    65     DirectShowPlayerServiceThread(DirectShowPlayerService *service)
    64     DirectShowPlayerServiceThread(DirectShowPlayerService *service)
    75 };
    74 };
    76 
    75 
    77 DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
    76 DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
    78     : QMediaService(parent)
    77     : QMediaService(parent)
    79     , m_playerControl(0)
    78     , m_playerControl(0)
    80     , m_audioEndpointControl(0)
       
    81     , m_metaDataControl(0)
    79     , m_metaDataControl(0)
    82     , m_videoOutputControl(0)
    80     , m_videoOutputControl(0)
    83     , m_videoRendererControl(0)
    81     , m_videoRendererControl(0)
    84     , m_videoWindowControl(0)
    82     , m_videoWindowControl(0)
       
    83     , m_audioEndpointControl(0)
    85     , m_taskThread(0)
    84     , m_taskThread(0)
       
    85     , m_loop(qt_directShowEventLoop())
    86     , m_pendingTasks(0)
    86     , m_pendingTasks(0)
    87     , m_executingTask(0)
    87     , m_executingTask(0)
    88     , m_executedTasks(0)
    88     , m_executedTasks(0)
    89     , m_taskHandle(::CreateEvent(0, 0, 0, 0))
    89     , m_taskHandle(::CreateEvent(0, 0, 0, 0))
    90     , m_eventHandle(0)
    90     , m_eventHandle(0)
   103 {
   103 {
   104     m_playerControl = new DirectShowPlayerControl(this);
   104     m_playerControl = new DirectShowPlayerControl(this);
   105     m_metaDataControl = new DirectShowMetaDataControl(this);
   105     m_metaDataControl = new DirectShowMetaDataControl(this);
   106     m_videoOutputControl = new DirectShowVideoOutputControl; 
   106     m_videoOutputControl = new DirectShowVideoOutputControl; 
   107     m_audioEndpointControl = new DirectShowAudioEndpointControl(this);
   107     m_audioEndpointControl = new DirectShowAudioEndpointControl(this);
   108     m_videoRendererControl = new DirectShowVideoRendererControl(&m_loop);
   108     m_videoRendererControl = new DirectShowVideoRendererControl(m_loop);
   109     m_videoWindowControl = new Vmr9VideoWindowControl;
   109     m_videoWindowControl = new Vmr9VideoWindowControl;
   110 
   110 
   111     m_taskThread = new DirectShowPlayerServiceThread(this);
   111     m_taskThread = new DirectShowPlayerServiceThread(this);
   112     m_taskThread->start();
   112     m_taskThread->start();
   113 
   113 
   176     if (m_graph)
   176     if (m_graph)
   177         releaseGraph();
   177         releaseGraph();
   178 
   178 
   179     m_resources = media.resources();
   179     m_resources = media.resources();
   180     m_stream = stream;
   180     m_stream = stream;
       
   181     m_error = QMediaPlayer::NoError;
       
   182     m_errorString = QString();
       
   183     m_position = 0;
   181     m_duration = 0;
   184     m_duration = 0;
   182     m_streamTypes = 0;
   185     m_streamTypes = 0;
   183     m_executedTasks = 0;
   186     m_executedTasks = 0;
   184     m_buffering = false;
   187     m_buffering = false;
   185     m_seekable = false;
   188     m_seekable = false;
   189     if (m_resources.isEmpty() && !stream) {
   192     if (m_resources.isEmpty() && !stream) {
   190         m_pendingTasks = 0;
   193         m_pendingTasks = 0;
   191         m_graphStatus = NoMedia;
   194         m_graphStatus = NoMedia;
   192 
   195 
   193         m_url.clear();
   196         m_url.clear();
       
   197     } else if (stream && (!stream->isReadable() || stream->isSequential())) {
       
   198         m_pendingTasks = 0;
       
   199         m_graphStatus = InvalidMedia;
       
   200         m_error = QMediaPlayer::ResourceError;
   194     } else {
   201     } else {
       
   202         // {36b73882-c2c8-11cf-8b46-00805f6cef60}
       
   203         static const GUID iid_IFilterGraph2 = {
       
   204             0x36b73882, 0xc2c8, 0x11cf, {0x8b, 0x46, 0x00, 0x80, 0x5f, 0x6c, 0xef, 0x60} };
   195         m_graphStatus = Loading;
   205         m_graphStatus = Loading;
   196 
   206 
   197         m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph);
   207         m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph, iid_IFilterGraph2);
   198 
   208 
   199         if (stream)
   209         if (stream)
   200             m_pendingTasks = SetStreamSource;
   210             m_pendingTasks = SetStreamSource;
   201         else
   211         else
   202             m_pendingTasks = SetUrlSource;
   212             m_pendingTasks = SetUrlSource;
   203 
   213 
   204         ::SetEvent(m_taskHandle);
   214         ::SetEvent(m_taskHandle);
   205     }
   215     }
   206 
   216 
       
   217     m_playerControl->updateError(m_error, m_errorString);
   207     m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
   218     m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
   208     m_playerControl->updateState(QMediaPlayer::StoppedState);
   219     m_playerControl->updateState(QMediaPlayer::StoppedState);
       
   220     m_playerControl->updatePosition(m_position);
   209     updateStatus();
   221     updateStatus();
   210 }
   222 }
   211 
   223 
   212 void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker)
   224 void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker)
   213 {
   225 {
   216     QMediaResource resource = m_resources.takeFirst();
   228     QMediaResource resource = m_resources.takeFirst();
   217     QUrl url = resource.url();
   229     QUrl url = resource.url();
   218 
   230 
   219     HRESULT hr = E_FAIL;
   231     HRESULT hr = E_FAIL;
   220 
   232 
   221 #ifndef QT_NO_WMSDK
       
   222     if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("https")) {
   233     if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("https")) {
   223         if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(CLSID_WMAsfReader)) {
   234         static const GUID clsid_WMAsfReader = {
       
   235             0x187463a0, 0x5bb7, 0x11d3, {0xac, 0xbe, 0x00, 0x80, 0xc7, 0x5e, 0x24, 0x6e} };
       
   236 
       
   237         // {56a868a6-0ad4-11ce-b03a-0020af0ba770}
       
   238         static const GUID iid_IFileSourceFilter = {
       
   239             0x56a868a6, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} };
       
   240 
       
   241         if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(
       
   242                 clsid_WMAsfReader, iid_IFileSourceFilter)) {
   224             locker->unlock();
   243             locker->unlock();
   225             hr = fileSource->Load(url.toString().utf16(), 0);
   244             hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(url.toString().utf16()), 0);
   226             locker->relock();
   245             locker->relock();
   227 
   246 
   228             if (SUCCEEDED(hr)) {
   247             if (SUCCEEDED(hr)) {
   229                 source = com_cast<IBaseFilter>(fileSource);
   248                 source = com_cast<IBaseFilter>(fileSource, IID_IBaseFilter);
   230 
   249 
   231                 if (!SUCCEEDED(hr = m_graph->AddFilter(source, L"Source")) && source) {
   250                 if (!SUCCEEDED(hr = m_graph->AddFilter(source, L"Source")) && source) {
   232                     source->Release();
   251                     source->Release();
   233                     source = 0;
   252                     source = 0;
   234                 }
   253                 }
   235             }
   254             }
   236 
   255 
   237             fileSource->Release();
   256             fileSource->Release();
   238         }
   257         }
       
   258     } else if (url.scheme() == QLatin1String("qrc")) {
       
   259         DirectShowRcSource *rcSource = new DirectShowRcSource(m_loop);
       
   260 
       
   261         if (rcSource->open(url) && SUCCEEDED(hr = m_graph->AddFilter(rcSource, L"Source")))
       
   262             source = rcSource;
       
   263         else
       
   264             rcSource->Release();
   239     }
   265     }
   240 
   266 
   241     if (!SUCCEEDED(hr)) {
   267     if (!SUCCEEDED(hr)) {
   242 #endif
       
   243         locker->unlock();
   268         locker->unlock();
   244         hr = m_graph->AddSourceFilter(url.toString().utf16(), L"Source", &source);
   269         hr = m_graph->AddSourceFilter(
       
   270                 reinterpret_cast<const OLECHAR *>(url.toString().utf16()), L"Source", &source);
   245         locker->relock();
   271         locker->relock();
   246 #ifndef QT_NO_WMSDK
   272     }
   247     }
       
   248 #endif
       
   249 
   273 
   250     if (SUCCEEDED(hr)) {
   274     if (SUCCEEDED(hr)) {
   251         m_executedTasks = SetSource;
   275         m_executedTasks = SetSource;
   252         m_pendingTasks |= Render;
   276         m_pendingTasks |= Render;
   253 
   277 
   267         m_graphStatus = InvalidMedia;
   291         m_graphStatus = InvalidMedia;
   268 
   292 
   269         switch (hr) {
   293         switch (hr) {
   270         case VFW_E_UNKNOWN_FILE_TYPE:
   294         case VFW_E_UNKNOWN_FILE_TYPE:
   271             m_error = QMediaPlayer::FormatError;
   295             m_error = QMediaPlayer::FormatError;
       
   296             m_errorString = QString();
   272             break;
   297             break;
   273         case E_OUTOFMEMORY:
   298         case E_OUTOFMEMORY:
   274         case VFW_E_CANNOT_LOAD_SOURCE_FILTER:
   299         case VFW_E_CANNOT_LOAD_SOURCE_FILTER:
   275         case VFW_E_NOT_FOUND:
   300         case VFW_E_NOT_FOUND:
   276             m_error = QMediaPlayer::ResourceError;
   301             m_error = QMediaPlayer::ResourceError;
       
   302             m_errorString = QString();
   277         default:
   303         default:
   278             m_error = QMediaPlayer::ResourceError;
   304             m_error = QMediaPlayer::ResourceError;
   279             qWarning("DirectShowPlayerService::doSetUrlSource: Unresolved error code %x", hr);
   305             m_errorString = QString();
       
   306             qWarning("DirectShowPlayerService::doSetUrlSource: Unresolved error code %x", uint(hr));
   280             break;
   307             break;
   281         }
   308         }
   282 
   309 
   283         QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   310         QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   284     }
   311     }
   285 }
   312 }
   286 
   313 
   287 void DirectShowPlayerService::doSetStreamSource(QMutexLocker *locker)
   314 void DirectShowPlayerService::doSetStreamSource(QMutexLocker *locker)
   288 {
   315 {
   289     IBaseFilter *source = new DirectShowIOSource(m_stream, &m_loop);
   316     DirectShowIOSource *source = new DirectShowIOSource(m_loop);
       
   317     source->setDevice(m_stream);
   290 
   318 
   291     if (SUCCEEDED(m_graph->AddFilter(source, L"Source"))) {
   319     if (SUCCEEDED(m_graph->AddFilter(source, L"Source"))) {
   292         m_executedTasks = SetSource;
   320         m_executedTasks = SetSource;
   293         m_pendingTasks |= Render;
   321         m_pendingTasks |= Render;
   294 
   322 
   306 
   334 
   307         m_pendingTasks = 0;
   335         m_pendingTasks = 0;
   308         m_graphStatus = InvalidMedia;
   336         m_graphStatus = InvalidMedia;
   309 
   337 
   310         m_error = QMediaPlayer::ResourceError;
   338         m_error = QMediaPlayer::ResourceError;
       
   339         m_errorString = QString();
   311 
   340 
   312         QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   341         QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   313     }
   342     }
   314 }
   343 }
   315 
   344 
   316 void DirectShowPlayerService::doRender(QMutexLocker *locker)
   345 void DirectShowPlayerService::doRender(QMutexLocker *locker)
   317 {
   346 {
       
   347     m_pendingTasks |= m_executedTasks & (Play | Pause);
       
   348 
       
   349     if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
       
   350         control->Stop();
       
   351         control->Release();
       
   352     }
       
   353 
   318     if (m_pendingTasks & SetAudioOutput) {
   354     if (m_pendingTasks & SetAudioOutput) {
   319         m_graph->AddFilter(m_audioOutput, L"AudioOutput");
   355         m_graph->AddFilter(m_audioOutput, L"AudioOutput");
   320 
   356 
   321         m_pendingTasks ^= SetAudioOutput;
   357         m_pendingTasks ^= SetAudioOutput;
   322         m_executedTasks |= SetAudioOutput;
   358         m_executedTasks |= SetAudioOutput;
   352                     ++outputs;
   388                     ++outputs;
   353 
   389 
   354                     IPin *peer = 0;
   390                     IPin *peer = 0;
   355                     if (pin->ConnectedTo(&peer) == S_OK) {
   391                     if (pin->ConnectedTo(&peer) == S_OK) {
   356                         PIN_INFO peerInfo;
   392                         PIN_INFO peerInfo;
   357                         if (peer->QueryPinInfo(&peerInfo) == S_OK)
   393                         if (SUCCEEDED(peer->QueryPinInfo(&peerInfo)))
   358                             filters.append(peerInfo.pFilter);
   394                             filters.append(peerInfo.pFilter);
   359                         peer->Release();
   395                         peer->Release();
   360                     } else {
   396                     } else {
   361                         locker->unlock();
   397                         locker->unlock();
   362                         HRESULT hr;
   398                         HRESULT hr;
   363                         if (SUCCEEDED(hr = graph->RenderEx(
   399                         if (SUCCEEDED(hr = graph->RenderEx(
   364                                 pin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, 0))) {
   400                                 pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, 0))) {
   365                             rendered = true;
   401                             rendered = true;
   366                         } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){
   402                         } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){
   367                             renderHr = hr;
   403                             renderHr = hr;
   368                         }
   404                         }
   369                         locker->relock();
   405                         locker->relock();
   370                     }
   406                     }
   371                 }
   407                 }
   372             }
   408             }
       
   409 
       
   410             pins->Release();
       
   411 
   373             if (outputs == 0)
   412             if (outputs == 0)
   374                 rendered = true;
   413                 rendered = true;
   375         }
   414         }
   376         filter->Release();
   415         filter->Release();
   377     }
   416     }
   378 
       
   379 
   417 
   380     if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) {
   418     if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) {
   381         graph->RemoveFilter(m_audioOutput);
   419         graph->RemoveFilter(m_audioOutput);
   382 
   420 
   383         m_executedTasks &= ~SetAudioOutput;
   421         m_executedTasks &= ~SetAudioOutput;
   400 
   438 
   401             m_graphStatus = InvalidMedia;
   439             m_graphStatus = InvalidMedia;
   402 
   440 
   403             if (!m_audioOutput && !m_videoOutput) {
   441             if (!m_audioOutput && !m_videoOutput) {
   404                 m_error = QMediaPlayer::ResourceError;
   442                 m_error = QMediaPlayer::ResourceError;
       
   443                 m_errorString = QString();
   405             } else {
   444             } else {
   406                 switch (renderHr) {
   445                 switch (renderHr) {
   407                 case VFW_E_UNSUPPORTED_AUDIO:
   446                 case VFW_E_UNSUPPORTED_AUDIO:
   408                 case VFW_E_UNSUPPORTED_VIDEO:
   447                 case VFW_E_UNSUPPORTED_VIDEO:
   409                 case VFW_E_UNSUPPORTED_STREAM:
   448                 case VFW_E_UNSUPPORTED_STREAM:
   410                     m_error = QMediaPlayer::FormatError;
   449                     m_error = QMediaPlayer::FormatError;
       
   450                     m_errorString = QString();
   411                 default:
   451                 default:
   412                     m_error = QMediaPlayer::ResourceError;
   452                     m_error = QMediaPlayer::ResourceError;
       
   453                     m_errorString = QString();
   413                     qWarning("DirectShowPlayerService::doRender: Unresolved error code %x",
   454                     qWarning("DirectShowPlayerService::doRender: Unresolved error code %x",
   414                              renderHr);
   455                              uint(renderHr));
   415                 }
   456                 }
   416             }
   457             }
   417 
   458 
   418             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   459             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   419         }
   460         }
   420 
   461 
   421         m_executedTasks |= Render;
   462         m_executedTasks |= Render;
   422     }
   463     }
   423 
   464 
   424     m_loop.wake();
   465     m_loop->wake();
   425 }
   466 }
   426 
   467 
   427 void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker)
   468 void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker)
   428 {
   469 {
   429     if (m_graphStatus != Loaded) {
   470     if (m_graphStatus != Loaded) {
   430         if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph)) {
   471         if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) {
   431             event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle));
   472             event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle));
   432             event->Release();
   473             event->Release();
   433         }
   474         }
   434         if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
   475         if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
   435             LONGLONG duration = 0;
   476             LONGLONG duration = 0;
   436             seeking->GetDuration(&duration);
   477             seeking->GetDuration(&duration);
   437             m_duration = duration / 10;
   478             m_duration = duration / 10;
   438 
   479 
   439             DWORD capabilities = 0;
   480             DWORD capabilities = 0;
   459 
   500 
   460 void DirectShowPlayerService::releaseGraph()
   501 void DirectShowPlayerService::releaseGraph()
   461 {
   502 {
   462     if (m_graph) {
   503     if (m_graph) {
   463         if (m_executingTask != 0) {
   504         if (m_executingTask != 0) {
   464             if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(m_graph)) {
   505             // {8E1C39A1-DE53-11cf-AA63-0080C744528D}
       
   506             static const GUID iid_IAMOpenProgress = {
       
   507                 0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D} };
       
   508 
       
   509             if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(
       
   510                     m_graph, iid_IAMOpenProgress)) {
   465                 progress->AbortOperation();
   511                 progress->AbortOperation();
   466                 progress->Release();
   512                 progress->Release();
   467             }
   513             }
   468             m_graph->Abort();
   514             m_graph->Abort();
   469         }
   515         }
   470         
   516         
   471         m_pendingTasks = ReleaseGraph;
   517         m_pendingTasks = ReleaseGraph;
   472 
   518 
   473         ::SetEvent(m_taskHandle);
   519         ::SetEvent(m_taskHandle);
   474 
   520 
   475         m_loop.wait(&m_mutex);
   521         m_loop->wait(&m_mutex);
   476     }
   522     }
   477 }
   523 }
   478 
   524 
   479 void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker)
   525 void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker)
   480 {
   526 {
   481     Q_UNUSED(locker);
   527     Q_UNUSED(locker);
   482 
   528 
   483     if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
   529     if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
   484         control->Stop();
   530         control->Stop();
   485         control->Release();
   531         control->Release();
   486     }
   532     }
   487 
   533 
   488     if (m_source) {
   534     if (m_source) {
   493     m_eventHandle = 0;
   539     m_eventHandle = 0;
   494 
   540 
   495     m_graph->Release();
   541     m_graph->Release();
   496     m_graph = 0;
   542     m_graph = 0;
   497 
   543 
   498     m_loop.wake();
   544     m_loop->wake();
   499 }
   545 }
   500 
   546 
   501 int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const
   547 int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const
   502 {
   548 {
   503     QVarLengthArray<IBaseFilter *, 16> filters;
   549     QVarLengthArray<IBaseFilter *, 16> filters;
   593     }
   639     }
   594 }
   640 }
   595 
   641 
   596 void DirectShowPlayerService::doPlay(QMutexLocker *locker)
   642 void DirectShowPlayerService::doPlay(QMutexLocker *locker)
   597 {
   643 {
   598     if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
   644     if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
   599         locker->unlock();
   645         locker->unlock();
   600         HRESULT hr = control->Run();
   646         HRESULT hr = control->Run();
   601         locker->relock();
   647         locker->relock();
   602 
   648 
   603         control->Release();
   649         control->Release();
   604 
   650 
   605         if (SUCCEEDED(hr))
       
   606             m_executedTasks |= Play;
       
   607 
       
   608         if (SUCCEEDED(hr)) {
   651         if (SUCCEEDED(hr)) {
   609             m_executedTasks |= Play;
   652             m_executedTasks |= Play;
   610 
   653 
   611             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
   654             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
   612         } else {
   655         } else {
   613             m_error = QMediaPlayer::ResourceError;
   656             m_error = QMediaPlayer::ResourceError;
   614             qWarning("DirectShowPlayerService::doPlay: Unresolved error code %x", hr);
   657             m_errorString = QString();
       
   658             qWarning("DirectShowPlayerService::doPlay: Unresolved error code %x", uint(hr));
   615 
   659 
   616             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   660             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   617         }
   661         }
   618     }
   662     }
   619 }
   663 }
   637     }
   681     }
   638 }
   682 }
   639 
   683 
   640 void DirectShowPlayerService::doPause(QMutexLocker *locker)
   684 void DirectShowPlayerService::doPause(QMutexLocker *locker)
   641 {
   685 {
   642     if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
   686     if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
   643         locker->unlock();
   687         locker->unlock();
   644         HRESULT hr = control->Pause();
   688         HRESULT hr = control->Pause();
   645         locker->relock();
   689         locker->relock();
   646 
   690 
   647         control->Release();
   691         control->Release();
   648 
   692 
   649         if (SUCCEEDED(hr)) {
   693         if (SUCCEEDED(hr)) {
       
   694             if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
       
   695                 LONGLONG position = 0;
       
   696 
       
   697                 seeking->GetCurrentPosition(&position);
       
   698                 seeking->Release();
       
   699 
       
   700                 m_position = position / 10;
       
   701             } else {
       
   702                 m_position = 0;
       
   703             }
       
   704 
   650             m_executedTasks |= Pause;
   705             m_executedTasks |= Pause;
   651 
   706 
   652             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
   707             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
   653         } else {
   708         } else {
   654             m_error = QMediaPlayer::ResourceError;
   709             m_error = QMediaPlayer::ResourceError;
   655             qWarning("DirectShowPlayerService::doPause: Unresolved error code %x", hr);
   710             m_errorString = QString();
       
   711             qWarning("DirectShowPlayerService::doPause: Unresolved error code %x", uint(hr));
   656 
   712 
   657             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   713             QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
   658         }
   714         }
   659     }
   715     }
   660 }
   716 }
   663 {
   719 {
   664     QMutexLocker locker(&m_mutex);
   720     QMutexLocker locker(&m_mutex);
   665 
   721 
   666     m_pendingTasks &= ~(Play | Pause | Seek);
   722     m_pendingTasks &= ~(Play | Pause | Seek);
   667 
   723 
   668     if (m_executedTasks & Render) {
   724     if ((m_executingTask | m_executedTasks) & (Play | Pause | Seek)) {
   669         if (m_executingTask & (Play | Pause | Seek)) {
   725         m_pendingTasks |= Stop;
   670             m_pendingTasks |= Stop;
   726 
   671 
   727         ::SetEvent(m_taskHandle);
   672             m_loop.wait(&m_mutex);
   728 
   673         }
   729         m_loop->wait(&m_mutex);
   674 
   730     }
   675         if (m_executedTasks & (Play | Pause)) {
   731 
   676             if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
   732 }
   677                 control->Stop();
   733 
   678                 control->Release();
   734 void DirectShowPlayerService::doStop(QMutexLocker *locker)
   679             }
   735 {
   680             m_executedTasks &= ~(Play | Pause);
   736     if (m_executedTasks & (Play | Pause)) {
   681         }
   737         if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
       
   738             control->Stop();
       
   739             control->Release();
       
   740         }
       
   741 
       
   742         if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
       
   743             LONGLONG position = 0;
       
   744 
       
   745             seeking->GetCurrentPosition(&position);
       
   746             seeking->Release();
       
   747 
       
   748             m_position = position / 10;
       
   749         } else {
       
   750             m_position = 0;
       
   751         }
       
   752 
       
   753         m_executedTasks &= ~(Play | Pause);
       
   754         
       
   755         QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
   682     }
   756     }
   683 
   757 
   684     m_executedTasks |= Stop;
   758     m_executedTasks |= Stop;
       
   759 
       
   760     m_loop->wake();
   685 }
   761 }
   686 
   762 
   687 void DirectShowPlayerService::setRate(qreal rate)
   763 void DirectShowPlayerService::setRate(qreal rate)
   688 {
   764 {
   689     QMutexLocker locker(&m_mutex);
   765     QMutexLocker locker(&m_mutex);
   696         ::SetEvent(m_taskHandle);
   772         ::SetEvent(m_taskHandle);
   697 }
   773 }
   698 
   774 
   699 void DirectShowPlayerService::doSetRate(QMutexLocker *locker)
   775 void DirectShowPlayerService::doSetRate(QMutexLocker *locker)
   700 {
   776 {
   701     if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
   777     if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
   702         // Cache current values as we can't query IMediaSeeking during a seek due to the
   778         // Cache current values as we can't query IMediaSeeking during a seek due to the
   703         // possibility of a deadlock when flushing the VideoSurfaceFilter.
   779         // possibility of a deadlock when flushing the VideoSurfaceFilter.
   704         LONGLONG currentPosition = 0;
   780         LONGLONG currentPosition = 0;
   705         seeking->GetCurrentPosition(&currentPosition);
   781         seeking->GetCurrentPosition(&currentPosition);
   706         m_position = currentPosition / 10;
   782         m_position = currentPosition / 10;
   734     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
   810     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
   735 
   811 
   736     if (m_graphStatus == Loaded) {
   812     if (m_graphStatus == Loaded) {
   737         if (m_executingTask == Seek || m_executingTask == SetRate) {
   813         if (m_executingTask == Seek || m_executingTask == SetRate) {
   738             return m_position;
   814             return m_position;
   739         } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
   815         } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
   740             LONGLONG position = 0;
   816             LONGLONG position = 0;
   741 
   817 
   742             seeking->GetCurrentPosition(&position);
   818             seeking->GetCurrentPosition(&position);
   743             seeking->Release();
   819             seeking->Release();
   744 
   820 
   745             return position / 10;
   821             const_cast<qint64 &>(m_position) = position / 10;
       
   822 
       
   823             return m_position;
   746         }
   824         }
   747     }
   825     }
   748     return 0;
   826     return 0;
   749 }
   827 }
   750 
   828 
   753     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
   831     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
   754 
   832 
   755     if (m_graphStatus == Loaded) {
   833     if (m_graphStatus == Loaded) {
   756         if (m_executingTask == Seek || m_executingTask == SetRate) {
   834         if (m_executingTask == Seek || m_executingTask == SetRate) {
   757             return m_playbackRange;
   835             return m_playbackRange;
   758         } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
   836         } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
   759             LONGLONG minimum = 0;
   837             LONGLONG minimum = 0;
   760             LONGLONG maximum = 0;
   838             LONGLONG maximum = 0;
   761 
   839 
   762             HRESULT hr = seeking->GetAvailable(&minimum, &maximum);
   840             HRESULT hr = seeking->GetAvailable(&minimum, &maximum);
   763             seeking->Release();
   841             seeking->Release();
   781         ::SetEvent(m_taskHandle);
   859         ::SetEvent(m_taskHandle);
   782 }
   860 }
   783 
   861 
   784 void DirectShowPlayerService::doSeek(QMutexLocker *locker)
   862 void DirectShowPlayerService::doSeek(QMutexLocker *locker)
   785 {
   863 {
   786     if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
   864     if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
   787         LONGLONG seekPosition = LONGLONG(m_position) * 10;
   865         LONGLONG seekPosition = LONGLONG(m_position) * 10;
   788 
   866 
   789         // Cache current values as we can't query IMediaSeeking during a seek due to the
   867         // Cache current values as we can't query IMediaSeeking during a seek due to the
   790         // possibility of a deadlock when flushing the VideoSurfaceFilter.
   868         // possibility of a deadlock when flushing the VideoSurfaceFilter.
   791         LONGLONG currentPosition = 0;
   869         LONGLONG currentPosition = 0;
   801         locker->unlock();
   879         locker->unlock();
   802         seeking->SetPositions(
   880         seeking->SetPositions(
   803                 &seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
   881                 &seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
   804         locker->relock();
   882         locker->relock();
   805 
   883 
       
   884         seeking->GetCurrentPosition(&currentPosition);
       
   885         m_position = currentPosition / 10;
       
   886 
   806         seeking->Release();
   887         seeking->Release();
   807     }
   888     } else {
       
   889         m_position = 0;
       
   890     }
       
   891 
       
   892     QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange)));
   808 }
   893 }
   809 
   894 
   810 int DirectShowPlayerService::bufferStatus() const
   895 int DirectShowPlayerService::bufferStatus() const
   811 {
   896 {
   812 #ifndef QT_NO_WMSDK
   897 #ifndef QT_NO_WMSDK
   813     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
   898     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
   814 
   899 
   815     if (IWMReaderAdvanced2 *reader = com_cast<IWMReaderAdvanced2>(m_source)) {
   900     if (IWMReaderAdvanced2 *reader = com_cast<IWMReaderAdvanced2>(
       
   901             m_source, IID_IWMReaderAdvanced2)) {
   816         DWORD percentage = 0;
   902         DWORD percentage = 0;
   817 
   903 
   818         reader->GetBufferProgress(&percentage, 0);
   904         reader->GetBufferProgress(&percentage, 0);
   819         reader->Release();
   905         reader->Release();
   820 
   906 
   836             if (m_executedTasks & SetAudioOutput) {
   922             if (m_executedTasks & SetAudioOutput) {
   837                 m_pendingTasks |= ReleaseAudioOutput;
   923                 m_pendingTasks |= ReleaseAudioOutput;
   838 
   924 
   839                 ::SetEvent(m_taskHandle);
   925                 ::SetEvent(m_taskHandle);
   840 
   926 
   841                 m_loop.wait(&m_mutex);
   927                 m_loop->wait(&m_mutex);
   842             }
   928             }
   843             m_audioOutput->Release();
   929             m_audioOutput->Release();
   844         } 
   930         } 
   845 
   931 
   846         m_audioOutput = filter;
   932         m_audioOutput = filter;
   847 
   933 
   848         if (m_audioOutput) {
   934         if (m_audioOutput) {
   849             m_audioOutput->AddRef();
   935             m_audioOutput->AddRef();
   850 
   936 
   851             m_pendingTasks |= SetAudioOutput;
   937             m_pendingTasks |= SetAudioOutput;
       
   938 
       
   939             if (m_executedTasks & SetSource) {
       
   940                 m_pendingTasks |= Render;
       
   941 
       
   942                 ::SetEvent(m_taskHandle);
       
   943             }
   852         } else {
   944         } else {
   853             m_pendingTasks &= ~ SetAudioOutput;
   945             m_pendingTasks &= ~ SetAudioOutput;
   854         }
       
   855 
       
   856         if (m_executedTasks & SetSource) {
       
   857             m_pendingTasks |= Render;
       
   858 
       
   859             ::SetEvent(m_taskHandle);
       
   860         }
   946         }
   861     } else {
   947     } else {
   862         if (m_audioOutput)
   948         if (m_audioOutput)
   863             m_audioOutput->Release();
   949             m_audioOutput->Release();
   864 
   950 
   873 
   959 
   874 void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker *locker)
   960 void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker *locker)
   875 {
   961 {
   876     m_pendingTasks |= m_executedTasks & (Play | Pause);
   962     m_pendingTasks |= m_executedTasks & (Play | Pause);
   877 
   963 
   878     if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
   964     if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
   879         control->Stop();
   965         control->Stop();
   880         control->Release();
   966         control->Release();
   881     }
   967     }
   882 
   968 
   883     m_graph->RemoveFilter(m_audioOutput);
   969     IBaseFilter *decoder = getConnected(m_audioOutput, PINDIR_INPUT);
       
   970     if (!decoder) {
       
   971         decoder = m_audioOutput;
       
   972         decoder->AddRef();
       
   973     }
       
   974 
       
   975     // {DCFBDCF6-0DC2-45f5-9AB2-7C330EA09C29}
       
   976     static const GUID iid_IFilterChain = {
       
   977         0xDCFBDCF6, 0x0DC2, 0x45f5, {0x9A, 0xB2, 0x7C, 0x33, 0x0E, 0xA0, 0x9C, 0x29} };
       
   978 
       
   979     if (IFilterChain *chain = com_cast<IFilterChain>(m_graph, iid_IFilterChain)) {
       
   980         chain->RemoveChain(decoder, m_audioOutput);
       
   981         chain->Release();
       
   982     } else {
       
   983         m_graph->RemoveFilter(m_audioOutput);
       
   984     }
       
   985 
       
   986     decoder->Release();
   884 
   987 
   885     m_executedTasks &= ~SetAudioOutput;
   988     m_executedTasks &= ~SetAudioOutput;
   886 
   989 
   887     m_loop.wake();
   990     m_loop->wake();
   888 }
   991 }
   889 
   992 
   890 void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
   993 void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
   891 {
   994 {
   892     QMutexLocker locker(&m_mutex);
   995     QMutexLocker locker(&m_mutex);
   896             if (m_executedTasks & SetVideoOutput) {
   999             if (m_executedTasks & SetVideoOutput) {
   897                 m_pendingTasks |= ReleaseVideoOutput;
  1000                 m_pendingTasks |= ReleaseVideoOutput;
   898 
  1001 
   899                 ::SetEvent(m_taskHandle);
  1002                 ::SetEvent(m_taskHandle);
   900 
  1003 
   901                 m_loop.wait(&m_mutex);
  1004                 m_loop->wait(&m_mutex);
   902             }
  1005             }
   903             m_videoOutput->Release();
  1006             m_videoOutput->Release();
   904         }
  1007         }
   905 
  1008 
   906         m_videoOutput = filter;
  1009         m_videoOutput = filter;
   907 
  1010 
   908         if (m_videoOutput) {
  1011         if (m_videoOutput) {
   909             m_videoOutput->AddRef();
  1012             m_videoOutput->AddRef();
   910 
  1013 
   911             m_pendingTasks |= SetVideoOutput;
  1014             m_pendingTasks |= SetVideoOutput;
   912         } else {
  1015 
   913             m_pendingTasks &= ~ SetVideoOutput;
  1016             if (m_executedTasks & SetSource) {
   914         }
  1017                 m_pendingTasks |= Render;
   915 
  1018 
   916         if (m_executedTasks & SetSource) {
  1019                 ::SetEvent(m_taskHandle);
   917             m_pendingTasks |= Render;
  1020             }
   918 
       
   919             ::SetEvent(m_taskHandle);
       
   920         }
  1021         }
   921     } else {
  1022     } else {
   922         if (m_videoOutput)
  1023         if (m_videoOutput)
   923             m_videoOutput->Release();
  1024             m_videoOutput->Release();
   924 
  1025 
   931 
  1032 
   932 void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker)
  1033 void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker)
   933 {
  1034 {
   934     m_pendingTasks |= m_executedTasks & (Play | Pause);
  1035     m_pendingTasks |= m_executedTasks & (Play | Pause);
   935 
  1036 
   936     if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
  1037     if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
   937         control->Stop();
  1038         control->Stop();
   938         control->Release();
  1039         control->Release();
   939     }
  1040     }
   940 
  1041 
   941     m_graph->RemoveFilter(m_videoOutput);
  1042     IBaseFilter *intermediate = 0;
       
  1043     if (!SUCCEEDED(m_graph->FindFilterByName(L"Color Space Converter", &intermediate))) {
       
  1044         intermediate = m_videoOutput;
       
  1045         intermediate->AddRef();
       
  1046     }
       
  1047 
       
  1048     IBaseFilter *decoder = getConnected(intermediate, PINDIR_INPUT);
       
  1049     if (!decoder) {
       
  1050         decoder = intermediate;
       
  1051         decoder->AddRef();
       
  1052     }
       
  1053 
       
  1054     // {DCFBDCF6-0DC2-45f5-9AB2-7C330EA09C29}
       
  1055     static const GUID iid_IFilterChain = {
       
  1056         0xDCFBDCF6, 0x0DC2, 0x45f5, {0x9A, 0xB2, 0x7C, 0x33, 0x0E, 0xA0, 0x9C, 0x29} };
       
  1057 
       
  1058     if (IFilterChain *chain = com_cast<IFilterChain>(m_graph, iid_IFilterChain)) {
       
  1059         chain->RemoveChain(decoder, m_videoOutput);
       
  1060         chain->Release();
       
  1061     } else {
       
  1062         m_graph->RemoveFilter(m_videoOutput);
       
  1063     }
       
  1064 
       
  1065     intermediate->Release();
       
  1066     decoder->Release();
   942 
  1067 
   943     m_executedTasks &= ~SetVideoOutput;
  1068     m_executedTasks &= ~SetVideoOutput;
   944 
  1069 
   945     m_loop.wake();
  1070     m_loop->wake();
   946 }
  1071 }
   947 
  1072 
   948 void DirectShowPlayerService::customEvent(QEvent *event)
  1073 void DirectShowPlayerService::customEvent(QEvent *event)
   949 {
  1074 {
   950     if (event->type() == QEvent::Type(FinalizedLoad)) {
  1075     if (event->type() == QEvent::Type(FinalizedLoad)) {
   953         m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
  1078         m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
   954         m_metaDataControl->updateGraph(m_graph, m_source);
  1079         m_metaDataControl->updateGraph(m_graph, m_source);
   955 
  1080 
   956         updateStatus();
  1081         updateStatus();
   957     } else if (event->type() == QEvent::Type(Error)) {
  1082     } else if (event->type() == QEvent::Type(Error)) {
   958         QMediaPlayer::Error error;
  1083         QMutexLocker locker(&m_mutex);
   959         {
  1084 
   960             QMutexLocker locker(&m_mutex);
  1085         if (m_error != QMediaPlayer::NoError) {
   961             error = m_error;
  1086             m_playerControl->updateError(m_error, m_errorString);
   962 
  1087             m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
   963             if (error != QMediaPlayer::NoError) {
  1088             m_playerControl->updateState(QMediaPlayer::StoppedState);
   964                 m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
  1089             updateStatus();
   965                 m_playerControl->updateState(QMediaPlayer::StoppedState);
  1090         }
   966                 updateStatus();
       
   967             }
       
   968         }
       
   969         m_playerControl->error(error, QString());
       
   970     } else if (event->type() == QEvent::Type(RateChange)) {
  1091     } else if (event->type() == QEvent::Type(RateChange)) {
   971         QMutexLocker locker(&m_mutex);
  1092         QMutexLocker locker(&m_mutex);
   972 
  1093 
   973         m_playerControl->updatePlaybackRate(m_rate);
  1094         m_playerControl->updatePlaybackRate(m_rate);
   974     } else if (event->type() == QEvent::Type(StatusChange)) {
  1095     } else if (event->type() == QEvent::Type(StatusChange)) {
   975         QMutexLocker locker(&m_mutex);
  1096         QMutexLocker locker(&m_mutex);
   976 
  1097 
   977         updateStatus();
  1098         updateStatus();
       
  1099         m_playerControl->updatePosition(m_position);
   978     } else if (event->type() == QEvent::Type(DurationChange)) {
  1100     } else if (event->type() == QEvent::Type(DurationChange)) {
   979         QMutexLocker locker(&m_mutex);
  1101         QMutexLocker locker(&m_mutex);
   980 
  1102 
   981         m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
  1103         m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
   982     } else if (event->type() == QEvent::Type(EndOfMedia)) {
  1104     } else if (event->type() == QEvent::Type(EndOfMedia)) {
   983         QMutexLocker locker(&m_mutex);
  1105         QMutexLocker locker(&m_mutex);
   984 
  1106 
   985         if (m_atEnd) {
  1107         if (m_atEnd) {
   986             m_playerControl->updateState(QMediaPlayer::StoppedState);
  1108             m_playerControl->updateState(QMediaPlayer::StoppedState);
   987             m_playerControl->updateStatus(QMediaPlayer::EndOfMedia);
  1109             m_playerControl->updateStatus(QMediaPlayer::EndOfMedia);
   988         }
  1110             m_playerControl->updatePosition(m_position);
       
  1111         }
       
  1112     } else if (event->type() == QEvent::Type(PositionChange)) {
       
  1113         QMutexLocker locker(&m_mutex);
       
  1114 
       
  1115         m_playerControl->updatePosition(m_position);
   989     } else {
  1116     } else {
   990         QMediaService::customEvent(event);
  1117         QMediaService::customEvent(event);
   991     }
  1118     }
   992 }
  1119 }
   993 
  1120 
  1009     setVideoOutput(videoOutput);
  1136     setVideoOutput(videoOutput);
  1010 }
  1137 }
  1011 
  1138 
  1012 void DirectShowPlayerService::graphEvent(QMutexLocker *locker)
  1139 void DirectShowPlayerService::graphEvent(QMutexLocker *locker)
  1013 {
  1140 {
  1014     if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph)) {
  1141     if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) {
  1015         long eventCode;
  1142         long eventCode;
  1016         LONG_PTR param1;
  1143         LONG_PTR param1;
  1017         LONG_PTR param2;
  1144         LONG_PTR param2;
  1018 
  1145 
  1019         while (event->GetEvent(&eventCode, &param1, &param2, 0) == S_OK) {
  1146         while (event->GetEvent(&eventCode, &param1, &param2, 0) == S_OK) {
  1028                 m_executedTasks |= Stop;
  1155                 m_executedTasks |= Stop;
  1029 
  1156 
  1030                 m_buffering = false;
  1157                 m_buffering = false;
  1031                 m_atEnd = true;
  1158                 m_atEnd = true;
  1032 
  1159 
       
  1160                 if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
       
  1161                     LONGLONG position = 0;
       
  1162 
       
  1163                     seeking->GetCurrentPosition(&position);
       
  1164                     seeking->Release();
       
  1165 
       
  1166                     m_position = position / 10;
       
  1167                 }
       
  1168 
  1033                 QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia)));
  1169                 QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia)));
  1034                 break;
  1170                 break;
  1035             case EC_LENGTH_CHANGED:
  1171             case EC_LENGTH_CHANGED:
  1036                 if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
  1172                 if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
  1037                     LONGLONG duration = 0;
  1173                     LONGLONG duration = 0;
  1038                     seeking->GetDuration(&duration);
  1174                     seeking->GetDuration(&duration);
  1039                     m_duration = duration / 10;
  1175                     m_duration = duration / 10;
  1040 
  1176 
  1041                     DWORD capabilities = 0;
  1177                     DWORD capabilities = 0;
  1105         pins->Release();
  1241         pins->Release();
  1106     }
  1242     }
  1107     return connected;
  1243     return connected;
  1108 }
  1244 }
  1109 
  1245 
       
  1246 IBaseFilter *DirectShowPlayerService::getConnected(
       
  1247         IBaseFilter *filter, PIN_DIRECTION direction) const
       
  1248 {
       
  1249     IBaseFilter *connected = 0;
       
  1250 
       
  1251     IEnumPins *pins = 0;
       
  1252 
       
  1253     if (SUCCEEDED(filter->EnumPins(&pins))) {
       
  1254         for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
       
  1255             PIN_DIRECTION dir;
       
  1256             if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) {
       
  1257                 IPin *peer = 0;
       
  1258                 if (SUCCEEDED(pin->ConnectedTo(&peer))) {
       
  1259                     PIN_INFO info;
       
  1260 
       
  1261                     if (SUCCEEDED(peer->QueryPinInfo(&info))) {
       
  1262                         if (connected) {
       
  1263                             qWarning("DirectShowPlayerService::getConnected: "
       
  1264                                 "Multiple connected filters");
       
  1265                             connected->Release();
       
  1266                         }
       
  1267                         connected = info.pFilter;
       
  1268                     }
       
  1269                     peer->Release();
       
  1270                 }
       
  1271             }
       
  1272         }
       
  1273         pins->Release();
       
  1274     }
       
  1275     return connected;
       
  1276 }
       
  1277 
  1110 void DirectShowPlayerService::run()
  1278 void DirectShowPlayerService::run()
  1111 {
  1279 {
  1112     QMutexLocker locker(&m_mutex);
  1280     QMutexLocker locker(&m_mutex);
  1113 
  1281 
  1114     for (;;) {
  1282     for (;;) {
  1169         } else if (m_pendingTasks & FinalizeLoad) {
  1337         } else if (m_pendingTasks & FinalizeLoad) {
  1170             m_pendingTasks ^= FinalizeLoad;
  1338             m_pendingTasks ^= FinalizeLoad;
  1171             m_executingTask = FinalizeLoad;
  1339             m_executingTask = FinalizeLoad;
  1172 
  1340 
  1173             doFinalizeLoad(&locker);
  1341             doFinalizeLoad(&locker);
       
  1342         } else if (m_pendingTasks & Stop) {
       
  1343             m_pendingTasks ^= Stop;
       
  1344             m_executingTask = Stop;
       
  1345 
       
  1346             doStop(&locker);
  1174         } else if (m_pendingTasks & SetRate) {
  1347         } else if (m_pendingTasks & SetRate) {
  1175             m_pendingTasks ^= SetRate;
  1348             m_pendingTasks ^= SetRate;
  1176             m_executingTask = SetRate;
  1349             m_executingTask = SetRate;
  1177 
  1350 
  1178             doSetRate(&locker);
  1351             doSetRate(&locker);
  1179         } else if (m_pendingTasks & Stop) {
       
  1180             m_pendingTasks ^= Stop;
       
  1181 
       
  1182             m_loop.wake();
       
  1183         } else if (m_pendingTasks & Pause) {
  1352         } else if (m_pendingTasks & Pause) {
  1184             m_pendingTasks ^= Pause;
  1353             m_pendingTasks ^= Pause;
  1185             m_executingTask = Pause;
  1354             m_executingTask = Pause;
  1186 
  1355 
  1187             doPause(&locker);
  1356             doPause(&locker);