diff options
Diffstat (limited to 'src/plugins/directshow/player/directshowplayerservice.cpp')
-rw-r--r-- | src/plugins/directshow/player/directshowplayerservice.cpp | 139 |
1 files changed, 65 insertions, 74 deletions
diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 059e253f1..56a428028 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -123,37 +123,8 @@ private: DirectShowPlayerService::DirectShowPlayerService(QObject *parent) : QMediaService(parent) - , m_playerControl(0) - , m_metaDataControl(0) - , m_videoRendererControl(0) - , m_videoWindowControl(0) - , m_audioEndpointControl(0) - , m_audioProbeControl(nullptr) - , m_videoProbeControl(nullptr) - , m_audioSampleGrabber(nullptr) - , m_videoSampleGrabber(nullptr) - , m_taskThread(0) , m_loop(qt_directShowEventLoop()) - , m_pendingTasks(0) - , m_executingTask(0) - , m_executedTasks(0) - , m_taskHandle(::CreateEvent(0, 0, 0, 0)) - , m_eventHandle(0) - , m_graphStatus(NoMedia) - , m_stream(0) - , m_graph(0) - , m_graphBuilder(nullptr) - , m_source(0) - , m_audioOutput(0) - , m_videoOutput(0) - , m_rate(1.0) - , m_position(0) - , m_seekPosition(-1) - , m_duration(0) - , m_buffering(false) - , m_seekable(false) - , m_atEnd(false) - , m_dontCacheNextSeekResult(false) + , m_taskHandle(::CreateEvent(nullptr, 0, 0, nullptr)) { m_playerControl = new DirectShowPlayerControl(this); m_metaDataControl = new DirectShowMetaDataControl(this); @@ -179,12 +150,12 @@ DirectShowPlayerService::~DirectShowPlayerService() if (m_audioOutput) { m_audioOutput->Release(); - m_audioOutput = 0; + m_audioOutput = nullptr; } if (m_videoOutput) { m_videoOutput->Release(); - m_videoOutput = 0; + m_videoOutput = nullptr; } delete m_playerControl; @@ -200,13 +171,13 @@ DirectShowPlayerService::~DirectShowPlayerService() QMediaControl *DirectShowPlayerService::requestControl(const char *name) { - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { + if (qstrcmp(name, QMediaPlayerControl_iid) == 0) return m_playerControl; - } else if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0) { + if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0) return m_audioEndpointControl; - } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { + if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) return m_metaDataControl; - } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { + if (qstrcmp(name, QVideoRendererControl_iid) == 0) { if (!m_videoRendererControl && !m_videoWindowControl) { m_videoRendererControl = new DirectShowVideoRendererControl(m_loop); @@ -215,7 +186,9 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) return m_videoRendererControl; } - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { + return nullptr; + } + if (qstrcmp(name, QVideoWindowControl_iid) == 0) { if (!m_videoRendererControl && !m_videoWindowControl) { IBaseFilter *filter{}; @@ -239,20 +212,23 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) return m_videoWindowControl; } - } else if (qstrcmp(name, QMediaAudioProbeControl_iid) == 0) { + return nullptr; + } + if (qstrcmp(name, QMediaAudioProbeControl_iid) == 0) { if (!m_audioProbeControl) m_audioProbeControl = new DirectShowAudioProbeControl(); m_audioProbeControl->ref(); updateAudioProbe(); return m_audioProbeControl; - } else if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) { + } + if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) { if (!m_videoProbeControl) m_videoProbeControl = new DirectShowVideoProbeControl(); m_videoProbeControl->ref(); updateVideoProbe(); return m_videoProbeControl; } - return 0; + return nullptr; } void DirectShowPlayerService::releaseControl(QMediaControl *control) @@ -261,17 +237,17 @@ void DirectShowPlayerService::releaseControl(QMediaControl *control) qWarning("QMediaService::releaseControl():" " Attempted release of null control"); } else if (control == m_videoRendererControl) { - setVideoOutput(0); + setVideoOutput(nullptr); delete m_videoRendererControl; - m_videoRendererControl = 0; + m_videoRendererControl = nullptr; } else if (control == m_videoWindowControl) { - setVideoOutput(0); + setVideoOutput(nullptr); delete m_videoWindowControl; - m_videoWindowControl = 0; + m_videoWindowControl = nullptr; } else if (control == m_audioProbeControl) { if (!m_audioProbeControl->deref()) { DirectShowAudioProbeControl *old = m_audioProbeControl; @@ -354,7 +330,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) { - IBaseFilter *source = 0; + IBaseFilter *source = nullptr; HRESULT hr = E_FAIL; if (m_url.scheme() == QLatin1String("http") || m_url.scheme() == QLatin1String("https")) { @@ -367,14 +343,14 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(clsid_WMAsfReader, iid_IFileSourceFilter)) { locker->unlock(); - hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(m_url.toString().utf16()), 0); + hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(m_url.toString().utf16()), nullptr); if (SUCCEEDED(hr)) { source = com_cast<IBaseFilter>(fileSource, IID_IBaseFilter); if (!SUCCEEDED(hr = m_graph->AddFilter(source, L"Source")) && source) { source->Release(); - source = 0; + source = nullptr; } } fileSource->Release(); @@ -408,8 +384,6 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) m_pendingTasks |= SetRate; m_source = source; - } else if (!m_url.isEmpty()) { - m_pendingTasks |= SetUrlSource; } else { m_graphStatus = InvalidMedia; @@ -511,18 +485,18 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker) HRESULT renderHr = S_OK; while (!filters.isEmpty()) { - IEnumPins *pins = 0; + IEnumPins *pins = nullptr; IBaseFilter *filter = filters[filters.size() - 1]; filters.removeLast(); if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) { int outputs = 0; - for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { PIN_DIRECTION direction; if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { ++outputs; - IPin *peer = 0; + IPin *peer = nullptr; if (pin->ConnectedTo(&peer) == S_OK) { PIN_INFO peerInfo; if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) @@ -530,10 +504,17 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker) peer->Release(); } else { locker->unlock(); - HRESULT hr = graph->RenderEx(pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, 0); - // Do not return an error if no video output is set yet. - if (SUCCEEDED(hr) || !(m_executedTasks & SetVideoOutput)) { + HRESULT hr = graph->RenderEx(pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, nullptr); + if (SUCCEEDED(hr)) { + rendered = true; + m_error = QMediaPlayer::NoError; + } else if (!(m_executedTasks & SetVideoOutput)) { + // Do not return an error if no video output is set yet. rendered = true; + // Remember the error in this case. + // Handle it when playing is requested and no video output has been provided. + m_error = QMediaPlayer::ResourceError; + m_errorString = QString("%1: %2").arg(__FUNCTION__).arg(qt_error_string(hr)); } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){ renderHr = hr; } @@ -675,13 +656,13 @@ void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker) if (m_source) { m_source->Release(); - m_source = 0; + m_source = nullptr; } - m_eventHandle = 0; + m_eventHandle = nullptr; m_graph->Release(); - m_graph = 0; + m_graph = nullptr; if (m_graphBuilder) { m_graphBuilder->Release(); @@ -819,17 +800,17 @@ int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const int streamTypes = 0; while (!filters.isEmpty()) { - IEnumPins *pins = 0; + IEnumPins *pins = nullptr; IBaseFilter *filter = filters[filters.size() - 1]; filters.removeLast(); if (SUCCEEDED(filter->EnumPins(&pins))) { - for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { PIN_DIRECTION direction; if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { DirectShowMediaType connectionType; if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) { - IPin *peer = 0; + IPin *peer = nullptr; if (connectionType->majortype == MEDIATYPE_Audio) { streamTypes |= AudioStream; @@ -862,8 +843,8 @@ int DirectShowPlayerService::findStreamType(IPin *pin) const bool audio = false; bool other = false; - for (AM_MEDIA_TYPE *type = 0; - types->Next(1, &type, 0) == S_OK; + for (AM_MEDIA_TYPE *type = nullptr; + types->Next(1, &type, nullptr) == S_OK; DirectShowMediaType::deleteType(type)) { if (type->majortype == MEDIATYPE_Audio) audio = true; @@ -914,6 +895,16 @@ void DirectShowPlayerService::play() void DirectShowPlayerService::doPlay(QMutexLocker *locker) { + // Invalidate if there is an error while loading. + if (m_error != QMediaPlayer::NoError) { + m_graphStatus = InvalidMedia; + if (!m_errorString.isEmpty()) + qWarning("%s", qPrintable(m_errorString)); + m_errorString = QString(); + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); + return; + } + if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { locker->unlock(); HRESULT hr = control->Run(); @@ -1165,7 +1156,7 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker) locker->unlock(); seeking->SetPositions( - &seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning); + &seekPosition, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning); locker->relock(); if (!m_dontCacheNextSeekResult) { @@ -1191,7 +1182,7 @@ int DirectShowPlayerService::bufferStatus() const m_source, IID_IWMReaderAdvanced2)) { DWORD percentage = 0; - reader->GetBufferProgress(&percentage, 0); + reader->GetBufferProgress(&percentage, nullptr); reader->Release(); return percentage; @@ -1364,7 +1355,7 @@ void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker) control->Release(); } - IBaseFilter *intermediate = 0; + IBaseFilter *intermediate = nullptr; if (!SUCCEEDED(m_graph->FindFilterByName(L"Color Space Converter", &intermediate))) { intermediate = m_videoOutput; intermediate->AddRef(); @@ -1615,7 +1606,7 @@ void DirectShowPlayerService::updateStatus() m_playerControl->updateStatus(QMediaPlayer::LoadingMedia); break; case Loaded: - if ((m_pendingTasks | m_executingTask | m_executedTasks) & (Play | Pause)) { + if ((m_executingTask | m_executedTasks) & (Play | Pause)) { if (m_buffering) m_playerControl->updateStatus(QMediaPlayer::BufferingMedia); else @@ -1636,13 +1627,13 @@ bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION dir { bool connected = false; - IEnumPins *pins = 0; + IEnumPins *pins = nullptr; if (SUCCEEDED(filter->EnumPins(&pins))) { - for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { PIN_DIRECTION dir; if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { - IPin *peer = 0; + IPin *peer = nullptr; if (SUCCEEDED(pin->ConnectedTo(&peer))) { connected = true; @@ -1658,15 +1649,15 @@ bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION dir IBaseFilter *DirectShowPlayerService::getConnected( IBaseFilter *filter, PIN_DIRECTION direction) const { - IBaseFilter *connected = 0; + IBaseFilter *connected = nullptr; - IEnumPins *pins = 0; + IEnumPins *pins = nullptr; if (SUCCEEDED(filter->EnumPins(&pins))) { - for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { PIN_DIRECTION dir; if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { - IPin *peer = 0; + IPin *peer = nullptr; if (SUCCEEDED(pin->ConnectedTo(&peer))) { PIN_INFO info; |