+ -
当前位置:首页 → 问答吧 → 高分求助!gstreamer的playbin2问题

高分求助!gstreamer的playbin2问题

时间:2011-11-30

来源:互联网


小弟的播放器用gstreamer的playbin2当做核心组件,遇到内存无法释放的问题:

  描述:
  系统内存
  播放前 30MB 
  播放完1曲 30+5*1(MB 大概)
  播放完n曲 30+5*n(MB 大概)
   
  播放完最后一曲循环播放,内存稳定在30+5*n(MB),内存不继续增加。问题是:N比较大的时
  候,内存就被耗尽...
   
  是不是我的单曲结束时释放操作未做,还是其控制就是如此?望有过相关开发经历的XD给些建议!

  贴上部分控制代码:
  C/C++ code

#include "player.h"
#include "player_core.h"
#include "player_types.h"

PLAYER_CORE_STRUC    stPlayer={0};
PLAYER_CORE_STRUC    *gp_player = &stPlayer;
PLAYER_INFO_STRUC    st_play_info = {0};
PLAYER_INFO_STRUC    *gp_play_info = &st_play_info;
void main_loop_thread_fun(gpointer data)
{
    if(data)
    {
        PLAYER_CORE_STRUC* pplayer = (PLAYER_CORE_STRUC*)data;
        if(pplayer->main_loop)
        {
            PRTMSG(MSG_DBG,"g_main_loop_run() run...\n");
            g_main_loop_run(pplayer->main_loop);
        }
    }
    PRTMSG(MSG_DBG,"main_loop_thread_fun() quit!\n");
}
static gboolean
my_bus_callback (GstBus     *bus,
         GstMessage *message,
         gpointer    data)
{
  GMainLoop *loop = data;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR: {
      GError *err;
      gchar *debug;

      gst_message_parse_error (message, &err, &debug);
      g_print ("Error: %s\n", err->message);
      g_error_free (err);
      g_free (debug);

      g_main_loop_quit (loop);

      break;
    }
    case GST_MESSAGE_EOS:
      /* end-of-stream */
      //g_main_loop_quit (loop);
      system("free");
      player_list_ctl(FILE_NEXT);
      player_play(get_play_filename());
      break;
    default:
      /* unhandled message */
      break;
  }

  /* remove message from the queue */
  return TRUE;
}

BOOL player_core_init()
{
    memset( &stPlayer, 0, sizeof(PLAYER_CORE_STRUC) );
    
    pthread_mutex_init(&(gp_player->core_mutex), NULL);
    
    /* init GStreamer */
    gst_init (NULL, NULL);
    gp_player->main_loop = g_main_loop_new (NULL, FALSE);
    if( NULL == gp_player->main_loop )
    {
        PRTMSG(MSG_DBG,"init main_loop failed\n");
        return FALSE;
    }
    /* set up */
    gp_player->playbin = gst_element_factory_make ("playbin2", "play");
    if( NULL == gp_player->playbin )
    {
        PRTMSG(MSG_DBG,"fail in gst_element_factory_make(playbin)\n");
        return FALSE;
    }
    
    gp_player->bus = gst_pipeline_get_bus (GST_PIPELINE (gp_player->playbin));
    if( NULL == gp_player->bus )
    {
        PRTMSG(MSG_DBG,"fail in gst_pipeline_get_bus\n");
        return FALSE;
    }    
    gp_player->watchid = gst_bus_add_watch (gp_player->bus, my_bus_callback, gp_player->main_loop);
    if( NULL == gp_player->watchid )
    {
        PRTMSG(MSG_DBG,"fail in gst_bus_add_watch\n");
        return FALSE;
    }
    gst_object_unref (gp_player->bus);
    
    if( NULL == gp_player->main_loop_thread )
    {
        gp_player->main_loop_thread = g_thread_create((GThreadFunc)main_loop_thread_fun,
                gp_player, TRUE, NULL);
    }
    
    gst_element_set_state (gp_player->playbin, GST_STATE_NULL);

    return TRUE;
}

void player_core_deinit()
{
    /* also clean up */
    if ( NULL != gp_player->playbin )
    {
        g_main_loop_quit (gp_player->main_loop);
        gst_element_set_state (gp_player->playbin, GST_STATE_NULL);
        gst_object_unref (GST_OBJECT (gp_player->playbin));
    }
}

char* filename2uri(char* uri, char* fn)
{
    if( fn[0] == '/' )
    {
        sprintf(uri, "file://%s", fn);
    }
    else
    {
        char* pwd = getenv("PWD");
        sprintf(uri, "file://%s/%s", pwd, fn);
    }
    return uri;
}

void player_play( char *filename )
{
    pthread_mutex_lock(&(gp_player->core_mutex));
    if ( NULL != gp_player->playbin )
    {
        char uri_buffer[512];
        g_object_set(G_OBJECT(gp_player->playbin), "uri", (gchar*)(filename2uri(uri_buffer,filename)), NULL);
        gst_element_set_state (gp_player->playbin, GST_STATE_PLAYING);
    }
    pthread_mutex_unlock(&(gp_player->core_mutex));
}

void player_stop()
{
    pthread_mutex_lock(&(gp_player->core_mutex));
    if ( NULL != gp_player->playbin )
    {
        gst_element_set_state (gp_player->playbin, GST_STATE_NULL);
    }
    pthread_mutex_unlock(&(gp_player->core_mutex));
}

void player_pause()
{
    pthread_mutex_lock(&(gp_player->core_mutex));
    if ( NULL != gp_player->playbin )
    {
        gst_element_set_state (gp_player->playbin, GST_STATE_PAUSED);
    }
    pthread_mutex_unlock(&(gp_player->core_mutex));
}

作者: benkaoya   发布时间: 2011-11-30

自己顶下。。

作者: benkaoya   发布时间: 2011-11-30