This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Gstreamer library not responding after playing 367 songs from USB

Hi,

I'm using GStreamer library and ALSA framework to play songs from USB. Only 367 songs are getting played from USB and after that GStreamer is not playing any song.     

I'm not getting any clue why this is happening and why only 367 songs are supported. Is this the limitation of GStreamer library.

Please help me out as I'm on the last stage of my project.

Thanks in advance.

Deshvir Malik

   

  • Hello,

    What is the gstreamer version that you are using?
    What is the hardware platform?
    Do you observe any error/s?

    BR
    Margarita
  • Hi Margarita,I am using GStreamer version 0.10

    I am using GStreamer version 0.10

    Hardware platform is TI AM335x

    Errors logs are mentioned below :

    Up to 367 songs, below three pipeline states are are changing

    Pipeline state changed from NULL to READY:

    Pipeline state changed from READY to PAUSED:

    Pipeline state changed from PAUSED to PLAYING:

    After 367 songs, I'm getting only

    Pipeline state changed from NULL to READY:

    Pipeline state changed from READY to PAUSED:

    here the state is not changing from pause to play

    Moreover, I checked with export GST_DEBUG=4 and got the attached logs

     File Expected logs.txt consist of logs up to 367 songs and file Logs with error.txt consist of error logs after 367 songs.

    Logs can be analysed by comparing both the files. 

     

    Thanks and Regards

    Deshvir Malik

    8883.Expected_logs.txt7345.Logs_with_error.txt

  • Hello,

    One more question. On every song you are moving from NULL to PLAYING State right?
    If yes, could you try something like:
    gst_element_set_state (pipeline, GST_STATE_NULL);
    if (msg)
    gst_message_unref(msg);

    or you could try this line in:
    switch (GST_MESSAGE_TYPE (msg)) {
    .......
    .......
    .......
    gst_message_unref( msg );




    You could check this description of gst_bus_timed_pop_filtered () and when the error is accruing also:
    gstreamer.freedesktop.org/.../GstBus.html

    BR
    Margarita

  • Hi Margarita,

    I'm using suugeested solution in my code whenever new song is playing. This code is a part of a thread 1.

    else if(index != curIndex)
    {

    NGT_LOG(DBG_ERROR, MEDIA_LOG_FILE, "Stop Song and clean "
    "media resources \n");
    curSong.terminate = TRUE;
    gst_object_unref (curSong.bus);
    gst_element_set_state (curSong.playbin, GST_STATE_NULL);
    gst_object_unref (curSong.playbin);
    while(PlaySongThreadActive);
    index = curIndex;

    }


    Inside thread1, I'm creating thread2

    Thread 2 consist of

    1. gst_element_factory_make ("playbin", "playbin")
    2. gst_element_set_state(playbin, GST_STATE_PLAYING)
    3. gst_element_get_bus (curSong.playbin)
    4. do
    {
    gst_bus_timed_pop_filtered(.....)


    switch (GST_MESSAGE_TYPE (msg)) {
    .......
    .......
    .......
    gst_message_unref( msg );

    }

    Thread2 exits after completion of every song and creats again after every song.

    Still I'm facing this issue.

    Thanks and Regards
    Deshvir Malik
  • Hello,

    Please check my previous post dark green lines and try it.
    I am sorry but I should ask one more question. Confirm is my understanding is right.
    In thread 1 you are moving pipeline is NULL state and thread 2 exist in thread 1 and in thread 2 you are moving pipeline in Playing state?

    BR
    Margarita
  • Hi Mr. Deshvir,

    Can you please respond on this please?

    Best Regards

    Feroz

  • Hi Margarita,

    I am sorry for late reply.

    Your understanding is not right as per implementation of the code.

    1. In thread 1, I have created thread 2 and song path is given as an input parameter to thread 1. Then thread 1 takes care of pipeline creation and playing song

    Below is the source code of thread 2.

    VOID* play(VOID* path)
    {    
        GstStateChangeReturn ret;
        CHAR *uri =(CHAR*)path;
        PlaySongThreadActive = TRUE;
        curSong.terminate = FALSE;
        
        
        static INT32 flag = 0;
        UCHAR deleteIndexStatus = 0;
            
        curSong.playbin = gst_element_factory_make ("playbin", "playbin");
        if (!curSong.playbin)
        {
            //log error ("Not all elements could be created.\n");        
            pthread_exit(NULL);
        }
            
        /* Set the URI to play */
        g_object_set (curSong.playbin, "uri",uri, NULL);
        ret = gst_element_set_state(curSong.playbin, GST_STATE_PLAYING);
        if (ret == GST_STATE_CHANGE_FAILURE) {
            //Unable to set the pipeline to the playing state.
        }
        else{
            //setting the pipeline to the playing state.        
        }
           
        curSong.playing = TRUE;
        curSong.seekEnabled = TRUE;     

        /* Listen to the bus */
        curSong.bus = gst_element_get_bus (curSong.playbin);

        do
        {
            curSong.msg = gst_bus_timed_pop_filtered (curSong.bus,                 \
            100000000 * GST_NSECOND, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR |
            GST_MESSAGE_EOS);   
            g_print("curSong : %s \n",curSong.msg);
           
           
            /* Parse message */
            if (curSong.msg != NULL)
            {
                
                GError *err;
                gchar *debug_info;       

                switch (GST_MESSAGE_TYPE (curSong.msg))
                {
                   
                    case GST_MESSAGE_ERROR:
                       
                        gst_message_parse_error (curSong.msg,&err, &debug_info);
                        g_printerr ("Error received from element %s: %s\n",        \
                        GST_OBJECT_NAME (curSong.msg->src), err->message);

                        g_printerr ("Debugging information: %s\n",debug_info ?     \
                         debug_info : "none");
                        
                        g_clear_error (&err);
                        g_free (debug_info);
                        g_debug("%s",curSong.msg);
                        curSong.playing = FALSE;
                        curSong.seekEnabled = FALSE;
                        curSong.terminate = TRUE;         
                        deleteIndexStatus = deleteEntryAt(curIndex+1);                    
                        if (deleteIndexStatus == SUCCESS)
                        {                                            
                           LOG(DBG_ERROR, MEDIA_LOG_FILE, "Entry deleted successfully\n");
                        }
                        else
                        {                 
                             
                            LOG(DBG_ERROR, MEDIA_LOG_FILE, "Entry not deleted\n");
                        }

                        break;
                    
                    case GST_MESSAGE_EOS:
     
                      
                        g_print ("End-Of-Stream reached.\n");
                       
                        
                        curSong.playing = FALSE;
                        curSong.seekEnabled = FALSE;
                        curSong.terminate = TRUE;
                        break;
                    
                    case GST_MESSAGE_STATE_CHANGED:              
                        {                        
                            GstState old_state, new_state, pending_state;
                            gst_message_parse_state_changed (curSong.msg,          \
                                &old_state, &new_state, &pending_state);
                            
                            if (GST_MESSAGE_SRC (curSong.msg) ==                   \
                                GST_OBJECT(curSong.playbin))
                            {
                                
                                g_print ("Pipeline state changed from %s to %s:\n",\
                                 gst_element_state_get_name (old_state),           \

                                gst_element_state_get_name (new_state));
                                /* Remember whether we are in the PLAYING state or
                                   not                                          */
                                curSong.playing = (new_state == GST_STATE_PLAYING);
                                if (curSong.playing)
                                {
                                    
                                    /* We just moved to PLAYING. Check if seeking
                                     is possible */
                                    GstQuery *query;
                                    gint64 start, end;
                                    query = gst_query_new_seeking (GST_FORMAT_TIME);
                                    if (gst_element_query (curSong.playbin, query))
                                    {
                                        
                                        gst_query_parse_seeking (query, NULL,          
                                            &curSong.seekEnabled, &start, &end);
                                        if (curSong.seekEnabled)
                                        {                                         
                                            g_print ("Seeking is ENABLED from %"   \
                                            GST_TIME_FORMAT " to %" GST_TIME_FORMAT\
                                            "\n", GST_TIME_ARGS (start),           \
                                            GST_TIME_ARGS (end));                                

                                        }
                                        else
                                        {                                        
                                            /*g_print ("Seeking is DISABLED for this"\
                                             "stream.\n"); */
                                        }
                                    }
                                    else
                                    {
                                       
                                        //g_print ("Seeking query failed.");
                                    }
                                    
                                    gst_query_unref (query);
                                }
                                
                            }
                           
                        }
                        
                        break;
                       
                    default:

                        /* Should not reach here */
                        
                        g_printerr ("Unexpected message received.\n");
                        break;
                }
                
                g_debug("%s",curSong.msg);
                gst_message_unref (curSong.msg);
            }        
            
        } while (!curSong.terminate);
        
        PlaySongThreadActive = FALSE;
        LOG(DBG_ERROR, MEDIA_LOG_FILE, "Playing Thread Killed\n");
        return SUCCESS;
    }

    After completion of a song, thread2 will get killed and return to thread 1.

    Again thread 1 will create thread 2 providing the path to thread 2 and process remains continue.

    Thanks and Regards,

    Deshvir Malik

  • Hello Deshvir Malik,

    We tried simple application which is building this pipeline:

    gst-launch filesrc location=XXX.aac ! faad ! alsasink

    This simple application has crossed 800 iterations.

    I am attaching the source code.

    As you could see, it plays two audio files one after the other(sample1.aac & sample.aac). Both files's locations are hard coded, just for the tests.

    6087.test_audio.txt

    We also tried the same pipeline with this script:

    COUNTER=0
    while true
    do
        echo The counter is $COUNTER
                    gst-launch-0.10 filesrc location=davinci.aac ! faad ! alsasink
        let COUNTER=COUNTER+1   
    done
     
     
    and ran for more than 20000 iterations.

    BR
    Margarita

  • Hello Deshvir,

    Could you try on your side the app that you are using but with filesrc and to read the audio file's not from USB?

    Let me know the result.

    BR
    Margarita
  • Hi Margarita,

    I am able to play upto 1500 songs and then exit the application. This I achieved by creating a simple application in which only Play(Void *Path) API called and static song path was given from SD Card rather than USB. This is the condition when play API is not used as a thread.

    But the next problem I'm facing is with CPU usage. CPU usage goes upto 95% and streaming of song becomes very slow. For ex, 10sec song will take 25Sec to play and which is equivalent to hang issue.

    I used top command to check CPU usage.

    I have attached three files

    1. Media.txt -> consist of Play API

    2. Application.txt -> Test Application

    3. Logs.txt -> Check for CPU usage of ./Test_Media_Call_Play

     

    According to my analysis, problem might be because of below command

    curSong.msg = gst_bus_timed_pop_filtered (curSong.bus,                 \
            100000000 * GST_NSECOND, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR |
            GST_MESSAGE_EOS);

    Note : Is there any alternative for above command?2311.Logs.txt

     

    5543.Application.txt

    0702.Media.txt

  • Hello,


    Could you try with:

    GST_CLOCK_TIME_NONE instead of 100000000 * GST_NSECOND?

    If you increase the app's priority do you observe improvement?

    Deshvir Malik said:
    Note : Is there any alternative for above command?(Please visit the site to view this file)

    Check here: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBus.html

    BR
    Margarita

  • Hi Margarita,

    I have tried with GST_CLOCK_TIME_NONE instead of 100000000 * GST_NSECOND

    curSong.msg = gst_bus_timed_pop_filtered (curSong.bus,                 \
            GST_CLOCK_TIME_NONE, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR |
            GST_MESSAGE_EOS);

    But still, CPU usage is going up to 95% in-between while a song is playing. Once CPU usage is high, it remains at the same level ie 90-95% for few minutes and comes down automatically. This I verified using top command.

    I have doubt on gst_bus_timed_pop_filtered function because I do not know what's going on internally at Gstreamer libraries once I call this function.

    Thanks and Regards,

    Deshvir Malik

  • Hello,

    I am sorry for the delay.
    When the CPU load is high?
    You are using playbin element to play songs right?
    If yes, could you check something?
    If I remember right the elements audioresample and audioconvert will be add in the pipeline when playbin is used.
    These elements will add CPU load if they are use(not in bypass mode) for some songs. Could you check when you are observing the CPU load is for specific song ?

    BR
    Margarita
  • Hi Margarita,

    I'm answering as per your question sequence.

    CPU load is high randomly. I haven't observed any specific pattern. For eg: As i observed during testing, it might occur after 5 sec of first song or it can occur after 50 songs.

    Yes I'm using playbin element to play songs. More specifically, I'm using dynamic pipeline using gst_element_factory_make("playbin","playbin"). 

    As you said, If I remember right the elements audioresample and audioconvert will be add in the pipeline when playbin is used. This would be taken care by gstreamer library...right?

    I played same song present in SDCard using a simple application. This was getting played as per expectation for around 15-16times but again system got hanged and CPU usage reached 70-95%. So I think we can't doubt on that song also because it played for few number of times properly and later same hang issue occurred for the same song.

     

    Thanks and Regards

    Deshvir Malik

  • Hello,

    Could you try to increase the gstreamer app priority(gstreamer process priority)?
    You could try to do that with nice command.

    It is not clear, now you are observing hang or only high CPU load?


    BR
    Margarita
  • Hi Margarita,

    I'll try with nice command.

    Consider an example, we are playing a song of 10sec. First, when CPU usage goes in the range of 70-95% (checked using top command), at that time rather than completing the song within 10sec, it takes around 20-30sec for 10 sec song duration. Secondly, there is no sound audible from speaker. This scenario I'm considering as hang.

    Thanks and Regards
    Deshvir Malik
  • Hello,

    I understand what you mean by hang.
    Let me know the result when you increase the priority.

    BR
    Margarita