6 second delay in video

This is a discussion on 6 second delay in video within the Windows Programming forums, part of the Platform Specific Boards category; I built a filter graph in directshow and can get the video feed started, but it seems that teh images ...

  1. #1
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189

    6 second delay in video

    I built a filter graph in directshow and can get the video feed started, but it seems that teh images I am reciving from the sample grabber are delayed 6 seconds behind when the events actually take place. That is, if I stick my hand in front of the camera, the image of my hand doesnt appear until 6 seconds later. I used the SetSyncSource(NULL) method to make all teh filters run as fast as possible, btu there is still the 6 second buffering delay. The source filter is created by -

    Code:
    IBaseFilter *pSrc;
    hr = pGraph->AddSourceFilter(L"http://192.168.0.115/img/video.asf", L"Source", &pSrc);


    Hopefully someone can help me to reduce this buffering delay?
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  2. #2
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    OK, I think I got it down to somethign in the sample grabber buffering scheme forcing this lag. So I want to set up the callback functionality, but it seems that there is far more to settign up the callback class that MSDN implies.

    here is what I have so far -

    Code:
    // Set the sample grabber to callback mode
    MyCallBack pCallBack;
    pGrabber->SetBufferSamples(FALSE);
    pGrabber->SetCallback((ISampleGrabberCB*)&pCallBack , 0);
    Code:
    class MyCallBack {
    public:
    STDMETHODIMP_(ULONG) AddRef() { return 2; }
    STDMETHODIMP_(ULONG) Release() { return 1; }
    HRESULT BufferCB(double SampleTime,BYTE *pBuffer,long BufferLen);
    STDMETHODIMP SampleCB (double n,IMediaSample *pms){
       BYTE* pBuffer;
       DWORD BuffLen;
     
       BuffLen = pms->GetActualDataLength();
       pms->GetPointer(&pBuffer);
       CopyMemory(&DrawBuffer[54] , pBuffer , BuffLen);
       return 0;
       }
    };
     
    
    the problem im having is as soon as I call setcallback, the application crashes.
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  3. #3
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    You should pass some real function pointer (that will be called on event), not just an uninitialized pointer with the appropriate type
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  4. #4
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    How is the function not valid? I instantiated it with
    Code:
    MyCallBack pCallBack;
    So &pCallBack should be a valid pointer, or is it friday and im dense...
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  5. #5
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    MyCallBack pCallBack; is not a function

    Code:
    int myfunction()
    {
       return 0;
    }
    is a function

    Don't you notice the difference?
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  6. #6
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    the method requires thet you pass a pointer to a class that implements the function, not the function itself. You had me going there for a minute. Its some peculiar directshow thingy. Anyhow, I got it working by borrowing some code from MSDN. Unfortunately that didnt solve the problem either. There is still a 6 second delay in the video. I even enumerated all the filters and set their reference clocks to NULL, still no change.
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  7. #7
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    Make sure you have set the interval for the multi-media timer. It defaults to 5 ms but can go as low as 1 ms. I doubt this is the issue but it's a start.

    I've used DirectShow before and did not experience this type of problem. By no means am I a DirectShow expert and don't plan on ever being one since they are probably going to get rid of it.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,265
    Shouldn't MyCallback inherit from ISampleGrabberCB? You are currently casting your callback class to an interface which it doesn't inherit from.

  9. #9
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    The class im using directly implements ISampleGrabberCB, so no inheritance needed.

    Code:
    extern BYTE DrawBuffer[];
    extern AM_MEDIA_TYPE mt;
    
    #ifndef CALLBACK_CLASS
    #define CALLBACK_CLASS
    
    // Class to hold the callback function for the Sample Grabber filter.
    class SampleGrabberCallback : public ISampleGrabberCB {
    public:
        // Fake referance counting.
        STDMETHODIMP_(ULONG) AddRef() { return 1; }
        STDMETHODIMP_(ULONG) Release() { return 2; }
    
        STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject){
            if (NULL == ppvObject) return E_POINTER;
            if (riid == __uuidof(IUnknown)){
                *ppvObject = static_cast<IUnknown*>(this);
                return S_OK;
                }
            if (riid == __uuidof(ISampleGrabberCB)){
                *ppvObject = static_cast<ISampleGrabberCB*>(this);
                return S_OK;
                }
            return E_NOTIMPL;
            }
    
        STDMETHODIMP SampleCB(double Time, IMediaSample *pSample){
            BYTE* pBuffer;
            DWORD dwLength;
    
            dwLength = pSample->GetActualDataLength();
            pSample->GetPointer(&pBuffer);
            if(pSample->IsPreroll() == S_OK){
                return S_OK;
                }
    
            CopyMemory(&DrawBuffer[54] , pBuffer , dwLength);
    
            return S_OK;
            }
    
        STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen){
            if ((mt.majortype != MEDIATYPE_Video) || (mt.formattype != FORMAT_VideoInfo) || (mt.cbFormat < sizeof(VIDEOINFOHEADER)) || (mt.pbFormat == NULL)){
                return VFW_E_INVALIDMEDIATYPE;
                }
            HANDLE hf = CreateFile("C:\\Example.bmp", GENERIC_WRITE, 
            FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
            if (hf == INVALID_HANDLE_VALUE){
                return E_FAIL;
                }
            long cbBitmapInfoSize = mt.cbFormat - SIZE_PREHEADER;
            VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)mt.pbFormat;
    
            BITMAPFILEHEADER bfh;
            ZeroMemory(&bfh, sizeof(bfh));
            bfh.bfType = 'MB';  // Little-endian for "MB".
            bfh.bfSize = sizeof( bfh ) + BufferLen + cbBitmapInfoSize;
            bfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + cbBitmapInfoSize;
            
            // Write the file header.
            DWORD dwWritten = 0;
            WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
            WriteFile(hf, HEADER(pVideoHeader), cbBitmapInfoSize, &dwWritten, NULL);        
            WriteFile( hf, pBuffer, BufferLen, &dwWritten, NULL );
            CloseHandle( hf );
    
            return S_OK;
            }
        };
    
    
    
    
    #endif
    Last edited by abachler; 03-03-2008 at 03:00 PM.
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  10. #10
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    OK, I solved the problem somewhat. Since I am using the callback method and gettign the actual sample, I just modified the presentation time for each sample and whaddaya know, it worked. For each sample I just subtracted 4.6 seconds from its start and finish time and it brought the delay down to a reasonable amount. This is still a bit wierd though, as i thought the reference clocks where all set to null to run as fast as possible, and im directly taking the image data from the samples when it gets sent to me, All i can think of is that the NULL render filter is somehow backing up the whole process.
    Last edited by abachler; 03-04-2008 at 10:40 AM.
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. temperature sensors
    By danko in forum C Programming
    Replies: 22
    Last Post: 07-10-2007, 08:26 PM
  2. Problem With My Box
    By HaVoX in forum Tech Board
    Replies: 9
    Last Post: 10-15-2005, 08:38 AM
  3. Codec Bitrates?
    By gvector1 in forum C# Programming
    Replies: 2
    Last Post: 06-16-2003, 09:39 AM
  4. OpenGL .dll vs video card dll
    By Silvercord in forum Game Programming
    Replies: 14
    Last Post: 02-12-2003, 07:57 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21