2017-11-03 2 views
1

Ich möchte einen bestimmten Encoder in Media Foundation unter UWP mit C++/Cx auswählen. Zur Zeit verwende ich einen SinkWriter und lasse das System einen Standard-Encoder wählen.UWP, Media Foundation, Auswahl bestimmter Encoder

Dieser Code gibt "Klasse nicht registriert" Fehler unter UWP, aber es funktioniert in einer win32 Konsole App:

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 
MFStartup(MF_VERSION); 
IMFTransform* mtf; 
CLSID id; 
CLSIDFromString(L"{966F107C-8EA2-425D-B822-E4A71BEF01D7}", &id); // "NVIDIA HEVC Encoder MFT" 
//CLSIDFromString(L"{F2F84074-8BCA-40BD-9159-E880F673DD3B}", &id); // "H265 Encoder MFT" 
//CLSIDFromString(L"{BC10864D-2B34-408F-912A-102B1B867B6C}", &id); // "Intel« Hardware H265 Encoder MFT" 
//HRESULT hr = CoCreateInstance(id, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void **)&mtf); 
HRESULT hr = CoCreateInstance(id, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&mtf)); 

Ich habe auch bemerkt, dass MFTEnumEx() nicht in den Header-Dateien unter UWP, definded ist so Ich kann die Encoder nicht aufzählen.

Ich bemerkte, so etwas wie dieses es C# Dokumentation ist erlaubt:

auto codecQuery = ref new Windows::Media::Core::CodecQuery(); 

Aber es scheint, es nicht verfügbar, wenn C++/cx verwenden.

Ich möchte auch die SinkWriter was Encoder fragen sie tatsächlich wählte, aber dieser Code funktioniert nicht, weil ICodecAPI nicht definiert ist:

IMFTransform* pEncoder = NULL; 
mWriter->GetServiceForStream(MF_SOURCE_READER_FIRST_VIDEO_STREAM, GUID_NULL, IID_IMFTransform, (void**)&pEncoder); 
if (pEncoder) 
{ 
    ICodecAPI* pCodecApi = NULL; 
    hr = pEncoder->QueryInterface<ICodecAPI>(&pCodecApi); 
} 

Bitte helfen Sie mir Encoder wählen oder gewählt wurde, welcher Geber herausfinden?

Antwort

0

Media Foundation bietet keine Flexibilität für die Angabe eines Encoders mithilfe der Sink Writer-API. Sie können nur zu verwenden oder nicht Hardware-Encoder verwenden anweisen, mit MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS attribute:

Aktiviert die Quelle Leser oder sink Schreiber Hardware-basierte Media Foundation-Transformationen (MFTs) zu verwenden.

Sobald Sink Writer eingerichtet ist, können Sie IMFSinkWriterEx::GetTransformForStream verwenden, um die Transformationen die API für die Verarbeitung vorbereitet aufzuzählen und den Geber aus der Aufzählung wählen. Dies wird Ihnen eine Idee geben, welcher Encoder tatsächlich verwendet wird.

Die Media Foundation Sink Writer API behält sich das Recht vor, den zu verwendenden Encoder zu dekodieren. Normalerweise würden zertifizierte kompatible Encoder bevorzugen, besonders wenn Sie das Direct3D-Szenario aktivieren.

Schließlich bin ich nicht sicher, welche davon für C++/CX verfügbar ist, aber Ihre Code-Snippets deuten darauf hin, dass die genannte API verfügbar ist.

Um einen Encoder Ihrer Wahl zu verwenden, sollten Sie Media Foundation Media Session API im Gegensatz zu Sink Writer verwenden.

+0

In Bezug auf Mediensitzungs-API scheint MFTRegister() nicht verfügbar zu sein. Ich müsste eine benutzerdefinierte IMFTransform erstellen, um das Video zu verarbeiten. Auch ein Dateileser und -schreiber. Der Encoder muss gezielt ausgewählt werden. Also scheint es mir nicht möglich zu sein? – Morten

+0

Sie haben keine Option für explizite Encoder mit Sink Writer. Es gibt nur zwei Optionen: den am besten geeigneten Encoder (normalerweise Hardware-Encoder) und den am besten geeigneten Nicht-Hardware-Encoder (der normalerweise in den MS-Software-Encoder aufgelöst wird). Sie wählen zwischen den beiden. Wenn Sie nicht zufrieden sind, verwenden Sie entweder die Media Session-API oder den Encoder, den Sie benötigen, um bereits komprimierte Daten an Sink Writer zu senden. Ich sehe nicht, wie "MFTRegister" hier verwandt ist, Sie verwenden es normalerweise nicht für diese Aufgabe. –

+0

MFCreateMediaSession() ist nicht verfügbar und dieser Beitrag schlägt vor, dass Media Session API unter UWP überhaupt nicht verfügbar ist: https://stackoverflow.com/questions/47059898/how-to-use-windows-media-foundation-with -uwp-ohne-eine-topologie? rq = 1 – Morten

0

Danke Roman. Ich habe versucht GetTranformForStream. Mit nvidia Treiber erhalte ich die Attribute für das IMFTransform:

{206B4FC8-FCF9-4C51-AFE3-9764369E33A0}=1, 
{2FB866AC-B078-4942-AB6C-003D05CDA674}=NVIDIA HEVC Encoder MFT, 
FRIENDLY_NAME_Attribute=NVIDIA HEVC Encoder MFT, 
{3AECB0CC-035B-4BCC-8185-2B8D551EF3AF}=VEN_10DE, 
MAJOR_TYPE=Video, 
{53476A11-3F13-49FB-AC42-EE2733C96741}=1, 
{86A355AE-3A77-4EC4-9F31-01149A4E92DE}=1, 
{88A7CB15-7B07-4A34-9128-E64C6703C4D3}=8, 
{E3F2E203-D445-4B8C-9211-AE390D3BA017}=2303214, 
{E5666D6B-3422-4EB6-A421-DA7DB1F8E207}=1, 
{F34B9093-05E0-4B16-993D-3E2A2CDE6AD3}=860522, 
SUBTYPE=Base, 
{F81A699A-649A-497D-8C73-29F8FED6AD7A}=1, 

Wenn nvidia-Treiber zu deaktivieren erhalte ich nur:

{86A355AE-3A77-4EC4-9F31-01149A4E92DE}=1 

Ich frage mich, ob die Transformation letzte ist eine Liste von mehreren Transformationen? Wie bekomme ich sie? Kann ich die Topologie von Sinkwriter durchqueren?

Mein PC hat folgenden Codecs ich verwenden könnte:

{966F107C-8EA2-425D-B822-E4A71BEF01D7} // "NVIDIA HEVC Encoder MFT" 
{F2F84074-8BCA-40BD-9159-E880F673DD3B} // "H265 Encoder MFT" 
{BC10864D-2B34-408F-912A-102B1B867B6C} // "Intel« Hardware H265 Encoder MFT" 

Im nvidia Fall, erhalte ich eine aussagekräftige Zeichenfolge, aber nicht, wenn es nicht nvidia scheinbar (Intel oder Software).

Jetzt werde ich auch versuchen, in Media Session API wie Sie vorgeschlagen zu prüfen.

Verwandte Themen