📄 udpoutput.c
字号:
/*Copyright (C) 2006 Adam CharrettThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USAudpoutput.cUDP Output Delivery Method handler.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netdb.h>#include <sys/time.h>#include "plugin.h"#include "ts.h"#include "udp.h"#include "deliverymethod.h"#include "logging.h"#include "sap.h"/******************************************************************************** Defines ********************************************************************************/#define MTU 1400 /* Conservative estimate */#define IP_HEADER (5*4)#define UDP_HEADER (2*4)#define MAX_TS_PACKETS_PER_DATAGRAM ((MTU - (IP_HEADER+UDP_HEADER)) / sizeof(TSPacket_t))#define RTP_HEADER_SIZE 12/* Default output targets if only host or port part is given */#define DEFAULT_HOST "localhost"#define DEFAULT_PORT "1234"#ifdef __CYGWIN__#define LogModule(_l, _m, _f...) fprintf(stderr, "%-15s : ", _m); fprintf(stderr, _f)#endif/******************************************************************************** Typedefs ********************************************************************************/struct UDPOutputState_t{ /* !!! MUST BE THE FIRST FIELD IN THE STRUCTURE !!! * As the address of this field will be passed to all delivery method * functions and a 0 offset is assumed! */ DeliveryMethodInstance_t instance; int socket; socklen_t addressLen; struct sockaddr_storage address; SAPSessionHandle_t sapHandle; int datagramFullCount; int tsPacketCount; uint16_t sequence; /* rtpHeader must always come before outputBuffer as the order is important when sending RTP packets as rtpHeader is passed as the address of the buffer to send! */ uint8_t rtpHeader[RTP_HEADER_SIZE]; TSPacket_t outputBuffer[MAX_TS_PACKETS_PER_DATAGRAM];};/******************************************************************************** Prototypes ********************************************************************************/void UDPOutputInstall(bool installed);static bool UDPOutputCanHandle(char *mrl);static DeliveryMethodInstance_t *UDPOutputCreate(char *arg);static void UDPOutputSendPacket(DeliveryMethodInstance_t *this, TSPacket_t *packet);static void UDPOutputSendBlock(DeliveryMethodInstance_t *this, void *block, unsigned long blockLen);static void UDPOutputDestroy(DeliveryMethodInstance_t *this);static void RTPOutputSendPacket(DeliveryMethodInstance_t *this, TSPacket_t *packet);static void RTPHeaderInit(uint8_t *header, uint16_t sequence);static void CreateSAPSession(struct UDPOutputState_t *state, bool rtp, unsigned char ttl, char *sessionName);/******************************************************************************** Global variables ********************************************************************************//** Constants for the start of the MRL **/#define PREFIX_LEN (sizeof(UDPPrefix) - 1)const char UDPPrefix[] = "udp://";const char RTPPrefix[] = "rtp://";/** Plugin Interface **/DeliveryMethodHandler_t UDPOutputHandler = { UDPOutputCanHandle, UDPOutputCreate };const char UDPOUTPUT[] = "UDPOutput";/******************************************************************************** Plugin Setup ********************************************************************************/PLUGIN_FEATURES( PLUGIN_FEATURE_DELIVERYMETHOD(UDPOutputHandler), PLUGIN_FEATURE_INSTALL(UDPOutputInstall));#ifdef __CYGWIN__#define PluginInterface UDPOutputPluginInterface#endifPLUGIN_INTERFACE_F( PLUGIN_FOR_ALL, "UDPOutput", "0.3", "UDP Delivery methods.\n" "Use udp://[<host>:[<port>[:<ttl>[:session name]]]] for simple raw TS packets in a UDP datagram.\n" "Use rtp://[<host>:[<port>[:<ttl>[:session name]]]] for RTP encapsulation.\n" "Default host is localhost, default port is 1234", "charrea6@users.sourceforge.net");void UDPOutputInstall(bool installed){ if (installed) { SAPServerInit(); } else { SAPServerDeinit(); }}/******************************************************************************** Delivery Method Functions ********************************************************************************/static bool UDPOutputCanHandle(char *mrl){ return (strncmp(UDPPrefix, mrl, PREFIX_LEN) == 0) || (strncmp(RTPPrefix, mrl, PREFIX_LEN) == 0);}static DeliveryMethodInstance_t *UDPOutputCreate(char *arg){ struct UDPOutputState_t *state; int i = 0; unsigned char ttl = 1; char hostbuffer[256]; char portbuffer[6]; /* 65536\0 */ char *sessionName= "DVBStreamer"; bool rtp; hostbuffer[0] = 0; portbuffer[0] = 0; /* * Process the mrl */ /* Is this a RTP MRL? */ rtp = (strncmp(RTPPrefix, arg, PREFIX_LEN) == 0); /* Ignore the prefix */ arg += PREFIX_LEN; if (arg[0] == '[') { arg ++; LogModule(LOG_DEBUG, UDPOUTPUT, "IPv6 Address! %s\n", arg); for (i = 0;arg[i] && (arg[i] != ']'); i ++) { hostbuffer[i] = arg[i]; } hostbuffer[i] = 0; arg += i; if (*arg == ']') { arg ++; } } else { LogModule(LOG_DEBUG, UDPOUTPUT, "IPv4 Address! %s\n", arg); for (i = 0;arg[i] && (arg[i] != ':'); i ++) { hostbuffer[i] = arg[i]; } hostbuffer[i] = 0; arg += i; } /* Port */ if (*arg == ':') { arg ++; LogModule(LOG_DEBUG, UDPOUTPUT, "Port parameter detected! %s\n", arg); /* Process port */ for (i = 0;arg[i] && (arg[i] != ':'); i ++) { portbuffer[i] = arg[i]; } portbuffer[i] = 0; arg += i; } /* TTL */ if (*arg == ':') { char ttlbuffer[4]; arg ++; LogModule(LOG_DEBUG, UDPOUTPUT, "TTL parameter detected! %s\n", arg); for (i = 0;arg[i] && (arg[i] != ':') && (i < 3); i ++) { ttlbuffer[i] = arg[i]; } /* process ttl */ ttl = (unsigned char)atoi(ttlbuffer) & 255; arg += i; } /* Anything else is the session name for SAP/SDP */ if (*arg == ':') { arg ++; sessionName = arg; } /* * Lookup the host name and port */ if (hostbuffer[0] == 0) { strcpy(hostbuffer, DEFAULT_HOST); } if (portbuffer[0] == 0) { strcpy(portbuffer, DEFAULT_PORT); } state = calloc(1, sizeof(struct UDPOutputState_t)); if (state == NULL) { LogModule(LOG_DEBUG, UDPOUTPUT, "Failed to allocate UDP Output state\n"); return NULL; } if (rtp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -