WMF: Recreate the MFMediaSession when loading a new media.
MFMediaSession doesn't seem to handle correctly the change of media source, causing the playback not to work afterwards. A single MFMediaSession was created and used for every loaded media, we now create a new one whenever we load a new media (releasing the old one beforehand). Task-number: QTBUG-26819 Change-Id: Id99c9dd54e161823d9580933e063f16240806529 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com> Reviewed-by: Jason Barron <jason@cutehacks.com>
This commit is contained in:
committed by
The Qt Project
parent
ad83534736
commit
06b63e99e4
@@ -57,26 +57,16 @@ Evr9VideoWindowControl::Evr9VideoWindowControl(QObject *parent)
|
|||||||
, m_currentActivate(0)
|
, m_currentActivate(0)
|
||||||
, m_evrSink(0)
|
, m_evrSink(0)
|
||||||
, m_displayControl(0)
|
, m_displayControl(0)
|
||||||
|
, m_processor(0)
|
||||||
{
|
{
|
||||||
if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) {
|
|
||||||
qWarning() << "Failed to create evr video renderer activate!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) {
|
|
||||||
qWarning() << "Failed to activate evr media sink!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (FAILED(MFGetService(m_evrSink, MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) {
|
|
||||||
qWarning() << "Failed to get display control from evr media sink!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (FAILED(MFGetService(m_evrSink, MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)))) {
|
|
||||||
qWarning() << "Failed to get video processor from evr media sink!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Evr9VideoWindowControl::~Evr9VideoWindowControl()
|
Evr9VideoWindowControl::~Evr9VideoWindowControl()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Evr9VideoWindowControl::clear()
|
||||||
{
|
{
|
||||||
if (m_processor)
|
if (m_processor)
|
||||||
m_processor->Release();
|
m_processor->Release();
|
||||||
@@ -88,8 +78,12 @@ Evr9VideoWindowControl::~Evr9VideoWindowControl()
|
|||||||
m_currentActivate->ShutdownObject();
|
m_currentActivate->ShutdownObject();
|
||||||
m_currentActivate->Release();
|
m_currentActivate->Release();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
m_processor = NULL;
|
||||||
|
m_displayControl = NULL;
|
||||||
|
m_evrSink = NULL;
|
||||||
|
m_currentActivate = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
WId Evr9VideoWindowControl::winId() const
|
WId Evr9VideoWindowControl::winId() const
|
||||||
{
|
{
|
||||||
@@ -307,8 +301,32 @@ void Evr9VideoWindowControl::setSaturation(int saturation)
|
|||||||
emit saturationChanged(saturation);
|
emit saturationChanged(saturation);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMFActivate* Evr9VideoWindowControl::currentActivate() const
|
IMFActivate* Evr9VideoWindowControl::createActivate()
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) {
|
||||||
|
qWarning() << "Failed to create evr video renderer activate!";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) {
|
||||||
|
qWarning() << "Failed to activate evr media sink!";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (FAILED(MFGetService(m_evrSink, MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) {
|
||||||
|
qWarning() << "Failed to get display control from evr media sink!";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (FAILED(MFGetService(m_evrSink, MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)))) {
|
||||||
|
qWarning() << "Failed to get video processor from evr media sink!";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWinId(m_windowId);
|
||||||
|
setDisplayRect(m_displayRect);
|
||||||
|
setAspectRatioMode(m_aspectRatioMode);
|
||||||
|
m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation;
|
||||||
|
|
||||||
return m_currentActivate;
|
return m_currentActivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,10 +85,12 @@ public:
|
|||||||
int saturation() const;
|
int saturation() const;
|
||||||
void setSaturation(int saturation);
|
void setSaturation(int saturation);
|
||||||
|
|
||||||
IMFActivate* currentActivate() const;
|
IMFActivate* createActivate();
|
||||||
|
|
||||||
|
void setProcAmpValues();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setProcAmpValues();
|
void clear();
|
||||||
DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, int value) const;
|
DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, int value) const;
|
||||||
|
|
||||||
WId m_windowId;
|
WId m_windowId;
|
||||||
|
|||||||
@@ -46,17 +46,23 @@ MFAudioEndpointControl::MFAudioEndpointControl(QObject *parent)
|
|||||||
: QAudioOutputSelectorControl(parent)
|
: QAudioOutputSelectorControl(parent)
|
||||||
, m_currentActivate(0)
|
, m_currentActivate(0)
|
||||||
{
|
{
|
||||||
updateEndpoints();
|
|
||||||
setActiveOutput(m_defaultEndpoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MFAudioEndpointControl::~MFAudioEndpointControl()
|
MFAudioEndpointControl::~MFAudioEndpointControl()
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MFAudioEndpointControl::clear()
|
||||||
|
{
|
||||||
|
m_activeEndpoint.clear();
|
||||||
|
|
||||||
foreach (LPWSTR wstrID, m_devices)
|
foreach (LPWSTR wstrID, m_devices)
|
||||||
CoTaskMemFree(wstrID);
|
CoTaskMemFree(wstrID);
|
||||||
|
|
||||||
if (m_currentActivate)
|
if (m_currentActivate)
|
||||||
m_currentActivate->Release();
|
m_currentActivate->Release();
|
||||||
|
m_currentActivate = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> MFAudioEndpointControl::availableOutputs() const
|
QList<QString> MFAudioEndpointControl::availableOutputs() const
|
||||||
@@ -119,8 +125,13 @@ void MFAudioEndpointControl::setActiveOutput(const QString &name)
|
|||||||
m_activeEndpoint = name;
|
m_activeEndpoint = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMFActivate* MFAudioEndpointControl::currentActivate() const
|
IMFActivate* MFAudioEndpointControl::createActivate()
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
updateEndpoints();
|
||||||
|
setActiveOutput(m_defaultEndpoint);
|
||||||
|
|
||||||
return m_currentActivate;
|
return m_currentActivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,9 +68,10 @@ public:
|
|||||||
|
|
||||||
void setActiveOutput(const QString& name);
|
void setActiveOutput(const QString& name);
|
||||||
|
|
||||||
IMFActivate* currentActivate() const;
|
IMFActivate* createActivate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void clear();
|
||||||
void updateEndpoints();
|
void updateEndpoints();
|
||||||
|
|
||||||
QString m_defaultEndpoint;
|
QString m_defaultEndpoint;
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
|
|||||||
, m_volumeControl(0)
|
, m_volumeControl(0)
|
||||||
, m_netsourceStatistics(0)
|
, m_netsourceStatistics(0)
|
||||||
, m_hCloseEvent(0)
|
, m_hCloseEvent(0)
|
||||||
|
, m_closing(false)
|
||||||
, m_pendingRate(1)
|
, m_pendingRate(1)
|
||||||
, m_volume(1)
|
, m_volume(1)
|
||||||
, m_muted(false)
|
, m_muted(false)
|
||||||
@@ -422,10 +423,6 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
|
|||||||
, m_audioSampleGrabberNode(0)
|
, m_audioSampleGrabberNode(0)
|
||||||
, m_videoProbeMFT(0)
|
, m_videoProbeMFT(0)
|
||||||
{
|
{
|
||||||
m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
||||||
m_sourceResolver = new SourceResolver();
|
|
||||||
QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
|
|
||||||
QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long)));
|
|
||||||
QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent *)), this, SLOT(handleSessionEvent(IMFMediaEvent *)));
|
QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent *)), this, SLOT(handleSessionEvent(IMFMediaEvent *)));
|
||||||
|
|
||||||
m_pendingState = NoPending;
|
m_pendingState = NoPending;
|
||||||
@@ -438,20 +435,23 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
|
|||||||
m_request.prevCmd = CmdNone;
|
m_request.prevCmd = CmdNone;
|
||||||
m_request.rate = 1.0f;
|
m_request.rate = 1.0f;
|
||||||
|
|
||||||
createSession();
|
|
||||||
PropVariantInit(&m_varStart);
|
|
||||||
m_varStart.vt = VT_I8;
|
|
||||||
m_varStart.uhVal.QuadPart = 0;
|
|
||||||
|
|
||||||
m_audioSampleGrabber = new AudioSampleGrabberCallback;
|
m_audioSampleGrabber = new AudioSampleGrabberCallback;
|
||||||
m_videoProbeMFT = new MFTransform;
|
m_videoProbeMFT = new MFTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFPlayerSession::close()
|
void MFPlayerSession::close()
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_MEDIAFOUNDATION
|
||||||
|
qDebug() << "close";
|
||||||
|
#endif
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
if (!m_session)
|
||||||
|
return;
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
if (m_session) {
|
if (m_session) {
|
||||||
|
m_closing = true;
|
||||||
hr = m_session->Close();
|
hr = m_session->Close();
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 100);
|
DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 100);
|
||||||
@@ -459,6 +459,7 @@ void MFPlayerSession::close()
|
|||||||
qWarning() << "session close time out!";
|
qWarning() << "session close time out!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_closing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
@@ -475,7 +476,9 @@ void MFPlayerSession::close()
|
|||||||
if (m_session)
|
if (m_session)
|
||||||
m_session->Release();
|
m_session->Release();
|
||||||
m_session = 0;
|
m_session = 0;
|
||||||
CloseHandle(m_hCloseEvent);
|
if (m_hCloseEvent)
|
||||||
|
CloseHandle(m_hCloseEvent);
|
||||||
|
m_hCloseEvent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFPlayerSession::addProbe(MFAudioProbeControl *probe)
|
void MFPlayerSession::addProbe(MFAudioProbeControl *probe)
|
||||||
@@ -522,6 +525,7 @@ void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream)
|
|||||||
changeStatus(QMediaPlayer::InvalidMedia);
|
changeStatus(QMediaPlayer::InvalidMedia);
|
||||||
emit error(QMediaPlayer::ResourceError, tr("Invalid stream source."), true);
|
emit error(QMediaPlayer::ResourceError, tr("Invalid stream source."), true);
|
||||||
} else {
|
} else {
|
||||||
|
createSession();
|
||||||
changeStatus(QMediaPlayer::LoadingMedia);
|
changeStatus(QMediaPlayer::LoadingMedia);
|
||||||
m_sourceResolver->load(resources, stream);
|
m_sourceResolver->load(resources, stream);
|
||||||
}
|
}
|
||||||
@@ -638,6 +642,7 @@ void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentat
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
outputNode->Release();
|
||||||
}
|
}
|
||||||
sourceNode->Release();
|
sourceNode->Release();
|
||||||
}
|
}
|
||||||
@@ -703,14 +708,14 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc,
|
|||||||
IMFActivate *activate = NULL;
|
IMFActivate *activate = NULL;
|
||||||
if (MFMediaType_Audio == guidMajorType) {
|
if (MFMediaType_Audio == guidMajorType) {
|
||||||
mediaType = Audio;
|
mediaType = Audio;
|
||||||
activate = m_playerService->audioEndpointControl()->currentActivate();
|
activate = m_playerService->audioEndpointControl()->createActivate();
|
||||||
} else if (MFMediaType_Video == guidMajorType) {
|
} else if (MFMediaType_Video == guidMajorType) {
|
||||||
mediaType = Video;
|
mediaType = Video;
|
||||||
if (m_playerService->videoRendererControl()) {
|
if (m_playerService->videoRendererControl()) {
|
||||||
activate = m_playerService->videoRendererControl()->currentActivate();
|
activate = m_playerService->videoRendererControl()->createActivate();
|
||||||
#ifndef Q_WS_SIMULATOR
|
#ifndef Q_WS_SIMULATOR
|
||||||
} else if (m_playerService->videoWindowControl()) {
|
} else if (m_playerService->videoWindowControl()) {
|
||||||
activate = m_playerService->videoWindowControl()->currentActivate();
|
activate = m_playerService->videoWindowControl()->createActivate();
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
|
qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
|
||||||
@@ -1136,6 +1141,7 @@ void MFPlayerSession::pause()
|
|||||||
} else {
|
} else {
|
||||||
if (m_state.command == CmdPause)
|
if (m_state.command == CmdPause)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (SUCCEEDED(m_session->Pause())) {
|
if (SUCCEEDED(m_session->Pause())) {
|
||||||
m_state.setCommand(CmdPause);
|
m_state.setCommand(CmdPause);
|
||||||
m_pendingState = CmdPending;
|
m_pendingState = CmdPending;
|
||||||
@@ -1163,6 +1169,14 @@ QMediaPlayer::MediaStatus MFPlayerSession::status() const
|
|||||||
|
|
||||||
void MFPlayerSession::createSession()
|
void MFPlayerSession::createSession()
|
||||||
{
|
{
|
||||||
|
close();
|
||||||
|
|
||||||
|
m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
m_sourceResolver = new SourceResolver();
|
||||||
|
QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
|
||||||
|
QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long)));
|
||||||
|
|
||||||
Q_ASSERT(m_session == NULL);
|
Q_ASSERT(m_session == NULL);
|
||||||
HRESULT hr = MFCreateMediaSession(NULL, &m_session);
|
HRESULT hr = MFCreateMediaSession(NULL, &m_session);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@@ -1176,6 +1190,10 @@ void MFPlayerSession::createSession()
|
|||||||
changeStatus(QMediaPlayer::UnknownMediaStatus);
|
changeStatus(QMediaPlayer::UnknownMediaStatus);
|
||||||
emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false);
|
emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PropVariantInit(&m_varStart);
|
||||||
|
m_varStart.vt = VT_I8;
|
||||||
|
m_varStart.hVal.QuadPart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 MFPlayerSession::position()
|
qint64 MFPlayerSession::position()
|
||||||
@@ -1511,7 +1529,8 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit sessionEvent(pEvent);
|
if (!m_closing)
|
||||||
|
emit sessionEvent(pEvent);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1569,6 +1588,13 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
|||||||
case MESessionStarted:
|
case MESessionStarted:
|
||||||
if (!m_scrubbing)
|
if (!m_scrubbing)
|
||||||
updatePendingCommands(CmdStart);
|
updatePendingCommands(CmdStart);
|
||||||
|
#ifndef Q_WS_SIMULATOR
|
||||||
|
// playback started, we can now set again the procAmpValues if they have been
|
||||||
|
// changed previously (these are lost when loading a new media)
|
||||||
|
if (m_playerService->videoWindowControl()) {
|
||||||
|
m_playerService->videoWindowControl()->setProcAmpValues();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case MESessionStopped:
|
case MESessionStopped:
|
||||||
if (m_status != QMediaPlayer::EndOfMedia) {
|
if (m_status != QMediaPlayer::EndOfMedia) {
|
||||||
@@ -1659,9 +1685,16 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
|||||||
m_volumeControl->SetMasterVolume(m_volume);
|
m_volumeControl->SetMasterVolume(m_volume);
|
||||||
m_volumeControl->SetMute(m_muted);
|
m_volumeControl->SetMute(m_muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD dwCharacteristics = 0;
|
DWORD dwCharacteristics = 0;
|
||||||
m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
|
m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
|
||||||
emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
|
emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
|
||||||
|
|
||||||
|
// Topology is resolved and successfuly set, this happens only after loading a new media.
|
||||||
|
// Make sure we always start the media from the beginning
|
||||||
|
m_varStart.vt = VT_I8;
|
||||||
|
m_varStart.hVal.QuadPart = 0;
|
||||||
|
|
||||||
changeStatus(QMediaPlayer::LoadedMedia);
|
changeStatus(QMediaPlayer::LoadedMedia);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ private:
|
|||||||
|
|
||||||
SourceResolver *m_sourceResolver;
|
SourceResolver *m_sourceResolver;
|
||||||
HANDLE m_hCloseEvent;
|
HANDLE m_hCloseEvent;
|
||||||
|
bool m_closing;
|
||||||
|
|
||||||
enum MediaType
|
enum MediaType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2130,17 +2130,23 @@ namespace
|
|||||||
MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
|
MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
|
||||||
: QVideoRendererControl(parent)
|
: QVideoRendererControl(parent)
|
||||||
, m_surface(0)
|
, m_surface(0)
|
||||||
|
, m_currentActivate(0)
|
||||||
, m_callback(0)
|
, m_callback(0)
|
||||||
{
|
{
|
||||||
m_currentActivate = new VideoRendererActivate(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MFVideoRendererControl::~MFVideoRendererControl()
|
MFVideoRendererControl::~MFVideoRendererControl()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MFVideoRendererControl::clear()
|
||||||
{
|
{
|
||||||
if (m_currentActivate) {
|
if (m_currentActivate) {
|
||||||
m_currentActivate->ShutdownObject();
|
m_currentActivate->ShutdownObject();
|
||||||
m_currentActivate->Release();
|
m_currentActivate->Release();
|
||||||
}
|
}
|
||||||
|
m_currentActivate = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractVideoSurface *MFVideoRendererControl::surface() const
|
QAbstractVideoSurface *MFVideoRendererControl::surface() const
|
||||||
@@ -2150,9 +2156,6 @@ QAbstractVideoSurface *MFVideoRendererControl::surface() const
|
|||||||
|
|
||||||
void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
||||||
{
|
{
|
||||||
if (m_surface == surface)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_surface)
|
if (m_surface)
|
||||||
disconnect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
|
disconnect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
|
||||||
m_surface = surface;
|
m_surface = surface;
|
||||||
@@ -2160,11 +2163,16 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
|||||||
if (m_surface) {
|
if (m_surface) {
|
||||||
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
|
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
|
||||||
}
|
}
|
||||||
static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
|
|
||||||
|
if (m_currentActivate)
|
||||||
|
static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFVideoRendererControl::customEvent(QEvent *event)
|
void MFVideoRendererControl::customEvent(QEvent *event)
|
||||||
{
|
{
|
||||||
|
if (!m_currentActivate)
|
||||||
|
return;
|
||||||
|
|
||||||
if (event->type() == MediaStream::PresentSurface) {
|
if (event->type() == MediaStream::PresentSurface) {
|
||||||
MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime();
|
MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime();
|
||||||
MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime();
|
MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime();
|
||||||
@@ -2185,16 +2193,26 @@ void MFVideoRendererControl::customEvent(QEvent *event)
|
|||||||
|
|
||||||
void MFVideoRendererControl::supportedFormatsChanged()
|
void MFVideoRendererControl::supportedFormatsChanged()
|
||||||
{
|
{
|
||||||
static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
|
if (m_currentActivate)
|
||||||
|
static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFVideoRendererControl::present()
|
void MFVideoRendererControl::present()
|
||||||
{
|
{
|
||||||
static_cast<VideoRendererActivate*>(m_currentActivate)->present();
|
if (m_currentActivate)
|
||||||
|
static_cast<VideoRendererActivate*>(m_currentActivate)->present();
|
||||||
}
|
}
|
||||||
|
|
||||||
IMFActivate* MFVideoRendererControl::currentActivate() const
|
IMFActivate* MFVideoRendererControl::createActivate()
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
m_currentActivate = new VideoRendererActivate(this);
|
||||||
|
if (m_surface) {
|
||||||
|
setSurface(m_surface);
|
||||||
|
supportedFormatsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
return m_currentActivate;
|
return m_currentActivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
QAbstractVideoSurface *surface() const;
|
QAbstractVideoSurface *surface() const;
|
||||||
void setSurface(QAbstractVideoSurface *surface);
|
void setSurface(QAbstractVideoSurface *surface);
|
||||||
|
|
||||||
IMFActivate* currentActivate() const;
|
IMFActivate* createActivate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void customEvent(QEvent *event);
|
void customEvent(QEvent *event);
|
||||||
@@ -68,6 +68,8 @@ private Q_SLOTS:
|
|||||||
void present();
|
void present();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void clear();
|
||||||
|
|
||||||
QAbstractVideoSurface *m_surface;
|
QAbstractVideoSurface *m_surface;
|
||||||
IMFActivate *m_currentActivate;
|
IMFActivate *m_currentActivate;
|
||||||
IMFSampleGrabberSinkCallback *m_callback;
|
IMFSampleGrabberSinkCallback *m_callback;
|
||||||
|
|||||||
Reference in New Issue
Block a user