diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2007-04-10 17:06:05 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-04-10 17:06:05 +0000 |
commit | acddbd83ff23d7016afdcfad5da3d3aa82b63679 (patch) | |
tree | 0a7c756fb05a0c6bfb3a1babfd85d327684b5f91 /gst | |
parent | 497d589d56cf5e0ef758ca6c0443cdee7b3da91d (diff) |
gst/rtp/gstrtpamrdepay.c: Fix depayloader clock_rate and some cleanups.
Original commit message from CVS:
* gst/rtp/gstrtpamrdepay.c: (gst_rtp_amr_depay_setcaps),
(gst_rtp_amr_depay_process):
Fix depayloader clock_rate and some cleanups.
* gst/rtp/gstrtph264depay.c: (gst_rtp_h264_depay_finalize),
(gst_rtp_h264_depay_setcaps), (gst_rtp_h264_depay_process):
* gst/rtp/gstrtph264depay.h:
Don't push codec_data in the adapter because it might get flushed when
we get a discont.
* gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_process):
Handle multiple AU per packet.
* gst/rtp/gstrtpsv3vdepay.c: (gst_rtp_sv3v_depay_process),
(gst_rtp_sv3v_depay_plugin_init):
Disable rank, this one does not work.
Remove timestamping, base class does that.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/rtp/gstrtpamrdepay.c | 88 | ||||
-rw-r--r-- | gst/rtp/gstrtph264depay.c | 37 | ||||
-rw-r--r-- | gst/rtp/gstrtph264depay.h | 1 | ||||
-rw-r--r-- | gst/rtp/gstrtpmp4gdepay.c | 98 | ||||
-rw-r--r-- | gst/rtp/gstrtpsv3vdepay.c | 7 |
5 files changed, 146 insertions, 85 deletions
diff --git a/gst/rtp/gstrtpamrdepay.c b/gst/rtp/gstrtpamrdepay.c index 06ea6cd6..f5871584 100644 --- a/gst/rtp/gstrtpamrdepay.c +++ b/gst/rtp/gstrtpamrdepay.c @@ -197,6 +197,7 @@ gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) if (!gst_structure_get_int (structure, "clock-rate", &clock_rate)) clock_rate = 8000; + depayload->clock_rate = clock_rate; /* we require 1 channel, 8000 Hz, octet aligned, no CRC, * no robust sorting, no interleaving for now */ @@ -233,24 +234,20 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) { GstRtpAMRDepay *rtpamrdepay; GstBuffer *outbuf = NULL; + gint payload_len; rtpamrdepay = GST_RTP_AMR_DEPAY (depayload); if (!rtpamrdepay->negotiated) goto not_negotiated; - if (!gst_rtp_buffer_validate (buf)) { - GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, - (NULL), ("AMR RTP packet did not validate")); - goto bad_packet; - } + if (!gst_rtp_buffer_validate (buf)) + goto invalid_packet; /* when we get here, 1 channel, 8000 Hz, octet aligned, no CRC, * no robust sorting, no interleaving data is to be depayloaded */ { - gint payload_len; guint8 *payload, *p, *dp; - guint32 timestamp; guint8 CMR; gint i, num_packets, num_nonempty_packets; gint amr_len; @@ -259,11 +256,8 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) payload_len = gst_rtp_buffer_get_payload_len (buf); /* need at least 2 bytes for the header */ - if (payload_len < 2) { - GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, - (NULL), ("AMR RTP payload too small (%d)", payload_len)); - goto bad_packet; - } + if (payload_len < 2) + goto too_small; payload = gst_rtp_buffer_get_payload (buf); @@ -290,11 +284,8 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) payload_len -= 1; payload += 1; - if (ILP > ILL) { - GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, - (NULL), ("AMR RTP wrong interleaving")); - goto bad_packet; - } + if (ILP > ILL) + goto wrong_interleaving; } /* @@ -317,11 +308,8 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) fr_size = frame_size[FT]; GST_DEBUG_OBJECT (rtpamrdepay, "frame size %d", fr_size); - if (fr_size == -1) { - GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, - (NULL), ("AMR RTP frame size == -1")); - goto bad_packet; - } + if (fr_size == -1) + goto wrong_framesize; if (fr_size > 0) { amr_len += fr_size; @@ -335,26 +323,15 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) if (rtpamrdepay->crc) { /* data len + CRC len + header bytes should be smaller than payload_len */ - if (num_packets + num_nonempty_packets + amr_len > payload_len) { - GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, - (NULL), ("AMR RTP wrong length 1")); - goto bad_packet; - } + if (num_packets + num_nonempty_packets + amr_len > payload_len) + goto wrong_length_1; } else { /* data len + header bytes should be smaller than payload_len */ - if (num_packets + amr_len > payload_len) { - GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, - (NULL), ("AMR RTP wrong length 2")); - goto bad_packet; - } + if (num_packets + amr_len > payload_len) + goto wrong_length_2; } - timestamp = gst_rtp_buffer_get_timestamp (buf); - outbuf = gst_buffer_new_and_alloc (payload_len); - GST_BUFFER_TIMESTAMP (outbuf) = - gst_util_uint64_scale_int (timestamp, GST_SECOND, - depayload->clock_rate); /* point to destination */ p = GST_BUFFER_DATA (outbuf); @@ -386,16 +363,51 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) GST_DEBUG ("gst_rtp_amr_depay_chain: pushing buffer of size %d", GST_BUFFER_SIZE (outbuf)); } - return outbuf; /* ERRORS */ +invalid_packet: + { + GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, + (NULL), ("AMR RTP packet did not validate")); + goto bad_packet; + } not_negotiated: { GST_ELEMENT_ERROR (rtpamrdepay, STREAM, NOT_IMPLEMENTED, (NULL), ("not negotiated")); return NULL; } +too_small: + { + GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, + (NULL), ("AMR RTP payload too small (%d)", payload_len)); + goto bad_packet; + } +wrong_interleaving: + { + GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, + (NULL), ("AMR RTP wrong interleaving")); + goto bad_packet; + } +wrong_framesize: + { + GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, + (NULL), ("AMR RTP frame size == -1")); + goto bad_packet; + } +wrong_length_1: + { + GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, + (NULL), ("AMR RTP wrong length 1")); + goto bad_packet; + } +wrong_length_2: + { + GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE, + (NULL), ("AMR RTP wrong length 2")); + goto bad_packet; + } bad_packet: { /* no fatal error */ diff --git a/gst/rtp/gstrtph264depay.c b/gst/rtp/gstrtph264depay.c index 11376797..be27910d 100644 --- a/gst/rtp/gstrtph264depay.c +++ b/gst/rtp/gstrtph264depay.c @@ -154,8 +154,10 @@ gst_rtp_h264_depay_finalize (GObject * object) rtph264depay = GST_RTP_H264_DEPAY (object); + if (rtph264depay->codec_data) + gst_buffer_unref (rtph264depay->codec_data); + g_object_unref (rtph264depay->adapter); - rtph264depay->adapter = NULL; G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -255,9 +257,12 @@ gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) } GST_BUFFER_SIZE (codec_data) = total; - /* don't set codec_data, we send unpacketized data so let the decoder - * packetize for us */ - gst_adapter_push (rtph264depay->adapter, codec_data); + /* keep the codec_data, we need to send it as the first buffer. We cannot + * push it in the adapter because the adapter might be flushed on discont. + */ + if (rtph264depay->codec_data) + gst_buffer_unref (rtph264depay->codec_data); + rtph264depay->codec_data = codec_data; } gst_pad_set_caps (depayload->srcpad, srccaps); @@ -333,6 +338,12 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) rtph264depay->wait_start = FALSE; + /* prepend codec_data */ + if (rtph264depay->codec_data) { + gst_adapter_push (rtph264depay->adapter, rtph264depay->codec_data); + rtph264depay->codec_data = NULL; + } + /* STAP-A Single-time aggregation packet 5.7.1 */ while (payload_len > 2) { /* 1 @@ -446,13 +457,20 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) /* if NAL unit ends, flush the adapter */ if (E) { + GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize); + outsize = gst_adapter_available (rtph264depay->adapter); outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); - GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize); - + /* push codec_data first */ + if (rtph264depay->codec_data) { + gst_buffer_set_caps (rtph264depay->codec_data, + GST_PAD_CAPS (depayload->srcpad)); + gst_base_rtp_depayload_push (depayload, rtph264depay->codec_data); + rtph264depay->codec_data = NULL; + } return outbuf; } break; @@ -473,6 +491,13 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); + /* push codec_data first */ + if (rtph264depay->codec_data) { + gst_buffer_set_caps (rtph264depay->codec_data, + GST_PAD_CAPS (depayload->srcpad)); + gst_base_rtp_depayload_push (depayload, rtph264depay->codec_data); + rtph264depay->codec_data = NULL; + } return outbuf; } } diff --git a/gst/rtp/gstrtph264depay.h b/gst/rtp/gstrtph264depay.h index ede2b841..41c4fc07 100644 --- a/gst/rtp/gstrtph264depay.h +++ b/gst/rtp/gstrtph264depay.h @@ -44,6 +44,7 @@ struct _GstRtpH264Depay { GstBaseRTPDepayload depayload; + GstBuffer *codec_data; GstAdapter *adapter; gboolean wait_start; }; diff --git a/gst/rtp/gstrtpmp4gdepay.c b/gst/rtp/gstrtpmp4gdepay.c index c9e2d453..f1d68a21 100644 --- a/gst/rtp/gstrtpmp4gdepay.c +++ b/gst/rtp/gstrtpmp4gdepay.c @@ -287,64 +287,92 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) guint32 timestamp; guint AU_headers_len; guint AU_size, AU_index; + gboolean M; payload_len = gst_rtp_buffer_get_payload_len (buf); payload = gst_rtp_buffer_get_payload (buf); payload_header = 0; + timestamp = gst_rtp_buffer_get_timestamp (buf); + M = gst_rtp_buffer_get_marker (buf); + if (rtpmp4gdepay->sizelength > 0) { + gint num_AU_headers, AU_headers_bytes, i; + /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+ * |AU-headers-length|AU-header|AU-header| |AU-header|padding| * | | (1) | (2) | | (n) * | bits | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+ * - * The lenght is 2 bytes and contains the length of the following + * The length is 2 bytes and contains the length of the following * AU-headers in bits. */ AU_headers_len = (payload[0] << 8) | payload[1]; + AU_headers_bytes = (AU_headers_len + 7) / 8; + num_AU_headers = AU_headers_len / 16; + + GST_DEBUG_OBJECT (rtpmp4gdepay, "AU headers len %d, bytes %d, num %d", + AU_headers_len, AU_headers_bytes, num_AU_headers); /* skip header */ payload += 2; - payload_header += 2; - payload_len -= 2; - - /* FIXME, use bits */ - AU_size = ((payload[0] << 8) | payload[1]) >> 3; - AU_index = payload[1] & 0x7; - - GST_DEBUG_OBJECT (rtpmp4gdepay, "len, %d, size %d, index %d", - AU_headers_len, AU_size, AU_index); - /* skip special headers */ - payload += (AU_headers_len + 7) / 8; - payload_header += (AU_headers_len + 7) / 8; - payload_len = AU_size; - } - - timestamp = gst_rtp_buffer_get_timestamp (buf); - - /* strip header from payload and push in the adapter */ - outbuf = - gst_rtp_buffer_get_payload_subbuffer (buf, payload_header, payload_len); - gst_adapter_push (rtpmp4gdepay->adapter, outbuf); + payload_header = 2 + AU_headers_bytes; + + for (i = 0; i < num_AU_headers; i++) { + /* FIXME, use bits */ + AU_size = ((payload[0] << 8) | payload[1]) >> 3; + AU_index = payload[1] & 0x7; + payload += 2; + + GST_DEBUG_OBJECT (rtpmp4gdepay, "len, %d, size %d, index %d", + AU_headers_len, AU_size, AU_index); + + /* collect stuff in the adapter, strip header from payload and push in + * the adapter */ + outbuf = + gst_rtp_buffer_get_payload_subbuffer (buf, payload_header, AU_size); + gst_adapter_push (rtpmp4gdepay->adapter, outbuf); + + if (M) { + guint avail; + + /* packet is complete, flush */ + avail = gst_adapter_available (rtpmp4gdepay->adapter); + + outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail); + gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); + + GST_DEBUG ("gst_rtp_mp4g_depay_chain: pushing buffer of size %d", + GST_BUFFER_SIZE (outbuf)); + + /* only apply the timestamp for the first buffer */ + if (i == 0) + gst_base_rtp_depayload_push_ts (depayload, timestamp, outbuf); + else + gst_base_rtp_depayload_push (depayload, outbuf); + } + payload_header += AU_size; + } + } else { + /* push complete buffer in adapter */ + outbuf = gst_rtp_buffer_get_payload_subbuffer (buf, 0, payload_len); + gst_adapter_push (rtpmp4gdepay->adapter, outbuf); - /* if this was the last packet of the VOP, create and push a buffer */ - if (gst_rtp_buffer_get_marker (buf)) { - guint avail; + /* if this was the last packet of the VOP, create and push a buffer */ + if (M) { + guint avail; - avail = gst_adapter_available (rtpmp4gdepay->adapter); + avail = gst_adapter_available (rtpmp4gdepay->adapter); - outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); - GST_BUFFER_TIMESTAMP (outbuf) = gst_util_uint64_scale_int - (timestamp, GST_SECOND, depayload->clock_rate); + outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail); + gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); - GST_DEBUG ("gst_rtp_mp4g_depay_chain: pushing buffer of size %d", - GST_BUFFER_SIZE (outbuf)); + GST_DEBUG ("gst_rtp_mp4g_depay_chain: pushing buffer of size %d", + GST_BUFFER_SIZE (outbuf)); - return outbuf; - } else { - return NULL; + return outbuf; + } } } return NULL; diff --git a/gst/rtp/gstrtpsv3vdepay.c b/gst/rtp/gstrtpsv3vdepay.c index f2df1794..bc2647b5 100644 --- a/gst/rtp/gstrtpsv3vdepay.c +++ b/gst/rtp/gstrtpsv3vdepay.c @@ -252,16 +252,11 @@ gst_rtp_sv3v_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) if (M) { /* frame is completed: push contents of adapter */ guint avail; - guint32 timestamp; avail = gst_adapter_available (rtpsv3vdepay->adapter); outbuf = gst_adapter_take_buffer (rtpsv3vdepay->adapter, avail); /* timestamp for complete buffer is that of last buffer as well */ - timestamp = gst_rtp_buffer_get_timestamp (buf); - GST_BUFFER_TIMESTAMP (outbuf) = - gst_util_uint64_scale_int (timestamp, GST_SECOND, - depayload->clock_rate); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad)); return outbuf; @@ -342,5 +337,5 @@ gboolean gst_rtp_sv3v_depay_plugin_init (GstPlugin * plugin) { return gst_element_register (plugin, "rtpsv3vdepay", - GST_RANK_MARGINAL, GST_TYPE_RTP_SV3V_DEPAY); + GST_RANK_NONE, GST_TYPE_RTP_SV3V_DEPAY); } |