0

YUYとMJPGの両方の色空間を実行できるWebカメラがあります。このカメラのデフォルトはYUYですが、プログラムでMJPGでカメラを起動するには、DirectShowグラフに何を変更または追加する必要がありますか?私のコードは、DirectShow.NetサンプルディレクトリにあるDxSnapの例に似ている、典型的なグラフの設定に非常に似ています。これに関するドキュメントはほとんどありません。私が見た唯一のサンプルは、キャプチャピンのプロパティページを表示し、そのUIを介して変更することですが、私のテクニックはプログラムで実装する必要があります。ヘルプ、ガイダンス、アドバイスをいただければ幸いです。ありがとうございました

これが私のグラフの構成です。

/// <summary> build the capture graph for grabber. </summary>
    private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight)
    {
        int hr;

        ISampleGrabber sampGrabber = null;

        ICaptureGraphBuilder2 capGraph = null;

        // Get the graphbuilder object
        m_graphBuilder = (IFilterGraph2)new FilterGraph();
        m_mediaCtrl = m_graphBuilder as IMediaControl;
        try
        {
            // Get the ICaptureGraphBuilder2
            capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();

            // Get the SampleGrabber interface
            sampGrabber = (ISampleGrabber)new SampleGrabber();

            // Start building the graph
            hr = capGraph.SetFiltergraph(m_graphBuilder);
            DsError.ThrowExceptionForHR(hr);

            // Add the video device
            hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, "Video input", out capFilter);
            DsError.ThrowExceptionForHR(hr);

            IBaseFilter baseGrabFlt = (IBaseFilter)sampGrabber;
            ConfigureSampleGrabber(sampGrabber);

            // Add the frame grabber to the graph
            hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
            DsError.ThrowExceptionForHR(hr);

            // Get list of video compressors on the system
            DsDevice[] videoCompressors = DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory);

            IBaseFilter videoCompressorFilter = null;
            string videoCompressor = "MJPEG Compressor";
            foreach (DsDevice compressor in videoCompressors)
            {
                if (compressor.Name == videoCompressor)
                {
                    object obj = null;
                    Guid bfGuid = typeof(IBaseFilter).GUID;
                    compressor.Mon.BindToObject(null, null, ref bfGuid, out obj);
                    videoCompressorFilter = obj as IBaseFilter;
                    break; // Found the compressor - stop looking for it
                }

            }

            if (videoCompressorFilter != null)
            {
                hr = m_graphBuilder.AddFilter(videoCompressorFilter, videoCompressor);
                DsError.ThrowExceptionForHR(hr);
            }


            // If any of the default config items are set
            if (iFrameRate + iHeight + iWidth > 0)
            {
                SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight);
            }


            hr = capGraph.RenderStream(PinCategory.Capture, MediaType.Video, capFilter, null, baseGrabFlt);
            DsError.ThrowExceptionForHR(hr);

            SaveSizeInfo(sampGrabber);

        }
        finally
        {

            if (sampGrabber != null)
            {
                Marshal.ReleaseComObject(sampGrabber);
                sampGrabber = null;
            }
            if (capGraph != null)
            {
                Marshal.ReleaseComObject(capGraph);
                capGraph = null;
            }
        }
    }

    private void SaveSizeInfo(ISampleGrabber sampGrabber)
    {
        int hr;

        // Get the media type from the SampleGrabber
        AMMediaType media = new AMMediaType();
        hr = sampGrabber.GetConnectedMediaType(media);
        DsError.ThrowExceptionForHR(hr);

        if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
        {
            throw new NotSupportedException("Unknown ISampleGrabber Media Format");
        }

        // Grab the size info
        VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
        m_videoWidth = videoInfoHeader.BmiHeader.Width;
        m_videoHeight = videoInfoHeader.BmiHeader.Height;
        m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);

        DsUtils.FreeAMMediaType(media);
        media = null;
    }
    private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
    {
        AMMediaType media;
        int hr;

        // Set the media type to Video/RBG24
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.MJPG;
        media.formatType = FormatType.VideoInfo;
        hr = sampGrabber.SetMediaType(media);
        DsError.ThrowExceptionForHR(hr);

        DsUtils.FreeAMMediaType(media);
        media = null;

        // Configure the samplegrabber
        hr = sampGrabber.SetCallback(this, 1);
        DsError.ThrowExceptionForHR(hr);
    }

フレームコールバックの関数:

    void OnFrameDone()
    {
        try
        {
            int w = Width;
            int h = Height;
            if (((w < 32) || (h < 32)))
            {                   
                return;
            }

            int stride = w * 3;

            lock (this)
            {
                GCHandle handle = GCHandle.Alloc(savedArray, GCHandleType.Pinned);
                int scan0 = (int)handle.AddrOfPinnedObject();
                scan0 += (h - 1) * stride;
                Bitmap b = new Bitmap(w, h, -stride, PixelFormat.Format24bppRgb, (IntPtr)scan0);


                //switch (FrameDirection)
                //{
                //    case VideoDir.Portrait:
                //        b.RotateFlip(RotateFlipType.Rotate90FlipNone);
                //        break;

                //    case VideoDir.Landscape:
                //        b.RotateFlip(RotateFlipType.Rotate180FlipNone);
                //        b.RotateFlip(RotateFlipType.Rotate180FlipNone);
                //        break;

                //}

                if(FrameCaptureComplete != null)
                    FrameCaptureComplete(b);

                handle.Free();
            }

        }
        catch (Exception ex)
        {
            string error = ex.Message;
        }


        return;

    }
4

2 に答える 2

1

カメラが非標準的な方法でそれを行わない限り、IAMStreamConfig出力ピンのインターフェイスを公開する必要があります。ここで、対象のメディアタイプをSetFormatメソッドに提供することでフォーマットを選択できます。完了したら、グラフを作成し、ピンを下流に接続し続けます。

于 2012-09-29T20:04:36.390 に答える
1

この試行錯誤のすべてを通して、私の研究は、私の努力が正確に失敗した試みではなかったという結論に達しました。Microsoft MJPEG Decompressorが3MPの解像度を超えて動作していません。私は、5MPでグラフを実行しようとしていました。5MPを実行できるサードパーティのMJPEGCompressorを使用すると、発生していたすべての問題が修正されました。

ローマン、助けてくれてありがとう。

于 2012-10-03T13:33:44.247 に答える