Commit 46d9a8a5 authored by Wim Taymans's avatar Wim Taymans
Browse files

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.
parent f1533c55
2006-09-21 Wim Taymans <wim@fluendo.com>
* 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.
2006-09-20 Philippe Kalaf <philippe.kalaf at collabora.co.uk>
* gst/rtp/gstrtph263pdepay.c:
* gst/rtp/gstrtph263pdepay.c:
* gst/rtp/gstrtph263ppay.c:
Correctly calculate size of each H263+ RTP buffer taking into account MTU and
RTP header.
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment