SampleGrabber参数不正确

时间:2011-10-16 23:25:32

标签: c# directshow

我正在试图在我的directshow应用程序中使用samplegrabber保存jpg文件。图表运行正常,但是当我启动CaptureImage()函数时,它获取GetCurrentBuffer并返回“参数不正确”.. hr = -2147024809。

        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检查但是图像是黑色的,具有正确的宽度和高度,这就是为什么我去检查HR以查看它是否健康。显然不是。我搜索谷歌试图弄清楚错误和问题的任何常见问题,但再次,敲打我的脑袋。 :(

快速浏览我的图表:

        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.");

欢迎任何建议或想法。如果需要更多信息,请与我们联系。

干杯。

1 个答案:

答案 0 :(得分:3)

转换为十六进制的

-2147024809是0x80070057,即E_INVALIDARG。

GetCurrentBuffer的E_INVALIDARG表示:样本未被缓冲。调用ISampleGrabber :: SetBufferSamples。

要激活缓冲,请调用值为TRUE的ISampleGrabber :: SetBufferSamples。