I'm implementing a custom IMFByteStream
to stream video over a network, but the problem is that I cannot pass its object to the source resolver to create media source, because the CreateObjectFromByteStream
is returning an error:
0xc00d36ee : The provided bytestream was expected to be seekable and it is not.
Of course my custom byte stream is not seekable because seeking over the network is not possible. So the question is how can I create a media source using a non-seekable byte stream? My final destination is to create a IMFSourceReader
object. The type of the source content is ASF.
I have implemented two IMFByteStream
interfaces, one is called MediaByteStream which is used for non-storage memory streaming and the other is called StoreByteStream (yes I know) which is used for in-memory storage.
Placing the code below in your IMFByteStream
implementation will eliminate your seekable error and have no effect on your ability to stream.
/// <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;
}
You can if you wish to implement the Seek
method of the IMFByteStream
interface, but in your case (Network streaming) you can just return the seek position.
/// <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;
}
Your failure supposedly comes from:
You might try media source properties but it more look like a mandatory requirement that byte stream is seekable. On thing you can do to work this around is to indeed mark as seekable and implement a wait once there is a read from position not yet available.
User contributions licensed under CC BY-SA 3.0