Direct3D: modo efficiente per ottenere la memoria di sistema bitmap da IDirect3DSurface9 (piscina default)?

StackOverflow https://stackoverflow.com/questions/4430204

Domanda

Ho IDirect3DSurface9, pool predefinito, formato YUV. Come posso ottenere in modo efficiente bitmap bit da esso? Al momento:

    creare il rendering di destinazione:
    device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
    convertire da YUV a RGB32:
    device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
    (Rettangolo completo, senza stretching)
    creare la superficie fuori schermo pianura nella memoria di sistema
    device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
    copia dei dati da video MEM per sysmem:
    device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
    GetDC da offscreen superficie, crea DC compatibile e bitmap compatibile, BitBlt da offscreen sufrace DC a DC compatibile e copiare bit bitmap nella mia buffer GetDIBits ()

questo sembra un po 'di testa, a causa di tanti copia: dalla superficie originale per rendere bersaglio, poi fuori campo di superficie, poi a bitmap compatibile, e poi finalmente al mio buffer. Come può essere migliorato?

grazie

È stato utile?

Soluzione

Dal momento che si crea si esegue il rendering di destinazione in modalità con serratura (6 ° parametro CreateRenderTarget), è possibile bloccare il bersaglio rendering con LockRect e copiare i dati direttamente da lì.

MSDN non consiglia di utilizzare con serratura render target, e dice :

  

Se avete bisogno di leggere l'accesso a rendere gli obiettivi, utilizzare GetRenderTargetData invece di serratura   render target.

Quindi, un alternativa è quella di chiamare GetRenderTargetData nella superficie fuori campo, e quindi bloccare la superficie fuori campo (invece di usare DC e bitmap).

Altri suggerimenti

così come i punti interjay fuori ... si sta quasi facendo le cose nel modo "corretto".

I miglioramenti sono evidenti chiamare CreateRenderTarget e CreateOffscreenPlainSurface volta e poi ri-utilizzarli più volte. Il modo più veloce di ottenere i bit di nuovo fuori sarebbe quello di direttamente LockRect superficie.

Inoltre, se si ha bisogno di fare questo in tempo reale su qualcosa come il video probabilmente sarebbe meglio per impostare una serie di superfici (entrambi i tipi). È quindi possibile caricare più fotogrammi YUV sulla superficie CreateRenderTarget'd e poi una volta che hai riempito la matrice quindi copiare il primo al OffscreenPlainSurface e bloccarlo.

In questo modo si permetterà più dei comandi da pipeline e smettere di chiamare voi serratura e costringendo una sincronizzazione della pipeline (cioè la superficie che si sta di blocco è essere pronti prima di procedere che provoca una sincronizzazione gasdotto).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top