2012-05-04 12 views
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; 
    } 
} 
+0

valgrindを実行しようとしましたか? – Daenyth

答えて

1

現在のスナップは完了していませんが、いくつかの問題があります。いくつかのヒント:

  • 使用playbin2
  • playbin2に「ミュート」プロパティを使用して「ミュート」実装は、音が良く求めるにセグメントフラグを使用してimplemntedし、バスにSEGMENT_DONEを聴くことになるループ
  • は、簡単に完全なスタンドアロンの例へのリンクを追加する理想的

を読み取るようにするために別々の方法)((play_soundに共通のコードを移動)とbus_call

  • 関連する問題