none
Vivek's vcam source filter crashes flash player

    Question

  • When trying to access the vcam source filter in flash,the browser just crashes.

     

    Has anyone ever tried the same? What's the reason?

    Sunday, October 03, 2010 12:21 PM

All replies

  • Crash details, call stack?
    http://alax.info/blog/tag/directshow
    Sunday, October 03, 2010 1:52 PM
  • >    vcam.ax!CopyMediaType()  + 0x49 bytes    
         vcam.ax!CMediaType::Set()  + 0x41 bytes    
         vcam.ax!CMediaType::operator=()  + 0x2f bytes    
         vcam.ax!CVCamStream::SetFormat(_AMMediaType * pmt=0x00000000)  Line 201    C++
         FlashPlayer.exe!005641be()     
    Sunday, October 03, 2010 3:18 PM
  • The first media type that flash player or flash media encoder will set is 'NULL'

    And i can see it is NULL in your stack trace.....

    If the mt pointer is null, return S_OK and create default media type.

     

     

     


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    • Proposed as answer by Bowljoman Tuesday, October 19, 2010 6:39 PM
    Sunday, October 03, 2010 3:24 PM
  • Yeah this problem is gone after that,  but when I switch from one filter to another ,got this exception which leads to crash again:

     

    >    0480b000()   
         vcam.ax!CSourceStream::DoBufferProcessingLoop()  + 0xe1 bytes   
         vcam.ax!CSourceStream::ThreadProc()  + 0x13e bytes   
         vcam.ax!CAMThread::InitialThreadProc()  + 0x51 bytes   
         kernel32.dll!7c80b713()

    The callstack is from this thread:

     

    0    >    0x000015b8    Worker Thread    CAMThread::InitialThreadProc    0480b000    Normal    0

     

    What does it mean?

    Sunday, October 03, 2010 3:30 PM
  • What does it mean?

    More of a guesswork for us, but you can set your debugger to break on exception and check the problem from source: at what source code line it breaks, any NULL variables etc. Define your "crash", it can me memory access violation or something else, what is the address, NULL or an attempt access to access memory which is already freed/deallocated etc.


    http://alax.info/blog/tag/directshow
    Sunday, October 03, 2010 5:19 PM
  • There's no source code available ,only disassembly code:

     

    017D0B5B  push        edx 
    017D0B5C  mov         eax,dword ptr [ecx+8]
    017D0B5F  call        eax 
    017D0B61  cmp         esi,esp
    017D0B63  call        @ILT+2525(__RTC_CheckEsp) (17C49E2h)
    017D0B68  cmp         dword ptr [ebp-2Ch],0
    017D0B6C  je          CSourceStream::DoBufferProcessingLoop+10Ah (17D0B8Ah)
    017D0B6E  mov         eax,dword ptr [ebp-2Ch]

     

    Problem exists at the line 017D0B5F  call        eax

    Monday, October 04, 2010 3:24 AM
  • You perhaps are using NULL interface pointer, such as:

    IFoo* pFoo = NULL;
    pFoo->WrongOne(); // <<--- pFoo is NULL!
    


    http://alax.info/blog/tag/directshow
    Monday, October 04, 2010 5:32 AM
  • If the program crashes in there in assembly code, you can always click on the call stack window to your own code, and quickly find the null pointer.

    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Wednesday, October 06, 2010 2:13 AM
  • I found another way to crash: just terminate it while playing.

     

    Has anyone else tried it out with flash player?

     

    @Bowljoman, no it's not my own code that cause the problem.

    Thursday, October 07, 2010 11:30 AM
  • Yeah, I have good success with using vCam as a basis for a flash player plugin.

     

    As detailed here http://www.thebitstream.com/?p=47

    I do plan to release the source as part of the framework that started and evolved from that experiment.

     

    I just started releasing framework bits here.

    http://code.google.com/p/comserver/

     

     


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Thursday, October 07, 2010 8:55 PM
  • But if you leave vcam as is, flash player will crash. Can you share how did you fix this problem? Thanks.
    Friday, October 08, 2010 2:49 AM
  • The first media type that flash player or flash media encoder will set is 'NULL'

    And i can see it is NULL in your stack trace.....

    If the mt pointer is null, return S_OK and create default media type.

    Anything else is probably not vCam or flash.

    ...meaning.... double check your pointers and stack vars, and be careful...

     


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Friday, October 08, 2010 4:25 AM
  • @Bowljoman, still no clue,stucked by this for many days...
    Friday, October 08, 2010 8:53 AM
  • Hi,

    JUst in case it may help to enter more diagnostic you can try same testing with my virtualcam source filter : it's based on VCam but with major differences in media type support and exposing. Send me an email at rostan.serge@orange.fr so that I can send you the filter.

    Friday, October 08, 2010 11:01 AM
  • Hi Serge,

    I just tried your filter, and it's even behaving worse than Vivek's vcam, because flash player crashed before I started playing, while enumerating the filters.

    Friday, October 08, 2010 12:37 PM
  • @Bowljoman, could you send me your filter so that I can try whether it actually works compatibly with Flash Player or not?
    Friday, October 08, 2010 12:39 PM
  • Sorry, not yet. When I can invest the time, I will be releasing it as a demo to the framework.

     

    Make sure you unregister your broken filters before trying the new ones.


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Friday, October 08, 2010 4:42 PM
  • Why dont you paste your filter code.......

     

    HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)
    {
    //	return S_OK;
    	if(!pmt)return S_OK;//Default?
    	VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)(pmt->pbFormat);
    	VIDEOINFOHEADER *mvi = (VIDEOINFOHEADER *)(m_mt.Format ());
    	if(pvi->bmiHeader.biHeight !=mvi->bmiHeader.biHeight || 
    		pvi->bmiHeader.biWidth != mvi->bmiHeader.biWidth || 
    		pvi->bmiHeader.biBitCount !=mvi->bmiHeader.biBitCount )
    		return VFW_E_INVALIDMEDIATYPE;	
    
    	if(pvi->AvgTimePerFrame <10000000/30)
    		return VFW_E_INVALIDMEDIATYPE;
    	if(pvi->AvgTimePerFrame <1)
    		return VFW_E_INVALIDMEDIATYPE;
    	
    
    	return S_OK;
    }


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Friday, October 08, 2010 4:49 PM
  • I have a very similar issue .. Flash obviously recognizes my filter, and it seems to be working - but nothing is displayed as output. And often (not always), when trying to turn the camera "off" flash (and the browser actually) just hangs/freezes and wont respond. I suspect it might it a missing interface, but it queries for so many..Also notice the extra CreateInstance() at first that never gets deallocated. works great with other programs.

    Attached is some debug, sorry a bit lengthy. FillBuffer() does get called, not debug obviously. Any suggestions, anything you notice? I'm stumped.

    MyFilter.dll(tid f58)        0 : CSourceFilter::CreateInstance()
    MyFilter.dll(tid f58)        0 : CSourceFilter()
    MyFilter.dll(tid f58)        0 : CCapturePin() // done
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=0) // return hr=0
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=0) // return hr=0
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=37d84f60) // return hr=80004002
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=56a86895) // return hr=0
    MyFilter.dll(tid f58)        0 : CSourceFilter::CreateInstance()
    MyFilter.dll(tid f58)        0 : CSourceFilter()
    MyFilter.dll(tid f58)        0 : CCapturePin()
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=0) // return hr=0
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=37d84f60) // return hr=80004002
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=56a86895) // return // hr=0
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=8e1c39a1) // return hr=80004002
    MyFilter.dll(tid f58)        0 : CSourceFilter::NonDelegatingQueryInterface(riid=f90a6130) // return hr=80004002
    MyFilter.dll(tid f58)        1 : CCapturePin::NonDelegatingQueryInterface(riid=c6e13340)
    MyFilter.dll(tid f58)        1 : CCapturePin::SetFormat()
    MyFilter.dll(tid f58)        1 : CCapturePin::GetNumberOfCapabilities()
    MyFilter.dll(tid f58)        1 : CCapturePin::GetStreamCaps()
    MyFilter.dll(tid f58)        1 : CCapturePin::GetMediaType( iPosition = 0 ) // OK
    MyFilter.dll(tid f58)        1 : CCapturePin::GetMediaType( iPosition = 1 ) // VFW_S_NO_MORE_ITEMS
    MyFilter.dll(tid f58)        1 : CSourceFilter::NonDelegatingQueryInterface(riid=f90a6130) // return hr=80004002
    MyFilter.dll(tid f58)        1 : CSourceFilter::NonDelegatingQueryInterface(riid=8e1c39a1) // return hr=80004002
    MyFilter.dll(tid f58)        1 : CSourceFilter::GetState(m_State=0)
    MyFilter.dll(tid f58)        1 : ~CSourceFilter()
    MyFilter.dll(tid f58)        1 : ~CCapturePin()
    MyFilter.dll(tid f58)        2 : CSourceFilter::CreateInstance()
    MyFilter.dll(tid f58)        2 : CSourceFilter()
    MyFilter.dll(tid f58)        2 : CCapturePin() // done
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface(riid=0)
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface // hr=0
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface(riid=37d84f60)
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface // hr=80004002
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface(riid=56a86895)
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface // hr=0
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface(riid=b5730a90)
    MyFilter.dll(tid f58)        2 : CSourceFilter::NonDelegatingQueryInterface // hr=80004002
    MyFilter.dll(tid f58)        2 : ~CSourceFilter() //
    MyFilter.dll(tid f58)        2 : ~CCapturePin() // done
    MyFilter.dll(tid f58)     4806 : CSourceFilter::CreateInstance()
    MyFilter.dll(tid f58)     4806 : CSourceFilter()
    MyFilter.dll(tid f58)     4806 : CCapturePin() // done
    MyFilter.dll(tid f58)     4806 : CSourceFilter::NonDelegatingQueryInterface(riid=0) // return hr=0
    MyFilter.dll(tid f58)     4806 : CSourceFilter::NonDelegatingQueryInterface(riid=37d84f60) // return hr=80004002
    MyFilter.dll(tid f58)     4806 : CSourceFilter::NonDelegatingQueryInterface(riid=56a86895) // return hr=0
    MyFilter.dll(tid f58)     4806 : CSourceFilter::NonDelegatingQueryInterface(riid=8e1c39a1) // return hr=80004002
    MyFilter.dll(tid f58)     4806 : CSourceFilter::NonDelegatingQueryInterface(riid=f90a6130) // return hr=80004002
    MyFilter.dll(tid f58)     4806 : CCapturePin::CheckMediaType() // OK
    MyFilter.dll(tid f58)     4806 : CCapturePin::SetMediaType()
    MyFilter.dll(tid f58)     4806 : CCapturePin::DecideBufferSize()
    MyFilter.dll(tid f58)     4806 : CCapturePin::DecideBufferSize // success
    MyFilter.dll(tid f58)     4806 : CSourceFilter::NonDelegatingQueryInterface..
    (riid=2dd74950)(riid=31efac30)(riid=31efac30 Impl )(riid=f185fe76)(riid=56a86897)
    ...
    CCapturePin::OnThreadCreate()
    MyFilter.dll(tid f58)     4807 : CSourceFilter::NonDelegatingQueryInterface..
    (riid=36b73880)(riid=56a868b2)(riid=2dd74950)riid=56a868b5)(riid=56a868b4)(riid=56a868b3) .. all not impl
    ...
    MyFilter.dll(tid f58)     6336 : CSourceFilter::GetState(m_State=2) // done     # <--- FREEZES HERE SOMETIMES
    CSourcePin::OnThreadDestroy()
    MyFilter.dll(tid 650)     5589 : CSourceFilter::GetState(m_State=0)
    MyFilter.dll(tid 650)     5589 : CSourceFilter::NonDelegatingQueryInterface(riid=f90a6130) // return hr=80004002
    MyFilter.dll(tid 650)     5589 : CSourceFilter::NonDelegatingQueryInterface(riid=0) // return hr=0
    MyFilter.dll(tid 650)     5589 : CSourceFilter::NonDelegatingQueryInterface(riid=8e1c39a1) // return hr=80004002
    MyFilter.dll(tid 650)     5589 : CSourceFilter::GetState(m_State=0)   # All happy it seems

    Friday, October 08, 2010 8:42 PM
  • I'm using exactly freely available Viveks' vcam filter here , I tried your solution,but seems it even can't pass compilation:

     

    error C2440: 'type cast' : cannot convert from 'BYTE *(__thiscall CMediaType::* )(void) const' toVIDEOINFOHEADER *'

     

     

    VIDEOINFOHEADER *mvi = (VIDEOINFOHEADER *)(m_mt.Format);

    Saturday, October 09, 2010 3:56 PM
  • Adjust the compiler strict type-checking or warning level.
    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Sunday, October 10, 2010 6:02 PM
  • As in my screenshot,the problem seems to be in CSourceStream::DoBufferProcessingLoop ,not CVCamStream::SetFormat though...
    Monday, October 11, 2010 3:18 AM
  • As in my screenshot,the problem seems to be in CSourceStream::DoBufferProcessingLoop ,not CVCamStream::SetFormat though...


    if you do not handle SetFormat  your filter can die in DoProcessingLoop .

     

    Think about if you accept a format but have allocated the wrong size.


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Monday, October 11, 2010 8:30 AM
  • P.S.

    You dont have to wait for a crash, you can set a break point inside set media type.

     

    *hint


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Monday, October 11, 2010 8:34 AM
  • I don't have the environment here now,but will try ASAP.

     

    Before the try,I'm wondering why it only happens when trying to turn the filter "off"?

    Monday, October 11, 2010 9:13 AM
  • After I fixed CVCamStream::SetFormat as suggested by @Bowljoman,

    nothing is displayed as output,though it doesn't crash any more when I switch from one filter to another.

     

    Of course ,I'm talking about it in flash player(works fine with GraphEdit)

    Monday, October 11, 2010 1:58 PM
  • Here's someone that asked a very similar question in 2007,

    and his solution is to comment out m_mt = *pmt; I tried ,but again,after that nothing is displayed as output:

     

    http://us.generation-nt.com/answer/vcam-filter-solved-issue-flash-player-help-28610022.html

    Monday, October 11, 2010 4:24 PM
  • Why do you not set a break point inside 'setMediaType()' ? It would probably save you a bunch of time.

    Flash player supports a set of media types and tests them against your filter. As I recall, it does not just try your media types as advertised. I bet it's a try/catch situation too, and possibly, that's how you get multiple vcam instances when bunking up the flash player.

     

     


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Monday, October 11, 2010 7:40 PM
  • I had an Adobe update this morning, something got changed for sure. Now the filter doesn't seems to crash at all, but the negotiation never completes. SetMediaType is called with RGB24 a few times (which is what my filter, and I believe vcam as well, implement).

    ...
    CCaputurePin::GetMediaType( iPosition = 1 ) // NO MORE ITEMS
    CCaputurePin::DecideBufferSize()
    CCaputurePin::DecideBufferSize // return
    CCaputurePin::CheckMediaType()
    CCaputurePin::GetMediaType( iPosition = 0 ) // OK
    CCaputurePin::CheckMediaType() // OK
    CCaputurePin::SetMediaType(0018B360) Maj({73646976-0000-0010-8000-00AA00389B71}) // Video
    CCaputurePin::SetMediaType(0018B360) Sub({E436EB7D-524F-11CE-9F53-0020AF0BA770}) // RGB24
    ...

    It then queries for numerous interfaces including IID_IAMFilterMiscFlags, IID_IReferenceClock, IID_IMediaSeeking, and IBasicVideo, IVideoWindow, IBasicAudio, IMediaPosition, etc

    Monday, October 11, 2010 9:53 PM
  • Through debug I found that after the fix suggested by @Bowljoman,

    CVCamStream::SetMediaType(const CMediaType *pmt) is called repeatedly and FillBuffer(IMediaSample *pms) is never called.

     

    So I guess flash player and vcam filter can't agree on the media format...

    Tuesday, October 12, 2010 2:00 PM
  • Warning: Use at your own risk. Not pretty code, but I didn't have flash player integration issues.

    I can't take time to help with it until I review it and release the entire collection as part of the app framework.

    If the flash player changed this summer, then that is a good thing. If the vCam is broken because of it, then I'll get to fixing  that when I have the time to review.

    Strip out the missing class references and resolve the differences.

    Good luck.

     

    #pragma warning(disable:4244)
    #pragma warning(disable:4711)
    #define WIN32_LEAN_AND_MEAN//winsock =)
    #include <streams.h>
    #include <sstream>
    #include <stdio.h>
    #include <olectl.h>
    #include <dvdmedia.h>
    using namespace std;
    
    #include "filters.h"
    //
    // 
    //
    //////////////////////////////////////////////////////////////////////////
    // CVCam is the source filter which masquerades as a capture device
    //////////////////////////////////////////////////////////////////////////
    CUnknown * WINAPI CVCam::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
    {
      ASSERT(phr);
      CUnknown *punk = new CVCam(lpunk, phr);
      return punk;
    }
    
    CVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) : 
      CSource(NAME("Flex COM"), lpunk, CLSID_FlexCOM)
    {
      ASSERT(phr);
      CAutoLock cAutoLock(&m_cStateLock);
      // Create the one and only output pin
      m_paStreams = (CSourceStream **) new CVCamStream*[1];
      m_paStreams[0] = new CVCamStream(phr, this, L"Flex COM");
    }
    
    HRESULT CVCam::QueryInterface(REFIID riid, void **ppv)
    {
      //Forward request for IAMStreamConfig & IKsPropertySet to the pin
      if(riid == _uuidof(IAMStreamConfig) || 
    		riid == _uuidof(IAMDroppedFrames) ||
    		riid == _uuidof(IKsPropertySet))
        return m_paStreams[0]->QueryInterface(riid, ppv);
      else
        return CSource::QueryInterface(riid, ppv);
    }
    
    //////////////////////////////////////////////////////////////////////////
    // CVCamStream is the one and only output pin of CVCam which handles 
    // all the stuff.
    //////////////////////////////////////////////////////////////////////////
    CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :
      CSourceStream(NAME("Flex COM"),phr, pParent, pPinName), m_pParent(pParent)
    {
    	NumDroppedFrames=0;
    	NumFrames=0;
      GetMediaType(0, &m_mt);
    	adc=new CAutoDC();
    	r5c=new Red5Com();
    	r5c->makeConnection();
    }
    
    CVCamStream::~CVCamStream()
    {
    
    } 
    
    HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)
    {  
      // Standard OLE stuff
      if(riid == _uuidof(IAMStreamConfig))
        *ppv = (IAMStreamConfig*)this;
      else if(riid == _uuidof(IKsPropertySet))
        *ppv = (IKsPropertySet*)this;
    	else if(riid == _uuidof(IAMDroppedFrames) )
    	*ppv = (IAMDroppedFrames*)this;
    	else
        return CSourceStream::QueryInterface(riid, ppv);
    
      AddRef();
      return S_OK;
    }
    
    
    //////////////////////////////////////////////////////////////////////////
    // This is the routine where we create the data being output by the Virtual
    // Camera device.
    //////////////////////////////////////////////////////////////////////////
    
    HRESULT CVCamStream::FillBuffer(IMediaSample *pms)
    {
      
      HRESULT hr=S_OK;
      	
    	
    	//create some working info
    	REFERENCE_TIME rtNow,rtDelta ,rtDelta2=0;//delta for dropped, delta 2 for sleep.
    	REFERENCE_TIME avgFrameTime = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame;
    
    	//What TIme is iT REALLY???
    	m_pParent->GetSyncSource(&m_pClock);
    	
    	m_pClock->GetTime(&refSync1);
    	if(m_pClock)
    		m_pClock->Release ();
    	if(NumFrames<=1)
    	{//initiate values
    		refStart=refSync1;//FirstFrame No Drop.
    		refSync2=0;
     
    	}
    	
    	rtNow = m_rtLastTime;
    	m_rtLastTime = avgFrameTime+m_rtLastTime;
    	
    	//IAMDropppedFrame. We only have avgFrameTime to generate image.
    	// Find generated stream time and compare to real elapsed time
    	rtDelta=((refSync1-refStart)-(((NumFrames)*avgFrameTime)-avgFrameTime));
    	
     if(rtDelta-refSync2<0)
    	{//we are early
    		rtDelta2=rtDelta-refSync2;
    			if( abs(rtDelta2/10000)>=1)
    		Sleep(abs(rtDelta2/10000));
    	}
     else 	if(rtDelta/avgFrameTime>NumDroppedFrames)
    	{	//new dropped frame
    		NumDroppedFrames=rtDelta/avgFrameTime;
    		// Figure new RT for sleeping
    		refSync2=NumDroppedFrames*avgFrameTime;
    		//Our time stamping needs adjustment.
    		//Find total real stream time from start time
    		rtNow=refSync1-refStart;
    		m_rtLastTime=rtNow+avgFrameTime;
    		pms->SetDiscontinuity(true);
    	}
    	pms->SetTime(&rtNow, &m_rtLastTime);
    	pms->SetSyncPoint(TRUE);
    	
      BYTE *pData;
      long lDataLen;
      pms->GetPointer(&pData);
      lDataLen = pms->GetSize();
    	
    	for(int j=0;j<lDataLen;j++)
    	{
    			pData[j]=0x0;
    	}
    
    	adc->TextSample(pData,"Hello world ",3);
    	adc->TextSample(pData,"Whats up? ",4);
    	char buff[36];
    	sprintf(buff,"Frame number %i",NumFrames);
    	
    char* ret=r5c->process();
    
    	adc->TextSample(pData,buff,5);
    //	ShellExecute(NULL,NULL,"C:\\mfc\\dshow\\DirectShow\\CameraServer\\Release\\CameraServer.exe",NULL,NULL,SW_SHOWMINIMIZED);
    	adc->TextSample(pData,ret,6);
    	
    	NumFrames++;
      return NOERROR;
    } // FillBuffer
    
    
    //
    // Notify
    // Ignore quality management messages sent from the downstream filter
    STDMETHODIMP CVCamStream::Notify(IBaseFilter * pSender, Quality q)
    {
      return E_NOTIMPL;
    } // Notify
    
    //////////////////////////////////////////////////////////////////////////
    // This is called when the output format has been negotiated
    //////////////////////////////////////////////////////////////////////////
    HRESULT CVCamStream::SetMediaType(const CMediaType *pmt)
    {
      DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->Format());
      HRESULT hr = CSourceStream::SetMediaType(pmt);
      return hr;
    }
    
    // See Directshow help topic for IAMStreamConfig for details on this method
    HRESULT CVCamStream::GetMediaType(int iPosition, CMediaType *pmt)
    {
      if(iPosition < 0) return E_INVALIDARG;
      if(iPosition >0) return VFW_S_NO_MORE_ITEMS;
    
    
    
      DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER)));
      ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));
    
      pvi->bmiHeader.biCompression = BI_RGB;
      pvi->bmiHeader.biBitCount  = 32;
      pvi->bmiHeader.biSize    = sizeof(BITMAPINFOHEADER);
      pvi->bmiHeader.biWidth   = 320;
      pvi->bmiHeader.biHeight   = 240;
      pvi->bmiHeader.biPlanes   = 1;
      pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
      pvi->bmiHeader.biClrImportant = 0;
    
      pvi->AvgTimePerFrame = 10000000/1;
    
      SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
      SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle
    
      pmt->SetType(&MEDIATYPE_Video);
      pmt->SetFormatType(&FORMAT_VideoInfo);
      pmt->SetTemporalCompression(FALSE);
    
      // Work out the GUID for the subtype from the header info.
      const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
      pmt->SetSubtype(&SubTypeGUID);
      pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);
      
      return NOERROR;
    
    } // GetMediaType
    
    // This method is called to see if a given output format is supported
    HRESULT CVCamStream::CheckMediaType(const CMediaType *pMediaType)
    {
      VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)(pMediaType->Format());
      if(*pMediaType != m_mt) 
        return E_INVALIDARG;
      return S_OK;
    } // CheckMediaType
    
    // This method is called after the pins are connected to allocate buffers to stream data
    HRESULT CVCamStream::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties)
    {
      CAutoLock cAutoLock(m_pFilter->pStateLock());
      HRESULT hr = NOERROR;
    
      VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) m_mt.Format();
      pProperties->cBuffers = 1;
      pProperties->cbBuffer = pvi->bmiHeader.biSizeImage;
    
      ALLOCATOR_PROPERTIES Actual;
      hr = pAlloc->SetProperties(pProperties,&Actual);
    
      if(FAILED(hr)) return hr;
      if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
    
      return NOERROR;
    } // DecideBufferSize
    
    // Called when graph is run
    HRESULT CVCamStream::OnThreadCreate()
    {
      m_rtLastTime = 0;
    	NumDroppedFrames=0;
    	NumFrames=0;
      return NOERROR;
    } // OnThreadCreate
    
    
    //////////////////////////////////////////////////////////////////////////
    // IAMStreamConfig
    //////////////////////////////////////////////////////////////////////////
    
    HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)
    {
    //	return S_OK;
    	if(!pmt)return S_OK;//Default?
    	VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)(pmt->pbFormat);
    	VIDEOINFOHEADER *mvi = (VIDEOINFOHEADER *)(m_mt.Format ());
    	if(pvi->bmiHeader.biHeight !=mvi->bmiHeader.biHeight || 
    		pvi->bmiHeader.biWidth != mvi->bmiHeader.biWidth || 
    		pvi->bmiHeader.biBitCount !=mvi->bmiHeader.biBitCount )
    		return VFW_E_INVALIDMEDIATYPE;	
    
    	if(pvi->AvgTimePerFrame <10000000/30)
    		return VFW_E_INVALIDMEDIATYPE;
    	if(pvi->AvgTimePerFrame <1)
    		return VFW_E_INVALIDMEDIATYPE;
    	
    
    	return S_OK;
    }
    
    HRESULT STDMETHODCALLTYPE CVCamStream::GetFormat(AM_MEDIA_TYPE **ppmt)
    {
      *ppmt = CreateMediaType(&m_mt);
      return S_OK;
    }
    
    HRESULT STDMETHODCALLTYPE CVCamStream::GetNumberOfCapabilities(int *piCount, int *piSize)
    {
      *piCount = 1;
      *piSize = sizeof(VIDEO_STREAM_CONFIG_CAPS);
      return S_OK;
    }
    
    HRESULT STDMETHODCALLTYPE CVCamStream::GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC)
    {
      *pmt = CreateMediaType(&m_mt);
      DECLARE_PTR(VIDEOINFOHEADER, pvi, (*pmt)->pbFormat);
    
      
    
      pvi->bmiHeader.biCompression = BI_RGB;
      pvi->bmiHeader.biBitCount  = 32;
      pvi->bmiHeader.biSize    = sizeof(BITMAPINFOHEADER);
      pvi->bmiHeader.biWidth   = 320;
      pvi->bmiHeader.biHeight   = 240;
      pvi->bmiHeader.biPlanes   = 1;
      pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
      pvi->bmiHeader.biClrImportant = 0;
    
      SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
      SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle
    
      (*pmt)->majortype = MEDIATYPE_Video;
      (*pmt)->subtype = MEDIASUBTYPE_RGB32;
      (*pmt)->formattype = FORMAT_VideoInfo;
      (*pmt)->bTemporalCompression = FALSE;
      (*pmt)->bFixedSizeSamples= FALSE;
      (*pmt)->lSampleSize = pvi->bmiHeader.biSizeImage;
      (*pmt)->cbFormat = sizeof(VIDEOINFOHEADER);
      
      DECLARE_PTR(VIDEO_STREAM_CONFIG_CAPS, pvscc, pSCC);
      
      pvscc->guid = FORMAT_VideoInfo;
      pvscc->VideoStandard = AnalogVideo_None;
      pvscc->InputSize.cx = 320;
      pvscc->InputSize.cy = 240;
      pvscc->MinCroppingSize.cx = 320;
      pvscc->MinCroppingSize.cy = 240;
      pvscc->MaxCroppingSize.cx = 320;
      pvscc->MaxCroppingSize.cy = 240;
      pvscc->CropGranularityX = 0;
      pvscc->CropGranularityY = 0;
      pvscc->CropAlignX = 0;
      pvscc->CropAlignY = 0;
    
      pvscc->MinOutputSize.cx = 320;
      pvscc->MinOutputSize.cy = 240;
      pvscc->MaxOutputSize.cx = 320;
      pvscc->MaxOutputSize.cy = 240;
      pvscc->OutputGranularityX = 0;
      pvscc->OutputGranularityY = 0;
      pvscc->StretchTapsX = 0;
      pvscc->StretchTapsY = 0;
      pvscc->ShrinkTapsX = 0;
      pvscc->ShrinkTapsY = 0;
      pvscc->MinFrameInterval = 200000;  //50 fps
      pvscc->MaxFrameInterval = 50000000; // 0.2 fps
      pvscc->MinBitsPerSecond = (320 * 240 * 4 * 8) / 5;
      pvscc->MaxBitsPerSecond = 320 * 240 * 4 * 8 * 50;
    
      return S_OK;
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    //			IAMDroppedFrames
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    HRESULT STDMETHODCALLTYPE CVCamStream::GetNumNotDropped (long* plNotDropped)
    {
    	
    	if (!plNotDropped) 
    		return E_POINTER;
    	
    	*plNotDropped=NumFrames;
    		return NOERROR;
    }
    HRESULT STDMETHODCALLTYPE CVCamStream::GetNumDropped (long* plDropped)
    {
    
    	if (!plDropped) 
    		return E_POINTER;
    	
    	*plDropped=NumDroppedFrames;
    		return NOERROR;
    }
    HRESULT STDMETHODCALLTYPE CVCamStream::GetDroppedInfo (long lSize,long *plArraym,long* plNumCopied)
    {
    	return E_NOTIMPL;
    }
    HRESULT STDMETHODCALLTYPE CVCamStream::GetAverageFrameSize (long* plAverageSize)
    {
    	if(!plAverageSize)return E_POINTER;
    	*plAverageSize=307200;
    	return S_OK;
    }
    //////////////////////////////////////////////////////////////////////////
    // IKsPropertySet
    //////////////////////////////////////////////////////////////////////////
    
    
    HRESULT CVCamStream::Set(REFGUID guidPropSet, DWORD dwID, void *pInstanceData, 
                DWORD cbInstanceData, void *pPropData, DWORD cbPropData)
    {// Set: Cannot set any properties.
      return E_NOTIMPL;
    }
    
    // Get: Return the pin category (our only property). 
    HRESULT CVCamStream::Get(
      REFGUID guidPropSet,  // Which property set.
      DWORD dwPropID,    // Which property in that set.
      void *pInstanceData,  // Instance data (ignore).
      DWORD cbInstanceData, // Size of the instance data (ignore).
      void *pPropData,    // Buffer to receive the property data.
      DWORD cbPropData,   // Size of the buffer.
      DWORD *pcbReturned   // Return the size of the property.
    )
    {
      if (guidPropSet != AMPROPSETID_Pin)       return E_PROP_SET_UNSUPPORTED;
      if (dwPropID != AMPROPERTY_PIN_CATEGORY)    return E_PROP_ID_UNSUPPORTED;
      if (pPropData == NULL && pcbReturned == NULL)  return E_POINTER;
      
      if (pcbReturned) *pcbReturned = sizeof(GUID);
      if (pPropData == NULL)     return S_OK; // Caller just wants to know the size. 
      if (cbPropData < sizeof(GUID)) return E_UNEXPECTED;// The buffer is too small.
        
      *(GUID *)pPropData = PIN_CATEGORY_CAPTURE;
      return S_OK;
    }
    
    // QuerySupported: Query whether the pin supports the specified property.
    HRESULT CVCamStream::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport)
    {
      if (guidPropSet != AMPROPSETID_Pin) return E_PROP_SET_UNSUPPORTED;
      if (dwPropID != AMPROPERTY_PIN_CATEGORY) return E_PROP_ID_UNSUPPORTED;
      // We support getting this property, but not setting it.
      if (pTypeSupport) *pTypeSupport = KSPROPERTY_SUPPORT_GET; 
      return S_OK;
    }
    


    'what does (int argc, char ** argv) mean?' :) http://thebitstream.com
    Tuesday, October 12, 2010 3:34 PM
  • I finally stripped out missing classes and made it work ,

    but it has the same problem as vcam,say,when I switch from the FlexCOM filter to another ,got the same exception above which leads to crash again.

     

    I'm testing with Flash Player 10,not the latest 10.1 though.

     

    UPDATE

    @Bowljoman, if you have time,please leave your email so that I can send you the swf I'm using to test.It only requires a REAL web cam is available, to switch from one to another.

     

     

     

    Tuesday, October 12, 2010 4:31 PM
  • I cant help at the moment. I have some clients I am attending to.

    Plus I dont want to get into potential SWF code problems. I compile my own swf files.

    If the programmer does not explicitly set your only resolution, you will be out of luck.

     

    I have created a vcam filter at 432 X 240 before with good results, provided the SWF file actually set that resolution.

    In some cases it will do a best case with crop and scale, but more often it does not with the vcam for lack of media type outputs that are configured correctly.


    *I = (Andy*)this;
    Tuesday, October 12, 2010 5:13 PM
  • Now I can't be sure whether it's the action script that has bug or the filter.

     

    Can you try the swf I sent you to see if it crashes your filter so that I can know where the problem lies?

    Thursday, October 14, 2010 4:02 PM
  • No.

    You got some cash?

     

     


    *I = (Andy*)this;
    Thursday, October 14, 2010 10:29 PM
  • @Bowljoman,

    I found a thread from google group  that's supposed to make vcam support arbitrary resolutions :

    http://groups.google.com/group/microsoft.public.win32.programmer.directx.video/browse_thread/thread/2c0fa338a768228d/e871892e0debcfce?pli=1

     

    Sorry, I cant afford the cash for the time being:(

    Friday, October 15, 2010 2:21 AM
  • Vcam works great with the latest flash player provided you follow the tips and tricks outlined before.
    *I = (Andy*)this;
    Friday, October 15, 2010 4:37 PM
  • @Bowljoman, can you provide a modified version of vcam that works with flash player?

     

    I've been suffering this trouble for a long time..... I'll compare bit by bit to see what is wrong

    Saturday, October 16, 2010 9:45 AM
  • Not much more I can do than this.

    http://code.google.com/p/comserver/source/browse/#svn/trunk/demo/comDemo


    *I = (Andy*)this;
    • Proposed as answer by Bowljoman Tuesday, October 19, 2010 6:38 PM
    Saturday, October 16, 2010 5:06 PM
  • @Bowljoman,it's really very nince of you,if you need any help in the future ,I will try my best to help you,just to give you a hand !

     

    Yes,I successfully installed and run your filter,but it's also crashing when switching to a REAL device(I can see the video of Flex_Com though):

    http://i.imgur.com/AoJzu.jpg

     

    Here's the tiny actionscript code I used to test(you can compile it yourself,or I can send you the swf directly:)):

    package
    {
        import fl.controls.ComboBox;
        import flash.display.Sprite;
        import flash.events.NetStatusEvent;
        import flash.events.MouseEvent;
        import flash.events.Event;
        import flash.media.Camera;
        import flash.media.Video;
        import flash.events.ActivityEvent;

        public class cameraswitch extends Sprite
        {
              private var rtmpNow:String;
              private var msg:Boolean;
              private var cam:Camera;
              private var vid1:Video;
              public var firstCam:Date;
              public var vsources:ComboBox;

              function cameraswitch ()
              {
                   addMedia ();
              }

              private function changeVSource(obj:Object)
              {
                    createCam(obj.target.selectedItem.data);
              }
             
              private function createCam(i:String)
              {
                      cam = Camera.getCamera(i);
                      cam.setMode (320,240,24);
                      cam.setQuality (0,90);
                         cam.setMotionLevel (35,3000);
                      if(vid1)
                      {
                        vid1.attachCamera(cam);
                      }
              }
             
              private function addMedia ():void
              {
                      firstCam = new Date();
                     trace(Camera.names);
                      vsources = new ComboBox();
                      var i:String = new String();
                    for(i in Camera.names) {
                           vsources.addItem({label:Camera.names[i],data:i});
                    }
                      createCam("0");
                       vid1=new Video(cam.width,cam.height);
                       vid1.attachCamera (cam);
                       addChild(vsources);
                      vsources.x = 250;
                      vsources.y = 100 + cam.height;
                      vsources.addEventListener("change", changeVSource);
                       addChild (vid1);
                       vid1.x=100;
                       vid1.y=50;
              }
        }
    }

    Sunday, October 17, 2010 1:48 AM
  • Sorry pal, the code is fine, and does not cause a crash.

    Tested it here and switched back and forth many times.

     

    http://red5.org:5080/demos/publisher.html

     

     


    *I = (Andy*)this;
    Sunday, October 17, 2010 10:56 AM
  • @Bowljoman,

     

    I think I've found a way to reproduce ,just switch back and forth several time,and it'll crash when you switch back to Flex_Com the 2nd time.

    Monday, October 18, 2010 1:38 PM
  • No, sorry. It doesn't.

     

    see

     

    I think you need to go back and mark some of the posts I responded to you as 'helpful' and at least one or two were actual answers. You seem to be getting a lot of help, but I'm not getting my rewards.

     

    Everything you said didn't work, seems to be fine. This is more a matter of improving your testing/debug practices

     

     


    *I = (Andy*)this;
    Monday, October 18, 2010 3:13 PM
  • @Bowljoman,sorry for the late votes:)

     

    Strange though it doesn't work for me,I'll test it on a different machine tomorrow.

     

    BTW, do you know whether it's possible to change filter properties with actionscript?

    Tuesday, October 19, 2010 2:09 PM
  • size, frame rate is about all you get to try.
    *I = (Andy*)this;
    Tuesday, October 19, 2010 6:37 PM
  • Can I distinguish/identify requests from flash  in my filter so that I can retrieve corresponding settings from database?
    Wednesday, October 27, 2010 8:57 AM