1
GtkとGstreamerを使用してサウンドを再生するアプリケーションを作成しました。新しいサウンドが再生されるたびに私のシステムにpulseaudioがインストールされていないと、アプリケーションは決して解放されない追加の10Mの仮想メモリを使用します。 pulseaudioがインストールされ、実行されている場合、メモリリークは発生しませんが、サウンドは非常に不安定で頻繁にクラッシュします。サウンドの再生を処理するコードのセクションです。 * update_callback *は10秒ごとに呼び出されます。gstreamerはパルスオーディオを使用していないときにメモリをリークします
int current_sound;
int current_beep_type = BEEP_CONT;
int next_beep_type = -1;
gboolean sound_muted = FALSE;
static GstSeekFlags seek_flags = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT;
GstElement *sound_pipeline = NULL;
int update_callback(GtkWidget *widget, gpointer data) {
static int i = 0;
switch((i++)%2) {
case 0:
play_sound("morse_code.ogg",BEEP_CONT);
break;
case 1:
destroy_sound();
break;
default:
break;
}
return TRUE;
}
static gboolean bus_call(GstBus *bus, GstMessage *msg, void *user_data)
{
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_EOS: {
//g_print("End of stream\n");
if(current_beep_type == BEEP_CONT) {
gst_element_seek (sound_pipeline, 1.0,
GST_FORMAT_TIME,
seek_flags,
GST_SEEK_TYPE_SET, 0,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
break;
}
else {
//gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_NULL);
}
if(strlen(next_uri) > 0) {
g_object_set(G_OBJECT(sound_pipeline), "uri", next_uri, NULL);
current_beep_type = next_beep_type;
memset(next_uri,0,sizeof(next_uri));
if(!sound_muted) gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_PLAYING);
else gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_PAUSED);
}
else {
gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_NULL);
}
break;
}
case GST_MESSAGE_ERROR: {
GError *err;
gst_message_parse_error(msg, &err, NULL);
g_error("%s", err->message);
g_error_free(err);
break;
}
default:
break;
}
return TRUE;
}
void play_sound(char *sound, int beep)
{
strcpy(next_uri,"file://");
strcat(next_uri,SOUNDS_DIR);
strcat(next_uri,sound);
next_beep_type = beep;
if(sound_pipeline == NULL) {
mad_log(LOG_INFO,"creating sound_pipeline\n");
GstBus *bus;
sound_pipeline = gst_element_factory_make("playbin", "play");
bus = gst_pipeline_get_bus(GST_PIPELINE(sound_pipeline));
gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
}
GstState state;
gst_element_get_state(sound_pipeline,&state,NULL,500000000);
if (state == GST_STATE_NULL) {
//g_print("pipeline is in NULL state\n");
g_object_set(G_OBJECT(sound_pipeline), "uri", next_uri, NULL);
current_beep_type = next_beep_type;
memset(next_uri,0,sizeof(next_uri));
if(!sound_muted) gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_PLAYING);
else gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_PAUSED);
}
}
void destroy_sound(void) {
if(sound_pipeline)
{
current_beep_type = -1;
gst_element_set_state(GST_ELEMENT(sound_pipeline), GST_STATE_NULL);
g_object_unref(G_OBJECT(sound_pipeline));
sound_pipeline = NULL;
}
}
valgrindを実行しようとしましたか? – Daenyth