| /* |
| * Implements IMediaSample2 for CMemMediaSample. |
| * |
| * 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 |
| */ |
| |
| #include "config.h" |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winerror.h" |
| #include "strmif.h" |
| #include "vfwmsgs.h" |
| |
| #include "wine/debug.h" |
| WINE_DEFAULT_DEBUG_CHANNEL(quartz); |
| |
| #include "quartz_private.h" |
| #include "sample.h" |
| #include "mtype.h" |
| |
| |
| /*************************************************************************** |
| * |
| * Helper functions |
| * |
| */ |
| |
| HRESULT QUARTZ_IMediaSample_GetProperties( |
| IMediaSample* pSample, |
| AM_SAMPLE2_PROPERTIES* pProp ) |
| { |
| #if 0 /* not yet */ |
| HRESULT hr; |
| AM_SAMPLE2_PROPERTIES prop; |
| IMediaSample2* pSample2 = NULL; |
| |
| ZeroMemory( &prop, sizeof(AM_SAMPLE2_PROPERTIES) ); |
| |
| hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 ); |
| if ( hr == S_OK ) |
| { |
| hr = IMediaSample2_GetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop); |
| IMediaSample2_Release(pSample2); |
| if ( hr == S_OK ) |
| { |
| memcpy( pProp, &prop, sizeof(AM_SAMPLE2_PROPERTIES) ); |
| pProp->pMediaType = |
| QUARTZ_MediaType_Duplicate( &prop.pMediaType ); |
| |
| return NOERROR; |
| } |
| } |
| #endif |
| |
| pProp->cbData = sizeof(AM_SAMPLE2_PROPERTIES); |
| pProp->dwTypeSpecificFlags = 0; |
| pProp->dwSampleFlags = 0; |
| if ( IMediaSample_IsSyncPoint(pSample) == S_OK ) |
| pProp->dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; |
| if ( IMediaSample_IsPreroll(pSample) == S_OK ) |
| pProp->dwSampleFlags |= AM_SAMPLE_PREROLL; |
| if ( IMediaSample_IsDiscontinuity(pSample) == S_OK ) |
| pProp->dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; |
| pProp->lActual = (LONG)IMediaSample_GetActualDataLength(pSample); |
| if ( IMediaSample_GetTime(pSample,&pProp->tStart,&pProp->tStop) == S_OK ) |
| pProp->dwSampleFlags |= AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID; |
| pProp->dwStreamId = 0; |
| if ( IMediaSample_GetMediaType(pSample,&(pProp->pMediaType)) == S_OK ) |
| pProp->dwSampleFlags |= AM_SAMPLE_TYPECHANGED; |
| IMediaSample_GetPointer(pSample,&(pProp->pbBuffer)); |
| pProp->cbBuffer = (LONG)IMediaSample_GetSize(pSample); |
| |
| return NOERROR; |
| } |
| |
| HRESULT QUARTZ_IMediaSample_SetProperties( |
| IMediaSample* pSample, |
| const AM_SAMPLE2_PROPERTIES* pProp ) |
| { |
| HRESULT hr; |
| AM_SAMPLE2_PROPERTIES prop; |
| #if 0 /* not yet */ |
| IMediaSample2* pSample2 = NULL; |
| #endif |
| |
| memcpy( &prop, pProp, sizeof(AM_SAMPLE2_PROPERTIES) ); |
| prop.cbData = sizeof(AM_SAMPLE2_PROPERTIES); |
| prop.pbBuffer = NULL; |
| prop.cbBuffer = 0; |
| |
| #if 0 /* not yet */ |
| hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 ); |
| if ( hr == S_OK ) |
| { |
| hr = IMediaSample2_SetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop); |
| IMediaSample2_Release(pSample2); |
| if ( hr == S_OK ) |
| return NOERROR; |
| } |
| #endif |
| |
| hr = S_OK; |
| |
| if ( SUCCEEDED(hr) ) |
| hr = IMediaSample_SetSyncPoint(pSample, |
| (prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE); |
| if ( SUCCEEDED(hr) ) |
| hr = IMediaSample_SetPreroll(pSample, |
| (prop.dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE); |
| if ( SUCCEEDED(hr) ) |
| hr = IMediaSample_SetDiscontinuity(pSample, |
| (prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE); |
| if ( SUCCEEDED(hr) ) |
| { |
| TRACE("length = %ld/%ld\n",prop.lActual,pProp->cbBuffer); |
| hr = IMediaSample_SetActualDataLength(pSample,prop.lActual); |
| } |
| if ( SUCCEEDED(hr) ) |
| { |
| if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) && |
| ( prop.dwSampleFlags & AM_SAMPLE_STOPVALID) ) |
| hr = IMediaSample_SetTime(pSample,&prop.tStart,&prop.tStop); |
| else |
| hr = IMediaSample_SetTime(pSample,NULL,NULL); |
| } |
| if ( SUCCEEDED(hr) ) |
| hr = IMediaSample_SetMediaType(pSample, |
| (prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ? |
| prop.pMediaType : NULL); |
| |
| return hr; |
| } |
| |
| HRESULT QUARTZ_IMediaSample_Copy( |
| IMediaSample* pDstSample, |
| IMediaSample* pSrcSample, |
| BOOL bCopyData ) |
| { |
| HRESULT hr; |
| AM_SAMPLE2_PROPERTIES prop; |
| BYTE* pDataSrc = NULL; |
| BYTE* pDataDst = NULL; |
| |
| hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop ); |
| if ( FAILED(hr) ) |
| return hr; |
| if ( !bCopyData ) |
| prop.lActual = 0; |
| hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop ); |
| if ( prop.pMediaType != NULL ) |
| QUARTZ_MediaType_Destroy( prop.pMediaType ); |
| |
| if ( SUCCEEDED(hr) && bCopyData ) |
| { |
| hr = IMediaSample_GetPointer(pSrcSample,&pDataSrc); |
| if ( SUCCEEDED(hr) ) |
| hr = IMediaSample_GetPointer(pDstSample,&pDataDst); |
| if ( SUCCEEDED(hr) ) |
| { |
| if ( pDataSrc != NULL && pDataDst != NULL ) |
| memcpy( pDataDst, pDataSrc, prop.lActual ); |
| else |
| hr = E_FAIL; |
| } |
| } |
| |
| return hr; |
| } |
| |
| /*************************************************************************** |
| * |
| * CMemMediaSample::IMediaSample2 |
| * |
| */ |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); |
| |
| if ( ppobj == NULL ) |
| return E_POINTER; |
| |
| if ( IsEqualGUID( riid, &IID_IUnknown ) || |
| IsEqualGUID( riid, &IID_IMediaSample ) || |
| IsEqualGUID( riid, &IID_IMediaSample2 ) ) |
| { |
| *ppobj = iface; |
| IMediaSample2_AddRef(iface); |
| return NOERROR; |
| } |
| |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI |
| IMediaSample2_fnAddRef(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return InterlockedExchangeAdd(&(This->ref),1) + 1; |
| } |
| |
| static ULONG WINAPI |
| IMediaSample2_fnRelease(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| LONG ref; |
| |
| TRACE("(%p)->()\n",This); |
| |
| if ( This->ref == 0 ) |
| { |
| ERR("(%p) - released sample!\n",This); |
| return 0; |
| } |
| |
| ref = InterlockedExchangeAdd(&(This->ref),-1) - 1; |
| if ( ref > 0 ) |
| return (ULONG)ref; |
| |
| /* this class would be reused.. */ |
| if ( This->prop.pMediaType != NULL ) |
| { |
| QUARTZ_MediaType_Destroy( This->prop.pMediaType ); |
| This->prop.pMediaType = NULL; |
| } |
| This->prop.dwTypeSpecificFlags = 0; |
| This->prop.dwSampleFlags = 0; |
| This->prop.lActual = This->prop.cbBuffer; |
| |
| IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface); |
| |
| return 0; |
| } |
| |
| |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| if ( This->ref == 0 ) |
| { |
| ERR("(%p) - released sample!\n",This); |
| return E_UNEXPECTED; |
| } |
| |
| if ( ppData == NULL ) |
| return E_POINTER; |
| |
| *ppData = This->prop.pbBuffer; |
| return NOERROR; |
| } |
| |
| static long WINAPI |
| IMediaSample2_fnGetSize(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return This->prop.cbBuffer; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd); |
| |
| if ( This->ref == 0 ) |
| { |
| ERR("(%p) - released sample!\n",This); |
| return E_UNEXPECTED; |
| } |
| |
| if ( prtStart == NULL || prtEnd == NULL ) |
| return E_POINTER; |
| |
| if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) && |
| ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) ) |
| { |
| *prtStart = This->prop.tStart; |
| *prtEnd = This->prop.tStop; |
| return NOERROR; |
| } |
| |
| return VFW_E_MEDIA_TIME_NOT_SET; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd); |
| |
| This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID); |
| if ( prtStart != NULL ) |
| { |
| This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID; |
| This->prop.tStart = *prtStart; |
| } |
| if ( prtEnd != NULL ) |
| { |
| This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID; |
| This->prop.tStop = *prtEnd; |
| } |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnIsSyncPoint(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ? |
| S_OK : S_FALSE; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%d)\n",This,bSync); |
| |
| if ( bSync ) |
| This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; |
| else |
| This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT; |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnIsPreroll(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ? |
| S_OK : S_FALSE; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%d)\n",This,bPreroll); |
| |
| if ( bPreroll ) |
| This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL; |
| else |
| This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL; |
| |
| return NOERROR; |
| } |
| |
| static long WINAPI |
| IMediaSample2_fnGetActualDataLength(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return This->prop.lActual; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%ld)\n",This,lLength); |
| |
| if ( This->prop.cbBuffer < lLength ) |
| return E_INVALIDARG; |
| |
| This->prop.lActual = lLength; |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%p)\n",This,ppmt); |
| |
| if ( ppmt == NULL ) |
| return E_POINTER; |
| *ppmt = NULL; |
| if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ) |
| return S_FALSE; |
| |
| *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType ); |
| if ( *ppmt == NULL ) |
| return E_OUTOFMEMORY; |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| AM_MEDIA_TYPE* pmtDup; |
| |
| TRACE("(%p)->(%p)\n",This,pmt); |
| |
| if ( pmt == NULL ) |
| { |
| /* FIXME? */ |
| if ( This->prop.pMediaType != NULL ) |
| { |
| QUARTZ_MediaType_Destroy( This->prop.pMediaType ); |
| This->prop.pMediaType = NULL; |
| } |
| This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED; |
| return NOERROR; |
| } |
| |
| pmtDup = QUARTZ_MediaType_Duplicate( pmt ); |
| if ( pmtDup == NULL ) |
| return E_OUTOFMEMORY; |
| |
| if ( This->prop.pMediaType != NULL ) |
| QUARTZ_MediaType_Destroy( This->prop.pMediaType ); |
| This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED; |
| This->prop.pMediaType = pmtDup; |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ? |
| S_OK : S_FALSE; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%d)\n",This,bDiscontinuity); |
| |
| if ( bDiscontinuity ) |
| This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; |
| else |
| This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY; |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd); |
| |
| if ( pTimeStart == NULL || pTimeEnd == NULL ) |
| return E_POINTER; |
| |
| if ( !This->fMediaTimeIsValid ) |
| return VFW_E_MEDIA_TIME_NOT_SET; |
| |
| *pTimeStart = This->llMediaTimeStart; |
| *pTimeEnd = This->llMediaTimeEnd; |
| |
| return NOERROR; |
| |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->()\n",This); |
| if ( pTimeStart == NULL || pTimeEnd == NULL ) |
| { |
| This->fMediaTimeIsValid = FALSE; |
| } |
| else |
| { |
| This->fMediaTimeIsValid = TRUE; |
| This->llMediaTimeStart = *pTimeStart; |
| This->llMediaTimeEnd = *pTimeEnd; |
| } |
| |
| return NOERROR; |
| } |
| |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| |
| TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp); |
| |
| if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) ) |
| return E_FAIL; |
| memcpy( pbProp, &This->prop, cbProp ); |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp) |
| { |
| ICOM_THIS(CMemMediaSample,iface); |
| const AM_SAMPLE2_PROPERTIES* pProp; |
| AM_SAMPLE2_PROPERTIES propNew; |
| AM_MEDIA_TYPE* pmtDup = NULL; |
| HRESULT hr = E_INVALIDARG; |
| |
| TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp); |
| |
| if ( pbProp == NULL ) |
| return E_POINTER; |
| pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp; |
| if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) ) |
| goto err; |
| |
| CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) ); |
| if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) ) |
| goto err; |
| |
| if ( This->prop.cbBuffer < propNew.lActual ) |
| goto err; |
| |
| if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED ) |
| { |
| pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType ); |
| if ( pmtDup == NULL ) |
| { |
| hr = E_OUTOFMEMORY; |
| goto err; |
| } |
| } |
| |
| if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer ) |
| goto err; |
| if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer ) |
| goto err; |
| |
| if ( This->prop.pMediaType != NULL ) |
| QUARTZ_MediaType_Destroy( This->prop.pMediaType ); |
| CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) ); |
| This->prop.pMediaType = pmtDup; |
| pmtDup = NULL; |
| |
| hr= NOERROR; |
| err: |
| if ( pmtDup != NULL ) |
| QUARTZ_MediaType_Destroy( pmtDup ); |
| |
| return hr; |
| } |
| |
| |
| static ICOM_VTABLE(IMediaSample2) imediasample2 = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| /* IUnknown fields */ |
| IMediaSample2_fnQueryInterface, |
| IMediaSample2_fnAddRef, |
| IMediaSample2_fnRelease, |
| /* IMediaSample fields */ |
| IMediaSample2_fnGetPointer, |
| IMediaSample2_fnGetSize, |
| IMediaSample2_fnGetTime, |
| IMediaSample2_fnSetTime, |
| IMediaSample2_fnIsSyncPoint, |
| IMediaSample2_fnSetSyncPoint, |
| IMediaSample2_fnIsPreroll, |
| IMediaSample2_fnSetPreroll, |
| IMediaSample2_fnGetActualDataLength, |
| IMediaSample2_fnSetActualDataLength, |
| IMediaSample2_fnGetMediaType, |
| IMediaSample2_fnSetMediaType, |
| IMediaSample2_fnIsDiscontinuity, |
| IMediaSample2_fnSetDiscontinuity, |
| IMediaSample2_fnGetMediaTime, |
| IMediaSample2_fnSetMediaTime, |
| /* IMediaSample2 fields */ |
| IMediaSample2_fnGetProperties, |
| IMediaSample2_fnSetProperties, |
| }; |
| |
| |
| /*************************************************************************** |
| * |
| * new/delete for CMemMediaSample |
| * |
| */ |
| |
| HRESULT QUARTZ_CreateMemMediaSample( |
| BYTE* pbData, DWORD dwDataLength, |
| IMemAllocator* pOwner, |
| CMemMediaSample** ppSample ) |
| { |
| CMemMediaSample* pms; |
| |
| TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample); |
| pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) ); |
| if ( pms == NULL ) |
| return E_OUTOFMEMORY; |
| |
| ICOM_VTBL(pms) = &imediasample2; |
| pms->ref = 0; |
| pms->pOwner = pOwner; |
| pms->fMediaTimeIsValid = FALSE; |
| pms->llMediaTimeStart = 0; |
| pms->llMediaTimeEnd = 0; |
| ZeroMemory( &(pms->prop), sizeof(pms->prop) ); |
| pms->prop.cbData = sizeof(pms->prop); |
| pms->prop.dwTypeSpecificFlags = 0; |
| pms->prop.dwSampleFlags = 0; |
| pms->prop.pbBuffer = pbData; |
| pms->prop.cbBuffer = (LONG)dwDataLength; |
| pms->prop.lActual = (LONG)dwDataLength; |
| |
| *ppSample = pms; |
| |
| return S_OK; |
| } |
| |
| void QUARTZ_DestroyMemMediaSample( |
| CMemMediaSample* pSample ) |
| { |
| TRACE("(%p)\n",pSample); |
| |
| QUARTZ_FreeObj( pSample ); |
| } |
| |