grabbing with direct show

May 19, 2008 at 8:19pm
Hello everybody
I want to retreive a buffer from a camera playing,my parts of code are:

The function CaptureVideo() that must play the video and grab the buffer ( with GrabData( ) in the end of function) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
 
HRESULT CCaptureVideo::CaptureVideo()
{
 HRESULT hr;
 IBaseFilter *pSrcFilter=NULL;
// Get DirectShow interfaces
 hr = GetInterfaces();
 if (FAILED(hr))
    {
     DisplayMesg(TEXT("Failed to get video interfaces!  hr=0x%x"), hr);
     return hr;
    }
// Attach the filter graph to the capture graph
    hr = m_pCapture->SetFiltergraph(m_pGraph);
    if (FAILED(hr))
    {
     DisplayMesg(TEXT("Failed to set capture filter graph!  hr=0x%x"), hr);
     return hr;
    }
// Use the system device enumerator and class enumerator to find
// a video capture/preview device, such as a desktop USB video camera.
 hr = FindCaptureDevice(&pSrcFilter);
 if (FAILED(hr))
    {
      return hr;
    }
 if( bDevCheck == FALSE)
 {
  return E_FAIL;
 }
// Add Capture filter to our graph.
hr = m_pGraph->AddFilter(pSrcFilter, L"Video Capture");
  if (FAILED(hr))
    {
DisplayMesg(TEXT("Couldn't add the capture filter to the graph!  hr=0x%\n\r\n") 
            TEXT("If you have a working video capture device, please make sure\r\n")
            TEXT("that it is connected and is not being used by another application.\r\n\r\n"), hr);
        pSrcFilter->Release();
        return hr;
    }
// Create the Sample Grabber.
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
                                      IID_IBaseFilter, (void**) & pGrabberF);
if (FAILED(hr)) {
                return hr;
                }
hr = m_pGraph->AddFilter(pGrabberF, L"Sample Grabber");
        if (FAILED(hr)) {
                return hr;
                        }
pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);
if (FAILED(hr)) {
                return hr;
                }
 
hr = pGrabber->SetOneShot(FALSE);
hr = pGrabber->SetBufferSamples(TRUE);
hr = pSrcFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
ConfigRenderer();
// Add Renderer filter to our graph.
hr = m_pGraph->AddFilter(pVmr, L"VMR9");
// Render the preview pin on the video capture filter
// Use this instead of m_pGraph->RenderFile
hr = m_pCapture->RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
                                   pSrcFilter,pGrabberF, pVmr);
if (FAILED(hr))
    {
DisplayMesg(TEXT("Couldn't render the video capture stream.  hr=0x%x\r\n")
            TEXT("The capture device may already be in use by another application.\r\n\r\n")
            TEXT("The sample will now close."), hr);
        pSrcFilter->Release();
        return hr;
    }
hr = pGrabber->GetConnectedMediaType(&mt);
if (FAILED(hr)) {
                return hr;
        }
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER *)mt.pbFormat;
gChannels = pVih->bmiHeader.biBitCount / 8;
gWidth = pVih->bmiHeader.biWidth;
gHeight = pVih->bmiHeader.biHeight;
// Now that the filter has been added to the graph and we have
// rendered its stream, we can release this reference to the filter.
pSrcFilter->Release();

#ifdef REGISTER_FILTERGRAPH
// Add our graph to the running object table, which will allow
// the GraphEdit application to "spy" on our graph
hr = AddGraphToRot(m_pGraph, &m_dwGraphRegister);
    if (FAILED(hr))
    {
DisplayMesg(TEXT("Failed to register filter graph with ROT!  hr=0x%x"), hr);
        m_dwGraphRegister = 0;
    }
#endif
// Start previewing video data
hr = m_pMC->Run();
if (FAILED(hr))
    {
DisplayMesg(TEXT("Couldn't run the graph!  hr=0x%x"), hr);
return hr;
    }
// Remember current state
m_psCurrent = RUNNING;
 
FILE *stream;
buffer = new unsigned char[size];
for(int i=0;i<5;i++)
{
   Sleep(100);
   buffer = GrabData();
   if (buffer!=NULL)
   {
     stream=fopen("c:\somefile.txt","wb");
     fprintf(stream,"%s",buffer);
     fclose(stream);
   }
}

return S_OK;
}

The fonction GrabData() that must retreive the buffer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
unsigned char* CCaptureVideo::GrabData()
{
HRESULT hr;
if (pGrabber == 0)
    return 0;
long Size = 0;
hr = pGrabber->GetCurrentBuffer(&Size, NULL);
if (FAILED(hr))
      return 0;
else if (Size != pBufferSize) {
          pBufferSize = Size;
          if (pBuffer != 0)
               delete[] pBuffer;
               pBuffer = new unsigned char[pBufferSize];
        }
hr = pGrabber->GetCurrentBuffer(&pBufferSize, (long*)pBuffer);
if (FAILED(hr))
  {
    return 0;
  }
else {
    return pBuffer;                
     }
}

First of all i am sorry to post all at once, my problem is that the buffer retreived with the function GrabData() has not a fixed size,i am trying to write it to a text file and the number of character written varies considerably (between 12000 and 180000), but i think that it is not retreiving a buffer because the size should be fixe (weight * heigth * 3 (RGB) = 640 * 576 * 3)so i want to know whats wrong with my program and if my reasoning is correct???????

And note that my code didn't causes any errors but by insering breakpoints i am concluding this problem.

So if you can help me I will be really very grateful and thank you in advance.
Last edited on May 21, 2008 at 11:35am
Topic archived. No new replies allowed.