summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Ostby <bjornos@axis.com>2008-11-14 11:41:55 +0000
committerWim Taymans <wim.taymans@gmail.com>2008-11-14 11:41:55 +0000
commitd8e74cabdc277a3e94edfbdff268fb7050fab5f4 (patch)
tree77ebdaabb52870e4f5cd2e5d249f630af9318b02
parent5a4565868dd3ba9ef8222fdb73a7a1dee8a1e843 (diff)
gst/rtp/: Add JPEG payloader. Fixes #560756.
Original commit message from CVS: Patch by: Bjorn Ostby <bjornos at axis dot com> * gst/rtp/Makefile.am: * gst/rtp/gstrtp.c: (plugin_init): * gst/rtp/gstrtpjpegpay.c: (gst_rtp_jpeg_pay_base_init), (gst_rtp_jpeg_pay_class_init), (gst_rtp_jpeg_pay_init), (gst_rtp_jpeg_pay_setcaps), (gst_rtp_jpeg_pay_header_size), (gst_rtp_jpeg_pay_read_quant_table), (gst_rtp_jpeg_pay_scan_marker), (gst_rtp_jpeg_pay_handle_buffer), (gst_rtp_jpeg_pay_set_property), (gst_rtp_jpeg_pay_get_property), (gst_rtp_jpeg_pay_plugin_init): * gst/rtp/gstrtpjpegpay.h: Add JPEG payloader. Fixes #560756.
-rw-r--r--ChangeLog16
-rw-r--r--gst/rtp/Makefile.am2
-rw-r--r--gst/rtp/gstrtp.c4
-rw-r--r--gst/rtp/gstrtpjpegpay.c514
-rw-r--r--gst/rtp/gstrtpjpegpay.h58
5 files changed, 594 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d7b839c..32d9b1d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-11-14 Wim Taymans <wim.taymans@collabora.co.uk>
+
+ Patch by: Bjorn Ostby <bjornos at axis dot com>
+
+ * gst/rtp/Makefile.am:
+ * gst/rtp/gstrtp.c: (plugin_init):
+ * gst/rtp/gstrtpjpegpay.c: (gst_rtp_jpeg_pay_base_init),
+ (gst_rtp_jpeg_pay_class_init), (gst_rtp_jpeg_pay_init),
+ (gst_rtp_jpeg_pay_setcaps), (gst_rtp_jpeg_pay_header_size),
+ (gst_rtp_jpeg_pay_read_quant_table),
+ (gst_rtp_jpeg_pay_scan_marker), (gst_rtp_jpeg_pay_handle_buffer),
+ (gst_rtp_jpeg_pay_set_property), (gst_rtp_jpeg_pay_get_property),
+ (gst_rtp_jpeg_pay_plugin_init):
+ * gst/rtp/gstrtpjpegpay.h:
+ Add JPEG payloader. Fixes #560756.
+
2008-11-13 Wim Taymans <wim.taymans@collabora.co.uk>
Patch by: Fabricio Godoy <skarllot at gmail dot com>
diff --git a/gst/rtp/Makefile.am b/gst/rtp/Makefile.am
index 6c4c52da..d677930b 100644
--- a/gst/rtp/Makefile.am
+++ b/gst/rtp/Makefile.am
@@ -32,6 +32,7 @@ libgstrtp_la_SOURCES = \
gstrtph263pay.c \
gstrtph264depay.c \
gstrtph264pay.c \
+ gstrtpjpegpay.c \
gstrtpL16depay.c \
gstrtpL16pay.c \
gstasteriskh263.c \
@@ -101,6 +102,7 @@ noinst_HEADERS = \
gstrtph263pay.h \
gstrtph264depay.h \
gstrtph264pay.h \
+ gstrtpjpegpay.h \
gstrtpmp1sdepay.h \
gstrtpmp2tdepay.h \
gstrtpmp2tpay.h \
diff --git a/gst/rtp/gstrtp.c b/gst/rtp/gstrtp.c
index 3ada28da..b7e000a0 100644
--- a/gst/rtp/gstrtp.c
+++ b/gst/rtp/gstrtp.c
@@ -49,6 +49,7 @@
#include "gstrtph263pay.h"
#include "gstrtph264depay.h"
#include "gstrtph264pay.h"
+#include "gstrtpjpegpay.h"
#include "gstrtpL16depay.h"
#include "gstrtpL16pay.h"
#include "gstasteriskh263.h"
@@ -158,6 +159,9 @@ plugin_init (GstPlugin * plugin)
if (!gst_rtp_h264_pay_plugin_init (plugin))
return FALSE;
+ if (!gst_rtp_jpeg_pay_plugin_init (plugin))
+ return FALSE;
+
if (!gst_rtp_L16_pay_plugin_init (plugin))
return FALSE;
diff --git a/gst/rtp/gstrtpjpegpay.c b/gst/rtp/gstrtpjpegpay.c
new file mode 100644
index 00000000..d59eebec
--- /dev/null
+++ b/gst/rtp/gstrtpjpegpay.c
@@ -0,0 +1,514 @@
+/* GStreamer
+ * Copyright (C) 2008 Axis Communications <dev-gstreamer@axis.com>
+ * @author Bjorn Ostby <bjorn.ostby@axis.com>
+ * @author Peter Kjellerstedt <peter.kjellerstedt@axis.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:rtpjpegpay
+ * @short_description: RTP payloader for JPEG pictures
+ *
+ * Payload encode JPEG pictures into RTP packets according to RFC 2435.
+ * For detailed information see: http://www.rfc-editor.org/rfc/rfc2435.txt
+ *
+ * The payloader takes a JPEG picture, scans the header for quantization
+ * tables (if needed) and constructs the RTP packet header followed by
+ * the actual JPEG entropy scan.
+ *
+ * The payloader assumes that correct width and height is found in the caps.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <gst/rtp/gstrtpbuffer.h>
+
+#include "gstrtpjpegpay.h"
+
+/* elementfactory information */
+static const GstElementDetails gst_rtp_jpeg_pay_details =
+GST_ELEMENT_DETAILS ("RTP packet payloader",
+ "Codec/Payloader/Network",
+ "Payload-encodes JPEG pictures into a RTP packet",
+ "Axis Communications <dev-gstreamer@axis.com>");
+
+static GstStaticPadTemplate gst_rtp_jpeg_pay_sink_template =
+ GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("image/jpeg, "
+ " height = (int) [0, 2040], "
+ " width = (int) [0, 2040]; "
+ "video/x-jpeg, "
+ " height = (int) [0, 2040], " " width = (int) [0, 2040]")
+ );
+
+static GstStaticPadTemplate gst_rtp_jpeg_pay_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("application/x-rtp, "
+ " media = (string) \"video\", "
+ " payload = (int) 26 , "
+ " clock-rate = (int) 90000, " " encoding-name = (string) \"JPEG\"")
+ );
+
+GST_DEBUG_CATEGORY_STATIC (rtpjpegpay_debug);
+#define GST_CAT_DEFAULT (rtpjpegpay_debug)
+
+/**
+ * QUANT_PREFIX_LEN:
+ *
+ * Prefix length in the header before the quantization tables:
+ * Two size bytes and one byte for precision
+ */
+#define QUANT_PREFIX_LEN 3
+
+/**
+ * DEFAULT_JPEG_QUALITY:
+ *
+ */
+#define DEFAULT_JPEG_QUALITY 0
+
+/**
+ * DEFAULT_JPEG_TYPE:
+ *
+ */
+#define DEFAULT_JPEG_TYPE 0
+
+typedef enum _RtpJpegMarker RtpJpegMarker;
+
+/**
+ * RtpJpegMarker:
+ * @JPEG_MARKER: Prefix for JPEG marker
+ * @JPEG_MARKER_SOI: Start of Image marker
+ * @JPEG_MARKER_JFIF: JFIF marker
+ * @JPEG_MARKER_CMT: Comment marker
+ * @JPEG_MARKER_DQT: Define Quantization Table marker
+ * @JPEG_MARKER_SOF: Start of Frame marker
+ * @JPEG_MARKER_DHT: Define Huffman Table marker
+ * @JPEG_MARKER_SOS: Start of Scan marker
+ * @JPEG_MARKER_EOI: End of Image marker
+ *
+ * Identifers for markers in JPEG header
+ */
+enum _RtpJpegMarker
+{
+ JPEG_MARKER = 0xFF,
+ JPEG_MARKER_SOI = 0xD8,
+ JPEG_MARKER_JFIF = 0xE0,
+ JPEG_MARKER_CMT = 0xFE,
+ JPEG_MARKER_DQT = 0xDB,
+ JPEG_MARKER_SOF = 0xC0,
+ JPEG_MARKER_DHT = 0xC4,
+ JPEG_MARKER_SOS = 0xDA,
+ JPEG_MARKER_EOI = 0xD9,
+};
+
+enum
+{
+ PROP_0,
+ PROP_JPEG_QUALITY,
+ PROP_JPEG_TYPE
+};
+
+enum
+{
+ Q_TABLE_0 = 0,
+ Q_TABLE_1,
+ Q_TABLE_MAX /* only support for two tables at the moment */
+};
+
+typedef struct _RtpJpegHeader RtpJpegHeader;
+typedef struct _RtpQuantHeader RtpQuantHeader;
+
+/**
+ * RtpJpegHeader:
+ * @type_spec: type specific
+ * @offset: fragment offset
+ * @type: type field
+ * @q: quantization table for this frame
+ * @width: width of image in 8-pixel multiples
+ * @height: height of image in 8-pixel multiples
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type-specific | Fragment Offset |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Q | Width | Height |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct _RtpJpegHeader
+{
+#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
+ guint type_spec:8;
+ guint offset:24;
+#else
+ guint offset:24;
+ guint type_spec:8;
+#endif
+ guint8 type;
+ guint8 q;
+ guint8 width;
+ guint8 height;
+};
+
+/**
+ * RtpQuantHeader
+ * @mbz: must be zero
+ * @precision: specify size of quantization tables
+ * @length: length of quantization data
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | MBZ | Precision | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Quantization Table Data |
+ * | ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct _RtpQuantHeader
+{
+ guint8 mbz;
+ guint8 precision;
+ guint16 length;
+};
+
+/* FIXME: restart marker header currently unsupported */
+
+static void gst_rtp_jpeg_pay_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+
+static void gst_rtp_jpeg_pay_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static gboolean gst_rtp_jpeg_pay_setcaps (GstBaseRTPPayload * basepayload,
+ GstCaps * caps);
+
+static GstFlowReturn gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * pad,
+ GstBuffer * buffer);
+
+GST_BOILERPLATE (GstRtpJPEGPay, gst_rtp_jpeg_pay, GstBaseRTPPayload,
+ GST_TYPE_BASE_RTP_PAYLOAD);
+
+static void
+gst_rtp_jpeg_pay_base_init (gpointer klass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_rtp_jpeg_pay_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_rtp_jpeg_pay_sink_template));
+
+ gst_element_class_set_details (element_class, &gst_rtp_jpeg_pay_details);
+}
+
+static void
+gst_rtp_jpeg_pay_class_init (GstRtpJPEGPayClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+
+ gobject_class->set_property = gst_rtp_jpeg_pay_set_property;
+ gobject_class->get_property = gst_rtp_jpeg_pay_get_property;
+
+ gstbasertppayload_class->set_caps = gst_rtp_jpeg_pay_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtp_jpeg_pay_handle_buffer;
+
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_JPEG_QUALITY,
+ g_param_spec_int ("quality", "Quality", "Quality factor on JPEG data",
+ 0, 255, DEFAULT_JPEG_QUALITY, G_PARAM_READWRITE));
+
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_JPEG_TYPE,
+ g_param_spec_int ("type", "Type", "JPEG Type",
+ 0, 255, DEFAULT_JPEG_TYPE, G_PARAM_READWRITE));
+
+ GST_DEBUG_CATEGORY_INIT (rtpjpegpay_debug, "rtpjpegpay", 0,
+ "Motion JPEG RTP Payloader");
+}
+
+static void
+gst_rtp_jpeg_pay_init (GstRtpJPEGPay * rtpjpegpay, GstRtpJPEGPayClass * klass)
+{
+ rtpjpegpay->quality = DEFAULT_JPEG_QUALITY;
+ rtpjpegpay->type = DEFAULT_JPEG_TYPE;
+}
+
+static gboolean
+gst_rtp_jpeg_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
+{
+ GstStructure *caps_structure = gst_caps_get_structure (caps, 0);
+ GstRtpJPEGPay *rtpjpegpay;
+
+ rtpjpegpay = GST_RTP_JPEG_PAY (basepayload);
+
+ if (!gst_structure_get_int (caps_structure, "height", &rtpjpegpay->height)) {
+ goto caps_fail;
+ }
+
+ if (!gst_structure_get_int (caps_structure, "width", &rtpjpegpay->width)) {
+ goto caps_fail;
+ }
+
+ rtpjpegpay->height /= 8;
+ rtpjpegpay->width /= 8;
+
+ gst_basertppayload_set_options (basepayload, "video", TRUE, "JPEG", 90000);
+ gst_basertppayload_set_outcaps (basepayload, NULL);
+
+ return TRUE;
+
+caps_fail:
+ GST_ERROR_OBJECT (rtpjpegpay, "Failed to get width/height from caps");
+ return FALSE;
+}
+
+
+static guint
+gst_rtp_jpeg_pay_header_size (const guint8 * data, guint offset)
+{
+ return data[offset] << 8 | data[offset + 1];
+}
+
+static guint
+gst_rtp_jpeg_pay_read_quant_table (const guint8 * data, guint offset,
+ const guint8 ** quantizer_table, RtpQuantHeader * qtable, guint8 index)
+{
+ gint quant_size = gst_rtp_jpeg_pay_header_size (data, offset);
+
+ qtable->precision |= (data[offset + 2] & 0x10) ? (1 << index) : 0x00;
+
+ /* ommit length and precision prefix from table */
+ quantizer_table[index] = &data[offset + QUANT_PREFIX_LEN];
+ quant_size -= QUANT_PREFIX_LEN;
+
+ qtable->length += quant_size;
+
+ return quant_size;
+}
+
+static RtpJpegMarker
+gst_rtp_jpeg_pay_scan_marker (const guint8 * data, guint size, guint * offset)
+{
+ while ((data[(*offset)++] != JPEG_MARKER) && ((*offset) < size));
+
+ if (G_UNLIKELY ((*offset) >= size)) {
+ return JPEG_MARKER_EOI;
+ } else {
+ return data[(*offset)++];
+ }
+}
+
+static GstFlowReturn
+gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
+{
+ GstRtpJPEGPay *rtpjpegpay;
+ GstClockTime timestamp;
+ GstFlowReturn ret = GST_FLOW_ERROR;
+ RtpJpegHeader jpeg_header;
+ RtpQuantHeader quant_header;
+ const guint8 *jpeg_quantizer_table[Q_TABLE_MAX] = { NULL };
+ guint8 *data;
+ guint8 quant_table_index = 0;
+ guint size;
+ guint mtu;
+ guint bytes_left;
+ guint quant_data_size = sizeof (quant_header);
+ guint jpeg_header_size = 0;
+ guint offset = 0;
+ gboolean frame_done = FALSE;
+ gboolean sos_found = FALSE;
+
+ rtpjpegpay = GST_RTP_JPEG_PAY (basepayload);
+ mtu = GST_BASE_RTP_PAYLOAD_MTU (rtpjpegpay);
+
+ jpeg_header.type_spec = 0;
+ jpeg_header.offset = 0;
+ jpeg_header.type = rtpjpegpay->type;
+ jpeg_header.q = rtpjpegpay->quality;
+ jpeg_header.width = rtpjpegpay->width;
+ jpeg_header.height = rtpjpegpay->height;
+
+ size = GST_BUFFER_SIZE (buffer);
+ data = GST_BUFFER_DATA (buffer);
+ timestamp = GST_BUFFER_TIMESTAMP (buffer);
+
+ /* parse the jpeg header for 'start of scan' and read quant tables if needed */
+ while (!sos_found && (offset < size)) {
+ switch (gst_rtp_jpeg_pay_scan_marker (data, size, &offset)) {
+ case JPEG_MARKER_JFIF:
+ case JPEG_MARKER_CMT:
+ case JPEG_MARKER_SOF:
+ case JPEG_MARKER_DHT:
+ offset += gst_rtp_jpeg_pay_header_size (data, offset);
+ break;
+ case JPEG_MARKER_DQT:{
+ if ((jpeg_header.q >= 128) && (quant_table_index < Q_TABLE_MAX)) {
+ if (!quant_table_index) {
+ quant_header.length = 0;
+ quant_header.precision = 0;
+ quant_header.mbz = 0;
+ }
+ quant_data_size += gst_rtp_jpeg_pay_read_quant_table (data, offset,
+ jpeg_quantizer_table, &quant_header, quant_table_index);
+
+ quant_table_index++;
+ }
+ offset += gst_rtp_jpeg_pay_header_size (data, offset);
+ }
+ break;
+ case JPEG_MARKER_SOS:
+ sos_found = TRUE;
+ jpeg_header_size = offset + gst_rtp_jpeg_pay_header_size (data, offset);
+ break;
+ case JPEG_MARKER_EOI:
+ GST_WARNING ("EOI reached before SOS!");
+ break;
+ case JPEG_MARKER_SOI:
+ default:
+ break;
+ }
+ }
+
+ size -= jpeg_header_size;
+ data += jpeg_header_size;
+ offset = 0;
+
+ bytes_left = sizeof (jpeg_header) + quant_data_size + size;
+
+ while (!frame_done) {
+ GstBuffer *outbuf;
+ guint8 *payload;
+ guint payload_size = (bytes_left < mtu ? bytes_left : mtu);
+
+ outbuf = gst_rtp_buffer_new_allocate (payload_size, 0, 0);
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+
+ if (payload_size == bytes_left) {
+ frame_done = TRUE;
+ gst_rtp_buffer_set_marker (outbuf, 1);
+ }
+
+ payload = gst_rtp_buffer_get_payload (outbuf);
+
+ memcpy (payload, &jpeg_header, sizeof (jpeg_header));
+ payload += sizeof (jpeg_header);
+ payload_size -= sizeof (jpeg_header);
+
+ /* only send quant table with first packet */
+ if (G_UNLIKELY (quant_data_size > 0)) {
+ guint8 index;
+ const guint8 table_size = quant_header.length / quant_table_index;
+
+ quant_header.length = g_htons (quant_header.length);
+
+ memcpy (payload, &quant_header, sizeof (quant_header));
+ payload += sizeof (quant_header);
+
+ for (index = 0; index < quant_table_index; index++) {
+ memcpy (payload, jpeg_quantizer_table[index], table_size);
+ payload += table_size;
+ }
+
+ payload_size -= quant_data_size;
+ bytes_left -= quant_data_size;
+ quant_data_size = 0;
+ }
+
+ memcpy (payload, &data[offset], payload_size);
+
+ ret = gst_basertppayload_push (basepayload, outbuf);
+ if (ret != GST_FLOW_OK)
+ break;
+
+ bytes_left -= payload_size;
+ offset += payload_size;
+
+#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
+ jpeg_header.offset = ((offset & 0x0000FF) << 16) |
+ ((offset & 0xFF0000) >> 16) | (offset & 0x00FF00);
+#else
+ jpeg_header.offset = offset;
+#endif
+ }
+
+ gst_buffer_unref (buffer);
+
+ return ret;
+}
+
+static void
+gst_rtp_jpeg_pay_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstRtpJPEGPay *rtpjpegpay;
+
+ rtpjpegpay = GST_RTP_JPEG_PAY (object);
+
+ switch (prop_id) {
+ case PROP_JPEG_QUALITY:
+ rtpjpegpay->quality = g_value_get_int (value);
+ GST_DEBUG_OBJECT (object, "quality = %d", rtpjpegpay->quality);
+ break;
+ case PROP_JPEG_TYPE:
+ rtpjpegpay->type = g_value_get_int (value);
+ GST_DEBUG_OBJECT (object, "type = %d", rtpjpegpay->type);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_rtp_jpeg_pay_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstRtpJPEGPay *rtpjpegpay;
+
+ rtpjpegpay = GST_RTP_JPEG_PAY (object);
+
+ switch (prop_id) {
+ case PROP_JPEG_QUALITY:
+ g_value_set_int (value, rtpjpegpay->quality);
+ break;
+ case PROP_JPEG_TYPE:
+ g_value_set_int (value, rtpjpegpay->type);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+gboolean
+gst_rtp_jpeg_pay_plugin_init (GstPlugin * plugin)
+{
+ return gst_element_register (plugin, "rtpjpegpay", GST_RANK_NONE,
+ GST_TYPE_RTP_JPEG_PAY);
+}
diff --git a/gst/rtp/gstrtpjpegpay.h b/gst/rtp/gstrtpjpegpay.h
new file mode 100644
index 00000000..5af6176c
--- /dev/null
+++ b/gst/rtp/gstrtpjpegpay.h
@@ -0,0 +1,58 @@
+/* GStreamer
+ * Copyright (C) 2008 Axis Communications <dev-gstreamer@axis.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_RTP_JPEG_PAY_H__
+#define __GST_RTP_JPEG_PAY_H__
+
+#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
+
+G_BEGIN_DECLS
+#define GST_TYPE_RTP_JPEG_PAY \
+ (gst_rtp_jpeg_pay_get_type())
+#define GST_RTP_JPEG_PAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_JPEG_PAY,GstRtpJPEGPay))
+#define GST_RTP_JPEG_PAY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_JPEG_PAY,GstRtpJPEGPayClass))
+#define GST_IS_RTP_JPEG_PAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_JPEG_PAY))
+#define GST_IS_RTP_JPEG_PAY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_JPEG_PAY))
+typedef struct _GstRtpJPEGPay GstRtpJPEGPay;
+typedef struct _GstRtpJPEGPayClass GstRtpJPEGPayClass;
+
+struct _GstRtpJPEGPay
+{
+ GstBaseRTPPayload payload;
+
+ gint height;
+ guint8 quality;
+ guint8 type;
+ gint width;
+};
+
+struct _GstRtpJPEGPayClass
+{
+ GstBaseRTPPayloadClass parent_class;
+};
+
+gboolean gst_rtp_jpeg_pay_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+#endif /* __GST_RTP_JPEG_PAY_H__ */