2017-05-18 3 views
0

Wie kann ich SharpDX.Databox spiegeln, ohne es in Bitmap zu konvertieren? Ich mache eine Bildschirmaufnahme mit SharpDX und Media Foundation. Unten ist der Code, wie ich die Databox bekomme.SharpDX MapSubresource wird vertikal umgedreht C#

mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0,SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None);

Aber wenn ich die mapSource in mediafoundation.net weitergegeben produzierte ich eine vertikale Video.

 IMFSample sample = null; 
     IMFMediaBuffer buffer = null; 

     IntPtr data = new IntPtr(); 
     int bufferMaxLength; 
     int bufferCurrentLength; 

     int hr = (int)MFExtern.MFCreateMemoryBuffer(frameSizeBytes, out buffer); 

     if (Succeeded(hr)) hr = (int)buffer.Lock(out data, out bufferMaxLength, out bufferCurrentLength); 
     if (Succeeded(hr)) 
     { 

      hr = (int)MFExtern.MFCopyImage(data, videoWidth * BYTES_PER_PIXEL, mapSource.DataPointer, videoWidth * BYTES_PER_PIXEL, videoWidth * BYTES_PER_PIXEL, videoHeight); 
     } 
     if (Succeeded(hr)) hr = (int)buffer.Unlock(); 
     if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(frameSizeBytes); 
     if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSample(out sample); 
     if (Succeeded(hr)) hr = (int)sample.AddBuffer(buffer); 
     if (Succeeded(hr)) hr = (int)sample.SetSampleTime(frame.prevRecordingDuration.Ticks);//(TICKS_PER_SECOND * frames/VIDEO_FPS); 
     if (Succeeded(hr)) hr = (int)sample.SetSampleDuration((frame.recordDuration-frame.prevRecordingDuration).Ticks); 
     if (Succeeded(hr)) hr = (int)sinkWriter.WriteSample(streamIndex, sample); 
     if (Succeeded(hr)) frames++; 

     COMBase.SafeRelease(sample); 
     COMBase.SafeRelease(buffer); 

enter image description here

Antwort

1

In Ihrem Code gibt es einen Fehler im Code mit MFCopyImage. Nach MFCopyImage function müssen Sie setzen _In_ LONG lDestStride, _In_ const BYTE *pSrc, _In_ LONG lSrcStride, - lDestStride und lSrcStride - ist die Breite des Speichers zum Speichern einer Zeile von Pixeln - Ihre Berechnung videoWidth * BYTES_PER_PIXEL ist nicht korrekt, weil für Windows RGB-Format Schrittweite als videoWidth * BYTES_PER_PIXEL sein kann. Sie müssen Ziel schreiten durch die Funktion MFGetStrideForBitmapInfoHeader, Quelle Schritt berechnen Sie von Ihnen Bild Quellcode bekommen - ich weiß nicht, dass Sie Code, aber für mein Projekt habe ich

D3D11_MAPPED_SUBRESOURCE resource; 
       UINT subresource = D3D11CalcSubresource(0, 0, 0); 
       ctx->Map(mDestImage, subresource, D3D11_MAP_READ_WRITE, 0, &resource); 
       LOG_INVOKE_MF_FUNCTION(MFCopyImage, 
        aPtrData, 
        mStride, 
        (BYTE*)resource.pData, 
        resource.RowPitch, 
  • RowPitch.

Grüße.

P.S. Zielschritt mStride kann negativ sein - es bedeutet, dass es von der letzten Zeile bis zur ersten Zeile geschrieben werden muss. Es kann durch den nächsten Wechsel des Zielzeigers gemacht werden - aPtrData += (mHeight - 1)*mStride;

+0

Ich benutze C# Ich denke, du bist C++ Programmierer. Aber ich werde deine Lösung versuchen. und lassen Sie das Ergebnis wissen Danke. – kripto

+0

Sie verwenden 'MFExtern' - es ist nur Wrapper zum Mapping der C-Funktion von MediaFoundation auf C# -Code. Versuchen Sie 'MFExtern.MFGetStrideForBitmapInfoHeader' zu finden. –

+0

Sorry aber ich kann meine Ausgabe immer noch nicht richtig machen. Ich bin nicht so Experte in der Verwendung von Media Foundation. Die Bildquelle ist bereits umgekehrt, da es einen Anhang zu meinem Post gibt. Ich habe nur vergessen, den Link umzubenennen. Sie können es unten sehen. Ich kann das richtig machen mit – kripto