2011-09-19 55 views
0

我正在嘗試使用Windows Media .Net庫複製asf文件的音頻/視頻文件。我對Windows Media Format SDK比較陌生,所以我不確定我是否做得對。我瀏覽了下載中包含的一些示例項目,並查看了C++版本的文檔,但似乎無法弄清楚爲什麼當我調用EndWriting時它會崩潰。所以如果有人能夠幫助指出我在這裏做錯了什麼,我會非常感激。嘗試調用IWMWriter的EndWriting時出現無法解釋的「災難性故障」錯誤

我有一個WinForm,它將有一個按鈕開始錄製,另一個按鈕結束錄製。我的類實現了IWMReaderCallback,並使用一個名爲SampleProp的私有類來保存這些指針的值,並且這些值將在OnSample方法中返回。所以在OnSample方法中,我用正在返回的樣本的副本填充SampleProp實例的byte []成員。然後,我將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

我不知道你的具體問題是什麼,但我可以給你兩個指針。首先是「Cestrophic Failure」幾乎總是COM調用COM對象返回的COM HRESULT「E_UNEXPECTED」的結果。第二個是許多COM對象是單元線程的,並且當從一個意外的線程調用時將返回E_UNEXPECTED。 (但是,這只是返回E_UNEXPECTED的一個原因 - 基本上,這是當調用者做了一些被調用者沒有想到的事情時返回的錯誤。) –

+0

首先刪除Marshal.ReleaseComObject(),這是要求麻煩的。 –

+0

@Eric - 你認爲這可能是因爲我正在創建一個新的主題?我試圖在OnSample事件中調用寫入器,但它在Com_Object上拋出了一些轉換異常。 – jhorton

回答

相關問題