Howto: libVLC and DirectX on Win32

This forum is about all development around libVLC.
chobi
New Cone
New Cone
Posts: 2
Joined: 17 Sep 2010 11:03
VLC version: 1.1.4
Operating System: Windows

Howto: libVLC and DirectX on Win32

Postby chobi » 17 Sep 2010 13:46

Hello guys!
Where can I find an example of using new fancy libvlc_video_set_callbacks() function that outputs to DirectX application's texture or surface?
Searching through forum didn't provide useful results.
I saw an SDL sample, but I am not familiar with SDL at all.

Jean-Baptiste Kempf
Site Administrator
Site Administrator
Posts: 37523
Joined: 22 Jul 2005 15:29
VLC version: 4.0.0-git
Operating System: Linux, Windows, Mac
Location: Cone, France
Contact:

Re: Howto: libVLC and DirectX on Win32

Postby Jean-Baptiste Kempf » 17 Sep 2010 16:26

I don't know if anyone has done an example about that yet.
Jean-Baptiste Kempf
http://www.jbkempf.com/ - http://www.jbkempf.com/blog/category/Videolan
VLC media player developer, VideoLAN President and Sites administrator
If you want an answer to your question, just be specific and precise. Don't use Private Messages.

xdenser
Blank Cone
Blank Cone
Posts: 23
Joined: 30 Aug 2010 23:39
Contact:

Re: Howto: libVLC and DirectX on Win32

Postby xdenser » 20 Sep 2010 20:29

I use it with DirectX
but in tricky way - trough DirectShow push filter and VMR9 in renderless mode
just combine samples from DX SDK for Bitmap push filter and VMR rendering to texture
It is possible to render directly to texture - the easiest way is to use D3DX library function to create texture from memory buffer.

chobi
New Cone
New Cone
Posts: 2
Joined: 17 Sep 2010 11:03
VLC version: 1.1.4
Operating System: Windows

Re: Howto: libVLC and DirectX on Win32

Postby chobi » 30 Sep 2010 21:06

So, I finally managed to do it somehow. I am pretty sure that my code is not elegant and there's a big room for optimizations. Particularly, I didn't understand why we need all those opaque, picture and plane parameters in callbacks. But at least it works. Oh, and it's in Pascal. All corrections are welcome and will be received with gratitude.

Declaration

Code: Select all

const video_width=800; video_height=600; var vlcMutex: TCriticalSection; vlcBuffer: array [0 .. video_width*video_height*4+32] of byte; vlcVideoTexture: IDirect3DTexture9; vlcMemoryTexture: IDirect3DTexture9; pSprite: ID3DXSprite;
Initialization

Code: Select all

pd3dDevice.CreateTexture(video_width, video_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, vlcVideoTexture, nil); pd3dDevice.CreateTexture(video_width, video_height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, vlcMemoryTexture, nil); D3DXCreateSprite(pd3dDevice, pSprite); vlcMutex:=TCriticalSection.Create;
Deinitialization

Code: Select all

SAFE_RELEASE(vlcVideoTexture); SAFE_RELEASE(vlcMemoryTexture); SAFE_RELEASE(pSprite); vlcMutex.Free;
Callbacks

Code: Select all

function VLCLock(opaque: Pointer; plane: Pointer): Pointer; cdecl; begin Result:=nil; Pointer(plane^):=@(vlcBuffer[0]); vlcMutex.Enter; end; function VLCUnlock(opaque: Pointer; picture: Pointer; plane: Pointer): Pointer; cdecl; begin Result:=nil; vlcMutex.Leave; end; function VLCdisplay(opaque: Pointer; picture: Pointer): Pointer; cdecl; var i, j: integer; prect: D3DLOCKED_RECT; pTexBuffer: PByte; begin Result:=nil; i:=0; /// VLC outputs data in RGBA while we need to load data in BGRA into texture /// so, swap all Red and Blue values while i<=(video_width*video_height-1)*4 do begin j:=vlcBuffer[i]; vlcBuffer[i]:=vlcBuffer[i+2]; vlcBuffer[i+2]:=j; inc(i, 4); end; /// lock system memory texture and fill it with data if vlcMemoryTexture.LockRect(0, prect, nil, 0)= S_OK then begin pTexBuffer:=prect.pBits; for i:=0 to video_height-1 do begin /// fill data into texture line by line MoveMemory(pTexBuffer, @vlcBuffer[i*video_width*4], video_width*4); /// and don't forget to offset by pitch, not by video_width*4 inc(pTexBuffer, prect.Pitch); end; vlcMemoryTexture.UnlockRect(0); end; end;
Starting playback

Code: Select all

procedure VideoPlay(videofile: PAnsiChar); var pMedia, pMediaPlayer: Pointer; begin pMedia:=libvlc_media_new_path(vlc, videofile); pMediaPlayer:=libvlc_media_player_new_from_media(pMedia); libvlc_media_release(pMedia); libvlc_video_set_callbacks(pMediaPlayer, @VLCLock, @VLCUnlock, @VLCDisplay, nil); libvlc_video_set_format(pMediaPlayer, 'RGBA', video_width, video_height, video_width*4); libvlc_media_player_play(pMediaPlayer); end;
Rendering

Code: Select all

procedure OnFrameRender; var mat: TD3DXMatrixA16; scale: TD3DXVector2; begin { Prepare to render the scene here } pSprite._Begin(D3DXSPRITE_DONOTSAVESTATE or D3DXSPRITE_DO_NOT_ADDREF_TEXTURE); /// update video texture which we are going to render now, from system memory texture pd3dDevice.UpdateTexture(vlcMemoryTexture, vlcVideoTexture); /// stretch sprite so video texture will fit in window. /// window_width and window_height are window's dimensions scale.x:=window_width/video_width; scale.y:=window_height/video_height; D3DXMatrixTransformation2D(mat, nil, 0, @scale, nil, 0, nil); pSprite.SetTransform(mat); /// finally, render it pSprite.Draw( vlcVideoTexture, nil, nil, nil, $FFFFFFFF ); pSprite._End; { End scene rendering here} end;


Return to “Development around libVLC”

Who is online

Users browsing this forum: No registered users and 8 guests