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

📄 videobuffer.cpp

📁 <VC++视频音频开发>一书的光盘资料。
💻 CPP
字号:
/**************************************************************************************
 *                                                                                    *
 *                                                                                    *
 **************************************************************************************/

#include "VideoBuffer.h"

/* 
 *
 * 只执行一次
 *
 */

MediaVideoBuffer::MediaVideoBuffer()
{
	DWORD i;

	for(i=0; i < 1; i++) {
	
		this->buffer[i] = new MediaBuffer();
	}

	this->bufferedFrames = 0;


	this->enabled = FALSE;

	this->decoder        = NULL;
	this->bufferingMutex = CreateMutex(NULL, FALSE, NULL);
}

MediaVideoBuffer::~MediaVideoBuffer()
{
	DWORD i;

	for(i=0; i < 1; i++) {
	
		delete this->buffer[i];
	}

	CloseHandle(this->bufferingMutex);
}

/*
 * 媒体项方法
 */

media_type_t MediaVideoBuffer::GetType()
{
	return MEDIA_TYPE_VIDEO_BUFFER;
}

char *MediaVideoBuffer::GetName()
{
	return "Default Video Buffer";
}

MP_RESULT MediaVideoBuffer::Connect(MediaItem *item)
{
	DWORD i;

	/*
	 * 接受任何视频解码器
	 *
	 */

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

		this->decoder = (MediaItemVideoDecoder *) item;

		if(this->decoder->GetFrameSize() != 0) {
	
			for(i=0; i < 1; i++) {

				if(this->buffer[i] == NULL) {

					this->buffer[i] = new MediaBuffer();
				}
				
				this->buffer[i]->Alloc(this->decoder->GetFrameSize());
			}
		
			this->bufferedFrames = 0;
			this->endReachedAt   = VIDEO_BUFFER_END_NOT_REACHED;

			this->bufferingThread = NULL;

			return MP_RESULT_OK;
		}
	}

	this->decoder = NULL;

	return MP_RESULT_ERROR;
}

MP_RESULT MediaVideoBuffer::ReleaseConnections()
{
	DWORD i;

	if(this->decoder) {

		for(i=0; i < 1; i++) {

			this->buffer[i]->Free();
		}

		this->decoder = NULL;
	}

	return MP_RESULT_OK;
}

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

MP_RESULT     MediaVideoBuffer::Configure(HINSTANCE hInstance, HWND hwnd)
{
	return MP_RESULT_ERROR;
}

/**************************************************************
 *                                                            *
 *                       视频缓冲线程                         *
 *                  ----------------------                    *
 *                                                            *
 **************************************************************/

DWORD WINAPI BufferingThreadFunc( LPVOID lpData)
{
	MediaVideoBuffer *buffer = (MediaVideoBuffer *) lpData;

	while(TRUE) {

		if(buffer->bufferedFrames >= VIDEO_BUFFER_SIZE) {
	
			buffer->suspended = TRUE;
			SuspendThread(buffer->bufferingThread);
		}
		else {

			WaitForSingleObject(buffer->bufferingMutex, INFINITE);

			if(buffer->decoder->Decompress(buffer->buffer[buffer->bufferedFrames], 0) != MP_RESULT_OK) {
			
				buffer->endReachedAt = buffer->bufferedFrames;
		
				ReleaseMutex(buffer->bufferingMutex);
				
				return 0;
			}

			buffer->bufferedFrames++;

			ReleaseMutex(buffer->bufferingMutex);
		}

	}

	return 0;
}

/**************************************************************/

/*
 * 视频缓冲方法
 */

MP_RESULT MediaVideoBuffer::StartBuffering(unsigned int stride)
{
	DWORD i;

	this->stride = stride;

	if(this->enabled) {

		if(this->bufferingThread != NULL)
			return MP_RESULT_ERROR;

		this->bufferedFrames = 0;
		this->suspended      = 0;

		CloseHandle(this->bufferingMutex);
		this->bufferingMutex = CreateMutex(NULL, FALSE, NULL);

		/*
		 * 等待缓冲器直到填充一半
		 */

		for(i=0; i<VIDEO_BUFFER_SIZE; i++) {

			if(this->decoder->Decompress(this->buffer[this->bufferedFrames], 0) != MP_RESULT_OK) {
			
				this->endReachedAt = this->bufferedFrames;
				return MP_RESULT_ERROR;
			}

			this->bufferedFrames++;
		}

		/*
		 * 启动一个线程
		 */

		this->bufferingThread = CreateThread(NULL, 0, BufferingThreadFunc, (LPVOID) this, 0, &this->bufferingThreadId);
		SetThreadPriority(this->bufferingThread, THREAD_PRIORITY_ABOVE_NORMAL);
	}

	return MP_RESULT_ERROR;
}

MP_RESULT MediaVideoBuffer::StopBuffering()
{
	if(this->enabled) {
		
		WaitForSingleObject(this->bufferingMutex, INFINITE);

		TerminateThread(this->bufferingThread, 0);
		this->bufferingThread = NULL;

		ReleaseMutex(this->bufferingMutex);
	
		this->bufferedFrames = 0;
		this->endReachedAt   = VIDEO_BUFFER_END_NOT_REACHED;
	}

	return MP_RESULT_OK;
}

MediaBuffer *MediaVideoBuffer::GetOneFrame()
{
	DWORD i;
	MediaBuffer *temp;

	if(this->enabled) {

		if(this->endReachedAt == 0)
			return NULL;
	
		WaitForSingleObject(this->bufferingMutex, INFINITE);

		if(this->bufferedFrames > 1) {

			if(this->endReachedAt < VIDEO_BUFFER_END_NOT_REACHED) {

				this->endReachedAt--;
			}

			/*
			 * 检查是否结束
			 */

			if(this->endReachedAt == 0) {
		
				ReleaseMutex(this->bufferingMutex);
				return NULL;
			}

			temp = this->buffer[0];
	
			for(i=0; i < VIDEO_BUFFER_SIZE - 1; i++) {
		
				this->buffer[i] = this->buffer[i+1];
			}
		
			this->buffer[VIDEO_BUFFER_SIZE - 1] = temp;
	
			this->bufferedFrames--;

			ReleaseMutex(this->bufferingMutex);

			if(this->suspended && this->endReachedAt == VIDEO_BUFFER_END_NOT_REACHED) {

				this->suspended = FALSE;
				ResumeThread(this->bufferingThread);
			}

			return this->buffer[0];
		}
		else {

			/*
			 * 解压缩
			 */
		
			if(this->decoder->Decompress(this->buffer[this->bufferedFrames], 0) != MP_RESULT_OK) {
			
				this->endReachedAt = 0;
		
				this->suspended = TRUE;
				SuspendThread(this->bufferingThread);
	
				ReleaseMutex(this->bufferingMutex);
				return NULL;
			}

			if(this->bufferedFrames == 1)
				this->bufferedFrames--;

			temp = this->buffer[0];

				for(i=0; i < VIDEO_BUFFER_SIZE - 1; i++) {
	
				this->buffer[i] = this->buffer[i+1];
			}
		
			this->buffer[VIDEO_BUFFER_SIZE - 1] = temp;
	
			ReleaseMutex(this->bufferingMutex);	

			if(this->suspended && this->endReachedAt == VIDEO_BUFFER_END_NOT_REACHED) {
		
				this->suspended = FALSE;
				ResumeThread(this->bufferingThread);
			}

			return temp;
		}
	}
	else {

		if(this->decoder->Decompress(this->buffer[0], this->stride) != MP_RESULT_OK) {
	
			return NULL;
		}

		return this->buffer[0];
	}
}

MediaBuffer  *MediaVideoBuffer::GetLastFrame()
{
	if(this->decoder) {

		return this->buffer[0];
	}

	return NULL;
}


MP_RESULT MediaVideoBuffer::DropOneFrame()
{
	if(this->decoder) {

		WaitForSingleObject(this->bufferingMutex, INFINITE);

		this->decoder->Drop(this->buffer[0], this->stride);
		
		ReleaseMutex(this->bufferingMutex);
	}

	return MP_RESULT_OK;
}

⌨️ 快捷键说明

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