📄 udpoutput.c
字号:
{ state->instance.SendPacket = RTPOutputSendPacket; state->instance.SendBlock = NULL; } else { state->instance.SendPacket = UDPOutputSendPacket; state->instance.SendBlock = UDPOutputSendBlock; } state->instance.DestroyInstance = UDPOutputDestroy; LogModule(LOG_DEBUG, UDPOUTPUT, "UDP Host \"%s\" Port \"%s\" TTL %d\n", hostbuffer, portbuffer, ttl);#ifdef USE_GETADDRINFO { struct addrinfo *addrinfo, hints; memset((void *)&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_ADDRCONFIG; if ((getaddrinfo(hostbuffer, portbuffer, &hints, &addrinfo) != 0) || (addrinfo == NULL)) { LogModule(LOG_DEBUG, UDPOUTPUT,"Failed to set UDP target address\n"); free(state); return NULL; } if (addrinfo->ai_addrlen > sizeof(struct sockaddr_storage)) { freeaddrinfo(addrinfo); free(state); return NULL; } state->addressLen = addrinfo->ai_addrlen; memcpy(&state->address, addrinfo->ai_addr, addrinfo->ai_addrlen); freeaddrinfo(addrinfo); }#else { struct sockaddr_in sockaddr; struct hostent *hostinfo; sockaddr.sin_port=htons(atoi(portbuffer)); hostinfo = gethostbyname(hostbuffer); if (hostinfo == NULL) { LogModule(LOG_DEBUG, UDPOUTPUT,"Failed to set UDP target address\n"); return NULL; } sockaddr.sin_family = hostinfo->h_addrtype; memcpy((char *)&(sockaddr.sin_addr), hostinfo->h_addr, hostinfo->h_length); memcpy(&state->address, &sockaddr, sizeof(sockaddr)); state->addressLen = sizeof(sockaddr); }#endif state->socket = UDPCreateSocket(state->address.ss_family); if (state->socket == -1) { LogModule(LOG_DEBUG, UDPOUTPUT,"Failed to create UDP socket\n"); free(state); return NULL; } if (IsMulticastAddress(&state->address)) { if (ttl > 1) { setsockopt(state->socket,IPPROTO_IP,IP_MULTICAST_TTL, &ttl,sizeof(ttl)); } CreateSAPSession(state, rtp, ttl, sessionName); } state->datagramFullCount = MAX_TS_PACKETS_PER_DATAGRAM; return &state->instance;}static void UDPOutputDestroy(DeliveryMethodInstance_t *this){ struct UDPOutputState_t *state = (struct UDPOutputState_t *)this; close(state->socket); if (state->sapHandle) { SAPServerDeleteSession(state->sapHandle); } free(state);}static void UDPOutputSendPacket(DeliveryMethodInstance_t *this, TSPacket_t *packet){ struct UDPOutputState_t *state = (struct UDPOutputState_t*)this; state->outputBuffer[state->tsPacketCount++] = *packet; if (state->tsPacketCount >= state->datagramFullCount) { UDPSendTo(state->socket, (char*)state->outputBuffer, state->datagramFullCount * TSPACKET_SIZE, (struct sockaddr *)(&state->address), state->addressLen); state->tsPacketCount = 0; }}static void UDPOutputSendBlock(DeliveryMethodInstance_t *this, void *block, unsigned long blockLen){ struct UDPOutputState_t *state = (struct UDPOutputState_t*)this; UDPSendTo(state->socket, (char*)block, blockLen, (struct sockaddr *)(&state->address), state->addressLen);}static void RTPOutputSendPacket(DeliveryMethodInstance_t *this, TSPacket_t *packet){ struct UDPOutputState_t *state = (struct UDPOutputState_t*)this; state->outputBuffer[state->tsPacketCount++] = *packet; if (state->tsPacketCount >= state->datagramFullCount) { RTPHeaderInit(state->rtpHeader, state->sequence); UDPSendTo(state->socket, (char*)state->rtpHeader, (state->datagramFullCount * TSPACKET_SIZE) + RTP_HEADER_SIZE, (struct sockaddr *)(&state->address), state->addressLen); state->tsPacketCount = 0; state->sequence ++; }}static void RTPHeaderInit(uint8_t *header, uint16_t sequence){ uint32_t temp; struct timeval tv; gettimeofday(&tv,(struct timezone*) NULL); /* Flags and payload type */ header[0] = (2 << 6); /* Version 2, No Padding, No Extensions, No CSRC count */ header[1] = 33; /* No Marker, Payload type MP2T */ /* Sequence */ header[2] = (uint8_t) (sequence >> 8) & 0xff; header[3] = (uint8_t) (sequence >> 0) & 0xff; /* Time stamp */ temp = ((tv.tv_sec%1000000)*1000000 + tv.tv_usec)/11; /* approximately a 90Khz clock (1000000/90000 = 11.1111111...)*/ header[4] = (temp >> 24) & 0xff; header[5] = (temp >> 16) & 0xff; header[6] = (temp >> 8) & 0xff; header[7] = temp & 0xff; /* SSRC (Not implemented) */ header[8] = 0x0f; header[9] = 0x0f; header[10] = 0x0f; header[11] = 0x0f;}static void CreateSAPSession(struct UDPOutputState_t *state, bool rtp, unsigned char ttl, char *sessionName){ char sdp[1000] = {0}; char hostname[256]; char addrtype[4]; char ipaddr[256]; char typevalue[256]; in_port_t port = 0; gethostname(hostname, sizeof(hostname) - 1); #ifdef USE_GETADDRINFO { struct addrinfo *addrinfo, hints; memset((void *)&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_ADDRCONFIG; if ((getaddrinfo(hostname, NULL, &hints, &addrinfo) != 0) || (addrinfo == NULL)) { LogModule(LOG_DEBUG, UDPOUTPUT,"Failed to get host address\n"); return; } if (addrinfo->ai_addrlen > sizeof(struct sockaddr_storage)) { freeaddrinfo(addrinfo); return; } if (addrinfo->ai_family == AF_INET) { struct sockaddr_in *inaddr = (struct sockaddr_in *) addrinfo->ai_addr; inet_ntop(AF_INET, &inaddr->sin_addr, ipaddr, sizeof(ipaddr)); strcpy(addrtype, "IP4"); } else { struct sockaddr_in6 *in6addr = (struct sockaddr_in6 *) addrinfo->ai_addr; inet_ntop(AF_INET6, &in6addr->sin6_addr, ipaddr, sizeof(ipaddr)); strcpy(addrtype, "IP6"); } freeaddrinfo(addrinfo); }#else { struct hostent *hostinfo; hostinfo = gethostbyname(hostname); if (hostinfo == NULL) { LogModule(LOG_DEBUG, UDPOUTPUT,"Failed to get host address\n"); return; } inet_ntop(hostinfo->h_addrtype, hostinfo->h_addr, ipaddr, sizeof(ipaddr)); if (hostinfo->h_addrtype) { strcpy(addrtype, "IP4"); } else { strcpy(addrtype, "IP6"); } }#endif#define SDPAdd(type,value) \ do{\ sprintf(typevalue,"%c=" value "\r\n", type);\ strcat(sdp,typevalue);\ }while(0) #define SDPAddf(type,fmt,values...) \ do{\ sprintf(typevalue,"%c=" fmt "\r\n", type, values);\ strcat(sdp,typevalue);\ }while(0) SDPAdd('v',"0"); SDPAddf('o',"- %ld 0 IN %s %s", time(NULL), addrtype, ipaddr); SDPAddf('s',"%s", sessionName); if (state->address.ss_family == AF_INET) { struct sockaddr_in *inaddr = (struct sockaddr_in *) &state->address; inet_ntop(AF_INET, &inaddr->sin_addr, ipaddr, sizeof(ipaddr)); SDPAddf('c',"IN IP4 %s/%d", ipaddr,ttl); port = ntohs(inaddr->sin_port); }#ifdef USE_GETADDRINFO else { struct sockaddr_in6 *in6addr = (struct sockaddr_in6 *) &state->address; inet_ntop(AF_INET6, &in6addr->sin6_addr, ipaddr, sizeof(ipaddr)); SDPAddf('c',"IN IP6 %s", ipaddr); port = ntohs(in6addr->sin6_port); }#endif if (rtp) { SDPAddf('m',"video %d RTP/AVP 33", port); } else { SDPAddf('m',"video %d udp 33", port); } state->sapHandle = SAPServerAddSession(&state->address, sdp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -