Необъяснимая ошибка «катастрофический сбой» при попытке вызова EndWriting IWMWriter - PullRequest
0 голосов
/ 19 сентября 2011

Я пытаюсь использовать библиотеку 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 Ответ

0 голосов
/ 20 сентября 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...