From: <bi...@ke...> - 2007-11-27 00:01:55
|
CVS Root: /cvs/gstreamer Module: gst-plugins-good Changes by: bilboed Date: Tue Nov 27 2007 00:01:55 UTC Log message: * gst/rtp/gstrtph263depay.c: (gst_rtp_h263_depay_init), (gst_rtp_h263_depay_process): * gst/rtp/gstrtph263depay.h: Fix h263 depayloader so that ANY h263 decoder can handle the outgoing stream. Modified files: . : ChangeLog gst/rtp : gstrtph263depay.c gstrtph263depay.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/ChangeLog.diff?r1=1.3190&r2=1.3191 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtp/gstrtph263depay.c.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-good/gst/rtp/gstrtph263depay.h.diff?r1=1.1&r2=1.2 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-good/ChangeLog,v retrieving revision 1.3190 retrieving revision 1.3191 diff -u -d -r1.3190 -r1.3191 --- ChangeLog 26 Nov 2007 19:17:09 -0000 1.3190 +++ ChangeLog 27 Nov 2007 00:01:39 -0000 1.3191 @@ -1,3 +1,11 @@ +2007-11-27 Edward Hervey <bi...@bi...> + + * gst/rtp/gstrtph263depay.c: (gst_rtp_h263_depay_init), + (gst_rtp_h263_depay_process): + * gst/rtp/gstrtph263depay.h: + Fix h263 depayloader so that ANY h263 decoder can handle the outgoing + stream. 2007-11-26 Wim Taymans <wim...@gm...> Based on Path by: Jayarama S. Santana <sundarsantana at gmail dot com> Index: gstrtph263depay.c RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtp/gstrtph263depay.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- gstrtph263depay.c 26 Nov 2007 12:01:11 -0000 1.2 +++ gstrtph263depay.c 27 Nov 2007 00:01:41 -0000 1.3 @@ -5,6 +5,7 @@ * @author: Philippe Kalaf <phi...@co...> * * Copyright (C) <2005> Wim Taymans <wi...@fl...> + * <2007> Edward Hervey <bi...@bi...> * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -36,7 +37,8 @@ GST_ELEMENT_DETAILS ("RTP H263 packet depayloader", "Codec/Depayloader/Network", "Extracts H263 video from RTP packets (RFC 2190)", - "Philippe Kalaf <phi...@co...>"); + "Philippe Kalaf <phi...@co...>, " + "Edward Hervey <bi...@bi...>"); enum { @@ -135,6 +137,9 @@ GstRtpH263DepayClass * klass) rtph263depay->adapter = gst_adapter_new (); + rtph263depay->offset = 0; + rtph263depay->leftover = 0; } static void @@ -181,14 +186,22 @@ if (!gst_rtp_buffer_validate (buf)) goto bad_packet; + /* flush remaining data on discont */ + if (GST_BUFFER_IS_DISCONT (buf)) { + gst_adapter_clear (rtph263depay->adapter); + rtph263depay->offset = 0; + rtph263depay->leftover = 0; + } { gint payload_len; guint8 *payload; - guint32 timestamp; guint header_len; + guint8 total_offset; + guint SBIT, EBIT; gboolean F, P, M; - gboolean I = FALSE; + gboolean I; payload_len = gst_rtp_buffer_get_payload_len (buf); payload = gst_rtp_buffer_get_payload (buf); @@ -196,9 +209,14 @@ M = gst_rtp_buffer_get_marker (buf); /* Let's see what mode we are using */ - F = (payload[0] & 0x01) == 0x01; - P = (payload[0] & 0x02) == 0x02; + F = (payload[0] & 0x80) == 0x80; + P = (payload[0] & 0x40) == 0x40; + /* Bit shifting */ + SBIT = (payload[0] & 0x38) >> 3; + EBIT = (payload[0] & 0x07); + /* Figure out header length and I-flag */ if (F == 0) { /* F == 0 and P == 0 or 1 * mode A */ @@ -211,6 +229,7 @@ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ I = (payload[1] & 0x10) == 0x10; } else if (P == 0) { /* F == 1 and P == 0 * mode B */ @@ -224,6 +243,7 @@ * |I|U|S|A| HMV1 | VMV1 | HMV2 | VMV2 | + I = (payload[4] & 0x80) == 0x80; } else { /* F == 1 and P == 1 * mode C */ @@ -239,50 +259,93 @@ * | RR |DBQ| TRB | TR | } +#if 0 + GST_WARNING ("F/P/M/I : %d/%d/%d/%d", F, P, M, I); + GST_WARNING ("SBIT : %d , EBIT : %d", SBIT, EBIT); + GST_WARNING ("payload_len : %d, header_len : %d , leftover : %d", + payload_len, header_len, rtph263depay->offset); + gst_util_dump_mem (payload, header_len); +#endif + /* skip header */ payload += header_len; payload_len -= header_len; - timestamp = gst_rtp_buffer_get_timestamp (buf); + total_offset = rtph263depay->offset + SBIT; - /* FIXME at this point, we just drop the header and don't check for any missing - * buffers, proper behaviour is to recreate the appropriate information in the - * bitstream if it has been lost */ - if (M) { - /* frame is completed: append to previous, push it out */ - guint len, padlen; - guint avail; + if (total_offset) { + int i; - avail = gst_adapter_available (rtph263depay->adapter); + /* shift bits */ - len = avail + payload_len; - padlen = (len % 4) + 4; - outbuf = gst_buffer_new_and_alloc (len + padlen); - memset (GST_BUFFER_DATA (outbuf) + len, 0, padlen); - GST_BUFFER_SIZE (outbuf) = len; + if (rtph263depay->offset) + rtph263depay->leftover |= payload[0] << total_offset; - /* prepend previous data */ - if (avail > 0) { - gst_adapter_copy (rtph263depay->adapter, GST_BUFFER_DATA (outbuf), 0, - avail); - gst_adapter_flush (rtph263depay->adapter, avail); - } - memcpy (GST_BUFFER_DATA (outbuf) + avail, payload, payload_len); + for (i = 0; i < payload_len - 1; i++) + payload[i] = + (payload[i] << total_offset) | (payload[i + 1] >> (8 - + total_offset)); - if (I) - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); + payload[payload_len - 1] = payload[payload_len - 1] << total_offset; + } - return outbuf; + if (rtph263depay->offset) { + /* push leftover into the adapter because by now it is a complete byte */ + GstBuffer *buf = gst_buffer_new_and_alloc (1); + GST_BUFFER_DATA (buf)[0] = rtph263depay->leftover; + gst_adapter_push (rtph263depay->adapter, buf); + /* store current buffer into the adapter */ + if (total_offset + EBIT) { + /* push payload_len - 1 */ + outbuf = gst_buffer_new_and_alloc (payload_len - 1); + memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len - 1); + gst_adapter_push (rtph263depay->adapter, outbuf); + /* store last byte as leftover */ + rtph263depay->leftover = payload[payload_len - 1]; - /* frame not completed: store in adapter */ outbuf = gst_buffer_new_and_alloc (payload_len); - memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len); gst_adapter_push (rtph263depay->adapter, outbuf); + /* Adjust offset */ + rtph263depay->offset += EBIT + SBIT; + rtph263depay->offset %= 8; + /* Trim end of the leftover */ + if (rtph263depay->offset) + rtph263depay->leftover &= 0xFF << rtph263depay->offset; + if (M) { + /* frame is completed */ + guint avail; + guint32 timestamp; + if (rtph263depay->offset) { + /* push in the leftover */ + GstBuffer *buf = gst_buffer_new_and_alloc (1); + GST_BUFFER_DATA (buf)[0] = rtph263depay->leftover; + gst_adapter_push (rtph263depay->adapter, buf); + } + avail = gst_adapter_available (rtph263depay->adapter); + outbuf = gst_adapter_take_buffer (rtph263depay->adapter, avail); + if (I) + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); + timestamp = gst_rtp_buffer_get_timestamp (buf); + gst_base_rtp_depayload_push_ts (depayload, timestamp, outbuf); } return NULL; Index: gstrtph263depay.h RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtp/gstrtph263depay.h,v retrieving revision 1.1 diff -u -d -r1.1 -r1.2 --- gstrtph263depay.h 20 Aug 2007 16:52:03 -0000 1.1 +++ gstrtph263depay.h 27 Nov 2007 00:01:41 -0000 1.2 @@ -44,6 +44,8 @@ GstBaseRTPDepayload depayload; + guint8 offset; /* offset to apply to next payload */ + guint8 leftover; /* leftover from previous payload (if offset != 0) */ GstAdapter *adapter; }; |