private static void SendRTPFromCamera() { try { unsafe { SIPSorceryMedia.MFVideoSampler videoSampler = new SIPSorceryMedia.MFVideoSampler(); //List<VideoMode> webcamModes = new List<VideoMode>(); //int deviceCount = videoSampler.GetVideoDevices(ref webcamModes); //foreach (var videoMode in webcamModes) //{ // Console.WriteLine(videoMode.DeviceFriendlyName + " " + (videoMode.VideoSubTypeFriendlyName ?? videoMode.VideoSubType.ToString()) + " " + videoMode.Width + "x" + videoMode.Height + "."); //} videoSampler.Init(_webcamIndex, _webcamVideoSubType, _webcamWidth, _webcamHeight); SIPSorceryMedia.VPXEncoder vpxEncoder = new VPXEncoder(); vpxEncoder.InitEncoder(_webcamWidth, _webcamHeight); SIPSorceryMedia.ImageConvert colorConverter = new ImageConvert(); byte pictureID = 0x1; byte[] sampleBuffer = null; byte[] encodedBuffer = new byte[4096]; while (true) { if (_webRTCClients.Any(x => x.STUNExchangeComplete == true && x.IsDtlsNegotiationComplete == true)) { int result = videoSampler.GetSample(ref sampleBuffer); if (result != 0) { Console.WriteLine("Video sampler returned a null sample."); } else { //Console.WriteLine("Got managed sample " + sample.Buffer.Length + ", is key frame " + sample.IsKeyFrame + "."); fixed (byte* p = sampleBuffer) { byte[] convertedFrame = null; colorConverter.ConvertToI420(p, _webcamVideoSubType, Convert.ToInt32(_webcamWidth), Convert.ToInt32(_webcamHeight), ref convertedFrame); //int encodeResult = vpxEncoder.Encode(p, sampleBuffer.Length, 1, ref encodedBuffer); fixed (byte* q = convertedFrame) { int encodeResult = vpxEncoder.Encode(q, sampleBuffer.Length, 1, ref encodedBuffer); if (encodeResult != 0) { Console.WriteLine("VPX encode of video sample failed."); continue; } } } lock (_webRTCClients) { foreach (var client in _webRTCClients.Where(x => x.STUNExchangeComplete && x.IsDtlsNegotiationComplete == true)) { try { //if (client.LastRtcpSenderReportSentAt == DateTime.MinValue) //{ // logger.Debug("Sending RTCP report to " + client.SocketAddress + "."); // // Send RTCP report. // RTCPPacket rtcp = new RTCPPacket(client.SSRC, 0, 0, 0, 0); // byte[] rtcpBuffer = rtcp.GetBytes(); // _webRTCReceiverClient.BeginSend(rtcpBuffer, rtcpBuffer.Length, client.SocketAddress, null, null); // //int rtperr = client.SrtpContext.ProtectRTP(rtcpBuffer, rtcpBuffer.Length - SRTP_AUTH_KEY_LENGTH); //} //Console.WriteLine("Sending VP8 frame of " + encodedBuffer.Length + " bytes to " + client.SocketAddress + "."); client.LastTimestamp = (client.LastTimestamp == 0) ? RTSPSession.DateTimeToNptTimestamp32(DateTime.Now) : client.LastTimestamp + TIMESTAMP_SPACING; for (int index = 0; index * RTP_MAX_PAYLOAD < encodedBuffer.Length; index++) { int offset = (index == 0) ? 0 : (index * RTP_MAX_PAYLOAD); int payloadLength = (offset + RTP_MAX_PAYLOAD < encodedBuffer.Length) ? RTP_MAX_PAYLOAD : encodedBuffer.Length - offset; byte[] vp8HeaderBytes = (index == 0) ? new byte[] { 0x10 } : new byte[] { 0x00 }; RTPPacket rtpPacket = new RTPPacket(payloadLength + SRTP_AUTH_KEY_LENGTH + vp8HeaderBytes.Length); rtpPacket.Header.SyncSource = client.SSRC; rtpPacket.Header.SequenceNumber = client.SequenceNumber++; rtpPacket.Header.Timestamp = client.LastTimestamp; rtpPacket.Header.MarkerBit = ((offset + payloadLength) >= encodedBuffer.Length) ? 1 : 0; // Set marker bit for the last packet in the frame. rtpPacket.Header.PayloadType = PAYLOAD_TYPE_ID; Buffer.BlockCopy(vp8HeaderBytes, 0, rtpPacket.Payload, 0, vp8HeaderBytes.Length); Buffer.BlockCopy(encodedBuffer, offset, rtpPacket.Payload, vp8HeaderBytes.Length, payloadLength); var rtpBuffer = rtpPacket.GetBytes(); //_webRTCReceiverClient.Send(rtpBuffer, rtpBuffer.Length, _wiresharpEP); int rtperr = client.SrtpContext.ProtectRTP(rtpBuffer, rtpBuffer.Length - SRTP_AUTH_KEY_LENGTH); if (rtperr != 0) { logger.Warn("SRTP packet protection failed, result " + rtperr + "."); } else { //logger.Debug("Sending RTP, offset " + offset + ", frame bytes " + payloadLength + ", vp8 header bytes " + vp8HeaderBytes.Length + ", timestamp " + rtpPacket.Header.Timestamp + ", seq # " + rtpPacket.Header.SequenceNumber + " to " + client.SocketAddress + "."); //_webRTCReceiverClient.Send(rtpBuffer, rtpBuffer.Length, client.SocketAddress); _webRTCReceiverClient.BeginSend(rtpBuffer, rtpBuffer.Length, client.SocketAddress, null, null); } } } catch (Exception sendExcp) { logger.Error("SendRTP exception sending to " + client.SocketAddress + ". " + sendExcp.Message); } } } pictureID++; if (pictureID > 127) { pictureID = 1; } encodedBuffer = null; sampleBuffer = null; } } } } } catch (Exception excp) { Console.WriteLine("Exception SendRTP. " + excp); } }