?? videobuffer.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 + -