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;
}
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. –
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
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. –