Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Implementing DirectShow IMediaDet Interface in Microsoft Vision SDK

Status
Not open for further replies.

AnnaWillson

Programmer
Apr 8, 2003
1
GB
Hi Guys,

I am writing some Machine Vision software in Visual C++ and am using a new SDK from Microsoft to do so. I would like to use some of the interfaces from Direct Show (in particular IMediaDet) so I can save a frame from an avi file. I am a newie to the dcom interface stuff!!!!!! I have got as far as Intialising com (whoopee) but am unsure how to get a reference to IMediaDet.

&quot;CComPtr<IMediaDet> pDet;
hr = pDet.CoCreateInstance(__uuidof(MediaDet));&quot;

returns error C2955: 'CComPtr' : use of class template requires template argument list (I am not an ATL programmer and am unsure where to put or use templates)

and this........
IMediaDet *ptr;
hr = CoCreateInstance(
CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
IID_IMediaDet, (void**)&ptr);
kinda makes more sense but of course IMediaDet is unrecognised. I know I am missing a step here...........can anyine let me know what it is or e-mail or post a basic example!

Ta very much
 
Some very messy Win32 IMediaDet code, hope this helps

// Win32Play.cpp : Defines the entry point for the application.
//
//***
//Had to comment out lines 666 (spooky!) and 807 in C:DXSDK\Include\mmstream.h!!!???
//Link with: strmiids.lib strmbase.lib
//***
#include &quot;stdafx.h&quot;
#include &quot;resource.h&quot;
#include <time.h>
#include <stdio.h>
#include <dshow.h>


// VMR Headers: for WINXP only!

#include <dshow.h>
#include <tchar.h>
#include <atlbase.h>
#include <Qedit.h>
#include <mtype.h>

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text

int m_FrameNumber = 0;
int FPSVAL = 100;
clock_t m_C0, m_C1;
unsigned char img[256][256][3];
BITMAPINFOHEADER bmih;
TCHAR szHello[256];
UINT mNFrames = 0;
IMediaDet *m_pDet = NULL;
int m_Width, m_Height;
UINT mFrameRateMS, mCurrentFrame = 0;
double mClipLength, mFrameRate;
char *m_pBuffer = NULL;
long mFrameDataSize = 0;
void *m_pRGBData = NULL;
BITMAPINFOHEADER* m_bmih = NULL;
BITMAPINFO m_bmi;
int winbm = 1, winbm2 = 1, vidgetf = 1, vidbm = 1;

// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);

void OnDraw(HWND pWnd, HDC pDC);
void DoTiming(TCHAR* str);
void SetupImage();
HRESULT InitializeMediaDet();
void FreeDirectShow();
HRESULT GetFrame();

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32PERF, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32PERF);

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return msg.wParam;
}



//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WIN32PERF);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_WIN32PERF;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, /*CW_USEDEFAULT*/1024, /*0*/800, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
//TCHAR szHello[MAX_LOADSTRING];
//LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

switch (message)
{
case WM_CREATE:
SetupImage();
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
InitializeMediaDet();
break;

case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
OnDraw(hWnd, hdc);
EndPaint(hWnd, &ps);
break;

case WM_KEYDOWN:
switch(wParam)
{
case '1':
(winbm)?(winbm=0):(winbm=1);
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case '2':
(winbm2)?(winbm2=0):(winbm2=1);
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case '3':
(vidbm)?(vidbm=0):(vidbm=1);
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case '4':
(vidgetf)?(vidgetf=0):(vidgetf=1);
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case 'Q':
case VK_ESCAPE:
DestroyWindow(hWnd);
return 0;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}

case WM_DESTROY:
FreeDirectShow();
// Finished with COM
CoUninitialize();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}

void OnDraw(HWND pWnd, HDC pDC)
{
RECT rt;
GetClientRect(pWnd, &rt);

if(winbm)
{
StretchDIBits(pDC,
100, 100, 256, 256,
0, 0, 256, 256,
img, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, SRCCOPY);
FPSVAL = 100;
}

if(winbm2)
{
StretchDIBits(pDC,
100, 400, 256, 256,
0, 0, 256, 256,
img, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, SRCCOPY);
FPSVAL = 100;
}
if(vidgetf)
{
GetFrame();
FPSVAL = 100;
}
if(vidbm)
{
StretchDIBits(pDC,
500, 100, m_Width, m_Height,
0, 0, m_bmi.bmiHeader.biWidth, m_bmi.bmiHeader.biHeight,
m_pRGBData, (BITMAPINFO*)&m_bmi.bmiHeader, DIB_RGB_COLORS, SRCCOPY);
FPSVAL = 100;
}

DoTiming(szHello);

DrawText(pDC, szHello, strlen(szHello), &rt, DT_LEFT);
InvalidateRect( pWnd, NULL, FALSE );
}

void DoTiming(TCHAR* str)
{
double m_FPS;

m_FrameNumber++;
if( m_FrameNumber > FPSVAL )
{
m_C1 = clock();
m_FPS = ( 1000.0 / ( (m_C1 - m_C0) * 1000.0 / CLOCKS_PER_SEC ) ) * m_FrameNumber;
m_FrameNumber = 0;
m_C0 = clock();
sprintf(str, &quot;%0.1f FPS &quot;, m_FPS);
if(m_FPS>2000)
{
FPSVAL = 2000;
}
else
{
FPSVAL = 100;
}
}
mCurrentFrame++;
if(mCurrentFrame==mNFrames)
mCurrentFrame = 0;
}

void SetupImage()
{
int i, j;

for(i=0;i<256;i++)
{
for(j=0;j<256;j++)
{
img[j][0] = 255;
img[j][1] = 0;
img[j][2] = 0;
}
}
memset(&bmih, 0, sizeof bmih);

bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biCompression = BI_RGB;
bmih.biWidth = 256;
bmih.biHeight = 256;
bmih.biPlanes = 1;
bmih.biBitCount = 24;

memset( szHello, 0, 256 );
}


/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
//ImediaDetector stuff:
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
HRESULT InitializeMediaDet()
{
HRESULT hr;
long lStreams;
bool bFound = false;


hr = CoCreateInstance(CLSID_MediaDet, NULL, CLSCTX_INPROC, IID_IMediaDet, (void**)&m_pDet);
if (FAILED(hr)){
return hr;
}

//CComBSTR bstrFileName(nVideoFileName);
//CComBSTR bstrFileName(&quot;C:\\users\\gibson\\AA_demo\\chet_orig.avi&quot;);
//CComBSTR bstrFileName(&quot;chet_orig.avi&quot;);
CComBSTR bstrFileName(&quot;C:\\Temp\\bigavi.avi&quot;);
//CComBSTR bstrFileName(&quot;C:\\users\\gibson\\AA_demo\\birds.avi&quot;);
//CComBSTR bstrFileName(&quot;C:\\users\\gibson\\AA_demo\\BCD0111_clips.avi&quot;);

hr = m_pDet->put_Filename(bstrFileName);
if (FAILED(hr)){
return hr;
}

hr = m_pDet->get_OutputStreams(&lStreams);
if (FAILED(hr)){
return hr;
}

for (long i = 0; i < lStreams; i++)
{
GUID major_type;
hr = m_pDet->put_CurrentStream(i);
if (SUCCEEDED(hr))
{
hr = m_pDet->get_StreamType(&major_type);
}
if (FAILED(hr)){
break;
}

if (major_type == MEDIATYPE_Video)
{
bFound = true;
break;
}
}
if (!bFound){
return VFW_E_INVALIDMEDIATYPE;
}

//long m_Width = 0, m_Height = 0;
AM_MEDIA_TYPE mt;

hr = m_pDet->get_StreamMediaType(&mt);

if (SUCCEEDED(hr))
{
if ((mt.formattype == FORMAT_VideoInfo) &&
(mt.cbFormat >= sizeof(VIDEOINFOHEADER)))
{
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)(mt.pbFormat);
m_Width = pVih->bmiHeader.biWidth;
m_Height = pVih->bmiHeader.biHeight;

// We want the absolute m_Height, don't care about orientation.
if (m_Height < 0) m_Height *= -1;
}
else
{
hr = VFW_E_INVALIDMEDIATYPE; // Should not happen, in theory.
}
FreeMediaType(mt);
}
if (FAILED(hr)){
return hr;
}

//Initialise all other stuff: could go in OnInitialUpdaet?
//mFrameRate = (UINT)GetFrameRate(); // Assume 25 fps
m_pDet->get_FrameRate(&mFrameRate);
mFrameRateMS = (UINT)(1000 / mFrameRate); // 40 milliseconds per frame
m_pDet->get_StreamLength(&mClipLength);

mNFrames = (UINT)( (mClipLength*1000) / mFrameRateMS ); // Number of frames
//m_IsKeyDown = FALSE;

//Set up the label data class
//GetDocument()->NewLabelData(int(mNFrames));

//m_CurrPlayState = Stopped; //Should be GetDocument()->m_PlayState;
//mPickState = PickLabel;
GetFrame();
return hr;
}

void FreeDirectShow()
{
if(m_pBuffer){
delete [] m_pBuffer;
}

if(m_pDet){
m_pDet->Release();
m_pDet = NULL;
}
}

//////////////////////////////////////////////////////////////////////////////////////////////////

HRESULT GetFrame()
{
// Find the required buffer size.
HRESULT hr = 1; //Only important if !mFrameDataSize, so make default 1
double frameno;

if(!mFrameDataSize){
hr = m_pDet->GetBitmapBits(0, &mFrameDataSize, NULL, m_Width, m_Height);
}

if (SUCCEEDED(hr))
{
if(!m_pBuffer){
m_pBuffer = new char[mFrameDataSize];
}
if (!m_pBuffer){
return E_OUTOFMEMORY;
}

frameno = ((double)mCurrentFrame * (double)mFrameRateMS) / 1000.0;
hr = m_pDet->GetBitmapBits(frameno, NULL, m_pBuffer, m_Width, m_Height);
if (SUCCEEDED(hr))
{
// Delete the old image, if any
m_pRGBData = m_pBuffer + sizeof(BITMAPINFOHEADER);
m_bmih = (BITMAPINFOHEADER*)m_pBuffer;
ZeroMemory(&m_bmi, sizeof(BITMAPINFO));
CopyMemory(&(m_bmi.bmiHeader), m_bmih, sizeof(BITMAPINFOHEADER));
}
else
{
delete [] m_pBuffer;
m_pBuffer = NULL;
return E_OUTOFMEMORY;
}
}
return hr;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top