quartz: Dump opendml indexes and header.
This commit is contained in:
parent
bd38e2b0ed
commit
64be38a5b2
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright 2003 Robert Shearman
|
* Copyright 2003 Robert Shearman
|
||||||
* Copyright 2004-2005 Christian Costa
|
* Copyright 2004-2005 Christian Costa
|
||||||
|
* Copyright 2008 Maarten Lankhorst
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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;
|
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)
|
static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE * pData, DWORD cb)
|
||||||
{
|
{
|
||||||
PIN_INFO piOutput;
|
PIN_INFO piOutput;
|
||||||
|
@ -388,6 +443,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
|
||||||
amt.formattype = FORMAT_WaveFormatEx;
|
amt.formattype = FORMAT_WaveFormatEx;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
FIXME("fccType %.4s not handled yet\n", (char *)&pStrHdr->fccType);
|
||||||
amt.formattype = FORMAT_None;
|
amt.formattype = FORMAT_None;
|
||||||
}
|
}
|
||||||
amt.majortype = MEDIATYPE_Video;
|
amt.majortype = MEDIATYPE_Video;
|
||||||
|
@ -456,6 +512,48 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
|
||||||
case ckidAVIPADDING:
|
case ckidAVIPADDING:
|
||||||
TRACE("JUNK chunk ignored\n");
|
TRACE("JUNK chunk ignored\n");
|
||||||
break;
|
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:
|
default:
|
||||||
FIXME("unknown chunk type \"%.04s\" ignored\n", (LPCSTR)&pChunk->fcc);
|
FIXME("unknown chunk type \"%.04s\" ignored\n", (LPCSTR)&pChunk->fcc);
|
||||||
}
|
}
|
||||||
|
@ -482,6 +580,42 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
|
||||||
return hr;
|
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 */
|
/* FIXME: fix leaks on failure here */
|
||||||
static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin)
|
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));
|
hr = AVISplitter_ProcessStreamList(pAviSplit, (BYTE *)pCurrentChunk + sizeof(RIFFLIST), pCurrentChunk->cb + sizeof(RIFFCHUNK) - sizeof(RIFFLIST));
|
||||||
break;
|
break;
|
||||||
case ckidODML:
|
case ckidODML:
|
||||||
FIXME("process ODML header\n");
|
hr = AVISplitter_ProcessODML(pAviSplit, (BYTE *)pCurrentChunk + sizeof(RIFFLIST), pCurrentChunk->cb + sizeof(RIFFCHUNK) - sizeof(RIFFLIST));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue