views:

898

answers:

2

Hi,

AMcap is a app for capturing video or to preview from webcam. Its source code comes with Microsoft Windows SDK as sample.

I want to (bypass the following process of user interaction in amcap code or say want to) set it as default:

Ampcap menu

  Options

    Video Capture Pin ...

        Color Space/Compression: YUY2

        Output size: 1600x1200

I have a compatible webcam and works fine on changing manually to YUY2 and 1600x1200 in AMcap app.

By default it is:

    Color Space/Compression: MJPG

    Output size: 160x120

I tried to find 'YUY2' string in whole project, but I could not find it, so that I could hardcode it. It seems it is created dynamically and then operated; refer: in the file amcap.cpp nearby line no 3395.

Please help.

-Rahul

+1  A: 

I have some code that uses an IID_IAMStreamConfig interface to set the camera image size. I didn't use it to set the image format, but I added the code that I think will do the job. It is untested however.

   // get the number of formats and make sure the strutucre size matches
   int count;
   int size;
   VIDEO_STREAM_CONFIG_CAPS caps;
   pSC->GetNumberOfCapabilities(&count, &size);
   if( sizeof(caps) != size )
   {
    // Error
   }

   AM_MEDIA_TYPE* mt_p = NULL;
   hr = pSC->GetStreamCaps(0, &mt_p, (BYTE*)&caps);
   if (hr != S_OK)
   {
    // Error
   }

   if ((mt_p->majortype != MEDIATYPE_Video) || (mt_p->formattype != FORMAT_VideoInfo))
   {
    // Error
   }

   VIDEOINFOHEADER* video_info_header_p = (VIDEOINFOHEADER *)mt_p->pbFormat;
      video_info_header_p->bmiHeader.biWidth = 1600;
   video_info_header_p->bmiHeader.biHeight = 1200;
   // Code to change video format 
   // I think 16 is the right value for biBitCount, but I am not sure!!!!
   video_info_header_p->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','2');
   video_info_header_p->bmiHeader.biBitCount = 16;

   hr = pSC->SetFormat(mt_p);
   if (hr != S_OK)
   {
    // Error
   }

   if (mt_p->cbFormat != 0)
   {
    CoTaskMemFree((PVOID)mt_p->pbFormat);
    mt_p->cbFormat = 0;
    mt_p->pbFormat = NULL;
   }
   if (mt_p->pUnk != NULL)
   {
    // Unecessary because pUnk should not be used, but safest.
    mt_p->pUnk->Release();
    mt_p->pUnk = NULL;
   }

You should place the code after the following block in amcap:

    if(hr != NOERROR)
        hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
            &MEDIATYPE_Video, gcap.pVCap,
            IID_IAMStreamConfig, (void **)&pSC);

Again, this is untested code, but you can try it and I hope it helps.

Dani van der Meer
Hey Thanksnext is the correct answer.
Rahul2047
A: 

Hey @Dani van der Meer: Thanks for the Pointer ... I have done it by: In the function BOOL InitCapFilters()

after

 if(hr != NOERROR)
{

    hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
                                      &MEDIATYPE_Video, gcap.pVCap,
                                      IID_IAMStreamConfig, (void **)&gcap.pVSC);

    if(hr != NOERROR)
    {
        // this means we can't set frame rate (non-DV only)
        ErrMsg(TEXT("Error %x: Cannot find VCapture:IAMStreamConfig"), hr);
    }
}

gcap.fCapAudioIsRelevant = TRUE;

Paste:

CMediaType *pmt;
// default capture format
if(gcap.pVSC && gcap.pVSC->GetFormat((AM_MEDIA_TYPE**)&pmt) == S_OK)
{
    // DV capture does not use a VIDEOINFOHEADER
    if(pmt->formattype == FORMAT_VideoInfo)
    {
  pmt->SetType(&MEDIATYPE_Video);
  pmt->SetFormatType(&FORMAT_VideoInfo);
  pmt->SetSubtype(&MEDIASUBTYPE_YUY2);
  pmt->SetTemporalCompression(FALSE);

     VIDEOINFOHEADER* lpvihin = (VIDEOINFOHEADER*) pmt->pbFormat;

  {

             //DWORD fccYUY2 =  'YUY2' ;
    //lpvihin->bmiHeader.biCompression  =fccYUY2;
   //'YUY2';// MAKEFOURCC('Y','U','Y','2');
   //lpvihin->bmiHeader.biBitCount = 16; 
   lpvihin->bmiHeader.biWidth =  1600;// 960; //1600;
   lpvihin->bmiHeader.biHeight =  1200;//  720; //1200;
   lpvihin->bmiHeader.biSizeImage =   1600*1200*3; 

   hr = gcap.pVSC->SetFormat(pmt);

   ResizeWindow(HEADER(pmt->pbFormat)->biWidth,
                     ABS(HEADER(pmt->pbFormat)->biHeight));
        }
    }
    if(pmt->majortype != MEDIATYPE_Video)
    {
        // This capture filter captures something other that pure video.
        // Maybe it's DV or something?  Anyway, chances are we shouldn't
        // allow capturing audio separately, since our video capture
        // filter may have audio combined in it already!
        gcap.fCapAudioIsRelevant = FALSE;
        gcap.fCapAudio = FALSE;
    }
    DeleteMediaType(pmt);
}

Thanks a lot

Rahul2047
OK. Good to know that this works. The DirectShow API is poorly documented, sometimes you just have to do some trial and error...
Dani van der Meer
yes, it is true.
Rahul2047