Gstreamer audio playback only at end of stream and for 5 seconds only

roonie mdzubair89 at yahoo.co.in
Mon Sep 8 23:36:57 PDT 2014


Hi all,

Iam trying to play audio only from mpegts stream using appsrc.
I have already tried with filesrc as input , i get the audio alone
perfectly. I am not sure what I am missing.

I am using I.MX6 for playback. So iam using freescale plugins.
Below is my code.

#include <stdio.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>

typedef struct {
    GstPipeline *pipeline;
    GstAppSrc *src;
    GstElement *demuxer;
    GstElement *audioqueue;
    GstElement *videoqueue;
    GstElement *audio_decoder;
    GstElement *video_decoder;
    GstElement *audio_sink;
    GstElement *video_sink;
    GstElement *video_convert;
    GstElement *audio_convert;
    GMainLoop *loop;
    guint sourceid;
    FILE *file;
}gst_app_t;

static gst_app_t gst_app;

//#define BUFF_SIZE (1024)
#define BUFF_SIZE (1316)

static gboolean read_data(gst_app_t *app)
{
    GstBuffer *buffer;
    guint8 *ptr;
    gint size;
    GstFlowReturn ret;

    ptr = g_malloc(BUFF_SIZE);
    g_assert(ptr);

    size = fread(ptr, 1, BUFF_SIZE, app->file);

    if(size == 0){
        ret = gst_app_src_end_of_stream(app->src);
        g_debug("eos returned %d at %d\n", ret, __LINE__);
        return FALSE;
    }

    buffer = gst_buffer_new();
    GST_BUFFER_MALLOCDATA(buffer) = ptr;
    GST_BUFFER_SIZE(buffer) = size;
    GST_BUFFER_DATA(buffer) = GST_BUFFER_MALLOCDATA(buffer);

    ret = gst_app_src_push_buffer(app->src, buffer);

    if(ret !=  GST_FLOW_OK){
        g_print("push buffer returned %d for %d bytes \n", ret, size);
        return FALSE;
    }

    if(size != BUFF_SIZE){
        ret = gst_app_src_end_of_stream(app->src);
        g_print("eos returned %d at %d\n", ret, __LINE__);
        return FALSE;
    }

    return TRUE;
}

static void start_feed (GstElement * pipeline, guint size, gst_app_t *app)
{
    if (app->sourceid == 0) {
        GST_DEBUG ("start feeding");
        app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
    }
}

static void stop_feed (GstElement * pipeline, gst_app_t *app)
{
    if (app->sourceid != 0) {
        GST_DEBUG ("stop feeding");
        g_source_remove (app->sourceid);
        app->sourceid = 0;
    }
}

static void on_pad_added(GstElement *element, GstPad *pad,gst_app_t *app )
{
    GstCaps *caps;
    GstStructure *str;
    gchar *name;
    GstPad *videosink,*audiosink;
    GstPadLinkReturn ret;

    g_print("pad added\n");

    caps = gst_pad_get_caps(pad);
    str = gst_caps_get_structure(caps, 0);

    g_assert(str);


    name = (gchar*)gst_structure_get_name(str);

    g_print("pad name %s\n", name);


     if (g_str_has_prefix (name,"audio/mpeg"))
 	{

		audiosink = gst_element_get_static_pad(app->audioqueue, "sink");
		g_print("audiosink:%s\n",  GST_PAD_NAME (audiosink));
		g_assert(audiosink);
		ret = gst_pad_link(pad, audiosink);
		if (GST_PAD_LINK_FAILED (ret))
		{
			g_print (" Type is '%s' but link failed.\n", pad);
		}
		else
		{
			g_print (" Link succeeded (type '%s').\n", pad);
		}

       // g_print("pad_link returned %d \n", ret);
	gst_object_unref(audiosink);
    }

    gst_caps_unref(caps);
}

static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer
*ptr)
{
    gst_app_t *app = (gst_app_t*)ptr;

    switch(GST_MESSAGE_TYPE(message)){

    case GST_MESSAGE_ERROR:{
        gchar *debug;
        GError *err;

        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(app->loop);
    }
    break;

    case GST_MESSAGE_EOS:
        g_print("End of stream\n");
        g_main_loop_quit(app->loop);
        break;

    default:
        g_print("got message %s\n", \
            gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
        break;
    }

    return TRUE;
}

int main(int argc, char *argv[])
{
    gst_app_t *app = &gst_app;
    GstBus *bus;
    GstCaps *caps;
    GstStateChangeReturn state_ret;

    if(argc != 2){
        printf("File name not specified\n");
        return 1;
    }

    app->file = fopen(argv[1], "r");

    g_assert(app->file);

    gst_init(NULL, NULL);

    app->pipeline = (GstPipeline*)gst_pipeline_new("mypipeline");
    bus = gst_pipeline_get_bus(app->pipeline);
    gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
    gst_object_unref(bus);

    app->src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc");

    app->demuxer = gst_element_factory_make ("aiurdemux", "demuxer");
    app->audioqueue = gst_element_factory_make("queue","audioqueue");
    app->audio_decoder = gst_element_factory_make ("beepdec",
"audio_decoder");
    app->audio_convert = gst_element_factory_make ("audioconvert",
"audio_convert");
    app->audio_sink = gst_element_factory_make ("autoaudiosink",
"audio_sink");



    g_assert(app->src);
    g_assert(app->demuxer);
     g_assert(app->audioqueue);
    g_assert(app->audio_decoder);
    g_assert(app->audio_convert);
    g_assert(app->audio_sink);

    g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
    g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
    g_signal_connect(app->demuxer, "pad-added", G_CALLBACK(on_pad_added),
app);
    caps = gst_caps_new_simple("video/mpegts",NULL);


    gst_bin_add_many(GST_BIN(app->pipeline),
(GstElement*)app->src,app->demuxer,app->audioqueue,app->audio_decoder,app->audio_sink,app->audio_convert,
NULL);
  

    
    if(!gst_element_link_filtered((GstElement*)app->src, app->demuxer
,caps)){
        g_print("failed to link with caps");
    }

  
   
if(!gst_element_link_many(app->audioqueue,app->audio_decoder,app->audio_convert,app->audio_sink,NULL)){
	    g_warning("failed to link audio elements");
    }


    state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_PLAYING);
    g_warning("set state returned %d\n", state_ret);

    app->loop = g_main_loop_new(NULL, FALSE);
    printf("Running main loop\n");
    g_main_loop_run(app->loop);
}

I have already tried with corresponding gst-launch command with the plugins
and it does playback a ts stream.

This is what I have used.
gst-launch filesrc location=/opt/zubair/test/stream2.ts typefind=true !
aiurde
mux ! queue ! beepdec ! audioconvert !  alsasink

When I playback through above code, I get below log. The "discont continued"
keeps logging till end of stream.

LOG:
              audio/mpeg, mpegversion=(int)1, framed=(boolean)true,
channels=(int)2, rate=(int
              )48000, bitrate=(int)192
pad added
pad name audio/mpeg
audiosink:sink
 Link succeeded (type '').
Track 01 [video_001011] Enabled
        ppid: 1, ppid 17
        Duration: 0:00:00.000000000
        Language: und
        Mime:
              video/mpeg, systemstream=(boolean)false, parsed=(boolean)true,
mpegversion=(int)
              2, width=(int)480, height=(int)480,
framerate=(fraction)30000/1001, codec_data=(
             
buffer)000001b31e01e024249f23811011111212121313131314141414141515151515151616161
             
6161616171717171717171718181819181818191a1a1a1a191b1b1b1b1b1c1c1c1c1e1e1e1f1f210
              00001b5148200010000
pad added
pad name video/mpeg
Discont detected from 0:00:00.000000000 to 0:01:31.904788000
got message tag
got message tag
Discont detected from 0:00:00.500000000 to 0:01:31.928788000
Discont detected from 0:00:00.500000000 to 0:01:31.952788000
Discont detected from 0:00:00.500000000 to 0:01:31.976788000
Discont detected from 0:00:00.500000000 to 0:01:32.000788000
Beep: 3.0.7 
Core: MP3 decoder Wrapper  build on Mar 20 2013 11:24:31
  mime: audio/mpeg, mpegversion = (int)1
  file: /usr/lib/imx-mm/audio-codec/wrap/lib_mp3d_wrap_arm12_elinux.so
CODEC: BLN_MAD-MMCODECS_MP3D_ARM_02.13.00_CORTEX-A8  build on Dec  5 2012
09:45:19.
Discont detected from 0:00:00.500000000 to 0:01:32.024788000
Discont detected from 0:00:00.500000000 to 0:01:32.048788000
got message tag
Discont detected from 0:00:00.500000000 to 0:01:32.072788000
Discont detected from 0:00:00.500000000 to 0:01:32.096788000
Discont detected from 0:00:00.500000000 to 0:01:32.120788000
Discont detected from 0:00:00.500000000 to 0:01:32.144788000
Discont detected from 0:00:00.500000000 to 0:01:32.168788000
Discont detected from 0:00:00.500000000 to 0:01:32.192788000
Discont detected from 0:00:00.500000000 to 0:01:32.216788000
Discont detected from 0:00:00.500000000 to 0:01:32.240788000


At the end of log I get the below log  and it does audio playback for 5
seconds

Discont detected from 0:00:00.500000000 to 0:03:04.856788000
Discont detected from 0:00:00.500000000 to 0:03:04.880788000
eos returned 0 at 59
Discont detected from 0:00:00.500000000 to 0:03:04.904788000
Discont detected from 0:00:00.500000000 to 0:03:04.928788000
Discont detected from 0:00:00.500000000 to 0:03:04.952788000
Discont detected from 0:00:00.500000000 to 0:03:04.976788000
Discont detected from 0:00:00.500000000 to 0:03:05.000788000
got message tag
got message stream-status
got message state-changed
got message state-changed
got message state-changed
got message async-done
got message new-clock
got message state-changed
got message state-changed
got message state-changed
got message state-changed
got message state-changed
got message state-changed
got message state-changed
got message state-changed
got message state-changed
End of stream


Am i missing something in appsrc.?





--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Gstreamer-audio-playback-only-at-end-of-stream-and-for-5-seconds-only-tp4668618.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list