DirectShow Problem



  • Guten Morgen zusammen,

    ist mein erster Post hier. Hoffe das ihr mir trotzdem weiter helfen könnt.
    Ich möchte für ein Uni Projekt eine Klasse schreiben die einzelne/mehrere Frames aus einem Video holt.
    Das klappt auch ohne Probleme wenn ich allen Code in eine Klasse packe.
    Da ich das aber ordentlich machen wollte, habe ich mir um das ganze DirectShow zu kappseln dafür eine Klasse geschrieben.
    Wenn ich aber in dieser Klasse auf Events warte bekomme ich eine Zugriffsverletzung.
    Meine Befürchtung ist jetzt das ich ein Thread Problem habe.

    Die Funktion die das Problem auslöst, ist das WaitTillEnd() in der DSBaseStream Klasse, die eigentlich nur solange blockieren soll bis das abspielen und damit das grabben der Frames abgeschlossen ist.

    Ich habe den Code mal zum anschauen in ein zip gepackt:
    DirectShow Code

    Mit freundlichen Grüßen
    Jim



  • Morgen,
    Der erste Fehler den ich gefunde habe:

    HRESULT DSBaseStream::SetCallback()
    {
    	HRESULT hr;
    	SampleGrabberCallback sgCallback; // das hier...
    

    ...sollte in class {} sein:

    class DSBaseStream
    {
    	SampleGrabberCallback m_sgCallback;
    


  • DSBaseStream::SetCallback()
    {
    	HRESULT hr;
    	SampleGrabberCallback sgCallback;
    
    	sgCallback.width = index.width;
    	sgCallback.heigth = index.height;
    	sgCallback.callCount = 0;
    	hr = m_Sg->SetCallback(&sgCallback,1);
    
    	return hr;
    }
    

    Ist schon richtig so. Die Klasse wird gebraucht um den Callback zu verarbeiten. Der SampleGrabber Filter erwartet das man die Klasse von ISampleGrabberCB ableitet.
    Ist auch so in DSBaseStream.h gemacht:

    class SampleGrabberCallback :
    	public ISampleGrabberCB
    {
    public:
    	long width;
    	long heigth;
    	long callCount;
    
        // 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)
        {
            return E_NOTIMPL;
        }
    
        STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
    	{
    		if(callCount == 250) {
    			/*
    			ImageSize size(width,heigth,3);
    			Image<uint8> img(size);
    			long count = 0;
    			for(int y=(heigth-1); y>=0; y--) {
    				for(int x=0; x<width; x++) {
    					for(int z=0; z<3; z++) {
    						img(x,y,z) = pBuffer[count];
    						count++;
    					}
    				}
    			}
    			WriteImage(img,"test.png");*/
    		}
    		callCount++;
    
            return S_OK;
    	}
    };
    

    Bis dahin meckert der Debuger auch nicht. Der Fehler taucht wirklich nur auf wenn er

    DSBaseStream::WaitTillEnd()
    {
    	long evCode = 0;
    	//this will throw the error
    	m_Me->WaitForCompletion(INFINITE,&evCode);
    }
    

    ausführen möchte.


Log in to reply