LibVLC empty image

感情迁移 提交于 2020-01-17 05:46:25

问题


I'm trying to use LibVLC to decode a video file and render it to a texture.

The code for opening and start playing works, the audio plays perfectly, but the pixel buffer is always filled with 0xCD. The videos I try to render work on VLC, and even in a C# implementation I did they work, but with this new code in C I can't manage to get it working...

I'm using the x64 version of the vlc libs and the program is compiled for x64 if this makes any difference.

Here is my code:

#include "stdafx.h"
#include "video.h"
#include <string.h>
#include <vlc\libvlc.h>
#include <vlc\libvlc_media.h>
#include <vlc\libvlc_media_player.h>

libvlc_instance_t* instance;
libvlc_media_t* media;
libvlc_media_player_t* player;

struct videoContext
{
    unsigned char *pixeldata;
    unsigned char currentFrame;
    int width;
    int height;
};

struct videoContext mainContext;

bool gotData = false;
int width;
int height;

static void *lock(void *data, void **p_pixels)
{

    videoContext* context = (videoContext*)data;
    *p_pixels = context->pixeldata;


    return NULL;
}

static void unlock(void *data, void *id, void *const *p_pixels)
{
    mainContext.currentFrame++;
    //If I check here mainContext.pixeldata is filled with 0xCD
}

static void display(void *data, void *id)
{

}

static unsigned int formatSetup(void **opaque, char *chroma, unsigned *w, unsigned *h, unsigned *pitches, unsigned *lines)
{
    chroma = "RV24";
    width = *w;
    height = *h;

    mainContext.pixeldata = (unsigned char*)malloc(width * height * 3);

    mainContext.width = width;
    mainContext.height = height;

    return 1;
}

void getVideoSize(int* w, int* h, int* bpp)
{
    *w = width;
    *h = height;
    *bpp = 3 * 8;


}

videoContext* initVideo(const char* fileName)
{
    mainContext.pixeldata = 0;

    instance = libvlc_new(0, NULL);
    media = libvlc_media_new_location(instance, fileName);
    player = libvlc_media_player_new_from_media(media);
    libvlc_video_set_callbacks(player, lock, unlock, display, &mainContext);
    libvlc_video_set_format_callbacks(player, formatSetup, NULL);
    libvlc_media_player_play(player);

    return &mainContext;
}

UPDATE:

It seems that nothing is being written to the buffer as anything I set is left there.

UPDATE2:

If I remove the format setup callback and I hardcode libvlc_video_set_format with the "RV24" chroma mode and the resolution it works, so, did I understood wrongly what libvlc_video_set_format_callbacks does? According to the documentation on the format setup callback the params can be changed to enable transcoding but even if I just leave the format as is whenever I set the format setup callback it doesn't works...


回答1:


Ok, so, the problem was extrmely stupid. First, the pitches and lines must be set so libvlc to know the allocated sizes. Second, can't just assign chroma with a const char, it seems as the const char has an extra "\0x00" at the end liblvc counts it and then doesn't finds the decoder.

The final callback is this:

static unsigned int formatSetup(void **opaque, char *chroma, unsigned *w, unsigned *h, unsigned *pitches, unsigned *lines)
{
    memcpy(chroma, "RV24", sizeof("RV24") - 1);

    width = *w;
    height = *h;

    *pitches = width * 3;
    *lines = height;

    mainContext.pixeldata = (unsigned char*)malloc(width * height * 4);

    mainContext.width = width;
    mainContext.height = height;

    return 1;
}


来源:https://stackoverflow.com/questions/40365353/libvlc-empty-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!