Changeset 396:e83a54f67a91 in mediastreamer2


Ignore:
Timestamp:
Apr 1, 2009 10:52:48 PM (4 years ago)
Author:
smorlat <smorlat@…>
Branch:
default
Message:

new directshow filter works

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@399 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

Location:
linphone
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • linphone/gtk-glade/linphone.h

    r371 r396  
    2424 
    2525#ifndef LINPHONE_VERSION 
    26 #define LINPHONE_VERSION "3.1.0" 
     26#define LINPHONE_VERSION "3.1.0-20090401" 
    2727#endif 
    2828 
  • linphone/mediastreamer2/plugins/msdscap/mdscap.cc

    r393 r396  
    444444ComPtr< IPin > getPin( IBaseFilter *filter, PIN_DIRECTION direction, int num ) 
    445445{ 
    446   ComPtr< IPin > retVal; 
    447   ComPtr< IEnumPins > enumPins; 
    448   COERRORMACRO( filter->EnumPins( &enumPins ), Error, , 
    449                 "Error getting pin enumerator" ); 
    450   ULONG found; 
    451   ComPtr< IPin > pin; 
    452   while ( enumPins->Next( 1, &pin, &found ) == S_OK ) { 
    453     PIN_DIRECTION pinDirection = (PIN_DIRECTION)( -1 ); 
    454     pin->QueryDirection( &pinDirection ); 
    455     if ( pinDirection == direction ) { 
    456       if ( num == 0 ) { 
    457         retVal = pin; 
    458         break; 
    459       }; 
    460       num--; 
    461     }; 
    462   }; 
    463   return retVal; 
    464 } 
    465  
    466 struct DscapState; 
    467  
    468 class MSCallback: public ISampleGrabberCB 
    469 { 
     446        ComPtr< IPin > retVal; 
     447        ComPtr< IEnumPins > enumPins; 
     448        if (filter->EnumPins( &enumPins )!=S_OK){ 
     449                ms_error("Error getting pin enumerator" ); 
     450                return retVal; 
     451        } 
     452        ULONG found; 
     453        ComPtr< IPin > pin; 
     454        while ( enumPins->Next( 1, &pin, &found ) == S_OK ) { 
     455                PIN_DIRECTION pinDirection = (PIN_DIRECTION)( -1 ); 
     456                pin->QueryDirection( &pinDirection ); 
     457                if ( pinDirection == direction ) { 
     458                        if ( num == 0 ) { 
     459                                retVal = pin; 
     460                                break; 
     461                        }; 
     462                        num--; 
     463                }; 
     464        }; 
     465        return retVal; 
     466} 
     467 
     468 
     469 
     470class DSCapture : public ISampleGrabberCB{ 
    470471public: 
    471   MSCallback(DscapState *s); 
    472   virtual ~MSCallback(void); 
    473   STDMETHODIMP QueryInterface( REFIID riid, void **ppv ); 
    474   STDMETHODIMP_(ULONG) AddRef(void); 
    475   STDMETHODIMP_(ULONG) Release(void); 
    476   STDMETHODIMP SampleCB(double,IMediaSample*); 
    477   STDMETHODIMP BufferCB(double,BYTE*,long); 
     472        DSCapture(){ 
     473                qinit(&_rq); 
     474                ms_mutex_init(&_mutex,NULL); 
     475                _vsize=MS_VIDEO_SIZE_CIF; 
     476                _fps=15; 
     477                _start_time=0; 
     478                _frame_count=0; 
     479                _pixfmt=MS_YUV420P; 
     480        } 
     481        virtual ~DSCapture(){ 
     482                flushq(&_rq,0); 
     483                ms_mutex_destroy(&_mutex); 
     484        } 
     485        STDMETHODIMP QueryInterface( REFIID riid, void **ppv ); 
     486        STDMETHODIMP_(ULONG) AddRef(void); 
     487        STDMETHODIMP_(ULONG) Release(void); 
     488        STDMETHODIMP SampleCB(double,IMediaSample*); 
     489        STDMETHODIMP BufferCB(double,BYTE*,long); 
     490        int startDshowGraph(); 
     491        void stopAndClean(); 
     492        mblk_t *readFrame(){ 
     493                mblk_t *ret=NULL; 
     494                ms_mutex_lock(&_mutex); 
     495                ret=getq(&_rq); 
     496                ms_mutex_unlock(&_mutex); 
     497                return ret; 
     498        } 
     499        bool isTimeToSend(uint64_t ticker_time); 
     500        MSVideoSize getVSize()const{ 
     501                return _vsize; 
     502        } 
     503        void setVSize(MSVideoSize vsize){ 
     504                _vsize=vsize; 
     505        } 
     506        void setFps(float fps){ 
     507                _fps=fps; 
     508        } 
     509        MSPixFmt getPixFmt()const{ 
     510                return _pixfmt; 
     511        } 
     512        void setDeviceIndex(int index){ 
     513                _devid=index; 
     514        } 
    478515protected: 
    479   long m_refCount; 
    480   DscapState *mState; 
    481 }; 
    482  
    483 #if 1 
    484 using namespace std; 
    485  
    486 int toto(void) 
    487 { 
    488   int retVal = 0; 
    489   bool initialized = false; 
    490   MSCallback *callback = NULL; 
    491   try { 
    492     COERRORMACRO( CoInitialize(NULL), Error, , "CoInitialize failed" ); 
    493     initialized = true; 
    494     ComPtr< IGraphBuilder > graphBuilder; 
    495     graphBuilder.coCreateInstance( CLSID_FilterGraph, IID_IGraphBuilder, 
    496                                    "Could not create graph builder " 
    497                                    "interface" ); 
    498     cerr << "graphBuilder is " << graphBuilder.get() << endl; 
    499     ComPtr< ICreateDevEnum > createDevEnum; 
    500     createDevEnum.coCreateInstance( CLSID_SystemDeviceEnum, 
    501                                     IID_ICreateDevEnum, "Could not create " 
    502                                     "device enumerator" ); 
    503     ComPtr< IEnumMoniker > enumMoniker; 
    504     COERRORMACRO( createDevEnum->CreateClassEnumerator 
    505                   ( CLSID_VideoInputDeviceCategory, &enumMoniker, 0 ), Error, , 
    506                   "Error requesting moniker enumerator" ); 
    507     createDevEnum.reset(); 
    508     COERRORMACRO( enumMoniker->Reset(), Error, , 
    509                   "Error resetting moniker enumerator" ); 
    510     int index = 0; 
    511     ComPtr< IMoniker > moniker; 
    512     for ( int i=0; i<=index; i++ ) { 
    513       ULONG fetched = 0; 
    514       COERRORMACRO( enumMoniker->Next( 1, &moniker, &fetched ), Error, , 
    515                     "Error fetching next moniker" ); 
    516     }; 
    517     enumMoniker.reset(); 
    518     ComPtr< IBaseFilter > source; 
    519     COERRORMACRO( moniker->BindToObject( 0, 0, IID_IBaseFilter, 
    520                                          (void **)&source ), Error, , 
    521                   "Error binding moniker to base filter" ); 
    522     moniker.reset(); 
    523     COERRORMACRO( graphBuilder->AddFilter( source.get(), L"Source" ), 
    524                   Error, , "Error adding camera source to filter graph" ); 
    525     ComPtr< IPin > sourceOut = getPin( source.get(), PINDIR_OUTPUT, 0 ); 
    526     ERRORMACRO( sourceOut.get() != NULL, Error, , 
    527                 "Error getting output pin of camera source" ); 
    528     ComPtr< IAMStreamConfig > streamConfig; 
    529     COERRORMACRO( sourceOut-> 
    530                   QueryInterface( IID_IAMStreamConfig, 
    531                                   (void **)&streamConfig ), 
    532                   Error, , "Error requesting stream configuration API" ); 
    533     int count, size; 
    534     COERRORMACRO( streamConfig->GetNumberOfCapabilities( &count, &size ), 
    535                   Error, , "Error getting number of capabilities" ); 
    536     bool ok = false; 
    537     for ( int i=0; i<count; i++ ) { 
    538       VIDEO_STREAM_CONFIG_CAPS videoConfig; 
    539       AM_MEDIA_TYPE *mediaType; 
    540       COERRORMACRO( streamConfig->GetStreamCaps( i, &mediaType, 
    541                                                  (BYTE *)&videoConfig ), 
    542                     Error, , "Error getting stream capabilities" ); 
    543       if ( mediaType->majortype == MEDIATYPE_Video && 
    544            mediaType->cbFormat != 0 ) { 
    545         VIDEOINFOHEADER *infoHeader = (VIDEOINFOHEADER*)mediaType->pbFormat; 
    546         // TODO: choose format here !!! 
    547         ms_message("Setting format %ix%i",infoHeader->bmiHeader.biWidth,infoHeader->bmiHeader.biHeight); 
    548         streamConfig->SetFormat( mediaType ); 
    549         ok = true; 
    550       }; 
    551       if ( mediaType->cbFormat != 0 ) 
    552         CoTaskMemFree( (PVOID)mediaType->pbFormat ); 
    553       if ( mediaType->pUnk != NULL ) mediaType->pUnk->Release(); 
    554       CoTaskMemFree( (PVOID)mediaType ); 
    555       if ( ok ) 
    556         break; 
    557     }; 
    558     streamConfig.reset(); 
    559     ERRORMACRO( ok, Error, , "Could not find any video format" ); 
    560  
    561     ComPtr< IBaseFilter > grabberBase; 
    562     COERRORMACRO( CoCreateInstance( CLSID_SampleGrabber, NULL, 
    563                                     CLSCTX_INPROC, IID_IBaseFilter, 
    564                                     (void **)&grabberBase ), 
    565                   Error, , "Error creating sample grabber" ); 
    566     COERRORMACRO( graphBuilder->AddFilter( grabberBase.get(), L"Grabber" ), 
    567                   Error, , "Error adding sample grabber to filter graph" ); 
    568     ComPtr< ISampleGrabber > sampleGrabber; 
    569     COERRORMACRO( grabberBase->QueryInterface( IID_ISampleGrabber, 
    570                                                (void **)&sampleGrabber ), 
    571                   Error, , "Error requesting sample grabber interface" ); 
    572     COERRORMACRO( sampleGrabber->SetOneShot( FALSE ), Error, , 
    573                   "Error disabling one-shot mode" ); 
    574     COERRORMACRO( sampleGrabber->SetBufferSamples( TRUE ), Error, , 
    575                   "Error enabling buffer sampling" ); 
    576     callback = new MSCallback(NULL); 
    577     COERRORMACRO( sampleGrabber->SetCallBack( callback, 0 ), Error, , 
    578                   "Error setting callback interface for grabbing" ); 
    579     ComPtr< IPin > grabberIn = getPin( grabberBase.get(), PINDIR_INPUT, 0 ); 
    580     ERRORMACRO( grabberIn.get() != NULL, Error, , 
    581                 "Error getting input of sample grabber" ); 
    582     ComPtr< IPin > grabberOut = getPin( grabberBase.get(), PINDIR_OUTPUT, 0 ); 
    583     ERRORMACRO( grabberOut.get() != NULL, Error, , 
    584                 "Error getting output of sample grabber" ); 
    585  
    586     ComPtr< IBaseFilter > nullRenderer; 
    587     COERRORMACRO( CoCreateInstance( CLSID_NullRenderer, NULL, 
    588                                     CLSCTX_INPROC, IID_IBaseFilter, 
    589                                     (void **)&nullRenderer ), 
    590                   Error, , "Error creating Null Renderer" ); 
    591     COERRORMACRO( graphBuilder->AddFilter( nullRenderer.get(), L"Sink" ), 
    592                   Error, , "Error adding null renderer to filter graph" ); 
    593     ComPtr< IPin > nullIn = getPin( nullRenderer.get(), PINDIR_INPUT, 0 ); 
    594  
    595     cerr << endl << "Attempting to connect" << endl; 
    596     COERRORMACRO( graphBuilder->Connect( sourceOut.get(), grabberIn.get() ), 
    597                   Error, , "Error connecting source to sample grabber" ); 
    598     COERRORMACRO( graphBuilder->Connect( grabberOut.get(), nullIn.get() ), 
    599                   Error, , "Error connecting sample grabber to sink" ); 
    600  
    601     cerr << "Success!!!!!!!!!!!!!!!!!!!!!" << endl; 
    602  
    603     ComPtr< IMediaControl > mediaControl; 
    604     COERRORMACRO( graphBuilder->QueryInterface( IID_IMediaControl, 
    605                                                 (void **)&mediaControl ), 
    606                   Error, , "Error requesting media control interface" ); 
    607     COERRORMACRO( mediaControl->Run(), Error, , "Error running graph" ); 
    608  
    609     ComPtr< IMediaEvent > mediaEvent; 
    610     COERRORMACRO( graphBuilder->QueryInterface( IID_IMediaEvent, 
    611                                                 (void **)&mediaEvent ), 
    612                   Error, , "Error requesting event interface" ); 
    613  
    614     cin.get(); 
    615  
    616     mediaControl->Stop(); 
    617  
    618     long evCode = 0; 
    619     mediaEvent->WaitForCompletion( INFINITE, &evCode ); 
    620  
    621     // sourceOut.reset(); 
    622     // sinkIn.reset(); 
    623     // source.reset(); 
    624   } catch ( Error &e ) { 
    625     cerr << e.what() << endl; 
    626     retVal = 1; 
    627   }; 
    628   if ( callback != NULL ) callback->Release(); 
    629   if ( initialized ) CoUninitialize(); 
    630   return retVal; 
    631 } 
    632  
    633 #endif  
    634  
    635 struct DscapState{ 
    636         DscapState(){ 
    637                 callback=0; 
    638         } 
    639         ~DscapState(){ 
    640                 if (callback) callback->Release(); 
    641         } 
    642         int devid; 
    643         MSVideoSize vsize; 
    644         queue_t rq; 
    645         ms_mutex_t mutex; 
    646         int frame_ind; 
    647         int frame_max; 
    648         float fps; 
    649         float start_time; 
    650         int frame_count; 
    651         MSPixFmt fmt; 
    652         ComPtr< IBaseFilter > source; 
    653         ComPtr< IBaseFilter > nullRenderer; 
    654         ComPtr< IBaseFilter > grabberBase; 
    655         ComPtr< IMediaControl > mediaControl; 
    656         ComPtr< IMediaEvent > mediaEvent; 
    657         MSCallback * callback; 
    658 }; 
    659  
    660  
    661  
    662 MSCallback::MSCallback(DscapState *s): m_refCount(1), mState(s) 
    663 { 
    664 } 
    665  
    666 MSCallback::~MSCallback(void) 
    667 { 
    668   ms_message("MSCallback::~MSCallback"); 
    669 } 
    670  
    671 STDMETHODIMP MSCallback::QueryInterface(REFIID riid, void **ppv) 
    672 { 
    673 #ifndef NDEBUG 
    674         ms_message("MSCallback::QueryInterface"); 
    675 #endif 
     516        long m_refCount; 
     517private: 
     518        int     selectBestFormat(ComPtr<IAMStreamConfig> streamConfig, int count); 
     519        int _devid; 
     520        MSVideoSize _vsize; 
     521        queue_t _rq; 
     522        ms_mutex_t _mutex; 
     523        float _fps; 
     524        float _start_time; 
     525        int _frame_count; 
     526        MSPixFmt _pixfmt; 
     527        ComPtr< IBaseFilter > _source; 
     528        ComPtr< IBaseFilter > _nullRenderer; 
     529        ComPtr< IBaseFilter > _grabberBase; 
     530        ComPtr< IMediaControl > _mediaControl; 
     531        ComPtr< IMediaEvent > _mediaEvent; 
     532}; 
     533 
     534 
     535STDMETHODIMP DSCapture::QueryInterface(REFIID riid, void **ppv) 
     536{ 
    676537  HRESULT retval; 
    677538  if ( ppv == NULL ) return E_POINTER; 
     
    707568}; 
    708569 
    709 STDMETHODIMP_(ULONG) MSCallback::AddRef(void) 
    710 { 
    711         ms_message("MSCallback::AddRef"); 
    712   m_refCount++; 
    713   return m_refCount; 
    714 } 
    715  
    716 STDMETHODIMP_(ULONG) MSCallback::Release(void) 
    717 { 
    718   ms_message("MSCallback::Release"); 
    719  
     570STDMETHODIMP_(ULONG) DSCapture::AddRef(){ 
     571        m_refCount++; 
     572        return m_refCount; 
     573} 
     574 
     575STDMETHODIMP_(ULONG) DSCapture::Release() 
     576{ 
     577  ms_message("DSCapture::Release"); 
    720578  if ( !InterlockedDecrement( &m_refCount ) ) { 
    721579                int refcnt=m_refCount; 
     
    729587} 
    730588 
    731 STDMETHODIMP MSCallback::SampleCB( double par1 , IMediaSample * sample) 
     589STDMETHODIMP DSCapture::SampleCB( double par1 , IMediaSample * sample) 
    732590{ 
    733591        uint8_t *p; 
     
    738596        } 
    739597        size=sample->GetSize(); 
    740         ms_message( "MSCallback::SampleCB pointer=%p, size=%i",p,size); 
     598        //ms_message( "DSCapture::SampleCB pointer=%p, size=%i",p,size); 
    741599        mblk_t *m=esballoc(p,size,0,dummy); 
    742600        m->b_wptr+=size; 
    743         ms_mutex_lock(&mState->mutex); 
    744         putq(&mState->rq,m); 
    745         ms_mutex_unlock(&mState->mutex); 
     601        ms_mutex_lock(&_mutex); 
     602        putq(&_rq,m); 
     603        ms_mutex_unlock(&_mutex); 
    746604        return S_OK; 
    747605} 
     
    749607 
    750608 
    751 STDMETHODIMP MSCallback::BufferCB( double, BYTE *b, long len) 
    752 { 
    753         ms_message("MSCallback::BufferCB"); 
    754  
     609STDMETHODIMP DSCapture::BufferCB( double, BYTE *b, long len) 
     610{ 
     611        ms_message("DSCapture::BufferCB"); 
    755612        return S_OK; 
    756613} 
    757614 
    758615static void dscap_init(MSFilter *f){ 
    759         DscapState *s=new DscapState; 
    760         s->vsize.width=MS_VIDEO_SIZE_CIF_W; 
    761         s->vsize.height=MS_VIDEO_SIZE_CIF_H; 
    762         qinit(&s->rq); 
    763         ms_mutex_init(&s->mutex,NULL); 
    764         s->start_time=0; 
    765         s->frame_count=-1; 
    766         s->fps=15; 
    767         s->fmt=MS_YUV420P; 
     616        DSCapture *s=new DSCapture(); 
    768617        f->data=s; 
    769618} 
     
    772621 
    773622static void dscap_uninit(MSFilter *f){ 
    774         DscapState *s=(DscapState*)f->data; 
    775         flushq(&s->rq,0); 
    776         ms_mutex_destroy(&s->mutex); 
    777         delete s; 
     623        DSCapture *s=(DSCapture*)f->data; 
     624        s->Release(); 
    778625} 
    779626 
     
    826673} 
    827674 
    828 static int select_best_format(DscapState *s, ComPtr<IAMStreamConfig> streamConfig, int count){ 
     675int DSCapture::selectBestFormat(ComPtr<IAMStreamConfig> streamConfig, int count){ 
    829676        int index; 
    830         s->fmt=MS_YUV420P; 
    831         index=find_best_format(streamConfig, count, &s->vsize, s->fmt); 
     677        _pixfmt=MS_YUV420P; 
     678        index=find_best_format(streamConfig, count, &_vsize, _pixfmt); 
    832679        if (index!=-1) goto success; 
    833         s->fmt=MS_YUY2; 
    834         index=find_best_format(streamConfig, count, &s->vsize, s->fmt); 
     680        _pixfmt=MS_YUY2; 
     681        index=find_best_format(streamConfig, count, &_vsize,_pixfmt); 
    835682        if (index!=-1) goto success; 
    836         s->fmt=MS_YUYV; 
    837         index=find_best_format(streamConfig, count, &s->vsize, s->fmt); 
     683        _pixfmt=MS_YUYV; 
     684        index=find_best_format(streamConfig, count, &_vsize, _pixfmt); 
    838685        if (index!=-1) goto success; 
    839         s->fmt=MS_RGB24; 
    840         index=find_best_format(streamConfig, count, &s->vsize, s->fmt); 
     686        _pixfmt=MS_RGB24; 
     687        index=find_best_format(streamConfig, count, &_vsize, _pixfmt); 
    841688        if (index!=-1) { 
    842                 s->fmt=MS_RGB24_REV; 
     689                _pixfmt=MS_RGB24_REV; 
    843690                goto success; 
    844691        } 
     
    856703} 
    857704 
    858 static void create_dshow_graph(DscapState *s){ 
     705int DSCapture::startDshowGraph(){ 
    859706        ComPtr< ICreateDevEnum > createDevEnum; 
    860         COERRORMACRO( CoInitialize(NULL), Error, , "CoInitialize failed" ); 
     707        CoInitialize(NULL); 
    861708    createDevEnum.coCreateInstance( CLSID_SystemDeviceEnum, 
    862709                                    IID_ICreateDevEnum, "Could not create " 
     
    865712    if (createDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &enumMoniker, 0 )!=S_OK){ 
    866713                ms_error("Fail to create class enumerator."); 
    867                 return; 
     714                return -1; 
    868715        } 
    869716    createDevEnum.reset(); 
     
    878725    ComPtr< IMoniker > moniker; 
    879726    for ( int i=0;enumMoniker->Next( 1, &moniker, &fetched )==S_OK;++i ) { 
    880                 if (i==s->devid){ 
    881                         if (moniker->BindToObject( 0, 0, IID_IBaseFilter, (void **)&s->source )!=S_OK){ 
     727                if (i==_devid){ 
     728                        if (moniker->BindToObject( 0, 0, IID_IBaseFilter, (void **)&_source )!=S_OK){ 
    882729                                ms_error("Error binding moniker to base filter" ); 
    883                                 return; 
     730                                return -1; 
    884731                        } 
    885732                } 
    886733        } 
    887         if (s->source.get()==0){ 
    888                 ms_error("Could not interface with webcam devid=%i",s->devid); 
    889                 return; 
     734        if (_source.get()==0){ 
     735                ms_error("Could not interface with webcam devid=%i",_devid); 
     736                return -1; 
    890737        } 
    891738        moniker.reset(); 
    892739    enumMoniker.reset(); 
    893     s->callback = new MSCallback(s); 
    894     ms_message("Callback created"); 
    895     fflush(NULL); 
    896     try{ 
    897     COERRORMACRO( graphBuilder->AddFilter( s->source.get(), L"Source" ), 
    898                   Error, , "Error adding camera source to filter graph" ); 
    899     ComPtr< IPin > sourceOut = getPin( s->source.get(), PINDIR_OUTPUT, 0 ); 
    900     ERRORMACRO( sourceOut.get() != NULL, Error, , 
    901                 "Error getting output pin of camera source" ); 
     740    if (graphBuilder->AddFilter( _source.get(), L"Source" )!=S_OK){ 
     741        ms_error("Error adding camera source to filter graph" ); 
     742        return -1; 
     743        } 
     744    ComPtr< IPin > sourceOut = getPin( _source.get(), PINDIR_OUTPUT, 0 ); 
     745    if (sourceOut.get()==NULL){ 
     746                ms_error("Error getting output pin of camera source" ); 
     747                return -1; 
     748        } 
    902749    ComPtr< IAMStreamConfig > streamConfig; 
    903     COERRORMACRO( sourceOut-> 
    904                   QueryInterface( IID_IAMStreamConfig, 
    905                                   (void **)&streamConfig ), 
    906                   Error, , "Error requesting stream configuration API" ); 
     750    if (sourceOut->QueryInterface( IID_IAMStreamConfig, 
     751                                  (void **)&streamConfig )!=S_OK){ 
     752        ms_error("Error requesting stream configuration API" ); 
     753        return -1; 
     754        } 
    907755    int count, size; 
    908     COERRORMACRO( streamConfig->GetNumberOfCapabilities( &count, &size ), 
    909                   Error, , "Error getting number of capabilities" ); 
    910     select_best_format(s,streamConfig,count); 
    911      
     756    if (streamConfig->GetNumberOfCapabilities( &count, &size )!=S_OK){ 
     757        ms_error("Error getting number of capabilities" ); 
     758        return -1; 
     759        } 
     760    if (selectBestFormat(streamConfig,count)!=0){ 
     761                return -1; 
     762        } 
    912763    streamConfig.reset(); 
    913764 
    914     COERRORMACRO( CoCreateInstance( CLSID_SampleGrabber, NULL, 
     765    if (CoCreateInstance( CLSID_SampleGrabber, NULL, 
    915766                                    CLSCTX_INPROC, IID_IBaseFilter, 
    916                                     (void **)&s->grabberBase ), 
    917                   Error, , "Error creating sample grabber" ); 
    918     COERRORMACRO( graphBuilder->AddFilter( s->grabberBase.get(), L"Grabber" ), 
    919                   Error, , "Error adding sample grabber to filter graph" ); 
     767                                    (void **)&_grabberBase )!=S_OK){ 
     768        ms_error("Error creating sample grabber" ); 
     769        return -1; 
     770        } 
     771    if (graphBuilder->AddFilter( _grabberBase.get(), L"Grabber" )!=S_OK){ 
     772                ms_error("Error adding sample grabber to filter graph"); 
     773                return -1; 
     774        } 
    920775    ComPtr< ISampleGrabber > sampleGrabber; 
    921     COERRORMACRO( s->grabberBase->QueryInterface( IID_ISampleGrabber, 
    922                                                (void **)&sampleGrabber ), 
    923                   Error, , "Error requesting sample grabber interface" ); 
    924     COERRORMACRO( sampleGrabber->SetOneShot( FALSE ), Error, , 
    925                   "Error disabling one-shot mode" ); 
    926     COERRORMACRO( sampleGrabber->SetBufferSamples( TRUE ), Error, , 
    927                   "Error enabling buffer sampling" ); 
    928  
    929     COERRORMACRO( sampleGrabber->SetCallBack( s->callback, 0 ), Error, , 
    930                   "Error setting callback interface for grabbing" ); 
    931     ComPtr< IPin > grabberIn = getPin( s->grabberBase.get(), PINDIR_INPUT, 0 ); 
    932     ERRORMACRO( grabberIn.get() != NULL, Error, , 
    933                 "Error getting input of sample grabber" ); 
    934     ComPtr< IPin > grabberOut = getPin( s->grabberBase.get(), PINDIR_OUTPUT, 0 ); 
    935     ERRORMACRO( grabberOut.get() != NULL, Error, , 
    936                 "Error getting output of sample grabber" ); 
    937  
    938      
    939     COERRORMACRO( CoCreateInstance( CLSID_NullRenderer, NULL, 
     776    if (_grabberBase->QueryInterface( IID_ISampleGrabber, 
     777                                               (void **)&sampleGrabber )!=S_OK){ 
     778                ms_error("Error requesting sample grabber interface"); 
     779                return -1; 
     780        } 
     781    if (sampleGrabber->SetOneShot( FALSE )!=S_OK){ 
     782        ms_error("Error disabling one-shot mode" ); 
     783        return -1; 
     784        } 
     785    if (sampleGrabber->SetBufferSamples( TRUE )!=S_OK){ 
     786        ms_error("Error enabling buffer sampling" ); 
     787        return -1; 
     788        } 
     789        if (sampleGrabber->SetCallBack(this, 0 )!=S_OK){ 
     790                ms_error("Error setting callback interface for grabbing" ); 
     791                return -1; 
     792        } 
     793    ComPtr< IPin > grabberIn = getPin( _grabberBase.get(), PINDIR_INPUT, 0 ); 
     794    if (grabberIn.get() == NULL){ 
     795        ms_error("Error getting input of sample grabber"); 
     796                return -1; 
     797        } 
     798    ComPtr< IPin > grabberOut = getPin( _grabberBase.get(), PINDIR_OUTPUT, 0 ); 
     799        if (grabberOut.get()==NULL){ 
     800                ms_error("Error getting output of sample grabber" ); 
     801                return -1; 
     802        } 
     803    if (CoCreateInstance( CLSID_NullRenderer, NULL, 
    940804                                    CLSCTX_INPROC, IID_IBaseFilter, 
    941                                     (void **)&s->nullRenderer ), 
    942                   Error, , "Error creating Null Renderer" ); 
    943     COERRORMACRO( graphBuilder->AddFilter( s->nullRenderer.get(), L"Sink" ), 
    944                   Error, , "Error adding null renderer to filter graph" ); 
    945     ComPtr< IPin > nullIn = getPin( s->nullRenderer.get(), PINDIR_INPUT, 0 ); 
    946  
    947     ms_message("Attempting to connect"); 
    948     COERRORMACRO( graphBuilder->Connect( sourceOut.get(), grabberIn.get() ), 
    949                   Error, , "Error connecting source to sample grabber" ); 
    950     COERRORMACRO( graphBuilder->Connect( grabberOut.get(), nullIn.get() ), 
    951                   Error, , "Error connecting sample grabber to sink" ); 
    952  
    953     ms_message("Success!!!!!!!!!!!!!!!!!!!!!"); 
    954  
    955  
    956         ms_message("Querying control interface"); 
    957     COERRORMACRO( graphBuilder->QueryInterface( IID_IMediaControl, 
    958                                                 (void **)&s->mediaControl ), 
    959                   Error, , "Error requesting media control interface" ); 
    960         ms_message("Got the control interface (%p).",s->mediaControl.get()); 
    961     ms_message("Going to start the graph"); 
    962     HRESULT r; 
    963         if ((r=s->mediaControl->Run())!=S_OK){ 
     805                                    (void **)&_nullRenderer )!=S_OK){ 
     806                ms_error("Error creating Null Renderer" ); 
     807                return -1; 
     808        } 
     809        if (graphBuilder->AddFilter( _nullRenderer.get(), L"Sink" )!=S_OK){ 
     810        ms_error("Error adding null renderer to filter graph" ); 
     811        return -1; 
     812        } 
     813    ComPtr< IPin > nullIn = getPin( _nullRenderer.get(), PINDIR_INPUT, 0 ); 
     814        if (graphBuilder->Connect( sourceOut.get(), grabberIn.get() )!=S_OK){ 
     815        ms_error("Error connecting source to sample grabber" ); 
     816        return -1; 
     817        } 
     818    if (graphBuilder->Connect( grabberOut.get(), nullIn.get() )!=S_OK){ 
     819        ms_error("Error connecting sample grabber to sink" ); 
     820        return -1; 
     821        } 
     822    ms_message("Directshow graph is now ready to run."); 
     823 
     824    if (graphBuilder->QueryInterface( IID_IMediaControl, 
     825                                                (void **)&_mediaControl )!=S_OK){ 
     826        ms_error("Error requesting media control interface" ); 
     827                return -1; 
     828        } 
     829    HRESULT r=_mediaControl->Run(); 
     830        if (r!=S_OK && r!=S_FALSE){ 
    964831                ms_error("Error starting graph (%i)",r); 
    965832        } 
    966833    ms_message("Graph started"); 
    967     COERRORMACRO( graphBuilder->QueryInterface( IID_IMediaEvent, 
    968                                                 (void **)&s->mediaEvent ), 
    969                   Error, , "Error requesting event interface" ); 
    970     ms_message("Graph created"); 
    971         } catch ( Error &e ) { 
    972         ms_error(e.what()); 
    973         }; 
     834    if (graphBuilder->QueryInterface( IID_IMediaEvent, 
     835                                        (void **)&_mediaEvent )!=S_OK){ 
     836        ms_error("Error requesting event interface" ); 
     837        return -1; 
     838        } 
     839} 
     840 
     841void DSCapture::stopAndClean(){ 
     842        if (_mediaControl.get()!=NULL){ 
     843                _mediaControl->Stop(); 
     844        long evCode = 0; 
     845        _mediaEvent->WaitForCompletion( INFINITE, &evCode ); 
     846        } 
     847        _source.reset(); 
     848        _grabberBase.reset(); 
     849        _nullRenderer.reset(); 
     850        _mediaControl.reset(); 
     851        _mediaEvent.reset(); 
     852        flushq(&_rq,0); 
     853} 
     854 
     855bool DSCapture::isTimeToSend(uint64_t ticker_time){ 
     856        if (_frame_count==-1){ 
     857                _start_time=(float)ticker_time; 
     858                _frame_count=0; 
     859        } 
     860        int cur_frame=(int)(((float)ticker_time-_start_time)*_fps/1000.0); 
     861        if (cur_frame>_frame_count){ 
     862                _frame_count++; 
     863                return true; 
     864        } 
     865        return false; 
    974866} 
    975867 
    976868static void dscap_preprocess(MSFilter * obj){ 
    977         DscapState *s=(DscapState*)obj->data; 
    978         create_dshow_graph(s); 
    979         //toto(); 
    980     ms_message("preprocess done."); 
     869        DSCapture *s=(DSCapture*)obj->data; 
     870        s->startDshowGraph(); 
    981871} 
    982872 
    983873static void dscap_postprocess(MSFilter * obj){ 
    984         DscapState *s=(DscapState*)obj->data; 
    985         if (s->mediaControl.get()!=NULL){ 
    986                 s->mediaControl->Stop(); 
    987         long evCode = 0; 
    988         s->mediaEvent->WaitForCompletion( INFINITE, &evCode ); 
    989         } 
    990         flushq(&s->rq,0); 
     874        DSCapture *s=(DSCapture*)obj->data; 
     875        s->stopAndClean(); 
    991876} 
    992877 
    993878static void dscap_process(MSFilter * obj){ 
    994         DscapState *s=(DscapState*)obj->data; 
     879        DSCapture *s=(DSCapture*)obj->data; 
    995880        mblk_t *m; 
    996881        uint32_t timestamp; 
    997882        int cur_frame; 
    998883 
    999         if (s->frame_count==-1){ 
    1000                 s->start_time=(float)obj->ticker->time; 
    1001                 s->frame_count=0; 
    1002         } 
    1003  
    1004         cur_frame=(int)((obj->ticker->time-s->start_time)*s->fps/1000.0); 
    1005         if (cur_frame>s->frame_count){ 
     884        if (s->isTimeToSend(obj->ticker->time)){ 
    1006885                mblk_t *om=NULL; 
    1007886                /*keep the most recent frame if several frames have been captured */ 
    1008                  
    1009                 ms_mutex_lock(&s->mutex); 
    1010                 while((m=getq(&s->rq))!=NULL){ 
    1011                         ms_mutex_unlock(&s->mutex); 
     887                while((m=s->readFrame())!=NULL){ 
    1012888                        if (om!=NULL) freemsg(om); 
    1013889                        om=m; 
    1014                         ms_mutex_lock(&s->mutex); 
    1015890                } 
    1016                 ms_mutex_unlock(&s->mutex); 
    1017891                if (om!=NULL){ 
    1018892                        timestamp=(uint32_t)(obj->ticker->time*90);/* rtp uses a 90000 Hz clockrate for video*/ 
     
    1020894                        ms_queue_put(obj->outputs[0],om); 
    1021895                } 
    1022                 s->frame_count++; 
    1023896        } 
    1024897} 
    1025898 
    1026899static int dscap_set_fps(MSFilter *f, void *arg){ 
    1027         DscapState *s=(DscapState*)f->data; 
    1028         s->fps=*((float*)arg); 
     900        DSCapture *s=(DSCapture*)f->data; 
     901        s->setFps(*(float*)arg); 
    1029902        return 0; 
    1030903} 
    1031904 
    1032905static int dscap_get_pix_fmt(MSFilter *f,void *arg){ 
    1033         DscapState *s=(DscapState*)f->data; 
    1034         *((MSPixFmt*)arg)=s->fmt; 
     906        DSCapture *s=(DSCapture*)f->data; 
     907        *((MSPixFmt*)arg)=s->getPixFmt(); 
    1035908        return 0; 
    1036909} 
    1037910 
    1038911static int dscap_set_vsize(MSFilter *f, void *arg){ 
    1039         DscapState *s=(DscapState*)f->data; 
    1040         s->vsize=*((MSVideoSize*)arg); 
     912        DSCapture *s=(DSCapture*)f->data; 
     913        s->setVSize(*((MSVideoSize*)arg)); 
    1041914        return 0; 
    1042915} 
    1043916 
    1044917static int dscap_get_vsize(MSFilter *f, void *arg){ 
    1045         DscapState *s=(DscapState*)f->data; 
     918        DSCapture *s=(DSCapture*)f->data; 
    1046919        MSVideoSize *vs=(MSVideoSize*)arg; 
    1047         *vs=s->vsize; 
     920        *vs=s->getVSize(); 
    1048921        return 0; 
    1049922} 
     
    1077950static MSFilter * ms_dshow_create_reader(MSWebCam *obj){ 
    1078951        MSFilter *f=ms_filter_new_from_desc(&ms_dscap_desc); 
    1079         DscapState *s=(DscapState*)f->data; 
    1080         s->devid=(int)obj->data; 
     952        DSCapture *s=(DSCapture*)f->data; 
     953        s->setDeviceIndex((int)obj->data); 
    1081954        return f; 
    1082955} 
     
    1095968        ComPtr<IPropertyBag> pBag; 
    1096969         
    1097         COERRORMACRO( CoInitialize(NULL), Error, , "CoInitialize failed" ); 
     970        CoInitialize(NULL); 
    1098971  
    1099972    ComPtr< ICreateDevEnum > createDevEnum; 
Note: See TracChangeset for help on using the changeset viewer.