Forum: VirtualDJ Plugins

Questions about plugins development, talks with other developers etc
Topic: VideoTransition: letterBoxing
djcelPRO InfinityModeratorMember since 2004
What is the best way to take into account LetterBoxing in VideoTransition (SDK)?

Posted Fri 19 Jul 19 @ 10:49 pm
AdionPRO InfinityCTOMember since 2006
It seems like your compose function is ignoring the existing values in the vertices, therefore ignoring any placement or stretching that existed.
You should use the values already in there to get default placement and stretch, and then just scale/move accordingly

Posted Sat 20 Jul 19 @ 4:20 am
djcelPRO InfinityModeratorMember since 2004
OK thank you. Fixed

main.cpp wrote :
#include "SDK8/Slide3D8.h"

HRESULT VDJ_API DllGetClassObject(const GUID &rclsid,const GUID &riid,void** ppObject)
{
//This is the standard DLL loader for COM object.
if (memcmp(&rclsid,&CLSID_VdjPlugin8,sizeof(GUID))==0 && memcmp(&riid,&IID_IVdjPluginVideoTransition8,sizeof(GUID))==0)
{
*ppObject = new CSlide3D8();
}
else
{
return CLASS_E_CLASSNOTAVAILABLE;
}

return NO_ERROR;
}


Slide3D8.h wrote :
#ifndef SLIDE3D8_H
#define SLIDE3D8_H

#pragma warning (disable : 4068 ) /* disable unknown pragma warnings */
#pragma warning (disable : 4163 ) /* disable '_InterlockedExchangeAdd8' : not available as an intrinsic function*/


#include "VdjVideo8.h"

#if (defined(VDJ_WIN))
#if (defined(_M_X64) || defined(__amd64__))
#define VDJ_WIN64
#define VDJ_D3D11
#include <D3D11_4.h>
#pragma comment (lib, "D3D11.lib")
typedef DWORD D3DCOLOR;
#define D3DCOLOR_RGBA(r,g,b,a) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
#else
#define VDJ_D3D9
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
#endif
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
#endif
#elif (defined(VDJ_MAC))
#define VDJ_OPENGL
#endif

//-------------------------------------------------------------------------------------------
class CSlide3D8 : public IVdjPluginVideoTransition8
{
public:
HRESULT VDJ_API OnLoad();
HRESULT VDJ_API OnGetPluginInfo(TVdjPluginInfo8 *info);
ULONG VDJ_API Release();
HRESULT VDJ_API OnDeviceInit();
HRESULT VDJ_API OnDeviceClose();
HRESULT VDJ_API OnDraw(float crossfader);

private:
HRESULT Compose(float crossfader);
HRESULT RenderSurface(int deck, bool bDefault);
void VideoScaling(int deck);

float m_Width;
float m_Height;
TVertex8 m_DefaultVertices[2][4];
TVertex8 m_Vertices[2][4];

#if (defined(VDJ_D3D9))
static const EVdjVideoEngine VDJVIDEOENGINE = VdjVideoEngineDirectX9;
typedef IDirect3DDevice9 VDJVIDEODEVICE;
typedef IDirect3DTexture9 VDJVIDEOTEXTURE;
VDJVIDEODEVICE *pVdjVideoDevice;
#elif (defined(VDJ_D3D11))
static const EVdjVideoEngine VDJVIDEOENGINE = VdjVideoEngineDirectX11;
typedef ID3D11Device VDJVIDEODEVICE;
typedef ID3D11ShaderResourceView VDJVIDEOTEXTURE;
VDJVIDEODEVICE *pVdjVideoDevice;
#elif (defined(VDJ_OPENGL))
static const EVdjVideoEngine VDJVIDEOENGINE = VdjVideoEngineOpenGL;
typedef GLuint VDJVIDEOTEXTURE;
#endif

};
#endif


Slide3D8.cpp wrote :
#include "Slide3D8.h"


//---------------------------------------------------------------------------------------------
HRESULT VDJ_API CSlide3D8::OnLoad()
{
memset(m_DefaultVertices[0],0,4*sizeof(TVertex8));
memset(m_DefaultVertices[1],0,4*sizeof(TVertex8));
memset(m_Vertices[0],0,4*sizeof(TVertex8));
memset(m_Vertices[1],0,4*sizeof(TVertex8));
m_Width = 0.0f;
m_Height = 0.0f;

return S_OK;
}
//---------------------------------------------------------------------------------------------
HRESULT VDJ_API CSlide3D8::OnGetPluginInfo(TVdjPluginInfo8 *infos)
{
infos->Author = "DJ CEL";
infos->PluginName = "Slide3D";
infos->Description = " A slide effect in 3D";
infos->Flags = VDJFLAG_VIDEO_MASTERONLY;

#if (defined(VDJ_WIN64) || defined(VDJ_MAC))
infos->Version = "3.0 (64-bit)";
#else
infos->Version = "3.0 (32-bit)";
#endif

#if (defined(VDJ_WIN))
infos->Bitmap = LoadBitmap(hInstance,MAKEINTRESOURCE(100));
#elif (defined(VDJ_MAC))
infos->Bitmap = "bitmap.bmp"
#endif

return S_OK;
}
//---------------------------------------------------------------------------------------------
ULONG VDJ_API CSlide3D8::Release()
{
delete this;
return 0;
}
//---------------------------------------------------------------------------------------------
HRESULT VDJ_API CSlide3D8::OnDeviceInit()
{
HRESULT hr = S_FALSE;
void *device = NULL;

hr = GetDevice(VDJVIDEOENGINE, &device);
if(hr!=S_OK || device==NULL) return S_FALSE;
pVdjVideoDevice = reinterpret_cast<VDJVIDEODEVICE*>(device);

m_Width = (float) width;
m_Height = (float) height;

return S_OK;
}
//---------------------------------------------------------------------------------------------
HRESULT VDJ_API CSlide3D8::OnDeviceClose()
{
return S_OK;
}
//---------------------------------------------------------------------------------------------
HRESULT VDJ_API CSlide3D8::OnDraw(float crossfader)
{
HRESULT hr = S_FALSE;

m_Width = (float) width;
m_Height = (float) height;

memcpy(m_Vertices[0],GetVertices(1),4*sizeof(TVertex8));
memcpy(m_Vertices[1],GetVertices(2),4*sizeof(TVertex8));

for(int deck=0;deck<2;deck++)
{
for(int v=0;v<4;v++)
{
m_Vertices[deck-1][v].position.x = m_Vertices[deck-1][v].position.x / m_Width;
m_Vertices[deck-1][v].position.y = m_Vertices[deck-1][v].position.y / m_Height;
}
}

hr = Compose(crossfader);

return hr;
}
//---------------------------------------------------------------------------------------------
HRESULT CSlide3D8::RenderSurface(int deck, bool bDefault)
{
HRESULT hr = S_OK;

for(int v=0;v<4;v++)
{
m_Vertices[deck-1][v].position.x = m_Vertices[deck-1][v].position.x * m_Width;
m_Vertices[deck-1][v].position.y = m_Vertices[deck-1][v].position.y * m_Height;
}

VideoScaling(deck);

if (bDefault==true)
{
hr = DrawDeck(deck, NULL); // (pass NULL to DrawDeck() to use the default vertices)
}
else
{
hr = DrawDeck(deck, m_Vertices[deck-1]);
}

return hr;
}
//---------------------------------------------------------------------------------------------
HRESULT CSlide3D8::Compose(float crossfader)
{
HRESULT hr;

float compressor_rate = 0.0f;
int alpha = 0;

//pVdjVideoDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

if (crossfader<=0.5f)
{
compressor_rate = crossfader/0.5f;
alpha = (int) (compressor_rate * 255.0f);

// Video 1
m_Vertices[0][0].position.x = 0.0f;
m_Vertices[0][0].position.y = 0.0f + compressor_rate * 0.25f; // de 0 à 0.25;

m_Vertices[0][1].position.x = 1.0f - compressor_rate * 0.5f; // de 1 à 0.5
m_Vertices[0][1].position.y = 0.0f + compressor_rate * 0.25f; // de 0 à 0.25

m_Vertices[0][2].position.x = 1.0f - compressor_rate * 0.5f; // de 1 à 0.5
m_Vertices[0][2].position.y = 1.0f - compressor_rate * 0.25f; // de 1 à 0.75;

m_Vertices[0][3].position.x = 0.0f;
m_Vertices[0][3].position.y = 1.0f - compressor_rate * 0.25f; // de 1 à 0.75;

//Video 2
m_Vertices[1][0].position.x = 0.5f;
m_Vertices[1][0].position.y = 0.25f;
m_Vertices[1][0].color = D3DCOLOR_RGBA(255,255,255,alpha);

m_Vertices[1][1].position.x = 1.0f;
m_Vertices[1][1].position.y = 0.25f;
m_Vertices[1][1].color = D3DCOLOR_RGBA(255,255,255,alpha);

m_Vertices[1][2].position.x = 1.0f;
m_Vertices[1][2].position.y = 0.75f;
m_Vertices[1][2].color = D3DCOLOR_RGBA(255,255,255,alpha);

m_Vertices[1][3].position.x = 0.5f;
m_Vertices[1][3].position.y = 0.75f;
m_Vertices[1][3].color = D3DCOLOR_RGBA(255,255,255,alpha);

hr = RenderSurface(2,false);
hr = RenderSurface(1,false);

}
else
{
compressor_rate=(1.0f-crossfader)/0.5f;
alpha = (int) (compressor_rate * 255.0f);

//Video 1
m_Vertices[0][0].position.x=0.0f;
m_Vertices[0][0].position.y=0.25f;
m_Vertices[0][0].color = D3DCOLOR_RGBA(255,255,255,alpha);

m_Vertices[0][1].position.x=0.5f;
m_Vertices[0][1].position.y=0.25f;
m_Vertices[0][1].color = D3DCOLOR_RGBA(255,255,255,alpha);

m_Vertices[0][2].position.x=0.5f;
m_Vertices[0][2].position.y=0.75f;
m_Vertices[0][2].color = D3DCOLOR_RGBA(255,255,255,alpha);

m_Vertices[0][3].position.x=0.0f;
m_Vertices[0][3].position.y=0.75f;
m_Vertices[0][3].color = D3DCOLOR_RGBA(255,255,255,alpha);

// Video 2
m_Vertices[1][0].position.x=0.0f + compressor_rate * 0.5f; // de 0.5 à 0.0
m_Vertices[1][0].position.y=0.0f + compressor_rate * 0.25f; // de 0.25 à 0.0

m_Vertices[1][1].position.x=1.0f;
m_Vertices[1][1].position.y=0.0f + compressor_rate * 0.25f; // de 0.25 à 0.0

m_Vertices[1][2].position.x=1.f;
m_Vertices[1][2].position.y=1.f - compressor_rate * 0.25f; // de 0.75 à 1.0

m_Vertices[1][3].position.x=0.f + compressor_rate * 0.5f; // de 0.5 à 0.0
m_Vertices[1][3].position.y=1.f - compressor_rate * 0.25f; // de 0.75 à 1.0

hr = RenderSurface(1,false);
hr = RenderSurface(2,false);
}

return S_OK;
}
//---------------------------------------------------------------------------------------------
void CSlide3D8::VideoScaling(int deck)
{
float WidthOriginalVideo, HeightOriginalVideo;
float WidthVideo, HeightVideo;
float NewWidthVideo, NewHeightVideo;
float RatioOriginalVideo;
bool b_CropVideoW,b_CropVideoH;
float dx,dy;

memcpy(m_DefaultVertices[deck-1],GetVertices(deck),4*sizeof(TVertex8));

WidthOriginalVideo = m_DefaultVertices[deck-1][1].position.x - m_DefaultVertices[deck-1][0].position.x;
HeightOriginalVideo = m_DefaultVertices[deck-1][3].position.y - m_DefaultVertices[deck-1][0].position.y;

b_CropVideoW = (WidthOriginalVideo != m_Width);
b_CropVideoH = (HeightOriginalVideo != m_Height);

RatioOriginalVideo = HeightOriginalVideo / WidthOriginalVideo;

WidthVideo = m_Vertices[deck-1][1].position.x - m_Vertices[deck-1][0].position.x;
HeightVideo = m_Vertices[deck-1][3].position.y - m_Vertices[deck-1][0].position.y;

if (b_CropVideoW)
{
NewWidthVideo = HeightVideo / RatioOriginalVideo;
dx = (WidthVideo - NewWidthVideo) * 0.5f;

m_Vertices[deck-1][0].position.x += dx;
m_Vertices[deck-1][1].position.x -= dx;
m_Vertices[deck-1][2].position.x -= dx;
m_Vertices[deck-1][3].position.x += dx;
}
else if (b_CropVideoH)
{
NewHeightVideo = WidthVideo * RatioOriginalVideo;
dy = (HeightVideo - NewHeightVideo) * 0.5f;

m_Vertices[deck-1][0].position.y += dy;
m_Vertices[deck-1][1].position.y += dy;
m_Vertices[deck-1][2].position.y -= dy;
m_Vertices[deck-1][3].position.y -= dy;
}
}

Posted Sat 20 Jul 19 @ 4:01 pm