From 68d62a8433a74388758ed4e9193330c7493c93fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 10 Feb 2024 19:47:24 +0000 Subject: [PATCH] realmedia: remove RealServer RTSP extension, RDT handling and PNM source Part-of: --- .../gst-docs/symbols/symbol_index.json | 35 - .../gst-libs/gst/rtsp/gstrtsptransport.c | 4 + .../docs/gst_plugins_cache.json | 220 +-- .../gst-plugins-ugly/gst/realmedia/asmrules.c | 712 --------- .../gst-plugins-ugly/gst/realmedia/asmrules.h | 115 -- .../gst/realmedia/gstrdtbuffer.c | 477 ------ .../gst/realmedia/gstrdtbuffer.h | 121 -- .../gst/realmedia/meson.build | 8 - .../gst-plugins-ugly/gst/realmedia/rdtdepay.c | 496 ------ .../gst-plugins-ugly/gst/realmedia/rdtdepay.h | 74 - .../gst/realmedia/rdtjitterbuffer.c | 531 ------- .../gst/realmedia/rdtjitterbuffer.h | 91 -- .../gst/realmedia/rdtmanager.c | 1371 ----------------- .../gst/realmedia/rdtmanager.h | 93 -- .../gst-plugins-ugly/gst/realmedia/realhash.c | 324 ---- .../gst-plugins-ugly/gst/realmedia/realhash.h | 31 - .../gst/realmedia/realmedia.c | 8 - .../gst-plugins-ugly/gst/realmedia/rtspreal.c | 735 --------- .../gst-plugins-ugly/gst/realmedia/rtspreal.h | 93 -- 19 files changed, 6 insertions(+), 5533 deletions(-) delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/asmrules.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/asmrules.h delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.h delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.h delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.h delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.h delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/realhash.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/realhash.h delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.c delete mode 100644 subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.h diff --git a/subprojects/gst-docs/symbols/symbol_index.json b/subprojects/gst-docs/symbols/symbol_index.json index f584d95a2c..a172839ebb 100644 --- a/subprojects/gst-docs/symbols/symbol_index.json +++ b/subprojects/gst-docs/symbols/symbol_index.json @@ -13890,9 +13890,6 @@ "GstOverlayComposition!src", "GstOverlayComposition::caps-changed", "GstOverlayComposition::draw", - "GstPNMSrc", - "GstPNMSrc!src", - "GstPNMSrc:location", "GstPad", "GstPad.ABI._gst_reserved", "GstPad.ABI.abi.eventfullfunc", @@ -14612,21 +14609,6 @@ "GstQueueLeaky::downstream", "GstQueueLeaky::no", "GstQueueLeaky::upstream", - "GstRDTDepay", - "GstRDTDepay!sink", - "GstRDTDepay!src", - "GstRDTManager", - "GstRDTManager!recv_rtcp_sink_%u", - "GstRDTManager!recv_rtp_sink_%u", - "GstRDTManager!recv_rtp_src_%u_%u_%u", - "GstRDTManager!rtcp_src_%u", - "GstRDTManager::clear-pt-map", - "GstRDTManager::on-bye-ssrc", - "GstRDTManager::on-bye-timeout", - "GstRDTManager::on-npt-stop", - "GstRDTManager::on-timeout", - "GstRDTManager::request-pt-map", - "GstRDTManager:latency", "GstRGB2Bayer", "GstRGB2Bayer!sink", "GstRGB2Bayer!src", @@ -15234,7 +15216,6 @@ "GstRTSPRange.max", "GstRTSPRange.min", "GstRTSPRangeUnit", - "GstRTSPReal", "GstRTSPResult", "GstRTSPSendFunc", "GstRTSPSendListFunc", @@ -36698,7 +36679,6 @@ "element-pngparse", "element-pnmdec", "element-pnmenc", - "element-pnmsrc", "element-progressreport", "element-proxysink", "element-proxysrc", @@ -36718,8 +36698,6 @@ "element-radioactv", "element-rawaudioparse", "element-rawvideoparse", - "element-rdtdepay", - "element-rdtmanager", "element-removesilence", "element-retinex", "element-revtv", @@ -36860,7 +36838,6 @@ "element-rtpvrawpay", "element-rtpxqtdepay", "element-rtspclientsink", - "element-rtspreal", "element-rtspsrc", "element-rtspwms", "element-sbcdec", @@ -66572,8 +66549,6 @@ "pnmdec", "pnmenc", "pnmenc:ascii", - "pnmsrc", - "pnmsrc:location", "progressreport", "progressreport:do-query", "progressreport:format", @@ -66834,15 +66809,6 @@ "rawvideoparse:plane-strides", "rawvideoparse:top-field-first", "rawvideoparse:width", - "rdtdepay", - "rdtmanager", - "rdtmanager::clear-pt-map", - "rdtmanager::on-bye-ssrc", - "rdtmanager::on-bye-timeout", - "rdtmanager::on-npt-stop", - "rdtmanager::on-timeout", - "rdtmanager::request-pt-map", - "rdtmanager:latency", "removesilence", "removesilence:hysteresis", "removesilence:minimum-silence-buffers", @@ -67462,7 +67428,6 @@ "rtspclientsink:user-agent", "rtspclientsink:user-id", "rtspclientsink:user-pw", - "rtspreal", "rtspsrc", "rtspsrc::accept-certificate", "rtspsrc::before-send", diff --git a/subprojects/gst-plugins-base/gst-libs/gst/rtsp/gstrtsptransport.c b/subprojects/gst-plugins-base/gst-libs/gst/rtsp/gstrtsptransport.c index eac1dc26f5..9849ef384c 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/rtsp/gstrtsptransport.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/rtsp/gstrtsptransport.c @@ -99,6 +99,10 @@ static const GstRTSPTransMap transports[] = { {"srtpf", GST_RTSP_TRANS_RTP, GST_RTSP_PROFILE_SAVPF, GST_RTSP_LOWER_TRANS_UDP_MCAST, "application/x-srtp", {"rtpbin", "rtpdec"}}, + /* FIXME: these two are no longer supported (the rdtmanager element and + * related code has been removed from the realmedia plugin), but let's keep + * this around for now so it can still be added back via plugins if needed. + * FIXME 2.0: remove */ {"x-real-rdt", GST_RTSP_TRANS_RDT, GST_RTSP_PROFILE_AVP, GST_RTSP_LOWER_TRANS_UNKNOWN, "application/x-rdt", {"rdtmanager", NULL}}, diff --git a/subprojects/gst-plugins-ugly/docs/gst_plugins_cache.json b/subprojects/gst-plugins-ugly/docs/gst_plugins_cache.json index 8401974919..303ca025b4 100644 --- a/subprojects/gst-plugins-ugly/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-ugly/docs/gst_plugins_cache.json @@ -507,46 +507,6 @@ "realmedia": { "description": "RealMedia support plugins", "elements": { - "pnmsrc": { - "author": "Wim Taymans ", - "description": "Receive data over the network via PNM", - "hierarchy": [ - "GstPNMSrc", - "GstPushSrc", - "GstBaseSrc", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "interfaces": [ - "GstURIHandler" - ], - "klass": "Source/Network", - "long-name": "PNM packet receiver", - "pad-templates": { - "src": { - "caps": "application/vnd.rn-realmedia:\n", - "direction": "src", - "presence": "always" - } - }, - "properties": { - "location": { - "blurb": "Location of the PNM url to read", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "NULL", - "mutable": "null", - "readable": true, - "type": "gchararray", - "writable": true - } - }, - "rank": "marginal" - }, "rademux": { "author": "Tim-Philipp Müller ", "description": "Demultiplex a RealAudio file", @@ -558,7 +518,6 @@ "GObject" ], "klass": "Codec/Demuxer", - "long-name": "RealAudio Demuxer", "pad-templates": { "sink": { "caps": "application/x-pn-realaudio:\n", @@ -571,163 +530,7 @@ "presence": "sometimes" } }, - "rank": "secondary", - "signals": {} - }, - "rdtdepay": { - "author": "Lutz Mueller , Wim Taymans ", - "description": "Extracts RealMedia from RDT packets", - "hierarchy": [ - "GstRDTDepay", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Depayloader/Network", - "long-name": "RDT packet parser", - "pad-templates": { - "sink": { - "caps": "application/x-rdt:\n media: application\n clock-rate: [ 1, 2147483647 ]\n encoding-name: X-REAL-RDT\n", - "direction": "sink", - "presence": "always" - }, - "src": { - "caps": "application/vnd.rn-realmedia:\n", - "direction": "src", - "presence": "always" - } - }, - "rank": "marginal" - }, - "rdtmanager": { - "author": "Wim Taymans ", - "description": "Accepts raw RTP and RTCP packets and sends them forward", - "hierarchy": [ - "GstRDTManager", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "klass": "Codec/Parser/Network", - "long-name": "RTP Decoder", - "pad-templates": { - "recv_rtcp_sink_%%u": { - "caps": "application/x-rtcp:\n", - "direction": "sink", - "presence": "request" - }, - "recv_rtp_sink_%%u": { - "caps": "application/x-rdt:\n", - "direction": "sink", - "presence": "request" - }, - "recv_rtp_src_%%u_%%u_%%u": { - "caps": "application/x-rdt:\n", - "direction": "src", - "presence": "sometimes" - }, - "rtcp_src_%%u": { - "caps": "application/x-rtcp:\n", - "direction": "src", - "presence": "request" - } - }, - "properties": { - "latency": { - "blurb": "Amount of ms to buffer", - "conditionally-available": false, - "construct": false, - "construct-only": false, - "controllable": false, - "default": "200", - "max": "-1", - "min": "0", - "mutable": "null", - "readable": true, - "type": "guint", - "writable": true - } - }, - "rank": "none", - "signals": { - "clear-pt-map": { - "args": [], - "return-type": "void", - "when": "last" - }, - "on-bye-ssrc": { - "args": [ - { - "name": "arg0", - "type": "guint" - }, - { - "name": "arg1", - "type": "guint" - } - ], - "return-type": "void", - "when": "last" - }, - "on-bye-timeout": { - "args": [ - { - "name": "arg0", - "type": "guint" - }, - { - "name": "arg1", - "type": "guint" - } - ], - "return-type": "void", - "when": "last" - }, - "on-npt-stop": { - "args": [ - { - "name": "arg0", - "type": "guint" - }, - { - "name": "arg1", - "type": "guint" - } - ], - "return-type": "void", - "when": "last" - }, - "on-timeout": { - "args": [ - { - "name": "arg0", - "type": "guint" - }, - { - "name": "arg1", - "type": "guint" - } - ], - "return-type": "void", - "when": "last" - }, - "request-pt-map": { - "args": [ - { - "name": "arg0", - "type": "guint" - }, - { - "name": "arg1", - "type": "guint" - } - ], - "return-type": "GstCaps", - "when": "last" - } - } + "rank": "secondary" }, "rmdemux": { "author": "David Schleef ", @@ -740,7 +543,6 @@ "GObject" ], "klass": "Codec/Demuxer", - "long-name": "RealMedia Demuxer", "pad-templates": { "audio_%%u": { "caps": "ANY", @@ -758,25 +560,7 @@ "presence": "sometimes" } }, - "rank": "primary", - "signals": {} - }, - "rtspreal": { - "author": "Wim Taymans ", - "description": "Extends RTSP so that it can handle RealMedia setup", - "hierarchy": [ - "GstRTSPReal", - "GstElement", - "GstObject", - "GInitiallyUnowned", - "GObject" - ], - "interfaces": [ - "GstRTSPExtension" - ], - "klass": "Network/Extension/Protocol", - "long-name": "RealMedia RTSP Extension", - "rank": "marginal" + "rank": "primary" } }, "filename": "gstrealmedia", diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/asmrules.c b/subprojects/gst-plugins-ugly/gst/realmedia/asmrules.c deleted file mode 100644 index af2f8a0a3f..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/asmrules.c +++ /dev/null @@ -1,712 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "asmrules.h" - -#define MAX_RULE_LENGTH 2048 - -/* define to enable some more debug */ -#undef DEBUG - -static GstASMNode * -gst_asm_node_new (void) -{ - GstASMNode *node; - - node = g_new0 (GstASMNode, 1); - node->type = GST_ASM_NODE_UNKNOWN; - - return node; -} - -static void -gst_asm_node_free (GstASMNode * node) -{ - if (node->left) - gst_asm_node_free (node->left); - if (node->right) - gst_asm_node_free (node->right); - if (node->type == GST_ASM_NODE_VARIABLE && node->data.varname) - g_free (node->data.varname); - g_free (node); -} - -static gfloat -gst_asm_operator_eval (GstASMOp optype, gfloat left, gfloat right) -{ - gfloat result = 0.0; - - switch (optype) { - case GST_ASM_OP_GREATER: - result = (gfloat) (left > right); - break; - case GST_ASM_OP_LESS: - result = (gfloat) (left < right); - break; - case GST_ASM_OP_GREATEREQUAL: - result = (gfloat) (left >= right); - break; - case GST_ASM_OP_LESSEQUAL: - result = (gfloat) (left <= right); - break; - case GST_ASM_OP_EQUAL: - result = (gfloat) (left == right); - break; - case GST_ASM_OP_NOTEQUAL: - result = (gfloat) (left != right); - break; - case GST_ASM_OP_AND: - result = (gfloat) (left && right); - break; - case GST_ASM_OP_OR: - result = (gfloat) (left || right); - break; - default: - break; - } - return result; -} - -static gfloat -gst_asm_node_evaluate (GstASMNode * node, GHashTable * vars) -{ - gfloat result = 0.0; - - if (node == NULL) - return 0.0; - - switch (node->type) { - case GST_ASM_NODE_VARIABLE: - { - gchar *val; - - val = g_hash_table_lookup (vars, node->data.varname); - if (val) - result = (gfloat) atof (val); - break; - } - case GST_ASM_NODE_INTEGER: - result = (gfloat) node->data.intval; - break; - case GST_ASM_NODE_FLOAT: - result = node->data.floatval; - break; - case GST_ASM_NODE_OPERATOR: - { - gfloat left, right; - - left = gst_asm_node_evaluate (node->left, vars); - right = gst_asm_node_evaluate (node->right, vars); - - result = gst_asm_operator_eval (node->data.optype, left, right); - break; - } - default: - break; - } - return result; -} - -#define IS_SPACE(p) (((p) == ' ') || ((p) == '\n') || \ - ((p) == '\r') || ((p) == '\t')) -#define IS_RULE_DELIM(p) (((p) == ',') || ((p) == ';') || ((p) == ')')) -#define IS_OPERATOR(p) (((p) == '>') || ((p) == '<') || \ - ((p) == '=') || ((p) == '!') || \ - ((p) == '&') || ((p) == '|')) -#define IS_NUMBER(p) ((((p) >= '0') && ((p) <= '9')) || ((p) == '.')) -#define IS_CHAR(p) (!IS_OPERATOR(ch) && !IS_RULE_DELIM(ch) && (ch != '\0')) - -#define IS_OP_TOKEN(t) (((t) == GST_ASM_TOKEN_AND) || ((t) == GST_ASM_TOKEN_OR)) -#define IS_COND_TOKEN(t) (((t) == GST_ASM_TOKEN_LESS) || ((t) == GST_ASM_TOKEN_LESSEQUAL) || \ - ((t) == GST_ASM_TOKEN_GREATER) || ((t) == GST_ASM_TOKEN_GREATEREQUAL) || \ - ((t) == GST_ASM_TOKEN_EQUAL) || ((t) == GST_ASM_TOKEN_NOTEQUAL)) - -typedef struct -{ - const gchar *buffer; - gint pos; - gchar ch; - - GstASMToken token; - gchar val[MAX_RULE_LENGTH]; -} GstASMScan; - -#define NEXT_CHAR(scan) ((scan)->ch = (scan)->buffer[(scan)->pos++]) -#define THIS_CHAR(scan) ((scan)->ch) - -static GstASMScan * -gst_asm_scan_new (const gchar * buffer) -{ - GstASMScan *scan; - - scan = g_new0 (GstASMScan, 1); - scan->buffer = buffer; - NEXT_CHAR (scan); - - return scan; -} - -static void -gst_asm_scan_free (GstASMScan * scan) -{ - g_free (scan); -} - -static void -gst_asm_scan_string (GstASMScan * scan, gchar delim) -{ - gchar ch; - gint i = 0; - - ch = THIS_CHAR (scan); - while ((ch != delim) && (ch != '\0')) { - if (i < MAX_RULE_LENGTH - 1) - scan->val[i++] = ch; - ch = NEXT_CHAR (scan); - if (ch == '\\') - ch = NEXT_CHAR (scan); - } - scan->val[i] = '\0'; - - if (ch == delim) - NEXT_CHAR (scan); - - scan->token = GST_ASM_TOKEN_STRING; -} - -static void -gst_asm_scan_number (GstASMScan * scan) -{ - gchar ch; - gint i = 0; - gboolean have_float = FALSE; - - ch = THIS_CHAR (scan); - /* real strips all spaces that are not inside quotes for numbers */ - while ((IS_NUMBER (ch) || IS_SPACE (ch))) { - if (i < (MAX_RULE_LENGTH - 1) && !IS_SPACE (ch)) - scan->val[i++] = ch; - if (ch == '.') - have_float = TRUE; - ch = NEXT_CHAR (scan); - } - scan->val[i] = '\0'; - - if (have_float) - scan->token = GST_ASM_TOKEN_FLOAT; - else - scan->token = GST_ASM_TOKEN_INT; -} - -static void -gst_asm_scan_identifier (GstASMScan * scan) -{ - gchar ch; - gint i = 0; - - ch = THIS_CHAR (scan); - /* real strips all spaces that are not inside quotes for identifiers */ - while ((IS_CHAR (ch) || IS_SPACE (ch))) { - if (i < (MAX_RULE_LENGTH - 1) && !IS_SPACE (ch)) - scan->val[i++] = ch; - ch = NEXT_CHAR (scan); - } - scan->val[i] = '\0'; - - scan->token = GST_ASM_TOKEN_IDENTIFIER; -} - -static void -gst_asm_scan_print_token (GstASMScan * scan) -{ -#ifdef DEBUG - switch (scan->token) { - case GST_ASM_TOKEN_NONE: - g_print ("none\n"); - break; - case GST_ASM_TOKEN_EOF: - g_print ("EOF\n"); - break; - - case GST_ASM_TOKEN_INT: - g_print ("INT %d\n", atoi (scan->val)); - break; - case GST_ASM_TOKEN_FLOAT: - g_print ("FLOAT %f\n", atof (scan->val)); - break; - case GST_ASM_TOKEN_IDENTIFIER: - g_print ("ID %s\n", scan->val); - break; - case GST_ASM_TOKEN_STRING: - g_print ("STRING %s\n", scan->val); - break; - - case GST_ASM_TOKEN_HASH: - g_print ("HASH\n"); - break; - case GST_ASM_TOKEN_SEMICOLON: - g_print ("SEMICOLON\n"); - break; - case GST_ASM_TOKEN_COMMA: - g_print ("COMMA\n"); - break; - case GST_ASM_TOKEN_EQUAL: - g_print ("==\n"); - break; - case GST_ASM_TOKEN_NOTEQUAL: - g_print ("!=\n"); - break; - case GST_ASM_TOKEN_AND: - g_print ("&&\n"); - break; - case GST_ASM_TOKEN_OR: - g_print ("||\n"); - break; - case GST_ASM_TOKEN_LESS: - g_print ("<\n"); - break; - case GST_ASM_TOKEN_LESSEQUAL: - g_print ("<=\n"); - break; - case GST_ASM_TOKEN_GREATER: - g_print (">\n"); - break; - case GST_ASM_TOKEN_GREATEREQUAL: - g_print (">=\n"); - break; - case GST_ASM_TOKEN_DOLLAR: - g_print ("$\n"); - break; - case GST_ASM_TOKEN_LPAREN: - g_print ("(\n"); - break; - case GST_ASM_TOKEN_RPAREN: - g_print (")\n"); - break; - default: - break; - } -#endif -} - -static GstASMToken -gst_asm_scan_next_token (GstASMScan * scan) -{ - gchar ch; - - ch = THIS_CHAR (scan); - - /* skip spaces */ - while (IS_SPACE (ch)) - ch = NEXT_CHAR (scan); - - /* remove \ which is common in front of " */ - while (ch == '\\') - ch = NEXT_CHAR (scan); - - switch (ch) { - case '#': - scan->token = GST_ASM_TOKEN_HASH; - NEXT_CHAR (scan); - break; - case ';': - scan->token = GST_ASM_TOKEN_SEMICOLON; - NEXT_CHAR (scan); - break; - case ',': - scan->token = GST_ASM_TOKEN_COMMA; - NEXT_CHAR (scan); - break; - case '=': - scan->token = GST_ASM_TOKEN_EQUAL; - if (NEXT_CHAR (scan) == '=') - NEXT_CHAR (scan); - break; - case '!': - if (NEXT_CHAR (scan) == '=') { - scan->token = GST_ASM_TOKEN_NOTEQUAL; - NEXT_CHAR (scan); - } - break; - case '&': - scan->token = GST_ASM_TOKEN_AND; - if (NEXT_CHAR (scan) == '&') - NEXT_CHAR (scan); - break; - case '|': - scan->token = GST_ASM_TOKEN_OR; - if (NEXT_CHAR (scan) == '|') - NEXT_CHAR (scan); - break; - case '<': - scan->token = GST_ASM_TOKEN_LESS; - if (NEXT_CHAR (scan) == '=') { - scan->token = GST_ASM_TOKEN_LESSEQUAL; - NEXT_CHAR (scan); - } - break; - case '>': - scan->token = GST_ASM_TOKEN_GREATER; - if (NEXT_CHAR (scan) == '=') { - scan->token = GST_ASM_TOKEN_GREATEREQUAL; - NEXT_CHAR (scan); - } - break; - case '$': - scan->token = GST_ASM_TOKEN_DOLLAR; - NEXT_CHAR (scan); - break; - case '(': - scan->token = GST_ASM_TOKEN_LPAREN; - NEXT_CHAR (scan); - break; - case ')': - scan->token = GST_ASM_TOKEN_RPAREN; - NEXT_CHAR (scan); - break; - case '"': - NEXT_CHAR (scan); - gst_asm_scan_string (scan, '"'); - break; - case '\'': - NEXT_CHAR (scan); - gst_asm_scan_string (scan, '\''); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - gst_asm_scan_number (scan); - break; - case '\0': - scan->token = GST_ASM_TOKEN_EOF; - break; - default: - gst_asm_scan_identifier (scan); - break; - } - gst_asm_scan_print_token (scan); - return scan->token; -} - -static GstASMRule * -gst_asm_rule_new (void) -{ - GstASMRule *rule; - - rule = g_new (GstASMRule, 1); - rule->root = NULL; - rule->props = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - return rule; -} - -static void -gst_asm_rule_free (GstASMRule * rule) -{ - g_hash_table_destroy (rule->props); - if (rule->root) - gst_asm_node_free (rule->root); - g_free (rule); -} - -static void -gst_asm_rule_add_property (GstASMRule * rule, gchar * key, gchar * val) -{ - g_hash_table_insert (rule->props, key, val); -} - -static GstASMNode *gst_asm_scan_parse_condition (GstASMScan * scan); - -static GstASMNode * -gst_asm_scan_parse_operand (GstASMScan * scan) -{ - GstASMNode *node; - - switch (scan->token) { - case GST_ASM_TOKEN_DOLLAR: - gst_asm_scan_next_token (scan); - - if (scan->token != GST_ASM_TOKEN_IDENTIFIER) - g_warning ("identifier expected"); - - node = gst_asm_node_new (); - node->type = GST_ASM_NODE_VARIABLE; - node->data.varname = g_strdup (scan->val); - break; - case GST_ASM_TOKEN_INT: - node = gst_asm_node_new (); - node->type = GST_ASM_NODE_INTEGER; - node->data.intval = (gfloat) atof (scan->val); - break; - case GST_ASM_TOKEN_FLOAT: - node = gst_asm_node_new (); - node->type = GST_ASM_NODE_FLOAT; - node->data.floatval = atoi (scan->val); - break; - case GST_ASM_TOKEN_LPAREN: - gst_asm_scan_next_token (scan); - node = gst_asm_scan_parse_condition (scan); - if (scan->token != GST_ASM_TOKEN_RPAREN) - g_warning (") expected"); - break; - default: - g_warning ("$ or ) expected"); - node = NULL; - break; - } - gst_asm_scan_next_token (scan); - - return node; -} - -static GstASMNode * -gst_asm_scan_parse_expression (GstASMScan * scan) -{ - GstASMNode *node, *left; - - node = gst_asm_scan_parse_operand (scan); - - while (IS_COND_TOKEN (scan->token)) { - left = node; - - node = gst_asm_node_new (); - node->type = GST_ASM_NODE_OPERATOR; - node->data.optype = (GstASMOp) scan->token; - - gst_asm_scan_next_token (scan); - - node->right = gst_asm_scan_parse_operand (scan); - node->left = left; - } - return node; -} - -static GstASMNode * -gst_asm_scan_parse_condition (GstASMScan * scan) -{ - GstASMNode *node, *left; - - node = gst_asm_scan_parse_expression (scan); - - while (IS_OP_TOKEN (scan->token)) { - left = node; - - node = gst_asm_node_new (); - node->type = GST_ASM_NODE_OPERATOR; - node->data.optype = (GstASMOp) scan->token; - - gst_asm_scan_next_token (scan); - - node->right = gst_asm_scan_parse_expression (scan); - node->left = left; - } - return node; -} - -static void -gst_asm_scan_parse_property (GstASMRule * rule, GstASMScan * scan) -{ - gchar *key, *val; - - if (scan->token != GST_ASM_TOKEN_IDENTIFIER) { - g_warning ("identifier expected"); - return; - } - key = g_strdup (scan->val); - - gst_asm_scan_next_token (scan); - if (scan->token != GST_ASM_TOKEN_EQUAL) { - g_warning ("= expected"); - g_free (key); - return; - } - gst_asm_scan_next_token (scan); - val = g_strdup (scan->val); - - gst_asm_rule_add_property (rule, key, val); - gst_asm_scan_next_token (scan); -} - -static GstASMRule * -gst_asm_scan_parse_rule (GstASMScan * scan) -{ - GstASMRule *rule; - - rule = gst_asm_rule_new (); - - if (scan->token == GST_ASM_TOKEN_HASH) { - gst_asm_scan_next_token (scan); - rule->root = gst_asm_scan_parse_condition (scan); - if (scan->token == GST_ASM_TOKEN_COMMA) - gst_asm_scan_next_token (scan); - } - - if (scan->token != GST_ASM_TOKEN_SEMICOLON) { - gst_asm_scan_parse_property (rule, scan); - while (scan->token == GST_ASM_TOKEN_COMMA) { - gst_asm_scan_next_token (scan); - gst_asm_scan_parse_property (rule, scan); - } - gst_asm_scan_next_token (scan); - } - return rule; -} - -static gboolean -gst_asm_rule_evaluate (GstASMRule * rule, GHashTable * vars) -{ - gboolean res; - - if (rule->root) { - res = (gboolean) gst_asm_node_evaluate (rule->root, vars); - } else - res = TRUE; - - return res; -} - -GstASMRuleBook * -gst_asm_rule_book_new (const gchar * rulebook) -{ - GstASMRuleBook *book; - GstASMRule *rule = NULL; - GstASMScan *scan; - GstASMToken token; - - book = g_new0 (GstASMRuleBook, 1); - book->rulebook = rulebook; - - scan = gst_asm_scan_new (book->rulebook); - gst_asm_scan_next_token (scan); - - do { - rule = gst_asm_scan_parse_rule (scan); - if (rule) { - book->rules = g_list_append (book->rules, rule); - book->n_rules++; - } - token = scan->token; - } while (token != GST_ASM_TOKEN_EOF); - - gst_asm_scan_free (scan); - - return book; -} - -void -gst_asm_rule_book_free (GstASMRuleBook * book) -{ - GList *walk; - - for (walk = book->rules; walk; walk = g_list_next (walk)) { - GstASMRule *rule = (GstASMRule *) walk->data; - - gst_asm_rule_free (rule); - } - g_list_free (book->rules); - g_free (book); -} - -gint -gst_asm_rule_book_match (GstASMRuleBook * book, GHashTable * vars, - gint * rulematches) -{ - GList *walk; - gint i, n = 0; - - for (walk = book->rules, i = 0; walk; walk = g_list_next (walk), i++) { - GstASMRule *rule = (GstASMRule *) walk->data; - - if (gst_asm_rule_evaluate (rule, vars)) { - rulematches[n++] = i; - } - } - return n; -} - -#ifdef TEST -gint -main (gint argc, gchar * argv[]) -{ - GstASMRuleBook *book; - gint rulematch[MAX_RULEMATCHES]; - GHashTable *vars; - gint i, n; - - static const gchar rules1[] = - "#($Bandwidth < 67959),TimestampDelivery=T,DropByN=T," - "priority=9;#($Bandwidth >= 67959) && ($Bandwidth < 167959)," - "AverageBandwidth=67959,Priority=9;#($Bandwidth >= 67959) && ($Bandwidth" - " < 167959),AverageBandwidth=0,Priority=5,OnDepend=\\\"1\\\";#($Bandwidth >= 167959)" - " && ($Bandwidth < 267959),AverageBandwidth=167959,Priority=9;#($Bandwidth >= 167959)" - " && ($Bandwidth < 267959),AverageBandwidth=0,Priority=5,OnDepend=\\\"3\\\";" - "#($Bandwidth >= 267959),AverageBandwidth=267959,Priority=9;#($Bandwidth >= 267959)" - ",AverageBandwidth=0,Priority=5,OnDepend=\\\"5\\\";"; - static const gchar rules2[] = - "AverageBandwidth=32041,Priority=5;AverageBandwidth=0," - "Priority=5,OnDepend=\\\"0\\\", OffDepend=\\\"0\\\";"; - static const gchar rules3[] = - "#(($Bandwidth >= 27500) && ($OldPNMPlayer)),AverageBandwidth=27500,priority=9,PNMKeyframeRule=T;#(($Bandwidth >= 27500) && ($OldPNMPlayer)),AverageBandwidth=0,priority=5,PNMNonKeyframeRule=T;#(($Bandwidth < 27500) && ($OldPNMPlayer)),TimestampDelivery=T,DropByN=T,priority=9,PNMThinningRule=T;#($Bandwidth < 13899),TimestampDelivery=T,DropByN=T,priority=9;#($Bandwidth >= 13899) && ($Bandwidth < 19000),AverageBandwidth=13899,Priority=9;#($Bandwidth >= 13899) && ($Bandwidth < 19000),AverageBandwidth=0,Priority=5,OnDepend=\\\"4\\\";#($Bandwidth >= 19000) && ($Bandwidth < 27500),AverageBandwidth=19000,Priority=9;#($Bandwidth >= 19000) && ($Bandwidth < 27500),AverageBandwidth=0,Priority=5,OnDepend=\\\"6\\\";#($Bandwidth >= 27500) && ($Bandwidth < 132958),AverageBandwidth=27500,Priority=9;#($Bandwidth >= 27500) && ($Bandwidth < 132958),AverageBandwidth=0,Priority=5,OnDepend=\\\"8\\\";#($Bandwidth >= 132958) && ($Bandwidth < 187958),AverageBandwidth=132958,Priority=9;#($Bandwidth >= 132958) && ($Bandwidth < 187958),AverageBandwidth=0,Priority=5,OnDepend=\\\"10\\\";#($Bandwidth >= 187958),AverageBandwidth=187958,Priority=9;#($Bandwidth >= 187958),AverageBandwidth=0,Priority=5,OnDepend=\\\"12\\\";"; - - vars = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (vars, (gchar *) "Bandwidth", (gchar *) "300000"); - - book = gst_asm_rule_book_new (rules1); - n = gst_asm_rule_book_match (book, vars, rulematch); - gst_asm_rule_book_free (book); - - g_print ("%d rules matched\n", n); - for (i = 0; i < n; i++) { - g_print ("rule %d matched\n", rulematch[i]); - } - - book = gst_asm_rule_book_new (rules2); - n = gst_asm_rule_book_match (book, vars, rulematch); - gst_asm_rule_book_free (book); - - g_print ("%d rules matched\n", n); - for (i = 0; i < n; i++) { - g_print ("rule %d matched\n", rulematch[i]); - } - - book = gst_asm_rule_book_new (rules3); - n = gst_asm_rule_book_match (book, vars, rulematch); - gst_asm_rule_book_free (book); - - - g_print ("%d rules matched\n", n); - for (i = 0; i < n; i++) { - g_print ("rule %d matched\n", rulematch[i]); - } - - g_hash_table_destroy (vars); - - return 0; -} -#endif diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/asmrules.h b/subprojects/gst-plugins-ugly/gst/realmedia/asmrules.h deleted file mode 100644 index 1f84f680f1..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/asmrules.h +++ /dev/null @@ -1,115 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_ASM_RULES_H__ -#define __GST_ASM_RULES_H__ - -#include - -G_BEGIN_DECLS - -#define MAX_RULEMATCHES 16 - -typedef struct _GstASMNode GstASMNode; -typedef struct _GstASMRule GstASMRule; -typedef struct _GstASMRuleBook GstASMRuleBook; - -typedef enum { - GST_ASM_TOKEN_NONE, - GST_ASM_TOKEN_EOF, - - GST_ASM_TOKEN_INT, - GST_ASM_TOKEN_FLOAT, - GST_ASM_TOKEN_IDENTIFIER, - GST_ASM_TOKEN_STRING, - - GST_ASM_TOKEN_HASH, - GST_ASM_TOKEN_SEMICOLON, - GST_ASM_TOKEN_COMMA, - GST_ASM_TOKEN_DOLLAR, - - GST_ASM_TOKEN_LPAREN, - GST_ASM_TOKEN_RPAREN, - - GST_ASM_TOKEN_GREATER, - GST_ASM_TOKEN_LESS, - GST_ASM_TOKEN_GREATEREQUAL, - GST_ASM_TOKEN_LESSEQUAL, - GST_ASM_TOKEN_EQUAL, - GST_ASM_TOKEN_NOTEQUAL, - - GST_ASM_TOKEN_AND, - GST_ASM_TOKEN_OR -} GstASMToken; - -typedef enum { - GST_ASM_NODE_UNKNOWN, - GST_ASM_NODE_VARIABLE, - GST_ASM_NODE_INTEGER, - GST_ASM_NODE_FLOAT, - GST_ASM_NODE_OPERATOR -} GstASMNodeType; - -typedef enum { - GST_ASM_OP_GREATER = GST_ASM_TOKEN_GREATER, - GST_ASM_OP_LESS = GST_ASM_TOKEN_LESS, - GST_ASM_OP_GREATEREQUAL = GST_ASM_TOKEN_GREATEREQUAL, - GST_ASM_OP_LESSEQUAL = GST_ASM_TOKEN_LESSEQUAL, - GST_ASM_OP_EQUAL = GST_ASM_TOKEN_EQUAL, - GST_ASM_OP_NOTEQUAL = GST_ASM_TOKEN_NOTEQUAL, - - GST_ASM_OP_AND = GST_ASM_TOKEN_AND, - GST_ASM_OP_OR = GST_ASM_TOKEN_OR -} GstASMOp; - -struct _GstASMNode { - GstASMNodeType type; - - union { - gchar *varname; - gint intval; - gfloat floatval; - GstASMOp optype; - } data; - - GstASMNode *left; - GstASMNode *right; -}; - -struct _GstASMRule { - GstASMNode *root; - GHashTable *props; -}; - -struct _GstASMRuleBook { - const gchar *rulebook; - - guint n_rules; - GList *rules; -}; - -G_END_DECLS - -GstASMRuleBook* gst_asm_rule_book_new (const gchar *rulebook); -void gst_asm_rule_book_free (GstASMRuleBook *book); - -gint gst_asm_rule_book_match (GstASMRuleBook *book, GHashTable *vars, - gint *rulematches); - -#endif /* __GST_ASM_RULES_H__ */ diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.c b/subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.c deleted file mode 100644 index 50bc7f438a..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.c +++ /dev/null @@ -1,477 +0,0 @@ -/* GStreamer - * Copyright (C) <2008> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#include - -#include "gstrdtbuffer.h" - -gboolean -gst_rdt_buffer_validate_data (guint8 * data, guint len) -{ - return TRUE; -} - -gboolean -gst_rdt_buffer_validate (GstBuffer * buffer) -{ - return TRUE; -} - -guint -gst_rdt_buffer_get_packet_count (GstBuffer * buffer) -{ - GstRDTPacket packet; - guint count; - - g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); - - count = 0; - if (gst_rdt_buffer_get_first_packet (buffer, &packet)) { - do { - count++; - } while (gst_rdt_packet_move_to_next (&packet)); - } - return count; -} - -static gboolean -read_packet_header (GstRDTPacket * packet) -{ - GstMapInfo map; - guint8 *data; - gsize size; - guint offset; - guint length; - guint length_offset; - - g_return_val_if_fail (packet != NULL, FALSE); - g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE); - - gst_buffer_map (packet->buffer, &map, GST_MAP_READ); - data = map.data; - size = map.size; - - offset = packet->offset; - - /* check if we are at the end of the buffer, we add 3 because we also want to - * ensure we can read the type, which is always at offset 1 and 2 bytes long. */ - if (offset + 3 > size) - goto packet_end; - - /* read type */ - packet->type = GST_READ_UINT16_BE (&data[offset + 1]); - - length = -1; - length_offset = -1; - - /* figure out the length of the packet, this depends on the type */ - if (GST_RDT_IS_DATA_TYPE (packet->type)) { - if (data[offset] & 0x80) - /* length is present */ - length_offset = 3; - } else { - switch (packet->type) { - case GST_RDT_TYPE_ASMACTION: - if (data[offset] & 0x80) - length_offset = 5; - break; - case GST_RDT_TYPE_BWREPORT: - if (data[offset] & 0x80) - length_offset = 3; - break; - case GST_RDT_TYPE_ACK: - if (data[offset] & 0x80) - length_offset = 3; - break; - case GST_RDT_TYPE_RTTREQ: - length = 3; - break; - case GST_RDT_TYPE_RTTRESP: - length = 11; - break; - case GST_RDT_TYPE_CONGESTION: - length = 11; - break; - case GST_RDT_TYPE_STREAMEND: - length = 9; - /* total_reliable */ - if (data[offset] & 0x80) - length += 2; - /* stream_id_expansion */ - if ((data[offset] & 0x7c) == 0x7c) - length += 2; - /* ext_flag, FIXME, get string length */ - if ((data[offset] & 0x1) == 0x1) - length += 7; - break; - case GST_RDT_TYPE_REPORT: - if (data[offset] & 0x80) - length_offset = 3; - break; - case GST_RDT_TYPE_LATENCY: - if (data[offset] & 0x80) - length_offset = 3; - break; - case GST_RDT_TYPE_INFOREQ: - length = 3; - /* request_time_ms */ - if (data[offset] & 0x2) - length += 2; - break; - case GST_RDT_TYPE_INFORESP: - length = 3; - /* has_rtt_info */ - if (data[offset] & 0x4) { - length += 4; - /* is_delayed */ - if (data[offset] & 0x2) { - length += 4; - } - } - if (data[offset] & 0x1) { - /* buffer_info_count, FIXME read and skip */ - length += 2; - } - break; - case GST_RDT_TYPE_AUTOBW: - if (data[offset] & 0x80) - length_offset = 3; - break; - case GST_RDT_TYPE_INVALID: - default: - goto unknown_packet; - } - } - - if (length != -1) { - /* we have a fixed length */ - packet->length = length; - } else if (length_offset != -1) { - /* we can read the length from an offset */ - packet->length = GST_READ_UINT16_BE (&data[length_offset]); - } else { - /* length is remainder of packet */ - packet->length = size - offset; - } - gst_buffer_unmap (packet->buffer, &map); - - /* the length should be smaller than the remaining size */ - if (packet->length + offset > size) - goto invalid_length; - - return TRUE; - - /* ERRORS */ -packet_end: - { - gst_buffer_unmap (packet->buffer, &map); - return FALSE; - } -unknown_packet: - { - packet->type = GST_RDT_TYPE_INVALID; - gst_buffer_unmap (packet->buffer, &map); - return FALSE; - } -invalid_length: - { - packet->type = GST_RDT_TYPE_INVALID; - packet->length = 0; - return FALSE; - } -} - -gboolean -gst_rdt_buffer_get_first_packet (GstBuffer * buffer, GstRDTPacket * packet) -{ - g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); - g_return_val_if_fail (packet != NULL, FALSE); - - /* init to 0 */ - packet->buffer = buffer; - packet->offset = 0; - packet->type = GST_RDT_TYPE_INVALID; - memset (&packet->map, 0, sizeof (GstMapInfo)); - - if (!read_packet_header (packet)) - return FALSE; - - return TRUE; -} - -gboolean -gst_rdt_packet_move_to_next (GstRDTPacket * packet) -{ - g_return_val_if_fail (packet != NULL, FALSE); - g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, FALSE); - g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE); - - /* if we have an invalid packet, it must be the last, - * return FALSE */ - if (packet->type == GST_RDT_TYPE_INVALID) - goto end; - - /* move to next packet */ - packet->offset += packet->length; - - /* try to read new header */ - if (!read_packet_header (packet)) - goto end; - - return TRUE; - - /* ERRORS */ -end: - { - packet->type = GST_RDT_TYPE_INVALID; - return FALSE; - } -} - -GstRDTType -gst_rdt_packet_get_type (GstRDTPacket * packet) -{ - g_return_val_if_fail (packet != NULL, GST_RDT_TYPE_INVALID); - g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, - GST_RDT_TYPE_INVALID); - - return packet->type; -} - -guint16 -gst_rdt_packet_get_length (GstRDTPacket * packet) -{ - g_return_val_if_fail (packet != NULL, 0); - g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, 0); - - return packet->length; -} - -GstBuffer * -gst_rdt_packet_to_buffer (GstRDTPacket * packet) -{ - GstBuffer *result; - - g_return_val_if_fail (packet != NULL, NULL); - g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, NULL); - - result = - gst_buffer_copy_region (packet->buffer, GST_BUFFER_COPY_ALL, - packet->offset, packet->length); - /* timestamp applies to all packets in this buffer */ - GST_BUFFER_TIMESTAMP (result) = GST_BUFFER_TIMESTAMP (packet->buffer); - - return result; -} - -gint -gst_rdt_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2) -{ - return (gint16) (seqnum2 - seqnum1); -} - -guint16 -gst_rdt_packet_data_get_seq (GstRDTPacket * packet) -{ - GstMapInfo map; - guint header; - guint16 result; - - g_return_val_if_fail (packet != NULL, FALSE); - g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE); - - gst_buffer_map (packet->buffer, &map, GST_MAP_READ); - - /* skip header bits */ - header = packet->offset + 1; - - /* read seq_no */ - result = GST_READ_UINT16_BE (&map.data[header]); - - gst_buffer_unmap (packet->buffer, &map); - - return result; -} - -guint8 * -gst_rdt_packet_data_map (GstRDTPacket * packet, guint * size) -{ - GstMapInfo map; - guint header; - gboolean length_included_flag; - gboolean need_reliable_flag; - guint8 stream_id; - guint8 asm_rule_number; - - g_return_val_if_fail (packet != NULL, NULL); - g_return_val_if_fail (packet->map.data == NULL, NULL); - g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), NULL); - - gst_buffer_map (packet->buffer, &map, GST_MAP_READ); - - header = packet->offset; - - length_included_flag = (map.data[header] & 0x80) == 0x80; - need_reliable_flag = (map.data[header] & 0x40) == 0x40; - stream_id = (map.data[header] & 0x3e) >> 1; - - /* skip seq_no and header bits */ - header += 3; - - if (length_included_flag) { - /* skip length */ - header += 2; - } - asm_rule_number = (map.data[header] & 0x3f); - - /* skip timestamp and asm_rule_number */ - header += 5; - - if (stream_id == 0x1f) { - /* skip stream_id_expansion */ - header += 2; - } - if (need_reliable_flag) { - /* skip total_reliable */ - header += 2; - } - if (asm_rule_number == 63) { - /* skip asm_rule_number_expansion */ - header += 2; - } - - if (size) - *size = packet->length - (header - packet->offset); - - packet->map = map; - - return &map.data[header]; -} - -gboolean -gst_rdt_packet_data_unmap (GstRDTPacket * packet) -{ - g_return_val_if_fail (packet != NULL, FALSE); - g_return_val_if_fail (packet->map.data != NULL, FALSE); - - gst_buffer_unmap (packet->buffer, &packet->map); - packet->map.data = NULL; - - return TRUE; -} - -guint16 -gst_rdt_packet_data_get_stream_id (GstRDTPacket * packet) -{ - GstMapInfo map; - guint16 result; - guint header; - gboolean length_included_flag; - - g_return_val_if_fail (packet != NULL, 0); - g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0); - - gst_buffer_map (packet->buffer, &map, GST_MAP_READ); - - header = packet->offset; - - length_included_flag = (map.data[header] & 0x80) == 0x80; - result = (map.data[header] & 0x3e) >> 1; - if (result == 31) { - /* skip seq_no and header bits */ - header += 3; - - if (length_included_flag) { - /* skip length */ - header += 2; - } - /* skip asm_rule_number and timestamp */ - header += 5; - - /* stream_id_expansion */ - result = GST_READ_UINT16_BE (&map.data[header]); - } - gst_buffer_unmap (packet->buffer, &map); - - return result; -} - -guint32 -gst_rdt_packet_data_get_timestamp (GstRDTPacket * packet) -{ - GstMapInfo map; - guint header; - gboolean length_included_flag; - guint32 result; - - g_return_val_if_fail (packet != NULL, 0); - g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0); - - gst_buffer_map (packet->buffer, &map, GST_MAP_READ); - - header = packet->offset; - - length_included_flag = (map.data[header] & 0x80) == 0x80; - - /* skip seq_no and header bits */ - header += 3; - - if (length_included_flag) { - /* skip length */ - header += 2; - } - /* skip asm_rule_number */ - header += 1; - - /* get timestamp */ - result = GST_READ_UINT32_BE (&map.data[header]); - gst_buffer_unmap (packet->buffer, &map); - - return result; -} - -guint8 -gst_rdt_packet_data_get_flags (GstRDTPacket * packet) -{ - GstMapInfo map; - guint8 result; - guint header; - gboolean length_included_flag; - - g_return_val_if_fail (packet != NULL, 0); - g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0); - - gst_buffer_map (packet->buffer, &map, GST_MAP_READ); - - header = packet->offset; - - length_included_flag = (map.data[header] & 0x80) == 0x80; - - /* skip seq_no and header bits */ - header += 3; - - if (length_included_flag) { - /* skip length */ - header += 2; - } - /* get flags */ - result = map.data[header]; - gst_buffer_unmap (packet->buffer, &map); - - return result; -} diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.h b/subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.h deleted file mode 100644 index fd1e067f83..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/gstrdtbuffer.h +++ /dev/null @@ -1,121 +0,0 @@ -/* GStreamer - * Copyright (C) <2008> Wim Taymans - * - * gstrdtbuffer.h: various helper functions to manipulate buffers - * with RDT payload. - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_RDTBUFFER_H__ -#define __GST_RDTBUFFER_H__ - -#include - -G_BEGIN_DECLS -/** - * GstRDTType: - * @GST_RDT_TYPE_INVALID: - * @GST_RDT_TYPE_ASMACTION: - * @GST_RDT_TYPE_ACK: - * @GST_RDT_TYPE_RTTREQ: - * @GST_RDT_TYPE_RTTRESP: - * @GST_RDT_TYPE_CONGESTION: - * @GST_RDT_TYPE_STREAMEND: - * @GST_RDT_TYPE_LATENCY: - * @GST_RDT_TYPE_INFOREQ: - * @GST_RDT_TYPE_INFORESP: - * @GST_RDT_TYPE_AUTOBW: - * - * Different RDT packet types. - */ -typedef enum -{ - GST_RDT_TYPE_INVALID = 0xffff, - GST_RDT_TYPE_ASMACTION = 0xff00, - GST_RDT_TYPE_BWREPORT = 0xff01, - GST_RDT_TYPE_ACK = 0xff02, - GST_RDT_TYPE_RTTREQ = 0xff03, - GST_RDT_TYPE_RTTRESP = 0xff04, - GST_RDT_TYPE_CONGESTION = 0xff05, - GST_RDT_TYPE_STREAMEND = 0xff06, - GST_RDT_TYPE_REPORT = 0xff07, - GST_RDT_TYPE_LATENCY = 0xff08, - GST_RDT_TYPE_INFOREQ = 0xff09, - GST_RDT_TYPE_INFORESP = 0xff0a, - GST_RDT_TYPE_AUTOBW = 0xff0b -} GstRDTType; - -/** - * GST_RDT_IS_DATA_TYPE: - * @t: the #GstRDTType to check - * - * Check if @t is a data packet type. - */ -#define GST_RDT_IS_DATA_TYPE(t) ((t) < 0xff00) - -typedef struct _GstRDTPacket GstRDTPacket; - -/** - * GstRDTPacket: - * @buffer: pointer to RDT buffer - * @offset: offset of packet in buffer data - * - * Data structure that points to a packet at @offset in @buffer. - * The size of the structure is made public to allow stack allocations. - */ -struct _GstRDTPacket -{ - GstBuffer *buffer; - guint offset; - - /*< private >*/ - GstRDTType type; /* type of current packet */ - guint16 length; /* length of current packet in bytes */ - GstMapInfo map; /* last mapped data */ -}; - -/* validate buffers */ -gboolean gst_rdt_buffer_validate_data (guint8 *data, guint len); -gboolean gst_rdt_buffer_validate (GstBuffer *buffer); - -/* retrieving packets */ -guint gst_rdt_buffer_get_packet_count (GstBuffer *buffer); -gboolean gst_rdt_buffer_get_first_packet (GstBuffer *buffer, GstRDTPacket *packet); -gboolean gst_rdt_packet_move_to_next (GstRDTPacket *packet); - -/* working with packets */ -GstRDTType gst_rdt_packet_get_type (GstRDTPacket *packet); -guint16 gst_rdt_packet_get_length (GstRDTPacket *packet); -GstBuffer* gst_rdt_packet_to_buffer (GstRDTPacket *packet); - - -/* data packets */ -guint16 gst_rdt_packet_data_get_seq (GstRDTPacket *packet); -guint8 * gst_rdt_packet_data_map (GstRDTPacket *packet, guint *size); -gboolean gst_rdt_packet_data_unmap (GstRDTPacket *packet); -guint16 gst_rdt_packet_data_get_stream_id (GstRDTPacket *packet); -guint32 gst_rdt_packet_data_get_timestamp (GstRDTPacket *packet); - -guint8 gst_rdt_packet_data_get_flags (GstRDTPacket * packet); - -/* utils */ -gint gst_rdt_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2); - -G_END_DECLS - -#endif /* __GST_RDTBUFFER_H__ */ - diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/meson.build b/subprojects/gst-plugins-ugly/gst/realmedia/meson.build index c4d4766c67..626ba88dfc 100644 --- a/subprojects/gst-plugins-ugly/gst/realmedia/meson.build +++ b/subprojects/gst-plugins-ugly/gst/realmedia/meson.build @@ -2,14 +2,6 @@ real_sources = [ 'rademux.c', 'rmdemux.c', 'rmutils.c', - 'rdtdepay.c', - 'rdtmanager.c', - 'rtspreal.c', - 'realhash.c', - 'asmrules.c', - 'rdtjitterbuffer.c', - 'gstrdtbuffer.c', - 'pnmsrc.c', 'realmedia.c' ] diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.c b/subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.c deleted file mode 100644 index f0612e742e..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.c +++ /dev/null @@ -1,496 +0,0 @@ -/* GStreamer - * Copyright (C) <2006> Lutz Mueller - * <2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "gstrdtbuffer.h" -#include "rdtdepay.h" - -GST_DEBUG_CATEGORY_STATIC (rdtdepay_debug); -#define GST_CAT_DEFAULT rdtdepay_debug - -/* RDTDepay signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, -}; - -static GstStaticPadTemplate gst_rdt_depay_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/vnd.rn-realmedia") - ); - -static GstStaticPadTemplate gst_rdt_depay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rdt, " - "media = (string) \"application\", " - "clock-rate = (int) [1, MAX ], " - "encoding-name = (string) \"X-REAL-RDT\"" - /* All optional parameters - * - * "config=" - */ - ) - ); - -#define gst_rdt_depay_parent_class parent_class -G_DEFINE_TYPE (GstRDTDepay, gst_rdt_depay, GST_TYPE_ELEMENT); -GST_ELEMENT_REGISTER_DEFINE (rdtdepay, "rdtdepay", - GST_RANK_MARGINAL, GST_TYPE_RDT_DEPAY); - -static void gst_rdt_depay_finalize (GObject * object); - -static GstStateChangeReturn gst_rdt_depay_change_state (GstElement * - element, GstStateChange transition); - -static gboolean gst_rdt_depay_sink_event (GstPad * pad, GstObject * parent, - GstEvent * event); -static GstFlowReturn gst_rdt_depay_chain (GstPad * pad, GstObject * parent, - GstBuffer * buf); - -static void -gst_rdt_depay_class_init (GstRDTDepayClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = gst_rdt_depay_finalize; - - gstelement_class->change_state = gst_rdt_depay_change_state; - - gst_element_class_add_static_pad_template (gstelement_class, - &gst_rdt_depay_src_template); - gst_element_class_add_static_pad_template (gstelement_class, - &gst_rdt_depay_sink_template); - - gst_element_class_set_static_metadata (gstelement_class, "RDT packet parser", - "Codec/Depayloader/Network", - "Extracts RealMedia from RDT packets", - "Lutz Mueller , " - "Wim Taymans "); - - GST_DEBUG_CATEGORY_INIT (rdtdepay_debug, "rdtdepay", - 0, "Depayloader for RDT RealMedia packets"); -} - -static void -gst_rdt_depay_init (GstRDTDepay * rdtdepay) -{ - rdtdepay->sinkpad = - gst_pad_new_from_static_template (&gst_rdt_depay_sink_template, "sink"); - gst_pad_set_chain_function (rdtdepay->sinkpad, gst_rdt_depay_chain); - gst_pad_set_event_function (rdtdepay->sinkpad, gst_rdt_depay_sink_event); - gst_element_add_pad (GST_ELEMENT_CAST (rdtdepay), rdtdepay->sinkpad); - - rdtdepay->srcpad = - gst_pad_new_from_static_template (&gst_rdt_depay_src_template, "src"); - gst_element_add_pad (GST_ELEMENT_CAST (rdtdepay), rdtdepay->srcpad); -} - -static void -gst_rdt_depay_finalize (GObject * object) -{ - GstRDTDepay *rdtdepay; - - rdtdepay = GST_RDT_DEPAY (object); - - if (rdtdepay->header) - gst_buffer_unref (rdtdepay->header); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -gst_rdt_depay_setcaps (GstPad * pad, GstCaps * caps) -{ - GstStructure *structure; - GstRDTDepay *rdtdepay; - GstCaps *srccaps; - gint clock_rate = 1000; /* default */ - const GValue *value; - GstBuffer *header; - - rdtdepay = GST_RDT_DEPAY (GST_PAD_PARENT (pad)); - - structure = gst_caps_get_structure (caps, 0); - - if (gst_structure_has_field (structure, "clock-rate")) - gst_structure_get_int (structure, "clock-rate", &clock_rate); - - /* config contains the RealMedia header as a buffer. */ - value = gst_structure_get_value (structure, "config"); - if (!value) - goto no_header; - - header = gst_value_get_buffer (value); - if (!header) - goto no_header; - - /* get other values for newsegment */ - value = gst_structure_get_value (structure, "npt-start"); - if (value && G_VALUE_HOLDS_UINT64 (value)) - rdtdepay->npt_start = g_value_get_uint64 (value); - else - rdtdepay->npt_start = 0; - GST_DEBUG_OBJECT (rdtdepay, "NPT start %" G_GUINT64_FORMAT, - rdtdepay->npt_start); - - value = gst_structure_get_value (structure, "npt-stop"); - if (value && G_VALUE_HOLDS_UINT64 (value)) - rdtdepay->npt_stop = g_value_get_uint64 (value); - else - rdtdepay->npt_stop = -1; - - GST_DEBUG_OBJECT (rdtdepay, "NPT stop %" G_GUINT64_FORMAT, - rdtdepay->npt_stop); - - value = gst_structure_get_value (structure, "play-speed"); - if (value && G_VALUE_HOLDS_DOUBLE (value)) - rdtdepay->play_speed = g_value_get_double (value); - else - rdtdepay->play_speed = 1.0; - - value = gst_structure_get_value (structure, "play-scale"); - if (value && G_VALUE_HOLDS_DOUBLE (value)) - rdtdepay->play_scale = g_value_get_double (value); - else - rdtdepay->play_scale = 1.0; - - /* caps seem good, configure element */ - rdtdepay->clock_rate = clock_rate; - - /* set caps on pad and on header */ - srccaps = gst_caps_new_empty_simple ("application/vnd.rn-realmedia"); - gst_pad_set_caps (rdtdepay->srcpad, srccaps); - gst_caps_unref (srccaps); - - if (rdtdepay->header) - gst_buffer_unref (rdtdepay->header); - rdtdepay->header = gst_buffer_ref (header); - - return TRUE; - - /* ERRORS */ -no_header: - { - GST_ERROR_OBJECT (rdtdepay, "no header found in caps, no 'config' field"); - return FALSE; - } -} - -static gboolean -gst_rdt_depay_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) -{ - GstRDTDepay *depay; - gboolean res = TRUE; - - depay = GST_RDT_DEPAY (parent); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_CAPS: - { - GstCaps *caps; - - gst_event_parse_caps (event, &caps); - res = gst_rdt_depay_setcaps (pad, caps); - gst_event_unref (event); - break; - } - case GST_EVENT_FLUSH_STOP: - res = gst_pad_push_event (depay->srcpad, event); - - gst_segment_init (&depay->segment, GST_FORMAT_UNDEFINED); - depay->need_newsegment = TRUE; - depay->next_seqnum = -1; - break; - case GST_EVENT_SEGMENT: - { - gst_event_copy_segment (event, &depay->segment); - /* don't pass the event downstream, we generate our own segment - * including the NTP time and other things we receive in caps */ - gst_event_unref (event); - break; - } - default: - /* pass other events forward */ - res = gst_pad_push_event (depay->srcpad, event); - break; - } - return res; -} - -static GstEvent * -create_segment_event (GstRDTDepay * depay, gboolean update, - GstClockTime position) -{ - GstSegment segment; - - gst_segment_init (&segment, GST_FORMAT_TIME); - segment.rate = depay->play_speed; - segment.applied_rate = depay->play_scale; - segment.start = position; - - if (depay->npt_stop != -1) - segment.stop = depay->npt_stop - depay->npt_start; - else - segment.stop = -1; - - segment.time = position + depay->npt_start; - - return gst_event_new_segment (&segment); -} - -static GstFlowReturn -gst_rdt_depay_push (GstRDTDepay * rdtdepay, GstBuffer * buffer) -{ - GstFlowReturn ret; - - if (rdtdepay->need_newsegment) { - GstEvent *event; - - event = create_segment_event (rdtdepay, FALSE, 0); - gst_pad_push_event (rdtdepay->srcpad, event); - - rdtdepay->need_newsegment = FALSE; - } - - if (rdtdepay->discont) { - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); - rdtdepay->discont = FALSE; - } - ret = gst_pad_push (rdtdepay->srcpad, buffer); - - return ret; -} - -static GstFlowReturn -gst_rdt_depay_handle_data (GstRDTDepay * rdtdepay, GstClockTime outtime, - GstRDTPacket * packet) -{ - GstFlowReturn ret; - GstBuffer *outbuf; - GstMapInfo outmap; - guint8 *data, *outdata; - guint size; - guint16 stream_id; - guint32 timestamp; - gint gap; - guint16 seqnum; - guint8 flags; - guint16 outflags; - - /* get pointers to the packet data */ - data = gst_rdt_packet_data_map (packet, &size); - - outbuf = gst_buffer_new_and_alloc (12 + size); - GST_BUFFER_TIMESTAMP (outbuf) = outtime; - - GST_DEBUG_OBJECT (rdtdepay, "have size %u", size); - - /* copy over some things */ - stream_id = gst_rdt_packet_data_get_stream_id (packet); - timestamp = gst_rdt_packet_data_get_timestamp (packet); - flags = gst_rdt_packet_data_get_flags (packet); - - seqnum = gst_rdt_packet_data_get_seq (packet); - - GST_DEBUG_OBJECT (rdtdepay, "stream_id %u, timestamp %u, seqnum %d, flags %d", - stream_id, timestamp, seqnum, flags); - - if (rdtdepay->next_seqnum != -1) { - gap = gst_rdt_buffer_compare_seqnum (seqnum, rdtdepay->next_seqnum); - - /* if we have no gap, all is fine */ - if (G_UNLIKELY (gap != 0)) { - GST_LOG_OBJECT (rdtdepay, "got packet %u, expected %u, gap %d", seqnum, - rdtdepay->next_seqnum, gap); - if (gap < 0) { - /* seqnum > next_seqnum, we are missing some packets, this is always a - * DISCONT. */ - GST_LOG_OBJECT (rdtdepay, "%d missing packets", gap); - rdtdepay->discont = TRUE; - } else { - /* seqnum < next_seqnum, we have seen this packet before or the sender - * could be restarted. If the packet is not too old, we throw it away as - * a duplicate, otherwise we mark discont and continue. 100 misordered - * packets is a good threshold. See also RFC 4737. */ - if (gap < 100) - goto dropping; - - GST_LOG_OBJECT (rdtdepay, - "%d > 100, packet too old, sender likely restarted", gap); - rdtdepay->discont = TRUE; - } - } - } - rdtdepay->next_seqnum = (seqnum + 1); - if (rdtdepay->next_seqnum == 0xff00) - rdtdepay->next_seqnum = 0; - - if ((flags & 1) == 0) - outflags = 2; - else - outflags = 0; - - gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE); - outdata = outmap.data; - GST_WRITE_UINT16_BE (outdata + 0, 0); /* version */ - GST_WRITE_UINT16_BE (outdata + 2, size + 12); /* length */ - GST_WRITE_UINT16_BE (outdata + 4, stream_id); /* stream */ - GST_WRITE_UINT32_BE (outdata + 6, timestamp); /* timestamp */ - GST_WRITE_UINT16_BE (outdata + 10, outflags); /* flags */ - memcpy (outdata + 12, data, size); - gst_buffer_unmap (outbuf, &outmap); - gst_buffer_resize (outbuf, 0, 12 + size); - - gst_rdt_packet_data_unmap (packet); - - GST_DEBUG_OBJECT (rdtdepay, "Pushing packet, outtime %" GST_TIME_FORMAT, - GST_TIME_ARGS (outtime)); - - ret = gst_rdt_depay_push (rdtdepay, outbuf); - - return ret; - - /* ERRORS */ -dropping: - { - GST_WARNING_OBJECT (rdtdepay, "%d <= 100, dropping old packet", gap); - return GST_FLOW_OK; - } -} - -static GstFlowReturn -gst_rdt_depay_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) -{ - GstRDTDepay *rdtdepay; - GstFlowReturn ret; - GstClockTime timestamp; - gboolean more; - GstRDTPacket packet; - - rdtdepay = GST_RDT_DEPAY (parent); - - if (GST_BUFFER_IS_DISCONT (buf)) { - GST_LOG_OBJECT (rdtdepay, "received discont"); - rdtdepay->discont = TRUE; - } - - if (rdtdepay->header) { - GstBuffer *out; - - out = rdtdepay->header; - rdtdepay->header = NULL; - - /* push header data first */ - gst_rdt_depay_push (rdtdepay, out); - } - - /* save timestamp */ - timestamp = GST_BUFFER_TIMESTAMP (buf); - - ret = GST_FLOW_OK; - - GST_LOG_OBJECT (rdtdepay, "received buffer timestamp %" GST_TIME_FORMAT, - GST_TIME_ARGS (timestamp)); - - /* data is in RDT format. */ - more = gst_rdt_buffer_get_first_packet (buf, &packet); - while (more) { - GstRDTType type; - - type = gst_rdt_packet_get_type (&packet); - GST_DEBUG_OBJECT (rdtdepay, "Have packet of type %04x", type); - - if (GST_RDT_IS_DATA_TYPE (type)) { - GST_DEBUG_OBJECT (rdtdepay, "We have a data packet"); - ret = gst_rdt_depay_handle_data (rdtdepay, timestamp, &packet); - } else { - switch (type) { - default: - GST_DEBUG_OBJECT (rdtdepay, "Ignoring packet"); - break; - } - } - if (ret != GST_FLOW_OK) - break; - - more = gst_rdt_packet_move_to_next (&packet); - } - - gst_buffer_unref (buf); - - return ret; -} - -static GstStateChangeReturn -gst_rdt_depay_change_state (GstElement * element, GstStateChange transition) -{ - GstRDTDepay *rdtdepay; - GstStateChangeReturn ret; - - rdtdepay = GST_RDT_DEPAY (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_segment_init (&rdtdepay->segment, GST_FORMAT_UNDEFINED); - rdtdepay->next_seqnum = -1; - rdtdepay->need_newsegment = TRUE; - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - if (rdtdepay->header) - gst_buffer_unref (rdtdepay->header); - rdtdepay->header = NULL; - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - return ret; -} diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.h b/subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.h deleted file mode 100644 index 8b208fcd9d..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rdtdepay.h +++ /dev/null @@ -1,74 +0,0 @@ -/* GStreamer - * Copyright (C) <2006> Lutz Mueller - * <2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_RDT_DEPAY_H__ -#define __GST_RDT_DEPAY_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_RDT_DEPAY \ - (gst_rdt_depay_get_type()) -#define GST_RDT_DEPAY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RDT_DEPAY,GstRDTDepay)) -#define GST_RDT_DEPAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RDT_DEPAY,GstRDTDepayClass)) -#define GST_IS_RDT_DEPAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RDT_DEPAY)) -#define GST_IS_RDT_DEPAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RDT_DEPAY)) - -typedef struct _GstRDTDepay GstRDTDepay; -typedef struct _GstRDTDepayClass GstRDTDepayClass; - -struct _GstRDTDepay -{ - GstElement parent; - - GstPad *sinkpad; - GstPad *srcpad; - - guint clock_rate; - GstClockTime npt_start; - GstClockTime npt_stop; - gdouble play_speed; - gdouble play_scale; - - guint32 next_seqnum; - - gboolean discont; - gboolean need_newsegment; - GstSegment segment; - GstBuffer *header; -}; - -struct _GstRDTDepayClass -{ - GstElementClass parent_class; -}; - -GType gst_rdt_depay_get_type (void); - -GST_ELEMENT_REGISTER_DECLARE (rdtdepay); - -G_END_DECLS - -#endif /* __GST_RDT_DEPAY_H__ */ diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.c b/subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.c deleted file mode 100644 index d0b8de06f6..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.c +++ /dev/null @@ -1,531 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#include -#include - -#include "rdtjitterbuffer.h" -#include "gstrdtbuffer.h" - -GST_DEBUG_CATEGORY_STATIC (rdt_jitter_buffer_debug); -#define GST_CAT_DEFAULT rdt_jitter_buffer_debug - -#define MAX_WINDOW RDT_JITTER_BUFFER_MAX_WINDOW -#define MAX_TIME (2 * GST_SECOND) - -/* signals and args */ -enum -{ - LAST_SIGNAL -}; - -enum -{ - PROP_0 -}; - -/* GObject vmethods */ -static void rdt_jitter_buffer_finalize (GObject * object); - -/* static guint rdt_jitter_buffer_signals[LAST_SIGNAL] = { 0 }; */ - -G_DEFINE_TYPE (RDTJitterBuffer, rdt_jitter_buffer, G_TYPE_OBJECT); - -static void -rdt_jitter_buffer_class_init (RDTJitterBufferClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - gobject_class->finalize = rdt_jitter_buffer_finalize; - - GST_DEBUG_CATEGORY_INIT (rdt_jitter_buffer_debug, "rdtjitterbuffer", 0, - "RDT Jitter Buffer"); -} - -static void -rdt_jitter_buffer_init (RDTJitterBuffer * jbuf) -{ - jbuf->packets = g_queue_new (); - - rdt_jitter_buffer_reset_skew (jbuf); -} - -static void -rdt_jitter_buffer_finalize (GObject * object) -{ - RDTJitterBuffer *jbuf; - - jbuf = RDT_JITTER_BUFFER_CAST (object); - - rdt_jitter_buffer_flush (jbuf); - g_queue_free (jbuf->packets); - - G_OBJECT_CLASS (rdt_jitter_buffer_parent_class)->finalize (object); -} - -/** - * rdt_jitter_buffer_new: - * - * Create an #RDTJitterBuffer. - * - * Returns: a new #RDTJitterBuffer. Use g_object_unref() after usage. - */ -RDTJitterBuffer * -rdt_jitter_buffer_new (void) -{ - RDTJitterBuffer *jbuf; - - jbuf = g_object_new (RDT_TYPE_JITTER_BUFFER, NULL); - - return jbuf; -} - -void -rdt_jitter_buffer_reset_skew (RDTJitterBuffer * jbuf) -{ - jbuf->base_time = -1; - jbuf->base_rtptime = -1; - jbuf->ext_rtptime = -1; - jbuf->window_pos = 0; - jbuf->window_filling = TRUE; - jbuf->window_min = 0; - jbuf->skew = 0; - jbuf->prev_send_diff = -1; -} - -/* For the clock skew we use a windowed low point averaging algorithm as can be - * found in http://www.grame.fr/pub/TR-050601.pdf. The idea is that the jitter is - * composed of: - * - * J = N + n - * - * N : a constant network delay. - * n : random added noise. The noise is concentrated around 0 - * - * In the receiver we can track the elapsed time at the sender with: - * - * send_diff(i) = (Tsi - Ts0); - * - * Tsi : The time at the sender at packet i - * Ts0 : The time at the sender at the first packet - * - * This is the difference between the RDT timestamp in the first received packet - * and the current packet. - * - * At the receiver we have to deal with the jitter introduced by the network. - * - * recv_diff(i) = (Tri - Tr0) - * - * Tri : The time at the receiver at packet i - * Tr0 : The time at the receiver at the first packet - * - * Both of these values contain a jitter Ji, a jitter for packet i, so we can - * write: - * - * recv_diff(i) = (Cri + D + ni) - (Cr0 + D + n0)) - * - * Cri : The time of the clock at the receiver for packet i - * D + ni : The jitter when receiving packet i - * - * We see that the network delay is irrelevant here as we can eliminate D: - * - * recv_diff(i) = (Cri + ni) - (Cr0 + n0)) - * - * The drift is now expressed as: - * - * Drift(i) = recv_diff(i) - send_diff(i); - * - * We now keep the W latest values of Drift and find the minimum (this is the - * one with the lowest network jitter and thus the one which is least affected - * by it). We average this lowest value to smooth out the resulting network skew. - * - * Both the window and the weighting used for averaging influence the accuracy - * of the drift estimation. Finding the correct parameters turns out to be a - * compromise between accuracy and inertia. - * - * We use a 2 second window or up to 512 data points, which is statistically big - * enough to catch spikes (FIXME, detect spikes). - * We also use a rather large weighting factor (125) to smoothly adapt. During - * startup, when filling the window, we use a parabolic weighting factor, the - * more the window is filled, the faster we move to the detected possible skew. - * - * Returns: @time adjusted with the clock skew. - */ -static GstClockTime -calculate_skew (RDTJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, - guint32 clock_rate) -{ - guint64 ext_rtptime; - guint64 send_diff, recv_diff; - gint64 delta; - gint64 old; - gint pos, i; - GstClockTime gstrtptime, out_time; - - //ext_rtptime = gst_rtp_buffer_ext_timestamp (&jbuf->ext_rtptime, rtptime); - ext_rtptime = rtptime; - - gstrtptime = gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, clock_rate); - -again: - /* first time, lock on to time and gstrtptime */ - if (jbuf->base_time == -1) - jbuf->base_time = time; - if (jbuf->base_rtptime == -1) - jbuf->base_rtptime = gstrtptime; - - if (gstrtptime >= jbuf->base_rtptime) - send_diff = gstrtptime - jbuf->base_rtptime; - else { - /* elapsed time at sender, timestamps can go backwards and thus be smaller - * than our base time, take a new base time in that case. */ - GST_DEBUG ("backward timestamps at server, taking new base time"); - jbuf->base_rtptime = gstrtptime; - jbuf->base_time = time; - send_diff = 0; - } - - GST_DEBUG ("extrtp %" G_GUINT64_FORMAT ", gstrtp %" GST_TIME_FORMAT ", base %" - GST_TIME_FORMAT ", send_diff %" GST_TIME_FORMAT, ext_rtptime, - GST_TIME_ARGS (gstrtptime), GST_TIME_ARGS (jbuf->base_rtptime), - GST_TIME_ARGS (send_diff)); - - if (jbuf->prev_send_diff != -1 && time != -1) { - gint64 delta_diff; - - if (send_diff > jbuf->prev_send_diff) - delta_diff = send_diff - jbuf->prev_send_diff; - else - delta_diff = jbuf->prev_send_diff - send_diff; - - /* server changed rtp timestamps too quickly, reset skew detection and start - * again. This value is sortof arbitrary and can be a bad measurement up if - * there are many packets missing because then we get a big gap that is - * unrelated to a timestamp switch. */ - if (delta_diff > GST_SECOND) { - GST_DEBUG ("delta changed too quickly %" GST_TIME_FORMAT " reset skew", - GST_TIME_ARGS (delta_diff)); - rdt_jitter_buffer_reset_skew (jbuf); - goto again; - } - } - jbuf->prev_send_diff = send_diff; - - /* we don't have an arrival timestamp so we can't do skew detection. we - * should still apply a timestamp based on RDT timestamp and base_time */ - if (time == -1) - goto no_skew; - - /* elapsed time at receiver, includes the jitter */ - recv_diff = time - jbuf->base_time; - - GST_DEBUG ("time %" GST_TIME_FORMAT ", base %" GST_TIME_FORMAT ", recv_diff %" - GST_TIME_FORMAT, GST_TIME_ARGS (time), GST_TIME_ARGS (jbuf->base_time), - GST_TIME_ARGS (recv_diff)); - - /* measure the diff */ - delta = ((gint64) recv_diff) - ((gint64) send_diff); - - pos = jbuf->window_pos; - - if (jbuf->window_filling) { - /* we are filling the window */ - GST_DEBUG ("filling %d, delta %" G_GINT64_FORMAT, pos, delta); - jbuf->window[pos++] = delta; - /* calc the min delta we observed */ - if (pos == 1 || delta < jbuf->window_min) - jbuf->window_min = delta; - - if (send_diff >= MAX_TIME || pos >= MAX_WINDOW) { - jbuf->window_size = pos; - - /* window filled */ - GST_DEBUG ("min %" G_GINT64_FORMAT, jbuf->window_min); - - /* the skew is now the min */ - jbuf->skew = jbuf->window_min; - jbuf->window_filling = FALSE; - } else { - gint perc_time, perc_window, perc; - - /* figure out how much we filled the window, this depends on the amount of - * time we have or the max number of points we keep. */ - perc_time = send_diff * 100 / MAX_TIME; - perc_window = pos * 100 / MAX_WINDOW; - perc = MAX (perc_time, perc_window); - - /* make a parabolic function, the closer we get to the MAX, the more value - * we give to the scaling factor of the new value */ - perc = perc * perc; - - /* quickly go to the min value when we are filling up, slowly when we are - * just starting because we're not sure it's a good value yet. */ - jbuf->skew = - (perc * jbuf->window_min + ((10000 - perc) * jbuf->skew)) / 10000; - jbuf->window_size = pos + 1; - } - } else { - /* pick old value and store new value. We keep the previous value in order - * to quickly check if the min of the window changed */ - old = jbuf->window[pos]; - jbuf->window[pos++] = delta; - - if (delta <= jbuf->window_min) { - /* if the new value we inserted is smaller or equal to the current min, - * it becomes the new min */ - jbuf->window_min = delta; - } else if (old == jbuf->window_min) { - gint64 min = G_MAXINT64; - - /* if we removed the old min, we have to find a new min */ - for (i = 0; i < jbuf->window_size; i++) { - /* we found another value equal to the old min, we can stop searching now */ - if (jbuf->window[i] == old) { - min = old; - break; - } - if (jbuf->window[i] < min) - min = jbuf->window[i]; - } - jbuf->window_min = min; - } - /* average the min values */ - jbuf->skew = (jbuf->window_min + (124 * jbuf->skew)) / 125; - GST_DEBUG ("delta %" G_GINT64_FORMAT ", new min: %" G_GINT64_FORMAT, - delta, jbuf->window_min); - } - /* wrap around in the window */ - if (pos >= jbuf->window_size) - pos = 0; - jbuf->window_pos = pos; - -no_skew: - /* the output time is defined as the base timestamp plus the RDT time - * adjusted for the clock skew .*/ - out_time = jbuf->base_time + send_diff + jbuf->skew; - - GST_DEBUG ("skew %" G_GINT64_FORMAT ", out %" GST_TIME_FORMAT, - jbuf->skew, GST_TIME_ARGS (out_time)); - - return out_time; -} - -/** - * rdt_jitter_buffer_insert: - * @jbuf: an #RDTJitterBuffer - * @buf: a buffer - * @time: a running_time when this buffer was received in nanoseconds - * @clock_rate: the clock-rate of the payload of @buf - * @tail: TRUE when the tail element changed. - * - * Inserts @buf into the packet queue of @jbuf. The sequence number of the - * packet will be used to sort the packets. This function takes ownerhip of - * @buf when the function returns %TRUE. - * @buf should have writable metadata when calling this function. - * - * Returns: %FALSE if a packet with the same number already existed. - */ -gboolean -rdt_jitter_buffer_insert (RDTJitterBuffer * jbuf, GstBuffer * buf, - GstClockTime time, guint32 clock_rate, gboolean * tail) -{ - GList *list; - guint32 rtptime; - guint16 seqnum; - GstRDTPacket packet; - gboolean more; - - g_return_val_if_fail (jbuf != NULL, FALSE); - g_return_val_if_fail (buf != NULL, FALSE); - - more = gst_rdt_buffer_get_first_packet (buf, &packet); - /* programmer error */ - g_return_val_if_fail (more == TRUE, FALSE); - - seqnum = gst_rdt_packet_data_get_seq (&packet); - /* do skew calculation by measuring the difference between rtptime and the - * receive time, this function will retimestamp @buf with the skew corrected - * running time. */ - rtptime = gst_rdt_packet_data_get_timestamp (&packet); - - /* loop the list to skip strictly smaller seqnum buffers */ - for (list = jbuf->packets->head; list; list = g_list_next (list)) { - guint16 qseq; - gint gap; - - more = - gst_rdt_buffer_get_first_packet (GST_BUFFER_CAST (list->data), &packet); - /* programmer error */ - g_return_val_if_fail (more == TRUE, FALSE); - - qseq = gst_rdt_packet_data_get_seq (&packet); - - /* compare the new seqnum to the one in the buffer */ - gap = gst_rdt_buffer_compare_seqnum (seqnum, qseq); - - /* we hit a packet with the same seqnum, notify a duplicate */ - if (G_UNLIKELY (gap == 0)) - goto duplicate; - - /* seqnum > qseq, we can stop looking */ - if (G_LIKELY (gap < 0)) - break; - } - - - if (clock_rate) { - time = calculate_skew (jbuf, rtptime, time, clock_rate); - GST_BUFFER_TIMESTAMP (buf) = time; - } - - if (list) - g_queue_insert_before (jbuf->packets, list, buf); - else - g_queue_push_tail (jbuf->packets, buf); - - /* tail was changed when we did not find a previous packet, we set the return - * flag when requested. */ - if (tail) - *tail = (list == NULL); - - return TRUE; - - /* ERRORS */ -duplicate: - { - GST_WARNING ("duplicate packet %d found", (gint) seqnum); - return FALSE; - } -} - -/** - * rdt_jitter_buffer_pop: - * @jbuf: an #RDTJitterBuffer - * - * Pops the oldest buffer from the packet queue of @jbuf. The popped buffer will - * have its timestamp adjusted with the incoming running_time and the detected - * clock skew. - * - * Returns: a #GstBuffer or %NULL when there was no packet in the queue. - */ -GstBuffer * -rdt_jitter_buffer_pop (RDTJitterBuffer * jbuf) -{ - GstBuffer *buf; - - g_return_val_if_fail (jbuf != NULL, FALSE); - - buf = g_queue_pop_tail (jbuf->packets); - - return buf; -} - -/** - * rdt_jitter_buffer_peek: - * @jbuf: an #RDTJitterBuffer - * - * Peek the oldest buffer from the packet queue of @jbuf. Register a callback - * with rdt_jitter_buffer_set_tail_changed() to be notified when an older packet - * was inserted in the queue. - * - * Returns: a #GstBuffer or %NULL when there was no packet in the queue. - */ -GstBuffer * -rdt_jitter_buffer_peek (RDTJitterBuffer * jbuf) -{ - GstBuffer *buf; - - g_return_val_if_fail (jbuf != NULL, FALSE); - - buf = g_queue_peek_tail (jbuf->packets); - - return buf; -} - -/** - * rdt_jitter_buffer_flush: - * @jbuf: an #RDTJitterBuffer - * - * Flush all packets from the jitterbuffer. - */ -void -rdt_jitter_buffer_flush (RDTJitterBuffer * jbuf) -{ - GstBuffer *buffer; - - g_return_if_fail (jbuf != NULL); - - while ((buffer = g_queue_pop_head (jbuf->packets))) - gst_buffer_unref (buffer); -} - -/** - * rdt_jitter_buffer_num_packets: - * @jbuf: an #RDTJitterBuffer - * - * Get the number of packets currently in "jbuf. - * - * Returns: The number of packets in @jbuf. - */ -guint -rdt_jitter_buffer_num_packets (RDTJitterBuffer * jbuf) -{ - g_return_val_if_fail (jbuf != NULL, 0); - - return jbuf->packets->length; -} - -/** - * rdt_jitter_buffer_get_ts_diff: - * @jbuf: an #RDTJitterBuffer - * - * Get the difference between the timestamps of first and last packet in the - * jitterbuffer. - * - * Returns: The difference expressed in the timestamp units of the packets. - */ -guint32 -rdt_jitter_buffer_get_ts_diff (RDTJitterBuffer * jbuf) -{ - guint64 high_ts, low_ts; - GstBuffer *high_buf, *low_buf; - guint32 result; - - g_return_val_if_fail (jbuf != NULL, 0); - - high_buf = g_queue_peek_head (jbuf->packets); - low_buf = g_queue_peek_tail (jbuf->packets); - - if (!high_buf || !low_buf || high_buf == low_buf) - return 0; - - //high_ts = gst_rtp_buffer_get_timestamp (high_buf); - //low_ts = gst_rtp_buffer_get_timestamp (low_buf); - high_ts = 0; - low_ts = 0; - - /* it needs to work if ts wraps */ - if (high_ts >= low_ts) { - result = (guint32) (high_ts - low_ts); - } else { - result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts); - } - return result; -} diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.h b/subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.h deleted file mode 100644 index 7eea5e6390..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rdtjitterbuffer.h +++ /dev/null @@ -1,91 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __RDT_JITTER_BUFFER_H__ -#define __RDT_JITTER_BUFFER_H__ - -#include - -typedef struct _RDTJitterBuffer RDTJitterBuffer; -typedef struct _RDTJitterBufferClass RDTJitterBufferClass; - -#define RDT_TYPE_JITTER_BUFFER (rdt_jitter_buffer_get_type()) -#define RDT_JITTER_BUFFER(src) (G_TYPE_CHECK_INSTANCE_CAST((src),RDT_TYPE_JITTER_BUFFER,RDTJitterBuffer)) -#define RDT_JITTER_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),RDT_TYPE_JITTER_BUFFER,RDTJitterBufferClass)) -#define RDT_IS_JITTER_BUFFER(src) (G_TYPE_CHECK_INSTANCE_TYPE((src),RDT_TYPE_JITTER_BUFFER)) -#define RDT_IS_JITTER_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),RDT_TYPE_JITTER_BUFFER)) -#define RDT_JITTER_BUFFER_CAST(src) ((RDTJitterBuffer *)(src)) - -/** - * RTPTailChanged: - * @jbuf: an #RDTJitterBuffer - * @user_data: user data specified when registering - * - * This callback will be called when the tail buffer of @jbuf changed. - */ -typedef void (*RTPTailChanged) (RDTJitterBuffer *jbuf, gpointer user_data); - -#define RDT_JITTER_BUFFER_MAX_WINDOW 512 -/** - * RDTJitterBuffer: - * - * A JitterBuffer in the #RTPSession - */ -struct _RDTJitterBuffer { - GObject object; - - GQueue *packets; - - /* for calculating skew */ - GstClockTime base_time; - GstClockTime base_rtptime; - guint64 ext_rtptime; - gint64 window[RDT_JITTER_BUFFER_MAX_WINDOW]; - guint window_pos; - guint window_size; - gboolean window_filling; - gint64 window_min; - gint64 skew; - gint64 prev_send_diff; -}; - -struct _RDTJitterBufferClass { - GObjectClass parent_class; -}; - -GType rdt_jitter_buffer_get_type (void); - -/* managing lifetime */ -RDTJitterBuffer* rdt_jitter_buffer_new (void); - -void rdt_jitter_buffer_reset_skew (RDTJitterBuffer *jbuf); - -gboolean rdt_jitter_buffer_insert (RDTJitterBuffer *jbuf, GstBuffer *buf, - GstClockTime time, - guint32 clock_rate, - gboolean *tail); -GstBuffer * rdt_jitter_buffer_peek (RDTJitterBuffer *jbuf); -GstBuffer * rdt_jitter_buffer_pop (RDTJitterBuffer *jbuf); - -void rdt_jitter_buffer_flush (RDTJitterBuffer *jbuf); - -guint rdt_jitter_buffer_num_packets (RDTJitterBuffer *jbuf); -guint32 rdt_jitter_buffer_get_ts_diff (RDTJitterBuffer *jbuf); - -#endif /* __RDT_JITTER_BUFFER_H__ */ diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.c b/subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.c deleted file mode 100644 index 978bc9ee92..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.c +++ /dev/null @@ -1,1371 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * <2013> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -/* - * Unless otherwise indicated, Source Code is licensed under MIT license. - * See further explanation attached in License Statement (distributed in the file - * LICENSE). - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* Element-Checklist-Version: 5 */ - -/** - * SECTION:element-rdtmanager - * @title: rdtmanager - * @see_also: GstRtspSrc - * - * A simple RTP session manager used internally by rtspsrc. - */ - -/* #define HAVE_RTCP */ - -#include "gstrdtbuffer.h" -#include "rdtmanager.h" -#include "rdtjitterbuffer.h" - -#include - -#include - -GST_DEBUG_CATEGORY_STATIC (rdtmanager_debug); -#define GST_CAT_DEFAULT (rdtmanager_debug) - -/* GstRDTManager signals and args */ -enum -{ - SIGNAL_REQUEST_PT_MAP, - SIGNAL_CLEAR_PT_MAP, - - SIGNAL_ON_NEW_SSRC, - SIGNAL_ON_SSRC_COLLISION, - SIGNAL_ON_SSRC_VALIDATED, - SIGNAL_ON_SSRC_ACTIVE, - SIGNAL_ON_SSRC_SDES, - SIGNAL_ON_BYE_SSRC, - SIGNAL_ON_BYE_TIMEOUT, - SIGNAL_ON_TIMEOUT, - SIGNAL_ON_NPT_STOP, - LAST_SIGNAL -}; - -#define DEFAULT_LATENCY_MS 200 - -enum -{ - PROP_0, - PROP_LATENCY -}; - -static GstStaticPadTemplate gst_rdt_manager_recv_rtp_sink_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink_%u", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rdt") - ); - -static GstStaticPadTemplate gst_rdt_manager_recv_rtcp_sink_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtcp_sink_%u", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate gst_rdt_manager_recv_rtp_src_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtp_src_%u_%u_%u", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rdt") - ); - -static GstStaticPadTemplate gst_rdt_manager_rtcp_src_template = -GST_STATIC_PAD_TEMPLATE ("rtcp_src_%u", - GST_PAD_SRC, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static void gst_rdt_manager_finalize (GObject * object); -static void gst_rdt_manager_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_rdt_manager_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -static gboolean gst_rdt_manager_query_src (GstPad * pad, GstObject * parent, - GstQuery * query); -static gboolean gst_rdt_manager_src_activate_mode (GstPad * pad, - GstObject * parent, GstPadMode mode, gboolean active); - -static GstClock *gst_rdt_manager_provide_clock (GstElement * element); -static GstStateChangeReturn gst_rdt_manager_change_state (GstElement * element, - GstStateChange transition); -static GstPad *gst_rdt_manager_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name, const GstCaps * caps); -static void gst_rdt_manager_release_pad (GstElement * element, GstPad * pad); - -static gboolean gst_rdt_manager_parse_caps (GstRDTManager * rdtmanager, - GstRDTManagerSession * session, GstCaps * caps); -static gboolean gst_rdt_manager_event_rdt (GstPad * pad, GstObject * parent, - GstEvent * event); - -static GstFlowReturn gst_rdt_manager_chain_rdt (GstPad * pad, - GstObject * parent, GstBuffer * buffer); -static GstFlowReturn gst_rdt_manager_chain_rtcp (GstPad * pad, - GstObject * parent, GstBuffer * buffer); -static void gst_rdt_manager_loop (GstPad * pad); - -static guint gst_rdt_manager_signals[LAST_SIGNAL] = { 0 }; - -#define JBUF_LOCK(sess) (g_mutex_lock (&(sess)->jbuf_lock)) - -#define JBUF_LOCK_CHECK(sess,label) G_STMT_START { \ - JBUF_LOCK (sess); \ - if (sess->srcresult != GST_FLOW_OK) \ - goto label; \ -} G_STMT_END - -#define JBUF_UNLOCK(sess) (g_mutex_unlock (&(sess)->jbuf_lock)) -#define JBUF_WAIT(sess) (g_cond_wait (&(sess)->jbuf_cond, &(sess)->jbuf_lock)) - -#define JBUF_WAIT_CHECK(sess,label) G_STMT_START { \ - JBUF_WAIT(sess); \ - if (sess->srcresult != GST_FLOW_OK) \ - goto label; \ -} G_STMT_END - -#define JBUF_SIGNAL(sess) (g_cond_signal (&(sess)->jbuf_cond)) - -/* Manages the receiving end of the packets. - * - * There is one such structure for each RTP session (audio/video/...). - * We get the RTP/RTCP packets and stuff them into the session manager. - */ -struct _GstRDTManagerSession -{ - /* session id */ - gint id; - /* the parent bin */ - GstRDTManager *dec; - - gboolean active; - /* we only support one ssrc and one pt */ - guint32 ssrc; - guint8 pt; - gint clock_rate; - GstCaps *caps; - gint64 clock_base; - - GstSegment segment; - - /* the last seqnum we pushed out */ - guint32 last_popped_seqnum; - /* the next expected seqnum */ - guint32 next_seqnum; - /* last output time */ - GstClockTime last_out_time; - - /* the pads of the session */ - GstPad *recv_rtp_sink; - GstPad *recv_rtp_src; - GstPad *recv_rtcp_sink; - GstPad *rtcp_src; - - GstFlowReturn srcresult; - gboolean blocked; - gboolean eos; - gboolean waiting; - gboolean discont; - GstClockID clock_id; - - /* jitterbuffer, lock and cond */ - RDTJitterBuffer *jbuf; - GMutex jbuf_lock; - GCond jbuf_cond; - - /* some accounting */ - guint64 num_late; - guint64 num_duplicates; -}; - -/* find a session with the given id */ -static GstRDTManagerSession * -find_session_by_id (GstRDTManager * rdtmanager, gint id) -{ - GSList *walk; - - for (walk = rdtmanager->sessions; walk; walk = g_slist_next (walk)) { - GstRDTManagerSession *sess = (GstRDTManagerSession *) walk->data; - - if (sess->id == id) - return sess; - } - return NULL; -} - -/* create a session with the given id */ -static GstRDTManagerSession * -create_session (GstRDTManager * rdtmanager, gint id) -{ - GstRDTManagerSession *sess; - - sess = g_new0 (GstRDTManagerSession, 1); - sess->id = id; - sess->dec = rdtmanager; - sess->jbuf = rdt_jitter_buffer_new (); - g_mutex_init (&sess->jbuf_lock); - g_cond_init (&sess->jbuf_cond); - rdtmanager->sessions = g_slist_prepend (rdtmanager->sessions, sess); - - return sess; -} - -static gboolean -forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data) -{ - GstPad *srcpad = GST_PAD_CAST (user_data); - - gst_pad_push_event (srcpad, gst_event_ref (*event)); - - return TRUE; -} - -static gboolean -activate_session (GstRDTManager * rdtmanager, GstRDTManagerSession * session, - guint32 ssrc, guint8 pt) -{ - GstPadTemplate *templ; - GstElementClass *klass; - gchar *name; - GstCaps *caps; - GValue ret = { 0 }; - GValue args[3] = { {0} - , {0} - , {0} - }; - - GST_DEBUG_OBJECT (rdtmanager, "creating stream"); - - session->ssrc = ssrc; - session->pt = pt; - - /* get pt map */ - g_value_init (&args[0], GST_TYPE_ELEMENT); - g_value_set_object (&args[0], rdtmanager); - g_value_init (&args[1], G_TYPE_UINT); - g_value_set_uint (&args[1], session->id); - g_value_init (&args[2], G_TYPE_UINT); - g_value_set_uint (&args[2], pt); - - g_value_init (&ret, GST_TYPE_CAPS); - g_value_set_boxed (&ret, NULL); - - g_signal_emitv (args, gst_rdt_manager_signals[SIGNAL_REQUEST_PT_MAP], 0, - &ret); - - g_value_unset (&args[0]); - g_value_unset (&args[1]); - g_value_unset (&args[2]); - caps = (GstCaps *) g_value_dup_boxed (&ret); - g_value_unset (&ret); - - if (caps) - gst_rdt_manager_parse_caps (rdtmanager, session, caps); - - name = g_strdup_printf ("recv_rtp_src_%u_%u_%u", session->id, ssrc, pt); - klass = GST_ELEMENT_GET_CLASS (rdtmanager); - templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u"); - session->recv_rtp_src = gst_pad_new_from_template (templ, name); - g_free (name); - - gst_pad_set_element_private (session->recv_rtp_src, session); - gst_pad_set_query_function (session->recv_rtp_src, gst_rdt_manager_query_src); - gst_pad_set_activatemode_function (session->recv_rtp_src, - gst_rdt_manager_src_activate_mode); - - gst_pad_set_active (session->recv_rtp_src, TRUE); - - gst_pad_sticky_events_foreach (session->recv_rtp_sink, forward_sticky_events, - session->recv_rtp_src); - gst_pad_set_caps (session->recv_rtp_src, caps); - gst_caps_unref (caps); - - gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtp_src); - - return TRUE; -} - -static void -free_session (GstRDTManagerSession * session) -{ - g_object_unref (session->jbuf); - g_cond_clear (&session->jbuf_cond); - g_mutex_clear (&session->jbuf_lock); - g_free (session); -} - -#define gst_rdt_manager_parent_class parent_class -G_DEFINE_TYPE (GstRDTManager, gst_rdt_manager, GST_TYPE_ELEMENT); -GST_ELEMENT_REGISTER_DEFINE (rdtmanager, "rdtmanager", - GST_RANK_NONE, GST_TYPE_RDT_MANAGER); - -/* BOXED:UINT,UINT */ -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) - -static void -gst_rdt_manager_marshal_BOXED__UINT_UINT (GClosure * closure, - GValue * return_value, - guint n_param_values, - const GValue * param_values, - gpointer invocation_hint, gpointer marshal_data) -{ - typedef gpointer (*GMarshalFunc_BOXED__UINT_UINT) (gpointer data1, - guint arg_1, guint arg_2, gpointer data2); - register GMarshalFunc_BOXED__UINT_UINT callback; - register GCClosure *cc = (GCClosure *) closure; - register gpointer data1, data2; - gpointer v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } else { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = - (GMarshalFunc_BOXED__UINT_UINT) (marshal_data ? marshal_data : - cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), data2); - - g_value_take_boxed (return_value, v_return); -} - -static void -gst_rdt_manager_marshal_VOID__UINT_UINT (GClosure * closure, - GValue * return_value, - guint n_param_values, - const GValue * param_values, - gpointer invocation_hint, gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1, - guint arg_1, guint arg_2, gpointer data2); - register GMarshalFunc_VOID__UINT_UINT callback; - register GCClosure *cc = (GCClosure *) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } else { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = - (GMarshalFunc_VOID__UINT_UINT) (marshal_data ? marshal_data : - cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), data2); -} - -static void -gst_rdt_manager_class_init (GstRDTManagerClass * g_class) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstRDTManagerClass *klass; - - klass = (GstRDTManagerClass *) g_class; - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = gst_rdt_manager_finalize; - gobject_class->set_property = gst_rdt_manager_set_property; - gobject_class->get_property = gst_rdt_manager_get_property; - - g_object_class_install_property (gobject_class, PROP_LATENCY, - g_param_spec_uint ("latency", "Buffer latency in ms", - "Amount of ms to buffer", 0, G_MAXUINT, DEFAULT_LATENCY_MS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstRDTManager::request-pt-map: - * @rdtmanager: the object which received the signal - * @session: the session - * @pt: the pt - * - * Request the payload type as #GstCaps for @pt in @session. - */ - gst_rdt_manager_signals[SIGNAL_REQUEST_PT_MAP] = - g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRDTManagerClass, request_pt_map), - NULL, NULL, gst_rdt_manager_marshal_BOXED__UINT_UINT, GST_TYPE_CAPS, 2, - G_TYPE_UINT, G_TYPE_UINT); - - /** - * GstRDTManager::clear-pt-map: - * @rtpbin: the object which received the signal - * - * Clear all previously cached pt-mapping obtained with - * GstRDTManager::request-pt-map. - */ - gst_rdt_manager_signals[SIGNAL_CLEAR_PT_MAP] = - g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRDTManagerClass, clear_pt_map), - NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); - - /** - * GstRDTManager::on-bye-ssrc: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of an SSRC that became inactive because of a BYE packet. - */ - gst_rdt_manager_signals[SIGNAL_ON_BYE_SSRC] = - g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRDTManagerClass, on_bye_ssrc), - NULL, NULL, gst_rdt_manager_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRDTManager::on-bye-timeout: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of an SSRC that has timed out because of BYE - */ - gst_rdt_manager_signals[SIGNAL_ON_BYE_TIMEOUT] = - g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRDTManagerClass, on_bye_timeout), - NULL, NULL, gst_rdt_manager_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRDTManager::on-timeout: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of an SSRC that has timed out - */ - gst_rdt_manager_signals[SIGNAL_ON_TIMEOUT] = - g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRDTManagerClass, on_timeout), - NULL, NULL, gst_rdt_manager_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - - /** - * GstRDTManager::on-npt-stop: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify that SSRC sender has sent data up to the configured NPT stop time. - */ - gst_rdt_manager_signals[SIGNAL_ON_NPT_STOP] = - g_signal_new ("on-npt-stop", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRDTManagerClass, on_npt_stop), - NULL, NULL, gst_rdt_manager_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - - - gstelement_class->provide_clock = - GST_DEBUG_FUNCPTR (gst_rdt_manager_provide_clock); - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_rdt_manager_change_state); - gstelement_class->request_new_pad = - GST_DEBUG_FUNCPTR (gst_rdt_manager_request_new_pad); - gstelement_class->release_pad = - GST_DEBUG_FUNCPTR (gst_rdt_manager_release_pad); - - /* sink pads */ - gst_element_class_add_static_pad_template (gstelement_class, - &gst_rdt_manager_recv_rtp_sink_template); - gst_element_class_add_static_pad_template (gstelement_class, - &gst_rdt_manager_recv_rtcp_sink_template); - /* src pads */ - gst_element_class_add_static_pad_template (gstelement_class, - &gst_rdt_manager_recv_rtp_src_template); - gst_element_class_add_static_pad_template (gstelement_class, - &gst_rdt_manager_rtcp_src_template); - - gst_element_class_set_static_metadata (gstelement_class, "RTP Decoder", - "Codec/Parser/Network", - "Accepts raw RTP and RTCP packets and sends them forward", - "Wim Taymans "); - - GST_DEBUG_CATEGORY_INIT (rdtmanager_debug, "rdtmanager", 0, "RTP decoder"); -} - -static void -gst_rdt_manager_init (GstRDTManager * rdtmanager) -{ - rdtmanager->provided_clock = gst_system_clock_obtain (); - rdtmanager->latency = DEFAULT_LATENCY_MS; - GST_OBJECT_FLAG_SET (rdtmanager, GST_ELEMENT_FLAG_PROVIDE_CLOCK); -} - -static void -gst_rdt_manager_finalize (GObject * object) -{ - GstRDTManager *rdtmanager; - - rdtmanager = GST_RDT_MANAGER (object); - - g_slist_foreach (rdtmanager->sessions, (GFunc) free_session, NULL); - g_slist_free (rdtmanager->sessions); - g_clear_object (&rdtmanager->provided_clock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -gst_rdt_manager_query_src (GstPad * pad, GstObject * parent, GstQuery * query) -{ - GstRDTManager *rdtmanager; - gboolean res; - - rdtmanager = GST_RDT_MANAGER (parent); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY: - { - GstClockTime latency; - - latency = rdtmanager->latency * GST_MSECOND; - - /* we pretend to be live with a 3 second latency */ - gst_query_set_latency (query, TRUE, latency, -1); - - GST_DEBUG_OBJECT (rdtmanager, "reporting %" GST_TIME_FORMAT " of latency", - GST_TIME_ARGS (latency)); - res = TRUE; - break; - } - default: - res = gst_pad_query_default (pad, parent, query); - break; - } - return res; -} - -static gboolean -gst_rdt_manager_src_activate_mode (GstPad * pad, GstObject * parent, - GstPadMode mode, gboolean active) -{ - gboolean result; - GstRDTManager *rdtmanager; - GstRDTManagerSession *session; - - session = gst_pad_get_element_private (pad); - rdtmanager = session->dec; - - switch (mode) { - case GST_PAD_MODE_PUSH: - if (active) { - /* allow data processing */ - JBUF_LOCK (session); - GST_DEBUG_OBJECT (rdtmanager, "Enabling pop on queue"); - /* Mark as non flushing */ - session->srcresult = GST_FLOW_OK; - gst_segment_init (&session->segment, GST_FORMAT_TIME); - session->last_popped_seqnum = -1; - session->last_out_time = -1; - session->next_seqnum = -1; - session->eos = FALSE; - JBUF_UNLOCK (session); - - /* start pushing out buffers */ - GST_DEBUG_OBJECT (rdtmanager, "Starting task on srcpad"); - result = - gst_pad_start_task (pad, (GstTaskFunction) gst_rdt_manager_loop, - pad, NULL); - } else { - /* make sure all data processing stops ASAP */ - JBUF_LOCK (session); - /* mark ourselves as flushing */ - session->srcresult = GST_FLOW_FLUSHING; - GST_DEBUG_OBJECT (rdtmanager, "Disabling pop on queue"); - /* this unblocks any waiting pops on the src pad task */ - JBUF_SIGNAL (session); - /* unlock clock, we just unschedule, the entry will be released by - * the locking streaming thread. */ - if (session->clock_id) - gst_clock_id_unschedule (session->clock_id); - JBUF_UNLOCK (session); - - /* NOTE this will hardlock if the state change is called from the src pad - * task thread because we will _join() the thread. */ - GST_DEBUG_OBJECT (rdtmanager, "Stopping task on srcpad"); - result = gst_pad_stop_task (pad); - } - break; - default: - result = FALSE; - break; - } - return result; -} - -static GstFlowReturn -gst_rdt_manager_handle_data_packet (GstRDTManagerSession * session, - GstClockTime timestamp, GstRDTPacket * packet) -{ - GstRDTManager *rdtmanager; - guint16 seqnum; - gboolean tail; - GstFlowReturn res; - GstBuffer *buffer; - - rdtmanager = session->dec; - - res = GST_FLOW_OK; - - seqnum = 0; - GST_DEBUG_OBJECT (rdtmanager, - "Received packet #%d at time %" GST_TIME_FORMAT, seqnum, - GST_TIME_ARGS (timestamp)); - - buffer = gst_rdt_packet_to_buffer (packet); - - JBUF_LOCK_CHECK (session, out_flushing); - - /* insert the packet into the queue now, FIXME, use seqnum */ - if (!rdt_jitter_buffer_insert (session->jbuf, buffer, timestamp, - session->clock_rate, &tail)) - goto duplicate; - - /* signal addition of new buffer when the _loop is waiting. */ - if (session->waiting) - JBUF_SIGNAL (session); - -finished: - JBUF_UNLOCK (session); - - return res; - - /* ERRORS */ -out_flushing: - { - res = session->srcresult; - GST_DEBUG_OBJECT (rdtmanager, "flushing %s", gst_flow_get_name (res)); - gst_buffer_unref (buffer); - goto finished; - } -duplicate: - { - GST_WARNING_OBJECT (rdtmanager, "Duplicate packet #%d detected, dropping", - seqnum); - session->num_duplicates++; - gst_buffer_unref (buffer); - goto finished; - } -} - -static gboolean -gst_rdt_manager_parse_caps (GstRDTManager * rdtmanager, - GstRDTManagerSession * session, GstCaps * caps) -{ - GstStructure *caps_struct; - guint val; - - /* first parse the caps */ - caps_struct = gst_caps_get_structure (caps, 0); - - GST_DEBUG_OBJECT (rdtmanager, "got caps"); - - /* we need a clock-rate to convert the rtp timestamps to GStreamer time and to - * measure the amount of data in the buffer */ - if (!gst_structure_get_int (caps_struct, "clock-rate", &session->clock_rate)) - session->clock_rate = 1000; - - if (session->clock_rate <= 0) - goto wrong_rate; - - GST_DEBUG_OBJECT (rdtmanager, "got clock-rate %d", session->clock_rate); - - /* gah, clock-base is uint. If we don't have a base, we will use the first - * buffer timestamp as the base time. This will screw up sync but it's better - * than nothing. */ - if (gst_structure_get_uint (caps_struct, "clock-base", &val)) - session->clock_base = val; - else - session->clock_base = -1; - - GST_DEBUG_OBJECT (rdtmanager, "got clock-base %" G_GINT64_FORMAT, - session->clock_base); - - /* first expected seqnum */ - if (gst_structure_get_uint (caps_struct, "seqnum-base", &val)) - session->next_seqnum = val; - else - session->next_seqnum = -1; - - GST_DEBUG_OBJECT (rdtmanager, "got seqnum-base %d", session->next_seqnum); - - return TRUE; - - /* ERRORS */ -wrong_rate: - { - GST_DEBUG_OBJECT (rdtmanager, "Invalid clock-rate %d", session->clock_rate); - return FALSE; - } -} - -static gboolean -gst_rdt_manager_event_rdt (GstPad * pad, GstObject * parent, GstEvent * event) -{ - GstRDTManager *rdtmanager; - GstRDTManagerSession *session; - gboolean res; - - rdtmanager = GST_RDT_MANAGER (parent); - /* find session */ - session = gst_pad_get_element_private (pad); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_CAPS: - { - GstCaps *caps; - - gst_event_parse_caps (event, &caps); - res = gst_rdt_manager_parse_caps (rdtmanager, session, caps); - gst_event_unref (event); - break; - } - default: - res = gst_pad_event_default (pad, parent, event); - break; - } - return res; -} - -static GstFlowReturn -gst_rdt_manager_chain_rdt (GstPad * pad, GstObject * parent, GstBuffer * buffer) -{ - GstFlowReturn res; - GstRDTManager *rdtmanager; - GstRDTManagerSession *session; - GstClockTime timestamp; - GstRDTPacket packet; - guint32 ssrc; - guint8 pt; - gboolean more; - - rdtmanager = GST_RDT_MANAGER (parent); - - GST_DEBUG_OBJECT (rdtmanager, "got RDT packet"); - - ssrc = 0; - pt = 0; - - GST_DEBUG_OBJECT (rdtmanager, "SSRC %08x, PT %d", ssrc, pt); - - /* find session */ - session = gst_pad_get_element_private (pad); - - /* see if we have the pad */ - if (!session->active) { - activate_session (rdtmanager, session, ssrc, pt); - session->active = TRUE; - } - - if (GST_BUFFER_IS_DISCONT (buffer)) { - GST_DEBUG_OBJECT (rdtmanager, "received discont"); - session->discont = TRUE; - } - - res = GST_FLOW_OK; - - /* take the timestamp of the buffer. This is the time when the packet was - * received and is used to calculate jitter and clock skew. We will adjust - * this timestamp with the smoothed value after processing it in the - * jitterbuffer. */ - timestamp = GST_BUFFER_TIMESTAMP (buffer); - /* bring to running time */ - timestamp = gst_segment_to_running_time (&session->segment, GST_FORMAT_TIME, - timestamp); - - more = gst_rdt_buffer_get_first_packet (buffer, &packet); - while (more) { - GstRDTType type; - - type = gst_rdt_packet_get_type (&packet); - GST_DEBUG_OBJECT (rdtmanager, "Have packet of type %04x", type); - - if (GST_RDT_IS_DATA_TYPE (type)) { - GST_DEBUG_OBJECT (rdtmanager, "We have a data packet"); - res = gst_rdt_manager_handle_data_packet (session, timestamp, &packet); - } else { - switch (type) { - default: - GST_DEBUG_OBJECT (rdtmanager, "Ignoring packet"); - break; - } - } - if (res != GST_FLOW_OK) - break; - - more = gst_rdt_packet_move_to_next (&packet); - } - - gst_buffer_unref (buffer); - - return res; -} - -/* push packets from the queue to the downstream demuxer */ -static void -gst_rdt_manager_loop (GstPad * pad) -{ - GstRDTManager *rdtmanager; - GstRDTManagerSession *session; - GstBuffer *buffer; - GstFlowReturn result; - - rdtmanager = GST_RDT_MANAGER (GST_PAD_PARENT (pad)); - - session = gst_pad_get_element_private (pad); - - JBUF_LOCK_CHECK (session, flushing); - GST_DEBUG_OBJECT (rdtmanager, "Peeking item"); - while (TRUE) { - /* always wait if we are blocked */ - if (!session->blocked) { - /* if we have a packet, we can exit the loop and grab it */ - if (rdt_jitter_buffer_num_packets (session->jbuf) > 0) - break; - /* no packets but we are EOS, do eos logic */ - if (session->eos) - goto do_eos; - } - /* underrun, wait for packets or flushing now */ - session->waiting = TRUE; - JBUF_WAIT_CHECK (session, flushing); - session->waiting = FALSE; - } - - buffer = rdt_jitter_buffer_pop (session->jbuf); - - GST_DEBUG_OBJECT (rdtmanager, "Got item %p", buffer); - - if (session->discont) { - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); - session->discont = FALSE; - } - - JBUF_UNLOCK (session); - - result = gst_pad_push (session->recv_rtp_src, buffer); - if (result != GST_FLOW_OK) - goto pause; - - return; - - /* ERRORS */ -flushing: - { - GST_DEBUG_OBJECT (rdtmanager, "we are flushing"); - gst_pad_pause_task (session->recv_rtp_src); - JBUF_UNLOCK (session); - return; - } -do_eos: - { - /* store result, we are flushing now */ - GST_DEBUG_OBJECT (rdtmanager, "We are EOS, pushing EOS downstream"); - session->srcresult = GST_FLOW_EOS; - gst_pad_pause_task (session->recv_rtp_src); - gst_pad_push_event (session->recv_rtp_src, gst_event_new_eos ()); - JBUF_UNLOCK (session); - return; - } -pause: - { - GST_DEBUG_OBJECT (rdtmanager, "pausing task, reason %s", - gst_flow_get_name (result)); - - JBUF_LOCK (session); - /* store result */ - session->srcresult = result; - /* we don't post errors or anything because upstream will do that for us - * when we pass the return value upstream. */ - gst_pad_pause_task (session->recv_rtp_src); - JBUF_UNLOCK (session); - return; - } -} - -static GstFlowReturn -gst_rdt_manager_chain_rtcp (GstPad * pad, GstObject * parent, - GstBuffer * buffer) -{ - GstRDTManager *src; - -#ifdef HAVE_RTCP - gboolean valid; - GstRTCPPacket packet; - gboolean more; -#endif - - src = GST_RDT_MANAGER (parent); - - GST_DEBUG_OBJECT (src, "got rtcp packet"); - -#ifdef HAVE_RTCP - valid = gst_rtcp_buffer_validate (buffer); - if (!valid) - goto bad_packet; - - /* position on first packet */ - more = gst_rtcp_buffer_get_first_packet (buffer, &packet); - while (more) { - switch (gst_rtcp_packet_get_type (&packet)) { - case GST_RTCP_TYPE_SR: - { - guint32 ssrc, rtptime, packet_count, octet_count; - guint64 ntptime; - guint count, i; - - gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, &rtptime, - &packet_count, &octet_count); - - GST_DEBUG_OBJECT (src, - "got SR packet: SSRC %08x, NTP %" G_GUINT64_FORMAT - ", RTP %u, PC %u, OC %u", ssrc, ntptime, rtptime, packet_count, - octet_count); - - count = gst_rtcp_packet_get_rb_count (&packet); - for (i = 0; i < count; i++) { - guint32 ssrc, exthighestseq, jitter, lsr, dlsr; - guint8 fractionlost; - gint32 packetslost; - - gst_rtcp_packet_get_rb (&packet, i, &ssrc, &fractionlost, - &packetslost, &exthighestseq, &jitter, &lsr, &dlsr); - - GST_DEBUG_OBJECT (src, "got RB packet %d: SSRC %08x, FL %u" - ", PL %u, HS %u, JITTER %u, LSR %u, DLSR %u", ssrc, fractionlost, - packetslost, exthighestseq, jitter, lsr, dlsr); - } - break; - } - case GST_RTCP_TYPE_RR: - { - guint32 ssrc; - guint count, i; - - ssrc = gst_rtcp_packet_rr_get_ssrc (&packet); - - GST_DEBUG_OBJECT (src, "got RR packet: SSRC %08x", ssrc); - - count = gst_rtcp_packet_get_rb_count (&packet); - for (i = 0; i < count; i++) { - guint32 ssrc, exthighestseq, jitter, lsr, dlsr; - guint8 fractionlost; - gint32 packetslost; - - gst_rtcp_packet_get_rb (&packet, i, &ssrc, &fractionlost, - &packetslost, &exthighestseq, &jitter, &lsr, &dlsr); - - GST_DEBUG_OBJECT (src, "got RB packet %d: SSRC %08x, FL %u" - ", PL %u, HS %u, JITTER %u, LSR %u, DLSR %u", ssrc, fractionlost, - packetslost, exthighestseq, jitter, lsr, dlsr); - } - break; - } - case GST_RTCP_TYPE_SDES: - { - guint chunks, i, j; - gboolean more_chunks, more_items; - - chunks = gst_rtcp_packet_sdes_get_chunk_count (&packet); - GST_DEBUG_OBJECT (src, "got SDES packet with %d chunks", chunks); - - more_chunks = gst_rtcp_packet_sdes_first_chunk (&packet); - i = 0; - while (more_chunks) { - guint32 ssrc; - - ssrc = gst_rtcp_packet_sdes_get_ssrc (&packet); - - GST_DEBUG_OBJECT (src, "chunk %d, SSRC %08x", i, ssrc); - - more_items = gst_rtcp_packet_sdes_first_item (&packet); - j = 0; - while (more_items) { - GstRTCPSDESType type; - guint8 len; - gchar *data; - - gst_rtcp_packet_sdes_get_item (&packet, &type, &len, &data); - - GST_DEBUG_OBJECT (src, "item %d, type %d, len %d, data %s", j, - type, len, data); - - more_items = gst_rtcp_packet_sdes_next_item (&packet); - j++; - } - more_chunks = gst_rtcp_packet_sdes_next_chunk (&packet); - i++; - } - break; - } - case GST_RTCP_TYPE_BYE: - { - guint count, i; - gchar *reason; - - reason = gst_rtcp_packet_bye_get_reason (&packet); - GST_DEBUG_OBJECT (src, "got BYE packet (reason: %s)", - GST_STR_NULL (reason)); - g_free (reason); - - count = gst_rtcp_packet_bye_get_ssrc_count (&packet); - for (i = 0; i < count; i++) { - guint32 ssrc; - - - ssrc = gst_rtcp_packet_bye_get_nth_ssrc (&packet, i); - - GST_DEBUG_OBJECT (src, "SSRC: %08x", ssrc); - } - break; - } - case GST_RTCP_TYPE_APP: - GST_DEBUG_OBJECT (src, "got APP packet"); - break; - default: - GST_WARNING_OBJECT (src, "got unknown RTCP packet"); - break; - } - more = gst_rtcp_packet_move_to_next (&packet); - } - gst_buffer_unref (buffer); - return GST_FLOW_OK; - -bad_packet: - { - GST_WARNING_OBJECT (src, "got invalid RTCP packet"); - return GST_FLOW_OK; - } -#else - return GST_FLOW_OK; -#endif -} - -static void -gst_rdt_manager_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstRDTManager *src; - - src = GST_RDT_MANAGER (object); - - switch (prop_id) { - case PROP_LATENCY: - src->latency = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_rdt_manager_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstRDTManager *src; - - src = GST_RDT_MANAGER (object); - - switch (prop_id) { - case PROP_LATENCY: - g_value_set_uint (value, src->latency); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstClock * -gst_rdt_manager_provide_clock (GstElement * element) -{ - GstRDTManager *rdtmanager; - - rdtmanager = GST_RDT_MANAGER (element); - - return GST_CLOCK_CAST (gst_object_ref (rdtmanager->provided_clock)); -} - -static GstStateChangeReturn -gst_rdt_manager_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret; - - switch (transition) { - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - /* we're NO_PREROLL when going to PAUSED */ - ret = GST_STATE_CHANGE_NO_PREROLL; - break; - default: - break; - } - - return ret; -} - -/* Create a pad for receiving RTP for the session in @name - */ -static GstPad * -create_recv_rtp (GstRDTManager * rdtmanager, GstPadTemplate * templ, - const gchar * name) -{ - guint sessid; - GstRDTManagerSession *session; - - /* first get the session number */ - if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1) - goto no_name; - - GST_DEBUG_OBJECT (rdtmanager, "finding session %d", sessid); - - /* get or create session */ - session = find_session_by_id (rdtmanager, sessid); - if (!session) { - GST_DEBUG_OBJECT (rdtmanager, "creating session %d", sessid); - /* create session now */ - session = create_session (rdtmanager, sessid); - if (session == NULL) - goto create_error; - } - /* check if pad was requested */ - if (session->recv_rtp_sink != NULL) - goto existed; - - GST_DEBUG_OBJECT (rdtmanager, "getting RTP sink pad"); - - session->recv_rtp_sink = gst_pad_new_from_template (templ, name); - gst_pad_set_element_private (session->recv_rtp_sink, session); - gst_pad_set_event_function (session->recv_rtp_sink, - gst_rdt_manager_event_rdt); - gst_pad_set_chain_function (session->recv_rtp_sink, - gst_rdt_manager_chain_rdt); - gst_pad_set_active (session->recv_rtp_sink, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtp_sink); - - return session->recv_rtp_sink; - - /* ERRORS */ -no_name: - { - g_warning ("rdtmanager: invalid name given"); - return NULL; - } -create_error: - { - /* create_session already warned */ - return NULL; - } -existed: - { - g_warning ("rdtmanager: recv_rtp pad already requested for session %d", - sessid); - return NULL; - } -} - -/* Create a pad for receiving RTCP for the session in @name - */ -static GstPad * -create_recv_rtcp (GstRDTManager * rdtmanager, GstPadTemplate * templ, - const gchar * name) -{ - guint sessid; - GstRDTManagerSession *session; - - /* first get the session number */ - if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1) - goto no_name; - - GST_DEBUG_OBJECT (rdtmanager, "finding session %d", sessid); - - /* get the session, it must exist or we error */ - session = find_session_by_id (rdtmanager, sessid); - if (!session) - goto no_session; - - /* check if pad was requested */ - if (session->recv_rtcp_sink != NULL) - goto existed; - - GST_DEBUG_OBJECT (rdtmanager, "getting RTCP sink pad"); - - session->recv_rtcp_sink = gst_pad_new_from_template (templ, name); - gst_pad_set_element_private (session->recv_rtp_sink, session); - gst_pad_set_chain_function (session->recv_rtcp_sink, - gst_rdt_manager_chain_rtcp); - gst_pad_set_active (session->recv_rtcp_sink, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtcp_sink); - - return session->recv_rtcp_sink; - - /* ERRORS */ -no_name: - { - g_warning ("rdtmanager: invalid name given"); - return NULL; - } -no_session: - { - g_warning ("rdtmanager: no session with id %d", sessid); - return NULL; - } -existed: - { - g_warning ("rdtmanager: recv_rtcp pad already requested for session %d", - sessid); - return NULL; - } -} - -/* Create a pad for sending RTCP for the session in @name - */ -static GstPad * -create_rtcp (GstRDTManager * rdtmanager, GstPadTemplate * templ, - const gchar * name) -{ - guint sessid; - GstRDTManagerSession *session; - - /* first get the session number */ - if (name == NULL || sscanf (name, "rtcp_src_%u", &sessid) != 1) - goto no_name; - - /* get or create session */ - session = find_session_by_id (rdtmanager, sessid); - if (!session) - goto no_session; - - /* check if pad was requested */ - if (session->rtcp_src != NULL) - goto existed; - - session->rtcp_src = gst_pad_new_from_template (templ, name); - gst_pad_set_active (session->rtcp_src, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->rtcp_src); - - return session->rtcp_src; - - /* ERRORS */ -no_name: - { - g_warning ("rdtmanager: invalid name given"); - return NULL; - } -no_session: - { - g_warning ("rdtmanager: session with id %d does not exist", sessid); - return NULL; - } -existed: - { - g_warning ("rdtmanager: rtcp_src pad already requested for session %d", - sessid); - return NULL; - } -} - -/* - */ -static GstPad * -gst_rdt_manager_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name, const GstCaps * caps) -{ - GstRDTManager *rdtmanager; - GstElementClass *klass; - GstPad *result; - - g_return_val_if_fail (templ != NULL, NULL); - g_return_val_if_fail (GST_IS_RDT_MANAGER (element), NULL); - - rdtmanager = GST_RDT_MANAGER (element); - klass = GST_ELEMENT_GET_CLASS (element); - - /* figure out the template */ - if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u")) { - result = create_recv_rtp (rdtmanager, templ, name); - } else if (templ == gst_element_class_get_pad_template (klass, - "recv_rtcp_sink_%u")) { - result = create_recv_rtcp (rdtmanager, templ, name); - } else if (templ == gst_element_class_get_pad_template (klass, "rtcp_src_%u")) { - result = create_rtcp (rdtmanager, templ, name); - } else - goto wrong_template; - - return result; - - /* ERRORS */ -wrong_template: - { - g_warning ("rdtmanager: this is not our template"); - return NULL; - } -} - -static void -gst_rdt_manager_release_pad (GstElement * element, GstPad * pad) -{ -} diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.h b/subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.h deleted file mode 100644 index d7a60fd595..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rdtmanager.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -/* - * Unless otherwise indicated, Source Code is licensed under MIT license. - * See further explanation attached in License Statement (distributed in the file - * LICENSE). - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __GST_RDT_MANAGER_H__ -#define __GST_RDT_MANAGER_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_RDT_MANAGER (gst_rdt_manager_get_type()) -#define GST_IS_RDT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RDT_MANAGER)) -#define GST_IS_RDT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RDT_MANAGER)) -#define GST_RDT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RDT_MANAGER, GstRDTManager)) -#define GST_RDT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RDT_MANAGER, GstRDTManagerClass)) - -typedef struct _GstRDTManager GstRDTManager; -typedef struct _GstRDTManagerClass GstRDTManagerClass; -typedef struct _GstRDTManagerSession GstRDTManagerSession; - -struct _GstRDTManager { - GstElement element; - - guint latency; - GSList *sessions; - GstClock *provided_clock; -}; - -struct _GstRDTManagerClass { - GstElementClass parent_class; - - /* get the caps for pt */ - GstCaps* (*request_pt_map) (GstRDTManager *rtpdec, guint session, guint pt); - - void (*clear_pt_map) (GstRDTManager *rtpdec); - - void (*on_new_ssrc) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_ssrc_collision) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_ssrc_validated) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_ssrc_active) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_ssrc_sdes) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_bye_ssrc) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_bye_timeout) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_timeout) (GstRDTManager *rtpdec, guint session, guint32 ssrc); - void (*on_npt_stop) (GstRDTManager *rtpdec, guint session, guint32 ssrc); -}; - -GType gst_rdt_manager_get_type(void); - -GST_ELEMENT_REGISTER_DECLARE (rdtmanager); - -G_END_DECLS - -#endif /* __GST_RDT_MANAGER_H__ */ diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/realhash.c b/subprojects/gst-plugins-ugly/gst/realmedia/realhash.c deleted file mode 100644 index 4a18189cee..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/realhash.c +++ /dev/null @@ -1,324 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -/* Element-Checklist-Version: 5 */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_STDINT_H -#include -#endif - -#include - -#include - -#include "realhash.h" - -void rtsp_ext_real_calc_response_and_checksum (char *response, - char *chksum, char *challenge); - -/* - * The following code has been copied from - * xine-lib-1.1.1/src/input/libreal/real.c. - */ - -static const unsigned char xor_table[] = { - 0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53, - 0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70, - 0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09, - 0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02, - 0x10, 0x57, 0x05, 0x18, 0x54, 0x00, 0x00, 0x00 -}; - -#define LE_32(x) GST_READ_UINT32_LE(x) -#define BE_32C(x,y) GST_WRITE_UINT32_BE(x,y) -#define LE_32C(x,y) GST_WRITE_UINT32_LE(x,y) - -static void -hash (char *field, char *param) -{ - uint32_t a, b, c, d; - - /* fill variables */ - a = LE_32 (field); - b = LE_32 (field + 4); - c = LE_32 (field + 8); - d = LE_32 (field + 12); - - a = ((b & c) | (~b & d)) + LE_32 ((param + 0x00)) + a - 0x28955B88; - a = ((a << 0x07) | (a >> 0x19)) + b; - d = ((a & b) | (~a & c)) + LE_32 ((param + 0x04)) + d - 0x173848AA; - d = ((d << 0x0c) | (d >> 0x14)) + a; - c = ((d & a) | (~d & b)) + LE_32 ((param + 0x08)) + c + 0x242070DB; - c = ((c << 0x11) | (c >> 0x0f)) + d; - b = ((c & d) | (~c & a)) + LE_32 ((param + 0x0c)) + b - 0x3E423112; - b = ((b << 0x16) | (b >> 0x0a)) + c; - a = ((b & c) | (~b & d)) + LE_32 ((param + 0x10)) + a - 0x0A83F051; - a = ((a << 0x07) | (a >> 0x19)) + b; - d = ((a & b) | (~a & c)) + LE_32 ((param + 0x14)) + d + 0x4787C62A; - d = ((d << 0x0c) | (d >> 0x14)) + a; - c = ((d & a) | (~d & b)) + LE_32 ((param + 0x18)) + c - 0x57CFB9ED; - c = ((c << 0x11) | (c >> 0x0f)) + d; - b = ((c & d) | (~c & a)) + LE_32 ((param + 0x1c)) + b - 0x02B96AFF; - b = ((b << 0x16) | (b >> 0x0a)) + c; - a = ((b & c) | (~b & d)) + LE_32 ((param + 0x20)) + a + 0x698098D8; - a = ((a << 0x07) | (a >> 0x19)) + b; - d = ((a & b) | (~a & c)) + LE_32 ((param + 0x24)) + d - 0x74BB0851; - d = ((d << 0x0c) | (d >> 0x14)) + a; - c = ((d & a) | (~d & b)) + LE_32 ((param + 0x28)) + c - 0x0000A44F; - c = ((c << 0x11) | (c >> 0x0f)) + d; - b = ((c & d) | (~c & a)) + LE_32 ((param + 0x2C)) + b - 0x76A32842; - b = ((b << 0x16) | (b >> 0x0a)) + c; - a = ((b & c) | (~b & d)) + LE_32 ((param + 0x30)) + a + 0x6B901122; - a = ((a << 0x07) | (a >> 0x19)) + b; - d = ((a & b) | (~a & c)) + LE_32 ((param + 0x34)) + d - 0x02678E6D; - d = ((d << 0x0c) | (d >> 0x14)) + a; - c = ((d & a) | (~d & b)) + LE_32 ((param + 0x38)) + c - 0x5986BC72; - c = ((c << 0x11) | (c >> 0x0f)) + d; - b = ((c & d) | (~c & a)) + LE_32 ((param + 0x3c)) + b + 0x49B40821; - b = ((b << 0x16) | (b >> 0x0a)) + c; - - a = ((b & d) | (~d & c)) + LE_32 ((param + 0x04)) + a - 0x09E1DA9E; - a = ((a << 0x05) | (a >> 0x1b)) + b; - d = ((a & c) | (~c & b)) + LE_32 ((param + 0x18)) + d - 0x3FBF4CC0; - d = ((d << 0x09) | (d >> 0x17)) + a; - c = ((d & b) | (~b & a)) + LE_32 ((param + 0x2c)) + c + 0x265E5A51; - c = ((c << 0x0e) | (c >> 0x12)) + d; - b = ((c & a) | (~a & d)) + LE_32 ((param + 0x00)) + b - 0x16493856; - b = ((b << 0x14) | (b >> 0x0c)) + c; - a = ((b & d) | (~d & c)) + LE_32 ((param + 0x14)) + a - 0x29D0EFA3; - a = ((a << 0x05) | (a >> 0x1b)) + b; - d = ((a & c) | (~c & b)) + LE_32 ((param + 0x28)) + d + 0x02441453; - d = ((d << 0x09) | (d >> 0x17)) + a; - c = ((d & b) | (~b & a)) + LE_32 ((param + 0x3c)) + c - 0x275E197F; - c = ((c << 0x0e) | (c >> 0x12)) + d; - b = ((c & a) | (~a & d)) + LE_32 ((param + 0x10)) + b - 0x182C0438; - b = ((b << 0x14) | (b >> 0x0c)) + c; - a = ((b & d) | (~d & c)) + LE_32 ((param + 0x24)) + a + 0x21E1CDE6; - a = ((a << 0x05) | (a >> 0x1b)) + b; - d = ((a & c) | (~c & b)) + LE_32 ((param + 0x38)) + d - 0x3CC8F82A; - d = ((d << 0x09) | (d >> 0x17)) + a; - c = ((d & b) | (~b & a)) + LE_32 ((param + 0x0c)) + c - 0x0B2AF279; - c = ((c << 0x0e) | (c >> 0x12)) + d; - b = ((c & a) | (~a & d)) + LE_32 ((param + 0x20)) + b + 0x455A14ED; - b = ((b << 0x14) | (b >> 0x0c)) + c; - a = ((b & d) | (~d & c)) + LE_32 ((param + 0x34)) + a - 0x561C16FB; - a = ((a << 0x05) | (a >> 0x1b)) + b; - d = ((a & c) | (~c & b)) + LE_32 ((param + 0x08)) + d - 0x03105C08; - d = ((d << 0x09) | (d >> 0x17)) + a; - c = ((d & b) | (~b & a)) + LE_32 ((param + 0x1c)) + c + 0x676F02D9; - c = ((c << 0x0e) | (c >> 0x12)) + d; - b = ((c & a) | (~a & d)) + LE_32 ((param + 0x30)) + b - 0x72D5B376; - b = ((b << 0x14) | (b >> 0x0c)) + c; - - a = (b ^ c ^ d) + LE_32 ((param + 0x14)) + a - 0x0005C6BE; - a = ((a << 0x04) | (a >> 0x1c)) + b; - d = (a ^ b ^ c) + LE_32 ((param + 0x20)) + d - 0x788E097F; - d = ((d << 0x0b) | (d >> 0x15)) + a; - c = (d ^ a ^ b) + LE_32 ((param + 0x2c)) + c + 0x6D9D6122; - c = ((c << 0x10) | (c >> 0x10)) + d; - b = (c ^ d ^ a) + LE_32 ((param + 0x38)) + b - 0x021AC7F4; - b = ((b << 0x17) | (b >> 0x09)) + c; - a = (b ^ c ^ d) + LE_32 ((param + 0x04)) + a - 0x5B4115BC; - a = ((a << 0x04) | (a >> 0x1c)) + b; - d = (a ^ b ^ c) + LE_32 ((param + 0x10)) + d + 0x4BDECFA9; - d = ((d << 0x0b) | (d >> 0x15)) + a; - c = (d ^ a ^ b) + LE_32 ((param + 0x1c)) + c - 0x0944B4A0; - c = ((c << 0x10) | (c >> 0x10)) + d; - b = (c ^ d ^ a) + LE_32 ((param + 0x28)) + b - 0x41404390; - b = ((b << 0x17) | (b >> 0x09)) + c; - a = (b ^ c ^ d) + LE_32 ((param + 0x34)) + a + 0x289B7EC6; - a = ((a << 0x04) | (a >> 0x1c)) + b; - d = (a ^ b ^ c) + LE_32 ((param + 0x00)) + d - 0x155ED806; - d = ((d << 0x0b) | (d >> 0x15)) + a; - c = (d ^ a ^ b) + LE_32 ((param + 0x0c)) + c - 0x2B10CF7B; - c = ((c << 0x10) | (c >> 0x10)) + d; - b = (c ^ d ^ a) + LE_32 ((param + 0x18)) + b + 0x04881D05; - b = ((b << 0x17) | (b >> 0x09)) + c; - a = (b ^ c ^ d) + LE_32 ((param + 0x24)) + a - 0x262B2FC7; - a = ((a << 0x04) | (a >> 0x1c)) + b; - d = (a ^ b ^ c) + LE_32 ((param + 0x30)) + d - 0x1924661B; - d = ((d << 0x0b) | (d >> 0x15)) + a; - c = (d ^ a ^ b) + LE_32 ((param + 0x3c)) + c + 0x1fa27cf8; - c = ((c << 0x10) | (c >> 0x10)) + d; - b = (c ^ d ^ a) + LE_32 ((param + 0x08)) + b - 0x3B53A99B; - b = ((b << 0x17) | (b >> 0x09)) + c; - - a = ((~d | b) ^ c) + LE_32 ((param + 0x00)) + a - 0x0BD6DDBC; - a = ((a << 0x06) | (a >> 0x1a)) + b; - d = ((~c | a) ^ b) + LE_32 ((param + 0x1c)) + d + 0x432AFF97; - d = ((d << 0x0a) | (d >> 0x16)) + a; - c = ((~b | d) ^ a) + LE_32 ((param + 0x38)) + c - 0x546BDC59; - c = ((c << 0x0f) | (c >> 0x11)) + d; - b = ((~a | c) ^ d) + LE_32 ((param + 0x14)) + b - 0x036C5FC7; - b = ((b << 0x15) | (b >> 0x0b)) + c; - a = ((~d | b) ^ c) + LE_32 ((param + 0x30)) + a + 0x655B59C3; - a = ((a << 0x06) | (a >> 0x1a)) + b; - d = ((~c | a) ^ b) + LE_32 ((param + 0x0C)) + d - 0x70F3336E; - d = ((d << 0x0a) | (d >> 0x16)) + a; - c = ((~b | d) ^ a) + LE_32 ((param + 0x28)) + c - 0x00100B83; - c = ((c << 0x0f) | (c >> 0x11)) + d; - b = ((~a | c) ^ d) + LE_32 ((param + 0x04)) + b - 0x7A7BA22F; - b = ((b << 0x15) | (b >> 0x0b)) + c; - a = ((~d | b) ^ c) + LE_32 ((param + 0x20)) + a + 0x6FA87E4F; - a = ((a << 0x06) | (a >> 0x1a)) + b; - d = ((~c | a) ^ b) + LE_32 ((param + 0x3c)) + d - 0x01D31920; - d = ((d << 0x0a) | (d >> 0x16)) + a; - c = ((~b | d) ^ a) + LE_32 ((param + 0x18)) + c - 0x5CFEBCEC; - c = ((c << 0x0f) | (c >> 0x11)) + d; - b = ((~a | c) ^ d) + LE_32 ((param + 0x34)) + b + 0x4E0811A1; - b = ((b << 0x15) | (b >> 0x0b)) + c; - a = ((~d | b) ^ c) + LE_32 ((param + 0x10)) + a - 0x08AC817E; - a = ((a << 0x06) | (a >> 0x1a)) + b; - d = ((~c | a) ^ b) + LE_32 ((param + 0x2c)) + d - 0x42C50DCB; - d = ((d << 0x0a) | (d >> 0x16)) + a; - c = ((~b | d) ^ a) + LE_32 ((param + 0x08)) + c + 0x2AD7D2BB; - c = ((c << 0x0f) | (c >> 0x11)) + d; - b = ((~a | c) ^ d) + LE_32 ((param + 0x24)) + b - 0x14792C6F; - b = ((b << 0x15) | (b >> 0x0b)) + c; - - a += LE_32 (field); - b += LE_32 (field + 4); - c += LE_32 (field + 8); - d += LE_32 (field + 12); - - LE_32C (field, a); - LE_32C (field + 4, b); - LE_32C (field + 8, c); - LE_32C (field + 12, d); -} - -static void -call_hash (char *key, char *challenge, int len) -{ - uint8_t *ptr1, *ptr2; - uint32_t a, b, c, d, tmp; - - ptr1 = (uint8_t *) (key + 16); - ptr2 = (uint8_t *) (key + 20); - - a = LE_32 (ptr1); - b = (a >> 3) & 0x3f; - a += len * 8; - LE_32C (ptr1, a); - - if (a < (len << 3)) - ptr2 += 4; - - tmp = LE_32 (ptr2) + (len >> 0x1d); - LE_32C (ptr2, tmp); - a = 64 - b; - c = 0; - if (a <= len) { - - memcpy (key + b + 24, challenge, a); - hash (key, key + 24); - c = a; - d = c + 0x3f; - - while (d < len) { - hash (key, challenge + d - 0x3f); - d += 64; - c += 64; - } - b = 0; - } - - memcpy (key + b + 24, challenge + c, len - c); -} - -void -gst_rtsp_ext_real_calc_response_and_checksum (char *response, char *chksum, - char *challenge) -{ - int ch_len, table_len, resp_len; - int i; - char *ptr; - char buf[128]; - char field[128]; - char zres[20]; - char buf1[128]; - char buf2[128]; - - /* initialize return values */ - memset (response, 0, 64); - memset (chksum, 0, 34); - - /* initialize buffer */ - memset (buf, 0, 128); - ptr = buf; - BE_32C (ptr, 0xa1e9149d); - ptr += 4; - BE_32C (ptr, 0x0e6b3b59); - ptr += 4; - - if ((ch_len = MIN (strlen (challenge), 56)) == 40) { - challenge[32] = 0; - ch_len = 32; - } - memcpy (ptr, challenge, ch_len); - - /* xor challenge bytewise with xor_table */ - table_len = MIN (strlen ((char *) xor_table), 56); - for (i = 0; i < table_len; i++) - ptr[i] = ptr[i] ^ xor_table[i]; - - /* initialize our field */ - BE_32C (field, 0x01234567); - BE_32C (field + 4, 0x89ABCDEF); - BE_32C (field + 8, 0xFEDCBA98); - BE_32C (field + 12, 0x76543210); - BE_32C (field + 16, 0x00000000); - BE_32C (field + 20, 0x00000000); - - /* calculate response */ - call_hash (field, buf, 64); - memset (buf1, 0, 64); - *buf1 = (char) 128; - memcpy (buf2, field + 16, 8); - i = (LE_32 ((buf2)) >> 3) & 0x3f; - if (i < 56) - i = 56 - i; - else - i = 120 - i; - call_hash (field, buf1, i); - call_hash (field, buf2, 8); - memcpy (zres, field, 16); - - /* convert zres to ascii string */ - for (i = 0; i < 16; i++) { - char a, b; - - a = (zres[i] >> 4) & 15; - b = zres[i] & 15; - - response[i * 2] = ((a < 10) ? (a + 48) : (a + 87)) & 255; - response[i * 2 + 1] = ((b < 10) ? (b + 48) : (b + 87)) & 255; - } - - /* add tail */ - resp_len = strlen (response); - strcpy (&response[resp_len], "01d0a8e3"); - - /* calculate checksum */ - for (i = 0; i < resp_len / 4; i++) - chksum[i] = response[i * 4]; -} diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/realhash.h b/subprojects/gst-plugins-ugly/gst/realmedia/realhash.h deleted file mode 100644 index 40b6500087..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/realhash.h +++ /dev/null @@ -1,31 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_RTSP_HASH_H__ -#define __GST_RTSP_HASH_H__ - -G_BEGIN_DECLS - -void -gst_rtsp_ext_real_calc_response_and_checksum (char *response, char *chksum, - char *challenge); - -G_END_DECLS - -#endif /* __GST_RTSP_HASH_H__ */ diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/realmedia.c b/subprojects/gst-plugins-ugly/gst/realmedia/realmedia.c index 71749f6334..b9bc71265c 100644 --- a/subprojects/gst-plugins-ugly/gst/realmedia/realmedia.c +++ b/subprojects/gst-plugins-ugly/gst/realmedia/realmedia.c @@ -23,10 +23,6 @@ #include "rmdemux.h" #include "rademux.h" -#include "rdtdepay.h" -#include "rdtmanager.h" -#include "rtspreal.h" -#include "pnmsrc.h" static gboolean plugin_init (GstPlugin * plugin) @@ -35,10 +31,6 @@ plugin_init (GstPlugin * plugin) ret |= GST_ELEMENT_REGISTER (rmdemux, plugin); ret |= GST_ELEMENT_REGISTER (rademux, plugin); - ret |= GST_ELEMENT_REGISTER (rdtdepay, plugin); - ret |= GST_ELEMENT_REGISTER (rdtmanager, plugin); - ret |= GST_ELEMENT_REGISTER (rtspreal, plugin); - ret |= GST_ELEMENT_REGISTER (pnmsrc, plugin); return ret; } diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.c b/subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.c deleted file mode 100644 index 5804747ee7..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.c +++ /dev/null @@ -1,735 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -/* Element-Checklist-Version: 5 */ - -/** - * SECTION:element-rtspreal - * @title: rtspreal - * - * A RealMedia RTSP extension - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_STDINT_H -#include -#endif - -#include -#include - -#include - -#include "realhash.h" -#include "rtspreal.h" -#include "asmrules.h" - -GST_DEBUG_CATEGORY_STATIC (rtspreal_debug); -#define GST_CAT_DEFAULT (rtspreal_debug) - -#define SERVER_PREFIX "RealServer" -#define DEFAULT_BANDWIDTH "10485800" - -static GstRTSPResult -rtsp_ext_real_get_transports (GstRTSPExtension * ext, - GstRTSPLowerTrans protocols, gchar ** transport) -{ - GstRTSPReal *ctx = (GstRTSPReal *) ext; - GString *str; - - if (!ctx->isreal) - return GST_RTSP_OK; - - GST_DEBUG_OBJECT (ext, "generating transports for %d", protocols); - - str = g_string_new (""); - - /* - if (protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST) { - g_string_append (str, "x-real-rdt/mcast;client_port=%%u1;mode=play,"); - } - if (protocols & GST_RTSP_LOWER_TRANS_UDP) { - g_string_append (str, "x-real-rdt/udp;client_port=%%u1;mode=play,"); - g_string_append (str, "x-pn-tng/udp;client_port=%%u1;mode=play,"); - } - */ - if (protocols & GST_RTSP_LOWER_TRANS_TCP) { - g_string_append (str, "x-real-rdt/tcp;mode=play,"); - g_string_append (str, "x-pn-tng/tcp;mode=play,"); - } - - /* if we added something, remove trailing ',' */ - if (str->len > 0) - g_string_truncate (str, str->len - 1); - - *transport = g_string_free (str, FALSE); - - return GST_RTSP_OK; -} - -static GstRTSPResult -rtsp_ext_real_before_send (GstRTSPExtension * ext, GstRTSPMessage * request) -{ - GstRTSPReal *ctx = (GstRTSPReal *) ext; - - switch (request->type_data.request.method) { - case GST_RTSP_OPTIONS: - { - gst_rtsp_message_add_header (request, GST_RTSP_HDR_USER_AGENT, - //"RealMedia Player (" GST_PACKAGE_NAME ")"); - "RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_CLIENT_CHALLENGE, - "9e26d33f2984236010ef6253fb1887f7"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_COMPANY_ID, - "KnKV4M4I/B2FjJ1TToLycw=="); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_GUID, - "00000000-0000-0000-0000-000000000000"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_REGION_DATA, "0"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_PLAYER_START_TIME, - "[28/03/2003:22:50:23 00:00]"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_CLIENT_ID, - "Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); - ctx->isreal = FALSE; - break; - } - case GST_RTSP_DESCRIBE: - { - if (ctx->isreal) { - gst_rtsp_message_add_header (request, GST_RTSP_HDR_BANDWIDTH, - DEFAULT_BANDWIDTH); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_GUID, - "00000000-0000-0000-0000-000000000000"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_REGION_DATA, "0"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_CLIENT_ID, - "Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_MAX_ASM_WIDTH, "1"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_LANGUAGE, "en-US"); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_REQUIRE, - "com.real.retain-entity-for-setup"); - } - break; - } - case GST_RTSP_SETUP: - { - if (ctx->isreal) { - gchar *value = - g_strdup_printf ("%s, sd=%s", ctx->challenge2, ctx->checksum); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_REAL_CHALLENGE2, - value); - gst_rtsp_message_add_header (request, GST_RTSP_HDR_IF_MATCH, ctx->etag); - g_free (value); - } - break; - } - default: - break; - } - return GST_RTSP_OK; -} - -static GstRTSPResult -rtsp_ext_real_after_send (GstRTSPExtension * ext, GstRTSPMessage * req, - GstRTSPMessage * resp) -{ - GstRTSPReal *ctx = (GstRTSPReal *) ext; - - switch (req->type_data.request.method) { - case GST_RTSP_OPTIONS: - { - gchar *challenge1 = NULL; - gchar *server = NULL; - - gst_rtsp_message_get_header (resp, GST_RTSP_HDR_SERVER, &server, 0); - - gst_rtsp_message_get_header (resp, GST_RTSP_HDR_REAL_CHALLENGE1, - &challenge1, 0); - if (!challenge1) - goto no_challenge1; - - gst_rtsp_ext_real_calc_response_and_checksum (ctx->challenge2, - ctx->checksum, challenge1); - - GST_DEBUG_OBJECT (ctx, "Found Real challenge tag"); - ctx->isreal = TRUE; - break; - } - case GST_RTSP_DESCRIBE: - { - gchar *etag = NULL; - guint len; - - gst_rtsp_message_get_header (resp, GST_RTSP_HDR_ETAG, &etag, 0); - if (etag) { - len = sizeof (ctx->etag); - strncpy (ctx->etag, etag, len); - ctx->etag[len - 1] = '\0'; - } - break; - } - default: - break; - } - return GST_RTSP_OK; - - /* ERRORS */ -no_challenge1: - { - GST_DEBUG_OBJECT (ctx, "Could not find challenge tag."); - ctx->isreal = FALSE; - return GST_RTSP_OK; - } -} - -#define ENSURE_SIZE(size) \ -G_STMT_START { \ - while (data_len < size) { \ - data_len += 1024; \ - data = g_realloc (data, data_len); \ - } \ -} G_STMT_END - -#define READ_BUFFER_GEN(src, func, name, dest, dest_len) \ -G_STMT_START { \ - dest = (gchar *)func (src, name); \ - dest_len = 0; \ - if (!dest) { \ - dest = (char *) ""; \ - } \ - else if (!strncmp (dest, "buffer;\"", 8)) { \ - dest += 8; \ - dest_len = strlen (dest) - 1; \ - dest[dest_len] = '\0'; \ - g_base64_decode_inplace (dest, &dest_len); \ - } \ -} G_STMT_END - -#define READ_BUFFER(sdp, name, dest, dest_len) \ - READ_BUFFER_GEN(sdp, gst_sdp_message_get_attribute_val, name, dest, dest_len) -#define READ_BUFFER_M(media, name, dest, dest_len) \ - READ_BUFFER_GEN(media, gst_sdp_media_get_attribute_val, name, dest, dest_len) - -#define READ_INT_GEN(src, func, name, dest) \ -G_STMT_START { \ - const gchar *val = func (src, name); \ - if (val && !strncmp (val, "integer;", 8)) \ - dest = atoi (val + 8); \ - else \ - dest = 0; \ -} G_STMT_END - -#define READ_INT(sdp, name, dest) \ - READ_INT_GEN(sdp, gst_sdp_message_get_attribute_val, name, dest) -#define READ_INT_M(media, name, dest) \ - READ_INT_GEN(media, gst_sdp_media_get_attribute_val, name, dest) - -#define READ_STRING(media, name, dest, dest_len) \ -G_STMT_START { \ - const gchar *val = gst_sdp_media_get_attribute_val (media, name); \ - if (val && !strncmp (val, "string;\"", 8)) { \ - dest = (gchar *) val + 8; \ - dest_len = strlen (dest) - 1; \ - dest[dest_len] = '\0'; \ - } else { \ - dest = (char *) ""; \ - dest_len = 0; \ - } \ -} G_STMT_END - -#define WRITE_STRING1(datap, str, str_len) \ -G_STMT_START { \ - *datap = str_len; \ - memcpy ((datap) + 1, str, str_len); \ - datap += str_len + 1; \ -} G_STMT_END - -#define WRITE_STRING2(datap, str, str_len) \ -G_STMT_START { \ - GST_WRITE_UINT16_BE (datap, str_len); \ - memcpy (datap + 2, str, str_len); \ - datap += str_len + 2; \ -} G_STMT_END - -static GstRTSPResult -rtsp_ext_real_parse_sdp (GstRTSPExtension * ext, GstSDPMessage * sdp, - GstStructure * props) -{ - GstRTSPReal *ctx = (GstRTSPReal *) ext; - guint size; - gint i; - gchar *title, *author, *copyright, *comment; - gsize title_len, author_len, copyright_len, comment_len; - guint8 *data = NULL, *datap; - guint data_len = 0, offset; - GstBuffer *buf; - gchar *opaque_data; - gsize opaque_data_len, asm_rule_book_len; - GHashTable *vars; - GString *rules; - - /* don't bother for non-real formats */ - READ_INT (sdp, "IsRealDataType", ctx->isreal); - if (!ctx->isreal) - return TRUE; - - /* Force PAUSE | PLAY */ - //src->methods |= GST_RTSP_PLAY | GST_RTSP_PAUSE; - - ctx->n_streams = gst_sdp_message_medias_len (sdp); - - ctx->max_bit_rate = 0; - ctx->avg_bit_rate = 0; - ctx->max_packet_size = 0; - ctx->avg_packet_size = 0; - ctx->duration = 0; - - for (i = 0; i < ctx->n_streams; i++) { - const GstSDPMedia *media; - gint intval; - - media = gst_sdp_message_get_media (sdp, i); - - READ_INT_M (media, "MaxBitRate", intval); - ctx->max_bit_rate += intval; - READ_INT_M (media, "AvgBitRate", intval); - ctx->avg_bit_rate += intval; - READ_INT_M (media, "MaxPacketSize", intval); - ctx->max_packet_size = MAX (ctx->max_packet_size, intval); - READ_INT_M (media, "AvgPacketSize", intval); - ctx->avg_packet_size = (ctx->avg_packet_size * i + intval) / (i + 1); - READ_INT_M (media, "Duration", intval); - ctx->duration = MAX (ctx->duration, intval); - } - - /* FIXME: use GstByteWriter to write the header */ - /* PROP */ - offset = 0; - size = 50; - ENSURE_SIZE (size); - datap = data + offset; - - memcpy (datap + 0, "PROP", 4); - GST_WRITE_UINT32_BE (datap + 4, size); - GST_WRITE_UINT16_BE (datap + 8, 0); - GST_WRITE_UINT32_BE (datap + 10, ctx->max_bit_rate); - GST_WRITE_UINT32_BE (datap + 14, ctx->avg_bit_rate); - GST_WRITE_UINT32_BE (datap + 18, ctx->max_packet_size); - GST_WRITE_UINT32_BE (datap + 22, ctx->avg_packet_size); - GST_WRITE_UINT32_BE (datap + 26, 0); - GST_WRITE_UINT32_BE (datap + 30, ctx->duration); - GST_WRITE_UINT32_BE (datap + 34, 0); - GST_WRITE_UINT32_BE (datap + 38, 0); - GST_WRITE_UINT32_BE (datap + 42, 0); - GST_WRITE_UINT16_BE (datap + 46, ctx->n_streams); - GST_WRITE_UINT16_BE (datap + 48, 0); - offset += size; - - /* CONT */ - READ_BUFFER (sdp, "Title", title, title_len); - READ_BUFFER (sdp, "Author", author, author_len); - READ_BUFFER (sdp, "Comment", comment, comment_len); - READ_BUFFER (sdp, "Copyright", copyright, copyright_len); - - size = 18 + title_len + author_len + comment_len + copyright_len; - ENSURE_SIZE (offset + size); - datap = data + offset; - - memcpy (datap, "CONT", 4); - GST_WRITE_UINT32_BE (datap + 4, size); - GST_WRITE_UINT16_BE (datap + 8, 0); /* Version */ - datap += 10; - WRITE_STRING2 (datap, title, title_len); - WRITE_STRING2 (datap, author, author_len); - WRITE_STRING2 (datap, copyright, copyright_len); - WRITE_STRING2 (datap, comment, comment_len); - offset += size; - - /* fix the hashtale for the rule parser */ - rules = g_string_new (""); - vars = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (vars, (gchar *) "Bandwidth", - (gchar *) DEFAULT_BANDWIDTH); - - /* MDPR */ - for (i = 0; i < ctx->n_streams; i++) { - const GstSDPMedia *media; - guint32 len; - GstRTSPRealStream *stream; - gchar *str; - gint rulematches[MAX_RULEMATCHES]; - gint sel, j, n; - - media = gst_sdp_message_get_media (sdp, i); - - if (media->media && !strcmp (media->media, "data")) - continue; - - stream = g_new0 (GstRTSPRealStream, 1); - ctx->streams = g_list_append (ctx->streams, stream); - - READ_INT_M (media, "MaxBitRate", stream->max_bit_rate); - READ_INT_M (media, "AvgBitRate", stream->avg_bit_rate); - READ_INT_M (media, "MaxPacketSize", stream->max_packet_size); - READ_INT_M (media, "AvgPacketSize", stream->avg_packet_size); - READ_INT_M (media, "StartTime", stream->start_time); - READ_INT_M (media, "Preroll", stream->preroll); - READ_INT_M (media, "Duration", stream->duration); - READ_STRING (media, "StreamName", str, stream->stream_name_len); - stream->stream_name = g_strndup (str, stream->stream_name_len); - READ_STRING (media, "mimetype", str, stream->mime_type_len); - stream->mime_type = g_strndup (str, stream->mime_type_len); - - /* FIXME: Depending on the current bandwidth, we need to select one - * bandwidth out of a list offered by the server. Someone needs to write - * a parser for strings like - * - * #($Bandwidth < 67959),TimestampDelivery=T,DropByN=T,priority=9; - * #($Bandwidth >= 67959) && ($Bandwidth < 167959),AverageBandwidth=67959, - * Priority=9;#($Bandwidth >= 67959) && ($Bandwidth < 167959), - * AverageBandwidth=0,Priority=5,OnDepend=\"1\"; - * #($Bandwidth >= 167959) && ($Bandwidth < 267959), - * AverageBandwidth=167959,Priority=9; - * #($Bandwidth >= 167959) && ($Bandwidth < 267959),AverageBandwidth=0, - * Priority=5,OnDepend=\"3\";#($Bandwidth >= 267959), - * AverageBandwidth=267959,Priority=9;#($Bandwidth >= 267959), - * AverageBandwidth=0,Priority=5,OnDepend=\"5\"; - * - * As I don't know how to do that, I just use the first entry (sel = 0). - * But to give you a starting point, I offer you above string - * in the variable 'asm_rule_book'. - */ - READ_STRING (media, "ASMRuleBook", str, asm_rule_book_len); - stream->rulebook = gst_asm_rule_book_new (str); - - n = gst_asm_rule_book_match (stream->rulebook, vars, rulematches); - for (j = 0; j < n; j++) { - g_string_append_printf (rules, "stream=%u;rule=%u,", i, rulematches[j]); - } - - /* get the MLTI for the first matched rules */ - sel = rulematches[0]; - - READ_BUFFER_M (media, "OpaqueData", opaque_data, opaque_data_len); - - if (opaque_data_len < 4) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < 4", - opaque_data_len); - goto strange_opaque_data; - } - if (strncmp (opaque_data, "MLTI", 4)) { - GST_DEBUG_OBJECT (ctx, "no MLTI found, appending all"); - stream->type_specific_data_len = opaque_data_len; - stream->type_specific_data = g_memdup2 (opaque_data, opaque_data_len); - goto no_type_specific; - } - opaque_data += 4; - opaque_data_len -= 4; - - if (opaque_data_len < 2) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < 2", - opaque_data_len); - goto strange_opaque_data; - } - stream->num_rules = GST_READ_UINT16_BE (opaque_data); - opaque_data += 2; - opaque_data_len -= 2; - - if (sel >= stream->num_rules) { - GST_DEBUG_OBJECT (ctx, "sel %d >= num_rules %d", sel, stream->num_rules); - goto strange_opaque_data; - } - - if (opaque_data_len < 2 * sel) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT - " < 2 * sel (%d)", opaque_data_len, 2 * sel); - goto strange_opaque_data; - } - opaque_data += 2 * sel; - opaque_data_len -= 2 * sel; - - if (opaque_data_len < 2) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < 2", - opaque_data_len); - goto strange_opaque_data; - } - stream->codec = GST_READ_UINT16_BE (opaque_data); - opaque_data += 2; - opaque_data_len -= 2; - - if (opaque_data_len < 2 * (stream->num_rules - sel - 1)) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT - " < %d", opaque_data_len, 2 * (stream->num_rules - sel - 1)); - goto strange_opaque_data; - } - opaque_data += 2 * (stream->num_rules - sel - 1); - opaque_data_len -= 2 * (stream->num_rules - sel - 1); - - if (opaque_data_len < 2) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < 2", - opaque_data_len); - goto strange_opaque_data; - } - stream->num_rules = GST_READ_UINT16_BE (opaque_data); - opaque_data += 2; - opaque_data_len -= 2; - - if (stream->codec > stream->num_rules) { - GST_DEBUG_OBJECT (ctx, "codec %d > num_rules %d", stream->codec, - stream->num_rules); - goto strange_opaque_data; - } - - for (j = 0; j < stream->codec; j++) { - if (opaque_data_len < 4) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < 4", - opaque_data_len); - goto strange_opaque_data; - } - len = GST_READ_UINT32_BE (opaque_data); - opaque_data += 4; - opaque_data_len -= 4; - - if (opaque_data_len < len) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < len %d", - opaque_data_len, len); - goto strange_opaque_data; - } - opaque_data += len; - opaque_data_len -= len; - } - - if (opaque_data_len < 4) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < 4", - opaque_data_len); - goto strange_opaque_data; - } - stream->type_specific_data_len = GST_READ_UINT32_BE (opaque_data); - opaque_data += 4; - opaque_data_len -= 4; - - if (opaque_data_len < stream->type_specific_data_len) { - GST_DEBUG_OBJECT (ctx, "opaque_data_len %" G_GSIZE_FORMAT " < %d", - opaque_data_len, stream->type_specific_data_len); - goto strange_opaque_data; - } - stream->type_specific_data = - g_memdup2 (opaque_data, stream->type_specific_data_len); - - no_type_specific: - size = - 46 + stream->stream_name_len + stream->mime_type_len + - stream->type_specific_data_len; - ENSURE_SIZE (offset + size); - datap = data + offset; - - memcpy (datap, "MDPR", 4); - GST_WRITE_UINT32_BE (datap + 4, size); - GST_WRITE_UINT16_BE (datap + 8, 0); - GST_WRITE_UINT16_BE (datap + 10, i); - GST_WRITE_UINT32_BE (datap + 12, stream->max_bit_rate); - GST_WRITE_UINT32_BE (datap + 16, stream->avg_bit_rate); - GST_WRITE_UINT32_BE (datap + 20, stream->max_packet_size); - GST_WRITE_UINT32_BE (datap + 24, stream->avg_packet_size); - GST_WRITE_UINT32_BE (datap + 28, stream->start_time); - GST_WRITE_UINT32_BE (datap + 32, stream->preroll); - GST_WRITE_UINT32_BE (datap + 36, stream->duration); - datap += 40; - WRITE_STRING1 (datap, stream->stream_name, stream->stream_name_len); - WRITE_STRING1 (datap, stream->mime_type, stream->mime_type_len); - GST_WRITE_UINT32_BE (datap, stream->type_specific_data_len); - if (stream->type_specific_data_len) - memcpy (datap + 4, stream->type_specific_data, - stream->type_specific_data_len); - offset += size; - } - - /* destroy the rulebook hashtable now */ - g_hash_table_destroy (vars); - - /* strip final , if we added some stream rules */ - if (rules->len > 0) { - rules = g_string_truncate (rules, rules->len - 1); - } - - /* and store rules in the context */ - ctx->rules = g_string_free (rules, FALSE); - - /* DATA */ - size = 18; - ENSURE_SIZE (offset + size); - datap = data + offset; - - memcpy (datap, "DATA", 4); - GST_WRITE_UINT32_BE (datap + 4, size); - GST_WRITE_UINT16_BE (datap + 8, 0); - GST_WRITE_UINT32_BE (datap + 10, 0); /* number of packets */ - GST_WRITE_UINT32_BE (datap + 14, 0); /* next data header */ - offset += size; - - buf = gst_buffer_new_wrapped (data, offset); - - /* Set on caps */ - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER); - gst_structure_set (props, "config", GST_TYPE_BUFFER, buf, NULL); - gst_buffer_unref (buf); - - /* Overwrite encoding and media fields */ - gst_structure_set (props, "encoding-name", G_TYPE_STRING, "X-REAL-RDT", NULL); - gst_structure_set (props, "media", G_TYPE_STRING, "application", NULL); - - return TRUE; - - /* ERRORS */ -strange_opaque_data: - { - g_string_free (rules, TRUE); - g_hash_table_destroy (vars); - g_free (data); - - GST_ELEMENT_ERROR (ctx, RESOURCE, WRITE, ("Strange opaque data."), (NULL)); - return FALSE; - } -} - -static GstRTSPResult -rtsp_ext_real_stream_select (GstRTSPExtension * ext, GstRTSPUrl * url) -{ - GstRTSPReal *ctx = (GstRTSPReal *) ext; - GstRTSPResult res; - GstRTSPMessage request = { 0 }; - GstRTSPMessage response = { 0 }; - gchar *req_url; - - if (!ctx->isreal) - return GST_RTSP_OK; - - if (!ctx->rules) - return GST_RTSP_OK; - - req_url = gst_rtsp_url_get_request_uri (url); - - /* create SET_PARAMETER */ - if ((res = gst_rtsp_message_init_request (&request, GST_RTSP_SET_PARAMETER, - req_url)) < 0) - goto create_request_failed; - - g_free (req_url); - - gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SUBSCRIBE, ctx->rules); - - /* send SET_PARAMETER */ - if ((res = gst_rtsp_extension_send (ext, &request, &response)) < 0) - goto send_error; - - gst_rtsp_message_unset (&request); - gst_rtsp_message_unset (&response); - - return GST_RTSP_OK; - - /* ERRORS */ -create_request_failed: - { - GST_ELEMENT_ERROR (ctx, LIBRARY, INIT, - ("Could not create request."), (NULL)); - g_free (req_url); - goto reset; - } -send_error: - { - GST_ELEMENT_ERROR (ctx, RESOURCE, WRITE, - ("Could not send message."), (NULL)); - goto reset; - } -reset: - { - gst_rtsp_message_unset (&request); - gst_rtsp_message_unset (&response); - return res; - } -} - -static void gst_rtsp_real_extension_init (gpointer g_iface, - gpointer iface_data); -static void gst_rtsp_real_finalize (GObject * obj); - -#define gst_rtsp_real_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE (GstRTSPReal, gst_rtsp_real, GST_TYPE_ELEMENT, - G_IMPLEMENT_INTERFACE (GST_TYPE_RTSP_EXTENSION, - gst_rtsp_real_extension_init)); -GST_ELEMENT_REGISTER_DEFINE (rtspreal, "rtspreal", - GST_RANK_MARGINAL, GST_TYPE_RTSP_REAL); - -static void -gst_rtsp_real_class_init (GstRTSPRealClass * g_class) -{ - GObjectClass *gobject_class = (GObjectClass *) g_class; - GstElementClass *gstelement_class = (GstElementClass *) g_class; - - gobject_class->finalize = gst_rtsp_real_finalize; - - gst_element_class_set_static_metadata (gstelement_class, - "RealMedia RTSP Extension", "Network/Extension/Protocol", - "Extends RTSP so that it can handle RealMedia setup", - "Wim Taymans "); - - GST_DEBUG_CATEGORY_INIT (rtspreal_debug, "rtspreal", 0, - "RealMedia RTSP extension"); -} - -static void -gst_rtsp_real_init (GstRTSPReal * rtspreal) -{ - rtspreal->isreal = FALSE; -} - -static void -gst_rtsp_stream_free (GstRTSPRealStream * stream) -{ - g_free (stream->stream_name); - g_free (stream->mime_type); - gst_asm_rule_book_free (stream->rulebook); - g_free (stream->type_specific_data); - - g_free (stream); -} - -static void -gst_rtsp_real_finalize (GObject * obj) -{ - GstRTSPReal *r = (GstRTSPReal *) obj; - - g_list_foreach (r->streams, (GFunc) gst_rtsp_stream_free, NULL); - g_list_free (r->streams); - g_free (r->rules); - - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -gst_rtsp_real_extension_init (gpointer g_iface, gpointer iface_data) -{ - GstRTSPExtensionInterface *iface = (GstRTSPExtensionInterface *) g_iface; - - iface->before_send = rtsp_ext_real_before_send; - iface->after_send = rtsp_ext_real_after_send; - iface->parse_sdp = rtsp_ext_real_parse_sdp; - iface->stream_select = rtsp_ext_real_stream_select; - iface->get_transports = rtsp_ext_real_get_transports; -} diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.h b/subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.h deleted file mode 100644 index f5cea96d5b..0000000000 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rtspreal.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_RTSP_REAL_H__ -#define __GST_RTSP_REAL_H__ - -#include - -#include "asmrules.h" - -G_BEGIN_DECLS - -#define GST_TYPE_RTSP_REAL (gst_rtsp_real_get_type()) -#define GST_IS_RTSP_REAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTSP_REAL)) -#define GST_IS_RTSP_REAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTSP_REAL)) -#define GST_RTSP_REAL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTSP_REAL, GstRTSPReal)) -#define GST_RTSP_REAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTSP_REAL, GstRTSPRealClass)) - -typedef struct _GstRTSPReal GstRTSPReal; -typedef struct _GstRTSPRealClass GstRTSPRealClass; - -typedef struct _GstRTSPRealStream GstRTSPRealStream; - -struct _GstRTSPRealStream { - guint id; - guint max_bit_rate; - guint avg_bit_rate; - guint max_packet_size; - guint avg_packet_size; - guint start_time; - guint preroll; - guint duration; - gchar *stream_name; - guint stream_name_len; - gchar *mime_type; - guint mime_type_len; - - GstASMRuleBook *rulebook; - - gchar *type_specific_data; - guint type_specific_data_len; - - guint16 num_rules, j, sel, codec; -}; - -struct _GstRTSPReal { - GstElement element; - - gchar checksum[34]; - gchar challenge2[64]; - gchar etag[64]; - gboolean isreal; - - guint n_streams; - GList *streams; - - guint max_bit_rate; - guint avg_bit_rate; - guint max_packet_size; - guint avg_packet_size; - guint duration; - - gchar *rules; -}; - -struct _GstRTSPRealClass { - GstElementClass parent_class; -}; - -GType gst_rtsp_real_get_type(void); - -GST_ELEMENT_REGISTER_DECLARE (rtspreal); - - -G_END_DECLS - -#endif /* __GST_RTSP_REAL_H__ */