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

📄 videodecodervfw.cpp

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 CPP
字号:

#include "VideoDecoderVFW.h"




MediaVideoDecoderVFW::MediaVideoDecoderVFW()
{
	this->hic    = NULL;
	this->decaps = NULL;

	this->invertFlag = 1;

	this->inputBuffer = new MediaBuffer();
}

MediaVideoDecoderVFW::~MediaVideoDecoderVFW()
{
	delete this->inputBuffer;
}



media_type_t  MediaVideoDecoderVFW::GetType()
{
	return MEDIA_TYPE_VIDEO_DECODER;
}

char *MediaVideoDecoderVFW::GetName()
{
	if(this->hic) {

		ICINFO icInfo;
		char *name;
		int i;
			
		ICGetInfo(this->hic, &icInfo, sizeof(ICINFO));

		name = (char *) new char[128];

		for(i=0; i < 128; i++) { 
			name[i] = icInfo.szDescription[i] & 255;
		}
	
		return name;
	}
	
	return "Video For Windows Decoder";
}

MP_RESULT     MediaVideoDecoderVFW::Connect(MediaItem *item)
{
	HRESULT h;

	if(item != NULL && item->GetType() == MEDIA_TYPE_DECAPS) {

		this->decaps = (MediaItemDecaps *) item;



		if(this->decaps->GetVideoHeader(0) == NULL)
			return MP_RESULT_ERROR;

		memcpy(&this->in_bih.bmiHeader, this->decaps->GetVideoHeader(0), sizeof(BITMAPINFOHEADER));

		this->hic = ICOpen(mmioFOURCC('V', 'I', 'D', 'C'), 
							          this->in_bih.bmiHeader.biCompression,
							          ICMODE_FASTDECOMPRESS);

		if(this->hic != 0) {

			ZeroMemory(&this->out_bih, sizeof(BITMAPINFO));

			this->out_bih.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
			this->out_bih.bmiHeader.biBitCount = 24;

			h = ICDecompressGetFormat( this->hic, &this->in_bih, &this->out_bih ); 

			if(h == ICERR_OK) {

				h = ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih);
			    
				this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;

				h = ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);  
			
				this->invertFlag = 1;

				if(this->in_bih.bmiHeader.biCompression == mmioFOURCC('D', 'I', 'V', '3') ||	
					this->in_bih.bmiHeader.biCompression == mmioFOURCC('D', 'I', 'V', '4')) {

					this->videoMode  = VIDEO_MODE_YUY2;
				}
				else {

					this->videoMode  = VIDEO_MODE_RGB24;
				}

				if(h != ICERR_OK) {
					
					this->hic    = 0;
					this->decaps = NULL;

					return MP_RESULT_ERROR;
				}

				this->inputBuffer->Alloc(VFW_INPUT_SIZE);

				return MP_RESULT_OK;
			}
		}
		
	}

	this->decaps = NULL;

	return MP_RESULT_ERROR;
}

MP_RESULT     MediaVideoDecoderVFW::ReleaseConnections()
{
	if(this->hic) {

		ICDecompressEnd(this->hic);
		ICClose(this->hic);

		this->inputBuffer->Free();
	}

	return MP_RESULT_OK;
}

DWORD         MediaVideoDecoderVFW::GetCaps()
{
	return 0;
}

MP_RESULT     MediaVideoDecoderVFW::Configure(HINSTANCE hInstance, HWND hwnd)
{
	return MP_RESULT_OK;
}



unsigned int       MediaVideoDecoderVFW::GetFrameSize()
{
	if(this->hic) {

		return this->out_bih.bmiHeader.biSizeImage;
	}

	return 0;
}

media_video_mode_t MediaVideoDecoderVFW::GetVideoMode()
{
	return this->videoMode;
}

MP_RESULT          MediaVideoDecoderVFW::SetQuality(DWORD quality)
{
	return MP_RESULT_OK;
}

DWORD          MediaVideoDecoderVFW::GetQuality()
{
	return 0;
}

BOOL			   MediaVideoDecoderVFW::GetInvertFlag()
{
	return this->invertFlag;
}

MP_RESULT          MediaVideoDecoderVFW::SetVideoMode(media_video_mode_t mode)
{
	if(this->hic) {
		
		switch(mode) {

		case VIDEO_MODE_YUY2:

			memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));

			this->out_bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

			this->out_bih.bmiHeader.biCompression = mmioFOURCC('Y', 'U', 'Y', '2');
			this->out_bih.bmiHeader.biBitCount    = 16;
				
			ICDecompressEnd(this->hic);



			ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih);

			this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;

			this->videoMode  = VIDEO_MODE_YUY2;
			this->invertFlag = 1;

			this->out_bih.bmiHeader.biCompression = 0;
			ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
			this->out_bih.bmiHeader.biCompression = mmioFOURCC('Y', 'U', 'Y', '2');

			return MP_RESULT_OK;

			break;


		case VIDEO_MODE_RGB16:

			memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));

			this->out_bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) + 12;

			this->out_bih.bmiHeader.biCompression = BI_BITFIELDS;
			this->out_bih.bmiHeader.biBitCount    = 16;

			((DWORD *) this->out_bih.bmiColors)[0] = (DWORD) 0xF800;
			((DWORD *) this->out_bih.bmiColors)[1] = (DWORD) 0x07E0;
			((DWORD *) this->out_bih.bmiColors)[2] = (DWORD) 0x001F;
				
			ICDecompressEnd(this->hic);

			if(ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih) == ICERR_OK) {

				this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;

				this->invertFlag = 1;
				this->videoMode  = VIDEO_MODE_RGB16;

				ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
				return MP_RESULT_OK;
			}
			break;

		case VIDEO_MODE_RGB24:
			
			memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));
			
			this->out_bih.bmiHeader.biCompression = BI_RGB;
			this->out_bih.bmiHeader.biBitCount    = 24;


			ICDecompressEnd(this->hic);
			
			if(ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih) == ICERR_OK) {

				this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;

				this->videoMode = VIDEO_MODE_RGB24;
				this->invertFlag = 1;

				ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
				return MP_RESULT_OK;
			}
			break;

		case VIDEO_MODE_RGB32:

			memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));

			this->out_bih.bmiHeader.biCompression = BI_RGB;
			this->out_bih.bmiHeader.biBitCount    = 32;

			ICDecompressEnd(this->hic);

			if(ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih) == ICERR_OK) {

				this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;

				this->videoMode = VIDEO_MODE_RGB32;
				this->invertFlag = 1;

				ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
				return MP_RESULT_OK;
			}
			break;

		default:
			return MP_RESULT_ERROR;
		}
	}		

	return MP_RESULT_ERROR;
}

MP_RESULT          MediaVideoDecoderVFW::Decompress(MediaBuffer *mb_out, unsigned int stride)
{
	unsigned int size;
	HRESULT h;

	if(this->decaps && mb_out && this->hic) {

		size = this->decaps->GetNextVideoFrameSize(0);
	
		if(size > this->inputBuffer->GetSize())
			this->inputBuffer->ReAlloc(size);

		if(this->decaps->ReadVideoFrame(0, this->inputBuffer) != MP_RESULT_OK) {

			return MP_RESULT_ERROR;
		}

		this->in_bih.bmiHeader.biSizeImage = size;

		if(size == 0) {
		
			return MP_RESULT_OK;
		}
		else {

			h = ICDecompress(this->hic, ICDECOMPRESS_NOTKEYFRAME,
							 &this->in_bih.bmiHeader, this->inputBuffer->GetData(),
							 &this->out_bih.bmiHeader, mb_out->GetData());

			return MP_RESULT_OK;
		}

	}	
	
	return MP_RESULT_ERROR;
}

MP_RESULT          MediaVideoDecoderVFW::Drop(MediaBuffer *mb_out, unsigned int stride)
{
	unsigned int size;
	HRESULT h;

	if(this->decaps && mb_out && this->hic) {

		size = this->decaps->GetNextVideoFrameSize(0);
	
		if(size > this->inputBuffer->GetSize())
			this->inputBuffer->ReAlloc(size);

		this->decaps->ReadVideoFrame(0, this->inputBuffer);

		this->in_bih.bmiHeader.biSizeImage = size;

		if(size == 0) {
		
			return MP_RESULT_ERROR;
		}
		else {

			h = ICDecompress(this->hic, ICDECOMPRESS_HURRYUP,
							 &this->in_bih.bmiHeader, this->inputBuffer->GetData(),
							 &this->out_bih.bmiHeader, mb_out->GetData());

			return MP_RESULT_OK;
		}

	}	
	
	return MP_RESULT_ERROR;
}

⌨️ 快捷键说明

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