⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cxviddecoder.cpp

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut){	BITMAPINFOHEADER * bmih;	DPRINTF("GetMediaType");	if (m_pInput->IsConnected() == FALSE)	{		return E_UNEXPECTED;	}	if (!g_config.videoinfo_compat) {		VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));		if (vih == NULL) return E_OUTOFMEMORY;		ZeroMemory(vih, sizeof (VIDEOINFOHEADER2));		bmih = &(vih->bmiHeader);		mtOut->SetFormatType(&FORMAT_VideoInfo2);		if (ar_x != 0 && ar_y != 0) {			vih->dwPictAspectRatioX = ar_x;			vih->dwPictAspectRatioY = ar_y;			forced_ar = true;		} else { // just to be safe			vih->dwPictAspectRatioX = m_create.width;			vih->dwPictAspectRatioY = abs(m_create.height);			forced_ar = false;		} 	} else {		VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));		if (vih == NULL) return E_OUTOFMEMORY;		ZeroMemory(vih, sizeof (VIDEOINFOHEADER));		bmih = &(vih->bmiHeader);		mtOut->SetFormatType(&FORMAT_VideoInfo);	}	bmih->biSize = sizeof(BITMAPINFOHEADER);	bmih->biWidth	= m_create.width;	bmih->biHeight = m_create.height;	bmih->biPlanes = 1;	if (iPosition < 0) return E_INVALIDARG;	switch(iPosition)	{	case 0:if ( USE_YUY2 ){		bmih->biCompression = MEDIASUBTYPE_YUY2.Data1;		bmih->biBitCount = 16;		mtOut->SetSubtype(&MEDIASUBTYPE_YUY2);		break;}	case 1 :if ( USE_YVYU ){		bmih->biCompression = MEDIASUBTYPE_YVYU.Data1;		bmih->biBitCount = 16;		mtOut->SetSubtype(&MEDIASUBTYPE_YVYU);		break;}	case 2 :if ( USE_UYVY ){		bmih->biCompression = MEDIASUBTYPE_UYVY.Data1;		bmih->biBitCount = 16;		mtOut->SetSubtype(&MEDIASUBTYPE_UYVY);		break;}	case 3	:		if ( USE_IYUV ){		bmih->biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1;		bmih->biBitCount = 12;		mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV);		break;}	case 4	:if ( USE_YV12 ){		bmih->biCompression = MEDIASUBTYPE_YV12.Data1;		bmih->biBitCount = 12;		mtOut->SetSubtype(&MEDIASUBTYPE_YV12);		break;}	case 5 :if ( USE_RGB32 ){		bmih->biCompression = BI_RGB;		bmih->biBitCount = 32;		mtOut->SetSubtype(&MEDIASUBTYPE_RGB32);		break;}	case 6 :if ( USE_RGB24 ){		bmih->biCompression = BI_RGB;		bmih->biBitCount = 24;			mtOut->SetSubtype(&MEDIASUBTYPE_RGB24);		break;}	case 7 :if ( USE_RG555 ){		bmih->biCompression = BI_RGB;		bmih->biBitCount = 16;			mtOut->SetSubtype(&MEDIASUBTYPE_RGB555);		break;}	case 8 :if ( USE_RG565 ){		bmih->biCompression = BI_RGB;		bmih->biBitCount = 16;			mtOut->SetSubtype(&MEDIASUBTYPE_RGB565);		break;}		default :		return VFW_S_NO_MORE_ITEMS;	}	bmih->biSizeImage = GetBitmapSize(bmih);	mtOut->SetType(&MEDIATYPE_Video);	mtOut->SetTemporalCompression(FALSE);	mtOut->SetSampleSize(bmih->biSizeImage);	return S_OK;}/* (internal function) change colorspace */#define CALC_BI_STRIDE(width,bitcount)  ((((width * bitcount) + 31) & ~31) >> 3)HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format){	DWORD biWidth;	if (formattype == FORMAT_VideoInfo)	{		VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format;		biWidth = vih->bmiHeader.biWidth;		m_frame.output.stride[0] = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount);		rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);	}	else if (formattype == FORMAT_VideoInfo2)	{		VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format;		biWidth = vih2->bmiHeader.biWidth;		m_frame.output.stride[0] = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount);		rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP);	}	else	{		return S_FALSE;	}	if (subtype == CLSID_MEDIASUBTYPE_IYUV)	{		DPRINTF("IYUV");		rgb_flip = 0;		m_frame.output.csp = XVID_CSP_I420;		m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8);	/* planar format fix */	}	else if (subtype == MEDIASUBTYPE_YV12)	{		DPRINTF("YV12");		rgb_flip = 0;		m_frame.output.csp = XVID_CSP_YV12;		m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8);	/* planar format fix */	}	else if (subtype == MEDIASUBTYPE_YUY2)	{		DPRINTF("YUY2");		rgb_flip = 0;		m_frame.output.csp = XVID_CSP_YUY2;	}	else if (subtype == MEDIASUBTYPE_YVYU)	{		DPRINTF("YVYU");		rgb_flip = 0;		m_frame.output.csp = XVID_CSP_YVYU;	}	else if (subtype == MEDIASUBTYPE_UYVY)	{		DPRINTF("UYVY");		rgb_flip = 0;		m_frame.output.csp = XVID_CSP_UYVY;	}	else if (subtype == MEDIASUBTYPE_RGB32)	{		DPRINTF("RGB32");		m_frame.output.csp = rgb_flip | XVID_CSP_BGRA;	}	else if (subtype == MEDIASUBTYPE_RGB24)	{		DPRINTF("RGB24");		m_frame.output.csp = rgb_flip | XVID_CSP_BGR;	}	else if (subtype == MEDIASUBTYPE_RGB555)	{		DPRINTF("RGB555");		m_frame.output.csp = rgb_flip | XVID_CSP_RGB555;	}	else if (subtype == MEDIASUBTYPE_RGB565)	{		DPRINTF("RGB565");		m_frame.output.csp = rgb_flip | XVID_CSP_RGB565;	}	else if (subtype == GUID_NULL)	{		m_frame.output.csp = XVID_CSP_NULL;	}	else	{		return S_FALSE;	}	return S_OK;}/* set output colorspace */HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt){	DPRINTF("SetMediaType");		if (direction == PINDIR_OUTPUT)	{		return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format());	}		return S_OK;}/* check input<->output compatiblity */HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut){	DPRINTF("CheckTransform");	return S_OK;}/* alloc output buffer */HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest){	DPRINTF("DecideBufferSize");	HRESULT result;	ALLOCATOR_PROPERTIES ppropActual;	if (m_pInput->IsConnected() == FALSE)	{		return E_UNEXPECTED;	}	ppropInputRequest->cBuffers = 1;	ppropInputRequest->cbBuffer = m_create.width * m_create.height * 4;	// cbAlign causes problems with the resize filter */	// ppropInputRequest->cbAlign = 16;		ppropInputRequest->cbPrefix = 0;			result = pAlloc->SetProperties(ppropInputRequest, &ppropActual);	if (result != S_OK)	{		return result;	}	if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer)	{		return E_FAIL;	}	return S_OK;}/* decode frame */HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut){	DPRINTF("Transform");	xvid_dec_stats_t stats;    int length;	memset(&stats, 0, sizeof(stats));	stats.version = XVID_VERSION;	if (m_create.handle == NULL)	{		if (xvid_decore_func == NULL)			return E_FAIL;		if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)		{            DPRINTF("*** XVID_DEC_CREATE error");			return S_FALSE;		}	}	AM_MEDIA_TYPE * mtOut;	pOut->GetMediaType(&mtOut);	if (mtOut != NULL)	{		HRESULT result;		result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);		DeleteMediaType(mtOut);		if (result != S_OK)		{            DPRINTF("*** ChangeColorspace error");			return result;		}	}		m_frame.length = pIn->GetActualDataLength();	if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)	{		return S_FALSE;	}	if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)	{		return S_FALSE; 	}	m_frame.general = XVID_LOWDELAY;	if (pIn->IsDiscontinuity() == S_OK)		m_frame.general |= XVID_DISCONTINUITY;	if (g_config.nDeblock_Y)		m_frame.general |= XVID_DEBLOCKY;	if (g_config.nDeblock_UV)		m_frame.general |= XVID_DEBLOCKUV;	if (g_config.nDering_Y)		m_frame.general |= XVID_DERINGY;	if (g_config.nDering_UV)		m_frame.general |= XVID_DERINGUV;	if (g_config.nFilmEffect)		m_frame.general |= XVID_FILMEFFECT;	m_frame.brightness = g_config.nBrightness;	m_frame.output.csp &= ~XVID_CSP_VFLIP;	m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);    // Paranoid check.    if (xvid_decore_func == NULL)		return E_FAIL;repeat :	if (pIn->IsPreroll() != S_OK)	{		length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);		if (length < 0)		{            DPRINTF("*** XVID_DEC_DECODE");			return S_FALSE;		} else 			if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) {              if (stats.type != XVID_TYPE_NOTHING) {  /* dont attempt to set vmr aspect ratio if no frame was returned by decoder */			// inspired by minolta! works for VMR 7 + 9			IMediaSample2 *pOut2 = NULL;			AM_SAMPLE2_PROPERTIES outProp2;			if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) &&				SUCCEEDED(pOut2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&outProp2)))			{				CMediaType mtOut2 = m_pOutput->CurrentMediaType();				VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format();				if (*mtOut2.FormatType() == FORMAT_VideoInfo2 && 					vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y)				{					vihOut2->dwPictAspectRatioX = ar_x;					vihOut2->dwPictAspectRatioY = ar_y;					pOut2->SetMediaType(&mtOut2);					m_pOutput->SetMediaType(&mtOut2);				}				pOut2->Release();			}      }		}	}	else	{	/* Preroll frame - won't be displayed */		int tmp = m_frame.output.csp;		int tmp_gen = m_frame.general;		m_frame.output.csp = XVID_CSP_NULL;		/* Disable postprocessing to speed-up seeking */		m_frame.general &= ~XVID_DEBLOCKY;		m_frame.general &= ~XVID_DEBLOCKUV;		/*m_frame.general &= ~XVID_DERING;*/		m_frame.general &= ~XVID_FILMEFFECT;		length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);		if (length < 0)		{            DPRINTF("*** XVID_DEC_DECODE");			return S_FALSE;		}		m_frame.output.csp = tmp;		m_frame.general = tmp_gen;	}	if (stats.type == XVID_TYPE_NOTHING && length > 0) {		DPRINTF(" B-Frame decoder lag");		return S_FALSE;	}	if (stats.type == XVID_TYPE_VOL)	{		if (stats.data.vol.width != m_create.width ||			stats.data.vol.height != m_create.height)		{			DPRINTF("TODO: auto-resize");			return S_FALSE;		}		pOut->SetSyncPoint(TRUE);		if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */			int par_x, par_y;			if (stats.data.vol.par == XVID_PAR_EXT) {				par_x = stats.data.vol.par_width;				par_y = stats.data.vol.par_height;			} else {				par_x = PARS[stats.data.vol.par-1][0];				par_y = PARS[stats.data.vol.par-1][1];			}			ar_x = par_x * stats.data.vol.width;			ar_y = par_y * stats.data.vol.height;		}		m_frame.bitstream = (BYTE*)m_frame.bitstream + length;		m_frame.length -= length;		goto repeat;	}	if (pIn->IsPreroll() == S_OK) {		return S_FALSE;	}	return S_OK;}/* get property page list */STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages){	DPRINTF("GetPages");	pPages->cElems = 1;	pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID));	if (pPages->pElems == NULL)	{		return E_OUTOFMEMORY;	}	pPages->pElems[0] = CLSID_CABOUT;	return S_OK;}/* cleanup pages */STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages){	DPRINTF("FreePages");	CoTaskMemFree(pPages->pElems);	return S_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -