2011-10-16 91 views
0

我在試圖使用我的directshow應用程序中的samplegrabber保存jpg文件,這讓我感到頭疼。該圖運行良好,但是當我啓動CaptureImage()函數時,GetCurrentBuffer會返回「參數不正確」.. hr = -2147024809。SampleGrabber參數不正確

 AMMediaType mediaType = new AMMediaType(); 
     VideoInfoHeader videoInfo = new VideoInfoHeader(); 

     (pSampleGrabber as ISampleGrabber).GetConnectedMediaType(mediaType); 
     videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); 

     int width = videoInfo.BmiHeader.Width; 
     int height = videoInfo.BmiHeader.Height; 
     int size = videoInfo.BmiHeader.ImageSize; 

     DsUtils.FreeAMMediaType(mediaType); 

     int hr = 0; 
     int bufferSize = 0; 
     hr = (pSampleGrabber as ISampleGrabber).GetCurrentBuffer(ref bufferSize, IntPtr.Zero); 
     CheckHR(hr, "Could not get buffer size for image capture."); 
     IntPtr frameBufferPointer = Marshal.AllocCoTaskMem(bufferSize); 
     hr = (pSampleGrabber as ISampleGrabber).GetCurrentBuffer(ref bufferSize, frameBufferPointer); 
     CheckHR(hr, "Could not get buffer size for image capture."); 

     byte[] frameBuffer = new byte[bufferSize]; 
     Marshal.Copy(frameBufferPointer, frameBuffer, 0, bufferSize); 
     Marshal.FreeCoTaskMem(frameBufferPointer); 

     Bitmap frame = new Bitmap(width, height, PixelFormat.Format32bppArgb); 
     Rectangle rect = new Rectangle(0, 0, width, height); 
     BitmapData bmpData = frame.LockBits(rect, ImageLockMode.ReadWrite, frame.PixelFormat); 

     Marshal.Copy(frameBuffer, 0, bmpData.Scan0, bufferSize); 
     frame.UnlockBits(bmpData); 
     frame.RotateFlip(RotateFlipType.RotateNoneFlipY); 

     if (format == "PAL" || format == "NTSC" || format == "NTSC32") 
     { 
      Bitmap sdBitmap = new Bitmap(width, height); 
      Graphics g = Graphics.FromImage((System.Drawing.Image)sdBitmap); 
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
      g.DrawImage(frame, 0, 0, width, height); 
      g.Dispose(); 
      frame = sdBitmap; 
      sdBitmap.Dispose(); 
     } 

     EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, (long)100); 
     ImageCodecInfo jpegInfo = null; 

     foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders()) 
     { 
      if (codec.MimeType.ToLower() == "image/jpeg") 
      { 
       jpegInfo = codec; 
       break; 
      } 
     } 

     EncoderParameters encoderParam = new EncoderParameters(1); 
     encoderParam.Param[0] = qualityParam; 
     double timeStamp = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; 

     frame.Save(@"C:\Records\" + timeStamp.ToString() + ".jpg", jpegInfo, encoderParam); 
     frame.Dispose(); 

文件並保存到了最後,如果我拿出CheckHR檢查然而圖像爲黑色,用正確的寬度和高度,這就是爲什麼我去檢查過了人力資源,看它是否是健康的。顯然不是。我搜索谷歌試圖找出這個問題的錯誤和任何共同的問題,但再次,敲我的頭。 :(

繼承人快看我的圖:。

 int hr = 0; 

     // Graph builder. 
     ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); 
     hr = pBuilder.SetFiltergraph(pGraph); 
     CheckHR(hr, "Can't SetFiltergraph."); 

     // Add Decklink Video Capture. 
     IBaseFilter pDecklinkVideoCapture = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_DecklinkVideoCapture)); 
     hr = pGraph.AddFilter(pDecklinkVideoCapture, "Decklink Video Capture"); 
     CheckHR(hr, "Can't add Decklink Video Capture to graph."); 

     // Get Decklink display format. 
     Dictionary<string, AMMediaType> formats = GetDisplayFormat(pDecklinkVideoCapture); 
     hr = (DsFindPin.ByName(pDecklinkVideoCapture, "Capture") as IAMStreamConfig).SetFormat(formats[format]); 
     CheckHR(hr, "Can't set video format on Decklink Video Capture."); 

     // Add Intel® Media SDK H.264 Encoder. 
     IBaseFilter pIntelMediaSDKH264Encoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_IntelMediaSDKH264Encoder)); 
     hr = pGraph.AddFilter(pIntelMediaSDKH264Encoder, "Intel® Media SDK H.264 Encoder"); 
     CheckHR(hr, "Can't add Intel® Media SDK H.264 Encoder to graph."); 

     // Add Intel® Media SDK MP4 Muxer. 
     IBaseFilter pIntelMediaSDKMP4Muxer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_IntelMediaSDKMP4Muxer)); 
     hr = pGraph.AddFilter(pIntelMediaSDKMP4Muxer, "Intel® Media SDK MP4 Muxer"); 
     CheckHR(hr, "Can't add Intel® Media SDK MP4 Muxer to graph."); 

     // Add File writer. 
     IBaseFilter pFilewriter = (IBaseFilter)new FileWriter(); 
     hr = pGraph.AddFilter(pFilewriter, "File writer"); 
     CheckHR(hr, "Can't add File writer to graph"); 

     // Set destination filename. 
     IFileSinkFilter pFilewriter_sink = pFilewriter as IFileSinkFilter; 

     if (pFilewriter_sink == null) 
     { 
      CheckHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter"); 
     } 

     hr = pFilewriter_sink.SetFileName(destination, null); 
     CheckHR(hr, "Can't set filename."); 

     // Add Smart Tee. 
     IBaseFilter pSmartTee = (IBaseFilter)new SmartTee(); 
     hr = pGraph.AddFilter(pSmartTee, "Smart Tee"); 
     CheckHR(hr, "Can't add Smart Tee to graph."); 

     // Add AVI Decompressor. 
     IBaseFilter pAVIDecompressor2 = (IBaseFilter)new AVIDec(); 
     hr = pGraph.AddFilter(pAVIDecompressor2, "AVI Decompressor"); 
     CheckHR(hr, "Can't add AVI Decompressor to graph."); 

     // Add SampleGrabber. 
     pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber)); 
     hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber"); 
     CheckHR(hr, "Can't add SampleGrabber to graph."); 

     // Set SampleGrabber Media Type. 
     AMMediaType pSampleGrabber_pmt = new AMMediaType(); 
     pSampleGrabber_pmt.majorType = MediaType.Video; 
     pSampleGrabber_pmt.subType = new Guid("{43594448-0000-0010-8000-00AA00389B71}"); 
     pSampleGrabber_pmt.formatType = FormatType.VideoInfo; 
     VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader(); 
     pSampleGrabber_pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pSampleGrabber_format)); 
     Marshal.StructureToPtr(pSampleGrabber_format, pSampleGrabber_pmt.formatPtr, false); 
     hr = ((ISampleGrabber)pSampleGrabber).SetMediaType(pSampleGrabber_pmt); 
     DsUtils.FreeAMMediaType(pSampleGrabber_pmt); 
     CheckHR(hr, "Can't set media type to sample grabber."); 

     // Add Null Renderer. 
     IBaseFilter pNullRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_NullRenderer)); 
     hr = pGraph.AddFilter(pNullRenderer, "Null Renderer"); 
     CheckHR(hr, "Can't add Null Renderer to graph."); 

     // Connect Decklink Video Capture and Smart Tee. 
     hr = pGraph.ConnectDirect(GetPin(pDecklinkVideoCapture, "Capture"), GetPin(pSmartTee, "Input"), null); 
     CheckHR(hr, "Can't connect Decklink Video Capture and Smart Tee."); 

     // Connect Smart Tee and AVI Decompressor. 
     hr = pGraph.ConnectDirect(GetPin(pSmartTee, "Capture"), GetPin(pAVIDecompressor2, "XForm In"), null); 
     CheckHR(hr, "Can't connect Smart Tee and AVI Decompressor."); 

     // Connect AVI Decompressor and Intel® Media SDK H.264 Encoder. 
     hr = pGraph.ConnectDirect(GetPin(pAVIDecompressor2, "XForm Out"), GetPin(pIntelMediaSDKH264Encoder, "In"), null); 
     CheckHR(hr, "Can't connect AVI Decompressor and Intel® Media SDK H.264 Encoder."); 

     // Connect Intel® Media SDK H.264 Encoder and Intel® Media SDK MP4 Muxer. 
     hr = pGraph.ConnectDirect(GetPin(pIntelMediaSDKH264Encoder, "Out"), GetPin(pIntelMediaSDKMP4Muxer, "Input 0"), null); 
     CheckHR(hr, "Can't connect Intel® Media SDK H.264 Encoder and Intel® Media SDK MP4 Muxer."); 

     // Connect Intel® Media SDK MP4 Muxer and File writer. 
     hr = pGraph.ConnectDirect(GetPin(pIntelMediaSDKMP4Muxer, "Output"), GetPin(pFilewriter, "in"), null); 
     CheckHR(hr, "Can't connect Intel® Media SDK MP4 Muxer and File writer."); 

     // Connect Smart Tee and SampleGrabber. 
     hr = pGraph.ConnectDirect(GetPin(pSmartTee, "Preview"), GetPin(pSampleGrabber, "Input"), null); 
     CheckHR(hr, "Can't connect Smart Tee and SampleGrabber."); 

     // Connect SampleGrabber and Null Renderer. 
     hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pNullRenderer, "In"), null); 
     CheckHR(hr, "Can't connect SampleGrabber and Null Renderer."); 

任何建議或想法是最歡迎讓我知道,如果需要更多的信息

乾杯

回答

3

-2147024809。轉換爲十六進制是0x80070057這是E_INVALIDARG

E_INVALIDARG for GetCurrentBuffer表示:樣本沒有被緩存調用ISampleGrabber :: SetBufferSampl ES。

要激活緩衝,請調用值爲TRUE的ISampleGrabber :: SetBufferSamples。

+0

你的權利,我忘了激活緩衝區樣本。我現在無法執行操作,因爲過濾器處於錯誤狀態。如果samplegrabber沒有正確連接,會出現這個錯誤嗎?還有什麼可以導致這個錯誤?謝謝吉姆。 – bl4kh4k

+0

啊,我現在把它連接好了,但最後一個問題,保存的圖像在地平線上是黑色的,底部是紫色的?顏色間距問題? – bl4kh4k

+0

色距是問題,都是固定的。 :) – bl4kh4k