How to play ts stream with specified pid

lessonZhang 176237766 at qq.com
Fri Sep 2 09:47:54 UTC 2016


Then i implement the above workflow in c code, and found that if play video
only, it can work as expect, but when play video and audio at same time, it
will return err:

Received new pad 'video_07d1' from 'mpg-demux':
  Link succeeded (type 'video/mpeg').
Received new pad 'src_0' from 'mpeg-decoder':
  Link succeeded (type 'video/x-raw').
Received new pad 'audio_07d2' from 'mpg-demux':
  Link succeeded (type 'audio/mpeg').
Error: Internal data stream error.
Debug details: mpegtsbase.c(1311): mpegts_base_loop (): /GstPipeline:VIDEO
PLAYER/GstTSDemux:mpg-demux:
stream stopped, reason not-negotiated

below the code:
#include<gst/gst.h>

static gboolean bus_call (GstBus     *bus,  GstMessage *msg,   gpointer   
data); 
static void on_decpad_added(GstElement *element, GstPad *pad ); 
static void on_dmxpad_added(GstElement *element, GstPad *pad ) ;


GstElement *pipeline, *src, *demux, *decoderv, *sinkv, *decodera, *convertv,
*convert, *resample, *sinka; 
GstElement *queueA, *queueV; 

int main(int argc, char *argv[]) 
  { 
   GstStateChangeReturn ret; 
   GMainLoop *loop; 
   GstBus *bus; 
   /*initialization*/ 
   gst_init(&argc,&argv); 
   loop = g_main_loop_new(NULL, FALSE); 
    
   if(argc != 2) 
     { 
     g_print("Usage: %s <mpg/mpeg video file>", argv[0]); 
     return -1; 
     } 

    pipeline = gst_pipeline_new("VIDEO PLAYER"); 
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); 
    gst_bus_add_watch(bus, bus_call, loop); 
	gst_object_unref (bus);

    src = gst_element_factory_make("filesrc", "filesource"); 
    demux = gst_element_factory_make("tsdemux", "mpg-demux"); 
	g_object_set (G_OBJECT (demux), "program-number", 40002, NULL); //the
program number get from PAT
    
    /*Gstreamer video elements*/ 
    decoderv = gst_element_factory_make("decodebin", "mpeg-decoder"); 
	 convertv = gst_element_factory_make("videoconvert", "video-convert"); 
    sinkv = gst_element_factory_make("xvimagesink", "video-out"); 
    if(!decoderv || !sinkv) 
     { 
      g_print("\nthe video could not playback\n"); 
      return -1; 
     } 

   /*Gstreamer audio elements*/ 
   decodera = gst_element_factory_make("mad", "decoder-audio"); 
   convert = gst_element_factory_make("audioconvert", "a-convert"); 
   resample = gst_element_factory_make("audioresample", "a-resample"); 
   sinka = gst_element_factory_make("alsasink", "play audio"); 
   if(!decodera || !convert || !resample || !sinka) 
     { 
      g_print("\nthe audio could not playback\n"); 
      return -1; 
     } 
    
   queueA = gst_element_factory_make("queue", "queue-audio"); 
   queueV = gst_element_factory_make("queue", "queue-video"); 

   g_object_set (G_OBJECT (src), "location", argv[1], NULL); 
   //gst_bin_add_many(GST_BIN(pipeline), src, demux, queueV, decoderv,
convertv,sinkv, NULL); //decode video only
   					
   gst_bin_add_many(GST_BIN(pipeline), src, demux, queueV, decoderv,
convertv,sinkv, 
   					queueA, decodera,convert, resample, sinka, NULL); 

  //link video source 
   gst_element_link (src, demux); 
   //gst_element_link (queueV, decoderv); 
	gst_element_link (convertv, sinkv); 
  // gst_element_link (queueA, convert); 

  //link audio source
   gst_element_link (decodera, convert);
   gst_element_link (convert, resample); 
   gst_element_link (resample, sinka); 

   g_signal_connect (demux, "pad-added",G_CALLBACK(on_dmxpad_added),demux); 
   g_signal_connect (decoderv,
"pad-added",G_CALLBACK(on_decpad_added),decoderv); 
  
 /* run */ 
   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); 
  
   if (ret == GST_STATE_CHANGE_FAILURE) 
    { 
     GstMessage *msg; 

     g_print ("Failed to start up pipeline!\n"); 

     /* check if there is an error message with details on the bus */ 
     msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0); 
     if (msg) { 
       GError *err = NULL; 
       g_print("\nDISPLAY ERROR:\n"); 
       gst_message_parse_error (msg, &err, NULL); 
       g_print ("ERROR: %s\n", err->message); 
       g_error_free (err); 
       gst_message_unref (msg); 
    } 
    return -1; 
  } 

   g_main_loop_run (loop); 

  /* clean up */ 
   gst_element_set_state (pipeline, GST_STATE_NULL); 
   gst_object_unref (pipeline); 

   return 0; 

  } 


static gboolean bus_call (GstBus     *bus,  GstMessage *msg,   gpointer   
data) 
{ 
  GMainLoop *loop = data; 

  switch (GST_MESSAGE_TYPE (msg)) { 
    case GST_MESSAGE_EOS: 
      g_print ("End-of-stream\n"); 
      g_main_loop_quit (loop); 
      break; 
    case GST_MESSAGE_ERROR: { 
      gchar *debug = NULL; 
      GError *err = NULL; 

      gst_message_parse_error (msg, &err, &debug); 

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

      if (debug) { 
        g_print ("Debug details: %s\n", debug); 
        g_free (debug); 
      } 

      g_main_loop_quit (loop); 
      break; 
    } 
    default: 
      break; 
  } 

  return TRUE; 
} 

static void on_dmxpad_added(GstElement *element, GstPad *pad ) 
{  
  GstPad *sink_padv = gst_element_get_static_pad (decoderv, "sink");  
  GstPad *sink_pada = gst_element_get_static_pad (decodera, "sink");  
  GstPadLinkReturn ret;  
  GstCaps *new_pad_caps = NULL;  
  GstStructure *new_pad_struct = NULL;  
  const gchar *new_pad_type = NULL;  
    
  g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (pad),
GST_ELEMENT_NAME (element));  
    
  /* Check the new pad's type */  
  new_pad_caps = gst_pad_get_current_caps (pad);  
  new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);  
  new_pad_type = gst_structure_get_name (new_pad_struct);  
  if (g_str_has_prefix (new_pad_type, "video")) {  
    /* If our converter is already linked, we have nothing to do here */  
	  if (gst_pad_is_linked (sink_padv)) {  
	    g_print ("  We are already linked. Ignoring.\n");  
	    goto exit;  
	  }  

	  /* Attempt the link */  
  	  ret = gst_pad_link (pad, sink_padv);  
  }  
  else if (g_str_has_prefix (new_pad_type, "audio")) {  
    /* If our converter is already linked, we have nothing to do here */  
	  if (gst_pad_is_linked (sink_pada)) {  
	    g_print ("  We are already linked. Ignoring.\n");  
	    goto exit;  
	  }  

	  /* Attempt the link */  
  	  ret = gst_pad_link (pad, sink_pada);  
  }  
    
  
  if (GST_PAD_LINK_FAILED (ret)) {  
    g_print ("  Type is '%s' but link failed.\n", new_pad_type);  
  } else {  
    g_print ("  Link succeeded (type '%s').\n", new_pad_type);  
  }  
    
exit:  
  /* Unreference the new pad's caps, if we got them */  
  if (new_pad_caps != NULL)  
    gst_caps_unref (new_pad_caps);  
    
  /* Unreference the sink pad */  
  gst_object_unref (sink_padv);  
  gst_object_unref (sink_pada);  
}


static void on_decpad_added(GstElement *element, GstPad *pad ) 
{  
  GstPad *sink_pad = gst_element_get_static_pad (convertv, "sink");  
  GstPadLinkReturn ret;  
  GstCaps *new_pad_caps = NULL;  
  GstStructure *new_pad_struct = NULL;  
  const gchar *new_pad_type = NULL;  
    
  g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (pad),
GST_ELEMENT_NAME (element));  
    
  /* If our converter is already linked, we have nothing to do here */  
  if (gst_pad_is_linked (sink_pad)) {  
    g_print ("  We are already linked. Ignoring.\n");  
    goto exit;  
  }  
    
  /* Check the new pad's type */  
  new_pad_caps = gst_pad_get_current_caps (pad);  
  new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);  
  new_pad_type = gst_structure_get_name (new_pad_struct);  
  if (!g_str_has_prefix (new_pad_type, "video")) {  
    g_print ("  It has type '%s' which is not raw audio. Ignoring.\n",
new_pad_type);  
    goto exit;  
  }  
    
  /* Attempt the link */  
  ret = gst_pad_link (pad, sink_pad);  
  if (GST_PAD_LINK_FAILED (ret)) {  
    g_print ("  Type is '%s' but link failed.\n", new_pad_type);  
  } else {  
    g_print ("  Link succeeded (type '%s').\n", new_pad_type);  
  }  
    
exit:  
  /* Unreference the new pad's caps, if we got them */  
  if (new_pad_caps != NULL)  
    gst_caps_unref (new_pad_caps);  
    
  /* Unreference the sink pad */  
  gst_object_unref (sink_pad);  
}  




--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/How-to-play-ts-stream-with-specified-pid-tp4679308p4679374.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list