Page 3 of 5

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 5:39 pm
by rhlawek
Antonio, on a device with 2 or more cameras do you know how to select which camera to use?

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 5:44 pm
by TimStone
OK ... so I finally got it to build and work. There are a couple of warnings but we can do that later.

I see we are first accessing the webcam. Ultimately, what I need is to have it open in snapshot mode. My clients will be saving photos of parts and vehicles that they will be looking at within the program.

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 5:48 pm
by Antonio Linares
Then we make it a true FWH control ;-)

Click over the camera display!

Code: Select all | Expand

#include "FiveWin.ch"

#define GWL_STYLE -16

function Main()

   local oWnd, hWnd, oCamera
   
   DEFINE WINDOW oWnd

   oCamera = TControl()
   
   oCamera:bLClicked = { || MsgInfo( "click" ) }

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT ( DShowCamera(),;
                SetParent( hWnd := FindWindow( 0, "ActiveMovie Window" ), oWnd:hWnd ),;
                SetWindowLong( hWnd, GWL_STYLE, nOr( WS_CHILD, WS_VISIBLE ) ),;
                SetWindowPos( hWnd, 0, 10, 10, 300, 300 ),;
                oCamera:oWnd := oWnd, oCamera:hWnd := hWnd, oCamera:Link() )

return nil

#pragma BEGINDUMP

#include <dshow.h>
#include <uuids.h>
#include <objbase.h>

#import "qedit.dll" raw_interfaces_only named_guids

EXTERN_C const CLSID CLSID_NullRenderer;
EXTERN_C const CLSID CLSID_SampleGrabber;

HB_FUNC( DSHOWCAMERA )
{
   HRESULT hr;
   ICreateDevEnum *pDevEnum = NULL;
   IEnumMoniker *pEnum = NULL;
   IMoniker *pMoniker = NULL;
   IPropertyBag *pPropBag = NULL;
   IGraphBuilder *pGraph = NULL;
   ICaptureGraphBuilder2 *pBuilder = NULL;
   IBaseFilter *pCap = NULL;
   IBaseFilter *pSampleGrabberFilter = NULL;
   IBaseFilter *pNullRenderer = NULL;
   IMediaControl *pMediaControl = NULL;
   char *pBuffer = NULL;
   VARIANT var;
    int n = 0;
    int device_number = 0;
    char device_name[ 100 ];
   char char_buffer[100];
   DexterLib::ISampleGrabber *pSampleGrabber = NULL;

   strcpy( device_name, "" );

   hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );

   if( hr != S_OK )
      MessageBox( 0, "CoInitializeEx error", "ok", 0 );

   hr = CoCreateInstance( CLSID_FilterGraph, NULL,
              CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
              ( void ** ) &pGraph );
           
   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance error", "ok", 0 );
     
    hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
            CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
            ( void ** ) &pBuilder );      

   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );

    hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
   
    if( hr != S_OK )
        MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
     
    hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
            CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
         
    if( hr != S_OK )
        MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
     
    hr = pDevEnum->CreateClassEnumerator(
                    CLSID_VideoInputDeviceCategory, &pEnum, 0 );
               
    if( hr != S_OK )
        MessageBox( 0, "No video devices found", "ok", 0 );      
     
    while(1)
    {
        // Access next device
        hr = pEnum->Next(1, &pMoniker, NULL);
        if( hr == S_OK )
            n++; // increment device count
      else  
         break;
       
        // If device was specified by name rather than number...
        if( device_number == 0 )
        {
            // Get video input device name
            hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
            if (hr == S_OK)
            {
                // Get current device name
                VariantInit(&var);
                hr = pPropBag->Read(L"FriendlyName", &var, 0);
               
                // Convert to a normal C string, i.e. char*
                sprintf(char_buffer, "%ls", var.bstrVal);
                VariantClear(&var);
                pPropBag->Release();
                pPropBag = NULL;
               
                // Exit loop if current device name matched devname
            // MessageBox( 0, char_buffer, "device_name", 0 );
           
                if (strcmp(device_name, char_buffer) == 0) break;
            }
            else
         {
                MessageBox( 0, "Error getting device names", "ok", 0 );
            break;
         }  
        }
        else if (n >= device_number) break;
    }  
   
    // Get video input device name
    hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
    VariantInit(&var);
    hr = pPropBag->Read(L"FriendlyName", &var, 0);
    // MessageBoxW( 0, L"Capture device", var.bstrVal, 0 );
    VariantClear(&var);  
   
    // Create capture filter and add to graph
    hr = pMoniker->BindToObject(0, 0,
                    IID_IBaseFilter, (void**)&pCap);
               
    if( hr != S_OK )
      MessageBox( 0, "Could not create capture filter", "ok", 0 );  

    // Add capture filter to graph
    hr = pGraph->AddFilter(pCap, L"Capture Filter");
   
    if( hr != S_OK )
      MessageBox( 0, "Could not add capture filter to graph", "ok", 0 );

    // Create sample grabber filter
    hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
        CLSCTX_INPROC_SERVER, IID_IBaseFilter,
        (void**)&pSampleGrabberFilter);
     
    if( hr != S_OK )
        MessageBox( 0, "Could not create Sample Grabber filter", "ok", 0 );

    // Query the ISampleGrabber interface of the sample grabber filter
    hr = pSampleGrabberFilter->QueryInterface(
            DexterLib::IID_ISampleGrabber, (void**)&pSampleGrabber);
         
    if( hr != S_OK )
        MessageBox( 0, "Could not get ISampleGrabber interface to sample grabber filter", "ok", 0 );

    // Enable sample buffering in the sample grabber filter
    hr = pSampleGrabber->SetBufferSamples(TRUE);
   
    if( hr != S_OK )
        MessageBox( 0, "Could not enable sample buffering in the sample grabber", "ok", 0 );

    // Set media type in sample grabber filter
    AM_MEDIA_TYPE mt;
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
    hr = pSampleGrabber->SetMediaType((DexterLib::_AMMediaType *)&mt);
   
    if( hr != S_OK )
        MessageBox( 0, "Could not set media type in sample grabber", "ok", 0 );

    // Add sample grabber filter to filter graph
    hr = pGraph->AddFilter(pSampleGrabberFilter, L"SampleGrab");
   
    if( hr != S_OK )
        MessageBox( 0, "Could not add Sample Grabber to filter graph", "ok", 0 );

    // Create Null Renderer filter
    hr = CoCreateInstance(CLSID_NullRenderer, NULL,
        CLSCTX_INPROC_SERVER, IID_IBaseFilter,
        (void**)&pNullRenderer);

   if( hr != S_OK )
        MessageBox( 0, "Could not create Null Renderer filter", "ok", 0 );

    // Add Null Renderer filter to filter graph
    hr = pGraph->AddFilter(pNullRenderer, L"NullRender");

   if( hr != S_OK )
        MessageBox( 0, "Could not add Null Renderer to filter graph", "ok", 0 );
     
   // Connect up the filter graph's capture stream
    hr = pBuilder->RenderStream(
        &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
        pCap,  pSampleGrabberFilter, pNullRenderer);
     
    if( hr != S_OK )
        MessageBox( 0, "Could not render capture video stream", "ok", 0 );

    hr = pBuilder->RenderStream(
                &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
                pCap, NULL, NULL);
   
   if (hr != S_OK && hr != VFW_S_NOPREVIEWPIN)
            MessageBox( 0, "Could not render preview video stream", "ok", 0 );

    // Get media control interfaces to graph builder object
    hr = pGraph->QueryInterface(IID_IMediaControl,
                    (void**)&pMediaControl);

   if( hr != S_OK )
      MessageBox( 0, "Could not get media control interface", "ok", 0 );

    // Run graph
    while(1)
    {
        hr = pMediaControl->Run();
       
        // Hopefully, the return value was S_OK or S_FALSE
        if (hr == S_OK) break; // graph is now running
        if (hr == S_FALSE) continue; // graph still preparing to run
       
        // If the Run function returned something else,
        // there must be a problem
        // fprintf(stderr, "Error: %u\n", hr);
        MessageBox( 0, "Could not run filter graph", "ok", 0 );
    }
}

#pragma ENDDUMP

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 5:57 pm
by rhlawek
Never mind on camera selection, it is a simple as changing the device number. So my next question is how to enumerate all available cameras.

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:00 pm
by Antonio Linares
Now you can click on it to stop it and record again, alternatively:

dshow.prg

Code: Select all | Expand

#include "FiveWin.ch"

#define GWL_STYLE -16

function Main()

   local oWnd, hWnd, oCamera, pMediaControl
   local lStop := .F.
   
   DEFINE WINDOW oWnd

   oCamera = TControl()
   
   oCamera:bLClicked = { || If( ! lStop,;
                            DShowStop( pMediaControl ), DShowPlay( pMediaControl ) ),;
                            lStop := ! lStop }

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT ( pMediaControl := DShowCamera(),;
                SetParent( hWnd := FindWindow( 0, "ActiveMovie Window" ), oWnd:hWnd ),;
                SetWindowLong( hWnd, GWL_STYLE, nOr( WS_CHILD, WS_VISIBLE ) ),;
                SetWindowPos( hWnd, 0, 10, 10, 300, 300 ),;
                oCamera:oWnd := oWnd, oCamera:hWnd := hWnd, oCamera:Link() )

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>

#import "qedit.dll" raw_interfaces_only named_guids

EXTERN_C const CLSID CLSID_NullRenderer;
EXTERN_C const CLSID CLSID_SampleGrabber;

HB_FUNC( DSHOWPLAY )
{
   IMediaControl * pMediaControl = ( IMediaControl * ) hb_parnll( 1 );

   pMediaControl->Run();
}  

HB_FUNC( DSHOWSTOP )
{
   IMediaControl * pMediaControl = ( IMediaControl * ) hb_parnll( 1 );

   pMediaControl->Stop();
}  

HB_FUNC( DSHOWCAMERA )
{
   HRESULT hr;
   ICreateDevEnum *pDevEnum = NULL;
   IEnumMoniker *pEnum = NULL;
   IMoniker *pMoniker = NULL;
   IPropertyBag *pPropBag = NULL;
   IGraphBuilder *pGraph = NULL;
   ICaptureGraphBuilder2 *pBuilder = NULL;
   IBaseFilter *pCap = NULL;
   IBaseFilter *pSampleGrabberFilter = NULL;
   IBaseFilter *pNullRenderer = NULL;
   IMediaControl *pMediaControl = NULL;
   char *pBuffer = NULL;
   VARIANT var;
    int n = 0;
    int device_number = 0;
    char device_name[ 100 ];
   char char_buffer[100];
   DexterLib::ISampleGrabber *pSampleGrabber = NULL;

   strcpy( device_name, "" );

   hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );

   if( hr != S_OK )
      MessageBox( 0, "CoInitializeEx error", "ok", 0 );

   hr = CoCreateInstance( CLSID_FilterGraph, NULL,
              CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
              ( void ** ) &pGraph );
           
   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance error", "ok", 0 );
     
    hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
            CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
            ( void ** ) &pBuilder );      

   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );

    hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
   
    if( hr != S_OK )
        MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
     
    hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
            CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
         
    if( hr != S_OK )
        MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
     
    hr = pDevEnum->CreateClassEnumerator(
                    CLSID_VideoInputDeviceCategory, &pEnum, 0 );
               
    if( hr != S_OK )
        MessageBox( 0, "No video devices found", "ok", 0 );      
     
    while(1)
    {
        // Access next device
        hr = pEnum->Next(1, &pMoniker, NULL);
        if( hr == S_OK )
            n++; // increment device count
      else  
         break;
       
        // If device was specified by name rather than number...
        if( device_number == 0 )
        {
            // Get video input device name
            hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
            if (hr == S_OK)
            {
                // Get current device name
                VariantInit(&var);
                hr = pPropBag->Read(L"FriendlyName", &var, 0);
               
                // Convert to a normal C string, i.e. char*
                sprintf(char_buffer, "%ls", var.bstrVal);
                VariantClear(&var);
                pPropBag->Release();
                pPropBag = NULL;
               
                // Exit loop if current device name matched devname
            // MessageBox( 0, char_buffer, "device_name", 0 );
           
                if (strcmp(device_name, char_buffer) == 0) break;
            }
            else
         {
                MessageBox( 0, "Error getting device names", "ok", 0 );
            break;
         }  
        }
        else if (n >= device_number) break;
    }  
   
    // Get video input device name
    hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
    VariantInit(&var);
    hr = pPropBag->Read(L"FriendlyName", &var, 0);
    // MessageBoxW( 0, L"Capture device", var.bstrVal, 0 );
    VariantClear(&var);  
   
    // Create capture filter and add to graph
    hr = pMoniker->BindToObject(0, 0,
                    IID_IBaseFilter, (void**)&pCap);
               
    if( hr != S_OK )
      MessageBox( 0, "Could not create capture filter", "ok", 0 );  

    // Add capture filter to graph
    hr = pGraph->AddFilter(pCap, L"Capture Filter");
   
    if( hr != S_OK )
      MessageBox( 0, "Could not add capture filter to graph", "ok", 0 );

    // Create sample grabber filter
    hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
        CLSCTX_INPROC_SERVER, IID_IBaseFilter,
        (void**)&pSampleGrabberFilter);
     
    if( hr != S_OK )
        MessageBox( 0, "Could not create Sample Grabber filter", "ok", 0 );

    // Query the ISampleGrabber interface of the sample grabber filter
    hr = pSampleGrabberFilter->QueryInterface(
            DexterLib::IID_ISampleGrabber, (void**)&pSampleGrabber);
         
    if( hr != S_OK )
        MessageBox( 0, "Could not get ISampleGrabber interface to sample grabber filter", "ok", 0 );

    // Enable sample buffering in the sample grabber filter
    hr = pSampleGrabber->SetBufferSamples(TRUE);
   
    if( hr != S_OK )
        MessageBox( 0, "Could not enable sample buffering in the sample grabber", "ok", 0 );

    // Set media type in sample grabber filter
    AM_MEDIA_TYPE mt;
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
    hr = pSampleGrabber->SetMediaType((DexterLib::_AMMediaType *)&mt);
   
    if( hr != S_OK )
        MessageBox( 0, "Could not set media type in sample grabber", "ok", 0 );

    // Add sample grabber filter to filter graph
    hr = pGraph->AddFilter(pSampleGrabberFilter, L"SampleGrab");
   
    if( hr != S_OK )
        MessageBox( 0, "Could not add Sample Grabber to filter graph", "ok", 0 );

    // Create Null Renderer filter
    hr = CoCreateInstance(CLSID_NullRenderer, NULL,
        CLSCTX_INPROC_SERVER, IID_IBaseFilter,
        (void**)&pNullRenderer);

   if( hr != S_OK )
        MessageBox( 0, "Could not create Null Renderer filter", "ok", 0 );

    // Add Null Renderer filter to filter graph
    hr = pGraph->AddFilter(pNullRenderer, L"NullRender");

   if( hr != S_OK )
        MessageBox( 0, "Could not add Null Renderer to filter graph", "ok", 0 );
     
   // Connect up the filter graph's capture stream
    hr = pBuilder->RenderStream(
        &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
        pCap,  pSampleGrabberFilter, pNullRenderer);
     
    if( hr != S_OK )
        MessageBox( 0, "Could not render capture video stream", "ok", 0 );

    hr = pBuilder->RenderStream(
                &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
                pCap, NULL, NULL);
   
   if (hr != S_OK && hr != VFW_S_NOPREVIEWPIN)
            MessageBox( 0, "Could not render preview video stream", "ok", 0 );

    // Get media control interfaces to graph builder object
    hr = pGraph->QueryInterface(IID_IMediaControl,
                    (void**)&pMediaControl);

   if( hr != S_OK )
      MessageBox( 0, "Could not get media control interface", "ok", 0 );

    // Run graph
    while(1)
    {
        hr = pMediaControl->Run();
       
        // Hopefully, the return value was S_OK or S_FALSE
        if (hr == S_OK) break; // graph is now running
        if (hr == S_FALSE) continue; // graph still preparing to run
       
        // If the Run function returned something else,
        // there must be a problem
        // fprintf(stderr, "Error: %u\n", hr);
        MessageBox( 0, "Could not run filter graph", "ok", 0 );
    }
   
   hb_retnll( ( HB_LONGLONG ) pMediaControl );
}

#pragma ENDDUMP

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:01 pm
by TimStone
Once again too many errors to compile this latest version. It seems a "select all" and copy of the code from the forum is adding some foreign characters. The downloaded .prg worked fine.

Tim

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:03 pm
by Antonio Linares
Robb,

This code seem to do what you want:

Code: Select all | Expand

    // If the user has included the "/list" command line
    // argument, just list available devices, then exit.
    if (list_devices != 0)
    {
        fprintf(stderr, "Available capture devices:\n");
        n = 0;
        while(1)
        {
            // Find next device
            hr = pEnum->Next(1, &pMoniker, NULL);
            if (hr == S_OK)
            {
                // Increment device counter
                n++;
               
                // Get device name
                hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
                VARIANT var;
                VariantInit(&var);
                hr = pPropBag->Read(L"FriendlyName", &var, 0);
                fprintf(stderr, "  %d. %ls\n", n, var.bstrVal);
                VariantClear(&var);
            }
            else
            {
                // Finished listing device, so exit program
                if (n == 0) exit_message("No devices found", 0);
                else exit_message("", 0);
            }
        }
    }

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:05 pm
by Antonio Linares

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:22 pm
by Antonio Linares
This version allows to take as many photos as wanted ;-)

dshow.prg

Code: Select all | Expand

#include "FiveWin.ch"

#define GWL_STYLE -16

function Main()

   local oWnd, hWnd, oCamera, pMediaControl
   
   DEFINE WINDOW oWnd

   oCamera = TControl()
   
   oCamera:bLClicked = { || DShowStop( pMediaControl ), TakePhoto( oCamera ),;
                            DShowPlay( pMediaControl ) }

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT ( pMediaControl := DShowCamera(),;
                SetParent( hWnd := FindWindow( 0, "ActiveMovie Window" ), oWnd:hWnd ),;
                SetWindowLong( hWnd, GWL_STYLE, nOr( WS_CHILD, WS_VISIBLE ) ),;
                SetWindowPos( hWnd, 0, 15, 15, 300, 300 ),;
                oCamera:oWnd := oWnd, oCamera:hWnd := hWnd, oCamera:Link() )

return nil

function TakePhoto( oCamera )

   static oBmp

   oCamera:SaveToBmp( "photo.bmp" )
   
   if oBmp == nil
      @ 1, 60 BITMAP oBmp OF oCamera:oWnd FILENAME "photo.bmp"
   else  
      oBmp:LoadImage( , "photo.bmp" )
      oBmp:Refresh()
   endif  

return nil  

#pragma BEGINDUMP

#include <hbapi.h>
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>

#import "qedit.dll" raw_interfaces_only named_guids

EXTERN_C const CLSID CLSID_NullRenderer;
EXTERN_C const CLSID CLSID_SampleGrabber;

HB_FUNC( DSHOWPLAY )
{
   IMediaControl * pMediaControl = ( IMediaControl * ) hb_parnll( 1 );

   pMediaControl->Run();
}  

HB_FUNC( DSHOWSTOP )
{
   IMediaControl * pMediaControl = ( IMediaControl * ) hb_parnll( 1 );

   pMediaControl->Stop();
}  

HB_FUNC( DSHOWCAMERA )
{
   HRESULT hr;
   ICreateDevEnum *pDevEnum = NULL;
   IEnumMoniker *pEnum = NULL;
   IMoniker *pMoniker = NULL;
   IPropertyBag *pPropBag = NULL;
   IGraphBuilder *pGraph = NULL;
   ICaptureGraphBuilder2 *pBuilder = NULL;
   IBaseFilter *pCap = NULL;
   IBaseFilter *pSampleGrabberFilter = NULL;
   IBaseFilter *pNullRenderer = NULL;
   IMediaControl *pMediaControl = NULL;
   char *pBuffer = NULL;
   VARIANT var;
    int n = 0;
    int device_number = 0;
    char device_name[ 100 ];
   char char_buffer[100];
   DexterLib::ISampleGrabber *pSampleGrabber = NULL;

   strcpy( device_name, "" );

   hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );

   if( hr != S_OK )
      MessageBox( 0, "CoInitializeEx error", "ok", 0 );

   hr = CoCreateInstance( CLSID_FilterGraph, NULL,
              CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
              ( void ** ) &pGraph );
           
   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance error", "ok", 0 );
     
    hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
            CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
            ( void ** ) &pBuilder );      

   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );

    hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
   
    if( hr != S_OK )
        MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
     
    hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
            CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
         
    if( hr != S_OK )
        MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
     
    hr = pDevEnum->CreateClassEnumerator(
                    CLSID_VideoInputDeviceCategory, &pEnum, 0 );
               
    if( hr != S_OK )
        MessageBox( 0, "No video devices found", "ok", 0 );      
     
    while(1)
    {
        // Access next device
        hr = pEnum->Next(1, &pMoniker, NULL);
        if( hr == S_OK )
            n++; // increment device count
      else  
         break;
       
        // If device was specified by name rather than number...
        if( device_number == 0 )
        {
            // Get video input device name
            hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
            if (hr == S_OK)
            {
                // Get current device name
                VariantInit(&var);
                hr = pPropBag->Read(L"FriendlyName", &var, 0);
               
                // Convert to a normal C string, i.e. char*
                sprintf(char_buffer, "%ls", var.bstrVal);
                VariantClear(&var);
                pPropBag->Release();
                pPropBag = NULL;
               
                // Exit loop if current device name matched devname
            // MessageBox( 0, char_buffer, "device_name", 0 );
           
                if (strcmp(device_name, char_buffer) == 0) break;
            }
            else
         {
                MessageBox( 0, "Error getting device names", "ok", 0 );
            break;
         }  
        }
        else if (n >= device_number) break;
    }  
   
    // Get video input device name
    hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
    VariantInit(&var);
    hr = pPropBag->Read(L"FriendlyName", &var, 0);
    // MessageBoxW( 0, L"Capture device", var.bstrVal, 0 );
    VariantClear(&var);  
   
    // Create capture filter and add to graph
    hr = pMoniker->BindToObject(0, 0,
                    IID_IBaseFilter, (void**)&pCap);
               
    if( hr != S_OK )
      MessageBox( 0, "Could not create capture filter", "ok", 0 );  

    // Add capture filter to graph
    hr = pGraph->AddFilter(pCap, L"Capture Filter");
   
    if( hr != S_OK )
      MessageBox( 0, "Could not add capture filter to graph", "ok", 0 );

    // Create sample grabber filter
    hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
        CLSCTX_INPROC_SERVER, IID_IBaseFilter,
        (void**)&pSampleGrabberFilter);
     
    if( hr != S_OK )
        MessageBox( 0, "Could not create Sample Grabber filter", "ok", 0 );

    // Query the ISampleGrabber interface of the sample grabber filter
    hr = pSampleGrabberFilter->QueryInterface(
            DexterLib::IID_ISampleGrabber, (void**)&pSampleGrabber);
         
    if( hr != S_OK )
        MessageBox( 0, "Could not get ISampleGrabber interface to sample grabber filter", "ok", 0 );

    // Enable sample buffering in the sample grabber filter
    hr = pSampleGrabber->SetBufferSamples(TRUE);
   
    if( hr != S_OK )
        MessageBox( 0, "Could not enable sample buffering in the sample grabber", "ok", 0 );

    // Set media type in sample grabber filter
    AM_MEDIA_TYPE mt;
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
    hr = pSampleGrabber->SetMediaType((DexterLib::_AMMediaType *)&mt);
   
    if( hr != S_OK )
        MessageBox( 0, "Could not set media type in sample grabber", "ok", 0 );

    // Add sample grabber filter to filter graph
    hr = pGraph->AddFilter(pSampleGrabberFilter, L"SampleGrab");
   
    if( hr != S_OK )
        MessageBox( 0, "Could not add Sample Grabber to filter graph", "ok", 0 );

    // Create Null Renderer filter
    hr = CoCreateInstance(CLSID_NullRenderer, NULL,
        CLSCTX_INPROC_SERVER, IID_IBaseFilter,
        (void**)&pNullRenderer);

   if( hr != S_OK )
        MessageBox( 0, "Could not create Null Renderer filter", "ok", 0 );

    // Add Null Renderer filter to filter graph
    hr = pGraph->AddFilter(pNullRenderer, L"NullRender");

   if( hr != S_OK )
        MessageBox( 0, "Could not add Null Renderer to filter graph", "ok", 0 );
     
   // Connect up the filter graph's capture stream
    hr = pBuilder->RenderStream(
        &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
        pCap,  pSampleGrabberFilter, pNullRenderer);
     
    if( hr != S_OK )
        MessageBox( 0, "Could not render capture video stream", "ok", 0 );

    hr = pBuilder->RenderStream(
                &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
                pCap, NULL, NULL);
   
   if (hr != S_OK && hr != VFW_S_NOPREVIEWPIN)
            MessageBox( 0, "Could not render preview video stream", "ok", 0 );

    // Get media control interfaces to graph builder object
    hr = pGraph->QueryInterface(IID_IMediaControl,
                    (void**)&pMediaControl);

   if( hr != S_OK )
      MessageBox( 0, "Could not get media control interface", "ok", 0 );

    // Run graph
    while(1)
    {
        hr = pMediaControl->Run();
       
        // Hopefully, the return value was S_OK or S_FALSE
        if (hr == S_OK) break; // graph is now running
        if (hr == S_FALSE) continue; // graph still preparing to run
       
        // If the Run function returned something else,
        // there must be a problem
        // fprintf(stderr, "Error: %u\n", hr);
        MessageBox( 0, "Could not run filter graph", "ok", 0 );
    }
   
   hb_retnll( ( HB_LONGLONG ) pMediaControl );
}

#pragma ENDDUMP

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:24 pm
by Antonio Linares
We don't need to stop the camera to take the photo, so we can simply do:

oCamera:bLClicked = { || TakePhoto( oCamera ) }

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:25 pm
by Antonio Linares

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 6:51 pm
by Antonio Linares

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 7:19 pm
by TimStone
OK ... that is running and building fine here ( from the .prg included in the .zip file ).

Tim

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 9:00 pm
by Gale FORd
On my Microsoft Surface Pro 3 with Windows 10 dshow.exe gets error.
"Could not render preview video stream"
dshow.exe was in the last .zip file you linked to.

Re: Camera Control needed for Tablet

Posted: Thu Aug 25, 2016 9:21 pm
by TimStone
My Microsoft Surface 3 with the current Win 10 works fine with dShow.exe