📄 videorendererrgb.cpp
字号:
/**************************************************************************************
* *
* This application contains code from OpenDivX and is released as a "Larger Work" *
* under that license. Consistant with that license, this application is released *
* under the GNU General Public License. *
* *
* The OpenDivX license can be found at: http://www.projectmayo.com/opendivx/docs.php *
* The GPL can be found at: http://www.gnu.org/copyleft/gpl.html *
* *
* Copyright (c) 2001 - Project Mayo *
* *
* Authors: Damien Chavarria *
* DivX Advanced Research Center <darc at projectmayo.com> *
* *
**************************************************************************************/
#include "VideoRendererRGB.h"
/*
* DirectDraw includes
*
*/
#include <ddraw.h>
/*
* RGB VideoRenderer Class
*/
MediaVideoRendererRGB::MediaVideoRendererRGB()
{
this->subtitler = NULL;
this->lpdd = NULL;
this->lpddClipper = NULL;
this->lpddsPrimary = NULL;
this->lpddsBack = NULL;
this->bpp = 0;
this->videoMode = VIDEO_MODE_NONE;
}
MediaVideoRendererRGB::~MediaVideoRendererRGB()
{
}
/*
* Media Item functions
*/
media_type_t MediaVideoRendererRGB::GetType()
{
return MEDIA_TYPE_VIDEO_RENDERER;
}
char *MediaVideoRendererRGB::GetName()
{
return "Standard RGB Video Renderer";
}
MP_RESULT MediaVideoRendererRGB::Connect(MediaItem *item)
{
/*
* We accept only Subtitlers
*
*/
if(item && item->GetType() == MEDIA_TYPE_SUBTITLER) {
/*
* Accpets the subtitle source
*/
this->subtitler = (MediaItemSubtitler *) item;
return MP_RESULT_OK;
}
return MP_RESULT_ERROR;
}
MP_RESULT MediaVideoRendererRGB::ReleaseConnections()
{
if(this->subtitler)
this->subtitler = NULL;
return MP_RESULT_OK;
}
DWORD MediaVideoRendererRGB::GetCaps()
{
return 0;
}
MP_RESULT MediaVideoRendererRGB::Configure(HINSTANCE hInstance, HWND hwnd)
{
return MP_RESULT_ERROR;
}
/*
* Video Renderer Functions
*/
MP_RESULT MediaVideoRendererRGB::Init(HWND hwnd, unsigned int width, unsigned int height)
{
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
if(hwnd && width > 0 && height > 0) {
/*
* Create the main DirectDraw Object
*/
ddrval = DirectDrawCreateEx(NULL, (void **) &this->lpdd, IID_IDirectDraw7, NULL);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
ddrval = lpdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
if(FAILED(ddrval)) {
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
/*
* Create the primary surface
*/
memset( &ddsd, 0, sizeof(ddsd) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
ddrval = this->lpdd->CreateSurface(&ddsd, &this->lpddsPrimary, NULL);
if(FAILED(ddrval)) {
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
/*
* Now set Clipping
*/
ddrval = this->lpdd->CreateClipper(0, &this->lpddClipper, NULL);
if(FAILED(ddrval)) {
this->lpddsPrimary->Release();
this->lpddsPrimary = NULL;
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
ddrval = this->lpddClipper->SetHWnd(0, hwnd);
if(FAILED(ddrval)) {
this->lpddsPrimary->Release();
this->lpddsPrimary = NULL;
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
ddrval = this->lpddsPrimary->SetClipper(this->lpddClipper);
if(ddrval != DD_OK) {
this->lpddsPrimary->Release();
this->lpddsPrimary = NULL;
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
/*
* Finally Create Back Surface
*/
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
if(this->lpdd->CreateSurface(&ddsd, &this->lpddsBack, NULL) != DD_OK) {
this->lpddsPrimary->Release();
this->lpddsPrimary = NULL;
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
this->width = width;
this->height = height;
this->hwndPlayback = hwnd;
/*
* Now Get the video mode
*/
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddrval = this->lpddsBack->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
this->lpddsBack->Unlock(NULL);
switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
case 8:
return MP_RESULT_ERROR;
break;
case 16:
this->bpp = 2;
this->videoMode = VIDEO_MODE_RGB16;
break;
case 24:
this->bpp = 3;
this->videoMode = VIDEO_MODE_RGB24;
break;
case 32:
this->bpp = 4;
this->videoMode = VIDEO_MODE_RGB32;
break;
}
return MP_RESULT_OK;
}
return MP_RESULT_ERROR;
}
/*
* Init the renderer for
* fullscreen drawing
*
*/
MP_RESULT MediaVideoRendererRGB::InitFullscreen(HWND hwnd, unsigned int width, unsigned int height)
{
if(hwnd && width > 0 && height > 0) {
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
ddrval = DirectDrawCreateEx(NULL, (VOID**)&this->lpdd, IID_IDirectDraw7, NULL);
if( FAILED(ddrval))
return MP_RESULT_ERROR;
/*
* Set Exclusive Cooperative Mode
*/
ddrval = this->lpdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL); //DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if( FAILED(ddrval)) {
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
/*
* Go to fullscreen
*
*/
DDSURFACEDESC2 ddDesc;
memset(&ddDesc, 0, sizeof(DDSURFACEDESC2));
ddDesc.dwSize = sizeof(DDSURFACEDESC2);
/*
* We need to know witch resolution
* we are in...
*/
ddrval = this->lpdd->GetDisplayMode(&ddDesc);
if(FAILED(ddrval)) {
this->lpdd->Release();
this->lpdd=NULL;
return MP_RESULT_ERROR;;
}
/*
* Store the fullscreen mode
*/
this->fullscreenWidth = ddDesc.dwWidth;
this->fullscreenHeight = ddDesc.dwHeight;
this->fullscreenVideoHeight = height * this->fullscreenWidth / width;
/*
* And create the primary surface
*/
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_CAPS;// | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; /*| DDSCAPS_FLIP | DDSCAPS_COMPLEX*/;
//ddsd.dwBackBufferCount = 1;
ddrval = this->lpdd->CreateSurface(&ddsd, &this->lpddsPrimary, NULL );
if(FAILED(ddrval)) {
this->lpdd->Release();
this->lpdd=NULL;
return MP_RESULT_ERROR;;
}
/*
* Get the back buffer
*
*/
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
if(this->lpdd->CreateSurface(&ddsd, &this->lpddsBack, NULL) != DD_OK) {
this->lpddsPrimary->Release();
this->lpddsPrimary = NULL;
this->lpdd->Release();
this->lpdd = NULL;
return MP_RESULT_ERROR;
}
/*
* Create a Clipper to avoid
* the overlay staying on top
*/
ddrval = this->lpdd->CreateClipper(0, &this->lpddClipper, NULL);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
ddrval = this->lpddClipper->SetHWnd(0, hwnd);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
ddrval = this->lpddsPrimary->SetClipper(this->lpddClipper);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
/*
* Black out the primary
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -