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>
258 lines
6.7 KiB
C++
258 lines
6.7 KiB
C++
//------------------------------------------------------------------------------
|
|
// File: SampGrabCB.cpp
|
|
//
|
|
// Desc: DirectShow sample code - C++ console application demonstrating
|
|
// use of the IMediaDet interface to create a graph that contains a
|
|
// sample grabber filter. It shows how to use the sample grabber
|
|
// and a COM object callback to display information about media
|
|
// samples in a running video file.
|
|
//
|
|
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
// Function prototypes
|
|
//
|
|
int GrabSamples( char * pFilename );
|
|
|
|
#ifdef UNICODE
|
|
#error This sample will not compile UNICODE.
|
|
#endif
|
|
|
|
// This semi-COM object is a callback COM object for the sample grabber
|
|
//
|
|
class CFakeCallback : public ISampleGrabberCB
|
|
{
|
|
public:
|
|
STDMETHODIMP_(ULONG) AddRef() { return 2; }
|
|
STDMETHODIMP_(ULONG) Release() { return 1; }
|
|
|
|
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
|
|
{
|
|
if (riid == IID_ISampleGrabberCB || riid == IID_IUnknown)
|
|
{
|
|
*ppv = (void *) static_cast<ISampleGrabberCB *>(this);
|
|
return NOERROR;
|
|
}
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
|
|
{
|
|
static long counter = 0;
|
|
printf( "Sample received = %05ld Clock = %ld\r\n",
|
|
counter++, timeGetTime( ) );
|
|
return 0;
|
|
}
|
|
|
|
STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferLen )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
if( argc != 2 )
|
|
{
|
|
printf( "Usage: SampGrabCB <filename>\r\n\r\n" );
|
|
printf( "This application reads a media file and receives callbacks for every\r\n"
|
|
"media sample processed. You must provide a valid filename.\r\n");
|
|
return -1;
|
|
}
|
|
|
|
// Initialize COM
|
|
CoInitialize( NULL );
|
|
|
|
// Run the test on the filename specified on the command line
|
|
GrabSamples( argv[1] );
|
|
|
|
// COM cleanup
|
|
CoUninitialize( );
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int GrabSamples( char * pFilename )
|
|
{
|
|
USES_CONVERSION;
|
|
|
|
CFakeCallback pCallback;
|
|
HRESULT hr;
|
|
|
|
printf("Grabbing samples from %s.\r\n", pFilename);
|
|
|
|
// create a media detector
|
|
//
|
|
CComPtr< IMediaDet > pDet;
|
|
hr = CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IMediaDet, (void**) &pDet );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed in CoCreateInstance! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// set filename
|
|
//
|
|
hr = pDet->put_Filename( T2W( pFilename ) );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "couldn't load the file! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// look for a video stream
|
|
//
|
|
long Streams = 0;
|
|
hr = pDet->get_OutputStreams( &Streams );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "couldn't get the output streams! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
BOOL bFoundVideo = FALSE;
|
|
|
|
for( int i = 0 ; i < Streams ; i++ )
|
|
{
|
|
BOOL bIsVideo = FALSE;
|
|
|
|
AM_MEDIA_TYPE Type;
|
|
memset( &Type, 0, sizeof( Type ) );
|
|
|
|
// Select a media stream
|
|
hr = pDet->put_CurrentStream( i );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "couldn't put stream %d hr=0x%x\r\n", i, hr );
|
|
return hr;
|
|
}
|
|
|
|
// Read the media type of the selected stream
|
|
hr = pDet->get_StreamMediaType( &Type );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "couldn't get stream media type for stream %d hr=0x%x\r\n",
|
|
i, hr );
|
|
return hr;
|
|
}
|
|
|
|
// Does this stream contain video?
|
|
if( Type.majortype == MEDIATYPE_Video )
|
|
bIsVideo = TRUE;
|
|
|
|
FreeMediaType( Type );
|
|
|
|
if( !bIsVideo )
|
|
continue;
|
|
|
|
// Found a video stream
|
|
bFoundVideo = TRUE;
|
|
break;
|
|
}
|
|
|
|
if( !bFoundVideo )
|
|
{
|
|
printf( "Couldn't find a video stream\r\n" );
|
|
return 0;
|
|
}
|
|
|
|
// this method will change the MediaDet to go into
|
|
// "sample grabbing mode" at time 0.
|
|
//
|
|
hr = pDet->EnterBitmapGrabMode( 0.0 );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed in EnterBitmapGrabMode! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// ask for the sample grabber filter that we know lives inside the
|
|
// graph made by the MediaDet
|
|
//
|
|
CComPtr< ISampleGrabber > pGrabber;
|
|
hr = pDet->GetSampleGrabber( &pGrabber );
|
|
if( FAILED(hr) || !pGrabber)
|
|
{
|
|
printf( "couldn't find the sample grabber filter! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// set the callback (our COM object callback)
|
|
//
|
|
CComQIPtr< ISampleGrabberCB, &IID_ISampleGrabberCB > pCB( &pCallback );
|
|
CComQIPtr< IBaseFilter, &IID_IBaseFilter > pFilter( pGrabber );
|
|
hr = pGrabber->SetCallback( pCB, 0 );
|
|
hr = pGrabber->SetOneShot( FALSE ); // don't do one-shot mode
|
|
hr = pGrabber->SetBufferSamples( FALSE ); // don't buffer samples
|
|
|
|
// find the filter graph interface from the sample grabber filter
|
|
//
|
|
FILTER_INFO fi;
|
|
memset( &fi, 0, sizeof( fi ) );
|
|
hr = pFilter->QueryFilterInfo( &fi );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed in QueryFilterInfo! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// Release the filter's graph reference
|
|
if( fi.pGraph )
|
|
fi.pGraph->Release( );
|
|
IFilterGraph * pGraph = fi.pGraph;
|
|
|
|
// The graph will have been paused by entering bitmap grab mode.
|
|
// We'll need to seek back to 0 to get it to deliver correctly.
|
|
//
|
|
CComQIPtr< IMediaSeeking, &IID_IMediaSeeking > pSeeking( pGraph );
|
|
REFERENCE_TIME Start = 0;
|
|
REFERENCE_TIME Duration = 0;
|
|
|
|
hr = pSeeking->GetDuration( &Duration );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed in GetDuration! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
hr = pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning,
|
|
&Duration, AM_SEEKING_AbsolutePositioning );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed in SetPositions! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// run the graph
|
|
//
|
|
CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
|
|
CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
|
|
hr = pControl->Run( );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed to run the graph! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
// wait
|
|
//
|
|
long EventCode = 0;
|
|
hr = pEvent->WaitForCompletion( INFINITE, &EventCode );
|
|
if( FAILED( hr ) )
|
|
{
|
|
printf( "Failed in WaitForCompletion! hr=0x%x\r\n", hr );
|
|
return hr;
|
|
}
|
|
|
|
printf("Sample grabbing complete.\r\n");
|
|
return 0;
|
|
}
|
|
|