asfのmuxのつづき
DirectShowのMediaType.asfでマルチプレクサを作ってwmvを吐き出すときになぜかサイズが320×240にリサイズされちゃうってことを書いたことのつづきです。
なんとなく解決はできたので一応書いておこう。
結論から書けば、MediaType.asfで作ったmuxからIConfigAsfWritierを作って(C#でいえばキャスト)、現在のプロファイルをIWMProfileで取得。
そのIWMProfileからビデオを設定しているStream(IWMStreamConfigとして)を取得。これにはオーディオを設定しているStreamもあるので注意。
ビデオの判断はIWMStreamConfigのGetStreamTypeで取得したguidとMediaType.Videoのguidと比較して確認。
そのIWMStreamConfigからVIDEOINFOHEADERを取得して、各設定を変更します。
private void AsfSetOutputSize(IBaseFilter asfMux, int outputWidth, int outputHEight) { Win32API.Native.IConfigAsfWriter config = (Win32API.Native.IConfigAsfWriter)asfMux; Win32API.Native.IWMProfile profile; config.GetCurrentProfile(out profile); uint count; profile.GetStreamCount(out count); for (ushort i = 1; i <= count; ++i) { Win32API.Native.IWMStreamConfig stream; profile.GetStreamByNumber(i, out stream); Guid guid; stream.GetStreamType(out guid); if (guid == MediaType.Video) { Win32API.Native.IWMMediaProps props = (Win32API.Native.IWMMediaProps)stream; uint formatSize = 0; props.GetMediaType(null, ref formatSize); if (formatSize == Marshal.SizeOf(typeof(Win32API.Native.WM_MEDIA_TYPE_VideoInfoHeader))) { Win32API.Native.WM_MEDIA_TYPE_VideoInfoHeader mediaType = new Win32API.Native.WM_MEDIA_TYPE_VideoInfoHeader(); props.GetMediaType(mediaType, ref formatSize); mediaType.pbFormat.rcSource = new Win32API.Native.RECT(); mediaType.pbFormat.rcTarget = new Win32API.Native.RECT(); mediaType.pbFormat.bmiHeader.biHeight = outputHeight; mediaType.pbFormat.bmiHeader.biWidth = outputWidth; props.SetMediaType(mediaType); profile.ReconfigStream(stream); config.ConfigureFilterUsingProfile(profile); } Marshal.ReleaseComObject(stream); break; } Marshal.ReleaseComObject(stream); } Marshal.ReleaseComObject(profile); }
Win32API.Nativeの名前空間は自分で作っているクラスです。見た感じで分かるように、ネイティブの関数や構造体COMオブジェクトを宣言しているクラスです。
その辺は適時読み替えてください。
その他では、IBaseFilterクラスはDirectShowLibのクラスです。
ちゃんと検証していないので、一応これで僕の場合は動いたというだけです。
これでも動いたんですが、別な方法でもできそうな気がする。
というかこれを完成させたその日中に別な方法で、むしろそっちのほうが簡単で、一般的そうな方法を見つけた。
悔しいのでそれはまだ試してません。問題なく動くしぃ〜。