1st step to understand DirectShow  その9 ( Multimedia Streaming 玉砕 )



 1.Multimedia Streaming で、解らない事

    前節では、強引に、ここまで、こじつけました。

    Multimedia Streaming の例の、RenderFileToMMStreamの部分で

        hr = pAMStream->OpenFile(wszName, AMMSF_RENDERALLSTREAMS); と、書いて

    AMMSF_RENDERALLSTREAMSを、dwFlags パラメータに 指定するだけで、自動的に

    IEEE_FLOATに対応する graphが作成されました。

HRESULT RenderFileToMMStream(
    const char * szFileName,
    IMultiMediaStream **ppMMStream)
{
  .....
    hr = pAMStream->OpenFile(wszName, AMMSF_RENDERALLSTREAMS);// ここが大切
        if (SUCCEEDED(hr))
        {
            hr = pAMStream->QueryInterface(IID_IMultiMediaStream,
                (void**)ppMMStream);
        }
  .....
}

     確かに、graphが自動的に発生されるのですが、しかし、不具合が発生します。

     つまり、できあがったMediaStreamに、アクセスできないのです。

AMMSF_RENDERALLSTREAMS フラグがオンの場合、ビデオおよびオーディオ用のデフォルト レンダリング フィルタがなければ作成する。ただし、これらのデフォルト フィルタは、IStreamSample::GetMediaStream メソッドではアクセスできない。(MSDN引用

    実は、IStreamSampleだけでなく、AMMultimediaStreamオブジェクトでさえも、このMediaStreamにアクセスできないのです。

  • Media Stream オブジェクトは IMediaStream インターフェイスを公開し、データに固有である。AMMultimediaStream オブジェクトは 1 つ以上のメディア ストリームを格納する。 (MSDN引用

        と、MSDNに書いてあるのですが、AMMultimedia Streamオブジェクトでさえ、メディアストリームに、アクセスできないのです。

    HRESULT RenderFileToMMStream(
        const char * szFileName,
        IMultiMediaStream **ppMMStream)
    {
    .... 
        hr = pAMStream->OpenFile(wszName, AMMSF_RENDERALLSTREAMS);// ここが大切
            if (SUCCEEDED(hr))
            {
                hr = pAMStream->QueryInterface(IID_IMultiMediaStream,
                    (void**)ppMMStream);
            }
     .....  
     IMediaStream *pMedStream=0;
    hr= pAMStream->EnumMediaStreams(0,&pMedStream); //これは、失敗する。

    .... 
      return S_OK;

    }

  •  2.では、AMMSF_RENDERALLSTREAMS パラメータを使わないとしたら...

        AMMultimediaStreamオブジェクトは、Multimedia Streamingの出発点です。

    MSDN引用

        ですので、先ず最初に、AMMultimediaStream オブジェクトを作成します。

        IAMMultiMediaStream *pAMStream;
        HRESULT hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL,
            CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream,
            (void **)&pAMStream);

        そして、このオブジェクトにアクセスする方法は、IAMMultiMediaStream と言う interfaceを、通して対話するしか、手段がないのです。

        次に、このIAMMultiMediaStream を初期化します。

        pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL); //原文

        そして、AMMSF_RENDERALLSTREAMS パラメータを使わないとすれば

        ここで、明示的に、MediaStreamを、加えなければなりません。

    pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, 0, NULL); //原文

        MSPID_PrimaryAudioは、IEEE_FLOATに対応していませんでしたので、

        メディアタイプストリームを加えねば、なりません。

  • メディア タイプ ストリーム。任意のデータを表す。IAMMediaTypeStream インターフェイスを公開する。 MSDN引用

        この、メディアタイプストリームは、CLSID_AMMediaTypeStream オブジェクトから作られますので MSDN引用

        先ず、CLSID_AMMediaTypeStream オブジェクトを作り、そして、ここから、IAMMediaTypeStreamを得ます。

     IAMMediaTypeStream  *pAMMTypeStream=NULL;
     hr=CoCreateInstance(CLSID_AMMediaTypeStream,NULL,CLSCTX_INPROC_SERVER,
      IID_IAMMediaTypeStream,(LPVOID*)&pAMMTypeStream);

     IAMMediaTypeStream  *pNewAMMTypeStream=NULL;
    hr=pAMMStream->AddMediaStream(pAMMTypeStream,NULL,0,(IMediaStream**)&pNewAMMTypeStream);

        これは、成功します。

        そして、dwFlags は、 今回は AMMSF_RENDERTOEXISTING を使って OpenFileするのです。

     hr=pAMMStream->OpenFile(L"mywave.wav",AMMSF_RENDERTOEXISTING );

        これは、成功しません。



        AMMSF_RENDERALLSTREAMSを使えば、一応、hrは、S_OKを返しますが、これは

        我々が作成した、IAMMediaTypeStream を使って作成されたgraphでは、ありませんでした...

        IMediastreamを得られないならば、 GetFormat(...) SetFormat(...).も、不可能です....万事休す。

  •     
        ええ経験でしたね。

        ほんなら、DirectShowに、戻りましょか

      H.20.4.13