Page 1 of 1

Playing back a 720x482 video using VMEM, distorting image.

Posted: 29 Oct 2015 15:17
by theonlylawislove
Here is my format callback using the VMEM output module.

Code: Select all

static unsigned int format_callback( void **data, char *chroma, unsigned *width, unsigned *height, unsigned *pitches, unsigned *lines) { HRESULT hr = S_OK; CMediaPlayer::Context* context = (CMediaPlayer::Context*)(*data); video_format_t format; ZeroMemory(&format, sizeof(video_format_t)); vlc_mutex_init(&context->mutex); video_format_Setup(&format, vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma), *width, *height, *width, *height, 0, 0); format.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); picture_t* picture = picture_NewFromFormat(&format); context->picture = picture; for (int planeNumber = 0; planeNumber < picture->i_planes; planeNumber++) { pitches[planeNumber] = picture->p[planeNumber].i_pitch; lines[planeNumber] = picture->p[planeNumber].i_lines; } context->planesSwapped = false; if (picture->format.i_chroma == VLC_CODEC_I420 || picture->format.i_chroma == VLC_CODEC_J420 || picture->format.i_chroma == VLC_CODEC_YV12) { /* The dx/d3d buffer is always allocated as YV12 */ if (vlc_fourcc_AreUVPlanesSwapped(picture->format.i_chroma, VLC_CODEC_YV12)) { context->planesSwapped = true; } } context->window1 = WindowContext::Create(context->parent1, format.i_visible_width, format.i_visible_height); context->window2 = WindowContext::Create(context->parent2, format.i_visible_width, format.i_visible_height); return context->picture->i_planes; }
Windows Media Player shows the dimensions of the video as 720x480. It is 2 pixels less (width) than what format_callback is telling me.

Here is what the image looks like when I am rendering.

Image

My renderer has been rendering videos fine. It is just this video. I think it is related to the fact that the dimensions are reported different in VLC, than in Windows Media Player. Can someone help guide my on this issue?

Re: Playing back a 720x482 video using VMEM, distorting image.

Posted: 29 Oct 2015 15:40
by theonlylawislove
Ok, so I am playing around with things, having no clue what I am doing, and I added 16 pixels of width to the renderer I build, and it works.

Code: Select all

context->window1 = WindowContext::Create(context->parent1, format.i_visible_width + 16, format.i_visible_height); context->window2 = WindowContext::Create(context->parent2, format.i_visible_width + 16, format.i_visible_height);
However, this now breaks the normal videos that never gave me an issue.

What am I missing here? I'm not getting it.

Re: Playing back a 720x482 video using VMEM, distorting image.

Posted: 29 Oct 2015 17:20
by theonlylawislove
Ok, so using the pitch created from picture_NewFromFormat resolved both cases.

Code: Select all

context->window1 = WindowContext::Create(context->parent1, pitches[0], format.i_visible_height); context->window2 = WindowContext::Create(context->parent2, pitches[0], format.i_visible_height);
However, now my 720x480 has a lot of empty pixels on the side of the video. So, I made a little check to determine if the generated pitch is larger than my with, otherwise, regenerate a new image with 16 pixels less. This method is not ideal because I am allocating more images than I intend to use. Here is my updated solution that works for both videos, and doesn't add a gutter of empty pixels.

Code: Select all

static unsigned int format_callback( void **data, char *chroma, unsigned *width, unsigned *height, unsigned *pitches, unsigned *lines) { picture_t* picture = NULL; HRESULT hr = S_OK; CMediaPlayer::Context* context = (CMediaPlayer::Context*)(*data); video_format_t format; ZeroMemory(&format, sizeof(video_format_t)); vlc_mutex_init(&context->mutex); video_format_Setup(&format, vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma), *width, *height, *width, *height, 0, 0); format.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); picture = picture_NewFromFormat(&format); context->picture = picture; if (picture->p[0].i_pitch > *width) { // delete old picture so we can allocate new one with 16 pixels less width picture_Release(picture); picture = NULL; context->picture = NULL; *width = *width - 16; video_format_Setup(&format, vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma), *width, *height, *width, *height, 0, 0); format.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); picture = picture_NewFromFormat(&format); context->picture = picture; } for (int planeNumber = 0; planeNumber < picture->i_planes; planeNumber++) { LOG(INFO) << "pitch:" << picture->p[planeNumber].i_pitch; LOG(INFO) << "lines:" << picture->p[planeNumber].i_lines; pitches[planeNumber] = picture->p[planeNumber].i_pitch; lines[planeNumber] = picture->p[planeNumber].i_lines; } assert(0 == pitches[0] % 4 && 0 == pitches[1] % 4 && 0 == pitches[2] % 4); context->planesSwapped = false; if (picture->format.i_chroma == VLC_CODEC_I420 || picture->format.i_chroma == VLC_CODEC_J420 || picture->format.i_chroma == VLC_CODEC_YV12) { /* The dx/d3d buffer is always allocated as YV12 */ if (vlc_fourcc_AreUVPlanesSwapped(picture->format.i_chroma, VLC_CODEC_YV12)) { context->planesSwapped = true; } } context->window1 = WindowContext::Create(context->parent1, pitches[0], format.i_visible_height); context->window2 = WindowContext::Create(context->parent2, pitches[0], format.i_visible_height); return context->picture->i_planes; }
I'm blindly fixing this. I really need to know what is going on. But hey, it's working!

Re: Playing back a 720x482 video using VMEM, distorting image.

Posted: 29 Oct 2015 17:29
by RĂ©mi Denis-Courmont
You should really not mix the plugin and external API in the same code. If you depend on the plugin API anyway, you might as well write a plugin, and the issue should be moot.