2016-12-31 38 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; 
     }