Hi all,
I am working on a feature that play specified program in one ts stream with relevant video pid and audio pid, eg, there is a ts file named test.ts, it has following program info which get from pat&pmt, program1, video pid=201, audio pid=401, program2, video pid=202, audio pid=402, program3, video pid=203, audio pid=403, it can play out the stream with cmd #gst-launch-0.10 filesrc location=test.ts ! decodebin ! ffmpegcolorspace ! videoscale ! ximagesink sync=false but i don't know how to play the specified program, or play with specified pid, can somebody help me? Kind regards! lesson |
Foremost, move to gstreamer 1.0. 0.10 is no longer maintained since a couple of years.
To answer your question, you can use the program-number property of tsdemux: gst-launch-0.10 filesrc location=test.ts ! tsdemux program-number=xxx ! decodebin ! ffmpegcolorspace ! videoscale ! ximagesink sync=false |
Hi Arjen,
Thanks for your reply! After modification, i use gst-launch-1.0 to play the file, and it played well, #gst-launch-1.0 -v filesrc location=test.ts ! decodebin ! videoconvert ! videoscale ! ximagesink sync=false then add program-number , #gst-launch-1.0 -v filesrc location=test.ts ! tsdemux program-number=1 ! decodebin ! videoconvert ! videoscale ! ximagesink sync=false but it failed, Setting pipeline to PAUSED ... Pipeline is PREROLLING ... ERROR: from element /GstPipeline:pipeline0/GstTSDemux:tsdemux0: Internal data stream error. Additional debug info: mpegtsbase.c(1307): mpegts_base_loop (): /GstPipeline:pipeline0/GstTSDemux:tsdemux0: No program activated before EOS ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... Freeing pipeline ... |
Hi,
Sorry for disturbing, but the problem is still there. If i use following cmd, #gst-launch-1.0 -v filesrc location=test.ts ! tsdemux ! decodebin ! videoconvert ! videoscale ! ximagesink sync=false it can play video out, and print info Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstDecodeBin:decodebin0.GstGhostPad:sink.GstProxyPad:proxypad0: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:src: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:sink: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false /GstPipeline:pipeline0/GstDecodeBin:decodebin0.GstGhostPad:sink: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMpegvParse:mpegvparse0.GstPad:sink: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMpegvParse:mpegvparse0.GstPad:src: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false, parsed=(boolean)true, width=(int)720, height=(int)576, framerate=(fraction)25/1, pixel-aspect-ratio=(fraction)64/45, codec_data=(buffer)000001b32d024033249f23821020202620262c2c2c2c2c2c343034363636343434343636363a3a3a4444443a3a3a36363a3a404044444a4c4a464644464c4c50505060605c5c7070748a8aa7111111151215191919191b1b201d202222222121212324242427272730303029292926262b2b2f2f3232373b39363635363e3e41414152524f4f6565688282a4000001b5148200010000, profile=(string)main, level=(string)main, interlace-mode=(string)mixed /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMpeg2dec:mpeg2dec0.GstPad:sink: caps = video/mpeg, mpegversion=(int)2, systemstream=(boolean)false, parsed=(boolean)true, width=(int)720, height=(int)576, framerate=(fraction)25/1, pixel-aspect-ratio=(fraction)64/45, codec_data=(buffer)000001b32d024033249f23821020202620262c2c2c2c2c2c343034363636343434343636363a3a3a4444443a3a3a36363a3a404044444a4c4a464644464c4c50505060605c5c7070748a8aa7111111151215191919191b1b201d202222222121212324242427272730303029292926262b2b2f2f3232373b39363635363e3e41414152524f4f6565688282a4000001b5148200010000, profile=(string)main, level=(string)main, interlace-mode=(string)mixed Redistribute latency... /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMpeg2dec:mpeg2dec0.GstPad:src: caps = video/x-raw, format=(string)I420, width=(int)720, height=(int)576, pixel-aspect-ratio=(fraction)64/45, interlace-mode=(string)mixed, chroma-site=(string)mpeg2, colorimetry=(string)bt601, framerate=(fraction)25/1 /GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = video/x-raw, width=(int)720, height=(int)576, pixel-aspect-ratio=(fraction)64/45, interlace-mode=(string)mixed, framerate=(fraction)25/1, format=(string)BGRx /GstPipeline:pipeline0/GstVideoScale:videoscale0.GstPad:src: caps = video/x-raw, width=(int)1024, height=(int)576, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)mixed, framerate=(fraction)25/1, format=(string)BGRx /GstPipeline:pipeline0/GstXImageSink:ximagesink0.GstPad:sink: caps = video/x-raw, width=(int)1024, height=(int)576, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)mixed, framerate=(fraction)25/1, format=(string)BGRx /GstPipeline:pipeline0/GstVideoScale:videoscale0.GstPad:sink: caps = video/x-raw, width=(int)720, height=(int)576, pixel-aspect-ratio=(fraction)64/45, interlace-mode=(string)mixed, framerate=(fraction)25/1, format=(string)BGRx /GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = video/x-raw, format=(string)I420, width=(int)720, height=(int)576, pixel-aspect-ratio=(fraction)64/45, interlace-mode=(string)mixed, chroma-site=(string)mpeg2, colorimetry=(string)bt601, framerate=(fraction)25/1 /GstPipeline:pipeline0/GstDecodeBin:decodebin0.GstDecodePad:src_0.GstProxyPad:proxypad1: caps = video/x-raw, format=(string)I420, width=(int)720, height=(int)576, pixel-aspect-ratio=(fraction)64/45, interlace-mode=(string)mixed, chroma-site=(string)mpeg2, colorimetry=(string)bt601, framerate=(fraction)25/1 but if i add the property "program-number=1", it will return err, Setting pipeline to PAUSED ... Pipeline is PREROLLING ... ERROR: from element /GstPipeline:pipeline0/GstTSDemux:tsdemux0: Internal data stream error. Additional debug info: mpegtsbase.c(1307): mpegts_base_loop (): /GstPipeline:pipeline0/GstTSDemux:tsdemux0: No program activated before EOS ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... Freeing pipeline ... Thanks! |
Are you sure that your program number is actually 1? (you can use ffprobe to verify that).
|
Here is the file information got from ffprobe,
ffprobe version 3.1.3 Copyright (c) 2007-2016 the FFmpeg developers built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04.3) configuration: --enable-memalign-hack --disable-yasm --disable-debug libavutil 55. 28.100 / 55. 28.100 libavcodec 57. 48.101 / 57. 48.101 libavformat 57. 41.100 / 57. 41.100 libavdevice 57. 0.101 / 57. 0.101 libavfilter 6. 47.100 / 6. 47.100 libswscale 4. 1.100 / 4. 1.100 libswresample 2. 1.100 / 2. 1.100 [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. [mpeg2video @ 0x275a160] Invalid frame dimensions 0x0. Last message repeated 1 times [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. [mpeg2video @ 0x275a160] Invalid frame dimensions 0x0. [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. [NULL @ 0x2870be0] SPS unavailable in decode_picture_timing [NULL @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [mpeg2video @ 0x275a160] Invalid frame dimensions 0x0. [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. Last message repeated 1 times [mpeg2video @ 0x275a160] Invalid frame dimensions 0x0. [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [mpeg2video @ 0x27744e0] Invalid frame dimensions 0x0. [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] SPS unavailable in decode_picture_timing [h264 @ 0x2870be0] non-existing PPS 0 referenced [h264 @ 0x2870be0] decode_slice_header error [h264 @ 0x2870be0] no frame! [h264 @ 0x2870be0] Increasing reorder buffer to 2 [mpegts @ 0x2736ba0] PES packet size mismatch Last message repeated 1 times Input #0, mpegts, from '../../test.ts': Duration: 00:01:00.28, start: 0.333333, bitrate: 26351 kb/s Program 40001 Metadata: service_name : TVE-HD Pruebas service_provider: TVE Stream #0:9[0x3e9]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc Stream #0:3[0x44c](spa): Audio: eac3 ([6][0][0][0] / 0x0006), 48000 Hz, stereo, fltp, 128 kb/s Program 40002 Metadata: service_name : tdp Pruebas service_provider: RTVE Stream #0:0[0x7d1]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc Stream #0:1[0x7d2](spa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 192 kb/s Program 40003 Metadata: service_name : Pruebas TVE service_provider: RTVE Stream #0:6[0xbb9]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc Stream #0:8[0xbba](spa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 192 kb/s Program 40005 Metadata: service_name : Radio Cl醩ica service_provider: NoName Stream #0:7[0x7da](spa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 320 kb/s Program 40006 Metadata: service_name : Radio 3 service_provider: NoName Stream #0:5[0xbc2](spa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 256 kb/s No Program Stream #0:2[0x21]: Video: mpeg2video (Main), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], 6000 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc Stream #0:4[0x23]: Audio: mp2, 48000 Hz, stereo, s16p, 224 kb/s |
I understand where is the problem, the program-number should be the number read from PAT, eg,40001.
i just thought its a logical number from 0~4 , thanks very much. |
That is indeed what you have to do. Great that you got it working.
|
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); } |
Free forum by Nabble | Edit this page |