diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp index 94aa1262e83b8d7eb203894b5daf6ef50a3c03ff..f91c1192d4c3f2a6c4ad982c7c9a52611e6c70a7 100644 --- a/src/gsttools/qvideosurfacegstsink.cpp +++ b/src/gsttools/qvideosurfacegstsink.cpp @@ -713,13 +713,14 @@ QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *byte void QVideoSurfaceGstSink::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer) { + // GStreamer uses nanoseconds, Qt uses microseconds qint64 startTime = GST_BUFFER_TIMESTAMP(buffer); if (startTime >= 0) { - frame->setStartTime(startTime/G_GINT64_CONSTANT (1000000)); + frame->setStartTime(startTime/G_GINT64_CONSTANT (1000)); qint64 duration = GST_BUFFER_DURATION(buffer); if (duration >= 0) - frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000000)); + frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000)); } } diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp index c67b5d4480b7b96045da3674928070a30d0f910a..01a5c3341747f5b2defbd1180b3b100cef708edb 100644 --- a/src/plugins/wmf/evrd3dpresentengine.cpp +++ b/src/plugins/wmf/evrd3dpresentengine.cpp @@ -288,9 +288,21 @@ void D3DPresentEngine::presentSample(void *opaque, qint64) } if (surface && updateTexture(surface)) { - m_surface->present(QVideoFrame(new TextureVideoBuffer(m_glTexture), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat())); + QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture), + m_surfaceFormat.frameSize(), + m_surfaceFormat.pixelFormat()); + + // WMF uses 100-nanosecond units, Qt uses microseconds + LONGLONG startTime = -1; + if (SUCCEEDED(sample->GetSampleTime(&startTime))) { + frame.setStartTime(startTime * 0.1); + + LONGLONG duration = -1; + if (SUCCEEDED(sample->GetSampleDuration(&duration))) + frame.setEndTime((startTime + duration) * 0.1); + } + + m_surface->present(frame); } done: diff --git a/src/plugins/wmf/mftvideo.cpp b/src/plugins/wmf/mftvideo.cpp index acec88d6be6fab0a8a5428f08646fbb0d8ef09e5..8e7ce069333549057c2135bfeba81031e325bc02 100644 --- a/src/plugins/wmf/mftvideo.cpp +++ b/src/plugins/wmf/mftvideo.cpp @@ -632,13 +632,14 @@ QVideoFrame MFTransform::makeVideoFrame() // That is why we copy data from IMFMediaBuffer here. frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format.frameSize(), m_format.pixelFormat()); + // WMF uses 100-nanosecond units, Qt uses microseconds LONGLONG startTime = -1; if (SUCCEEDED(m_sample->GetSampleTime(&startTime))) { - frame.setStartTime(startTime); + frame.setStartTime(startTime * 0.1); LONGLONG duration = -1; if (SUCCEEDED(m_sample->GetSampleDuration(&duration))) - frame.setEndTime(startTime + duration); + frame.setEndTime((startTime + duration) * 0.1); } } while (false); diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp index 8f73244c0afe0ec70ef47af920b2e85a60f4315f..83768c8e227fdbe1c21650a91415e675b49618cd 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp @@ -254,6 +254,8 @@ namespace , m_workQueueCB(this, &MediaStream::onDispatchWorkItem) , m_finalizeResult(0) , m_scheduledBuffer(0) + , m_bufferStartTime(-1) + , m_bufferDuration(-1) , m_presentationClock(0) , m_currentMediaType(0) , m_prerolling(false) @@ -839,10 +841,13 @@ namespace QMutexLocker locker(&m_mutex); if (!m_scheduledBuffer) return; - m_surface->present(QVideoFrame( - new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat())); + QVideoFrame frame = QVideoFrame( + new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine), + m_surfaceFormat.frameSize(), + m_surfaceFormat.pixelFormat()); + frame.setStartTime(m_bufferStartTime * 0.1); + frame.setEndTime((m_bufferStartTime + m_bufferDuration) * 0.1); + m_surface->present(frame); m_scheduledBuffer->Release(); m_scheduledBuffer = NULL; if (m_rate != 0) @@ -1309,8 +1314,10 @@ namespace HRESULT processSampleData(IMFSample *pSample) { - LONGLONG time; + LONGLONG time, duration = -1; HRESULT hr = pSample->GetSampleTime(&time); + if (SUCCEEDED(hr)) + pSample->GetSampleDuration(&duration); if (m_prerolling) { if (SUCCEEDED(hr) && time >= m_prerollTargetTime) { @@ -1320,6 +1327,7 @@ namespace SampleBuffer sb; sb.m_buffer = pBuffer; sb.m_time = time; + sb.m_duration = duration; m_bufferCache.push_back(sb); endPreroll(S_OK); } @@ -1336,6 +1344,7 @@ namespace SampleBuffer sb; sb.m_buffer = pBuffer; sb.m_time = time; + sb.m_duration = duration; m_bufferCache.push_back(sb); } if (m_rate == 0) @@ -1351,6 +1360,7 @@ namespace public: IMFMediaBuffer *m_buffer; LONGLONG m_time; + LONGLONG m_duration; }; QList<SampleBuffer> m_bufferCache; static const int BUFFER_CACHE_SIZE = 2; @@ -1383,6 +1393,8 @@ namespace continue; } m_scheduledBuffer = sb.m_buffer; + m_bufferStartTime = sb.m_time; + m_bufferDuration = sb.m_duration; QCoreApplication::postEvent(m_rendererControl, new PresentEvent(sb.m_time)); if (m_rate == 0) queueEvent(MEStreamSinkScrubSampleComplete, GUID_NULL, S_OK, NULL); @@ -1393,6 +1405,8 @@ namespace queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); } IMFMediaBuffer *m_scheduledBuffer; + MFTIME m_bufferStartTime; + MFTIME m_bufferDuration; IMFPresentationClock *m_presentationClock; float m_rate; };