2

Ich muss IMFSample Objekt duplizieren, so dass ich getrennte unabhängige Objekte haben werde. Microsoft-API bietet keine einfache Möglichkeit zum Duplizieren IMFSample Video Frame.Wie IMFSample Objekt zu duplizieren

Antwort

0

Hier ist ein Beispielcode:

#define MmfThrowIfError(hrVal) \ 
{ \ 
    HRESULT hrMmfTraceInternal = (hrVal); \ 
    if (FAILED(hrMmfTraceInternal)) \ 
    { \ 
     /* LOG_F(LS_ERROR)<<"MMF hr: 0x"<<std::hex<<hrMmfTraceInternal; */ \ 
     throw ref new ::Platform::Exception(hrMmfTraceInternal); \ 
    } \ 
} 

MFComPtr<IMFMediaBuffer> DuplicateBuffer(const MFComPtr<IMFMediaBuffer>& srcBuf) 
{ 
    byte* srcByteBuffer = nullptr; 
    DWORD srcBuffMaxLen = 0; 
    DWORD srcBuffCurrLen = 0; 
    MmfThrowIfError(srcBuf->Lock(&srcByteBuffer, &srcBuffMaxLen, &srcBuffCurrLen)); 

    MFComPtr<IMFMediaBuffer> destBuf = nullptr; 
    MmfThrowIfError(MFCreateMemoryBuffer(srcBuffCurrLen, &destBuf)); 

    byte* destByteBuffer = nullptr; 
    MmfThrowIfError(destBuf->Lock(&destByteBuffer, nullptr, nullptr)); 
    memcpy(destByteBuffer, srcByteBuffer, srcBuffCurrLen); 
    MmfThrowIfError(destBuf->Unlock()); 
    MmfThrowIfError(srcBuf->Unlock()); 

    MmfThrowIfError(destBuf->SetCurrentLength(srcBuffCurrLen)); 
    return destBuf; 
} 

SampleComPtr DuplicateSample(const SampleComPtr& sample) 
{ 
    if (!sample) 
     return nullptr; 

    DWORD sampleFlags = 0; 
    LONGLONG llVideoTimeStamp = 0; 
    LONGLONG llSampleDuration = 0; 
    MmfThrowIfError(sample->GetSampleFlags(&sampleFlags)); 
    MmfThrowIfError(sample->GetSampleTime(&llVideoTimeStamp)); 
    MmfThrowIfError(sample->GetSampleDuration(&llSampleDuration)); 

    SampleComPtr outSample; 
    MFCreateSample(&outSample); 
    MmfThrowIfError(outSample->SetSampleFlags(sampleFlags)); 
    MmfThrowIfError(outSample->SetSampleTime(llVideoTimeStamp)); 
    MmfThrowIfError(outSample->SetSampleDuration(llSampleDuration)); 

    DWORD bufferCount = 0; 
    MmfThrowIfError(sample->GetBufferCount(&bufferCount)); 

    for (DWORD index = 0; index < bufferCount; ++index) 
    { 
     MFComPtr<IMFMediaBuffer> srcBuf = nullptr; 
     MmfThrowIfError(sample->GetBufferByIndex(index, &srcBuf)); 

     MFComPtr<IMFMediaBuffer> reConstructedBuffer = DuplicateBuffer(srcBuf); 
     srcBuf = nullptr; 
     MmfThrowIfError(outSample->AddBuffer(reConstructedBuffer.Get())); 
    } 

    return outSample; 
} 
+1

Dies ist für die meisten Fälle gut, aber ist nicht eine genaue Kopie. Eine Kopie ist immer ein einfaches Beispiel, während das Originalmuster möglicherweise von Direct3D-Textur usw. unterstützt wird. –

+0

Was meinen Sie mit "nicht genau"? Welcher Beispielaspekt ist verloren? (außer Puffergrößen werden auf ihre tatsächliche (nicht maximale) Größe verringert). – Sergey

+0

Mit "genau" meine ich exakte Kopie, die alle Fähigkeiten dupliziert. Ich habe oben ein Beispiel gegeben. Dies ist auch genau der Grund, warum die API für die Musterduplizierung nicht vorhanden ist: Media Foundation kann einfach keine exakte Kopie erstellen, da das Beispiel im Allgemeinen implementierungsspezifisch ist, auch wenn es sich um generische Schnittstellen handelt. –