summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2006-09-21 09:35:13 +0000
committerWim Taymans <wim.taymans@gmail.com>2006-09-21 09:35:13 +0000
commit46d9a8a5e69743f571b0c4ea0a8a1ce1fcd8d937 (patch)
tree29e165d0077490463a072544ca2d4c9ff48db0cf /gst
parentf1533c55045bffbb9716ddd5df348ceff7213fbd (diff)
gst/rtp/README: Update README with some examples.
Original commit message from CVS: * gst/rtp/README: Update README with some examples. * gst/rtp/gstrtpmp4gpay.c: (gst_rtp_mp4g_pay_init), (gst_rtp_mp4g_pay_finalize), (gst_rtp_mp4g_pay_parse_audio_config), (gst_rtp_mp4g_pay_parse_video_config), (gst_rtp_mp4g_pay_new_caps), (gst_rtp_mp4g_pay_setcaps): * gst/rtp/gstrtpmp4gpay.h: Make optional RTP parameters of type STRING, as required by the application/x-rtp caps specification.
Diffstat (limited to 'gst')
-rw-r--r--gst/rtp/README105
-rw-r--r--gst/rtp/gstrtpmp4gpay.c75
-rw-r--r--gst/rtp/gstrtpmp4gpay.h6
3 files changed, 135 insertions, 51 deletions
diff --git a/gst/rtp/README b/gst/rtp/README
index 146c55fa..129efb97 100644
--- a/gst/rtp/README
+++ b/gst/rtp/README
@@ -29,7 +29,7 @@ The following fields can or must (*) be specified in the structure:
clock-base: (uint) [0 - MAXINT]
The RTP time representing time 0
- seqnum-base:
+ seqnum-base: (uint) [0 - MAXINT]
The RTP sequence number representing the first rtp packet
encoding-name: (String) ANY
@@ -76,19 +76,96 @@ The following fields can or must (*) be specified in the structure:
possible.
-TODO
-----
-
-- implement packing up to the MTU.
-- discont events in the case of packet loss
-- figure out the clocking.
-- implement various RFCs dealing with different payload types.
- (as modules?)
-- Throw-out the the caps-nego & other session control things to the
- Application Developer( App ), by turning rtcp work into, signals
- in gstrtpsend & props/args in gstrtprecv.
- The App would then be free to use any sort of session control
- protocal like RTSP.( done )
+usage with UDP
+--------------
+
+To correctly and completely use the RTP payloaders on the sender and the
+receiver you need to write an application. It is not possible to write a full
+blown RTP server with a single gst-launch line.
+
+That said, it is possible to do something functional with a few gst-launch
+lines. The biggest problem when constructing a correct gst-launch line lies on
+the receiver end.
+
+The receiver needs to know about the type of the RTP data along with a set of
+RTP configuration parameters. This information is usually transmitted to the
+client using some sort of session description language (SDP) over some reliable
+channel (HTTP/RTSP/...).
+
+All of the required parameters to connect and use the RTP session on the
+server can be found in the caps on the server end. The client receives this
+information in some way (caps are converted to and from SDP, as explained above,
+for example).
+
+Some gst-launch lines:
+
+ gst-launch-0.10 -v videotestsrc ! ffenc_h263p ! rtph263ppay ! udpsink
+
+ Setting pipeline to PAUSED ...
+ /pipeline0/videotestsrc0.src: caps = video/x-raw-yuv, format=(fourcc)I420,
+ width=(int)320, height=(int)240, framerate=(fraction)30/1
+ Pipeline is PREROLLING ...
+ ....
+ /pipeline0/udpsink0.sink: caps = application/x-rtp, media=(string)video,
+ payload=(int)96, clock-rate=(int)90000, encoding-name=(string)H263-1998,
+ ssrc=(guint)527842345, clock-base=(guint)1150776941, seqnum-base=(guint)30982
+ ....
+ Pipeline is PREROLLED ...
+ Setting pipeline to PLAYING ...
+ New clock: GstSystemClock
+
+ Write down the caps on the udpsink and set them as the caps of the UDP
+ receiver:
+
+ gst-launch-0.10 -v udpsrc caps="application/x-rtp, media=(string)video,
+ payload=(int)96, clock-rate=(int)90000, encoding-name=(string)H263-1998,
+ ssrc=(guint)527842345, clock-base=(guint)1150776941, seqnum-base=(guint)30982"
+ ! rtph263pdepay ! ffdec_h263 ! xvimagesink sync=false
+
+ The receiver now displays an h263 image. Note that the sync parameter on
+ xvimagesink needs to be FALSE because we do not have an RTP session manager
+ that controls the synchronisation in this pipeline.
+
+ Stream a quicktime file with mpeg4 video and AAC audio on port 5000 and port
+ 5002.
+
+ gst-launch-0.10 -v filesrc location=~/data/sincity.mp4 ! qtdemux name=d ! queue ! rtpmp4vpay ! udpsink port=5000
+ d. ! queue ! rtpmp4gpay ! udpsink port=5002
+ ....
+ /pipeline0/udpsink0.sink: caps = application/x-rtp, media=(string)video,
+ payload=(int)96, clock-rate=(int)90000, encoding-name=(string)MP4V-ES,
+ ssrc=(guint)1162703703, clock-base=(guint)816135835, seqnum-base=(guint)9294,
+ profile-level-id=(string)3, config=(string)000001b003000001b50900000100000001200086c5d4c307d314043c1463000001b25876694430303334
+ /pipeline0/udpsink1.sink: caps = application/x-rtp, media=(string)audio,
+ payload=(int)96, clock-rate=(int)44100, encoding-name=(string)mpeg4-generic,
+ ssrc=(guint)3246149898, clock-base=(guint)4134514058, seqnum-base=(guint)57633,
+ encoding-params=(string)2, streamtype=(string)5, profile-level-id=(string)1,
+ mode=(string)AAC-hbr, config=(string)1210, sizelength=(string)13,
+ indexlength=(string)3, indexdeltalength=(string)3
+ ....
+
+ Again copy the caps on both sinks to the receiver launch line
+
+ gst-launch
+ udpsrc port=5000 caps="application/x-rtp, media=(string)video, payload=(int)96,
+ clock-rate=(int)90000, encoding-name=(string)MP4V-ES, ssrc=(guint)1162703703,
+ clock-base=(guint)816135835, seqnum-base=(guint)9294, profile-level-id=(string)3,
+ config=(string)000001b003000001b50900000100000001200086c5d4c307d314043c1463000001b25876694430303334"
+ ! rtpmp4vdepay ! ffdec_mpeg4 ! xvimagesink sync=false
+ udpsrc port=5002 caps="application/x-rtp, media=(string)audio, payload=(int)96,
+ clock-rate=(int)44100, encoding-name=(string)mpeg4-generic, ssrc=(guint)3246149898,
+ clock-base=(guint)4134514058, seqnum-base=(guint)57633, encoding-params=(string)2,
+ streamtype=(string)5, profile-level-id=(string)1, mode=(string)AAC-hbr,
+ config=(string)1210, sizelength=(string)13, indexlength=(string)3,
+ indexdeltalength=(string)3"
+ ! rtpmp4gdepay ! faad ! alsasink sync=false
+
+ The caps on the udpsinks can be retrieved when the server pipeline prerolled to
+ PAUSED.
+
+ The caps on the receiver side can be set on the UDP source elements when the
+ pipeline went to PAUSED. In that state no data is received from the UDP sources
+ as they are live sources and only produce data in PLAYING.
Relevant RFCs
diff --git a/gst/rtp/gstrtpmp4gpay.c b/gst/rtp/gstrtpmp4gpay.c
index 3c8d804f..42fae2ef 100644
--- a/gst/rtp/gstrtpmp4gpay.c
+++ b/gst/rtp/gstrtpmp4gpay.c
@@ -56,24 +56,25 @@ GST_STATIC_PAD_TEMPLATE ("src",
"clock-rate = (int) [1, MAX ], "
"encoding-name = (string) \"mpeg4-generic\", "
/* required string params */
- "streamtype = (int) { \"4\", \"5\" }, " /* 4 = video, 5 = audio */
- "profile-level-id = (int) [1,MAX], "
+ "streamtype = (string) { \"4\", \"5\" }, " /* 4 = video, 5 = audio */
+ /* "profile-level-id = (string) [1,MAX], " */
/* "config = (string) [1,MAX]" */
- "mode = (string) { \"generic\", \"CELP-cbr\", \"CELP-vbr\", \"AAC-lbr\", \"AAC-hbr\" }, "
+ "mode = (string) { \"generic\", \"CELP-cbr\", \"CELP-vbr\", \"AAC-lbr\", \"AAC-hbr\" } "
/* Optional general parameters */
- "objecttype = (int) [1,MAX], " "constantsize = (int) [1,MAX], " /* constant size of each AU */
- "constantduration = (int) [1,MAX], " /* constant duration of each AU */
- "maxdisplacement = (int) [1,MAX], "
- "de-interleavebuffersize = (int) [1,MAX], "
+ /* "objecttype = (string) [1,MAX], " */
+ /* "constantsize = (string) [1,MAX], " *//* constant size of each AU */
+ /* "constantduration = (string) [1,MAX], " *//* constant duration of each AU */
+ /* "maxdisplacement = (string) [1,MAX], " */
+ /* "de-interleavebuffersize = (string) [1,MAX], " */
/* Optional configuration parameters */
- "sizelength = (int) [1, 16], " /* max 16 bits, should be enough... */
- "indexlength = (int) [1, 8], "
- "indexdeltalength = (int) [1, 8], "
- "ctsdeltalength = (int) [1, 64], "
- "dtsdeltalength = (int) [1, 64], "
- "randomaccessindication = (int) {0, 1}, "
- "streamstateindication = (int) [0, 64], "
- "auxiliarydatasizelength = (int) [0, 64]")
+ /* "sizelength = (string) [1, 16], " *//* max 16 bits, should be enough... */
+ /* "indexlength = (string) [1, 8], " */
+ /* "indexdeltalength = (string) [1, 8], " */
+ /* "ctsdeltalength = (string) [1, 64], " */
+ /* "dtsdeltalength = (string) [1, 64], " */
+ /* "randomaccessindication = (string) {0, 1}, " */
+ /* "streamstateindication = (string) [0, 64], " */
+ /* "auxiliarydatasizelength = (string) [0, 64]" */ )
);
enum
@@ -167,7 +168,7 @@ gst_rtp_mp4g_pay_init (GstRtpMP4GPay * rtpmp4gpay)
{
rtpmp4gpay->adapter = gst_adapter_new ();
rtpmp4gpay->rate = 90000;
- rtpmp4gpay->profile = 1;
+ rtpmp4gpay->profile = g_strdup ("1");
rtpmp4gpay->mode = "";
}
@@ -180,6 +181,8 @@ gst_rtp_mp4g_pay_finalize (GObject * object)
g_object_unref (rtpmp4gpay->adapter);
rtpmp4gpay->adapter = NULL;
+ g_free (rtpmp4gpay->params);
+ rtpmp4gpay->params = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -232,13 +235,15 @@ gst_rtp_mp4g_pay_parse_audio_config (GstRtpMP4GPay * rtpmp4gpay,
rtpmp4gpay->rate = sampling_table[samplingIdx];
}
/* extra rtp params contain the number of channels */
- rtpmp4gpay->params = channelCfg;
+ g_free (rtpmp4gpay->params);
+ rtpmp4gpay->params = g_strdup_printf ("%d", channelCfg);
/* audio stream type */
- rtpmp4gpay->streamtype = 5;
+ rtpmp4gpay->streamtype = "5";
/* mode */
rtpmp4gpay->mode = "AAC-hbr";
/* profile (should be 1) */
- rtpmp4gpay->profile = objectType - 1;
+ g_free (rtpmp4gpay->profile);
+ rtpmp4gpay->profile = g_strdup_printf ("%d", objectType - 1);
GST_DEBUG_OBJECT (rtpmp4gpay,
"objectType: %d, samplingIdx: %d (%d), channelCfg: %d", objectType,
@@ -290,25 +295,27 @@ gst_rtp_mp4g_pay_parse_video_config (GstRtpMP4GPay * rtpmp4gpay,
goto too_short;
code = GST_READ_UINT32_BE (data);
+
+ g_free (rtpmp4gpay->profile);
if (code == VOS_STARTCODE) {
/* get profile */
- rtpmp4gpay->profile = data[4];
+ rtpmp4gpay->profile = g_strdup_printf ("%d", (gint) data[4]);
} else {
GST_ELEMENT_WARNING (rtpmp4gpay, STREAM, FORMAT,
- (NULL), ("profile not found in config string"));
- rtpmp4gpay->profile = 1;
+ (NULL), ("profile not found in config string, assuming \'1\'"));
+ rtpmp4gpay->profile = g_strdup ("1");
}
/* fixed rate */
rtpmp4gpay->rate = 90000;
/* video stream type */
- rtpmp4gpay->streamtype = 4;
+ rtpmp4gpay->streamtype = "4";
/* no params for video */
- rtpmp4gpay->params = 0;
+ rtpmp4gpay->params = NULL;
/* mode */
rtpmp4gpay->mode = "generic";
- GST_LOG_OBJECT (rtpmp4gpay, "profile %d", rtpmp4gpay->profile);
+ GST_LOG_OBJECT (rtpmp4gpay, "profile %s", rtpmp4gpay->profile);
return TRUE;
@@ -327,14 +334,14 @@ gst_rtp_mp4g_pay_new_caps (GstRtpMP4GPay * rtpmp4gpay)
gchar *config;
GValue v = { 0 };
-#define MP4GCAPS \
- "streamtype", G_TYPE_INT, rtpmp4gpay->streamtype, \
- "profile-level-id", G_TYPE_INT, rtpmp4gpay->profile, \
- "mode", G_TYPE_STRING, rtpmp4gpay->mode, \
- "config", G_TYPE_STRING, config, \
- "sizelength", G_TYPE_INT, 13, \
- "indexlength", G_TYPE_INT, 3, \
- "indexdeltalength", G_TYPE_INT, 3, \
+#define MP4GCAPS \
+ "streamtype", G_TYPE_STRING, rtpmp4gpay->streamtype, \
+ "profile-level-id", G_TYPE_STRING, rtpmp4gpay->profile, \
+ "mode", G_TYPE_STRING, rtpmp4gpay->mode, \
+ "config", G_TYPE_STRING, config, \
+ "sizelength", G_TYPE_STRING, "13", \
+ "indexlength", G_TYPE_STRING, "3", \
+ "indexdeltalength", G_TYPE_STRING, "3", \
NULL
g_value_init (&v, GST_TYPE_BUFFER);
@@ -344,7 +351,7 @@ gst_rtp_mp4g_pay_new_caps (GstRtpMP4GPay * rtpmp4gpay)
/* hmm, silly */
if (rtpmp4gpay->params) {
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4gpay),
- "encoding-params", G_TYPE_INT, rtpmp4gpay->params, MP4GCAPS);
+ "encoding-params", G_TYPE_STRING, rtpmp4gpay->params, MP4GCAPS);
} else {
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4gpay),
MP4GCAPS);
diff --git a/gst/rtp/gstrtpmp4gpay.h b/gst/rtp/gstrtpmp4gpay.h
index bb0bb8fd..b1557f5a 100644
--- a/gst/rtp/gstrtpmp4gpay.h
+++ b/gst/rtp/gstrtpmp4gpay.h
@@ -49,9 +49,9 @@ struct _GstRtpMP4GPay
GstClockTime duration;
gint rate;
- gint params;
- gint profile;
- gint streamtype;
+ gchar *params;
+ gchar *profile;
+ const gchar *streamtype;
const gchar *mode;
GstBuffer *config;
};