Show
Ignore:
Timestamp:
06/12/07 15:57:23 (7 years ago)
Author:
piers
Message:

Updates to fix grabbers on windows:
- Old vfw Win32 made more robust to failing grabbers
- Win32DS now attempts to select best resolution to fix the selected capture size. It is also now possible to select PAL or NTSC from Signal.. menu to adjust captured video size.
- Altered code so it chooses the capture size before calling RenderStream? on filterGraph - that way the filter graph manager can insert the appropriate colour space converter.
- Uses set_size_cif() in size() - which falls thru to ste_size_411() not handled. Fixed bug in Grabber.cpp: set_size_cif() where width=176 didn't have a break statement.
- tweaked ui-ctrlmenu.tcl so Signal..(type) is set before decimate on - so win32 grabber can use it.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • vic/branches/mpeg4/video/grabber-win32DS.cpp

    r4047 r4064  
    190190   svideoPort = -1; 
    191191   compositePort = -1; 
     192   decimate_ =-1; 
     193   converter_=0; 
     194   cb_mutex_=0; 
     195 
    192196 
    193197   crossbar = crossbarCursor = NULL;   
     
    196200   setport("external"); 
    197201 
    198    basewidth_  = CIF_BASE_WIDTH; 
    199    baseheight_ = CIF_BASE_HEIGHT; 
     202   //basewidth_  = CIF_BASE_WIDTH; 
     203   //baseheight_ = CIF_BASE_HEIGHT; 
    200204   
    201205   /* 
     
    242246   debug_msg("DirectShowGrabber::DirectShowGrabber():  graph builder interface acquired\n"); 
    243247 
    244    // Tell the capture graph builder about the FGM. 
     248   // Tell the capture graph builder about the Filter Graph Manager (FGM). 
    245249   hr = pBuild_->SetFiltergraph(pGraph_); 
    246250   //showErrorMessage(hr); 
     
    251255   debug_msg("DirectShowGrabber::DirectShowGrabber():  graph associated with builder\n"); 
    252256 
    253    // Add the capture filter to the filter graph 
     257   // Add the capture filter (obtained by the DirectShowDevice Scanner) to the filter graph 
    254258   hr = pGraph_->AddFilter(pCaptureFilter_, L"VicCaptureFilter"); 
    255259   //showErrorMessage(hr); 
     
    293297                return; 
    294298   } 
    295    // setCaptureOutputFormat(); 
     299   //Not needed as width & height aren't known yet. 
     300   //setCaptureOutputFormat(); 
    296301    
    297302   findCrossbar(pCaptureFilter_); 
     
    303308   mt_.majortype = MEDIATYPE_Video; 
    304309   mt_.subtype   = MEDIASUBTYPE_RGB24; 
     310   //mt_.subtype   = MEDIASUBTYPE_UYVY; 
     311   //mt_.formattype == FORMAT_VideoInfo; 
    305312   hr            = pSampleGrabber_->SetMediaType(&mt_); 
    306313   //showErrorMessage(hr); 
    307314 
    308315   // Connect the filters    
    309    hr = pBuild_->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
    310                               pCaptureFilter_, pGrabberBaseFilter_, pNullBaseFilter_); 
    311    //showErrorMessage(hr); 
    312    debug_msg("DirectShowGrabber::DirectShowGrabber():  builder render stream\n"); 
     316   //hr = pBuild_->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
     317   //                           pCaptureFilter_, pGrabberBaseFilter_, pNullBaseFilter_); 
     318   //showErrorMessage(hr); 
     319   //debug_msg("DirectShowGrabber::DirectShowGrabber():  builder render stream\n"); 
    313320    
    314321   if (FAILED(hr)) { 
     322          debug_msg("DirectShowGrabber::DirectShowGrabber():  FAILed to build render stream\n"); 
    315323                status_=-1; 
    316324                return; 
     
    325333    debug_msg("~DirectShowGrabber()\n"); 
    326334 
    327     capturing_ = !capturing_; 
    328     hr         = pMediaControl_->Stop(); 
     335    //capturing_ = !capturing_; 
     336    if (capturing_)  
     337        hr  = pMediaControl_->Stop(); 
    329338    //showErrorMessage(hr);     
    330339 
     
    355364      hr = pXBar->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
    356365      if ( SUCCEEDED(hr) ) { 
    357          findCrossbar(pFilter); 
     366        debug_msg("DirectShowGrabber::FindCrossbar()...Found and added\n"); 
     367        findCrossbar(pFilter); 
    358368         pFilter->Release(); 
    359369      } 
     
    417427       } 
    418428    } 
    419  
    420          
    421429        if(strcmp(input_port_, "S-Video")==0){ 
    422430                port = svideoPort; 
     
    445453 
    446454   setsize(); 
    447  
     455   setCaptureOutputFormat(); 
     456   hr = pBuild_->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
     457        pCaptureFilter_, pGrabberBaseFilter_, pNullBaseFilter_); 
    448458   // callback mutex 
     459   if (SUCCEEDED(hr) ) 
     460       debug_msg("DirectShowGrabber::DirectShowGrabber():  builder render stream\n"); 
     461   else { 
     462       debug_msg("DirectShowGrabber::DirectShowGrabber():  FAILED to builder render stream: %x\n", hr); 
     463       stop(); 
     464       return; 
     465   } 
     466 
    449467   cb_mutex_ = CreateMutex(NULL, FALSE, NULL); 
    450468   WaitForSingleObject(cb_mutex_, INFINITE); 
     
    457475   // Run the graph... 
    458476   hr = pMediaControl_->Run(); 
     477   if (SUCCEEDED(hr) ) 
     478       debug_msg("DirectShowGrabber::DirectShowGrabber():  Graph set to Run\n"); 
     479 
    459480   //showErrorMessage(hr); 
    460481 
     
    475496    
    476497   CloseHandle(cb_mutex_);   
    477    delete converter_; 
     498   delete[] converter_; 
    478499   capturing_  = 0;    
    479500   converter_  = 0; 
     
    506527   int rval; 
    507528 
    508    /* 
    509    debug_msg("DirectShowGrabber::grab: thread=%x w=%d h=%d frame_=%p fsize_=%d in=%dx%d out=%dx%d\n", 
     529    
     530   debug_msg("DirectShowGrabber::grab: thread=%x w=%d h=%d bw=%d bh=%d frame_=%p fsize_=%d in=%dx%d out=%dx%d\n", 
    510531             GetCurrentThreadId(), 
    511              basewidth_, baseheight_, frame_, framesize_, 
     532             width_, height_, basewidth_, baseheight_, frame_, framesize_, 
    512533             inw_, inh_, outw_, outh_); 
    513    */ 
     534    
    514535 
    515536   WaitForSingleObject(cb_mutex_, INFINITE); 
     
    556577   VIDEO_STREAM_CONFIG_CAPS scc; 
    557578   HRESULT                  hr; 
     579   VIDEOINFOHEADER          *pVih; 
    558580 
    559581   pConfig   = NULL; 
     
    580602         if( SUCCEEDED(hr) ) { 
    581603            if ((pmtConfig->majortype  == MEDIATYPE_Video)            && 
    582                   (pmtConfig->subtype    == MEDIASUBTYPE_RGB24)       && 
     604                  //(pmtConfig->subtype    == MEDIASUBTYPE_RGB24)       && 
    583605                  (pmtConfig->formattype == FORMAT_VideoInfo)         && 
    584606                  (pmtConfig->cbFormat   >= sizeof (VIDEOINFOHEADER)) && 
     
    588610                               max_width_  = scc.MaxOutputSize.cx; 
    589611                               max_height_ =  scc.MaxOutputSize.cy; 
    590                                         return TRUE; 
    591612 
    592613                           } 
     614                                            debug_msg("Windows GDI BITMAPINFOHEADER follows:\n"); 
     615                    pVih                        = (VIDEOINFOHEADER *)pmtConfig->pbFormat;                          
     616                    debug_msg("biWidth=        %d\n", pVih->bmiHeader.biWidth); 
     617                    debug_msg("biHeight=       %d\n", pVih->bmiHeader.biHeight); 
     618                    debug_msg("biSize=         %d\n", pVih->bmiHeader.biSize); 
     619                    debug_msg("biPlanes=       %d\n", pVih->bmiHeader.biPlanes); 
     620                    debug_msg("biBitCount=     %d\n", pVih->bmiHeader.biBitCount); 
     621                    debug_msg("biCompression=  %d\n", pVih->bmiHeader.biCompression); 
     622                    debug_msg("biSizeImage=    %d\n", pVih->bmiHeader.biSizeImage); 
     623                    debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter); 
     624                    debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter); 
    593625                        } 
    594626                 } 
    595627          } 
    596628   } 
     629   if (max_width_>0)                             
     630       return TRUE; 
     631 
    597632   return FALSE; 
    598633} 
     
    602637   int                      iCount; 
    603638   int                      iSize; 
     639   int                      curr_w=0; 
     640   int                      curr_h=0; 
     641   int                      temp_w, temp_h; 
    604642   VIDEOINFOHEADER          *pVih; 
    605643   VIDEO_STREAM_CONFIG_CAPS scc; 
     
    617655                                     pCaptureFilter_, IID_IAMStreamConfig, (void**)&pConfig); 
    618656   if (FAILED(hr)) { 
    619                 Grabber::status_=-1; 
    620                 return; 
     657        debug_msg("Failed to FindInterface\n"); 
     658        Grabber::status_=-1; 
     659        return; 
    621660   } 
    622661 
     
    635674         if( SUCCEEDED(hr) ) { 
    636675            if ((pmtConfig->majortype  == MEDIATYPE_Video)            && 
    637                   (pmtConfig->subtype    == MEDIASUBTYPE_RGB24)       && 
     676                  //(pmtConfig->subtype    == MEDIASUBTYPE_RGB24)       && 
    638677                  (pmtConfig->formattype == FORMAT_VideoInfo)         && 
    639678                  (pmtConfig->cbFormat   >= sizeof (VIDEOINFOHEADER)) && 
    640                   (pmtConfig->pbFormat   != NULL)                     && 
    641                   (scc.MaxOutputSize.cx >= width_)                    && 
    642                   (scc.MaxOutputSize.cy >= height_)){ 
    643  
    644                pVih                        = (VIDEOINFOHEADER *)pmtConfig->pbFormat;                       
    645                pVih->bmiHeader.biWidth     = width_; 
    646                pVih->bmiHeader.biHeight    = height_; 
    647                pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader); 
    648                // AvgTimePerFrame value that specifies the video frame' 
    649                // average display time, in 100-nanosecond units.  
    650                if (fps_)  
    651                  pVih->AvgTimePerFrame     = 10000000/fps_; 
    652  
    653                debug_msg("Windows GDI BITMAPINFOHEADER follows:\n"); 
    654                debug_msg("biWidth=        %d\n", pVih->bmiHeader.biWidth); 
    655                debug_msg("biHeight=       %d\n", pVih->bmiHeader.biHeight); 
    656                debug_msg("biSize=         %d\n", pVih->bmiHeader.biSize); 
    657                debug_msg("biPlanes=       %d\n", pVih->bmiHeader.biPlanes); 
    658                debug_msg("biBitCount=     %d\n", pVih->bmiHeader.biBitCount); 
    659                debug_msg("biCompression=  %d\n", pVih->bmiHeader.biCompression); 
    660                debug_msg("biSizeImage=    %d\n", pVih->bmiHeader.biSizeImage); 
    661                debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter); 
    662                debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter); 
    663                debug_msg("biClrUsed=      %d\n", pVih->bmiHeader.biClrUsed); 
    664                debug_msg("biClrImportant= %d\n", pVih->bmiHeader.biClrImportant); 
    665  
    666                hr = pConfig->SetFormat(pmtConfig); 
    667                //showErrorMessage(hr); 
    668  
     679                  (pmtConfig->pbFormat   != NULL) /*                  && 
     680                  (scc.MaxOutputSize.cx <= width_)                    && 
     681                  (scc.MaxOutputSize.cy <= height_)*/){ 
     682 
     683               if ((abs(width_ - scc.MaxOutputSize.cx) + abs(height_ - scc.MaxOutputSize.cy))< 
     684                   (abs(width_ - curr_w) +abs(height_ - curr_h))) { 
     685 
     686                    pVih                        = (VIDEOINFOHEADER *)pmtConfig->pbFormat;                          
     687                    //pVih->bmiHeader.biWidth     = width_; 
     688                    //pVih->bmiHeader.biWidth     = 320; 
     689                    //pVih->bmiHeader.biHeight    = height_; 
     690                    //pVih->bmiHeader.biHeight    = 240; 
     691                    //pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader); 
     692                    // AvgTimePerFrame value that specifies the video frame' 
     693                    // average display time, in 100-nanosecond units.  
     694                    //if (fps_)  
     695                        // pVih->AvgTimePerFrame           = 10000000/fps_; 
     696 
     697                    debug_msg("fps_= %d\n", fps_); 
     698 
     699                    debug_msg("Windows GDI BITMAPINFOHEADER follows:\n"); 
     700                    debug_msg("biWidth=        %d\n", pVih->bmiHeader.biWidth); 
     701                    debug_msg("biHeight=       %d\n", pVih->bmiHeader.biHeight); 
     702                    debug_msg("biSize=         %d\n", pVih->bmiHeader.biSize); 
     703                    debug_msg("biPlanes=       %d\n", pVih->bmiHeader.biPlanes); 
     704                    debug_msg("biBitCount=     %d\n", pVih->bmiHeader.biBitCount); 
     705                    debug_msg("biCompression=  %d\n", pVih->bmiHeader.biCompression); 
     706                    debug_msg("biSizeImage=    %d\n", pVih->bmiHeader.biSizeImage); 
     707                    debug_msg("biXPelsPerMeter=%d\n", pVih->bmiHeader.biXPelsPerMeter); 
     708                    debug_msg("biYPelsPerMeter=%d\n", pVih->bmiHeader.biYPelsPerMeter); 
     709                    debug_msg("biClrUsed=      %d\n", pVih->bmiHeader.biClrUsed); 
     710                    debug_msg("biClrImportant= %d\n", pVih->bmiHeader.biClrImportant); 
     711 
     712                    //pmtConfig->subtype    = MEDIASUBTYPE_RGB24; 
     713                    temp_w = pVih->bmiHeader.biWidth; 
     714                    temp_h = pVih->bmiHeader.biHeight; 
     715                    pVih->bmiHeader.biWidth     = width_; 
     716                    pVih->bmiHeader.biHeight    = height_; 
     717                    hr = pConfig->SetFormat(pmtConfig); 
     718                    if (SUCCEEDED(hr)) { 
     719                        curr_w = width_; 
     720                        curr_h = height_; 
     721                        formatSet = 1; 
     722                        debug_msg("Set(wxh): %dx%d, and Got: %dx%d\n",width_,height_, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight); 
     723                        break; 
     724                    } else { 
     725                        if ((temp_w < width_) && (temp_h < height_)) { 
     726                            pVih->bmiHeader.biWidth = temp_w; 
     727                            pVih->bmiHeader.biHeight = temp_h; 
     728                            hr = pConfig->SetFormat(pmtConfig); 
     729                            if (SUCCEEDED(hr)) { 
     730                                curr_w = temp_w; 
     731                                curr_h = temp_h; 
     732                                formatSet = 1; 
     733                                debug_msg("Set(wxh): %dx%d, and Got: %dx%d\n",width_,height_, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight); 
     734                            } 
     735                        } else { 
     736                            debug_msg("Failed to Set format this time - trying again\n"); 
     737                        } 
     738                    } 
     739               } 
    669740               // XXX:  leak.  need to deal with this - msp 
    670741               //DeleteMediaType(pmtConfig); 
    671                formatSet = 1; 
    672 //               break; 
    673  
    674742            } 
    675743         } 
     
    678746   pConfig->Release(); 
    679747 
    680    if( formatSet ) 
    681       debug_msg("DirectShowGrabber::setCaptureOutputFormat:  format set\n"); 
     748   if ( formatSet ) { 
     749      if ( (curr_w != width_) || (curr_h != height_ )) { 
     750           width_  = curr_w; 
     751           height_ = curr_h; 
     752           debug_msg("DirectShowGrabber::setCaptureOutputFormat:  format set to near res: %dx%d\n",width_,height_); 
     753      } else  
     754           debug_msg("DirectShowGrabber::setCaptureOutputFormat:  format set\n"); 
     755   } 
    682756   else 
    683757      debug_msg("DirectShowGrabber::setCaptureOutputFormat:  format not set\n"); 
     
    700774            decimate_ = dec; 
    701775            if (running_) { 
    702                stop(); 
    703                setsize(); 
    704                            setCaptureOutputFormat(); 
    705                start(); 
    706                         } else{ 
    707                setsize(); 
    708                            setCaptureOutputFormat(); 
    709                         } 
     776                   stop(); 
     777                   setsize(); 
     778                   setCaptureOutputFormat(); 
     779                   start(); 
     780            } else{ 
     781                   setsize(); 
     782                   setCaptureOutputFormat(); 
     783            } 
    710784         } 
    711785         return (TCL_OK); 
    712786      } else if (strcmp(argv[1], "port") == 0) { 
    713787         setport(argv[2]); 
     788         return (TCL_OK); 
     789      } else if (strcmp(argv[1], "type") == 0) { 
     790         if (strcmp(argv[2], "auto") == 0) 
     791                   ; 
     792         else if (strcmp(argv[2], "pal") == 0) { 
     793                basewidth_  = CIF_BASE_WIDTH; 
     794                baseheight_ = CIF_BASE_HEIGHT; 
     795         } else if (strcmp(argv[2], "ntsc") == 0) { 
     796                basewidth_  = NTSC_BASE_WIDTH; 
     797                baseheight_ = NTSC_BASE_HEIGHT; 
     798         } 
     799         if (running_) { 
     800                   stop(); 
     801                   setsize(); 
     802                   setCaptureOutputFormat(); 
     803                   start(); 
     804         } else if (decimate_!=-1) { 
     805                   setsize(); 
     806                   setCaptureOutputFormat(); 
     807         } 
    714808         return (TCL_OK); 
    715809      } else if (strcmp(argv[1], "useconfig") ==0) { 
     
    752846   if(max_width_ >= D1_BASE_WIDTH){ 
    753847          max_width_ = D1_BASE_WIDTH; 
    754       max_height_ = D1_BASE_HEIGHT; 
     848          max_height_ = D1_BASE_HEIGHT; 
    755849   } 
    756850 
     
    758852       width_ = max_width_; 
    759853       height_ = max_height_; 
    760    }else{ 
     854   } else { 
    761855       width_ = basewidth_  / decimate_; 
    762856       height_ = baseheight_ / decimate_; 
     
    765859   debug_msg("DirectShowCIFGrabber::setsize: %dx%d\n", width_, height_); 
    766860 
    767    set_size_411(width_, height_); 
     861   set_size_cif(width_, height_); 
    768862   allocref(); 
    769863} 
     
    780874   directShowFilter_  = pCapFilt;            
    781875   //SV: XXX got rid of 422 format since there's no grabber returned for it and vic crashes 
    782    attributes_        = "format { 422 411 } size { large small cif } port { external-in } "; 
     876   attributes_        = "format { 411 } size { large small cif } port { external-in } type {pal ntsc} "; 
    783877   DirectShowCIFGrabber o(directShowFilter_);  
    784878    
    785    strcat(attri, "format { 411 } size { large small cif } port { "); 
     879   strcat(attri, "format { 411 } size { large small cif } type { pal ntsc } port { "); 
    786880   if(o.hasSVideo() || o.hasComposite()){ 
    787881     if(o.hasSVideo()){ 
     
    797891   strcat(attri, "} ");  
    798892   attributes_ = attri; 
    799  
    800893} 
    801894