📄 cmediasample.c
字号:
/* * Modified for use with MPlayer, detailed changelog at * http://svn.mplayerhq.hu/mplayer/trunk/ */#include "cmediasample.h"#include "mediatype.h"#include "wine/winerror.h"#include <stdio.h>#include <string.h>#include <stdlib.h>/* * currently hack to make some extra room for DS Acel codec which * seems to overwrite allocated memory - FIXME better later * check the buffer allocation */static const int SAFETY_ACEL = 1024;#ifdef USE_SHARED_MEM#include <pthread.h>static pthread_mutex_t mem_mutex = PTHREAD_MUTEX_INITIALIZER;struct { unsigned int pagecount; unsigned int pagesize; void *base; void *end; void *used[32]; unsigned char locked[32];} memstruct;void set_memstruct(void *base, int count, int size){ memstruct.base = base; memstruct.end = (char *)base + size * count; memstruct.pagesize = size; memstruct.pagecount = count; memset(memstruct.used, 0, sizeof(memstruct.used)); memset(memstruct.locked, 0, sizeof(memstruct.locked));}int get_memstruct_pagenum(void * __ptr){ int i; if(__ptr < memstruct.base || __ptr > memstruct.end) return -1; pthread_mutex_lock(&mem_mutex); for(i=0; i < memstruct.pagecount; i++) if(__ptr < memstruct.used[i]) break; pthread_mutex_unlock(&mem_mutex); return i;}static void *MALLOC (size_t __size){ int i; void *__ptr; pthread_mutex_lock(&mem_mutex); for(i=0; i < memstruct.pagecount; i++) if(memstruct.used[i] == NULL && ! memstruct.locked[i]) break; if(i >= memstruct.pagecount || __size > memstruct.pagesize) { __ptr = malloc(__size); } else { __ptr = (BYTE *)memstruct.base+memstruct.pagesize*i; memstruct.used[i] = (BYTE *)__ptr + memstruct.pagesize; } pthread_mutex_unlock(&mem_mutex); return __ptr;}static void *REALLOC (void *__ptr, size_t __size){ int i; if(__ptr < memstruct.base || __ptr > memstruct.end) return realloc(__ptr, __size); pthread_mutex_lock(&mem_mutex); for(i=0; i < memstruct.pagecount; i++) if(__ptr < memstruct.used[i]) break; if(__size > memstruct.pagesize) { memstruct.used[i] = NULL; __ptr = malloc(__size); } pthread_mutex_unlock(&mem_mutex); return __ptr;}static void FREE(void *__ptr){ int i; if(__ptr < memstruct.base || __ptr > memstruct.end) { free(__ptr); return; } pthread_mutex_lock(&mem_mutex); for(i=0; i < memstruct.pagecount; i++) if(__ptr < memstruct.used[i]) break; memstruct.used[i] = NULL; pthread_mutex_unlock(&mem_mutex);}void memstruct_setlock(void * __ptr, unsigned char value){ int i; if(__ptr < memstruct.base || __ptr > memstruct.end) return; pthread_mutex_lock(&mem_mutex); for(i=0; i < memstruct.pagecount; i++) if(__ptr < memstruct.used[i]) memstruct.locked[i] = value; pthread_mutex_unlock(&mem_mutex);} #else#define MALLOC malloc#define REALLOC realloc#define FREE freevoid memstruct_setlock(void * __ptr, unsigned char value) {}int get_memstruct_pagenum(void * __ptr) { return -1;}void set_memstruct(void *base, int count, int size) {}#endif/** * \brief IPin::QueryInternalConnections (retries pin's internal connections) * * \param[in] This pointer to IPin interface * \param[out] apPin Array that receives pins, internally connected to this * \param[in,out] nPint Size of an array * * \return S_OK - success * \return S_FALSE - pin rejects media type * \return E_NOTIMPL - not implemented * */static long STDCALL CMediaSample_QueryInterface(IUnknown* This, /* [in] */ const GUID* iid, /* [iid_is][out] */ void **ppv){ Debug printf("CMediaSample_QueryInterface(%p) called\n", This); if (!ppv) return E_INVALIDARG; if (memcmp(iid, &IID_IUnknown, sizeof(*iid)) == 0) { *ppv = (void*)This; ((IMediaSample*) This)->vt->AddRef(This); return 0; } if (memcmp(iid, &IID_IMediaSample, sizeof(*iid)) == 0) { *ppv = (void*)This; ((IMediaSample*) This)->vt->AddRef(This); return 0; } return E_NOINTERFACE;}/** * \brief IUnknown::AddRef (increases reference counter for interface) * * \param[in] This pointer to IUnknown class * * \return new value of reference counter * * \remarks * Return value should be used only for debug purposes * */static long STDCALL CMediaSample_AddRef(IUnknown* This){ Debug printf("CMediaSample_AddRef(%p) called\n", This); ((CMediaSample*)This)->refcount++; return 0;}/** * \brief CMediaSample destructor * * \param[in] This pointer to CMediaSample object * */void CMediaSample_Destroy(CMediaSample* This){ Debug printf("CMediaSample_Destroy(%p) called (ref:%d)\n", This, This->refcount); free(This->vt); FREE(This->own_block); if(((CMediaSample*)This)->type_valid) FreeMediaType(&(This->media_type)); free(This);}/** * \brief IUnknown::Release (desreases reference counter for interface) * * \param[in] This pointer to IUnknown class * * \return new value of reference counter * * \remarks * When reference counter reaches zero calls destructor * Return value should be used only for debug purposes * */static long STDCALL CMediaSample_Release(IUnknown* This){ CMediaSample* parent = (CMediaSample*)This; Debug printf("CMediaSample_Release(%p) called (new ref:%d)\n", This, ((CMediaSample*)This)->refcount-1); if (--((CMediaSample*) This)->refcount == 0) { parent->all->vt->ReleaseBuffer((IMemAllocator*)(parent->all), (IMediaSample*)This); } return 0;}/** * \brief IMediaSample::GetPointer (retrieves a read/write pointer to the media sample's buffer) * * \param[in] This pointer to CMediaSample object * \param[out] address of variable that receives pointer to sample's buffer * * \return S_OK success * \return apropriate error otherwise * * \note The calles should not free or reallocate buffer * */static HRESULT STDCALL CMediaSample_GetPointer(IMediaSample* This, /* [out] */ BYTE** ppBuffer){ Debug printf("CMediaSample_GetPointer(%p) called -> %p, size: %d %d\n", This, ((CMediaSample*) This)->block, ((CMediaSample*)This)->actual_size, ((CMediaSample*)This)->size); if (!ppBuffer) return E_INVALIDARG; *ppBuffer = (BYTE*) ((CMediaSample*) This)->block; return 0;}/** * \brief IMediaSample::GetSize (retrieves a size of buffer in bytes) * * \param[in] This pointer to CMediaSample object * * \return size of buffer in bytes * */static long STDCALL CMediaSample_GetSize(IMediaSample * This){ Debug printf("CMediaSample_GetSize(%p) called -> %d\n", This, ((CMediaSample*) This)->size); return ((CMediaSample*) This)->size;}/** * \brief IMediaSample::GetTime (retrieves a stream time at wich sample sould start and finish) * * \param[in] This pointer to CMediaSample object * \param[out] pTimeStart pointer to variable that receives start time * \param[out] pTimeEnd pointer to variable that receives end time * * \return S_OK success * \return VFW_E_NO_STOP_TIME The sample has valid start time, but no stop time * \return VFW_E_SAMPLE_TIME_NOT_SET The sample is not time-stamped * * \remarks * Both values are relative to stream time * */static HRESULT STDCALL CMediaSample_GetTime(IMediaSample * This, /* [out] */ REFERENCE_TIME *pTimeStart, /* [out] */ REFERENCE_TIME *pTimeEnd){ //return E_NOTIMPL; if (pTimeStart) *pTimeStart = ((CMediaSample*) This)->time_start; if (pTimeEnd) *pTimeEnd = ((CMediaSample*) This)->time_end; Debug printf("CMediaSample_GetTime(%p) called => (%lld, %lld)\n", This, (pTimeStart ? *pTimeStart : -1), (pTimeEnd ? *pTimeEnd : -1)); return 0;}/** * \brief IMediaSample::SetTime (sets a stream time at wich sample sould start and finish) * * \param[in] This pointer to CMediaSample object * \param[out] pTimeStart pointer to variable that contains start time * \param[out] pTimeEnd pointer to variable that contains end time * * \return S_OK success * \return apropriate error otherwise * * \remarks * Both values are relative to stream time * To invalidate the stream times set pTimeStart and pTimeEnd to NULL. this will cause * IMEdiaSample::GetTime to return VFW_E_SAMPLE_TIME_NOT_SET * */static HRESULT STDCALL CMediaSample_SetTime(IMediaSample * This, /* [in] */ REFERENCE_TIME *pTimeStart, /* [in] */ REFERENCE_TIME *pTimeEnd){ Debug printf("CMediaSample_SetTime(%p, %lld, %lld) called\n", This, (pTimeStart ? *pTimeStart : -1), (pTimeEnd ? *pTimeEnd : -1)); //return E_NOTIMPL; if (pTimeStart) ((CMediaSample*) This)->time_start = *pTimeStart; if (pTimeEnd) ((CMediaSample*) This)->time_end = *pTimeEnd; return 0;}/** * \brief IMediaSample::IsSyncPoint (determines if start of this sample is sync point) * * \param[in] This pointer to CMediaSample object * * \return S_OK start of this sample is sync point * \return S_FALSE start of this sample is not sync point * * \remarks * If bTemporalCompression of AM_MEDIA_TYPE is FALSE, all samples are sync points. * */static HRESULT STDCALL CMediaSample_IsSyncPoint(IMediaSample * This){ Debug printf("CMediaSample_IsSyncPoint(%p) called ==> %d\n", This, ((CMediaSample*)This)->isSyncPoint); if (((CMediaSample*)This)->isSyncPoint) return 0; return 1;}/** * \brief IMediaSample::SetSyncPoint (specifies if start of this sample is sync point) * * \param[in] This pointer to CMediaSample object * \param[in] bIsSyncPoint specifies whether this is sync point or not * * \return S_OK success * \return apropriate error code otherwise * */static HRESULT STDCALL CMediaSample_SetSyncPoint(IMediaSample * This, long bIsSyncPoint){ Debug printf("CMediaSample_SetSyncPoint(%p) called\n", This);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -