Potential bug in Windows Media Foundation about seekable IMFByteStream (regression from Windows 7)

Pierre CHATELIER 11 Reputation points
2024-06-12T10:29:40.55+00:00

I have a minimal sample code that is using Microsoft Media Foundation

It works perfectly well under W7, it fails with an error on W10+

The code :

  • opens an existing (valid) *.avi file to create a readonly IMFByteStream
  • tries to create an IMFMediaSource from it

Under W10, the source resolver claims that the bytestream is not seekable, while it does have that capability (checked at run-time)

Under W7, everything runs fine

Sample VS project is here : https://chachatelier.fr/www/temp/TestMF.zip

Below is the code :

int main(int argc, char* agr[])
{
  HRESULT hr = S_OK;

  printf("initalizing MSMF...\r\n");
  hr = CoInitializeEx(0, COINIT_MULTITHREADED);
  hr = MFStartup(MF_VERSION);

  //input movie
  std::wstring filePathWCString = L"test.avi";
  printf("opening <%s>...\r\n", std::filesystem::path(filePathWCString).string().c_str());

  IMFByteStream* byteStream = 0;
  hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filePathWCString.c_str(), &byteStream);
  CheckError(hr);
  if (hr != S_OK)
    printf("could not find file <%s>\r\n", std::filesystem::path(filePathWCString).string().c_str());
  if (byteStream != nullptr)
  {
    DWORD capabilities = 0;
    byteStream->GetCapabilities(&capabilities);
    const bool isReadable  = ((capabilities & MFBYTESTREAM_IS_READABLE) != 0);
    const bool isWriteable = ((capabilities & MFBYTESTREAM_IS_WRITABLE) != 0);
    const bool isSeekable  = ((capabilities & MFBYTESTREAM_IS_SEEKABLE) != 0);
    printf("readable:%s writable:%s seekable:%s\r\n",
      isReadable ? "yes" : "no",
      isWriteable ? "yes" : "no",
      isSeekable ? "yes" : "no");

    printf("create media source from byte stream...\r\n");
    IMFMediaSource* mediaSource = 0;
    IMFSourceResolver* sourceResolver = 0;
    hr = MFCreateSourceResolver(&sourceResolver);
    CheckError(hr);
    if (sourceResolver != nullptr)
    {
      IUnknown* source = NULL;
      MF_OBJECT_TYPE objectType = MF_OBJECT_INVALID;
      printf("first attempt to open...\r\n");
      hr = sourceResolver->CreateObjectFromByteStream(byteStream, 0, MF_RESOLUTION_MEDIASOURCE|MF_RESOLUTION_KEEP_BYTE_STREAM_ALIVE_ON_FAIL|MF_RESOLUTION_READ, 0, &objectType, &source);
      CheckError(hr);
      if (FAILED(hr))
      {
        printf("second attempt to open with more permissive options...\r\n");
        hr = sourceResolver->CreateObjectFromByteStream(byteStream, 0, MF_RESOLUTION_MEDIASOURCE|MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE|MF_RESOLUTION_READ, 0, &objectType, &source);
        CheckError(hr);
        if ((hr == MF_E_BYTESTREAM_NOT_SEEKABLE) && isSeekable)
          printf("incoherent <not seekable> error\r\n");
      }//end if (FAILED(hr))
      if (source != nullptr)
      {
        printf("SUCCESS!!!\r\n");
        hr = source->QueryInterface(IID_PPV_ARGS(&mediaSource));
        CheckError(hr);
        SafeRelease(&source);
      }//end if (source != nullptr)
      SafeRelease(&sourceResolver);
    }//end if (sourceResolver != nullptr)
  }//end if (byteStream != nullptr)
  SafeRelease(&byteStream);

  done:

  {
    printf("Hit <Enter> to continue...\r\n");
    std::string s;
    std::getline(std::cin, s);
  }

  return 0;
}

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,491 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Castorix31 82,666 Reputation points
    2024-06-12T11:01:10.2333333+00:00

    On my Windows 10 OS (22H2), it works with the second try on first try :

      hr = sourceResolver->CreateObjectFromByteStream(byteStream, 0, MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE | MF_RESOLUTION_READ, 0, &objectType, &source);
    

    (the extension is .AVI and format is MPEG-4) Apparently, there is a call to IMFByteStream::Close with MF_RESOLUTION_KEEP_BYTE_STREAM_ALIVE_ON_FAIL, while it should not close the stream, from MSDN doc


  2. Pierre Chatelier 81 Reputation points
    2024-06-20T06:46:33.92+00:00

    Can I bug report it at a specific place or is this forum the best place ?