Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何在C中使用DirectShowLib从内存流播放视频文件#_Arrays_Byte_Memorystream - Fatal编程技术网

Arrays 如何在C中使用DirectShowLib从内存流播放视频文件#

Arrays 如何在C中使用DirectShowLib从内存流播放视频文件#,arrays,byte,memorystream,Arrays,Byte,Memorystream,我正在从事一个项目,其中视频文件有非标准头,它使用H264算法,文件为.avi格式。问题是该文件不包含.avi标准头,该头是自定义的,我想执行以下操作 以字节数组的形式加载内存中的视频流(例如IO.stream或DirectShow.IStream) 从视频的每个帧(字节数组)中删除标头 获取其余的帧数据(原始视频数据)并将其提供给DirectShowLib 使用DirectShowLib播放原始视频数据 请指导我如何在这种情况下在GrapherDitPlus中创建图形,附上示例图像 using

我正在从事一个项目,其中视频文件有非标准头,它使用H264算法,文件为.avi格式。问题是该文件不包含.avi标准头,该头是自定义的,我想执行以下操作

  • 以字节数组的形式加载内存中的视频流(例如IO.stream或DirectShow.IStream)
  • 从视频的每个帧(字节数组)中删除标头
  • 获取其余的帧数据(原始视频数据)并将其提供给DirectShowLib
  • 使用DirectShowLib播放原始视频数据
  • 请指导我如何在这种情况下在GrapherDitPlus中创建图形,附上示例图像

    using DirectShowLib;
    
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        //[STAThread]
        //static void Main(string[] args)
        //{
        //    Application.EnableVisualStyles();
        //    Application.SetCompatibleTextRenderingDefault(false);
        //    Application.Run(new Form1());
        //}
    
    
    
    
        static void checkHR(int hr, string msg)
        {
            if (hr < 0)
            {
                Console.WriteLine(msg);
                DsError.ThrowExceptionForHR(hr);
            }
        }
    
        static void BuildGraph(IGraphBuilder pGraph, string srcFile1)
        {
            int hr = 0;
    
            //graph builder
            ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
            hr = pBuilder.SetFiltergraph(pGraph);
            checkHR(hr, "Can't SetFiltergraph");
    
            Guid CLSID_Mpeg4sDecoderDMO = new Guid("{2A11BAE2-FE6E-4249-864B-9E9ED6E8DBC2}"); //DMO
            Guid CLSID_Mpeg4sDecoderDMO_cat = new Guid("{4A69B442-28BE-4991-969C-B500ADF5D8A8}"); //DMO category
            Guid CLSID_MP3DecoderDMO = new Guid("{BBEEA841-0A63-4F52-A7AB-A9B3A84ED38A}"); //DMO
            Guid CLSID_MP3DecoderDMO_cat = new Guid("{57F2DB8B-E6BB-4513-9D43-DCD2A6593125}"); //DMO category
            Guid CLSID_VideoRenderer = new Guid("{B87BEB7B-8D29-423F-AE4D-6582C10175AC}"); //quartz.dll
            Guid CLSID_SampleGrabber = new Guid("{C1F400A0-3F08-11D3-9F0B-006008039E37}"); //qedit.dll
    
            Guid CLSID_Filestreamrenderer = new Guid("{D51BD5A5-7548-11CF-A520-0080C77EF58A}"); //quartz.dll
    
            //add File stream renderer
            IBaseFilter pFilestreamrenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_Filestreamrenderer));
            hr = pGraph.AddFilter(pFilestreamrenderer, "File stream renderer");
            checkHR(hr, "Can't add File stream renderer to graph");
    
    
    
            //add File Source (Async.)
            IBaseFilter pFileSourceAsync = (IBaseFilter)new AsyncReader();
            hr = pGraph.AddFilter(pFileSourceAsync, "File Source (Async.)");
            checkHR(hr, "Can't add File Source (Async.) to graph");
    
    
    
            //set source filename
            IFileSourceFilter pFileSourceAsync_src = pFileSourceAsync as IFileSourceFilter;
            if (pFileSourceAsync_src == null)
                checkHR(unchecked((int)0x80004002), "Can't get IFileSourceFilter");
            hr = pFileSourceAsync_src.Load(srcFile1, null);
            checkHR(hr, "Can't load file");
    
            //add AVI Splitter
            IBaseFilter pAVISplitter = (IBaseFilter)new AviSplitter();
            hr = pGraph.AddFilter(pAVISplitter, "AVI Splitter");
            checkHR(hr, "Can't add AVI Splitter to graph");
    
            //connect File Source (Async.) and AVI Splitter
            hr = pGraph.ConnectDirect(GetPin(pFileSourceAsync, "Output"), GetPin(pAVISplitter, "input pin"), null);
            checkHR(hr, "Can't connect File Source (Async.) and AVI Splitter");
    
            //add Mpeg4s Decoder DMO
            IBaseFilter pMpeg4sDecoderDMO = (IBaseFilter)new DMOWrapperFilter();
            var pMpeg4sDecoderDMO_wrapper = pMpeg4sDecoderDMO as IDMOWrapperFilter;
            if (pMpeg4sDecoderDMO_wrapper == null)
                checkHR(unchecked((int)0x80004002), "Can't get IDMOWrapperFilter");
            hr = pMpeg4sDecoderDMO_wrapper.Init(CLSID_Mpeg4sDecoderDMO, CLSID_Mpeg4sDecoderDMO_cat);
            checkHR(hr, "DMO Wrapper Init failed");
            hr = pGraph.AddFilter(pMpeg4sDecoderDMO, "Mpeg4s Decoder DMO");
            checkHR(hr, "Can't add Mpeg4s Decoder DMO to graph");
    
            //add MP3 Decoder DMO
            IBaseFilter pMP3DecoderDMO = (IBaseFilter)new DMOWrapperFilter();
            var pMP3DecoderDMO_wrapper = pMP3DecoderDMO as IDMOWrapperFilter;
            if (pMP3DecoderDMO_wrapper == null)
                checkHR(unchecked((int)0x80004002), "Can't get IDMOWrapperFilter");
            hr = pMP3DecoderDMO_wrapper.Init(CLSID_MP3DecoderDMO, CLSID_MP3DecoderDMO_cat);
            checkHR(hr, "DMO Wrapper Init failed");
            hr = pGraph.AddFilter(pMP3DecoderDMO, "MP3 Decoder DMO");
            checkHR(hr, "Can't add MP3 Decoder DMO to graph");
    
            //connect AVI Splitter and MP3 Decoder DMO
            hr = pGraph.ConnectDirect(GetPin(pAVISplitter, "Stream 01"), GetPin(pMP3DecoderDMO, "in0"), null);
            checkHR(hr, "Can't connect AVI Splitter and MP3 Decoder DMO");
    
            //add Video Renderer
            IBaseFilter pVideoRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_VideoRenderer));
            hr = pGraph.AddFilter(pVideoRenderer, "Video Renderer");
            checkHR(hr, "Can't add Video Renderer to graph");
    
            //add Default DirectSound Device
            IBaseFilter pDefaultDirectSoundDevice = (IBaseFilter)new DSoundRender();
            hr = pGraph.AddFilter(pDefaultDirectSoundDevice, "Default DirectSound Device");
            checkHR(hr, "Can't add Default DirectSound Device to graph");
    
            //connect MP3 Decoder DMO and Default DirectSound Device
            hr = pGraph.ConnectDirect(GetPin(pMP3DecoderDMO, "out0"), GetPin(pDefaultDirectSoundDevice, "Audio Input pin (rendered)"), null);
            checkHR(hr, "Can't connect MP3 Decoder DMO and Default DirectSound Device");
    
            //add SampleGrabber
            IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
            hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
            checkHR(hr, "Can't add SampleGrabber to graph");
    
            ISampleGrabber _sampleGrabber = ((ISampleGrabber)pSampleGrabber);
            _sampleGrabber.SetOneShot(false);
            _sampleGrabber.SetBufferSamples(false);
            SampleGrabberCallback _sampleGrabberCallback = new SampleGrabberCallback();
    
            //hr = ((ISampleGrabber)pSampleGrabber).SetBufferSamples(false);
            //if (hr == 0)
            //{
            //    hr = ((ISampleGrabber)pSampleGrabber).SetOneShot(false);
            //}
            //if (hr == 0)
            //{
            //    hr = ((ISampleGrabber)pSampleGrabber).SetCallback(_sampleGrabberCallback, 0);
            //}
            //if (hr < 0)
            //{
            //    Marshal.ThrowExceptionForHR(hr);
            //}
    
            //set callback
            hr = _sampleGrabber.SetCallback(new SampleGrabberCallback(), 0);
            checkHR(hr, "Can't set callback.");
    
            AMMediaType pSampleGrabber_pmt = new AMMediaType();
            pSampleGrabber_pmt.majorType = MediaType.Video;
            pSampleGrabber_pmt.subType = MediaSubType.YUY2;
            pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
            pSampleGrabber_pmt.fixedSizeSamples = true;
            pSampleGrabber_pmt.formatSize = 88;
            pSampleGrabber_pmt.sampleSize = 4147200;
            pSampleGrabber_pmt.temporalCompression = false;
            VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
            pSampleGrabber_format.SrcRect = new DsRect();
            pSampleGrabber_format.TargetRect = new DsRect();
            pSampleGrabber_format.AvgTimePerFrame = 400000;
            pSampleGrabber_format.BmiHeader = new BitmapInfoHeader();
            pSampleGrabber_format.BmiHeader.Size = 40;
            pSampleGrabber_format.BmiHeader.Width = 1920;
            pSampleGrabber_format.BmiHeader.Height = 1080;
            pSampleGrabber_format.BmiHeader.Planes = 1;
            pSampleGrabber_format.BmiHeader.BitCount = 16;
            pSampleGrabber_format.BmiHeader.Compression = 844715353;
            pSampleGrabber_format.BmiHeader.ImageSize = 4147200;
            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");
    
    
            //connect AVI Splitter and Mpeg4s Decoder DMO
            hr = pGraph.ConnectDirect(GetPin(pAVISplitter, "Stream 00"), GetPin(pMpeg4sDecoderDMO, "in0"), null);
            checkHR(hr, "Can't connect AVI Splitter and Mpeg4s Decoder DMO");
    
            //connect Mpeg4s Decoder DMO and SampleGrabber
            hr = pGraph.ConnectDirect(GetPin(pMpeg4sDecoderDMO, "out0"), GetPin(pSampleGrabber, "Input"), null);
            checkHR(hr, "Can't connect Mpeg4s Decoder DMO and SampleGrabber");
    
            //add AVI Decompressor
            IBaseFilter pAVIDecompressor = (IBaseFilter)new AVIDec();
            hr = pGraph.AddFilter(pAVIDecompressor, "AVI Decompressor");
            checkHR(hr, "Can't add AVI Decompressor to graph");
    
            //connect SampleGrabber and AVI Decompressor
            hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pAVIDecompressor, "XForm In"), null);
            checkHR(hr, "Can't connect SampleGrabber and AVI Decompressor");
    
            //connect AVI Decompressor and Video Renderer
            hr = pGraph.ConnectDirect(GetPin(pAVIDecompressor, "XForm Out"), GetPin(pVideoRenderer, "VMR Input0"), null);
            checkHR(hr, "Can't connect AVI Decompressor and Video Renderer");
    
        }
    
        static void Main(string[] args)
        {
            try
            {
                IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
                Console.WriteLine("Building graph...");
                BuildGraph(graph, @"Panasonic_HDC_TM_700_P_50i.avi");
                Console.WriteLine("Running...");
                IMediaControl mediaControl = (IMediaControl)graph;
                IMediaEvent mediaEvent = (IMediaEvent)graph;
                int hr = mediaControl.Run();
                checkHR(hr, "Can't run the graph");
                bool stop = false;
                while (!stop)
                {
                    System.Threading.Thread.Sleep(500);
                    Console.Write(".");
                    EventCode ev;
                    IntPtr p1, p2;
                    System.Windows.Forms.Application.DoEvents();
                    while (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0)
                    {
                        if (ev == EventCode.Complete || ev == EventCode.UserAbort)
                        {
                            Console.WriteLine("Done!");
                            stop = true;
                        }
                        else
                        if (ev == EventCode.ErrorAbort)
                        {
                            Console.WriteLine("An error occured: HRESULT={0:X}", p1);
                            mediaControl.Stop();
                            stop = true;
                        }
                        mediaEvent.FreeEventParams(ev, p1, p2);
                    }
                }
            }
            catch (COMException ex)
            {
                Console.WriteLine("COM error: " + ex.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.ToString());
            }
        }
        static IPin GetPin(IBaseFilter filter, string pinname)
        {
            IEnumPins epins;
            int hr = filter.EnumPins(out epins);
            checkHR(hr, "Can't enumerate pins");
            IntPtr fetched = Marshal.AllocCoTaskMem(4);
            IPin[] pins = new IPin[1];
            while (epins.Next(1, pins, fetched) == 0)
            {
                PinInfo pinfo;
                pins[0].QueryPinInfo(out pinfo);
                bool found = (pinfo.name == pinname);
                DsUtils.FreePinInfo(pinfo);
                if (found)
                    return pins[0];
            }
            checkHR(-1, "Pin not found");
            return null;
        }
    
    }
    
    class SampleGrabberCallback : ISampleGrabberCB
    {
        public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
        {
            //Console.WriteLine("Time : " + SampleTime + " " + BufferLen);
            return 0;
        }
    
        public int SampleCB(double SampleTime, IMediaSample pSample)
        {
    
            Console.WriteLine("Time : " + SampleTime + " " + pSample.GetActualDataLength().ToString());
            if (pSample == null) return -1;
            int len = pSample.GetActualDataLength();
            IntPtr pbuf;
            if (pSample.GetPointer(out pbuf) == 0 && len > 0)
            {
                byte[] buf = new byte[len];
                Marshal.Copy(pbuf, buf, 0, len);
                for (int i = 0; i < len; i += 2)
                    buf[i] = (byte)(255 - buf[i]);
                Marshal.Copy(buf, 0, pbuf, len);
            }
            Marshal.ReleaseComObject(pSample);
            return 0;
        }
    }
    

    使用DirectShowLib;
    静态类程序
    {
    /// 
    ///应用程序的主要入口点。
    /// 
    //[状态线程]
    //静态void Main(字符串[]参数)
    //{
    //Application.EnableVisualStyles();
    //Application.SetCompatibleTextRenderingDefault(false);
    //Application.Run(新Form1());
    //}
    静态void checkHR(int hr,string msg)
    {
    如果(hr<0)
    {
    控制台写入线(msg);
    DsError.THROWEExceptionForHR(hr);
    }
    }
    静态void BuildGraph(IGraphBuilder pGraph,字符串srcFile1)
    {
    int-hr=0;
    //图形生成器
    ICaptureGraphBuilder2 pBuilder=(ICaptureGraphBuilder2)新CaptureGraphBuilder2();
    hr=pBuilder.SetFiltergraph(pGraph);
    检查hr(hr,“无法设置FilterGraph”);
    Guid CLSID_Mpeg4sDecoderDMO=新Guid({2A11BAE2-FE6E-4249-864B-9E9ED6E8DBC2});//DMO
    Guid CLSID_mpeg4sdecordmo_cat=新Guid({4A69B442-28BE-4991-969C-B500ADF5D8A8});//DMO类别
    Guid CLSID_MP3DecoderDMO=新Guid({BBEEA841-0A63-4F52-A7AB-A9B3A84ED38A});//DMO
    Guid CLSID_MP3DecoderDMO_cat=新Guid({57F2DB8B-E6BB-4513-9D43-DCD2A6593125});//DMO类别
    Guid CLSID_VideoRenderer=新Guid({B87BEB7B-8D29-423F-AE4D-6582C10175AC}”);//quartz.dll
    Guid CLSID_SampleGrabber=新Guid({C1F400A0-3F08-11D3-9F0B-006008039E37});//qedit.dll
    Guid CLSID_Filestreamrenderer=新Guid(“{D51BD5A5-7548-11CF-A520-0080C77EF58A}”);//quartz.dll
    //添加文件流渲染器
    IBaseFilter pFilestreamrenderer=(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_Filestreamrenderer));
    hr=pGraph.AddFilter(pFilestreamrenderer,“文件流渲染器”);
    checkHR(hr,“无法将文件流渲染器添加到图形”);
    //添加文件源(异步)
    IBaseFilter pFileSourceAsync=(IBaseFilter)新异步读取器();
    hr=pGraph.AddFilter(pFileSourceAsync,“文件源(异步)”;
    checkHR(hr,“无法将文件源(异步)添加到图形”);
    //设置源文件名
    IFileSourceFilter pFileSourceAsync_src=pFileSourceAsync作为IFileSourceFilter;
    if(pFileSourceAsync\u src==null)
    checkHR(未选中((int)0x80004002),“无法获取IFileSourceFilter”);
    hr=pFileSourceAsync\u src.Load(srcFile1,null);
    checkHR(hr,“无法加载文件”);
    //添加AVI拆分器
    IBaseFilter PAVISPLITT=(IBaseFilter)新AviSplitter();
    hr=pGraph.AddFilter(pAVISplitter,“AVI拆分器”);
    checkHR(hr,“无法将AVI拆分器添加到图形”);
    //连接文件源(异步)和AVI拆分器
    hr=pGraph.ConnectDirect(GetPin(pFileSourceAsync,“输出”)、GetPin(pavisplit,“输入pin”)、null;
    选中hr(hr,“无法连接文件源(异步)和AVI拆分器”);
    //添加Mpeg4s解码器DMO
    IBaseFilter pMpeg4sDecoderDMO=(IBaseFilter)新的DMOWrapperFilter();
    var pmpeg4sdecordmo_wrapper=pmpeg4sdecordmo作为IDMOWrapperFilter;
    if(pmpeg4sdecordmo_包装==null)
    checkHR(未选中((int)0x80004002),“无法获取IDMOWrapperFilter”);
    hr=pmpeg4sdecordmo_wrapper.Init(CLSID_mpeg4sdecordmo,CLSID_mpeg4sdecordmo_cat);
    checkHR(hr,“DMO包装初始化失败”);
    hr=pGraph.AddFilter(pmpeg4sdecordmo,“Mpeg4s解码器DMO”);
    checkHR(hr,“无法将Mpeg4s解码器DMO添加到图形中”);
    //添加MP3解码器DMO
    IBaseFilter pMP3DecoderDMO=(IBaseFilter)新的DMOWrapperFilter();
    var pMP3DecoderDMO_wrapper=pMP3DecoderDMO作为IDMOWrapperFilter;
    if(pMP3DecoderDMO_包装==null)
    checkHR(未选中((int)0x80004002),“无法获取IDMOWrapperFilter”);
    hr=pMP3DecoderDMO_wrapper.Init(CLSID_MP3DecoderDMO,CLSID_MP3DecoderDMO_cat);
    checkHR(hr,“DMO包装初始化失败”);
    hr=pGraph.AddFilter(pMP3DecoderDMO,“MP3解码器DMO”);
    checkHR(hr,“无法将MP3解码器DMO添加到图形中”);
    //连接AVI分离器和MP3解码器DMO
    hr=pGraph.ConnectDirect(GetPin(pavisplite,“流01”)、GetPin(pMP3DecoderDMO,“in0”)、null;
    检查hr(hr,“无法连接AVI拆分器和MP3解码器DMO”);
    //添加视频渲染器
    IBaseFilter pvideorederer=(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_VideoRenderer));
    hr=pGraph.AddFilter(pvideorederer,“视频渲染器”);
    checkHR(hr,“无法将视频渲染器添加到图形”);
    //添加默认的DirectSound设备
    IBaseFilter pDefaultDirectSoundDevice=(IBaseFilter)新DSoundRender();
    hr=pGraph.AddFilter(pDefaultDirectSoundDevice,“默认DirectSound设备”);
    checkHR(hr,“无法将默认DirectSound设备添加到图形”);
    //连接MP3解码器DMO和默认DirectSound设备
    hr=pGraph.ConnectDirect(GetPin(pMP3DecoderDMO,“out0”)、GetPin(pDefaultDirectSoundDevice,“音频输入pin(呈现)”、null);
    检查hr(hr,“无法连接MP3解码器DMO和默认DirectSound设备”);
    //添加采样捕获器
    IBaseFilter pSampleGrabber=(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
    hr=pGraph.AddFilter(pSamp