Segmentation fault al salir de BennuGD (módulo libvlc)

Started by josebita, June 22, 2010, 03:14:15 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

josebita

Llevo un par de días pegándome con esto. El tema es que la librería funciona bien, pero al ir a salir, aparece un segmentation fault.
De hecho, ni siquiera aparece al ejecutar el código de mi librería sino cuando cualquiera de las librerías de las que depende ejecuta sus rutinas definidas en module_finalize. En particular, el segmentation fault se da al hacer el:
[code language="c" options="singleline"]if ( SDL_WasInit( SDL_INIT_VIDEO ) ) SDL_QuitSubSystem( SDL_INIT_VIDEO );[/code]

Aunque no entiendo por qué falla (creo que todo lo relacionado con la librería debería descargarse al llamar a video_stop()) me huelo que puede tener que ver con cómo uso los mapas de Bennu...
Bueno, aquí os dejo el código fuente bennu del ejemplo que se cuelga (al salir) y el fuente resumido de la librería que falla.[code language="bennu"]import "mod_vlc"
import "mod_key"
import "mod_video"
import "mod_mouse"
import "mod_say"
import "mod_map"
import "mod_file"
import "mod_proc"
import "mod_timers"

#define SCR_WIDTH  640
#define SCR_HEIGHT 480

/* Player main window */
Process main()
Private
    string fname="";
    int time=0, delay=30, track=1;

Begin
    // Handle the command line
    if(argc != 2)
        say("Must be given file to play, quitting.");
        exit();
    end;

    // Try to find the file that the user wants us to play, or die
    fname = argv[1];
    if(! fexists(fname))
        say("Couldn't find "+fname+" to be played, quitting.");
        exit();
    end

    /* Start the graphics subsystem */
    set_mode(SCR_WIDTH, SCR_HEIGHT, 16);

    /* Finally play the video and place it in the middle of the screen */
    graph = video_play(fname, SCR_WIDTH, SCR_HEIGHT);
    x = SCR_WIDTH/2; y = SCR_HEIGHT/2;
    while(! video_is_playing()) // Wait for the video to actually start
        FRAME;
    end;
    while(! key(_esc))
        FRAME;
    end;

    video_stop();
    while(! key(_q))
        // If you press space bar, we start over
        if(key(_space))
            main();
            return;
        end;
        FRAME;
    end;
   
    exit();  // <--------------- Aquí es donde falla...
End;[/code]

[code language="c"]#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>

#include <vlc/vlc.h>

/* BennuGD stuff */
#include <bgddl.h>
#include <xstrings.h>
#include <libgrbase.h>
#include <g_video.h>

struct ctx
{
    GRAPH *graph;
};

static char clock[64], cunlock[64], cdata[64];
static char width[32], height[32], pitch[32];
static libvlc_instance_t *libvlc;
static libvlc_media_t *m;
static libvlc_media_player_t *mp=NULL;
static struct ctx video;
static int playing_video=0;
static char const *vlc_argv[] =
{
    "-q",
//    "-vvvvv",
    "--ignore-config", /* Don't use VLC's config files */
    "--no-video-title-show",
    "--sub-autodetect-file",
    "--vout", "vmem",
    "--plugin-path", "vlc", /* For win32 */
    "--vmem-width", width,
    "--vmem-height", height,
    "--vmem-pitch", pitch,
    "--vmem-chroma", "RV16",
    "--vmem-lock", clock,
    "--vmem-unlock", cunlock,
    "--vmem-data", cdata,
};
static int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);

static void lock(struct ctx *ctx, void **pp_ret)
{
    *pp_ret = ctx->graph->data;
}

static void unlock(struct ctx *ctx)
{
}

/* Mark the graphic as dirty */
static void graph_update()
{
    if(playing_video && video.graph != NULL && video.graph->code != -1) {
        video.graph->modified = 1;
        video.graph->info_flags &=~GI_CLEAN;
    }
}

/* Checks wether the current video is being played */
static int video_is_playing() {
    if(mp) {
        return libvlc_media_player_is_playing(mp);
    } else {
        return 0;
    }
}


/*********************************************/
/* Plays the given video with libVLC         */
/* Must be given:                            */
/*    filename to be played                  */
/*    width  of the video to render          */
/*    height of the video to render          */
/*********************************************/
static int video_play(INSTANCE *my, int * params)
{
    /* Ensure we're not playing a video already */
    if(playing_video == 1)
        return -1;

    /* Start the graphics mode, if not initialized yet */
   if(! scr_initialized) gr_init(320, 240);
   
    /* Lock the video playback */
    playing_video = 1;

    /* Create the 16bpp graphic that will hold the video          */
    /* We don't yet support 32bpp modes, but this'll work fine    */
    /* in BennuGD's 32bpp video mode.                             */
    /* It won't work in 8bpp mode and support for it is not       */
    /* planned, either.                                           */
    video.graph = bitmap_new_syslib(params[1], params[2], 16);

    sprintf(clock, "%lld", (long long int)(intptr_t)lock);
    sprintf(cunlock, "%lld", (long long int)(intptr_t)unlock);
    sprintf(cdata, "%lld", (long long int)(intptr_t)&video);
    sprintf(width, "%i", params[1]);
    sprintf(height, "%i", params[2]);
    sprintf(pitch, "%i", params[1] * 2);

    /* This could really be done earlier, but we need to know the      */
    /* video width/height before doing it and we'd have to use default */
    /* values for them.                                                */
    libvlc = libvlc_new(vlc_argc, vlc_argv);

    /* The name of the file to play */
    m = libvlc_media_new_path(libvlc, string_get(params[0]));
    mp = libvlc_media_player_new_from_media(m);
    libvlc_media_release(m);
    libvlc_media_player_play(mp);

    /* Discard the file path, as we don't need it */
    string_discard(params[0]);
   
    return video.graph->code;
}

/* Stop the currently being played video and release libVLC */
static int video_stop(INSTANCE *my, int * params)
{
    if(! playing_video)
        return 0;

    /* Stop the playback and release the media */
    if(mp) {
        if(video_is_playing())
            libvlc_media_player_stop(mp);

        libvlc_media_player_release(mp);
        mp=NULL;
    }

    if(libvlc) {
        libvlc_release(libvlc);
        libvlc=NULL;
    }
     
    /* Unload the graph */
    if(video.graph) {
        grlib_unload_map(0, video.graph->code);
        video.graph = NULL;
    }

    /* Release the video playback lock */
    playing_video = 0;       

    return 0;
}

DLSYSFUNCS __bgdexport( mod_vlc, functions_exports )[] =
{
   {"VIDEO_PLAY"                  , "SII"  , TYPE_DWORD , video_play       },
   {"VIDEO_STOP"                  , ""     , TYPE_DWORD , video_stop       },
   {"VIDEO_IS_PLAYING"            , ""     , TYPE_DWORD , video_is_playing },
   { NULL        , NULL , 0         , NULL              }
};

/* Bigest priority first execute
   Lowest priority last execute */

HOOK __bgdexport( mod_vlc, handler_hooks )[] =
{
    { 4700, graph_update    },
    {    0, NULL            }
} ;

char * __bgdexport( mod_vlc, modules_dependency )[] =
{
   "libgrbase",
   "libvideo",
   NULL
};

void __bgdexport( mod_vlc, module_finalize )()
{
    video_stop(NULL, NULL);
}[/code]

SplinterGU

mmm... me suena que me paso... a ver, proba poniendo el import "mod_vlc" como ultimo modulo... creo que viene por las dependencias, y como se inicializan las SDL.

proba y confirmame si deja de caer, y si es asi, te digo que falla.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2