SampleGrabber يعمل بشكل جيد على ملفات AVI/MPEG ولكن متقطع مع WMV

StackOverflow https://stackoverflow.com/questions/2649191

سؤال

لقد كنت أستخدم أحدث إصدار من wpfmediakit. ما أحاول القيام به هو كتابة تطبيق عينة من شأنه أن يستخدم samplegrabber لالتقاط إطارات الفيديو لملفات الفيديو حتى أتمكن من الحصول عليها كفرس فردية.

حتى الآن ، لقد حظيت حظًا سعيدًا مع الكود التالي عند إنشاء الرسم البياني الخاص بي وتقديمه. ومع ذلك ، عندما أستخدم هذا الرمز لتشغيل ملف الفيديو .wmv ، عندما يتم إرفاق SampleGrabber ، سيتم تشغيله إلى الوراء أو متقلبة. إذا قمت بتعليق الخط حيث أضيف عينة مرشح Grabber ، فهو يعمل بشكل جيد. مرة أخرى ، يعمل مع SampleGrabber بشكل صحيح مع AVI/MPEG ، إلخ.

 protected virtual void OpenSource()
    {
        FrameCount = 0;
        /* Make sure we clean up any remaining mess */
        FreeResources();

        if (m_sourceUri == null)
            return;

        string fileSource = m_sourceUri.OriginalString;

        if (string.IsNullOrEmpty(fileSource))
            return;

        try
        {
            /* Creates the GraphBuilder COM object */
            m_graph = new FilterGraphNoThread() as IGraphBuilder;

            if (m_graph == null)
                throw new Exception("Could not create a graph");


            /* Add our prefered audio renderer */
            InsertAudioRenderer(AudioRenderer);

            var filterGraph = m_graph as IFilterGraph2;

            if (filterGraph == null)
                throw new Exception("Could not QueryInterface for the IFilterGraph2");

            IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1);                                

            IBaseFilter sourceFilter;

            /* Have DirectShow find the correct source filter for the Uri */
            var hr = filterGraph.AddSourceFilter(fileSource, fileSource, out sourceFilter);
            DsError.ThrowExceptionForHR(hr);

            /* We will want to enum all the pins on the source filter */
            IEnumPins pinEnum;

            hr = sourceFilter.EnumPins(out pinEnum);
            DsError.ThrowExceptionForHR(hr);

            IntPtr fetched = IntPtr.Zero;
            IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            int pinsRendered = 0;                

            m_sampleGrabber = (ISampleGrabber)new SampleGrabber();
            SetupSampleGrabber(m_sampleGrabber);
            hr = m_graph.AddFilter(m_sampleGrabber as IBaseFilter, "SampleGrabber");
            DsError.ThrowExceptionForHR(hr);

            /* Loop over each pin of the source filter */
            while (pinEnum.Next(pins.Length, pins, fetched) == 0)
            {
                if (filterGraph.RenderEx(pins[0],
                                         AMRenderExFlags.RenderToExistingRenderers,
                                         IntPtr.Zero) >= 0)
                pinsRendered++;

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pinEnum);
            Marshal.ReleaseComObject(sourceFilter);

            if (pinsRendered == 0)
                throw new Exception("Could not render any streams from the source Uri");

            /* Configure the graph in the base class */
            SetupFilterGraph(m_graph);

            HasVideo = true;
            /* Sets the NaturalVideoWidth/Height */
            //SetNativePixelSizes(renderer);
        }
        catch (Exception ex)
        {
            /* This exection will happen usually if the media does
             * not exist or could not open due to not having the
             * proper filters installed */
            FreeResources();

            /* Fire our failed event */
            InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex));
        }

        InvokeMediaOpened();
    }

و:

 private void SetupSampleGrabber(ISampleGrabber sampleGrabber)
    {
        FrameCount = 0;
        var mediaType = new AMMediaType
        {
            majorType = MediaType.Video,
            subType = MediaSubType.RGB24,
            formatType = FormatType.VideoInfo
        };

        int hr = sampleGrabber.SetMediaType(mediaType);

        DsUtils.FreeAMMediaType(mediaType);
        DsError.ThrowExceptionForHR(hr);

        hr = sampleGrabber.SetCallback(this, 0);
        DsError.ThrowExceptionForHR(hr);
    }

لقد قرأت بعض الأشياء التي تقول تنسيقات .wmv أو .asf غير متزامنة أو شيء من هذا القبيل. لقد حاولت إدخال wmasfreader لفك التشفير الذي يعمل ، ولكن بمجرد أن يذهب إلى VMR9 ، فإنه يعطي نفس السلوك. أيضا ، لقد حصلت عليه للعمل بشكل صحيح عندما أعلق على IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1); خط ولديه filterGraph.Render(pins[0]); - العيب الوحيد هو أنه الآن يجعل في أرملة Activemovie من تلقاء نفسها بدلاً من سيطرتي ، ومع ذلك يعمل عينة grabber بشكل صحيح ودون أي تخطي. لذلك أعتقد أن الخطأ في VMR9 / Samplegbing في مكان ما.

أي مساعدة؟ أنا جديد في هذا.

هل كانت مفيدة؟

المحلول

ستستخدم بعض عمليات فك التشفير تسريع الأجهزة باستخدام DXVA. يتم تنفيذ ذلك من خلال التفاوض على تنسيق تم ترميزه جزئيًا ، وتمرير هذه البيانات التي تم فك تشفيرها جزئيًا إلى العارض لإكمال فك التشفير والعرض. إذا قمت بإدخال نموذج تم تكوينه إلى RGB24 بين وحدة فك الترميز والعارض ، فسوف تقوم بتعطيل تسريع الأجهزة.

هذا ، أنا متأكد ، هو جوهر المشكلة. أخشى أن التفاصيل لا تزال غامضة بعض الشيء ، مثل سبب عملها عند استخدام VMR-7 الافتراضي ، لكنها تفشل عند استخدام VMR-9. أظن أن وحدة فك الترميز تحاول استخدام DXVA والفشل ، في حالة VMR-9 ، ولكن لديه نسخة احتياطية معقولة للبرمجيات فقط تعمل بشكل جيد في VMR-7.

لست على دراية بـ WPFMediAkit ، لكنني أعتقد أن أبسط الحلول هو استبدال إنشاء VMR-9 الصريح بخلق VMR-7 صريح. هذا هو ، إذا كان وحدة فك الترميز تعمل فقط مع VMR-7 ، فاستخدم ذلك والتركيز على إصلاح مشكلة إعادة النافذة.

نصائح أخرى

انتهى الأمر بالرمز الذي نشرته (والذي تم تعديله في حد ذاته إلى حد ما من قبل لي من رمز مصدر WPFMediakit من Jeremiah Morrill) في الواقع كافية لتقديم ملفات .wmv والعينة.

يبدو أن التقطيع له علاقة بالركض من خلال VS Debugger ، أو VS2008 نفسه. بعد العبث مع XAML لفترة من الوقت في المحرر المرئي ، ثم تشغيل التطبيق ، سأقدم هذا السلوك المتقلبة. يبدو أن إيقاف تشغيل VS2008 يعالجه. : ص

لذلك ليس الكثير من الإجابة ، ولكن على الأقل إصلاح (مزعج - إعادة تشغيل VS2008) عند ظهوره.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top