Maarten Lankhorst : quartz: Dump opendml indexes and header.
Alexandre Julliard
julliard at winehq.org
Wed Apr 16 08:09:52 CDT 2008
Module: wine
Branch: master
Commit: 64be38a5b20b5fe64d52e4c2464434e6b5a313d0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=64be38a5b20b5fe64d52e4c2464434e6b5a313d0
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Fri Apr 11 14:02:26 2008 -0700
quartz: Dump opendml indexes and header.
---
dlls/quartz/avisplit.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 135 insertions(+), 1 deletions(-)
diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c
index ee002ce..ce44f95 100644
--- a/dlls/quartz/avisplit.c
+++ b/dlls/quartz/avisplit.c
@@ -3,6 +3,7 @@
*
* Copyright 2003 Robert Shearman
* Copyright 2004-2005 Christian Costa
+ * Copyright 2008 Maarten Lankhorst
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -340,6 +341,60 @@ static HRESULT AVISplitter_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
return S_FALSE;
}
+static HRESULT AVISplitter_ProcessIndex(AVISplitterImpl *This, LONGLONG qwOffset, DWORD cb)
+{
+ AVISTDINDEX *pIndex;
+ int x;
+ long rest;
+
+ if (cb < sizeof(AVISTDINDEX))
+ {
+ FIXME("size %u too small\n", cb);
+ return E_INVALIDARG;
+ }
+
+ pIndex = CoTaskMemAlloc(cb);
+ if (!pIndex)
+ return E_OUTOFMEMORY;
+
+ IAsyncReader_SyncRead(((PullPin *)This->Parser.ppPins[0])->pReader, qwOffset, cb, (BYTE *)pIndex);
+ pIndex = CoTaskMemRealloc(pIndex, pIndex->cb);
+ if (!pIndex)
+ return E_OUTOFMEMORY;
+
+ IAsyncReader_SyncRead(((PullPin *)This->Parser.ppPins[0])->pReader, qwOffset, pIndex->cb, (BYTE *)pIndex);
+ rest = pIndex->cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex[0]) * ANYSIZE_ARRAY;
+
+ TRACE("wLongsPerEntry: %hd\n", pIndex->wLongsPerEntry);
+ TRACE("bIndexSubType: %hd\n", pIndex->bIndexSubType);
+ TRACE("bIndexType: %hd\n", pIndex->bIndexType);
+ TRACE("nEntriesInUse: %u\n", pIndex->nEntriesInUse);
+ TRACE("dwChunkId: %.4s\n", (char *)&pIndex->dwChunkId);
+ TRACE("qwBaseOffset: %x%08x\n", (DWORD)(pIndex->qwBaseOffset >> 32), (DWORD)pIndex->qwBaseOffset);
+ TRACE("dwReserved_3: %u\n", pIndex->dwReserved_3);
+
+ if (pIndex->bIndexType != AVI_INDEX_OF_CHUNKS
+ || pIndex->wLongsPerEntry != 2
+ || rest < (pIndex->nEntriesInUse * sizeof(DWORD) * pIndex->wLongsPerEntry)
+ || (pIndex->bIndexSubType != AVI_INDEX_SUB_DEFAULT))
+ {
+ FIXME("Invalid index chunk encountered\n");
+ return E_INVALIDARG;
+ }
+
+ for (x = 0; x < pIndex->nEntriesInUse; ++x)
+ {
+ BOOL keyframe = !(pIndex->aIndex[x].dwOffset >> 31);
+ DWORDLONG offset = pIndex->qwBaseOffset + (pIndex->aIndex[x].dwOffset & ~(1<<31));
+ TRACE("dwOffset: %x%08x\n", (DWORD)(offset >> 32), (DWORD)offset);
+ TRACE("dwSize: %u\n", pIndex->aIndex[x].dwSize);
+ TRACE("Frame is a keyframe: %s\n", keyframe ? "yes" : "no");
+ }
+
+ CoTaskMemFree(pIndex);
+ return S_OK;
+}
+
static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE * pData, DWORD cb)
{
PIN_INFO piOutput;
@@ -388,6 +443,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
amt.formattype = FORMAT_WaveFormatEx;
break;
default:
+ FIXME("fccType %.4s not handled yet\n", (char *)&pStrHdr->fccType);
amt.formattype = FORMAT_None;
}
amt.majortype = MEDIATYPE_Video;
@@ -456,6 +512,48 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
case ckidAVIPADDING:
TRACE("JUNK chunk ignored\n");
break;
+ case ckidAVISUPERINDEX:
+ {
+ const AVISUPERINDEX *pIndex = (const AVISUPERINDEX *)pChunk;
+ int x;
+ long rest = pIndex->cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex[0]) * ANYSIZE_ARRAY;
+
+ if (pIndex->cb < sizeof(AVISUPERINDEX) - sizeof(RIFFCHUNK))
+ {
+ FIXME("%u < %u?!\n", pIndex->cb, sizeof(AVISUPERINDEX) - sizeof(RIFFCHUNK));
+ break;
+ }
+
+ TRACE("wLongsPerEntry: %hd\n", pIndex->wLongsPerEntry);
+ TRACE("bIndexSubType: %hd\n", pIndex->bIndexSubType);
+ TRACE("bIndexType: %hd\n", pIndex->bIndexType);
+ TRACE("nEntriesInUse: %u\n", pIndex->nEntriesInUse);
+ TRACE("dwChunkId: %.4s\n", (char *)&pIndex->dwChunkId);
+ if (pIndex->dwReserved[0])
+ TRACE("dwReserved[0]: %u\n", pIndex->dwReserved[0]);
+ if (pIndex->dwReserved[2])
+ TRACE("dwReserved[1]: %u\n", pIndex->dwReserved[1]);
+ if (pIndex->dwReserved[2])
+ TRACE("dwReserved[2]: %u\n", pIndex->dwReserved[2]);
+
+ if (pIndex->bIndexType != AVI_INDEX_OF_INDEXES
+ || pIndex->wLongsPerEntry != 4
+ || rest < (pIndex->nEntriesInUse * sizeof(DWORD) * pIndex->wLongsPerEntry)
+ || (pIndex->bIndexSubType != AVI_INDEX_SUB_2FIELD && pIndex->bIndexSubType != AVI_INDEX_SUB_DEFAULT))
+ {
+ FIXME("Invalid index chunk encountered\n");
+ break;
+ }
+ for (x = 0; x < pIndex->nEntriesInUse; ++x)
+ {
+ TRACE("qwOffset: %x%08x\n", (DWORD)(pIndex->aIndex[x].qwOffset >> 32), (DWORD)pIndex->aIndex[x].qwOffset);
+ TRACE("dwSize: %u\n", pIndex->aIndex[x].dwSize);
+ AVISplitter_ProcessIndex(This, pIndex->aIndex[x].qwOffset, pIndex->aIndex[x].dwSize);
+
+ TRACE("dwDuration: %u (unreliable)\n", pIndex->aIndex[x].dwDuration);
+ }
+ break;
+ }
default:
FIXME("unknown chunk type \"%.04s\" ignored\n", (LPCSTR)&pChunk->fcc);
}
@@ -482,6 +580,42 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
return hr;
}
+static HRESULT AVISplitter_ProcessODML(AVISplitterImpl * This, const BYTE * pData, DWORD cb)
+{
+ const RIFFCHUNK * pChunk;
+
+ for (pChunk = (const RIFFCHUNK *)pData;
+ ((const BYTE *)pChunk >= pData) && ((const BYTE *)pChunk + sizeof(RIFFCHUNK) < pData + cb) && (pChunk->cb > 0);
+ pChunk = (const RIFFCHUNK *)((const BYTE*)pChunk + sizeof(RIFFCHUNK) + pChunk->cb)
+ )
+ {
+ switch (pChunk->fcc)
+ {
+ case ckidAVIEXTHEADER:
+ {
+ int x;
+ const AVIEXTHEADER * pExtHdr = (const AVIEXTHEADER *)pChunk;
+
+ TRACE("processing extension header\n");
+ if (pExtHdr->cb != sizeof(AVIEXTHEADER) - sizeof(RIFFCHUNK))
+ {
+ FIXME("Size: %u, other size: %u\n", pExtHdr->cb, sizeof(AVIEXTHEADER) - sizeof(RIFFCHUNK));
+ break;
+ }
+ TRACE("dwGrandFrames: %u\n", pExtHdr->dwGrandFrames);
+ for (x = 0; x < 61; ++x)
+ if (pExtHdr->dwFuture[x])
+ FIXME("dwFuture[%i] = %u (0x%08x)\n", x, pExtHdr->dwFuture[x], pExtHdr->dwFuture[x]);
+ break;
+ }
+ default:
+ FIXME("unknown chunk type \"%.04s\" ignored\n", (LPCSTR)&pChunk->fcc);
+ }
+ }
+
+ return S_OK;
+}
+
/* FIXME: fix leaks on failure here */
static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
{
@@ -542,7 +676,7 @@ static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
hr = AVISplitter_ProcessStreamList(pAviSplit, (BYTE *)pCurrentChunk + sizeof(RIFFLIST), pCurrentChunk->cb + sizeof(RIFFCHUNK) - sizeof(RIFFLIST));
break;
case ckidODML:
- FIXME("process ODML header\n");
+ hr = AVISplitter_ProcessODML(pAviSplit, (BYTE *)pCurrentChunk + sizeof(RIFFLIST), pCurrentChunk->cb + sizeof(RIFFCHUNK) - sizeof(RIFFLIST));
break;
}
break;
More information about the wine-cvs
mailing list