LosaDev source snapshot 2019
This commit is contained in:
commit
c198676e97
20588 files changed
+8812878
No files matched your search
@@ -0,0 +1,147 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "BandiVideoFileReader.h"
|
||||
|
||||
|
||||
CBandiVideoFileReader::CBandiVideoFileReader() : m_ref_count(0), m_file_handle(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CBandiVideoFileReader::~CBandiVideoFileReader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG) CBandiVideoFileReader::AddRef()
|
||||
{
|
||||
LONG lRef = InterlockedIncrement(&m_ref_count);
|
||||
ASSERT(lRef >= 0);
|
||||
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG) CBandiVideoFileReader::Release()
|
||||
{
|
||||
LONG lRef = InterlockedDecrement(&m_ref_count);
|
||||
ASSERT(lRef >= 0);
|
||||
|
||||
if(lRef == 0)
|
||||
{
|
||||
delete this;
|
||||
return ULONG(0);
|
||||
}
|
||||
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Open a bandivideo file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoFileReader::Open(LPCWSTR path_name)
|
||||
{
|
||||
Close();
|
||||
|
||||
HANDLE hFile = CreateFileW(path_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return E_FAIL;
|
||||
|
||||
m_file_handle = hFile;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Close a bandivideo file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CBandiVideoFileReader::Close()
|
||||
{
|
||||
if(m_file_handle)
|
||||
{
|
||||
::CloseHandle(m_file_handle);
|
||||
m_file_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Read data from a file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
INT CBandiVideoFileReader::Read(BYTE* buf, INT bytes_to_read)
|
||||
{
|
||||
DWORD dwBytesRead = 0;
|
||||
if (!::ReadFile(m_file_handle, buf, bytes_to_read, &dwBytesRead, NULL))
|
||||
return 0;
|
||||
|
||||
return dwBytesRead;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Move the file pointer of the specified file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
INT64 CBandiVideoFileReader::SetPosition(INT64 pos)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = pos;
|
||||
|
||||
li.LowPart = ::SetFilePointer(m_file_handle , li.LowPart , &li.HighPart , FILE_BEGIN);
|
||||
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
{
|
||||
li.QuadPart = -1;
|
||||
}
|
||||
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Return the file pointer of the specified file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
INT64 CBandiVideoFileReader::GetPosition()
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = 0;
|
||||
|
||||
li.LowPart = ::SetFilePointer(m_file_handle , li.LowPart , &li.HighPart , FILE_CURRENT);
|
||||
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Return the size of the specified file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
INT64 CBandiVideoFileReader::GetFileSize()
|
||||
{
|
||||
LARGE_INTEGER size = {0, 0};
|
||||
size.LowPart = ::GetFileSize(m_file_handle , (DWORD*)&size.HighPart);
|
||||
|
||||
return size.QuadPart;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bandivid.h"
|
||||
|
||||
class CBandiVideoFileReader : public IBandiVideoFileReader
|
||||
{
|
||||
public:
|
||||
CBandiVideoFileReader();
|
||||
virtual ~CBandiVideoFileReader();
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { return E_NOTIMPL; };
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
STDMETHODIMP_(ULONG) Release();
|
||||
|
||||
// IBandiVideoFileReader
|
||||
HRESULT Open(LPCWSTR path_name);
|
||||
void Close();
|
||||
INT Read(BYTE* buf, INT bytes_to_read);
|
||||
INT64 SetPosition(INT64 pos);
|
||||
INT64 GetPosition();
|
||||
INT64 GetFileSize();
|
||||
|
||||
protected:
|
||||
LONG m_ref_count;
|
||||
HANDLE m_file_handle;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "BandiVideoLibrary.h"
|
||||
|
||||
CBandiVideoLibrary::CBandiVideoLibrary()
|
||||
{
|
||||
m_dll = NULL;
|
||||
m_pCreateBandiVideo2 = NULL;
|
||||
|
||||
m_bvl = NULL;
|
||||
}
|
||||
|
||||
CBandiVideoLibrary::~CBandiVideoLibrary()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
// 라이브러리 초기화
|
||||
HRESULT CBandiVideoLibrary::Create(LPCTSTR dll_path_name, IBandiVideoFileReader *reader /*= NULL */, IBandiVideoSound *sound /*= NULL */)
|
||||
{
|
||||
if(m_dll) {ASSERT(0); return BVERR_ALREADY_CREATED;}
|
||||
|
||||
// check os version
|
||||
OSVERSIONINFO osv;
|
||||
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
if (GetVersionEx(&osv)==FALSE ||
|
||||
osv.dwPlatformId <=VER_PLATFORM_WIN32_WINDOWS) // does not support 98
|
||||
{
|
||||
return BVERR_UNSUPPORTED_OS;
|
||||
}
|
||||
|
||||
// DLL 로드
|
||||
m_dll = LoadLibrary(dll_path_name);
|
||||
if(m_dll==NULL)
|
||||
{
|
||||
m_dll = LoadLibrary(BANDIVIDEO_RELEASE_DLL_FILE_NAME);
|
||||
if(m_dll==NULL)
|
||||
{
|
||||
ASSERT(0);
|
||||
return BVERR_LOAD_LIBRARY_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
m_pCreateBandiVideo2 = (LPCREATEBANDIVIDEO2)GetProcAddress(m_dll, "CreateBandiVideo2");
|
||||
if(m_pCreateBandiVideo2==NULL)
|
||||
{
|
||||
ASSERT(0);
|
||||
FreeLibrary(m_dll);
|
||||
m_dll = NULL;
|
||||
return BVERR_GET_PROC_ADDRESS_FAIL;
|
||||
}
|
||||
|
||||
return m_pCreateBandiVideo2(BVL_VERSION, (void**)&m_bvl, reader, sound);
|
||||
}
|
||||
|
||||
|
||||
BOOL CBandiVideoLibrary::IsCreated()
|
||||
{
|
||||
return m_bvl ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
// 라이브러리 해제
|
||||
void CBandiVideoLibrary::Destroy()
|
||||
{
|
||||
if(m_bvl)
|
||||
{
|
||||
m_bvl->Release();
|
||||
m_bvl = NULL;
|
||||
}
|
||||
|
||||
m_pCreateBandiVideo2 = NULL;
|
||||
if(m_dll) FreeLibrary(m_dll);
|
||||
m_dll = NULL;
|
||||
}
|
||||
|
||||
// 인증하기
|
||||
HRESULT CBandiVideoLibrary::Verify(LPCSTR id, LPCSTR key)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Verify(id, key);
|
||||
}
|
||||
|
||||
// 버전 정보
|
||||
INT CBandiVideoLibrary::GetVersion()
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return 0;}
|
||||
return m_bvl->GetVersion();
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Open(LPCWSTR path_name, BOOL async)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Open(path_name, async);
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Open(LPCSTR path_name, BOOL async)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
|
||||
WCHAR wszPath[MAX_PATH+1];
|
||||
MultiByteToWideChar(CP_ACP, NULL, path_name, -1, wszPath, MAX_PATH);
|
||||
|
||||
return m_bvl->Open(wszPath, async);
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Close()
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Close();
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Play()
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Play();
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Stop()
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Stop();
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Seek(INT64 value, BVL_SEEK_FLAG seek_flag)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Seek(value, seek_flag);
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::Pause(BOOL pause)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->Pause(pause);
|
||||
}
|
||||
|
||||
BOOL CBandiVideoLibrary::IsNextFrame()
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return FALSE;}
|
||||
return m_bvl->IsNextFrame();
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::GetFrame(BVL_FRAME &frame, BOOL can_skip)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->GetFrame(frame, can_skip);
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::GetVideoInfo(BVL_VIDEO_INFO &info)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->GetVideoInfo(info);
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::GetStatus(BVL_STATUS &status)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->GetStatus(status);
|
||||
}
|
||||
|
||||
HRESULT CBandiVideoLibrary::SetVolume(INT volume)
|
||||
{
|
||||
if(m_bvl==NULL) {ASSERT(0); return BVERR_LIBRARY_NOT_LOADED;}
|
||||
return m_bvl->SetVolume(volume);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bandivid.h"
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
# ifdef _DEBUG
|
||||
# define BANDIVIDEO_DLL_FILE_NAME _T("bdvid64_d.dll")
|
||||
# else
|
||||
# define BANDIVIDEO_DLL_FILE_NAME _T("bdvid64.dll")
|
||||
# endif
|
||||
# define BANDIVIDEO_RELEASE_DLL_FILE_NAME _T("bdvid64.dll")
|
||||
#else
|
||||
# ifdef _DEBUG
|
||||
# define BANDIVIDEO_DLL_FILE_NAME _T("bdvid32_d.dll")
|
||||
# else
|
||||
# define BANDIVIDEO_DLL_FILE_NAME _T("bdvid32.dll")
|
||||
# endif
|
||||
# define BANDIVIDEO_RELEASE_DLL_FILE_NAME _T("bdvid32.dll")
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// utility class for load library and create instance for video library
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CBandiVideoLibrary : public IBandiVideo2
|
||||
{
|
||||
public :
|
||||
CBandiVideoLibrary();
|
||||
~CBandiVideoLibrary();
|
||||
|
||||
HRESULT Create(LPCTSTR dll_path_name, IBandiVideoFileReader *reader = NULL, IBandiVideoSound *sound = NULL);
|
||||
void Destroy();
|
||||
BOOL IsCreated();
|
||||
|
||||
public :
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** p) { return E_NOTIMPL; }
|
||||
ULONG STDMETHODCALLTYPE AddRef(void) {return 0;}
|
||||
ULONG STDMETHODCALLTYPE Release(void) {return 0;}
|
||||
|
||||
// IBandiVideo2
|
||||
HRESULT Verify(LPCSTR szID, LPCSTR szKey); // ÀÎÁõÇϱâ
|
||||
INT GetVersion(); // ¹öÀü Á¤º¸
|
||||
|
||||
HRESULT Open(LPCWSTR path_name, BOOL async = FALSE);
|
||||
HRESULT Open(LPCSTR path_name, BOOL async = FALSE);
|
||||
HRESULT Close();
|
||||
HRESULT Play();
|
||||
HRESULT Stop();
|
||||
HRESULT Seek(INT64 value, BVL_SEEK_FLAG seek_flag);
|
||||
HRESULT Pause(BOOL pause);
|
||||
|
||||
BOOL IsNextFrame();
|
||||
HRESULT GetFrame(BVL_FRAME &frame, BOOL can_skip);
|
||||
HRESULT GetVideoInfo(BVL_VIDEO_INFO &info);
|
||||
HRESULT GetStatus(BVL_STATUS &status);
|
||||
|
||||
HRESULT SetVolume(INT volume); // 0 ~ 255
|
||||
|
||||
private :
|
||||
HMODULE m_dll;
|
||||
LPCREATEBANDIVIDEO2 m_pCreateBandiVideo2;
|
||||
|
||||
public:
|
||||
IBandiVideo2* m_bvl;
|
||||
};
|
||||
@@ -0,0 +1,504 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <math.h>
|
||||
#include "BandiVideoSound_DS.h"
|
||||
|
||||
#define BVL_DSWND_CLASS_NAME _T("CBandiVideoSound_DS")
|
||||
|
||||
|
||||
CBandiVideoSound_DS::CBandiVideoSound_DS() : m_ref_count(0)
|
||||
{
|
||||
m_hwnd = NULL;
|
||||
m_hinst = NULL;
|
||||
m_ds = NULL;
|
||||
m_dsb_primary = NULL;
|
||||
m_dsb_secondary = NULL;
|
||||
|
||||
m_channels = m_samplerate = 0;
|
||||
m_last_write_pos = 0;
|
||||
m_inbuf_samples = m_total_samples = 0;
|
||||
|
||||
m_cur_play_time = 0;
|
||||
|
||||
memset(&m_crit_sec, NULL, sizeof(m_crit_sec));
|
||||
m_crit_sec_inited = FALSE;
|
||||
|
||||
m_hevent = NULL;
|
||||
m_hthread = NULL;
|
||||
m_thread_id = 0;
|
||||
|
||||
m_playing = FALSE;
|
||||
m_callback = NULL;
|
||||
|
||||
m_outbuf_size_max = -1;
|
||||
m_outbuf_size_min = -1;
|
||||
|
||||
memset(m_sample_block, NULL, PLAY_SAMPLE_BLOCK_LEN);
|
||||
m_sample_block_size = 0;
|
||||
}
|
||||
|
||||
|
||||
CBandiVideoSound_DS::~CBandiVideoSound_DS()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG) CBandiVideoSound_DS::AddRef()
|
||||
{
|
||||
LONG lRef = InterlockedIncrement(&m_ref_count);
|
||||
ASSERT(lRef >= 0);
|
||||
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG) CBandiVideoSound_DS::Release()
|
||||
{
|
||||
LONG lRef = InterlockedDecrement(&m_ref_count);
|
||||
ASSERT(lRef >= 0);
|
||||
|
||||
if(lRef == 0)
|
||||
{
|
||||
delete this;
|
||||
return ULONG(0);
|
||||
}
|
||||
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Open sound device.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::Open(INT channels, INT samplerate, IBandiVideoSoundCB *callback)
|
||||
{
|
||||
Close();
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
m_hinst = (HINSTANCE)GetModuleHandle(NULL);
|
||||
if(m_hinst == NULL) goto error;
|
||||
|
||||
WNDCLASS wc;
|
||||
ZeroMemory(&wc, sizeof(wc));
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
wc.lpszClassName = BVL_DSWND_CLASS_NAME;
|
||||
RegisterClass(&wc);
|
||||
|
||||
// 버퍼타임으로 버퍼 byte 크기 계산
|
||||
m_outbuf_size_max = MulDiv(samplerate * channels * 2, MAX_BUFFER_TIME , 1000) ;
|
||||
m_outbuf_size_min = MulDiv(samplerate * channels * 2, MIN_BUFFER_TIME ,1000 );
|
||||
|
||||
// Create dummy window
|
||||
m_hwnd = CreateWindow(BVL_DSWND_CLASS_NAME, _T(""), 0, 0, 0, 0, 0, NULL, NULL, m_hinst, 0L);
|
||||
if(m_hwnd == NULL)
|
||||
goto error;
|
||||
|
||||
// Create Direct Sound Instance
|
||||
hr = DirectSoundCreate8(NULL, &m_ds, NULL);
|
||||
if(FAILED(hr))
|
||||
goto error;
|
||||
|
||||
hr = m_ds->SetCooperativeLevel(m_hwnd, DSSCL_PRIORITY);
|
||||
if(FAILED(hr))
|
||||
goto error;
|
||||
|
||||
// Create a primary buffer
|
||||
DSBUFFERDESC dsbdesc;
|
||||
ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
|
||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
hr = m_ds->CreateSoundBuffer(&dsbdesc, &m_dsb_primary, NULL);
|
||||
if(FAILED(hr))
|
||||
goto error;
|
||||
|
||||
// Set format of the primary buffer
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = channels;
|
||||
wfx.nSamplesPerSec = samplerate;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
hr = m_dsb_primary->SetFormat(&wfx);
|
||||
if(FAILED(hr))
|
||||
goto error;
|
||||
|
||||
// Create secondary sound buffer
|
||||
ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
|
||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS
|
||||
/*| DSBCAPS_LOCDEFER | DSBCAPS_CTRLFREQUENCY*/ | DSBCAPS_CTRLVOLUME;
|
||||
dsbdesc.dwBufferBytes = m_outbuf_size_max;
|
||||
dsbdesc.lpwfxFormat = &wfx;
|
||||
hr = m_ds->CreateSoundBuffer(&dsbdesc, &m_dsb_secondary, NULL);
|
||||
if(FAILED(hr))
|
||||
goto error;
|
||||
|
||||
InitializeCriticalSection(&m_crit_sec);
|
||||
m_crit_sec_inited = TRUE;
|
||||
|
||||
// Create an event object for periodical processing
|
||||
m_hevent = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset event
|
||||
if(m_hevent == NULL)
|
||||
goto error;
|
||||
|
||||
// Create thread for playback
|
||||
m_hthread = (HANDLE)_beginthreadex(NULL, 0, InitialThreadProc, this, CREATE_SUSPENDED, &m_thread_id);
|
||||
if(m_hthread == NULL)
|
||||
goto error;
|
||||
|
||||
m_channels = channels;
|
||||
m_samplerate = samplerate;
|
||||
|
||||
m_callback = callback;
|
||||
|
||||
memset(m_sample_block, NULL, PLAY_SAMPLE_BLOCK_LEN);
|
||||
m_sample_block_size = 0;
|
||||
|
||||
SetThreadPriority(m_hthread, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
ResumeThread(m_hthread);
|
||||
|
||||
return S_OK;
|
||||
|
||||
error:
|
||||
Close();
|
||||
|
||||
return FAILED(hr) ? hr : E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Close sound device.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CBandiVideoSound_DS::Close()
|
||||
{
|
||||
HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hthread, 0);
|
||||
if(hThread)
|
||||
{
|
||||
if(m_hevent) SetEvent(m_hevent);
|
||||
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
|
||||
if(m_hevent)
|
||||
{
|
||||
CloseHandle(m_hevent);
|
||||
m_hevent = NULL;
|
||||
}
|
||||
|
||||
if(m_crit_sec_inited)
|
||||
{
|
||||
DeleteCriticalSection(&m_crit_sec);
|
||||
m_crit_sec_inited = FALSE;
|
||||
}
|
||||
|
||||
if(m_dsb_secondary)
|
||||
{
|
||||
m_dsb_secondary->Release();
|
||||
m_dsb_secondary = NULL;
|
||||
}
|
||||
|
||||
if(m_dsb_primary)
|
||||
{
|
||||
m_dsb_primary->Release();
|
||||
m_dsb_primary = NULL;
|
||||
}
|
||||
|
||||
if(m_ds)
|
||||
{
|
||||
m_ds->Release();
|
||||
m_ds = NULL;
|
||||
}
|
||||
|
||||
if(m_hwnd)
|
||||
{
|
||||
DestroyWindow(m_hwnd);
|
||||
UnregisterClass(BVL_DSWND_CLASS_NAME, m_hinst);
|
||||
m_hwnd = NULL;
|
||||
}
|
||||
|
||||
m_channels = m_samplerate = 0;
|
||||
m_last_write_pos = 0;
|
||||
m_inbuf_samples = m_total_samples = 0;
|
||||
m_cur_play_time = 0;
|
||||
|
||||
m_playing = FALSE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Start
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::Start()
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
|
||||
m_playing = TRUE;
|
||||
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Stop
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::Stop()
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
|
||||
m_playing = FALSE;
|
||||
|
||||
if(m_dsb_secondary)
|
||||
{
|
||||
BYTE *pbData = NULL;
|
||||
BYTE *pbData2 = NULL;
|
||||
DWORD dwLength=0;
|
||||
DWORD dwLength2=0;
|
||||
|
||||
m_dsb_secondary->Stop();
|
||||
m_dsb_secondary->SetCurrentPosition(0);
|
||||
|
||||
// Lock DirectSound buffer
|
||||
m_dsb_secondary->Lock(0, m_outbuf_size_max, (void**)&pbData, &dwLength, (void**)&pbData2, &dwLength2, 0);
|
||||
|
||||
if(pbData) memset(pbData, 0, dwLength);
|
||||
if(pbData2) memset(pbData2, 0, dwLength2);
|
||||
|
||||
// Unlock the buffer
|
||||
m_dsb_secondary->Unlock(pbData, dwLength, pbData2, dwLength2);
|
||||
|
||||
m_last_write_pos = 0;
|
||||
m_total_samples = m_inbuf_samples = 0;
|
||||
m_cur_play_time = 0;
|
||||
|
||||
memset(m_sample_block, NULL, PLAY_SAMPLE_BLOCK_LEN);
|
||||
m_sample_block_size = 0;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Stop
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::Pause(BOOL pause)
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
|
||||
if(pause)
|
||||
{
|
||||
m_playing = FALSE;
|
||||
if(m_dsb_secondary) m_dsb_secondary->Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_playing = TRUE;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Get play time (100nsec units)
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::GetTime(INT64 &time)
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
|
||||
time = m_cur_play_time;
|
||||
|
||||
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Set sound volume
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::SetVolume(INT volume)
|
||||
{
|
||||
if(m_dsb_secondary == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
double lfPower10 = pow(10.0,-10.0); // 10^(-10);
|
||||
double lfVolume = (1 - lfPower10)*((double)volume/255) + lfPower10;
|
||||
|
||||
lfVolume = 10*log10(lfVolume);
|
||||
lfVolume *= 300;
|
||||
|
||||
if(lfVolume < -10000)
|
||||
lfVolume = -10000;
|
||||
|
||||
return m_dsb_secondary->SetVolume((LONG)lfVolume);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// ThreadProc
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
UINT CBandiVideoSound_DS::ThreadProc()
|
||||
{
|
||||
BOOL bWorking = FALSE;
|
||||
while(m_hthread)
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
if(m_playing)
|
||||
PlayDS();
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
WaitForSingleObject(m_hevent, 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Play DirectSound
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_DS::PlayDS()
|
||||
{
|
||||
HRESULT hr;
|
||||
int sample_bytes = m_channels*sizeof(INT16);
|
||||
DWORD free_buffer_size = GetFreeBufferSize();
|
||||
|
||||
// Update play position
|
||||
m_inbuf_samples = (m_outbuf_size_max - free_buffer_size)/(m_channels*sizeof(INT16));
|
||||
m_cur_play_time = max((m_total_samples - m_inbuf_samples)*10000000i64/m_samplerate, 0);
|
||||
|
||||
// Transfer PCM data to Direct Sound Buffer
|
||||
if(m_callback)
|
||||
{
|
||||
void *lock1_ptr = NULL;
|
||||
void *lock2_ptr = NULL;
|
||||
DWORD lock1_bytes = 0;
|
||||
DWORD lock2_bytes = 0;
|
||||
|
||||
if(m_sample_block_size < PLAY_SAMPLE_BLOCK_LEN)
|
||||
{
|
||||
int req_samples = (PLAY_SAMPLE_BLOCK_LEN-m_sample_block_size)/sample_bytes;
|
||||
int get_samples = m_callback->GetPcmData((INT16*)(&m_sample_block[m_sample_block_size]), req_samples);
|
||||
m_sample_block_size += get_samples*sample_bytes;
|
||||
}
|
||||
|
||||
if(m_sample_block_size == PLAY_SAMPLE_BLOCK_LEN && m_sample_block_size <= free_buffer_size)
|
||||
{
|
||||
hr = m_dsb_secondary->Lock(m_last_write_pos, m_sample_block_size,
|
||||
&lock1_ptr, &lock1_bytes,
|
||||
&lock2_ptr, &lock2_bytes, 0);
|
||||
|
||||
if(hr == DSERR_BUFFERLOST)
|
||||
{
|
||||
m_dsb_secondary->Restore();
|
||||
hr = m_dsb_secondary->Lock(m_last_write_pos, m_sample_block_size,
|
||||
&lock1_ptr, &lock1_bytes,
|
||||
&lock2_ptr, &lock2_bytes, 0);
|
||||
}
|
||||
|
||||
if(FAILED(hr)) return hr;
|
||||
|
||||
if(lock1_ptr) memcpy(lock1_ptr, m_sample_block, lock1_bytes);
|
||||
if(lock2_ptr) memcpy(lock2_ptr, m_sample_block+lock1_bytes, lock2_bytes);
|
||||
|
||||
m_dsb_secondary->Unlock(lock1_ptr, lock1_bytes, lock2_ptr, lock2_bytes);
|
||||
|
||||
// Update Write Pointer
|
||||
m_total_samples += m_sample_block_size/sample_bytes;
|
||||
m_last_write_pos += m_sample_block_size;
|
||||
if (INT(m_last_write_pos) >= m_outbuf_size_max)
|
||||
m_last_write_pos = m_last_write_pos - m_outbuf_size_max;
|
||||
|
||||
m_sample_block_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// PLAYBACK control
|
||||
DWORD dsb_status;
|
||||
m_dsb_secondary->GetStatus(&dsb_status);
|
||||
if((dsb_status & DSBSTATUS_PLAYING) == 0)
|
||||
{
|
||||
if (m_inbuf_samples >= m_outbuf_size_min)
|
||||
{
|
||||
m_dsb_secondary->Play(0, 0, DSBPLAY_LOOPING);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Get amount of free data in the buffer
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
DWORD CBandiVideoSound_DS::GetFreeBufferSize()
|
||||
{
|
||||
if(m_dsb_secondary == NULL) return 0;
|
||||
|
||||
if(m_total_samples == 0)
|
||||
return m_outbuf_size_max;
|
||||
|
||||
DWORD play_pos;
|
||||
DWORD free_buffer_size = 0;
|
||||
if(SUCCEEDED(m_dsb_secondary->GetCurrentPosition(&play_pos, NULL)))
|
||||
{
|
||||
if(m_last_write_pos > play_pos)
|
||||
free_buffer_size = (m_outbuf_size_max - m_last_write_pos) + play_pos;
|
||||
else
|
||||
free_buffer_size = play_pos - m_last_write_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
free_buffer_size = m_outbuf_size_max;
|
||||
}
|
||||
|
||||
return free_buffer_size;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#define DIRECTSOUND_VERSION 0x0800
|
||||
|
||||
#include <dsound.h>
|
||||
#include "bandivid.h"
|
||||
|
||||
|
||||
class CBandiVideoSound_DS : public IBandiVideoSound
|
||||
{
|
||||
public:
|
||||
static const UINT MAX_BUFFER_TIME = 200; // ms
|
||||
static const UINT MIN_BUFFER_TIME = 20; // ms
|
||||
|
||||
static const UINT PLAY_SAMPLE_BLOCK = 1000;
|
||||
static const UINT PLAY_SAMPLE_BLOCK_LEN = PLAY_SAMPLE_BLOCK*4;
|
||||
|
||||
CBandiVideoSound_DS();
|
||||
virtual ~CBandiVideoSound_DS();
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { return E_NOTIMPL; };
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
STDMETHODIMP_(ULONG) Release();
|
||||
|
||||
// IBandiVideoSound
|
||||
HRESULT Open(INT channels, INT samplerate, IBandiVideoSoundCB *callback);
|
||||
void Close();
|
||||
HRESULT Start();
|
||||
HRESULT Stop();
|
||||
HRESULT Pause(BOOL pause);
|
||||
HRESULT GetTime(INT64 &time);
|
||||
HRESULT SetVolume(INT volume);
|
||||
|
||||
protected:
|
||||
static unsigned WINAPI InitialThreadProc(LPVOID param)
|
||||
{
|
||||
CBandiVideoSound_DS *p = (CBandiVideoSound_DS*)param;
|
||||
return p->ThreadProc();
|
||||
};
|
||||
UINT ThreadProc();
|
||||
HRESULT PlayDS();
|
||||
DWORD GetFreeBufferSize();
|
||||
|
||||
LONG m_ref_count;
|
||||
|
||||
HWND m_hwnd; // Window Handle
|
||||
HINSTANCE m_hinst; // Instance Handle
|
||||
LPDIRECTSOUND8 m_ds; // DirectSound Interface
|
||||
LPDIRECTSOUNDBUFFER m_dsb_primary; // Primary buffer Interface
|
||||
LPDIRECTSOUNDBUFFER m_dsb_secondary; // DirectSound secondary sound buffer
|
||||
|
||||
UINT m_channels; // Number of Channnel
|
||||
UINT m_samplerate; // Sample rate;
|
||||
|
||||
INT m_outbuf_size_max;
|
||||
INT m_outbuf_size_min;
|
||||
|
||||
UINT m_last_write_pos; // Last write offset (in BYTE)
|
||||
|
||||
INT m_inbuf_samples; // Number of samples in the buffer
|
||||
INT m_total_samples; // Total number of written samples
|
||||
|
||||
LONGLONG m_cur_play_time; // 100nsec
|
||||
|
||||
CRITICAL_SECTION m_crit_sec;
|
||||
BOOL m_crit_sec_inited;
|
||||
|
||||
HANDLE m_hevent;
|
||||
HANDLE m_hthread;
|
||||
UINT m_thread_id;
|
||||
|
||||
BOOL m_playing;
|
||||
|
||||
BYTE m_sample_block[PLAY_SAMPLE_BLOCK_LEN];
|
||||
UINT m_sample_block_size;
|
||||
|
||||
IBandiVideoSoundCB* m_callback;
|
||||
};
|
||||
@@ -0,0 +1,294 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <process.h>
|
||||
#include "BandiVideoSound_NULL.h"
|
||||
|
||||
CBandiVideoSound_NULL::CBandiVideoSound_NULL() : m_ref_count(0)
|
||||
{
|
||||
m_init_count = 0;
|
||||
m_start_time = 0;
|
||||
|
||||
memset(&m_crit_sec, NULL, sizeof(m_crit_sec));
|
||||
m_crit_sec_inited = FALSE;
|
||||
|
||||
m_playing = FALSE;
|
||||
|
||||
m_hevent = NULL;
|
||||
m_hthread = NULL;
|
||||
m_thread_id = 0;
|
||||
|
||||
m_callback = NULL;
|
||||
|
||||
// Performance Frequency ±¸Çϱâ
|
||||
LARGE_INTEGER freq = {0, 0};
|
||||
QueryPerformanceFrequency(&freq);
|
||||
m_freq_units = freq.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
CBandiVideoSound_NULL::~CBandiVideoSound_NULL()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG) CBandiVideoSound_NULL::AddRef()
|
||||
{
|
||||
LONG lRef = InterlockedIncrement( &m_ref_count );
|
||||
ASSERT(lRef >= 0);
|
||||
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG) CBandiVideoSound_NULL::Release()
|
||||
{
|
||||
LONG lRef = InterlockedDecrement( &m_ref_count );
|
||||
ASSERT(lRef >= 0);
|
||||
|
||||
if(lRef == 0)
|
||||
{
|
||||
delete this;
|
||||
return ULONG(0);
|
||||
}
|
||||
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Open sound device.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::Open(INT channels, INT samplerate, IBandiVideoSoundCB *callback)
|
||||
{
|
||||
InitializeCriticalSection(&m_crit_sec);
|
||||
m_crit_sec_inited = TRUE;
|
||||
|
||||
// Create an event object for periodical processing
|
||||
m_hevent = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset event
|
||||
if(m_hevent == NULL)
|
||||
goto error;
|
||||
|
||||
// Create thread for playback
|
||||
m_hthread = (HANDLE)_beginthreadex(NULL, 0, InitialThreadProc, this, CREATE_SUSPENDED, &m_thread_id);
|
||||
if(m_hthread == NULL)
|
||||
goto error;
|
||||
|
||||
m_callback = callback;
|
||||
|
||||
SetThreadPriority(m_hthread, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
ResumeThread(m_hthread);
|
||||
|
||||
return S_OK;
|
||||
|
||||
error:
|
||||
Close();
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Close sound device.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CBandiVideoSound_NULL::Close()
|
||||
{
|
||||
HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hthread, 0);
|
||||
if(hThread)
|
||||
{
|
||||
if(m_hevent) SetEvent(m_hevent);
|
||||
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
|
||||
if(m_hevent)
|
||||
{
|
||||
CloseHandle(m_hevent);
|
||||
m_hevent = NULL;
|
||||
}
|
||||
|
||||
if(m_crit_sec_inited)
|
||||
{
|
||||
DeleteCriticalSection(&m_crit_sec);
|
||||
m_crit_sec_inited = FALSE;
|
||||
}
|
||||
|
||||
m_init_count = 0;
|
||||
m_start_time = 0;
|
||||
}
|
||||
|
||||
|
||||
static LONGLONG GetPerformanceCounter()
|
||||
{
|
||||
LARGE_INTEGER count;
|
||||
::QueryPerformanceCounter(&count);
|
||||
return count.QuadPart;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Start
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::Start()
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
m_init_count = GetPerformanceCounter();
|
||||
|
||||
m_start_time = 0;
|
||||
m_playing = TRUE;
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Stop
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::Stop()
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
m_start_time = 0;
|
||||
m_playing = FALSE;
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Stop
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::Pause(BOOL pause)
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
if(pause)
|
||||
{
|
||||
m_start_time = CalcTime();
|
||||
m_playing = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_init_count = GetPerformanceCounter();
|
||||
m_playing = TRUE;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Get play time (100nsec units)
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::GetTime(INT64 &time)
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
time = CalcTime();
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Set sound volume
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::SetVolume(INT volume)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// ThreadProc
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
UINT CBandiVideoSound_NULL::ThreadProc()
|
||||
{
|
||||
BOOL bWorking = FALSE;
|
||||
while(m_hthread)
|
||||
{
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
if(m_playing)
|
||||
PlayNULL();
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
WaitForSingleObject(m_hevent, 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Play NullSound
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoSound_NULL::PlayNULL()
|
||||
{
|
||||
if(m_callback)
|
||||
{
|
||||
INT16 buf[1024*2];
|
||||
m_callback->GetPcmData(buf, 1024);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Calculate current time
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
LONGLONG CBandiVideoSound_NULL::CalcTime()
|
||||
{
|
||||
LONGLONG ret;
|
||||
LONGLONG delta_time = 0;
|
||||
|
||||
EnterCriticalSection(&m_crit_sec);
|
||||
{
|
||||
if(m_playing && m_freq_units)
|
||||
delta_time = LONGLONG(double(GetPerformanceCounter() - m_init_count)/(double)m_freq_units*10000000.0);
|
||||
|
||||
ret = m_start_time + delta_time;
|
||||
}
|
||||
LeaveCriticalSection(&m_crit_sec);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bandivid.h"
|
||||
|
||||
class CBandiVideoSound_NULL : public IBandiVideoSound
|
||||
{
|
||||
public:
|
||||
CBandiVideoSound_NULL();
|
||||
virtual ~CBandiVideoSound_NULL();
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { return E_NOTIMPL; };
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
STDMETHODIMP_(ULONG) Release();
|
||||
|
||||
// IBandiVideoSound
|
||||
HRESULT Open(INT channels, INT samplerate, IBandiVideoSoundCB *callback);
|
||||
void Close();
|
||||
HRESULT Start();
|
||||
HRESULT Stop();
|
||||
HRESULT Pause(BOOL pause);
|
||||
HRESULT GetTime(INT64 &time);
|
||||
HRESULT SetVolume(INT volume);
|
||||
|
||||
protected:
|
||||
static unsigned WINAPI InitialThreadProc(LPVOID param)
|
||||
{
|
||||
CBandiVideoSound_NULL *p = (CBandiVideoSound_NULL*)param;
|
||||
return p->ThreadProc();
|
||||
};
|
||||
UINT ThreadProc();
|
||||
|
||||
HRESULT PlayNULL();
|
||||
LONGLONG CalcTime();
|
||||
|
||||
LONG m_ref_count;
|
||||
|
||||
LONGLONG m_freq_units; // 초당 카운터 단위(1000 이면 ms단위 카운터임)
|
||||
LONGLONG m_init_count; // 초기 카운터
|
||||
|
||||
LONGLONG m_start_time; // 시작 시간
|
||||
BOOL m_playing;
|
||||
|
||||
CRITICAL_SECTION m_crit_sec;
|
||||
BOOL m_crit_sec_inited;
|
||||
|
||||
HANDLE m_hevent;
|
||||
HANDLE m_hthread;
|
||||
UINT m_thread_id;
|
||||
|
||||
IBandiVideoSoundCB* m_callback;
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "bandivid.h"
|
||||
|
||||
|
||||
class CBandiVideoDevice
|
||||
{
|
||||
public:
|
||||
virtual ~CBandiVideoDevice() {};
|
||||
|
||||
virtual HRESULT Open(HWND hWnd) PURE;
|
||||
virtual void Close() PURE;
|
||||
|
||||
virtual HRESULT Resize(INT width, INT height) PURE;
|
||||
|
||||
virtual HRESULT StartFrame() PURE;
|
||||
virtual HRESULT EndFrame() PURE;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CBandiVideoTexture
|
||||
{
|
||||
public:
|
||||
virtual ~CBandiVideoTexture() {};
|
||||
|
||||
virtual HRESULT Open(INT vid_width, INT vid_height) PURE;
|
||||
virtual void Close() PURE;
|
||||
|
||||
virtual BYTE* Lock(INT &pitch) PURE;
|
||||
virtual void Unlock() PURE;
|
||||
|
||||
virtual HRESULT Draw(INT x, INT y, INT width, INT height) PURE;
|
||||
|
||||
virtual void* GetObject() PURE;
|
||||
virtual BVL_PIXEL_FORMAT GetFormat() PURE;
|
||||
};
|
||||
@@ -0,0 +1,457 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "BandiVideoTexture_DX9.h"
|
||||
|
||||
static BOOL GetTextureFormat(LPDIRECT3D9 d3d9, D3DFORMAT &texture_fmt_d3d, BVL_PIXEL_FORMAT &texture_fmt_bvl, int &texture_pixel_size)
|
||||
{
|
||||
struct
|
||||
{
|
||||
D3DFORMAT d3d_fmt;
|
||||
BVL_PIXEL_FORMAT bvl_fmt;
|
||||
int pixel_size;
|
||||
} fmt_list[] =
|
||||
{
|
||||
{ D3DFMT_X8R8G8B8, BVLPF_X8R8G8B8, 4},
|
||||
{ D3DFMT_R8G8B8, BVLPF_R8G8B8, 3},
|
||||
{ D3DFMT_R5G6B5, BVLPF_R5G6B5, 2},
|
||||
{ D3DFMT_X1R5G5B5, BVLPF_R5G5B5, 2},
|
||||
};
|
||||
|
||||
D3DDISPLAYMODE d3ddm;
|
||||
HRESULT hr = d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
int fmt_count = sizeof(fmt_list)/sizeof(fmt_list[0]);
|
||||
for(int i = 0; i < fmt_count; i++ )
|
||||
{
|
||||
if(SUCCEEDED(d3d9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, 0, D3DRTYPE_TEXTURE, fmt_list[i].d3d_fmt)))
|
||||
{
|
||||
texture_fmt_d3d = fmt_list[i].d3d_fmt;
|
||||
texture_fmt_bvl = fmt_list[i].bvl_fmt;
|
||||
texture_pixel_size = fmt_list[i].pixel_size;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture_fmt_d3d = D3DFMT_UNKNOWN;
|
||||
texture_fmt_bvl = BVLPF_NULL;
|
||||
texture_pixel_size = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// CBandiVideoDevice_DX9 class
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
CBandiVideoDevice_DX9::CBandiVideoDevice_DX9()
|
||||
{
|
||||
// BV_DEVICE_DX9 structure
|
||||
m_d3d9 = NULL;
|
||||
m_d3d9_device = NULL;
|
||||
m_hwnd_parent = NULL;
|
||||
}
|
||||
|
||||
|
||||
CBandiVideoDevice_DX9::~CBandiVideoDevice_DX9()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Open Direct3D9 Device.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoDevice_DX9::Open(HWND hWnd)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPDIRECT3D9 d3d9 = NULL;
|
||||
LPDIRECT3DDEVICE9 d3d9_device = NULL;
|
||||
D3DDISPLAYMODE d3ddm;
|
||||
D3DPRESENT_PARAMETERS d3dpp = {0};;
|
||||
|
||||
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if(d3d9 == NULL)
|
||||
{
|
||||
ASSERT(0);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ASSERT(0);
|
||||
return hr;
|
||||
}
|
||||
|
||||
d3dpp.hDeviceWindow = hWnd;
|
||||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.BackBufferFormat = d3ddm.Format;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
|
||||
if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3d9_device)))
|
||||
{
|
||||
ASSERT(0);
|
||||
if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3d9_device)))
|
||||
{
|
||||
ASSERT(0);
|
||||
if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3d9_device)))
|
||||
{
|
||||
ASSERT(0);
|
||||
d3d9->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_d3d9 = d3d9;
|
||||
m_d3d9_device = d3d9_device;
|
||||
m_hwnd_parent = hWnd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Close Direct3D9 Device.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CBandiVideoDevice_DX9::Close()
|
||||
{
|
||||
if(m_d3d9_device)
|
||||
{
|
||||
m_d3d9_device->Release();
|
||||
m_d3d9_device = NULL;
|
||||
}
|
||||
|
||||
if(m_d3d9)
|
||||
{
|
||||
m_d3d9->Release( );
|
||||
m_d3d9 = NULL;
|
||||
}
|
||||
|
||||
m_hwnd_parent = NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Resize the Direct3D9 viewport.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoDevice_DX9::Resize(INT width, INT height)
|
||||
{
|
||||
if(m_d3d9_device == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
width = max(1, width);
|
||||
height = max(1, height);
|
||||
|
||||
// Create the viewport
|
||||
D3DVIEWPORT9 vp = { 0, 0, width, height, 0.0f, 1.0f };
|
||||
|
||||
m_d3d9_device->SetViewport( &vp );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Begin a Direct3D9 frame.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoDevice_DX9::StartFrame()
|
||||
{
|
||||
if(m_d3d9_device == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
m_d3d9_device->Clear( 0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0 );
|
||||
m_d3d9_device->BeginScene();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// End a Direct3D9 frame.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoDevice_DX9::EndFrame()
|
||||
{
|
||||
if(m_d3d9_device == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
m_d3d9_device->EndScene();
|
||||
m_d3d9_device->Present(NULL, NULL, NULL, NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// D3DVERTEX structure
|
||||
typedef struct _D3DVERTEX { // D3D Vertex
|
||||
D3DVECTOR pos;
|
||||
float rhw;
|
||||
float tu, tv;
|
||||
} D3DVERTEX;
|
||||
#define D3DFVF_VERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// CBandiVideoTexture_DX9 class
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
CBandiVideoTexture_DX9::CBandiVideoTexture_DX9(BV_DEVICE_DX9* device)
|
||||
{
|
||||
memcpy(&m_device, device, sizeof(BV_DEVICE_DX9));
|
||||
|
||||
m_texture = NULL;
|
||||
m_vertex_buffer = NULL;
|
||||
|
||||
m_vid_width = m_vid_height = 0;
|
||||
m_tex_width = m_tex_height = 0;
|
||||
|
||||
if(!GetTextureFormat(device->m_d3d9, m_fmt_d3d, m_fmt_bvl, m_pixel_size))
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
|
||||
CBandiVideoTexture_DX9::~CBandiVideoTexture_DX9()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Open a Direct3D9 texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoTexture_DX9::Open(INT vid_width, INT vid_height)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPDIRECT3DTEXTURE9 texture = NULL;
|
||||
LPDIRECT3DDEVICE9 d3d9_device = m_device.m_d3d9_device;
|
||||
BOOL pow2 = TRUE;
|
||||
|
||||
D3DCAPS9 Caps;
|
||||
d3d9_device->GetDeviceCaps(&Caps);
|
||||
if(!!(Caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
|
||||
{
|
||||
pow2 = FALSE;
|
||||
}
|
||||
|
||||
int tex_width = CalcTexSize(vid_width, pow2);
|
||||
int tex_height = CalcTexSize(vid_height, pow2);
|
||||
|
||||
// try to create a dynamic texture first
|
||||
hr = d3d9_device->CreateTexture(tex_width, tex_height, 1,D3DUSAGE_DYNAMIC,
|
||||
m_fmt_d3d, D3DPOOL_DEFAULT, &texture, 0);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
hr = d3d9_device->CreateTexture(tex_width, tex_height, 1, 0,
|
||||
m_fmt_d3d, D3DPOOL_MANAGED, &texture, 0);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
Beep(1000, 1000);
|
||||
ASSERT(0);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
D3DLOCKED_RECT locked_rect;
|
||||
|
||||
// Clear the texture to black.
|
||||
if(SUCCEEDED(texture->LockRect(0, &locked_rect, NULL, NULL)))
|
||||
{
|
||||
// Clear the pixels.
|
||||
BYTE* dest = (BYTE*) locked_rect.pBits;
|
||||
int bytes = tex_width*m_pixel_size;
|
||||
|
||||
for(int y = 0 ; y < tex_height ; y++)
|
||||
{
|
||||
memset(dest, 0, bytes);
|
||||
dest += locked_rect.Pitch;
|
||||
}
|
||||
|
||||
// Unlock the DirectX texture.
|
||||
texture->UnlockRect(NULL);
|
||||
}
|
||||
|
||||
m_texture = texture;
|
||||
|
||||
m_vid_width = vid_width;
|
||||
m_vid_height = vid_height;
|
||||
m_tex_width = tex_width;
|
||||
m_tex_height = tex_height;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Close a Direct3D9 texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CBandiVideoTexture_DX9::Close()
|
||||
{
|
||||
m_vid_width = m_vid_height = 0;
|
||||
m_tex_width = m_tex_height = 0;
|
||||
|
||||
if(m_texture)
|
||||
{
|
||||
m_texture->Release();
|
||||
m_texture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Lock a Direct3D9 teture and return the buffer address and pitch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
BYTE* CBandiVideoTexture_DX9::Lock(INT &pitch)
|
||||
{
|
||||
D3DLOCKED_RECT rc;
|
||||
BYTE *buf;
|
||||
|
||||
m_texture->LockRect(0, &rc, NULL, 0);
|
||||
buf = (BYTE*)rc.pBits;
|
||||
pitch = rc.Pitch;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Unlock a Direct3D9 texture.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CBandiVideoTexture_DX9::Unlock()
|
||||
{
|
||||
m_texture->UnlockRect(NULL);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Draw a Direct3D9 texture.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoTexture_DX9::Draw(INT x, INT y, INT width, INT height)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = m_device.m_d3d9_device->SetTexture(0, m_texture);
|
||||
if(FAILED(hr)) return hr;
|
||||
|
||||
static DWORD dwAddressU, dwAddressV;
|
||||
|
||||
m_device.m_d3d9_device->GetSamplerState(0, D3DSAMP_ADDRESSU, &dwAddressU);
|
||||
m_device.m_d3d9_device->GetSamplerState(0, D3DSAMP_ADDRESSV, &dwAddressV);
|
||||
|
||||
m_device.m_d3d9_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
m_device.m_d3d9_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
m_device.m_d3d9_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
m_device.m_d3d9_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
hr = SetVertices((float)x, (float)y, (float)width, (float)height);
|
||||
|
||||
m_device.m_d3d9_device->SetSamplerState(0, D3DSAMP_ADDRESSU, dwAddressU);
|
||||
m_device.m_d3d9_device->SetSamplerState(0, D3DSAMP_ADDRESSV, dwAddressV);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Set the vertices.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CBandiVideoTexture_DX9::SetVertices(float scr_x, float scr_y, float scr_width, float scr_height)
|
||||
{
|
||||
D3DVERTEX vertices[4];
|
||||
|
||||
// Set vertices
|
||||
vertices[0].pos.x = scr_x;
|
||||
vertices[0].pos.y = scr_y;
|
||||
vertices[0].tu = 0.0f;
|
||||
vertices[0].tv = 0.0f;
|
||||
|
||||
vertices[1].pos.x = scr_x + scr_width;
|
||||
vertices[1].pos.y = scr_y;
|
||||
vertices[1].tu = 1.0f * ((float)m_vid_width / m_tex_width);
|
||||
vertices[1].tv = 0.0f;
|
||||
|
||||
vertices[2].pos.x = scr_x;
|
||||
vertices[2].pos.y = scr_y + scr_height;
|
||||
vertices[2].tu = 0.0f;
|
||||
vertices[2].tv = 1.0f * ((float)m_vid_height / m_tex_height);
|
||||
|
||||
vertices[3].pos.x = scr_x + scr_width;
|
||||
vertices[3].pos.y = scr_y + scr_height;
|
||||
vertices[3].tu = 1.0f * ((float)m_vid_width / m_tex_width);
|
||||
vertices[3].tv = 1.0f * ((float)m_vid_height / m_tex_height);
|
||||
|
||||
|
||||
vertices[0].pos.z = vertices[1].pos.z = vertices[2].pos.z = vertices[3].pos.z = 0.0f;
|
||||
vertices[0].rhw = vertices[1].rhw = vertices[2].rhw = vertices[3].rhw = 1.0f;
|
||||
|
||||
// Draw the vertices.
|
||||
m_device.m_d3d9_device->SetVertexShader(0);
|
||||
m_device.m_d3d9_device->SetFVF(D3DFVF_VERTEX);
|
||||
|
||||
return m_device.m_d3d9_device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(vertices[0]));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Calculate texture size.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int CBandiVideoTexture_DX9::CalcTexSize(int vid_size, BOOL pow2)
|
||||
{
|
||||
// Power-of-2 texture dimensions are required.
|
||||
D3DCAPS9 caps;
|
||||
m_device.m_d3d9_device->GetDeviceCaps(&caps);
|
||||
if(pow2 && caps.TextureCaps & D3DPTEXTURECAPS_POW2)
|
||||
{
|
||||
int tex_size = 16;
|
||||
while (tex_size < vid_size)
|
||||
tex_size = tex_size<<1;
|
||||
|
||||
return tex_size;
|
||||
}
|
||||
|
||||
return vid_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// BandiVideoLibrary 2.1
|
||||
///
|
||||
/// Copyright(C) 2008-2011 BandiSoft.com All rights reserved.
|
||||
///
|
||||
/// Visit http://www.bandisoft.com for more information.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d3d9.h>
|
||||
#include "BandiVideoTexture.h"
|
||||
|
||||
|
||||
struct BV_DEVICE_DX9
|
||||
{
|
||||
LPDIRECT3D9 m_d3d9;
|
||||
LPDIRECT3DDEVICE9 m_d3d9_device;
|
||||
HWND m_hwnd_parent;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CBandiVideoDevice_DX9 : public CBandiVideoDevice, public BV_DEVICE_DX9
|
||||
{
|
||||
public:
|
||||
CBandiVideoDevice_DX9();
|
||||
virtual ~CBandiVideoDevice_DX9();
|
||||
|
||||
virtual HRESULT Open(HWND hWnd);
|
||||
virtual void Close();
|
||||
|
||||
virtual HRESULT Resize(INT width, INT height);
|
||||
|
||||
virtual HRESULT StartFrame();
|
||||
virtual HRESULT EndFrame();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CBandiVideoTexture_DX9 : public CBandiVideoTexture
|
||||
{
|
||||
public:
|
||||
CBandiVideoTexture_DX9(BV_DEVICE_DX9* device);
|
||||
virtual ~CBandiVideoTexture_DX9();
|
||||
|
||||
virtual HRESULT Open(INT vid_width, INT vid_height);
|
||||
virtual void Close();
|
||||
|
||||
virtual BYTE* Lock(INT &pitch);
|
||||
virtual void Unlock();
|
||||
|
||||
virtual HRESULT Draw(INT x, INT y, INT width, INT height);
|
||||
|
||||
virtual void* GetObject() { return m_texture; };
|
||||
virtual BVL_PIXEL_FORMAT GetFormat() { return m_fmt_bvl; };
|
||||
|
||||
protected:
|
||||
HRESULT SetVertices(float scr_x, float scr_y, float scr_width, float scr_height);
|
||||
int CalcTexSize(int vid_size, BOOL pow2);
|
||||
|
||||
BV_DEVICE_DX9 m_device;
|
||||
LPDIRECT3DTEXTURE9 m_texture;
|
||||
LPDIRECT3DVERTEXBUFFER9 m_vertex_buffer;
|
||||
|
||||
D3DFORMAT m_fmt_d3d;
|
||||
BVL_PIXEL_FORMAT m_fmt_bvl;
|
||||
|
||||
int m_vid_width;
|
||||
int m_vid_height;
|
||||
int m_tex_width;
|
||||
int m_tex_height;
|
||||
int m_pixel_size;
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user