Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2013-01-15 11:22:44 +0400
committerHendrik Leppkes <h.leppkes@gmail.com>2013-01-15 11:31:21 +0400
commita9c8d77606449205f3e2b15143eeea4f12df73cf (patch)
tree30cd1792c39aaa255b9f62ab4c811cc51add7bdf /decoder
parent00b6435ee84b04f63f5060b5044e35be2a945a2b (diff)
wmv9dmo: improve handling of streams not starting with a keyframe
When the wmv9 dmo internally drops a frame, it doesn't drop the timestamps with it. So instead of letting the DMO drop frames, ensure the stream it sees always starts with an I frame, and drop the frames ourselves.
Diffstat (limited to 'decoder')
-rw-r--r--decoder/LAVVideo/decoders/wmv9.cpp35
-rw-r--r--decoder/LAVVideo/decoders/wmv9.h2
2 files changed, 27 insertions, 10 deletions
diff --git a/decoder/LAVVideo/decoders/wmv9.cpp b/decoder/LAVVideo/decoders/wmv9.cpp
index 9e3922fc..c1b1b7d3 100644
--- a/decoder/LAVVideo/decoders/wmv9.cpp
+++ b/decoder/LAVVideo/decoders/wmv9.cpp
@@ -185,6 +185,8 @@ CDecWMV9::CDecWMV9(void)
, m_bReorderBufferValid(FALSE)
, m_rtReorderBuffer(AV_NOPTS_VALUE)
, m_vc1Profile(0)
+ , m_bNeedKeyFrame(FALSE)
+ , m_nCodecId(AV_CODEC_ID_NONE)
{
memset(&m_StreamAR, 0, sizeof(m_StreamAR));
}
@@ -333,6 +335,7 @@ STDMETHODIMP CDecWMV9::InitDecoder(AVCodecID codec, const CMediaType *pmt)
/* Create input type */
GUID subtype = codec == AV_CODEC_ID_VC1 ? MEDIASUBTYPE_WVC1 : MEDIASUBTYPE_WMV3;
+ m_nCodecId = codec;
mtIn.SetType(&MEDIATYPE_Video);
mtIn.SetSubtype(&subtype);
@@ -484,8 +487,6 @@ STDMETHODIMP CDecWMV9::Decode(const BYTE *buffer, int buflen, REFERENCE_TIME rtS
}
if (!(dwStatus & DMO_INPUT_STATUSF_ACCEPT_DATA))
return S_FALSE;
-
- CMediaBuffer *pInBuffer = new CMediaBufferDecode(buffer, buflen);
DWORD dwFlags = 0;
if (bSyncPoint)
@@ -495,18 +496,31 @@ STDMETHODIMP CDecWMV9::Decode(const BYTE *buffer, int buflen, REFERENCE_TIME rtS
if (rtStop != AV_NOPTS_VALUE)
dwFlags |= DMO_INPUT_DATA_BUFFERF_TIMELENGTH;
- if (m_bManualReorder) {
+ if (m_bManualReorder || m_bNeedKeyFrame) {
AVPictureType pictype = parse_picture_type(buffer, buflen, m_vc1Profile, m_bInterlaced);
- if (pictype == AV_PICTURE_TYPE_I || pictype == AV_PICTURE_TYPE_P) {
- if (m_bReorderBufferValid)
- m_timestampQueue.push(m_rtReorderBuffer);
- m_rtReorderBuffer = rtStart;
- m_bReorderBufferValid = TRUE;
- } else {
- m_timestampQueue.push(rtStart);
+ if (m_bManualReorder) {
+ if (pictype == AV_PICTURE_TYPE_I || pictype == AV_PICTURE_TYPE_P) {
+ if (m_bReorderBufferValid)
+ m_timestampQueue.push(m_rtReorderBuffer);
+ m_rtReorderBuffer = rtStart;
+ m_bReorderBufferValid = TRUE;
+ } else {
+ m_timestampQueue.push(rtStart);
+ }
+ }
+
+ if (m_bNeedKeyFrame) {
+ if (pictype != AV_PICTURE_TYPE_I) {
+ if (m_bManualReorder)
+ m_timestampQueue.pop();
+ return S_OK;
+ } else {
+ m_bNeedKeyFrame = FALSE;
+ }
}
}
+ CMediaBuffer *pInBuffer = new CMediaBufferDecode(buffer, buflen);
hr = m_pDMO->ProcessInput(0, pInBuffer, dwFlags, rtStart, rtStop - rtStart);
if (FAILED(hr)) {
DbgLog((LOG_TRACE, 10, L"-> ProcessInput failed with hr: %0x%x", hr));
@@ -652,6 +666,7 @@ STDMETHODIMP CDecWMV9::Flush()
std::queue<REFERENCE_TIME>().swap(m_timestampQueue);
m_rtReorderBuffer = AV_NOPTS_VALUE;
m_bReorderBufferValid = FALSE;
+ m_bNeedKeyFrame = (m_nCodecId == AV_CODEC_ID_VC1);
return __super::Flush();
}
diff --git a/decoder/LAVVideo/decoders/wmv9.h b/decoder/LAVVideo/decoders/wmv9.h
index 13f34fda..67f92056 100644
--- a/decoder/LAVVideo/decoders/wmv9.h
+++ b/decoder/LAVVideo/decoders/wmv9.h
@@ -72,10 +72,12 @@ private:
AVRational m_StreamAR;
LAVPixelFormat m_OutPixFmt;
+ AVCodecID m_nCodecId;
CCritSec m_BufferCritSec;
std::vector<Buffer *> m_BufferQueue;
+ BOOL m_bNeedKeyFrame;
BOOL m_bManualReorder;
BOOL m_bReorderBufferValid;
REFERENCE_TIME m_rtReorderBuffer;