int OutputProcessor::packageAudio(unsigned char* inBuff, int inBuffLen, unsigned char* outBuff, long int pts) { if (audioPackager == 0) { ELOG_DEBUG("No se ha inicializado el codec de output audio RTP"); return -1; } timeval time; gettimeofday(&time, NULL); long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000); RtpHeader head; head.setSeqNumber(audioSeqnum_++); // head.setTimestamp(millis*8); head.setMarker(1); if (pts==0){ // head.setTimestamp(audioSeqnum_*160); head.setTimestamp(av_rescale(audioSeqnum_, (mediaInfo.audioCodec.sampleRate/1000), 1)); }else{ // head.setTimestamp(pts*8); head.setTimestamp(av_rescale(pts, mediaInfo.audioCodec.sampleRate,1000)); } head.setSSRC(44444); head.setPayloadType(mediaInfo.rtpAudioInfo.PT); // memcpy (rtpAudioBuffer_, &head, head.getHeaderLength()); // memcpy(&rtpAudioBuffer_[head.getHeaderLength()], inBuff, inBuffLen); memcpy (outBuff, &head, head.getHeaderLength()); memcpy(&outBuff[head.getHeaderLength()], inBuff, inBuffLen); // sink_->sendData(rtpBuffer_, l); // rtpReceiver_->receiveRtpData(rtpBuffer_, (inBuffLen + RTP_HEADER_LEN)); return (inBuffLen+head.getHeaderLength()); }
void WebRtcConnection::writeSsrc(char* buf, int len, unsigned int ssrc) { ELOG_DEBUG("LEN %d", len); RtpHeader *head = reinterpret_cast<RtpHeader*> (buf); RtcpHeader *chead = reinterpret_cast<RtcpHeader*> (buf); //if it is RTCP we check it it is a compound packet if (chead->isRtcp()) { char* movingBuf = buf; int rtcpLength = 0; int totalLength = 0; do{ movingBuf+=rtcpLength; RtcpHeader *chead= reinterpret_cast<RtcpHeader*>(movingBuf); rtcpLength= (ntohs(chead->length)+1)*4; totalLength+= rtcpLength; ELOG_DEBUG("Is RTCP, prev SSRC %u, new %u, len %d ", chead->getSSRC(), ssrc, rtcpLength); chead->ssrc=htonl(ssrc); if (chead->packettype == RTCP_PS_Feedback_PT){ FirHeader *thefir = reinterpret_cast<FirHeader*>(movingBuf); if (thefir->fmt == 4){ // It is a FIR Packet, we generate it this->sendPLI(); } } } while(totalLength<len); } else { head->setSSRC(ssrc); } }
int OutputProcessor::packageVideo(unsigned char* inBuff, int buffSize, unsigned char* outBuff, long int pts) { if (videoPackager == 0) { ELOG_DEBUG("No se ha inicailizado el codec de output vídeo RTP"); return -1; } // ELOG_DEBUG("To packetize %u", buffSize); if (buffSize <= 0) return -1; RtpVP8Fragmenter frag(inBuff, buffSize, 1100); bool lastFrame = false; unsigned int outlen = 0; timeval time; gettimeofday(&time, NULL); long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000); // timestamp_ += 90000 / mediaInfo.videoCodec.frameRate; //int64_t pts = av_rescale(lastPts_, 1000000, (long int)video_time_base_); do { outlen = 0; frag.getPacket(outBuff, &outlen, &lastFrame); RtpHeader rtpHeader; rtpHeader.setMarker(lastFrame?1:0); rtpHeader.setSeqNumber(seqnum_++); if (pts==0){ rtpHeader.setTimestamp(av_rescale(millis, 90000, 1000)); }else{ rtpHeader.setTimestamp(av_rescale(pts, 90000, 1000)); } rtpHeader.setSSRC(55543); rtpHeader.setPayloadType(100); memcpy(rtpBuffer_, &rtpHeader, rtpHeader.getHeaderLength()); memcpy(&rtpBuffer_[rtpHeader.getHeaderLength()],outBuff, outlen); int l = outlen + rtpHeader.getHeaderLength(); // sink_->sendData(rtpBuffer_, l); rtpReceiver_->receiveRtpData(rtpBuffer_, l); } while (!lastFrame); return 0; }
void WebRtcConnection::onTransportData(char* buf, int len, Transport *transport) { if (audioSink_ == NULL && videoSink_ == NULL && fbSink_==NULL){ return; } // PROCESS STATS if (this->statsListener_){ // if there is no listener we dont process stats RtpHeader *head = reinterpret_cast<RtpHeader*> (buf); if (head->payloadtype != RED_90000_PT && head->payloadtype != PCMU_8000_PT) thisStats_.processRtcpPacket(buf, len); } RtcpHeader* chead = reinterpret_cast<RtcpHeader*>(buf); // DELIVER FEEDBACK (RR, FEEDBACK PACKETS) if (chead->isFeedback()){ if (fbSink_ != NULL) { fbSink_->deliverFeedback(buf,len); } } else { // RTP or RTCP Sender Report if (bundle_) { // Check incoming SSRC RtpHeader *head = reinterpret_cast<RtpHeader*> (buf); RtcpHeader *chead = reinterpret_cast<RtcpHeader*> (buf); unsigned int recvSSRC; if (chead->packettype == RTCP_Sender_PT) { //Sender Report recvSSRC = chead->getSSRC(); }else{ recvSSRC = head->getSSRC(); } // Deliver data if (recvSSRC==this->getVideoSourceSSRC() || recvSSRC==this->getVideoSinkSSRC()) { videoSink_->deliverVideoData(buf, len); } else if (recvSSRC==this->getAudioSourceSSRC() || recvSSRC==this->getAudioSinkSSRC()) { audioSink_->deliverAudioData(buf, len); } else { ELOG_ERROR("Unknown SSRC %u, localVideo %u, remoteVideo %u, ignoring", recvSSRC, this->getVideoSourceSSRC(), this->getVideoSinkSSRC()); } } else if (transport->mediaType == AUDIO_TYPE) { if (audioSink_ != NULL) { RtpHeader *head = reinterpret_cast<RtpHeader*> (buf); // Firefox does not send SSRC in SDP if (this->getAudioSourceSSRC() == 0) { ELOG_DEBUG("Audio Source SSRC is %u", head->getSSRC()); this->setAudioSourceSSRC(head->getSSRC()); //this->updateState(TRANSPORT_READY, transport); } head->setSSRC(this->getAudioSinkSSRC()); audioSink_->deliverAudioData(buf, len); } } else if (transport->mediaType == VIDEO_TYPE) { if (videoSink_ != NULL) { RtpHeader *head = reinterpret_cast<RtpHeader*> (buf); RtcpHeader *chead = reinterpret_cast<RtcpHeader*> (buf); // Firefox does not send SSRC in SDP if (this->getVideoSourceSSRC() == 0) { unsigned int recvSSRC; if (chead->packettype == RTCP_Sender_PT) { //Sender Report recvSSRC = chead->getSSRC(); } else { recvSSRC = head->getSSRC(); } ELOG_DEBUG("Video Source SSRC is %u", recvSSRC); this->setVideoSourceSSRC(recvSSRC); //this->updateState(TRANSPORT_READY, transport); } // change ssrc for RTP packets, don't touch here if RTCP if (chead->packettype != RTCP_Sender_PT) { head->setSSRC(this->getVideoSinkSSRC()); } videoSink_->deliverVideoData(buf, len); } } } }