2016-12-31 54 views
0

我正在實現自定義IMFByteStream通過網絡流式傳輸視頻,但問題是我無法將其對象傳遞給源解析器以創建媒體源,因爲CreateObjectFromByteStream正在返回一個錯誤:源讀取器和自定義非搜索字節流

0xc00d36ee : The provided bytestream was expected to be seekable and it is not.

當然,我的自定義字節流不可搜索,因爲通過網絡搜索是不可能的。所以問題是如何使用不可查找的字節流創建媒體源?我的最終目的是創建一個IMFSourceReader對象。源內容的類型是ASF。

+0

您需要一個媒體源,對於不可查找的流很好。一些消息來源需要尋找的是整個觀點,並且他們檢查這些上限以確保尋求可用。 –

+0

我的目標媒體源的內容類型是ASF。可以創建不需要可查找字節流的ASF媒體源? – pawel

+0

我認爲所有的尋求都是「前進」的,所以最有可能實現一個簡單的尋找流(只是讀取不需要的數據) –

回答

0

你的失敗理應來源於:

During the creation of the media source, the source resolver creates a byte stream for the file from which the media source reads the ASF content. In order for the time conversions to be successful, the byte stream associated with the ASF file must have seeking capabilities; otherwise, the application gets the MF_E_BYTESTREAM_NOT_SEEKABLE error from the Begin... call.

你可以嘗試媒體來源properties但它看上去更像一個強制性的要求,即字節流是可查找。關於如何解決這個問題,事實上標記爲可搜索的,並且在從尚未提供的位置讀取數據時實施等待。

+0

但是可尋址字節流中的位置可以設置爲無處不在。所以我將不得不緩衝我收到的所有數據。是不可能的。 – pawel

+1

可尋址性要求通常是有原因的。您正在使用假定有限字節流的源。您可以調整您的代碼以儘可能模仿可搜索性,或者您需要切換到方案處理程序和全功能網絡源(而不是字節流)。當字節流攜帶漸進式下載樣式數據時,很有可能只在小系統(格式,元數據)範圍內進行搜索,然後對有效負載進行順序讀取。 –

1

我已經實現了兩個IMFByteStream接口,其中一個稱爲MediaByteStream,用於非存儲內存流,另一個稱爲StoreByteStream(是的,我知道),用於內存存儲。

將以下代碼放置在您的IMFByteStream實現中將消除您的可尋址錯誤,並且不會影響您的流式傳輸能力。

 /// <summary> 
     /// Retrieves the characteristics of the byte stream. 
     /// </summary> 
     /// <param name="pdwCapabilities">Receives a bitwise OR of zero or more flags. The following flags are defined. [out]</param> 
     /// <returns>The result of the operation.</returns> 
     HRESULT MediaByteStream::GetCapabilities(
      DWORD *pdwCapabilities) 
     { 
      HRESULT hr = S_OK; 

      // Stream can read, can write, can seek. 
      *pdwCapabilities = MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_WRITABLE | MFBYTESTREAM_IS_SEEKABLE; 

      // Return the result. 
      return hr; 
     } 

你可以,如果你想實現IMFByteStream接口的Seek方法,但在你的情況下(網絡流),你可以只返回搜索位置。

 /// <summary> 
     /// Moves the current position in the stream by a specified offset. 
     /// </summary> 
     /// <param name="SeekOrigin">Specifies the origin of the seek as a member of the MFBYTESTREAM_SEEK_ORIGIN enumeration. The offset is calculated relative to this position. [in]</param> 
     /// <param name="qwSeekOffset">Specifies the new position, as a byte offset from the seek origin. [in]</param> 
     /// <param name="dwSeekFlags">Specifies zero or more flags. The following flags are defined. [in]</param> 
     /// <param name="pqwCurrentPosition">Receives the new position after the seek. [out]</param> 
     /// <returns>The result of the operation.</returns> 
     HRESULT MediaByteStream::Seek(
      MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, 
      LONGLONG     qwSeekOffset, 
      DWORD     dwSeekFlags, 
      QWORD     *pqwCurrentPosition) 
     { 
      HRESULT hr = S_OK; 
      _seekRequest = true; 

      // Select the seek origin. 
      switch (SeekOrigin) 
      { 
      case MFBYTESTREAM_SEEK_ORIGIN::msoCurrent: 
       // If the buffer is less or same. 
       if ((qwSeekOffset + _position) < size) 
        _position += qwSeekOffset; 
       else 
        _position = size; 

       break; 

      case MFBYTESTREAM_SEEK_ORIGIN::msoBegin: 
      default: 
       // If the buffer is less or same. 
       if (qwSeekOffset < size) 
        _position = qwSeekOffset; 
       else 
        _position = size; 

       break; 
      } 

      // Get the current position in the stream. 
      *pqwCurrentPosition = _position; 

      // Return the result. 
      return hr; 
     }