weird webcam capture problem



I have an application that is behaving strangely. My application
captures video to a wmv file from a web cam. I have one user that
records wmv files that are black with no sound. You can see a filter
graph from this problem cam here
http://www.bowerstechnologies.com/problem.grf.

Here is the code that created that filter graph. Can you have a look
at this code and let me know if you see any problems that could be
causing this behavior? Thanks all,

David K. Bowers

HRESULT CCaptureGraph::RenderWmvCapture(const TCHAR* szFileName, int
cchFileName,
const TCHAR* szProfileFile, WCHAR* pwszAuthor,
WCHAR* pwszTitle, WCHAR* pwszRating,
WCHAR* pwszDescription, WCHAR* pwszCopyright)
{
if(m_bUseLog){
LogText("\r\nEntering CCaptureGraph::RenderWmvCapture()\r\n");
}

OutputDebugString(TEXT("RenderWmvCapture()\n"));

if (!m_pCap) return E_FAIL;
m_pControl->Stop();

HRESULT hr;
CComPtr<IBaseFilter> pMux;

// Build the Mux -> File Writer part of the graph.

// I'm using TCHAR strings for input but the API wants wide char
only

#ifdef _UNICODE
hr = m_pBuild->SetOutputFileName(&MEDIASUBTYPE_Asf, szFileName, &pMux,
0);
#else
WCHAR *wszFileName = NULL;
int i = AnsiToWide(szFileName, cchFileName + 1, &wszFileName);
if (!wszFileName)
{
return E_FAIL;
}

hr = m_pBuild->SetOutputFileName(&MEDIASUBTYPE_Asf, wszFileName,
&pMux, 0);
if(m_bUseLog){
char text[500];
sprintf(text, "SetOutputFileName returned %d for file name %s\r\n",
hr, wszFileName);
LogText(text);
}

delete [] wszFileName;
#endif

if (FAILED(hr))
{
return hr;
}

// Now configure the ASF Writer
// Present the property pages for this filter
//hr = ShowWmvFilterPropertyPages(pMux);

// newstuff begin
IConfigAsfWriter *pConfig = 0;
hr = pMux->QueryInterface(IID_IConfigAsfWriter, (void**)&pConfig);
if(m_bUseLog){
char text[500];
sprintf(text, "pMux->QueryInterface(IID_IConfigAsfWriter returned
%d\r\n", hr);
LogText(text);
}

if (SUCCEEDED(hr))
{
// Configure the ASF Writer filter.
// Configure the filter with the profile
CComPtr<IWMProfile> pProfile1;
BOOL fZeroSizedVidRect = FALSE;

// Load the data in the prx file into a WMProfile object
_TCHAR szProfile[_MAX_PATH] = {'\0'};
_tcscpy(szProfile, szProfileFile);
hr = LoadCustomProfile((LPCSTR)szProfile, &pProfile1,
/*out*/fZeroSizedVidRect);
if(m_bUseLog){
char text[500];
sprintf(text, "LoadCustomProfile returned %d for profile %s\r\n",
hr, szProfile);
LogText(text);
}

if(FAILED(hr))
{
//DbgLog((LOG_TRACE, 3, _T("Failed to load profile! hr=0x%x\n"),
hr));
return hr;
}

if(fZeroSizedVidRect)
{
//OutputMsg(_T("The profile has a zero-sized rectangle. This will be
interpreted as an instruction to use the native video size.\r\n"));
//DbgLog((LOG_TRACE, 3, _T("Zero-sized rectangle!\n")));

// Now we need to insert some dummy values for the output rectangle
in order to avoid an
// unhandled exception when we first configure the filter with this
profile.
// Later, after we connect the filter, we will be able to determine
the upstream rectangle size, and
// then adjust profile's rectangle values to match it.

hr = SetNativeVideoSize(pMux, pProfile1, TRUE);
if(m_bUseLog){
char text[500];
sprintf(text, "SetNativeVideoSize returned %d\r\n", hr);
LogText(text);
}

if(FAILED(hr))
{
//DbgLog((LOG_TRACE, 3, _T("Failed to SetNativeVideoSize with dummy
values! hr=0x%x\n"), hr));
return hr;
}
}

hr = pConfig->ConfigureFilterUsingProfile(pProfile1);
if(m_bUseLog){
char text[500];
sprintf(text, "ConfigureFilterUsingProfile returned %d\r\n", hr);
LogText(text);
}

if(FAILED(hr))
{
//DbgLog((LOG_TRACE, 3, _T("Failed to configure filter to use
profile1! hr=0x%08x\n"), hr));
return hr;
}

pConfig->Release();
}
else
return hr;

// newstuff end

bool bDVDevice = IsDVDevice(m_pCap);
if(m_bUseLog){
char text[500];
sprintf(text, "IsDVDevice returned %d\r\n", bDVDevice);
LogText(text);
}

if(bDVDevice)
hr = HookUpFiltersDV(pMux);
else
hr = HookUpFiltersCam(pMux);

/*
// Now add the video capture to the output file
hr = m_pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pCap, NULL, pMux);

if (FAILED(hr))
return hr;

// And do the same for the audio
hr = m_pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio,
m_pAudioCap, NULL, pMux);
*/
if (FAILED(hr))
{
// Abject failure. Try to recover the preview, at least.
TearDownGraph();
//RenderPreview();
return hr;
}

// add the metadata to the wmv file
hr = AddWmvMetadata(pMux, pwszAuthor, pwszTitle, pwszRating,
pwszDescription, pwszCopyright);
if(m_bUseLog){
char text[500];
sprintf(text, "AddWmvMetadata returned %d\r\n", hr);
LogText(text);
}

if (FAILED(hr))
return hr;

hr = StopCapture(); // Don't capture now, but get ready to do so.
if(m_bUseLog){
char text[500];
sprintf(text, "StopCapture returned %d\r\n", hr);
LogText(text);
}

if (FAILED(hr))
return hr;

hr = m_pControl->Run();
if(m_bUseLog){
char text[500];
sprintf(text, "Run returned %d\r\n", hr);
LogText(text);
}

if (FAILED(hr))
return hr;

// Then start the capture stream.
hr = StartCapture();

if(m_bUseLog){
LogText("Leaving CCaptureGraph::RenderWmvCapture()\r\n");
}

return hr;
}

HRESULT CCaptureGraph::HookUpFiltersCam(IBaseFilter* pWmvMux)
{
if(m_bUseLog){
char* msg = "Entering CCaptureGraph::HookUpFiltersCam\0";
LogText(msg);
}

//HRESULT hr = m_pBuild->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
// m_pCap, 0, pWmvMux);
HRESULT hr = m_pBuild->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
m_pCap, 0, 0);

if(m_bUseLog){
char text[500];
sprintf(text, "RenderStream(&PIN_CATEGORY_PREVIEW returned %d\r\n",
hr);
LogText(text);
}

// Now add the video capture to the output file
hr = m_pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pCap, 0, pWmvMux);
if(m_bUseLog){
char text[500];
sprintf(text, "RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video
returned %d\r\n", hr);
LogText(text);
}

if(FAILED(hr)) return hr;

hr = m_pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio,
m_pAudioCap, 0, pWmvMux);
if(m_bUseLog){
char text[500];
sprintf(text, "RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio
returned %d\r\n", hr);
LogText(text);
}
if(m_bUseLog){
char* msg = "Leaving CCaptureGraph::HookUpFiltersCam\0";
LogText(msg);
}

return hr;
}

.



Relevant Pages

  • Re: DirectShow @ WM 5.0: Capture camera to memory?
    ... The still image pin will most likely expose higher resolutions than ... the capture pin which could negativly impact your performance, ... You'll need to create a sink filter that does your processing, RGB video ...
    (microsoft.public.pocketpc.developer)
  • HELP! Text overlay on live video
    ... which is for live video streaming with time frame on the video. ... // We don't have the necessary capture filters ... // filter only has a capture pin this should ... because the capture graph builder will use a smart tee filter ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: Converting YUY2 format video to AVI
    ... Windows media encoder sdk to convert avi to wmv. ... your H.264 video decoder output in another format, ... His capture card is the following - ... filter graph instance in the "Running Object Table", ...
    (rec.video.desktop)
  • Re: DirectShow @ WM 5.0: Capture camera to memory?
    ... You want to process a sequence of still images (which is basically video). ... The still image pin probably isn't what you want unless you want to manually ... The video capture filter is what talks to the camera driver, ...
    (microsoft.public.pocketpc.developer)
  • Re: Video Capture Performance with directshow
    ... As for your question about video encoding, that is similar what we're doing ... The output pin on the filter is running ... so it slowly feeds data into the WMV encoder as ... delved into it a bit and found that it was a capture filter from HTC ...
    (microsoft.public.pocketpc.developer)