mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
gst/rtp/gstrtpamrdec.c: Handle multiple AMr packets per payload. Handle CRC and parse ILL/ILP.
Original commit message from CVS: * gst/rtp/gstrtpamrdec.c: (gst_rtpamrdec_sink_setcaps), (gst_rtpamrdec_chain): Handle multiple AMr packets per payload. Handle CRC and parse ILL/ILP. * gst/rtp/gstrtpamrenc.c: (gst_rtpamrenc_setcaps): Make caps params strings for easy SDP mapping. * gst/rtp/gstrtpdec.c: (gst_rtpdec_init), (gst_rtpdec_getcaps): Handle capsnego better. * gst/rtp/gstrtpmp4vdec.c: (gst_rtpmp4vdec_setcaps): * gst/rtp/gstrtpmp4venc.c: (gst_rtpmp4venc_new_caps): Generate and parse config string in the caps.
This commit is contained in:
parent
9dd3929730
commit
a297069e16
11 changed files with 373 additions and 108 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2005-09-21 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/rtp/gstrtpamrdec.c: (gst_rtpamrdec_sink_setcaps),
|
||||||
|
(gst_rtpamrdec_chain):
|
||||||
|
Handle multiple AMr packets per payload. Handle CRC and
|
||||||
|
parse ILL/ILP.
|
||||||
|
|
||||||
|
* gst/rtp/gstrtpamrenc.c: (gst_rtpamrenc_setcaps):
|
||||||
|
Make caps params strings for easy SDP mapping.
|
||||||
|
|
||||||
|
* gst/rtp/gstrtpdec.c: (gst_rtpdec_init), (gst_rtpdec_getcaps):
|
||||||
|
Handle capsnego better.
|
||||||
|
|
||||||
|
* gst/rtp/gstrtpmp4vdec.c: (gst_rtpmp4vdec_setcaps):
|
||||||
|
* gst/rtp/gstrtpmp4venc.c: (gst_rtpmp4venc_new_caps):
|
||||||
|
Generate and parse config string in the caps.
|
||||||
|
|
||||||
2005-09-21 Wim Taymans <wim@fluendo.com>
|
2005-09-21 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/rtp/README:
|
* gst/rtp/README:
|
||||||
|
|
|
@ -63,9 +63,9 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
"clock-rate = (int) 8000, "
|
"clock-rate = (int) 8000, "
|
||||||
"encoding-name = (string) \"AMR\", "
|
"encoding-name = (string) \"AMR\", "
|
||||||
"encoding-params = (string) \"1\", "
|
"encoding-params = (string) \"1\", "
|
||||||
"octet-align = (string) 1, "
|
"octet-align = (string) \"1\", "
|
||||||
"crc = (string) 0, "
|
"crc = (string) { \"0\", \"1\" }, "
|
||||||
"robust-sorting = (string) 0, " "interleaving = (string) 0"
|
"robust-sorting = (string) \"0\", " "interleaving = (string) \"0\""
|
||||||
/* following options are not needed for a decoder
|
/* following options are not needed for a decoder
|
||||||
*
|
*
|
||||||
"mode-set = (int) [ 0, 7 ], "
|
"mode-set = (int) [ 0, 7 ], "
|
||||||
|
@ -238,8 +238,6 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdec->octet_align != TRUE)
|
if (rtpamrdec->octet_align != TRUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdec->crc != FALSE)
|
|
||||||
return FALSE;
|
|
||||||
if (rtpamrdec->robust_sorting != FALSE)
|
if (rtpamrdec->robust_sorting != FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdec->interleaving != FALSE)
|
if (rtpamrdec->interleaving != FALSE)
|
||||||
|
@ -256,6 +254,12 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -1 is invalid */
|
||||||
|
static gint frame_size[16] = {
|
||||||
|
12, 13, 15, 17, 19, 20, 26, 31,
|
||||||
|
5, -1, -1, -1, -1, -1, -1, 0
|
||||||
|
};
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -275,9 +279,12 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
* no robust sorting, no interleaving data is to be parsed */
|
* no robust sorting, no interleaving data is to be parsed */
|
||||||
{
|
{
|
||||||
gint payload_len;
|
gint payload_len;
|
||||||
guint8 *payload;
|
guint8 *payload, *p, *dp;
|
||||||
guint32 timestamp;
|
guint32 timestamp;
|
||||||
guint8 CMR, F, FT, Q;
|
guint8 CMR;
|
||||||
|
gint i, num_packets, num_nonempty_packets;
|
||||||
|
gint amr_len;
|
||||||
|
gint ILL, ILP;
|
||||||
|
|
||||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||||
|
|
||||||
|
@ -287,46 +294,111 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
payload = gst_rtpbuffer_get_payload (buf);
|
payload = gst_rtpbuffer_get_payload (buf);
|
||||||
|
|
||||||
/* parse header
|
/* parse CMR. The CMR is used by the sender to request
|
||||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|
* a new encoding mode.
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
|
*
|
||||||
* | CMR |R|R|R|R|F| FT |Q|P|P|
|
* 0 1 2 3 4 5 6 7
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
|
* +-+-+-+-+-+-+-+-+
|
||||||
|
* | CMR |R|R|R|R|
|
||||||
|
* +-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
CMR = (payload[0] & 0xf0) >> 4;
|
CMR = (payload[0] & 0xf0) >> 4;
|
||||||
F = (payload[1] & 0x80) >> 7;
|
|
||||||
/* we only support 1 packet per RTP packet for now */
|
|
||||||
if (F != 0)
|
|
||||||
goto one_packet_only;
|
|
||||||
|
|
||||||
FT = (payload[1] & 0x78) >> 3;
|
/* strip CMR header now, pack FT and the data for the decoder */
|
||||||
Q = (payload[1] & 0x04) >> 2;
|
|
||||||
|
|
||||||
/* skip packet */
|
|
||||||
if (FT > 9 && FT < 15) {
|
|
||||||
ret = GST_FLOW_OK;
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* strip header now, leave FT in the data for the decoder */
|
|
||||||
payload_len -= 1;
|
payload_len -= 1;
|
||||||
payload += 1;
|
payload += 1;
|
||||||
|
|
||||||
|
if (rtpamrdec->interleaving) {
|
||||||
|
ILL = (payload[0] & 0xf0) >> 4;
|
||||||
|
ILP = (payload[0] & 0x0f);
|
||||||
|
|
||||||
|
payload_len -= 1;
|
||||||
|
payload += 1;
|
||||||
|
|
||||||
|
if (ILP > ILL)
|
||||||
|
goto bad_packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|
||||||
|
* +-+-+-+-+-+-+-+-+..
|
||||||
|
* |F| FT |Q|P|P| more FT..
|
||||||
|
* +-+-+-+-+-+-+-+-+..
|
||||||
|
*/
|
||||||
|
/* count number of packets by counting the FTs. Also
|
||||||
|
* count number of amr data bytes and number of non-empty
|
||||||
|
* packets (this is also the number of CRCs if present). */
|
||||||
|
amr_len = 0;
|
||||||
|
num_nonempty_packets = 0;
|
||||||
|
num_packets = 0;
|
||||||
|
for (i = 0; i < payload_len; i++) {
|
||||||
|
gint fr_size;
|
||||||
|
guint8 FT;
|
||||||
|
|
||||||
|
FT = (payload[i] & 0x78) >> 3;
|
||||||
|
|
||||||
|
fr_size = frame_size[FT];
|
||||||
|
if (fr_size == -1)
|
||||||
|
goto bad_packet;
|
||||||
|
|
||||||
|
if (fr_size > 0) {
|
||||||
|
amr_len += fr_size;
|
||||||
|
num_nonempty_packets++;
|
||||||
|
}
|
||||||
|
num_packets++;
|
||||||
|
|
||||||
|
if ((payload[i] & 0x80) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is impossible */
|
||||||
|
if (num_packets == payload_len)
|
||||||
|
goto bad_packet;
|
||||||
|
|
||||||
|
if (rtpamrdec->crc) {
|
||||||
|
/* data len + CRC len + header bytes should be smaller than payload_len */
|
||||||
|
if (num_packets + num_nonempty_packets + amr_len > payload_len)
|
||||||
|
goto bad_packet;
|
||||||
|
} else {
|
||||||
|
/* data len + header bytes should be smaller than payload_len */
|
||||||
|
if (num_packets + amr_len > payload_len)
|
||||||
|
goto bad_packet;
|
||||||
|
}
|
||||||
|
|
||||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||||
|
|
||||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
|
||||||
|
|
||||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
/* point to destination */
|
||||||
|
p = GST_BUFFER_DATA (outbuf);
|
||||||
|
/* point to first data packet */
|
||||||
|
dp = payload + num_packets;
|
||||||
|
if (rtpamrdec->crc) {
|
||||||
|
/* skip CRC if present */
|
||||||
|
dp += num_nonempty_packets;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_packets; i++) {
|
||||||
|
gint fr_size;
|
||||||
|
|
||||||
|
fr_size = frame_size[(payload[i] & 0x78) >> 3];
|
||||||
|
if (fr_size > 0) {
|
||||||
|
/* copy FT */
|
||||||
|
*p++ = payload[i];
|
||||||
|
/* copy data packet, FIXME, calc CRC here. */
|
||||||
|
memcpy (p, dp, fr_size);
|
||||||
|
|
||||||
|
p += fr_size;
|
||||||
|
dp += fr_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
|
||||||
|
|
||||||
GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
|
GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
|
||||||
GST_BUFFER_SIZE (outbuf));
|
GST_BUFFER_SIZE (outbuf));
|
||||||
ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
|
ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
|
||||||
|
|
||||||
skip:
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,21 +406,17 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
not_negotiated:
|
not_negotiated:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("not_negotiated");
|
GST_ELEMENT_ERROR (rtpamrdec, STREAM, NOT_IMPLEMENTED,
|
||||||
|
("not negotiated"), (NULL));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
}
|
}
|
||||||
bad_packet:
|
bad_packet:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("Packet did not validate");
|
GST_ELEMENT_WARNING (rtpamrdec, STREAM, DECODE,
|
||||||
|
("amr packet did not validate"), (NULL));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_OK;
|
||||||
}
|
|
||||||
one_packet_only:
|
|
||||||
{
|
|
||||||
GST_DEBUG ("One packet per RTP packet only");
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,9 +63,9 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
"clock-rate = (int) 8000, "
|
"clock-rate = (int) 8000, "
|
||||||
"encoding-name = (string) \"AMR\", "
|
"encoding-name = (string) \"AMR\", "
|
||||||
"encoding-params = (string) \"1\", "
|
"encoding-params = (string) \"1\", "
|
||||||
"octet-align = (string) 1, "
|
"octet-align = (string) \"1\", "
|
||||||
"crc = (string) 0, "
|
"crc = (string) { \"0\", \"1\" }, "
|
||||||
"robust-sorting = (string) 0, " "interleaving = (string) 0"
|
"robust-sorting = (string) \"0\", " "interleaving = (string) \"0\""
|
||||||
/* following options are not needed for a decoder
|
/* following options are not needed for a decoder
|
||||||
*
|
*
|
||||||
"mode-set = (int) [ 0, 7 ], "
|
"mode-set = (int) [ 0, 7 ], "
|
||||||
|
@ -238,8 +238,6 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdec->octet_align != TRUE)
|
if (rtpamrdec->octet_align != TRUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdec->crc != FALSE)
|
|
||||||
return FALSE;
|
|
||||||
if (rtpamrdec->robust_sorting != FALSE)
|
if (rtpamrdec->robust_sorting != FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdec->interleaving != FALSE)
|
if (rtpamrdec->interleaving != FALSE)
|
||||||
|
@ -256,6 +254,12 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -1 is invalid */
|
||||||
|
static gint frame_size[16] = {
|
||||||
|
12, 13, 15, 17, 19, 20, 26, 31,
|
||||||
|
5, -1, -1, -1, -1, -1, -1, 0
|
||||||
|
};
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -275,9 +279,12 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
* no robust sorting, no interleaving data is to be parsed */
|
* no robust sorting, no interleaving data is to be parsed */
|
||||||
{
|
{
|
||||||
gint payload_len;
|
gint payload_len;
|
||||||
guint8 *payload;
|
guint8 *payload, *p, *dp;
|
||||||
guint32 timestamp;
|
guint32 timestamp;
|
||||||
guint8 CMR, F, FT, Q;
|
guint8 CMR;
|
||||||
|
gint i, num_packets, num_nonempty_packets;
|
||||||
|
gint amr_len;
|
||||||
|
gint ILL, ILP;
|
||||||
|
|
||||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||||
|
|
||||||
|
@ -287,46 +294,111 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
payload = gst_rtpbuffer_get_payload (buf);
|
payload = gst_rtpbuffer_get_payload (buf);
|
||||||
|
|
||||||
/* parse header
|
/* parse CMR. The CMR is used by the sender to request
|
||||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|
* a new encoding mode.
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
|
*
|
||||||
* | CMR |R|R|R|R|F| FT |Q|P|P|
|
* 0 1 2 3 4 5 6 7
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
|
* +-+-+-+-+-+-+-+-+
|
||||||
|
* | CMR |R|R|R|R|
|
||||||
|
* +-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
CMR = (payload[0] & 0xf0) >> 4;
|
CMR = (payload[0] & 0xf0) >> 4;
|
||||||
F = (payload[1] & 0x80) >> 7;
|
|
||||||
/* we only support 1 packet per RTP packet for now */
|
|
||||||
if (F != 0)
|
|
||||||
goto one_packet_only;
|
|
||||||
|
|
||||||
FT = (payload[1] & 0x78) >> 3;
|
/* strip CMR header now, pack FT and the data for the decoder */
|
||||||
Q = (payload[1] & 0x04) >> 2;
|
|
||||||
|
|
||||||
/* skip packet */
|
|
||||||
if (FT > 9 && FT < 15) {
|
|
||||||
ret = GST_FLOW_OK;
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* strip header now, leave FT in the data for the decoder */
|
|
||||||
payload_len -= 1;
|
payload_len -= 1;
|
||||||
payload += 1;
|
payload += 1;
|
||||||
|
|
||||||
|
if (rtpamrdec->interleaving) {
|
||||||
|
ILL = (payload[0] & 0xf0) >> 4;
|
||||||
|
ILP = (payload[0] & 0x0f);
|
||||||
|
|
||||||
|
payload_len -= 1;
|
||||||
|
payload += 1;
|
||||||
|
|
||||||
|
if (ILP > ILL)
|
||||||
|
goto bad_packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|
||||||
|
* +-+-+-+-+-+-+-+-+..
|
||||||
|
* |F| FT |Q|P|P| more FT..
|
||||||
|
* +-+-+-+-+-+-+-+-+..
|
||||||
|
*/
|
||||||
|
/* count number of packets by counting the FTs. Also
|
||||||
|
* count number of amr data bytes and number of non-empty
|
||||||
|
* packets (this is also the number of CRCs if present). */
|
||||||
|
amr_len = 0;
|
||||||
|
num_nonempty_packets = 0;
|
||||||
|
num_packets = 0;
|
||||||
|
for (i = 0; i < payload_len; i++) {
|
||||||
|
gint fr_size;
|
||||||
|
guint8 FT;
|
||||||
|
|
||||||
|
FT = (payload[i] & 0x78) >> 3;
|
||||||
|
|
||||||
|
fr_size = frame_size[FT];
|
||||||
|
if (fr_size == -1)
|
||||||
|
goto bad_packet;
|
||||||
|
|
||||||
|
if (fr_size > 0) {
|
||||||
|
amr_len += fr_size;
|
||||||
|
num_nonempty_packets++;
|
||||||
|
}
|
||||||
|
num_packets++;
|
||||||
|
|
||||||
|
if ((payload[i] & 0x80) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is impossible */
|
||||||
|
if (num_packets == payload_len)
|
||||||
|
goto bad_packet;
|
||||||
|
|
||||||
|
if (rtpamrdec->crc) {
|
||||||
|
/* data len + CRC len + header bytes should be smaller than payload_len */
|
||||||
|
if (num_packets + num_nonempty_packets + amr_len > payload_len)
|
||||||
|
goto bad_packet;
|
||||||
|
} else {
|
||||||
|
/* data len + header bytes should be smaller than payload_len */
|
||||||
|
if (num_packets + amr_len > payload_len)
|
||||||
|
goto bad_packet;
|
||||||
|
}
|
||||||
|
|
||||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||||
|
|
||||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
|
||||||
|
|
||||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
/* point to destination */
|
||||||
|
p = GST_BUFFER_DATA (outbuf);
|
||||||
|
/* point to first data packet */
|
||||||
|
dp = payload + num_packets;
|
||||||
|
if (rtpamrdec->crc) {
|
||||||
|
/* skip CRC if present */
|
||||||
|
dp += num_nonempty_packets;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_packets; i++) {
|
||||||
|
gint fr_size;
|
||||||
|
|
||||||
|
fr_size = frame_size[(payload[i] & 0x78) >> 3];
|
||||||
|
if (fr_size > 0) {
|
||||||
|
/* copy FT */
|
||||||
|
*p++ = payload[i];
|
||||||
|
/* copy data packet, FIXME, calc CRC here. */
|
||||||
|
memcpy (p, dp, fr_size);
|
||||||
|
|
||||||
|
p += fr_size;
|
||||||
|
dp += fr_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
|
||||||
|
|
||||||
GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
|
GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
|
||||||
GST_BUFFER_SIZE (outbuf));
|
GST_BUFFER_SIZE (outbuf));
|
||||||
ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
|
ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
|
||||||
|
|
||||||
skip:
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,21 +406,17 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
not_negotiated:
|
not_negotiated:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("not_negotiated");
|
GST_ELEMENT_ERROR (rtpamrdec, STREAM, NOT_IMPLEMENTED,
|
||||||
|
("not negotiated"), (NULL));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
}
|
}
|
||||||
bad_packet:
|
bad_packet:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("Packet did not validate");
|
GST_ELEMENT_WARNING (rtpamrdec, STREAM, DECODE,
|
||||||
|
("amr packet did not validate"), (NULL));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_OK;
|
||||||
}
|
|
||||||
one_packet_only:
|
|
||||||
{
|
|
||||||
GST_DEBUG ("One packet per RTP packet only");
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,13 +54,13 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
"clock-rate = (int) 8000, "
|
"clock-rate = (int) 8000, "
|
||||||
"encoding-name = (string) \"AMR\", "
|
"encoding-name = (string) \"AMR\", "
|
||||||
"encoding-params = (string) \"1\", "
|
"encoding-params = (string) \"1\", "
|
||||||
"octet-align = (boolean) TRUE, "
|
"octet-align = (string) \"1\", "
|
||||||
"crc = (boolean) FALSE, "
|
"crc = (string) \"0\", "
|
||||||
"robust-sorting = (boolean) FALSE, "
|
"robust-sorting = (string) \"0\", "
|
||||||
"interleaving = (boolean) FALSE, "
|
"interleaving = (string) \"0\", "
|
||||||
"mode-set = (int) [ 0, 7 ], "
|
"mode-set = (int) [ 0, 7 ], "
|
||||||
"mode-change-period = (int) [ 1, MAX ], "
|
"mode-change-period = (int) [ 1, MAX ], "
|
||||||
"mode-change-neighbor = (boolean) { TRUE, FALSE }, "
|
"mode-change-neighbor = (string) { \"0\", \"1\" }, "
|
||||||
"maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ]")
|
"maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ]")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -144,11 +144,14 @@ gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||||
|
|
||||||
gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
|
gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
|
||||||
gst_basertppayload_set_outcaps (basepayload,
|
gst_basertppayload_set_outcaps (basepayload,
|
||||||
"encoding-params", G_TYPE_STRING, "1",
|
"encoding-params", G_TYPE_STRING, "1", "octet-align", G_TYPE_STRING, "1",
|
||||||
"octet-align", G_TYPE_BOOLEAN, TRUE,
|
/* don't set the defaults
|
||||||
"crc", G_TYPE_BOOLEAN, FALSE,
|
*
|
||||||
"robust-sorting", G_TYPE_BOOLEAN, FALSE,
|
* "crc", G_TYPE_STRING, "0",
|
||||||
"interleaving", G_TYPE_BOOLEAN, FALSE, NULL);
|
* "robust-sorting", G_TYPE_STRING, "0",
|
||||||
|
* "interleaving", G_TYPE_STRING, "0",
|
||||||
|
*/
|
||||||
|
NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,13 +54,13 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
"clock-rate = (int) 8000, "
|
"clock-rate = (int) 8000, "
|
||||||
"encoding-name = (string) \"AMR\", "
|
"encoding-name = (string) \"AMR\", "
|
||||||
"encoding-params = (string) \"1\", "
|
"encoding-params = (string) \"1\", "
|
||||||
"octet-align = (boolean) TRUE, "
|
"octet-align = (string) \"1\", "
|
||||||
"crc = (boolean) FALSE, "
|
"crc = (string) \"0\", "
|
||||||
"robust-sorting = (boolean) FALSE, "
|
"robust-sorting = (string) \"0\", "
|
||||||
"interleaving = (boolean) FALSE, "
|
"interleaving = (string) \"0\", "
|
||||||
"mode-set = (int) [ 0, 7 ], "
|
"mode-set = (int) [ 0, 7 ], "
|
||||||
"mode-change-period = (int) [ 1, MAX ], "
|
"mode-change-period = (int) [ 1, MAX ], "
|
||||||
"mode-change-neighbor = (boolean) { TRUE, FALSE }, "
|
"mode-change-neighbor = (string) { \"0\", \"1\" }, "
|
||||||
"maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ]")
|
"maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ]")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -144,11 +144,14 @@ gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||||
|
|
||||||
gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
|
gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
|
||||||
gst_basertppayload_set_outcaps (basepayload,
|
gst_basertppayload_set_outcaps (basepayload,
|
||||||
"encoding-params", G_TYPE_STRING, "1",
|
"encoding-params", G_TYPE_STRING, "1", "octet-align", G_TYPE_STRING, "1",
|
||||||
"octet-align", G_TYPE_BOOLEAN, TRUE,
|
/* don't set the defaults
|
||||||
"crc", G_TYPE_BOOLEAN, FALSE,
|
*
|
||||||
"robust-sorting", G_TYPE_BOOLEAN, FALSE,
|
* "crc", G_TYPE_STRING, "0",
|
||||||
"interleaving", G_TYPE_BOOLEAN, FALSE, NULL);
|
* "robust-sorting", G_TYPE_STRING, "0",
|
||||||
|
* "interleaving", G_TYPE_STRING, "0",
|
||||||
|
*/
|
||||||
|
NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ GST_STATIC_PAD_TEMPLATE ("sinkrtcp",
|
||||||
static void gst_rtpdec_class_init (gpointer g_class);
|
static void gst_rtpdec_class_init (gpointer g_class);
|
||||||
static void gst_rtpdec_init (GstRTPDec * rtpdec);
|
static void gst_rtpdec_init (GstRTPDec * rtpdec);
|
||||||
|
|
||||||
|
static GstCaps *gst_rtpdec_getcaps (GstPad * pad);
|
||||||
static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
(&gst_rtpdec_sink_rtp_template), "sinkrtp");
|
(&gst_rtpdec_sink_rtp_template), "sinkrtp");
|
||||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
|
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
|
||||||
|
gst_pad_set_getcaps_function (rtpdec->sink_rtp, gst_rtpdec_getcaps);
|
||||||
gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
|
gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
|
||||||
|
|
||||||
/* the input rtcp pad */
|
/* the input rtcp pad */
|
||||||
|
@ -166,6 +168,7 @@ gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||||
rtpdec->src_rtp =
|
rtpdec->src_rtp =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
(&gst_rtpdec_src_rtp_template), "srcrtp");
|
(&gst_rtpdec_src_rtp_template), "srcrtp");
|
||||||
|
gst_pad_set_getcaps_function (rtpdec->src_rtp, gst_rtpdec_getcaps);
|
||||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
|
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
|
||||||
|
|
||||||
/* the output rtcp pad */
|
/* the output rtcp pad */
|
||||||
|
@ -175,6 +178,19 @@ gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
|
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
gst_rtpdec_getcaps (GstPad * pad)
|
||||||
|
{
|
||||||
|
GstRTPDec *src;
|
||||||
|
GstPad *other;
|
||||||
|
|
||||||
|
src = GST_RTPDEC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
other = pad == src->src_rtp ? src->sink_rtp : src->src_rtp;
|
||||||
|
|
||||||
|
return gst_pad_peer_get_caps (other);
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,7 @@ GST_STATIC_PAD_TEMPLATE ("sinkrtcp",
|
||||||
static void gst_rtpdec_class_init (gpointer g_class);
|
static void gst_rtpdec_class_init (gpointer g_class);
|
||||||
static void gst_rtpdec_init (GstRTPDec * rtpdec);
|
static void gst_rtpdec_init (GstRTPDec * rtpdec);
|
||||||
|
|
||||||
|
static GstCaps *gst_rtpdec_getcaps (GstPad * pad);
|
||||||
static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
(&gst_rtpdec_sink_rtp_template), "sinkrtp");
|
(&gst_rtpdec_sink_rtp_template), "sinkrtp");
|
||||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
|
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
|
||||||
|
gst_pad_set_getcaps_function (rtpdec->sink_rtp, gst_rtpdec_getcaps);
|
||||||
gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
|
gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
|
||||||
|
|
||||||
/* the input rtcp pad */
|
/* the input rtcp pad */
|
||||||
|
@ -166,6 +168,7 @@ gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||||
rtpdec->src_rtp =
|
rtpdec->src_rtp =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
(&gst_rtpdec_src_rtp_template), "srcrtp");
|
(&gst_rtpdec_src_rtp_template), "srcrtp");
|
||||||
|
gst_pad_set_getcaps_function (rtpdec->src_rtp, gst_rtpdec_getcaps);
|
||||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
|
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
|
||||||
|
|
||||||
/* the output rtcp pad */
|
/* the output rtcp pad */
|
||||||
|
@ -175,6 +178,19 @@ gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
|
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
gst_rtpdec_getcaps (GstPad * pad)
|
||||||
|
{
|
||||||
|
GstRTPDec *src;
|
||||||
|
GstPad *other;
|
||||||
|
|
||||||
|
src = GST_RTPDEC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
other = pad == src->src_rtp ? src->sink_rtp : src->src_rtp;
|
||||||
|
|
||||||
|
return gst_pad_peer_get_caps (other);
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -161,6 +161,7 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
GstRtpMP4VDec *rtpmp4vdec;
|
GstRtpMP4VDec *rtpmp4vdec;
|
||||||
GstCaps *srccaps;
|
GstCaps *srccaps;
|
||||||
|
const gchar *str;
|
||||||
|
|
||||||
rtpmp4vdec = GST_RTP_MP4V_DEC (GST_OBJECT_PARENT (pad));
|
rtpmp4vdec = GST_RTP_MP4V_DEC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
@ -175,6 +176,29 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
gst_pad_set_caps (rtpmp4vdec->srcpad, srccaps);
|
gst_pad_set_caps (rtpmp4vdec->srcpad, srccaps);
|
||||||
gst_caps_unref (srccaps);
|
gst_caps_unref (srccaps);
|
||||||
|
|
||||||
|
if ((str = gst_structure_get_string (structure, "config"))) {
|
||||||
|
GValue v = { 0 };
|
||||||
|
|
||||||
|
g_print ("config=%s\n", str);
|
||||||
|
|
||||||
|
g_value_init (&v, GST_TYPE_BUFFER);
|
||||||
|
if (gst_value_deserialize (&v, str)) {
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
|
buffer = gst_value_get_buffer (&v);
|
||||||
|
gst_buffer_ref (buffer);
|
||||||
|
g_value_unset (&v);
|
||||||
|
|
||||||
|
g_print ("buf=%p\n", buffer);
|
||||||
|
|
||||||
|
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rtpmp4vdec->srcpad));
|
||||||
|
|
||||||
|
gst_pad_push (rtpmp4vdec->srcpad, buffer);
|
||||||
|
} else {
|
||||||
|
g_warning ("cannot convert config to buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,7 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
GstRtpMP4VDec *rtpmp4vdec;
|
GstRtpMP4VDec *rtpmp4vdec;
|
||||||
GstCaps *srccaps;
|
GstCaps *srccaps;
|
||||||
|
const gchar *str;
|
||||||
|
|
||||||
rtpmp4vdec = GST_RTP_MP4V_DEC (GST_OBJECT_PARENT (pad));
|
rtpmp4vdec = GST_RTP_MP4V_DEC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
@ -175,6 +176,29 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
gst_pad_set_caps (rtpmp4vdec->srcpad, srccaps);
|
gst_pad_set_caps (rtpmp4vdec->srcpad, srccaps);
|
||||||
gst_caps_unref (srccaps);
|
gst_caps_unref (srccaps);
|
||||||
|
|
||||||
|
if ((str = gst_structure_get_string (structure, "config"))) {
|
||||||
|
GValue v = { 0 };
|
||||||
|
|
||||||
|
g_print ("config=%s\n", str);
|
||||||
|
|
||||||
|
g_value_init (&v, GST_TYPE_BUFFER);
|
||||||
|
if (gst_value_deserialize (&v, str)) {
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
|
buffer = gst_value_get_buffer (&v);
|
||||||
|
gst_buffer_ref (buffer);
|
||||||
|
g_value_unset (&v);
|
||||||
|
|
||||||
|
g_print ("buf=%p\n", buffer);
|
||||||
|
|
||||||
|
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rtpmp4vdec->srcpad));
|
||||||
|
|
||||||
|
gst_pad_push (rtpmp4vdec->srcpad, buffer);
|
||||||
|
} else {
|
||||||
|
g_warning ("cannot convert config to buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,11 +45,11 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_STATIC_CAPS ("application/x-rtp, "
|
GST_STATIC_CAPS ("application/x-rtp, "
|
||||||
"media = (string) \"video\", "
|
"media = (string) \"video\", "
|
||||||
"payload = (int) [ 96, 255 ], "
|
"payload = (int) [ 96, 255 ], "
|
||||||
"clock-rate = (int) [1, MAX ], "
|
"clock-rate = (int) [1, MAX ], " "encoding-name = (string) \"MP4V-ES\""
|
||||||
"encoding-name = (string) \"MP4V-ES\", " "profile-level-id=[1,MAX]"
|
/* two string params
|
||||||
/* All optional parameters
|
|
||||||
*
|
*
|
||||||
* "config="
|
"profile-level-id = (string) [1,MAX]"
|
||||||
|
"config = (string) [1,MAX]"
|
||||||
*/
|
*/
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -148,9 +148,22 @@ gst_rtpmp4venc_finalize (GObject * object)
|
||||||
static void
|
static void
|
||||||
gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
||||||
{
|
{
|
||||||
|
gchar *profile, *config;
|
||||||
|
GValue v = { 0 };
|
||||||
|
|
||||||
|
profile = g_strdup_printf ("%d", rtpmp4venc->profile);
|
||||||
|
g_value_init (&v, GST_TYPE_BUFFER);
|
||||||
|
gst_value_set_buffer (&v, rtpmp4venc->config);
|
||||||
|
config = gst_value_serialize (&v);
|
||||||
|
|
||||||
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
|
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
|
||||||
"profile-level-id", G_TYPE_INT, rtpmp4venc->profile,
|
"profile-level-id", G_TYPE_STRING, profile,
|
||||||
"config", GST_TYPE_BUFFER, rtpmp4venc->config, NULL);
|
"config", G_TYPE_STRING, config, NULL);
|
||||||
|
|
||||||
|
g_value_unset (&v);
|
||||||
|
|
||||||
|
g_free (profile);
|
||||||
|
g_free (config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -45,11 +45,11 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_STATIC_CAPS ("application/x-rtp, "
|
GST_STATIC_CAPS ("application/x-rtp, "
|
||||||
"media = (string) \"video\", "
|
"media = (string) \"video\", "
|
||||||
"payload = (int) [ 96, 255 ], "
|
"payload = (int) [ 96, 255 ], "
|
||||||
"clock-rate = (int) [1, MAX ], "
|
"clock-rate = (int) [1, MAX ], " "encoding-name = (string) \"MP4V-ES\""
|
||||||
"encoding-name = (string) \"MP4V-ES\", " "profile-level-id=[1,MAX]"
|
/* two string params
|
||||||
/* All optional parameters
|
|
||||||
*
|
*
|
||||||
* "config="
|
"profile-level-id = (string) [1,MAX]"
|
||||||
|
"config = (string) [1,MAX]"
|
||||||
*/
|
*/
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -148,9 +148,22 @@ gst_rtpmp4venc_finalize (GObject * object)
|
||||||
static void
|
static void
|
||||||
gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
||||||
{
|
{
|
||||||
|
gchar *profile, *config;
|
||||||
|
GValue v = { 0 };
|
||||||
|
|
||||||
|
profile = g_strdup_printf ("%d", rtpmp4venc->profile);
|
||||||
|
g_value_init (&v, GST_TYPE_BUFFER);
|
||||||
|
gst_value_set_buffer (&v, rtpmp4venc->config);
|
||||||
|
config = gst_value_serialize (&v);
|
||||||
|
|
||||||
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
|
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
|
||||||
"profile-level-id", G_TYPE_INT, rtpmp4venc->profile,
|
"profile-level-id", G_TYPE_STRING, profile,
|
||||||
"config", GST_TYPE_BUFFER, rtpmp4venc->config, NULL);
|
"config", G_TYPE_STRING, config, NULL);
|
||||||
|
|
||||||
|
g_value_unset (&v);
|
||||||
|
|
||||||
|
g_free (profile);
|
||||||
|
g_free (config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
Loading…
Reference in a new issue