1st step to understand
DirectShow その9 ( Multimedia Streaming 玉砕 ) 1.Multimedia Streaming
で、解らない事 HRESULT RenderFileToMMStream( AMMSF_RENDERALLSTREAMS フラグがオンの場合、ビデオおよびオーディオ用のデフォルト レンダリング
フィルタがなければ作成する。ただし、これらのデフォルト フィルタは、IStreamSample::GetMediaStream
メソッドではアクセスできない。(MSDN引用) と、MSDNに書いてあるのですが、AMMultimedia Streamオブジェクトでさえ、メディアストリームに、アクセスできないのです。 .... この、メディアタイプストリームは、CLSID_AMMediaTypeStream オブジェクトから作られますので MSDN引用 IAMMediaTypeStream
*pAMMTypeStream=NULL; IAMMediaTypeStream
*pNewAMMTypeStream=NULL;
前節では、強引に、ここまで、こじつけました。
Multimedia
Streaming の例の、RenderFileToMMStreamの部分で
hr =
pAMStream->OpenFile(wszName,
AMMSF_RENDERALLSTREAMS); と、書いて
AMMSF_RENDERALLSTREAMSを、dwFlags パラメータに
指定するだけで、自動的に
IEEE_FLOATに対応する graphが作成されました。
const char *
szFileName,
IMultiMediaStream
**ppMMStream)
{
.....
hr =
pAMStream->OpenFile(wszName, AMMSF_RENDERALLSTREAMS);// ここが大切
if
(SUCCEEDED(hr))
{
hr
= pAMStream->QueryInterface(IID_IMultiMediaStream,
(void**)ppMMStream);
}
.....
}
確かに、graphが自動的に発生されるのですが、しかし、不具合が発生します。
つまり、できあがったMediaStreamに、アクセスできないのです。
実は、IStreamSampleだけでなく、AMMultimediaStreamオブジェクトでさえも、このMediaStreamにアクセスできないのです。
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に対応していませんでしたので、
メディアタイプストリームを加えねば、なりません。
先ず、CLSID_AMMediaTypeStream オブジェクトを作り、そして、ここから、IAMMediaTypeStreamを得ます。
hr=CoCreateInstance(CLSID_AMMediaTypeStream,NULL,CLSCTX_INPROC_SERVER,
IID_IAMMediaTypeStream,(LPVOID*)&pAMMTypeStream);
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