Page 1 of 1

Rendering video in two separate windows.

Posted: 23 Sep 2015 22:14
by theonlylawislove
I noticed that the QT4 player can clone the video to multiple windows.

I need to do this from the API (libvlc). I have tried the following.

Code: Select all

char const *vlc_argv[] = { "--no-xlib", "--video-filter=clone", // I want to clone video "--clone-count=2" // in two seperate windows }; int done = 0, action = 0, pause = 0, n = 0; libvlc_instance_t* vlc; libvlc_media_t* md; libvlc_media_list_t* ml; libvlc_media_list_player_t* mlp; libvlc_media_player_t* mp; vlc = libvlc_new(sizeof(vlc_argv) / sizeof(*vlc_argv), vlc_argv); md = libvlc_media_new_path(vlc, "D:\\bbb.avi"); ml = libvlc_media_list_new(vlc); libvlc_media_list_add_media(ml, md); mlp = libvlc_media_list_player_new(vlc); libvlc_media_list_player_set_media_list(mlp, ml); mp = libvlc_media_player_new(vlc); libvlc_media_list_player_set_media_player(mlp, mp); libvlc_media_list_player_play(mlp); libvlc_media_player_set_hwnd(mp, NULL); // this would be the handle of my first window libvlc_media_player_set_hwnd(mp, NULL); // and this would be the handle of my second window
However, I get this error in the standard output.

Code: Select all

[02869764] core video output error: Failed to create video filter2 'clone' [02869764] core video output error: Failed to add filter 'clone'
How do I create two clones, and set the parent HWND for these two clones?

Re: Rendering video in two separate windows.

Posted: 23 Sep 2015 22:30
by theonlylawislove
I accidentally was using "filter" and not splitter. New code:

Code: Select all

char const *vlc_argv[] = { "--no-xlib", "--video-splitter=clone", // I want to clone video "--clone-count=2" // in two seperate windows };
I get the two windows now. But how do I set their parents individually?

Re: Rendering video in two separate windows.

Posted: 24 Sep 2015 12:00
by RĂ©mi Denis-Courmont
You don't. Passing arguments to libvlc_new() is explicitly not supported.

Re: Rendering video in two separate windows.

Posted: 24 Sep 2015 12:05
by RSATom
I get the two windows now. But how do I set their parents individually?
You could use "vmem" module and decode video frames to memory, after that you could render it anywhere you like.

Re: Rendering video in two separate windows.

Posted: 24 Sep 2015 18:50
by theonlylawislove
I have started going down the vmem route. However, i am getting some errors when playing.
[swscaler @ 03844c20] bad dst image pointers
[swscaler @ 03844c20] bad dst image pointers
[swscaler @ 03844c20] bad dst image pointers
[swscaler @ 03844c20] bad dst image pointers
[swscaler @ 03844c20] bad dst image pointers
[swscaler @ 03844c20] bad dst image pointers
I am simply trying to setup a minimal example that does nothing at first, and I can't get it to work. I have seen the SDL example, but I need to allocate the buffer myself instead of having SDL handle it (since I am not using SDL).

Code: Select all

struct CMediaPlayer::Context { Context() : picture(NULL) {} picture_t* picture; vlc_mutex_t mutex; }; static unsigned int format_callback( void **data, char *chroma, unsigned *width, unsigned *height, unsigned *pitches, unsigned *lines) { CMediaPlayer::Context* context = (CMediaPlayer::Context*)(*data); video_format_t format; ZeroMemory(&format, sizeof(video_format_t)); format.i_width = *width; format.i_height = *height; format.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); picture_t* picture = picture_NewFromFormat(&format); context->picture = picture; vlc_mutex_init(&context->mutex); return context->picture->i_planes; } static void format_cleanup ( void *data ) { } static void* on_lock ( void* data, void** plane ) { CMediaPlayer::Context* context = (CMediaPlayer::Context*)data; vlc_mutex_lock(&context->mutex); for (int planeNumber = 0; planeNumber < context->picture->i_planes; planeNumber++) plane[planeNumber] = &context->picture->p[planeNumber].p_pixels; return NULL; } static void on_unlock ( void *data, void *picture, void *const *planes ) { CMediaPlayer::Context* context = (CMediaPlayer::Context*)data; vlc_mutex_unlock(&context->mutex); } static void on_display(void* data, void* picture) { CMediaPlayer::Context* context = (CMediaPlayer::Context*)data; BYTE* plane1 = context->picture->p[0].p_pixels; }
Can you see why I would be getting these errors?

Re: Rendering video in two separate windows.

Posted: 24 Sep 2015 19:03
by RSATom

Re: Rendering video in two separate windows.

Posted: 24 Sep 2015 22:00
by theonlylawislove
Thanks, I got your code running and it works. After looking at it, I figured out why mine doesn't work. I am using the "I420" format that comes from the decoded video, and you are converting to RV32.

So, then the question is, why can't I use I420? It seems that most renderers can play YUV formats with limited effort, compared to RGB. Is it possible to use vmem with I420?

Re: Rendering video in two separate windows.

Posted: 24 Sep 2015 22:23
by theonlylawislove
I got I420 working with vmem. I had to add the following to the format callback.

Code: Select all

for (int planeNumber = 0; planeNumber < picture->i_planes; planeNumber++) { pitches[planeNumber] = picture->p[planeNumber].i_pitch; lines[planeNumber] = picture->p[planeNumber].i_lines; }

Re: Rendering video in two separate windows.

Posted: 25 Sep 2015 06:48
by RSATom

Re: Rendering video in two separate windows.

Posted: 25 Sep 2015 12:03
by parker
I have 2 controls "panel". How to put 2 VLC window panel.

EX: m_player.WindowHandle = panel1.Handle
m_player.WindowHandle = panel2.Handle