Необъяснимая ошибка "Катастрофический сбой" при попытке вызвать EndWriting IWMWriter

Я пытаюсь использовать библиотеку Windows Media .Net для копирования аудио / видео файла в формате asf. Я относительно новичок в Windows Media Format SDK, поэтому не уверен, правильно ли я это делаю. Я просмотрел некоторые примеры проектов, которые включены в загрузку, и просмотрел документацию по версии C++, но не могу понять, почему происходит сбой при вызове EndWriting. Так что, если кто-то может помочь указать на то, что я делаю здесь неправильно, я был бы признателен за это.

У меня есть WinForm, на котором будет кнопка для начала записи и еще одна кнопка для завершения записи. Мой класс реализует IWMReaderCallback и использует закрытый класс с именем SampleProp, который будет использоваться для хранения значений для указателей и таких, которые будут возвращены в методе OnSample. Поэтому в методе OnSample я заполняю элемент byte[] экземпляра SampleProp копией возвращаемого образца. Затем я добавляю экземпляр SampleProp в коллекцию, которая будет использоваться в другом методе с именем ProcessReaderSample. В этом другом методе я создаю объекты IWMReader и IWMWriter, и у меня есть цикл while, который будет вызывать BeginWriting, AllocateSample, WriteSample, затем EndWriting. И вот где он падает. Вот мой код, который я использую...

public class MyClass : IWMReaderCallback  
{  
    static readonly string _streamingFileName = "C:\\tmpStream.asf";  
    static readonly string _streamingURL = @"http://localhost:8080";
    static readonly string _recordingFileName = "C:\\tmpRecording.asf";  

    IWMReader _reader = null;
    IWMReaderAdvanced _readerAdvanced = null;
    IWMHeaderInfo _readerHeaderInfo = null;
    IWMProfile _readerProfile = null;

    IWMWriter _writer = null;
    IWMWriterAdvanced _writerAdvanced = null;
    IWMHeaderInfo _writerHeaderInfo = null;

    int _streamCount = 0;
    Guid[] _guidStreamType = null;
    short[] _streamNumber = null;

    void GetReader()
    {
        WMUtils.WMCreateReader(IntPtr.Zero, Rights.Playback, out _reader);
        _readerAdvanced = _reader as IWMReaderAdvanced;
        _readerHeaderInfo = _reader as IWMHeaderInfo;

        _reader.Open(_streamingFileName, this, IntPtr.Zero);  
        _readerAdvanced.SetUserProvidedClock(true);
        _readerAdvanced.SetManualStreamSelection(true);  
    }  

    void GetWritter()
    {
        WMUtils.WMCreateWriter(IntPtr.Zero, out _writer);
        _writerAdvanced = _writer as IWMWriterAdvanced;
        _writerHeaderInfo = _writer as IWMHeaderInfo;

        _writer.SetProfile(_readerProfile);  
        _writer.SetOutputFilename(_recordingFileName);  
        int inputCount = 0;
        _writer.GetInputCount(out inputCount);  


        for (int i = 0; i < inputCount; i++)
        {
            _writer.SetInputProps(i, null);

        }  
    }  

    class SampleProp
    {
        public int OutputNum { get; private set; }
        public long SampleTime { get; private set; }
        public SampleFlag Flag { get; private set; }
        public byte[] Sample;
        public int Size { get; private set; }

        public SampleProp(int size, int outputNum, long sampleTime, SampleFlag flag)
        {
            Size = size;
            OutputNum = outputNum;
            SampleTime = sampleTime;
            Flag = flag;
            Sample = new byte[size];
        }
    }

    List<SampleProp> _writableSamples = null;
    public void OnSample(int dwOutputNum, long cnsSampleTime, long cnsSampleDuration, SampleFlag dwFlags, INSSBuffer pSample, IntPtr pvContext)
    {
        int size = 0;
        pSample.GetLength(out size);
        var prop = new SampleProp(size, dwOutputNum, cnsSampleTime, dwFlags);
        IntPtr ptr = IntPtr.Zero;
        pSample.GetBuffer(out ptr);
        Marshal.Copy(ptr, prop.Sample, 0, size);
        _writableSamples.Add(prop);
    }  

    void ProcessReaderSample()
    {
        _event.Reset();

        GetReader();

        GetProfileInfo();

        GetWritter();

        _reader.Start(0, 0, 1.0f, IntPtr.Zero);
        _isRecording = true;

        var hasStarted = false;
        while (_isRecording || _writableSamples.Count > 0)
        {
            if (_writableSamples.Count > 0)
            {
                _writer.BeginWriting();
                INSSBuffer buffer;
                _writer.AllocateSample(_writableSamples[0].Size, out buffer);
                IntPtr ptr = IntPtr.Zero;
                buffer.GetBuffer(out ptr);
                Marshal.Copy(_writableSamples[0].Sample, 0, ptr, _writableSamples[0].Size);
                buffer.SetLength(_writableSamples[0].Size);
                _writer.WriteSample(_writableSamples[0].OutputNum, _writableSamples[0].SampleTime, _writableSamples[0].Flag, buffer);
                Marshal.ReleaseComObject(buffer);
                _writableSamples.RemoveAt(0);
                _writer.EndWriting();
            }

        }
    }  

    bool _isRecording = false;
    public void StartRecording()
    {
        if (_isRecording) return;

        _writableSamples = new List<SampleProp>();

        Thread writingThread = new Thread(new ThreadStart(ProcessReaderSample));
        writingThread.Start();

    }  

    public void StopRecording()
    {
        if (!_isRecording) return;

        _isRecording = false;
    }  

Так что, если кто-нибудь может помочь мне с этим. Заранее спасибо.

1 ответ

Решение

Я пошел совершенно в другом направлении для решения этой проблемы. Я решил не использовать только WM .Net Framework и вместо этого использовал DirectShow.Net Framework, реализующий WM Asf Reader и Writer. Вот ссылка на мой вопрос и ответ.

Можно ли использовать URL-адрес http в качестве исходного местоположения фильтра источника в DirectShow .Net?

Другие вопросы по тегам