Initial commit: ROW Client source code

Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
//------------------------------------------------------------------------------
// File: Sample.h
//
// Desc: DirectShow sample code - definition of CSample class.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __SAMPLE_H_
#define __SAMPLE_H_
// df20ddfa-0d19-463a-ab46-e5d8ef6efd69
DEFINE_GUID(CLSID_Sample,
0xdf20ddfa, 0x0d19, 0x463a, 0xab, 0x46, 0xe5, 0xd8, 0xef, 0x6e, 0xfd, 0x69);
/////////////////////////////////////////////////////////////////////////////
// CSample
class ATL_NO_VTABLE CSample :
public IMediaObjectImpl<CSample, 1, 2>, // 1 input, 2 outputs
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CSample, &CLSID_Sample>
{
public:
CSample()
{
m_pUnkMarshaler = NULL;
}
DECLARE_REGISTRY_RESOURCEID(IDR_SAMPLE)
DECLARE_GET_CONTROLLING_UNKNOWN()
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSample)
COM_INTERFACE_ENTRY(IMediaObject)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
END_COM_MAP()
HRESULT FinalConstruct()
{
return CoCreateFreeThreadedMarshaler(
GetControllingUnknown(), &m_pUnkMarshaler.p);
}
void FinalRelease()
{
// Make sure we clean up
FreeStreamingResources();
m_pUnkMarshaler.Release();
}
// IMediaObjectImpl callbacks
HRESULT InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags);
HRESULT InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags);
HRESULT InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt);
HRESULT InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt);
HRESULT InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
DMO_MEDIA_TYPE *pmt);
HRESULT InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
DMO_MEDIA_TYPE *pmt);
HRESULT InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
DWORD *pcbMaxLookahead, DWORD *pcbAlignment);
HRESULT InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
DWORD *pcbAlignment);
HRESULT InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency);
HRESULT InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency);
HRESULT InternalFlush();
HRESULT InternalDiscontinuity(DWORD dwInputStreamIndex);
HRESULT InternalAllocateStreamingResources();
HRESULT InternalFreeStreamingResources();
HRESULT InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
DWORD dwFlags, REFERENCE_TIME rtTimestamp,
REFERENCE_TIME rtTimelength);
HRESULT InternalProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount,
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
DWORD *pdwStatus);
HRESULT InternalAcceptingInput(DWORD dwInputStreamIndex);
// Internal processing routine
HRESULT Process();
CComPtr<IUnknown> m_pUnkMarshaler;
// Streaming locals
CComPtr<IMediaBuffer> m_pBuffer;
BYTE * m_pbData;
DWORD m_cbData;
// Fabricate timestamps based on the average time per from if there isn't one in the stream
REFERENCE_TIME m_rtFrame;
// Current state info
CStreamState m_StreamState;
bool m_bPicture;
public:
};
#endif //__SAMPLE_H_

View File

@@ -0,0 +1,14 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {df20ddfa-0d19-463a-ab46-e5d8ef6efd69} = s ' DMO Sample Class'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
val MERIT = d '0'
}
}
}

View File

@@ -0,0 +1,12 @@
// stdafx.cpp : source file that includes just the standard includes
// stdafx.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#include <statreg.cpp>
#endif
#include <atlimpl.cpp>

View File

@@ -0,0 +1,34 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__9C2D1EC0_3838_4746_AD1D_EB6E217364A3__INCLUDED_)
#define AFX_STDAFX_H__9C2D1EC0_3838_4746_AD1D_EB6E217364A3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_FREE_THREADED
#define _ATL_STATIC_REGISTRY
#pragma warning(disable:4701) // Disable C4701
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__9C2D1EC0_3838_4746_AD1D_EB6E217364A3__INCLUDED)

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// File: DMOSample.cpp
//
// Desc: DirectShow sample code - implementation of DLL exports.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "stdafx.h"
#define FIX_LOCK_NAME
#include <dmo.h>
#include <dmoimpl.h>
#include "resource.h"
#include <initguid.h>
#include <limits.h>
#include "state.h"
#include "Sample.h"
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Sample, CSample)
END_OBJECT_MAP()
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE; // ok
}
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
{
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
// Register ourselves as a DMO with no types
// RGS file also registers with a merit of 0 so DShow won't try to use us
DMORegister(L"DMO Sample",
CLSID_Sample,
DMOCATEGORY_VIDEO_DECODER,
0,
0,
NULL,
0,
NULL);
// registers object
return _Module.RegisterServer();
}
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
DMOUnregister(CLSID_Sample, DMOCATEGORY_VIDEO_DECODER);
return _Module.UnregisterServer();
}

View File

@@ -0,0 +1,9 @@
; dmosample.def : Declares the module parameters.
LIBRARY "dmosample.DLL"
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

View File

@@ -0,0 +1,46 @@
#include <activex.ver>
#include "resource.h"
#include "winres.h"
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
/////////////////////////////////////////////////////////////////////////////
//
// REGISTRY
//
//==========================================================================;
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All Rights Reserved.
//
//--------------------------------------------------------------------------;
IDR_SAMPLE REGISTRY DISCARDABLE "Sample.rgs"
//
// Version Info
//
#define VERSION_RES_BIN_NAME "DMOSample.dll\0"
#define VERSION_RES_BIN_DESCRIPTION "DMO Sample Filter (Sample)\0"
#define AMOVIE_SELF_REGISTER
#include <activex.rcv>

View File

@@ -0,0 +1,18 @@
DirectShow Sample -- DMOSample
------------------------------
DMO Sample is a sample Microsoft DirectX Media Object (DMO). It takes MPEG-1
video packets as input and produces two output streams. The first output stream
contains video frames in RGB 565 format. Each frame displays the time code
taken from the MPEG-1 video, and is otherwise blank. The second output stream
is an optional text stream with the time code.
DMO Sample uses the IMediaObjectImpl base-class template to implement the
IMediaObject interface. For information about using this template, see
"Using the DMO Base Class" in the DirectX 8 SDK documentation.
The Active Template Library (ATL) handles various COM details, including
registration, aggregation, IUnknown, and the DLL entry points.
For more information about this sample, see "DirectShow Samples" in the
DirectX 8 SDK documentation.

View File

@@ -0,0 +1,3 @@
#define IDR_SAMPLE 101

View File

@@ -0,0 +1,395 @@
//------------------------------------------------------------------------------
// File: Sample.cpp
//
// Desc: DirectShow sample code - implementation of CSample class.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "stdafx.h"
#define FIX_LOCK_NAME
#include <dmo.h>
#include <limits.h> // _I64_MAX
#include <crtdbg.h>
#include <dmoimpl.h>
#include <uuids.h> // DirectShow media type guids
#include <amvideo.h> // VIDEOINFOHEADER definition
#include "resource.h"
#include "state.h"
#include "Sample.h"
#include "util.h" // Helpers
#pragma warning(disable:4100) // Disable C4100: unreferenced formal parameter
HRESULT CSample::InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags)
{
// We can process data on any boundary
*pdwFlags = 0;
return S_OK;
}
HRESULT CSample::InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags)
{
// We output single frames
if (0 == dwOutputStreamIndex) {
*pdwFlags = DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE;
} else {
// Stream 1
// Just text, no special buffering but 1 sample per sample
*pdwFlags = DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
DMO_OUTPUT_STREAMF_OPTIONAL;
}
return S_OK;
}
HRESULT CSample::InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
// Check if the type is already set and if so reject any type that's not identical
if (InputTypeSet(dwInputStreamIndex)) {
if (!TypesMatch(pmt, InputType(dwInputStreamIndex))) {
return DMO_E_INVALIDTYPE;
} else {
return S_OK;
}
}
// We accept MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Video
// Check the format is defined
if (pmt->majortype == MEDIATYPE_Video &&
pmt->subtype == MEDIASUBTYPE_MPEG1Payload &&
pmt->formattype == FORMAT_MPEGVideo &&
pmt->pbFormat != NULL) {
return S_OK;
} else {
return DMO_E_INVALIDTYPE;
}
}
HRESULT CSample::InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
// Check if the type is already set and if so reject any type that's not identical
if (OutputTypeSet(dwOutputStreamIndex)) {
if (!TypesMatch(pmt, OutputType(dwOutputStreamIndex))) {
return DMO_E_INVALIDTYPE;
} else {
return S_OK;
}
}
// We output frames on stream 1
if (dwOutputStreamIndex == 0) {
if (!InputTypeSet(0)) {
return DMO_E_INVALIDTYPE;
}
if (pmt->majortype == MEDIATYPE_Video &&
pmt->subtype == MEDIASUBTYPE_RGB565 &&
pmt->formattype == FORMAT_VideoInfo &&
pmt->pbFormat != NULL) {
const VIDEOINFOHEADER *pvihInput = (const VIDEOINFOHEADER *)InputType(0)->pbFormat;
const VIDEOINFOHEADER *pvihOutput = (const VIDEOINFOHEADER *)pmt->pbFormat;
LONG lWidth, lHeight;
if (IsRectEmpty(&pvihOutput->rcTarget)) {
lWidth = pvihOutput->bmiHeader.biWidth;
lHeight = pvihOutput->bmiHeader.biHeight;
} else {
lWidth = pvihOutput->rcTarget.right - pvihOutput->rcTarget.left;
lHeight = pvihOutput->rcTarget.bottom - pvihOutput->rcTarget.top;
}
if (pvihInput->bmiHeader.biWidth == lWidth &&
pvihInput->bmiHeader.biHeight == lHeight) {
return S_OK;
}
}
return DMO_E_INVALIDTYPE;
} else {
// Stream 1
if (pmt->majortype == MEDIATYPE_Text && pmt->subtype == GUID_NULL) {
return S_OK;
} else {
return DMO_E_INVALIDTYPE;
}
}
}
HRESULT CSample::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
DMO_MEDIA_TYPE *pmt)
{
// No types to all indices for dwTypeIndex are out of range.
return DMO_E_NO_MORE_ITEMS;
}
HRESULT CSample::InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
DMO_MEDIA_TYPE *pmt)
{
if (!InputTypeSet(0)) {
return DMO_E_TYPE_NOT_SET;
}
if (dwTypeIndex != 0) {
return DMO_E_NO_MORE_ITEMS;
}
// If GetOutputType()'s pmt parameter is NULL, return S_OK if the type exists.
// Return DMO_E_NO_MORE_ITEMS if the type does not exists. See the
// documentation for IMediaObject::GetOutputType() for more information.
if (NULL != pmt) {
if (dwOutputStreamIndex == 0) {
// Create our media type
HRESULT hr = MoInitMediaType(pmt, FIELD_OFFSET(VIDEOINFO, dwBitMasks[3]));
if (FAILED(hr)) {
return hr;
}
const VIDEOINFOHEADER *pvihInput = (const VIDEOINFOHEADER *)InputType(0)->pbFormat;
LONG lWidth = pvihInput->bmiHeader.biWidth;
LONG lHeight = pvihInput->bmiHeader.biHeight;
// Initialize the media type structure (MoInitMediaType initalized cbFormat
// and pbFormat)
pmt->majortype = MEDIATYPE_Video;
pmt->subtype = MEDIASUBTYPE_RGB565;
pmt->bFixedSizeSamples = TRUE;
pmt->bTemporalCompression = FALSE;
pmt->lSampleSize = lWidth * lHeight * 2;
pmt->formattype = FORMAT_VideoInfo;
pmt->pUnk = NULL;
// Initialize the format
VIDEOINFO *pviOutput = (VIDEOINFO *)pmt->pbFormat;
ZeroMemory(pviOutput, FIELD_OFFSET(VIDEOINFO, dwBitMasks[3]));
pviOutput->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pviOutput->bmiHeader.biCompression = BI_BITFIELDS;
pviOutput->bmiHeader.biBitCount = 16;
pviOutput->bmiHeader.biPlanes = 1;
pviOutput->bmiHeader.biWidth = lWidth;
pviOutput->bmiHeader.biHeight = lHeight;
pviOutput->bmiHeader.biSizeImage = pmt->lSampleSize;
pviOutput->TrueColorInfo.dwBitMasks[0] = 0xF800;
pviOutput->TrueColorInfo.dwBitMasks[1] = 0x07E0;
pviOutput->TrueColorInfo.dwBitMasks[2] = 0x001F;
pviOutput->AvgTimePerFrame = pvihInput->AvgTimePerFrame;
} else {
ZeroMemory(pmt, sizeof(*pmt));
pmt->majortype = MEDIATYPE_Text;
}
}
return S_OK;
}
HRESULT CSample::InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
DWORD *pcbMaxLookahead, DWORD *pcbAlignment)
{
*pcbSize = 1;
*pcbMaxLookahead = 0;
*pcbAlignment = 1;
return S_OK;
}
HRESULT CSample::InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
DWORD *pcbAlignment)
{
*pcbAlignment = 1;
if (dwOutputStreamIndex == 0) {
*pcbSize = OutputType(0)->lSampleSize;
return S_OK;
} else {
*pcbSize = sizeof(L"hh:mm:ss:ff"); // hh:mm:ss:ff
return S_OK;
}
}
HRESULT CSample::InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency)
{
return E_NOTIMPL;
}
HRESULT CSample::InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency)
{
return E_NOTIMPL;
}
HRESULT CSample::InternalFlush()
{
InternalDiscontinuity(0);
// Release buffer
m_pBuffer = NULL;
return S_OK;
}
HRESULT CSample::InternalDiscontinuity(DWORD dwInputStreamIndex)
{
// Zero our timestamp
m_rtFrame = 0;
// No pictures yet
m_bPicture = false;
// Reset state machine
m_StreamState.Reset();
return S_OK;
}
HRESULT CSample::InternalAllocateStreamingResources()
{
// Reinitialize variables
InternalDiscontinuity(0);
// Allocate our bitmap
return S_OK;
}
HRESULT CSample::InternalFreeStreamingResources()
{
return S_OK;
}
HRESULT CSample::InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
DWORD dwFlags, REFERENCE_TIME rtTimestamp,
REFERENCE_TIME rtTimelength)
{
// Check parameters
_ASSERTE(m_pBuffer == NULL);
HRESULT hr = pBuffer->GetBufferAndLength(&m_pbData, &m_cbData);
if (FAILED(hr)) {
return hr;
}
m_pBuffer = pBuffer;
if (0 == (dwFlags & DMO_INPUT_DATA_BUFFERF_TIME)) {
rtTimestamp = INVALID_TIME;
}
m_StreamState.TimeStamp(rtTimestamp);
// Process() returns S_FALSE if there is no output, S_OK otherwise
hr = Process();
return hr;
}
HRESULT CSample::InternalProcessOutput(DWORD dwFlags,
DWORD cOutputBufferCount,
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
DWORD *pdwStatus)
{
// Check buffer
PBYTE pbData;
DWORD cbData;
DWORD cbCurrent;
// Do we have any output?
if (!m_bPicture) {
return S_FALSE;
}
HRESULT hr = pOutputBuffers[0].pBuffer->GetBufferAndLength(
&pbData, &cbCurrent);
if (FAILED(hr)) {
return hr;
}
hr = pOutputBuffers[0].pBuffer->GetMaxLength(&cbData);
if (FAILED(hr)) {
return hr;
}
if (cbData < cbCurrent + (DWORD)OutputType(0)->lSampleSize) {
return E_INVALIDARG;
}
// Say we've filled the buffer
hr = pOutputBuffers[0].pBuffer->SetLength(cbCurrent + (DWORD)OutputType(0)->lSampleSize);
cbData -= cbCurrent;
pbData += cbCurrent;
// Generate our data
DWORD dwTimeCode;
REFERENCE_TIME rt = m_StreamState.PictureTime(&dwTimeCode);
TCHAR szBuffer[20];
wsprintf(szBuffer, TEXT("%2.2d:%2.2d:%2.2d:%2.2d"),
(dwTimeCode >> 19) & 0x1F,
(dwTimeCode >> 13) & 0x3F,
(dwTimeCode >> 6) & 0x3F,
dwTimeCode & 0x3F);
// Update our bitmap with turquoise
OurFillRect((const VIDEOINFOHEADER *)OutputType(0)->pbFormat, pbData, 0x03EF);
// Draw our text
DrawOurText((const VIDEOINFOHEADER *)OutputType(0)->pbFormat, pbData, szBuffer);
pOutputBuffers[0].dwStatus = DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT;
// Set the timestamp
if (rt != INVALID_TIME) {
pOutputBuffers[0].rtTimestamp = rt;
} else {
pOutputBuffers[0].rtTimestamp = m_rtFrame;
}
REFERENCE_TIME rtLength = ((const VIDEOINFOHEADER *)OutputType(0)->pbFormat)->AvgTimePerFrame;
pOutputBuffers[0].rtTimelength = rtLength;
m_rtFrame = pOutputBuffers[0].rtTimestamp + rtLength;
// Uncompressed video must always have a timestamp
pOutputBuffers[0].dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIME | DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH;
// Update our state
m_bPicture = false;
// Is there any more data to output at this point?
if (S_OK == Process()) {
pOutputBuffers[0].dwStatus = DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
}
// Is there an output buffer for stream 1?
if (pOutputBuffers[1].pBuffer) {
PBYTE pbData;
DWORD cbLength;
DWORD cbMax;
DWORD dwLen = lstrlen(szBuffer) * sizeof(WCHAR);
if (S_OK == pOutputBuffers[1].pBuffer->GetBufferAndLength(&pbData, &cbLength) &&
S_OK == pOutputBuffers[1].pBuffer->GetMaxLength(&cbMax) &&
cbLength + dwLen <= cbMax) {
// Convert to UNICODE!
USES_CONVERSION;
LPWSTR lpsz = T2W(szBuffer);
CopyMemory(pbData + cbLength, lpsz, dwLen);
pOutputBuffers[1].pBuffer->SetLength(cbLength + dwLen);
pOutputBuffers[1].dwStatus = pOutputBuffers[0].dwStatus;
pOutputBuffers[1].rtTimestamp = pOutputBuffers[0].rtTimestamp;
pOutputBuffers[1].rtTimelength = rtLength;
}
}
return S_OK;
}
HRESULT CSample::InternalAcceptingInput(DWORD dwInputStreamIndex)
{
return m_pBuffer == NULL ? S_OK : S_FALSE;
}
// Scan input data until either we're exhausted or we find
// a picture start code
// Note GOP time codes as we encounter them so we can
// output time codes
HRESULT CSample::Process()
{
// Process bytes and update our state machine
while (m_cbData && !m_bPicture) {
m_bPicture = m_StreamState.NextByte(*m_pbData);
m_cbData--;
m_pbData++;
}
// Release buffer if we're done with it
if (m_cbData == 0) {
m_pBuffer = NULL;
}
// assert that if have no picture to output then we ate all the data
_ASSERTE(m_bPicture || m_cbData == 0);
return m_bPicture ? S_OK : S_FALSE;
}

View File

@@ -0,0 +1,149 @@
# Microsoft Developer Studio Project File - Name="dmosample" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=dmosample - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "sample.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "sample.mak" CFG="dmosample - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "dmosample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "dmosample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "dmosample - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /i "..\..\BaseClasses" /d "NDEBUG" /d "WIN32"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /map /machine:I386 /def:"dmosample.def" /out:"Release\dmosample.dll" /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "dmosample - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /i "..\..\BaseClasses" /d "_DEBUG" /d "WIN32"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /debug /machine:I386 /def:"dmosample.def" /out:"Debug\dmosample.dll" /pdbtype:sept /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "dmosample - Win32 Release"
# Name "dmosample - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\dmosample.cpp
# End Source File
# Begin Source File
SOURCE=.\sample.cpp
# End Source File
# Begin Source File
SOURCE=.\state.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# End Source File
# Begin Source File
SOURCE=.\util.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\Sample.h
# End Source File
# Begin Source File
SOURCE=.\State.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\util.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\dmosample.rc
# End Source File
# Begin Source File
SOURCE=.\Sample.rgs
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "sample"=.\sample.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,242 @@
# Microsoft Developer Studio Generated NMAKE File, Based on sample.dsp
!IF "$(CFG)" == ""
CFG=dmosample - Win32 Debug
!MESSAGE No configuration specified. Defaulting to dmosample - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "dmosample - Win32 Release" && "$(CFG)" != "dmosample - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "sample.mak" CFG="dmosample - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "dmosample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "dmosample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
!IF "$(CFG)" == "dmosample - Win32 Release"
OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros
ALL : "$(OUTDIR)\dmosample.dll"
CLEAN :
-@erase "$(INTDIR)\dmosample.obj"
-@erase "$(INTDIR)\dmosample.res"
-@erase "$(INTDIR)\sample.obj"
-@erase "$(INTDIR)\state.obj"
-@erase "$(INTDIR)\StdAfx.obj"
-@erase "$(INTDIR)\util.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(OUTDIR)\dmosample.dll"
-@erase "$(OUTDIR)\dmosample.exp"
-@erase "$(OUTDIR)\dmosample.lib"
-@erase "$(OUTDIR)\dmosample.map"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /Fp"$(INTDIR)\sample.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dmosample.res" /i "..\..\BaseClasses" /d "NDEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\dmosample.pdb" /map:"$(INTDIR)\dmosample.map" /machine:I386 /def:"dmosample.def" /out:"$(OUTDIR)\dmosample.dll" /implib:"$(OUTDIR)\dmosample.lib" /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
LINK32_OBJS= \
"$(INTDIR)\dmosample.obj" \
"$(INTDIR)\sample.obj" \
"$(INTDIR)\state.obj" \
"$(INTDIR)\StdAfx.obj" \
"$(INTDIR)\util.obj" \
"$(INTDIR)\dmosample.res"
"$(OUTDIR)\dmosample.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "dmosample - Win32 Debug"
OUTDIR=.\Debug
INTDIR=.\Debug
# Begin Custom Macros
OutDir=.\Debug
# End Custom Macros
ALL : "$(OUTDIR)\dmosample.dll"
CLEAN :
-@erase "$(INTDIR)\dmosample.obj"
-@erase "$(INTDIR)\dmosample.res"
-@erase "$(INTDIR)\sample.obj"
-@erase "$(INTDIR)\state.obj"
-@erase "$(INTDIR)\StdAfx.obj"
-@erase "$(INTDIR)\util.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(OUTDIR)\dmosample.dll"
-@erase "$(OUTDIR)\dmosample.exp"
-@erase "$(OUTDIR)\dmosample.ilk"
-@erase "$(OUTDIR)\dmosample.lib"
-@erase "$(OUTDIR)\dmosample.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /Fp"$(INTDIR)\sample.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dmosample.res" /i "..\..\BaseClasses" /d "_DEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\dmosample.pdb" /debug /machine:I386 /def:"dmosample.def" /out:"$(OUTDIR)\dmosample.dll" /implib:"$(OUTDIR)\dmosample.lib" /pdbtype:sept /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
LINK32_OBJS= \
"$(INTDIR)\dmosample.obj" \
"$(INTDIR)\sample.obj" \
"$(INTDIR)\state.obj" \
"$(INTDIR)\StdAfx.obj" \
"$(INTDIR)\util.obj" \
"$(INTDIR)\dmosample.res"
"$(OUTDIR)\dmosample.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
!IF "$(NO_EXTERNAL_DEPS)" != "1"
!IF EXISTS("sample.dep")
!INCLUDE "sample.dep"
!ELSE
!MESSAGE Warning: cannot find "sample.dep"
!ENDIF
!ENDIF
!IF "$(CFG)" == "dmosample - Win32 Release" || "$(CFG)" == "dmosample - Win32 Debug"
SOURCE=.\dmosample.cpp
"$(INTDIR)\dmosample.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\sample.cpp
"$(INTDIR)\sample.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\state.cpp
"$(INTDIR)\state.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\StdAfx.cpp
"$(INTDIR)\StdAfx.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\util.cpp
"$(INTDIR)\util.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\dmosample.rc
"$(INTDIR)\dmosample.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
!ENDIF

View File

@@ -0,0 +1,137 @@
//------------------------------------------------------------------------------
// File: State.cpp
//
// Desc: DirectShow sample code - implementation of CStreamState class.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "stdafx.h"
#include <limits.h> // _I64_MAX
#include <crtdbg.h>
#include <dmo.h>
#include "state.h"
void CStreamState::TimeStamp(REFERENCE_TIME rt)
{
DWORD dwIndex = m_cbBytes >= 4 ? 0 : m_cbBytes;
m_arTS[dwIndex].bValid = true;
m_arTS[dwIndex].rt = rt;
}
void CStreamState::Reset()
{
m_cbBytes = 0;
m_dwNextTimeCode = 0;
for (int i = 0; i < 4; i++) {
m_arTS[i].bValid = false;
}
}
bool CStreamState::NextByte(BYTE bData)
{
_ASSERTE(m_arTS[0].bValid);
switch (m_cbBytes) {
case 0:
if (bData == 0) {
m_cbBytes++;
}
return false;
case 1:
if (bData == 0) {
m_cbBytes++;
} else {
m_cbBytes = 0;
// Pick up new timestamp if there was one
if (m_arTS[1].bValid) {
m_arTS[0].rt = m_arTS[1].rt;
m_arTS[1].bValid = false;
}
}
return false;
case 2:
if (bData == 1) {
m_cbBytes++;
} else {
if (bData == 0) {
if (m_arTS[1].bValid) {
m_arTS[0].rt = m_arTS[1].rt;
m_arTS[1].bValid = false;
}
if (m_arTS[2].bValid) {
m_arTS[1] = m_arTS[2];
m_arTS[2].bValid = false;
}
} else {
// Not 0 or 1, revert
m_cbBytes = 0;
// and pick up latest timestamp
if (m_arTS[1].bValid) {
m_arTS[0].rt = m_arTS[1].rt;
m_arTS[1].bValid = false;
}
if (m_arTS[2].bValid) {
m_arTS[0].rt = m_arTS[2].rt;
m_arTS[2].bValid = false;
}
}
}
return false;
case 3:
{
// It's a start code whatever it is
// return the timestamp and reset everything
m_rt = m_arTS[0].rt;
// If it's a picture start code can't use this timestamp again.
if (0 == bData) {
m_arTS[0].rt = INVALID_TIME;
m_cbBytes = 0;
}
// Catch up and clean out timestamps
for (int i = 1; i < 4; i++) {
if (m_arTS[i].bValid) {
m_arTS[0].rt = m_arTS[i].rt;
m_arTS[i].bValid = false;
}
}
// Picture start code?
if (0 == bData) {
m_cbBytes = 0;
m_dwTimeCode = m_dwNextTimeCode;
m_dwNextTimeCode++;
return true;
} else {
// Is it a GOP start code?
if (bData == 0xb8) {
m_cbBytes++;
} else {
m_cbBytes = 0;
}
return false;
}
}
case 4:
case 5:
case 6:
case 7:
m_bGOPData[m_cbBytes - 4] = bData;
m_cbBytes++;
if (m_cbBytes == 8) {
m_cbBytes = 0;
m_dwNextTimeCode = ((DWORD)m_bGOPData[0] << 17) +
((DWORD)m_bGOPData[1] << 9) +
((DWORD)m_bGOPData[2] << 1) +
((DWORD)m_bGOPData[3] >> 7);
}
return false;
}
// Should never reach here
return false;
};

View File

@@ -0,0 +1,57 @@
//------------------------------------------------------------------------------
// File: State.h
//
// Desc: DirectShow sample code - definition of CStreamState class.
// Provides state machine for picture start codes and timestamps.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// We need to know:
//
// - The time stamp to associate with a picture start code
// - The next time stamp
//
// State:
//
// m_cbBytes - number of valid bytes of start code so far
// m_arTS[4] - array of all the timestamps
// m_cbBytes+1 entries are valid
// Not really invalid but unlikely enough for sample code.
static const REFERENCE_TIME INVALID_TIME = _I64_MAX;
class CStreamState
{
private:
DWORD m_cbBytes;
struct {
bool bValid;
REFERENCE_TIME rt;
} m_arTS[4];
REFERENCE_TIME m_rt;
BYTE m_bGOPData[4];
DWORD m_dwTimeCode;
DWORD m_dwNextTimeCode;
public:
CStreamState()
{
Reset();
}
// Returns true if a start code was identifed
bool NextByte(BYTE bData);
void TimeStamp(REFERENCE_TIME rt);
REFERENCE_TIME PictureTime(DWORD *pdwTimeCode) const
{
*pdwTimeCode = m_dwTimeCode;
return m_rt;
}
void Reset();
};

View File

@@ -0,0 +1,201 @@
//------------------------------------------------------------------------------
// File: Util.cpp
//
// Desc: DirectShow sample code - implementation of utility routines.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "stdafx.h"
#include "dmo.h"
#include "amvideo.h"
#include "util.h"
// Helper to get the important info out of VIDEOINFOHEADER
void GetVideoInfoParameters(
const VIDEOINFOHEADER *pvih,
PBYTE pbData,
DWORD *pdwWidth,
DWORD *pdwHeight,
LONG *plStrideInBytes, // Add this on to a pointer to a row to get the new row down
BYTE **ppbTop // Return position of first byte of top row of pixels
)
{
LONG lStride;
// biWidth is the stride in pixels for 'normal formats'
// Expand to bytes and round up to a multiple of 4
if (pvih->bmiHeader.biBitCount != 0 &&
0 == (7 & pvih->bmiHeader.biBitCount)) {
lStride = (pvih->bmiHeader.biWidth * (pvih->bmiHeader.biBitCount / 8) + 3) & ~3;
} else {
lStride = pvih->bmiHeader.biWidth;
}
// If rcTarget is empty it means 'the whole image'
if (IsRectEmpty(&pvih->rcTarget)) {
*pdwWidth = (DWORD)pvih->bmiHeader.biWidth;
*pdwHeight = (DWORD)(abs(pvih->bmiHeader.biHeight));
if (pvih->bmiHeader.biHeight < 0) {
*plStrideInBytes = lStride;
*ppbTop = pbData;
} else {
*plStrideInBytes = -lStride;
*ppbTop = pbData + lStride * (*pdwHeight - 1);
}
} else {
*pdwWidth = (DWORD)(pvih->rcTarget.right - pvih->rcTarget.left);
*pdwHeight = (DWORD)(pvih->rcTarget.bottom - pvih->rcTarget.top);
if (pvih->bmiHeader.biHeight < 0) {
*plStrideInBytes = lStride;
*ppbTop = pbData +
lStride * pvih->rcTarget.top +
(pvih->bmiHeader.biBitCount * pvih->rcTarget.left) / 8;
} else {
*plStrideInBytes = -lStride;
*ppbTop = pbData +
lStride * (pvih->bmiHeader.biHeight - pvih->rcTarget.top - 1) +
(pvih->bmiHeader.biBitCount * pvih->rcTarget.left) / 8;
}
}
}
// stuff to draw string
PBYTE TextBitmap(LPCTSTR lpsz, SIZE *pSize)
{
HDC hdc = CreateCompatibleDC(NULL);
if (NULL == hdc) {
return NULL;
}
if (!GetTextExtentPoint32(hdc, lpsz, lstrlen(lpsz), pSize))
{
return NULL;
}
// Create our bitmap
struct {
BITMAPINFOHEADER bmiHeader;
DWORD rgbEntries[2];
} bmi =
{
{
sizeof(BITMAPINFOHEADER),
pSize->cx,
pSize->cy,
1,
1,
BI_RGB,
0,
0,
0
},
{
0x00000000,
0xFFFFFFFF
}
};
HBITMAP hbm = CreateDIBitmap(hdc, &bmi.bmiHeader, 0, NULL, NULL, 0);
if (NULL == hbm) {
DeleteDC(hdc);
return NULL;
}
HGDIOBJ hobj = SelectObject(hdc, hbm);
if (NULL == hobj) {
DeleteObject(hbm);
DeleteDC(hdc);
return NULL;
}
PBYTE pbReturn = NULL;
BOOL bResult = ExtTextOut(hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, NULL, lpsz,
lstrlen(lpsz), NULL);
SelectObject(hdc, hobj);
LONG lLines;
if (bResult) {
LONG lWidthInBytes = ((pSize->cx + 31) >> 3) & ~3;
pbReturn = new BYTE[lWidthInBytes * pSize->cy];
if (pbReturn) {
ZeroMemory(pbReturn, lWidthInBytes * pSize->cy);
lLines = GetDIBits(hdc, hbm, 0, pSize->cy, (PVOID)pbReturn, (BITMAPINFO *)&bmi, DIB_RGB_COLORS);
}
}
DeleteObject(hbm);
DeleteDC(hdc);
return pbReturn;
}
// Helper to fill memory
void OurFillRect(const VIDEOINFOHEADER *pvih, PBYTE pbData, WORD wVal)
{
DWORD dwWidth, dwHeight;
LONG lStrideInBytes;
PBYTE pbTop;
GetVideoInfoParameters(pvih, pbData, &dwWidth, &dwHeight, &lStrideInBytes, &pbTop);
PBYTE pbPixels = pbTop;
// For just filling we don't care which way up the bitmap is - we just start at pbData
for (DWORD dwCount = 0; dwCount < dwHeight; dwCount++) {
WORD *pWord = (WORD *)pbPixels;
for (DWORD dwPixel = 0; dwPixel < dwWidth; dwPixel++) {
pWord[dwPixel] = wVal;
}
// biWidth is the stride
pbPixels += lStrideInBytes;
}
}
// Helper to get some text into memory (note we're ignoring errors!)
void DrawOurText(const VIDEOINFOHEADER * pvih, PBYTE pbData, LPCTSTR szBuffer)
{
// Copy the data into our real buffer (top lhs)
DWORD dwWidthTarget, dwHeightTarget;
LONG lStrideInBytesTarget;
PBYTE pbTarget;
SIZE size;
// Get a bit map representing our bits
PBYTE pbBits = TextBitmap(szBuffer, &size);
if (NULL == pbBits) {
return;
}
GetVideoInfoParameters(pvih, pbData, &dwWidthTarget, &dwHeightTarget, &lStrideInBytesTarget, &pbTarget);
// Now copy the data from the DIB section (which is bottom up)
// but first check if it's too big
if (dwWidthTarget >= (DWORD)size.cx && dwHeightTarget > (DWORD)size.cy && size.cx > 0 && size.cy > 0) {
// PBYTE pbSource = (PBYTE)pbBits;
DWORD dwSourceStride = ((size.cx + 31) >> 3) & ~3;
for (DWORD dwY = 0; dwY < (DWORD)size.cy; dwY++) {
WORD *pwTarget = (WORD *)pbTarget;
PBYTE pbSource = pbBits + dwSourceStride * ((DWORD)size.cy - dwY - 1);
for (DWORD dwX = 0; dwX < (DWORD)size.cx; dwX++) {
if ( !((0x80 >> (dwX & 7)) & pbSource[dwX >> 3]) ) {
pwTarget[dwX] = 0x0000; // Black
}
}
pbTarget += lStrideInBytesTarget;
}
}
delete [] pbBits;
}
// Helper - compares media types - ignoring the advisory fields
bool TypesMatch(const DMO_MEDIA_TYPE *pmt1, const DMO_MEDIA_TYPE *pmt2)
{
if (pmt1->majortype == pmt2->majortype &&
pmt1->subtype == pmt2->subtype &&
pmt1->lSampleSize == pmt2->lSampleSize &&
pmt1->formattype == pmt2->formattype &&
pmt1->cbFormat == pmt2->cbFormat &&
0 == memcmp(pmt1->pbFormat, pmt2->pbFormat, pmt1->cbFormat)) {
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// File: Util.h
//
// Desc: DirectShow sample code - prototypes of utility routines.
//
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
void GetVideoInfoParameters(
const VIDEOINFOHEADER *pvih,
PBYTE pbData,
DWORD *pdwWidth,
DWORD *pdwHeight,
LONG *plStrideInBytes,
BYTE **ppbTop
);
void OurFillRect(const VIDEOINFOHEADER *pvih, PBYTE pbData, WORD wVal);
void DrawOurText(const VIDEOINFOHEADER * pvih, PBYTE pbData, LPCTSTR szBuffer);
PBYTE TextBitmap(LPCTSTR lpsz, SIZE *pSize);
// Helper
bool TypesMatch(const DMO_MEDIA_TYPE *pmt1, const DMO_MEDIA_TYPE *pmt2);