по формату AVI
От: bolivar Латвия  
Дата: 27.12.04 14:54
Оценка:
кто-нибудь может подсказать ,где в файле формата AVI находятся REFERENCE_TIME данные самплов ?
Re: по формату AVI
От: romson  
Дата: 27.12.04 17:33
Оценка:
Здравствуйте, bolivar, Вы писали:

B>кто-нибудь может подсказать ,где в файле формата AVI находятся REFERENCE_TIME данные самплов ?


Насколько я знаю, REFERENCE_TIME данные в AVI не хранятся. В заголовке каждого потока есть данные о его продолжительности и количестве сэмплов. Исходя из этого, можно вычислить время каждого сэмпла по его номеру.
Хотя, может быть, какие-нибудь кодеки и помещают свои REFERENCE_TIME в закодированные сэмплы, но к формату AVI это уже не имеет никакого отношения.

ЗЫ. Про формат AVI можно почитать здесь.
Re[2]: по формату AVI
От: bolivar Латвия  
Дата: 28.12.04 07:36
Оценка:
Здравствуйте, romson, Вы писали:

R>Здравствуйте, bolivar, Вы писали:


B>>кто-нибудь может подсказать ,где в файле формата AVI находятся REFERENCE_TIME данные самплов ?


R>Насколько я знаю, REFERENCE_TIME данные в AVI не хранятся. В заголовке каждого потока есть данные о его продолжительности и количестве сэмплов. Исходя из этого, можно вычислить время каждого сэмпла по его номеру.

R>Хотя, может быть, какие-нибудь кодеки и помещают свои REFERENCE_TIME в закодированные сэмплы, но к формату AVI это уже не имеет никакого отношения.

R>ЗЫ. Про формат AVI можно почитать здесь.


спасибо за информацию.

как понять кусок из filesink.c (quartz — проект wine):

static HRESULT CFileWriterPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
{
CFileWriterPinImpl_THIS(pImpl,pin);
BYTE* pData = NULL;
LONG lLength;
ULONG cbWritten;
HRESULT hr;
REFERENCE_TIME rtStart;
REFERENCE_TIME rtEnd;
LARGE_INTEGER dlibMove;

TRACE( "(%p,%p)\n",This,pSample );

if ( This->pRender->m_fInFlush )
return S_FALSE;
if ( pSample == NULL )
return E_POINTER;

hr = IMediaSample_GetPointer(pSample,&pData);
if ( FAILED(hr) )
return hr;
lLength = (LONG)IMediaSample_GetActualDataLength(pSample);
if ( lLength == 0 )
return S_OK;

if ( lLength < 0 )
{
ERR( "invalid length: %ld\n", lLength );
return S_OK;
}

hr = IMediaSample_GetTime( pSample, &rtStart, &rtEnd );
if ( FAILED(hr) )
return hr;

dlibMove.QuadPart = rtStart;
hr = IStream_Seek(CFileWriterPinImpl_IStream(This),dlibMove,STREAM_SEEK_SET,NULL);
if ( FAILED(hr) )
return hr;

hr = IStream_Write(CFileWriterPinImpl_IStream(This),pData,lLength,&cbWritten);

return hr;
}
Re[3]: по формату AVI
От: Денис Майдыковский Россия http://www.maydyk.com
Дата: 28.12.04 08:12
Оценка:
Здравствуйте, bolivar, Вы писали:

B>как понять кусок из filesink.c (quartz — проект wine):


А можно по подробнее узнать про проект "wine" и где можно посмотреть на исходники filesink.c?
Re[4]: по формату AVI
От: bolivar Латвия  
Дата: 28.12.04 08:27
Оценка:
Здравствуйте, Денис Майдыковский, Вы писали:

ДМ>Здравствуйте, bolivar, Вы писали:


B>>как понять кусок из filesink.c (quartz — проект wine):


ДМ>А можно по подробнее узнать про проект "wine" и где можно посмотреть на исходники filesink.c?


у меня другой вопрос:

JUNK Chunk
One other type of chunk that is commonly encountered in an AVI chunk is the padding or JUNK chunk (so named because its chunk identifier is JUNK). This chunk is used to pad data out to specific boundaries (for example, CD-ROMs use 2048-byte boundaries). The size of the chunk is the number of bytes of padding it contains. If you are reading AVI data, do not use use the data in the JUNK chunk. Skip it when reading and preserve it when writing. The JUNK chunk uses the standard chunk structure:

typedef struct _JunkChunk
{
DWORD ChunkId; /* Chunk ID marker (JUNK)*/
DWORD PaggingSize; /* Size of the padding in bytes */
BYTE Padding[ChunkSize]; /* Padding */
} JUNKCHUNK;

етот chunk везде торчит в chunk-ах 'movi' и с ним лучше фильтр работает чем без него.

проект wine — windoza под linux наскока я понимаю.

здесь:

/*
* Implements CLSID_FileWriter.
*
* Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FIXME — not tested
*/

#include "config.h"

#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "mmsystem.h"
#include "strmif.h"
#include "control.h"
#include "vfwmsgs.h"
#include "uuids.h"
#include "evcode.h"

#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);

#include "quartz_private.h"
#include "filesink.h"
#include "seekpass.h"

static const WCHAR QUARTZ_FileWriter_Name[] =
{ 'F','i','l','e',' ','W','r','i','t','e','r',0 };
static const WCHAR QUARTZ_FileWriterPin_Name[] =
{ 'I','n',0 };


/* FIXME — add this flag to strmif.h */
#define AM_FILE_OVERWRITE 0x1

/***************************************************************************
*
* CFileWriterImpl methods
*
*/

static HRESULT CFileWriterImpl_OnActive( CBaseFilterImpl* pImpl )
{
CFileWriterImpl_THIS(pImpl,basefilter);

FIXME( "(%p)\n", This );

return NOERROR;
}

static HRESULT CFileWriterImpl_OnInactive( CBaseFilterImpl* pImpl )
{
CFileWriterImpl_THIS(pImpl,basefilter);

FIXME( "(%p)\n", This );

return NOERROR;
}

static const CBaseFilterHandlers filterhandlers =
{
CFileWriterImpl_OnActive, /* pOnActive */
CFileWriterImpl_OnInactive, /* pOnInactive */
NULL, /* pOnStop */
};


/***************************************************************************
*
* CFileWriterPinImpl methods
*
*/

static HRESULT CFileWriterPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
{
CFileWriterPinImpl_THIS(pImpl,pin);

TRACE("(%p,%p)\n",This,pPin);

return NOERROR;
}

static HRESULT CFileWriterPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
{
CFileWriterPinImpl_THIS(pImpl,pin);

TRACE("(%p,%p)\n",This,pPin);

return NOERROR;
}

static HRESULT CFileWriterPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
{
CFileWriterPinImpl_THIS(pImpl,pin);

TRACE("(%p)\n",This);

if ( This->meminput.pAllocator != NULL )
{
IMemAllocator_Decommit(This->meminput.pAllocator);
IMemAllocator_Release(This->meminput.pAllocator);
This->meminput.pAllocator = NULL;
}

return NOERROR;
}

static HRESULT CFileWriterPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
{
CFileWriterPinImpl_THIS(pImpl,pin);

TRACE("(%p,%p)\n",This,pmt);

if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
return E_FAIL;

return NOERROR;
}

static HRESULT CFileWriterPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
{
CFileWriterPinImpl_THIS(pImpl,pin);
BYTE* pData = NULL;
LONG lLength;
ULONG cbWritten;
HRESULT hr;
REFERENCE_TIME rtStart;
REFERENCE_TIME rtEnd;
LARGE_INTEGER dlibMove;

TRACE( "(%p,%p)\n",This,pSample );

if ( This->pRender->m_fInFlush )
return S_FALSE;
if ( pSample == NULL )
return E_POINTER;

hr = IMediaSample_GetPointer(pSample,&pData);
if ( FAILED(hr) )
return hr;
lLength = (LONG)IMediaSample_GetActualDataLength(pSample);
if ( lLength == 0 )
return S_OK;

if ( lLength < 0 )
{
ERR( "invalid length: %ld\n", lLength );
return S_OK;
}

hr = IMediaSample_GetTime( pSample, &rtStart, &rtEnd );
if ( FAILED(hr) )
return hr;

dlibMove.QuadPart = rtStart;
hr = IStream_Seek(CFileWriterPinImpl_IStream(This),dlibMove,STREAM_SEEK_SET,NULL);
if ( FAILED(hr) )
return hr;

hr = IStream_Write(CFileWriterPinImpl_IStream(This),pData,lLength,&cbWritten);

return hr;
}

static HRESULT CFileWriterPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
{
CFileWriterPinImpl_THIS(pImpl,pin);

TRACE( "(%p)\n", This );

return S_FALSE;
}

static HRESULT CFileWriterPinImpl_EndOfStream( CPinBaseImpl* pImpl )
{
CFileWriterPinImpl_THIS(pImpl,pin);

FIXME( "(%p)\n", This );

This->pRender->m_fInFlush = FALSE;


/* FIXME — don't notify twice until stopped or seeked. */
return CBaseFilterImpl_MediaEventNotify(
&This->pRender->basefilter, EC_COMPLETE,
(LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
}

static HRESULT CFileWriterPinImpl_BeginFlush( CPinBaseImpl* pImpl )
{
CFileWriterPinImpl_THIS(pImpl,pin);

FIXME( "(%p)\n", This );

This->pRender->m_fInFlush = TRUE;


return NOERROR;
}

static HRESULT CFileWriterPinImpl_EndFlush( CPinBaseImpl* pImpl )
{
CFileWriterPinImpl_THIS(pImpl,pin);

FIXME( "(%p)\n", This );

This->pRender->m_fInFlush = FALSE;


return NOERROR;
}

static HRESULT CFileWriterPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
{
CFileWriterPinImpl_THIS(pImpl,pin);

FIXME( "(%p)\n", This );

This->pRender->m_fInFlush = FALSE;


return NOERROR;
}




static const CBasePinHandlers pinhandlers =
{
CFileWriterPinImpl_OnPreConnect, /* pOnPreConnect */
CFileWriterPinImpl_OnPostConnect, /* pOnPostConnect */
CFileWriterPinImpl_OnDisconnect, /* pOnDisconnect */
CFileWriterPinImpl_CheckMediaType, /* pCheckMediaType */
NULL, /* pQualityNotify */
CFileWriterPinImpl_Receive, /* pReceive */
CFileWriterPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
CFileWriterPinImpl_EndOfStream, /* pEndOfStream */
CFileWriterPinImpl_BeginFlush, /* pBeginFlush */
CFileWriterPinImpl_EndFlush, /* pEndFlush */
CFileWriterPinImpl_NewSegment, /* pNewSegment */
};


/***************************************************************************
*
* new/delete CFileWriterImpl
*
*/

/* can I use offsetof safely? — FIXME? */
static QUARTZ_IFEntry FilterIFEntries[] =
{
{ &IID_IPersist, offsetof(CFileWriterImpl,basefilter)-offsetof(CFileWriterImpl,unk) },
{ &IID_IMediaFilter, offsetof(CFileWriterImpl,basefilter)-offsetof(CFileWriterImpl,unk) },
{ &IID_IBaseFilter, offsetof(CFileWriterImpl,basefilter)-offsetof(CFileWriterImpl,unk) },
{ &IID_IFileSinkFilter, offsetof(CFileWriterImpl,filesink)-offsetof(CFileWriterImpl,unk) },
{ &IID_IFileSinkFilter2, offsetof(CFileWriterImpl,filesink)-offsetof(CFileWriterImpl,unk) },
};

static HRESULT CFileWriterImpl_OnQueryInterface(
IUnknown* punk, const IID* piid, void** ppobj )
{
CFileWriterImpl_THIS(punk,unk);

if ( This->pSeekPass == NULL )
return E_NOINTERFACE;

if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
IsEqualGUID( &IID_IMediaSeeking, piid ) )
{
TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
}

return E_NOINTERFACE;
}

static void QUARTZ_DestroyFileWriter(IUnknown* punk)
{
CFileWriterImpl_THIS(punk,unk);

TRACE( "(%p)\n", This );
CFileWriterImpl_OnInactive(&This->basefilter);

if ( This->pPin != NULL )
{
IUnknown_Release(This->pPin->unk.punkControl);
This->pPin = NULL;
}
if ( This->pSeekPass != NULL )
{
IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
This->pSeekPass = NULL;
}

if ( This->m_hFile != INVALID_HANDLE_VALUE )
{
CloseHandle( This->m_hFile );
This->m_hFile = INVALID_HANDLE_VALUE;
}
if ( This->m_pszFileName != NULL )
{
QUARTZ_FreeMem( This->m_pszFileName );
This->m_pszFileName = NULL;
}
QUARTZ_MediaType_Free( &This->m_mt );

CFileWriterImpl_UninitIFileSinkFilter2(This);
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);

DeleteCriticalSection( &This->m_csReceive );
}

HRESULT QUARTZ_CreateFileWriter(IUnknown* punkOuter,void** ppobj)
{
CFileWriterImpl* This = NULL;
HRESULT hr;

TRACE("(%p,%p)\n",punkOuter,ppobj);

This = (CFileWriterImpl*)
QUARTZ_AllocObj( sizeof(CFileWriterImpl) );
if ( This == NULL )
return E_OUTOFMEMORY;
This->pSeekPass = NULL;
This->pPin = NULL;
This->m_fInFlush = FALSE;

This->m_hFile = INVALID_HANDLE_VALUE;

This->m_pszFileName = NULL;
This->m_cbFileName = 0;
This->m_dwMode = 0;
ZeroMemory( &This->m_mt, sizeof(AM_MEDIA_TYPE) );

QUARTZ_IUnkInit( &This->unk, punkOuter );
This->qiext.pNext = NULL;
This->qiext.pOnQueryInterface = &CFileWriterImpl_OnQueryInterface;
QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );

hr = CBaseFilterImpl_InitIBaseFilter(
&This->basefilter,
This->unk.punkControl,
&CLSID_FileWriter,
QUARTZ_FileWriter_Name,
&filterhandlers );
if ( SUCCEEDED(hr) )
{
hr = CFileWriterImpl_InitIFileSinkFilter2(This);
if ( FAILED(hr) )
{
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
}
}

if ( FAILED(hr) )
{
QUARTZ_FreeObj(This);
return hr;
}

This->unk.pEntries = FilterIFEntries;

This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
This->unk.pOnFinalRelease = QUARTZ_DestroyFileWriter;

InitializeCriticalSection( &This->m_csReceive );

hr = QUARTZ_CreateFileWriterPin(
This,
&This->basefilter.csFilter,
&This->m_csReceive,
&This->pPin );
if ( SUCCEEDED(hr) )
hr = QUARTZ_CompList_AddComp(
This->basefilter.pInPins,
(IUnknown*)&This->pPin->pin,
NULL, 0 );
if ( SUCCEEDED(hr) )
hr = QUARTZ_CreateSeekingPassThruInternal(
(IUnknown*)&(This->unk), &This->pSeekPass,
TRUE, (IPin*)&(This->pPin->pin) );

if ( FAILED(hr) )
{
IUnknown_Release( This->unk.punkControl );
return hr;
}

*ppobj = (void*)&(This->unk);

return S_OK;
}

/***************************************************************************
*
* new/delete CFileWriterPinImpl
*
*/

/* can I use offsetof safely? — FIXME? */
static QUARTZ_IFEntry PinIFEntries[] =
{
{ &IID_IPin, offsetof(CFileWriterPinImpl,pin)-offsetof(CFileWriterPinImpl,unk) },
{ &IID_IMemInputPin, offsetof(CFileWriterPinImpl,meminput)-offsetof(CFileWriterPinImpl,unk) },
{ &IID_IStream, offsetof(CFileWriterPinImpl,stream)-offsetof(CFileWriterPinImpl,unk) },
};

static void QUARTZ_DestroyFileWriterPin(IUnknown* punk)
{
CFileWriterPinImpl_THIS(punk,unk);

TRACE( "(%p)\n", This );

CPinBaseImpl_UninitIPin( &This->pin );
CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
CFileWriterPinImpl_UninitIStream(This);
}

HRESULT QUARTZ_CreateFileWriterPin(
CFileWriterImpl* pFilter,
CRITICAL_SECTION* pcsPin,
CRITICAL_SECTION* pcsPinReceive,
CFileWriterPinImpl** ppPin)
{
CFileWriterPinImpl* This = NULL;
HRESULT hr;

TRACE("(%p,%p,%p,%p)\n",pFilter,pcsPin,pcsPinReceive,ppPin);

This = (CFileWriterPinImpl*)
QUARTZ_AllocObj( sizeof(CFileWriterPinImpl) );
if ( This == NULL )
return E_OUTOFMEMORY;

QUARTZ_IUnkInit( &This->unk, NULL );
This->pRender = pFilter;

hr = CPinBaseImpl_InitIPin(
&This->pin,
This->unk.punkControl,
pcsPin, pcsPinReceive,
&pFilter->basefilter,
QUARTZ_FileWriterPin_Name,
FALSE,
&pinhandlers );

if ( SUCCEEDED(hr) )
{
hr = CMemInputPinBaseImpl_InitIMemInputPin(
&This->meminput,
This->unk.punkControl,
&This->pin );
if ( SUCCEEDED(hr) )
{
hr = CFileWriterPinImpl_InitIStream(This);
if ( FAILED(hr) )
{
CMemInputPinBaseImpl_UninitIMemInputPin(&This->meminput);
}
}

if ( FAILED(hr) )
{
CPinBaseImpl_UninitIPin( &This->pin );
}
}

if ( FAILED(hr) )
{
QUARTZ_FreeObj(This);
return hr;
}

This->unk.pEntries = PinIFEntries;

This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
This->unk.pOnFinalRelease = QUARTZ_DestroyFileWriterPin;

*ppPin = This;

TRACE("returned successfully.\n");

return S_OK;
}

/***************************************************************************
*
* CFileWriterPinImpl::IStream
*
*/

static HRESULT WINAPI
IStream_fnQueryInterface(IStream* iface,REFIID riid,void** ppobj)
{
CFileWriterPinImpl_THIS(iface,stream);

TRACE("(%p)->()\n",This);

return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IStream_fnAddRef(IStream* iface)
{
CFileWriterPinImpl_THIS(iface,stream);

TRACE("(%p)->()\n",This);

return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IStream_fnRelease(IStream* iface)
{
CFileWriterPinImpl_THIS(iface,stream);

TRACE("(%p)->()\n",This);

return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
IStream_fnRead(IStream* iface,void* pv,ULONG cb,ULONG* pcbRead)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->()\n",This);

return E_FAIL;
}

static HRESULT WINAPI
IStream_fnWrite(IStream* iface,const void* pv,ULONG cb,ULONG* pcbWritten)
{
CFileWriterPinImpl_THIS(iface,stream);
HRESULT hr;

FIXME("(%p)->(%p,%lu,%p)\n",This,pv,cb,pcbWritten);

EnterCriticalSection( &This->pRender->m_csReceive );
if ( This->pRender->m_hFile == INVALID_HANDLE_VALUE )
{
hr = E_UNEXPECTED;
goto err;
}

if ( ! WriteFile( This->pRender->m_hFile, pv, cb, pcbWritten, NULL ) )
{
hr = E_FAIL;
goto err;
}

hr = S_OK;
err:
LeaveCriticalSection( &This->pRender->m_csReceive );
return hr;
}

static HRESULT WINAPI
IStream_fnSeek(IStream* iface,LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER* plibNewPosition)
{
CFileWriterPinImpl_THIS(iface,stream);
HRESULT hr;
DWORD dwDistLow;
LONG lDistHigh;

FIXME("(%p)->() stub!\n",This);

EnterCriticalSection( &This->pRender->m_csReceive );
if ( This->pRender->m_hFile == INVALID_HANDLE_VALUE )
{
hr = E_UNEXPECTED;
goto err;
}

dwDistLow = dlibMove.s.LowPart;
lDistHigh = dlibMove.s.HighPart;

SetLastError(0);
dwDistLow = SetFilePointer( This->pRender->m_hFile, (LONG)dwDistLow, &lDistHigh, dwOrigin );
if ( dwDistLow == 0xffffffff && GetLastError() != 0 )
{
hr = E_FAIL;
goto err;
}

if ( plibNewPosition != NULL )
{
plibNewPosition->s.LowPart = dwDistLow;
plibNewPosition->s.HighPart = lDistHigh;
}

hr = S_OK;
err:
LeaveCriticalSection( &This->pRender->m_csReceive );
return hr;
}

static HRESULT WINAPI
IStream_fnSetSize(IStream* iface,ULARGE_INTEGER libNewSize)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

if ( This->pRender->m_hFile == INVALID_HANDLE_VALUE )
return E_UNEXPECTED;


return E_NOTIMPL;
}

static HRESULT WINAPI
IStream_fnCopyTo(IStream* iface,IStream* pstrm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->()\n",This);

return E_FAIL;
}

static HRESULT WINAPI
IStream_fnCommit(IStream* iface,DWORD grfCommitFlags)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

return E_NOTIMPL;
}

static HRESULT WINAPI
IStream_fnRevert(IStream* iface)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

return E_NOTIMPL;
}

static HRESULT WINAPI
IStream_fnLockRegion(IStream* iface,ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

return E_NOTIMPL;
}

static HRESULT WINAPI
IStream_fnUnlockRegion(IStream* iface,ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

return E_NOTIMPL;
}

static HRESULT WINAPI
IStream_fnStat(IStream* iface,STATSTG* pstatstg,DWORD grfStatFlag)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

return E_NOTIMPL;
}

static HRESULT WINAPI
IStream_fnClone(IStream* iface,IStream** ppstrm)
{
CFileWriterPinImpl_THIS(iface,stream);

FIXME("(%p)->() stub!\n",This);

return E_NOTIMPL;
}

static ICOM_VTABLE(IStream) istream =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IStream_fnQueryInterface,
IStream_fnAddRef,
IStream_fnRelease,
/* IStream fields */
IStream_fnRead,
IStream_fnWrite,
IStream_fnSeek,
IStream_fnSetSize,
IStream_fnCopyTo,
IStream_fnCommit,
IStream_fnRevert,
IStream_fnLockRegion,
IStream_fnUnlockRegion,
IStream_fnStat,
IStream_fnClone,
};

HRESULT CFileWriterPinImpl_InitIStream( CFileWriterPinImpl* This )
{
TRACE("(%p)\n",This);
ICOM_VTBL(&This->stream) = &istream;

return NOERROR;
}

HRESULT CFileWriterPinImpl_UninitIStream( CFileWriterPinImpl* This )
{
TRACE("(%p)\n",This);

return S_OK;
}


/***************************************************************************
*
* CFileWriterImpl::IFileSinkFilter2
*
*/

static HRESULT WINAPI
IFileSinkFilter2_fnQueryInterface(IFileSinkFilter2* iface,REFIID riid,void** ppobj)
{
CFileWriterImpl_THIS(iface,filesink);

TRACE("(%p)->()\n",This);

return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IFileSinkFilter2_fnAddRef(IFileSinkFilter2* iface)
{
CFileWriterImpl_THIS(iface,filesink);

TRACE("(%p)->()\n",This);

return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IFileSinkFilter2_fnRelease(IFileSinkFilter2* iface)
{
CFileWriterImpl_THIS(iface,filesink);

TRACE("(%p)->()\n",This);

return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
IFileSinkFilter2_fnSetFileName(IFileSinkFilter2* iface,LPCOLESTR pszFileName,const AM_MEDIA_TYPE* pmt)
{
CFileWriterImpl_THIS(iface,filesink);
HRESULT hr;

TRACE("(%p)->(%s,%p)\n",This,debugstr_w(pszFileName),pmt);

if ( pszFileName == NULL )
return E_POINTER;

if ( This->m_pszFileName != NULL )
return E_UNEXPECTED;

This->m_cbFileName = sizeof(WCHAR)*(lstrlenW(pszFileName)+1);

This->m_pszFileName = (WCHAR*)QUARTZ_AllocMem( This->m_cbFileName );
if ( This->m_pszFileName == NULL )
return E_OUTOFMEMORY;
memcpy( This->m_pszFileName, pszFileName, This->m_cbFileName );

if ( pmt != NULL )
{
hr = QUARTZ_MediaType_Copy( &This->m_mt, pmt );
if ( FAILED(hr) )
goto err;
}
else
{
ZeroMemory( &This->m_mt, sizeof(AM_MEDIA_TYPE) );
memcpy( &This->m_mt.majortype, &MEDIATYPE_Stream, sizeof(GUID) );
memcpy( &This->m_mt.subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) );
This->m_mt.lSampleSize = 1;
memcpy( &This->m_mt.formattype, &FORMAT_None, sizeof(GUID) );
}

This->m_hFile = CreateFileW(

This->m_pszFileName,
GENERIC_WRITE,
0,
NULL,
( This->m_dwMode == AM_FILE_OVERWRITE ) ? CREATE_ALWAYS : OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL );
if ( This->m_hFile == INVALID_HANDLE_VALUE )
{
hr = E_FAIL;
goto err;
}

This->pPin->pin.pmtAcceptTypes = &This->m_mt;

This->pPin->pin.cAcceptTypes = 1;

return NOERROR;
err:;
return hr;
}

static HRESULT WINAPI
IFileSinkFilter2_fnGetCurFile(IFileSinkFilter2* iface,LPOLESTR* ppszFileName,AM_MEDIA_TYPE* pmt)
{
CFileWriterImpl_THIS(iface,filesink);
HRESULT hr = E_NOTIMPL;

TRACE("(%p)->(%p,%p)\n",This,ppszFileName,pmt);

if ( ppszFileName == NULL || pmt == NULL )
return E_POINTER;

if ( This->m_pszFileName == NULL )
return E_FAIL;

hr = QUARTZ_MediaType_Copy( pmt, &This->m_mt );
if ( FAILED(hr) )
return hr;

*ppszFileName = (WCHAR*)CoTaskMemAlloc( This->m_cbFileName );
if ( *ppszFileName == NULL )
{
QUARTZ_MediaType_Free(pmt);
ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
return E_OUTOFMEMORY;
}

memcpy( *ppszFileName, This->m_pszFileName, This->m_cbFileName );

return NOERROR;
}

static HRESULT WINAPI
IFileSinkFilter2_fnSetMode(IFileSinkFilter2* iface,DWORD dwFlags)
{
CFileWriterImpl_THIS(iface,filesink);

TRACE("(%p)->(%08lx)\n",This,dwFlags);

if ( dwFlags != 0 && dwFlags != AM_FILE_OVERWRITE )
return E_INVALIDARG;
This->m_dwMode = dwFlags;

return S_OK;
}

static HRESULT WINAPI
IFileSinkFilter2_fnGetMode(IFileSinkFilter2* iface,DWORD* pdwFlags)
{
CFileWriterImpl_THIS(iface,filesink);

TRACE("(%p)->(%p)\n",This,pdwFlags);

if ( pdwFlags == NULL )
return E_POINTER;

*pdwFlags = This->m_dwMode;

return S_OK;
}

static ICOM_VTABLE(IFileSinkFilter2) ifilesink2 =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IFileSinkFilter2_fnQueryInterface,
IFileSinkFilter2_fnAddRef,
IFileSinkFilter2_fnRelease,
/* IFileSinkFilter2 fields */
IFileSinkFilter2_fnSetFileName,
IFileSinkFilter2_fnGetCurFile,
IFileSinkFilter2_fnSetMode,
IFileSinkFilter2_fnGetMode,
};

HRESULT CFileWriterImpl_InitIFileSinkFilter2( CFileWriterImpl* This )
{
TRACE("(%p)\n",This);
ICOM_VTBL(&This->filesink) = &ifilesink2;

return NOERROR;
}

HRESULT CFileWriterImpl_UninitIFileSinkFilter2( CFileWriterImpl* This )
{
TRACE("(%p)\n",This);

return S_OK;
}
Re[5]: по формату AVI
От: bolivar Латвия  
Дата: 28.12.04 14:03
Оценка:
в чем трабла:

закомпрессованные 'movi' chunk-и содержат header и данные:

например видео 30 30 64 62 (00db) 3F 07 00 00 (073F — size chunk-а) и т.д.

так вот если отсчитать size chunk-a то потом еще идут байтики:

3D 96 A1 B7 DE 29 DF 00 ( 8 обычно) потом пустой JUNK-chunk:

4A 55 4E 4B B0 00 00 00 ..... (JUNK.....)

Вопрос : что ето за 8 байтиков ?
Re[6]: по формату AVI
От: bolivar Латвия  
Дата: 29.12.04 07:43
Оценка:
Вопрос : что ето за 8 байтиков ?

Не вопрос — считать надо не учитывая первые 8 — ошибся сам.

все о wine — www.winehq.com
Re[7]: по формату AVI
От: bolivar Латвия  
Дата: 29.12.04 08:02
Оценка:
А почему ошибся:

IMediaSample::GetSize
The GetSize method retrieves the size of the buffer.

Syntax

long GetSize(void);

Return Value

Returns the size of the buffer, in bytes. The size does not include the prefix bytes, if any.

Брал буффер с этим size, записывал в файл и у меня пропадали последние 8 байтов.
Сделал size + 8 все OK.

GetActualDataLength() возвращает такой же size как и GetSize().
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.