private void TestProfile() { int hr; IntPtr prof; hr = m_asfw.GetCurrentProfile(out prof); DsError.ThrowExceptionForHR(hr); #if false IWMProfile ipr = o as IWMProfile; int s = 255; StringBuilder sb = new StringBuilder(s, s); ipr.GetName(sb, ref s); Debug.Assert(sb.ToString() == "Intranet - High Speed LAN Multiple Bit Rate Video", "GetProfile"); #endif #if false IntPtr ip = Marshal.GetIUnknownForObject(o); IntPtr ip2; Guid g = typeof(IWMProfile).GUID; Marshal.QueryInterface(ip, ref g, out ip2); #endif hr = m_asfw.ConfigureFilterUsingProfile(prof); DsError.ThrowExceptionForHR(hr); #if false Guid g2 = new Guid("00000000-0000-0000-C000-000000000046"); IntPtr ip3; Marshal.QueryInterface(ip, ref g2, out ip3); hr = m_asfw.ConfigureFilterUsingProfile(ip3); DsError.ThrowExceptionForHR(hr); Marshal.Release(ip3); #endif #if false Marshal.Release(ip); Marshal.Release(ip2); #endif }
/// <summary> /// WMV 形式ファイル保存用: ビデオのフレームサイズを設定します。 /// </summary> /// <param name="config">ASF Writer から取得したインターフェース</param> /// <param name="size">設定値</param> /// <remarks> /// 第一引数の <c>config</c> は下記のように取得してください。<br/> /// <example lang="c#"> /// var filetype = new Guid(GUID.MEDIASUBTYPE_Asf); /// builder.SetOutputFileName(new IntPtr(&filetype), filename, ref videoRenderer, ref fileSink); /// var config = (IConfigAsfWriter)videoRenderer; /// </example> /// <br/> /// 詳細は下記に記載されています。(但し、言語は C++ です。) <br/> /// <br/> /// <list type="bullet"> /// <item> /// Capturing Video to a Windows Media File <br/> /// https://msdn.microsoft.com/en-us/library/windows/desktop/dd318630(v=vs.85).aspx /// </item> /// <item> /// Creating ASF Files in DirectShow <br/> /// https://msdn.microsoft.com/en-us/library/windows/desktop/dd375008(v=vs.85).aspx /// <list type="bullet"> /// <item> /// Configuring the ASF Writer <br/> /// https://msdn.microsoft.com/en-us/library/windows/desktop/dd387911(v=vs.85).aspx /// </item> /// </list> /// </item> /// <item> /// Using Windows Media in DirectShow <br/> /// https://msdn.microsoft.com/en-us/library/windows/desktop/dd407300(v=vs.85).aspx /// <list type="bullet"> /// <item> /// WM ASF Writer Filter <br/> /// https://msdn.microsoft.com/en-us/library/windows/desktop/dd390985(v=vs.85).aspx /// </item> /// </list> /// </item> /// </list> /// <br/> /// しかし、上記の説明だけでは解決できないので、下記も参考にしています。<br/> /// Social <br/> /// https://social.msdn.microsoft.com/Forums/sqlserver/en-US/962d4370-5fde-4d23-83bc-b8f6191b375e/asf-writer-creates-a-file-that-appears-not-to-match-the-encoding-profile-settings?forum=windowsdirectshowdevelopment <br/> /// https://social.msdn.microsoft.com/forums/windowsdesktop/en-us/fb0a6151-d916-422a-966b-ee1fb164df5f/asf-profile-configurations-fails <br/> /// </remarks> public static void SetVideoFrameSize(IConfigAsfWriter config, Size size) { try { HRESULT hr; // 現在のプロファイルを取得します. IWMProfile profile; hr = (HRESULT)config.GetCurrentProfile(out profile); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } // ストリームの個数を取得します. uint stream_num; hr = (HRESULT)profile.GetStreamCount(out stream_num); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } // 映像入力のストリームを探索してフレームサイズを設定します. for (uint index = 0; index < stream_num; index++) { // ストリームを取得します. IWMStreamConfig stream_config; hr = (HRESULT)profile.GetStream(index, out stream_config); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } // ストリームのメディアタイプを確認します. Guid stream_type; hr = (HRESULT)stream_config.GetStreamType(out stream_type); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } // 映像以外は無視します. if (stream_type != new Guid(GUID.MEDIATYPE_Video)) { continue; } // メディアタイプ情報を格納するために必要なサイズ (bytes) を取得します. var props = (IWMMediaProps)stream_config; int cbType = 0; hr = (HRESULT)props.GetMediaType(IntPtr.Zero, ref cbType); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } // メディアタイプ情報を格納する領域を確保します. var pwmt = Marshal.AllocHGlobal(cbType); if (pwmt != IntPtr.Zero) { try { // メディアタイプ情報を取得します. hr = (HRESULT)props.GetMediaType(pwmt, ref cbType); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } // フレームサイズを指定された値に書き替えます. unsafe { var wmt = (WM_MEDIA_TYPE *)pwmt; var vih = (VIDEOINFOHEADER *)wmt->pbFormat; vih->bmiHeader.biWidth = size.Width; // 幅. vih->bmiHeader.biHeight = size.Height; // 高さ. } // メディアタイプを設定します. hr = (HRESULT)props.SetMediaType(pwmt); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } } finally { Marshal.FreeHGlobal(pwmt); } } // ストリームを再構成します. hr = (HRESULT)profile.ReconfigStream(stream_config); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } } // プロファイルを再構成します. hr = (HRESULT)config.ConfigureFilterUsingProfile(profile); if (hr < HRESULT.S_OK) { throw new CxDSException(hr); } } catch (System.Exception ex) { throw ex; } }