2014-01-06 21 views
2

我正在使用SinkWriter爲了使用媒體基礎對視頻進行編碼。從SinkWriter或ICodecAPI獲取編碼器名稱或IMFTransform

在初始化SinkWriter之後,我想獲取它使用的底層編碼器,並打印出它的名稱,以便我可以看到它使用的編碼器。 (在我的情況下,編碼器最有可能是MF中包含的H.264 Video Encoder)。

我可以參考編碼器的ICodecAPI和IMFTransform接口(使用pSinkWriter->GetServiceForStream),但我不知道如何使用這些接口獲得編碼器的友好名稱。

有沒有人知道如何從水槽作家獲得編碼器的友好名稱?或從其ICodecAPIIMFTransform界面?

+0

沒有人找到對此的迴應嗎?這似乎是一件非常基本的事情,至少GUID會有所幫助。 –

回答

0

IMFTransform你沒有友好的編碼器名稱。

你有一個選擇是檢查變換輸出類型,並比較知名的GUID來識別編碼器,特別是你將有一個子類型MFVideoFormat_H264與H264編碼MFT。

另一種選擇是,以達到編碼器的CLSIDIMFTransform沒有得到你,但你可能有它通過IMFActivate或查詢MFT_TRANSFORM_CLSID_Attribute屬性,或通過IPersist*接口,否則這樣的)。然後,您可以通過比較CLSID來查看註冊表中的友好名稱或枚舉轉換,然後在該列表中查找您的名稱。

+1

MS H.264視頻編碼器沒有實現'IPersist',並且不支持屬性( - > GetAttributes()返回E_NOTIMPL)。此外,SinkWriter枚舉並創建編碼器,所以我無法訪問IMFActivate對象。編碼器實現的唯一兩個接口是'ICodecAPI'和'IMFTransform',看起來我無法從其中任何一個獲得名稱。 – Ove

+0

這是真的。它的設計目的不是爲了使這個信息能從「IMFTransform」中反向訪問。很難說清楚爲什麼,增加對'IPersist'的支持會簡單而有效。每當我需要進行轉換時,我肯定會在那裏進行轉換,但是存貨過濾器就像它們一樣...並不像開發人員友好。 –

1

這是目前一種有效的解決方案,我不是100%肯定它的工作原理,但有什麼可以做的是:

1)在啓動時枚舉可能被使用的所有編解碼器(我的理解在這種情況下,H264編碼器)和訂閱設定變更事件

MFT_REGISTER_TYPE_INFO TransformationOutput = { MFMediaType_Video, MFVideoFormat_H264 }; 
DWORD nFlags = MFT_ENUM_FLAG_ALL; 
UINT32 nCount = 0; 
CLSID* pClsids; 
MFTEnum(MFT_CATEGORY_VIDEO_ENCODER, nFlags, NULL, &TransformationOutput, NULL, &pClsids, &nCount); 
// Ok here we assume nCount is 1 and we got the MS encoder 
ICodecAPI *pMsEncoder; 
hr = CoCreateInstance(pClsids[0], NULL, CLSCTX_INPROC_SERVER, __uuidof(ICodecAPI), (void**)&pMsEncoder); 
// nCodecIds is supposed to be an array of identifiers to distinguish the sender 
hr = pMsEncoder->RegisterForEvent(CODECAPI_AVEncVideoOutputFrameRate, (LONG_PTR)&nCodecIds[0]); 

2)不是100%肯定,如果幀速率設定也被設置時,數據流的輸入媒體類型設置,但無論如何你可以試試在SinkWriter檢索到的ICodecAPI上設置相同的屬性。然後在得到事件後,您應該能夠通過比較lParam1與傳遞的值來識別編解碼器。但是這仍然很差,因爲它依賴於所有編碼器支持事件通知並且如果我關於在流構造中生成的事件的假設是錯誤的,則需要不必要的參數改變。

相關問題