using LibVLCSharp.Shared;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using Serilog.Extensions.Logging;
using SIPSorcery.Media;
using SIPSorcery.Net;
using SIPSorcery.Sys;
using SIPSorceryMedia.Abstractions;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Timers;
using Websocket.Client;
namespace JanusWebRTCClient
{
class Program
{
private const string JANUS_WEBSOCKET_URL = "ws://192.168.29.198/janus/ws?auth_token=53aab30177eac083a5cf2e73ba0bc4bd3bc7b83639905f8fde06f6b80a109a57";
static async Task Main(string[] args)
{
// 初始化日志
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
SIPSorcery.LogFactory.Set(new SerilogLoggerFactory(Log.Logger));
Console.WriteLine("Starting Janus WebRTC client...");
LibVLCSharp.Shared.Core.Initialize();
var libVlc = new LibVLC();
var mediaPlayer = new MediaPlayer(libVlc);
var webRTC = new WebRTCVideo();
webRTC.OnConnected = (sdpPath) =>
{
// 关键:使用 demux=h264 来播放原始H.264流
var options = new[]
{
":no-audio",
":demux=any",
//":rtp-max-dropout=0",
//":rtp-max-misorder=0",
":file-caching=0",
":live-caching=0",
":network-caching=0",
//":fps=30",
//":clock-jitter=0",
//":skip-frames",
//":drop-late-frames",
//":avcodec-threads=0",
":avcodec-hw=any"
};
using var media = new Media(libVlc, new Uri(sdpPath), options);
mediaPlayer.Play(media);
};
webRTC.OnDisConnected = () =>
{
mediaPlayer.Stop();
};
await webRTC.Start(JANUS_WEBSOCKET_URL);
Console.ReadKey();
}
private class WebRTCVideo : IDisposable
{
private int _videoPort;
private string _sdpPath = "";
private WebsocketClient ws;
private RTCPeerConnection _peerConnection;
private RTPSession _rtpSession;
private System.Timers.Timer timer;
private static long? _sessionId;
private static long? _handleId;
public Action<string> OnConnected { get; set; }
public Action OnDisConnected { get; set; }
public async Task Start(string url)
{
_sdpPath = Path.GetTempFileName() + ".sdp";
_videoPort = 5018;
await ConnectToJanus(url);
timer = new System.Timers.Timer(15000);
timer.Elapsed += (s, e) =>
{
var keepaliveReq = new { janus = "keepalive", transaction = Guid.NewGuid().ToString("N").Substring(0, 12) };
SendJanusMessage(ws, keepaliveReq);
};
}
private async Task CreateAndSendAnswer(WebsocketClient ws, string sdpOffer)
{
RTCConfiguration config = new RTCConfiguration
{
iceServers = new List<RTCIceServer> { new RTCIceServer { urls = "stun:stun.cloudflare.com" } },
X_BindAddress = IPAddress.Parse("192.168.28.224")
};
_peerConnection = new RTCPeerConnection(config);
_peerConnection.onicecandidate += (candidate) =>
{
if (candidate != null)
{
var trickleMsg = new
{
janus = "trickle",
candidate = new
{
candidate = $"candidate:{candidate.candidate}",
sdpMid = candidate.sdpMid,
sdpMLineIndex = candidate.sdpMLineIndex
},
transaction = Guid.NewGuid().ToString("N").Substring(0, 12)
};
SendJanusMessage(ws, trickleMsg);
var trickleCompletedMsg = new
{
janus = "trickle",
candidate = new { completed = true },
transaction = Guid.NewGuid().ToString("N").Substring(0, 12)
};
SendJanusMessage(ws, trickleCompletedMsg);
}
};
// 监听连接状态
_peerConnection.onconnectionstatechange += async (state) =>
{
Log.Information($"PeerConnection state: {state}");
if (state == RTCPeerConnectionState.connected)
{
Log.Information("WebRTC connected. Preparing for VLC playback.");
_rtpSession = CreateRtpSession(_peerConnection.VideoLocalTrack?.Capabilities);
// 请求关键帧
var localVideoSsrc = _peerConnection.VideoLocalTrack.Ssrc;
var remoteVideoSsrc = _peerConnection.VideoRemoteTrack.Ssrc;
var pli = new RTCPFeedback(localVideoSsrc, remoteVideoSsrc, PSFBFeedbackTypesEnum.PLI);
_peerConnection.SendRtcpFeedback(SDPMediaTypesEnum.video, pli);
_peerConnection.OnRtpPacketReceived += (rep, media, rtpPkt) =>
{
if (media == SDPMediaTypesEnum.video)
{
_rtpSession.SendRtpRaw(media, rtpPkt.Payload, rtpPkt.Header.Timestamp, rtpPkt.Header.MarkerBit, rtpPkt.Header.PayloadType);
}
};
_peerConnection.OnRtpClosed += (reason) =>
{
timer?.Stop();
OnDisConnected?.Invoke();
};
OnConnected?.Invoke(_sdpPath);
}
};
// 设置并发送Answer
var sdp = SDP.ParseSDPDescription(sdpOffer);
foreach (var ann in sdp.Media.Where(m => m.Media == SDPMediaTypesEnum.video))
{
var track = new MediaStreamTrack(ann.Media, false, ann.MediaFormats.Values.ToList(), MediaStreamStatusEnum.RecvOnly);
_peerConnection.addTrack(track);
}
_peerConnection.setRemoteDescription(new RTCSessionDescriptionInit { type = RTCSdpType.offer, sdp = sdpOffer });
var answer = _peerConnection.createAnswer(null);
await _peerConnection.setLocalDescription(answer);
var answerMessage = new
{
janus = "message",
body = new { request = "start" },
jsep = new { type = "answer", sdp = answer.sdp },
transaction = Guid.NewGuid().ToString("N")
};
SendJanusMessage(ws, answerMessage);
}
private RTPSession CreateRtpSession(List<SDPAudioVideoMediaFormat> videoFormats)
{
var rtpSession = new RTPSession(false, false, false, IPAddress.Parse("192.168.28.224"));
bool hasVideo = false;
if (videoFormats != null && videoFormats.Count > 0)
{
MediaStreamTrack videoTrack = new MediaStreamTrack(SDPMediaTypesEnum.video, false, videoFormats, MediaStreamStatusEnum.SendRecv);
rtpSession.addTrack(videoTrack);
hasVideo = true;
}
var sdpOffer = rtpSession.CreateOffer(null);
if (hasVideo)
{
sdpOffer.Media.Single(x => x.Media == SDPMediaTypesEnum.video).Port = _videoPort;
}
Console.WriteLine(sdpOffer);
using (StreamWriter sw = new StreamWriter(_sdpPath))
{
sw.Write(sdpOffer);
}
rtpSession.Start();
rtpSession.SetDestination(SDPMediaTypesEnum.video, new IPEndPoint(IPAddress.Parse("192.168.28.224"), _videoPort), new IPEndPoint(IPAddress.Parse("192.168.28.224"), _videoPort + 1));
return rtpSession;
}
#region WebSocket相关 (保持不变)
private async Task ConnectToJanus(string url)
{
var factory = new Func<ClientWebSocket>(() =>
{
var clientWebSocket = new ClientWebSocket();
clientWebSocket.Options.KeepAliveInterval = TimeSpan.FromSeconds(10);
clientWebSocket.Options.AddSubProtocol("janus-protocol");
return clientWebSocket;
});
ws = new WebsocketClient(new Uri(url), factory);
ws.IsReconnectionEnabled = false;
ws.DisconnectionHappened.Subscribe(info =>
{
Log.Information("WebRTC WebSocket disconnect");
timer?.Stop();
OnDisConnected?.Invoke();
});
ws.ReconnectionHappened.Subscribe(info =>
{
Log.Information("WebRTC WebSocket connect success");
var createSessionReq = new { janus = "create", transaction = Guid.NewGuid().ToString("N").Substring(0, 12) };
SendJanusMessage(ws, createSessionReq);
});
ws.MessageReceived.Subscribe(async msg => await HandleJanusMessage(ws, msg.Text));
await ws.Start();
}
private async Task HandleJanusMessage(WebsocketClient ws, string msg)
{
if (string.IsNullOrEmpty(msg)) return;
Log.Debug($"Received from Janus: {msg}");
var response = JObject.Parse(msg);
var janusType = response["janus"]?.Value<string>();
switch (janusType)
{
case "success" when response.ContainsKey("data") && !response.ContainsKey("session_id"):
_sessionId = response["data"]?["id"]?.Value<long>();
Log.Information($"Session created with ID: {_sessionId}");
var attachReq = new
{
janus = "attach",
plugin = "janus.plugin.ustreamer",
opaque_id = "oid-" + Guid.NewGuid().ToString("N").Substring(0, 12),
transaction = Guid.NewGuid().ToString("N").Substring(0, 12)
};
SendJanusMessage(ws, attachReq);
break;
case "success" when response.ContainsKey("session_id") && !response.ContainsKey("plugindata"):
_handleId = response["data"]?["id"]?.Value<long>();
Log.Information($"Attached to streaming plugin with handle ID: {_handleId}");
var watchReq = new
{
janus = "message",
body = new { request = "watch" },
transaction = Guid.NewGuid().ToString("N").Substring(0, 12)
};
SendJanusMessage(ws, watchReq);
break;
case "event" when response.ContainsKey("jsep"):
var jsep = response["jsep"];
var sdpOffer = jsep["sdp"]?.Value<string>();
var sdpType = jsep["type"]?.Value<string>();
if (sdpType == "offer" && !string.IsNullOrEmpty(sdpOffer))
{
Log.Information("Received SDP offer from Janus. Creating answer...");
await CreateAndSendAnswer(ws, sdpOffer);
}
break;
case "webrtcup":
timer.Start();
break;
}
}
private void SendJanusMessage(WebsocketClient ws, object messageObj)
{
var message = JObject.FromObject(messageObj);
if (_sessionId != null) message["session_id"] = _sessionId;
if (_handleId != null) message["handle_id"] = _handleId;
var json = JsonConvert.SerializeObject(message);
Log.Debug($"Sending to Janus: {json}");
ws.Send(json);
}
#endregion
public void Dispose()
{
try
{
_sessionId = null;
_handleId = null;
ws?.Dispose();
//_udpSender?.Close();
//_udpSender?.Dispose();
_peerConnection?.close();
_peerConnection?.Dispose();
if (!string.IsNullOrEmpty(_sdpPath) && File.Exists(_sdpPath))
{
File.Delete(_sdpPath);
}
}
catch { }
}
}
}
}
Starting Janus WebRTC client...
[10:32:46 INF] WebRTC WebSocket connect success
[10:32:46 DBG] Sending to Janus: {"janus":"create","transaction":"21d6791b69d9"}
[10:32:47 DBG] Received from Janus: {
"janus": "success",
"transaction": "21d6791b69d9",
"data": {
"id": 158384276970872
}
}
[10:32:47 INF] Session created with ID: 158384276970872
[10:32:47 DBG] Sending to Janus: {"janus":"attach","plugin":"janus.plugin.ustreamer","opaque_id":"oid-03acc408af63","transaction":"2dde35387fd5","session_id":158384276970872}
[10:32:47 DBG] Received from Janus: {
"janus": "success",
"session_id": 158384276970872,
"transaction": "2dde35387fd5",
"data": {
"id": 2699408990676378
}
}
[10:32:47 INF] Attached to streaming plugin with handle ID: 2699408990676378
[10:32:47 DBG] Sending to Janus: {"janus":"message","body":{"request":"watch"},"transaction":"63179ea4c0e6","session_id":158384276970872,"handle_id":2699408990676378}
[10:32:47 DBG] Received from Janus: {
"janus": "event",
"session_id": 158384276970872,
"sender": 2699408990676378,
"plugindata": {
"plugin": "janus.plugin.ustreamer",
"data": {
"ustreamer": "event",
"result": {
"status": "started"
}
}
},
"jsep": {
"type": "offer",
"sdp": "v=0\r\no=- 1797027044865807995 1 IN IP4 113.89.35.155\r\ns=PiKVM uStreamer\r\nt=0 0\r\na=group:BUNDLE v\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS janus\r\nm=video 9 UDP/TLS/RTP/SAVPF 96 97\r\nc=IN IP4 113.89.35.155\r\na=sendonly\r\na=mid:v\r\na=rtcp-mux\r\na=ice-ufrag:2MIY\r\na=ice-pwd:X4OrwSMpZst5NJrccEeyIB\r\na=ice-options:trickle\r\na=fingerprint:sha-256 CE:A9:32:FF:A6:6C:2F:DE:33:87:91:7F:C7:CD:CB:08:89:2F:0F:5F:4F:BB:8B:E3:65:C8:E8:A3:6D:DF:C4:60\r\na=setup:actpass\r\na=rtpmap:96 H264/90000\r\na=fmtp:96 profile-level-id=42E01F\r\na=fmtp:96 packetization-mode=1\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtcp-fb:96 goog-remb\r\na=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=extmap:2 urn:3gpp:video-orientation\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=96\r\na=ssrc-group:FID 2876871073 1033412930\r\na=msid:janus janusv0\r\na=ssrc:2876871073 cname:janus\r\na=ssrc:2876871073 msid:janus janusv0\r\na=ssrc:2876871073 mslabel:janus\r\na=ssrc:2876871073 label:janusv0\r\na=ssrc:1033412930 cname:janus\r\na=ssrc:1033412930 msid:janus janusv0\r\na=ssrc:1033412930 mslabel:janus\r\na=ssrc:1033412930 label:janusv0\r\na=candidate:1 1 udp 2013266431 192.168.29.198 33288 typ host\r\na=candidate:2 1 udp 2013266430 fe80::fba6:419f:7d8a:525e 30337 typ host\r\na=candidate:3 1 udp 1677722111 113.89.35.155 33288 typ srflx raddr 192.168.29.198 rport 33288\r\na=end-of-candidates\r\n"
}
}
[10:32:47 INF] Received SDP offer from Janus. Creating answer...
[10:32:47 DBG] No DTLS certificate is provided in the configuration
[10:32:48 DBG] CreateRtpSocket attempting to create and bind RTP socket(s) on 192.168.28.224:0.
[10:32:48 DBG] CreateBoundSocket attempting to create and bind socket(s) on 192.168.28.224:0 using protocol Udp.
[10:32:48 DBG] CreateBoundSocket successfully bound on 192.168.28.224:51974.
[10:32:48 DBG] Successfully bound RTP socket 192.168.28.224:51974.
[10:32:48 DBG] IceServerResolver starting DNS lookup for ICE server stun:stun.cloudflare.com
[10:32:48 DBG] RTPChannel for 192.168.28.224:51974 started.
[10:32:48 DBG] IceServerResolver resolved stun:stun.cloudflare.com -> 162.159.207.0:3478
[10:32:48 DBG] SCTP windows size for data receiver set at 218.
[10:32:48 DBG] SCTP creating DTLS based association, is DTLS client False, ID 5000:5000:51974.
[10:32:48 DBG] Sending to Janus: {"janus":"trickle","candidate":{"candidate":"candidate:518684609 1 udp 2113937663 192.168.28.224 51974 typ host generation 0","sdpMid":null,"sdpMLineIndex":0},"transaction":"3b043fce8650","session_id":158384276970872,"handle_id":2699408990676378}
[10:32:48 DBG] Sending to Janus: {"janus":"trickle","candidate":{"completed":true},"transaction":"ffee6150ce27","session_id":158384276970872,"handle_id":2699408990676378}
[10:32:48 DBG] RTP ICE Channel discovered 1 local candidates.
[10:32:48 DBG] Sending STUN binding request to ICE server stun:stun.cloudflare.com with address 162.159.207.0:3478.
[10:32:48 DBG] [setRemoteDescription] - Extension:[2 - urn:3gpp:video-orientation]
[10:32:48 DBG] Sending STUN binding request to ICE server stun:stun.cloudflare.com with address 162.159.207.0:3478.
[10:32:48 DBG] Setting remote video track with sdp destination null and control destination null.
[10:32:48 DBG] Sending STUN binding request to ICE server stun:stun.cloudflare.com with address 162.159.207.0:3478.
[10:32:48 DBG] RTP ICE Channel remote credentials set.
[10:32:48 DBG] RTP ICE Channel received remote candidate: 1 1 udp 2013266431 192.168.29.198 33288 typ host generation 0
[10:32:48 DBG] RTP ICE Channel received remote candidate: 2 1 udp 2013266430 fe80::fba6:419f:7d8a:525e 30337 typ host generation 0
[10:32:48 DBG] RTP ICE Channel received remote candidate: 3 1 udp 1677722111 113.89.35.155 33288 typ srflx raddr 192.168.29.198 rport 33288 generation 0
[10:32:48 DBG] LogRemoteSDPSsrcAttributes: Audio:[ ]
Video: [ [2876871073 - 1033412930 - ] ]
Text: [ ]
[10:32:48 DBG] Sending STUN binding request to ICE server stun:stun.cloudflare.com with address 162.159.207.0:3478.
[10:32:48 DBG] Adding new candidate pair to checklist for: udp:192.168.28.224:51974 (host)->udp:192.168.29.198:33288 (host)
[10:32:48 DBG] Adding new candidate pair to checklist for: udp:192.168.28.224:51974 (host)->udp:113.89.35.155:33288 (srflx)
[10:32:48 DBG] ICE RTP channel sending connectivity check for udp:192.168.28.224:51974 (host)->udp:192.168.29.198:33288(host) from 192.168.28.224:51974 to 192.168.29.198:33288 (use candidate False).
[10:32:48 DBG] Sending STUN binding request to ICE server stun:stun.cloudflare.com with address 162.159.207.0:3478.
[10:32:48 DBG] STUN binding success response received for ICE server check to stun:stun.cloudflare.com.
[10:32:49 DBG] Adding server reflex ICE candidate for ICE server stun:stun.cloudflare.com and 113.89.35.155:51974.
[10:32:49 DBG] ICE RTP channel sending connectivity check for udp:192.168.28.224:51974 (host)->udp:113.89.35.155:33288 (srflx) from 192.168.28.224:51974 to 113.89.35.155:33288 (use candidate False).
[10:32:49 DBG] Sending to Janus: {"janus":"trickle","candidate":{"candidate":"candidate:187536785 1 udp 1677730047 113.89.35.155 51974 typ srflx raddr 0.0.0.0 rport 0 generation 0","sdpMid":"0","sdpMLineIndex":0},"transaction":"b4cb4c4e1c33","session_id":158384276970872,"handle_id":2699408990676378}
[10:32:49 DBG] Sending to Janus: {"janus":"message","body":{"request":"start"},"jsep":{"type":"answer","sdp":"v=0\r\no=- 55620 0 IN IP4 127.0.0.1\r\ns=sipsorcery\r\nt=0 0\r\na=group:BUNDLE v\r\nm=video 9 UDP/TLS/RTP/SAVP 96 97\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:KYSU\r\na=ice-pwd:UXVQUZSLUKWLOSUZZAWCLZMI\r\na=fingerprint:sha-256 24:2A:3F:49:95:B1:80:58:C0:19:06:85:53:7A:27:4F:02:70:81:D1:C9:7E:CC:56:0C:15:BA:70:33:FB:41:2E\r\na=setup:active\r\na=candidate:518684609 1 udp 2113937663 192.168.28.224 51974 typ host generation 0\r\na=ice-options:ice2,trickle\r\na=mid:v\r\na=rtpmap:96 H264/90000\r\na=rtcp-fb:96 transport-cc\r\na=fmtp:96 packetization-mode=1\r\na=rtpmap:97 rtx/90000\r\na=rtcp-fb:97 transport-cc\r\na=fmtp:97 apt=96\r\na=rtcp-mux\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=recvonly\r\na=ssrc:1487256276 cname:31750716-caeb-4964-bb9b-6f19afd1d91e\r\n"},"transaction":"f29acb601c0c4a0780206e01aff0a1ae","session_id":158384276970872,"handle_id":2699408990676378}
[10:32:49 DBG] Sending to Janus: {"janus":"trickle","candidate":{"completed":true},"transaction":"3eac30b9418b","session_id":158384276970872,"handle_id":2699408990676378}
[10:32:49 DBG] Received from Janus: {
"janus": "success",
"session_id": 158384276970872,
"transaction": "63179ea4c0e6",
"sender": 2699408990676378,
"plugindata": {
"plugin": "janus.plugin.ustreamer",
"data": {
"ok": true
}
}
}
[10:32:49 WRN] The active ICE server reached an unexpected state stun:stun.cloudflare.com.
[10:32:49 DBG] Received from Janus: {
"janus": "ack",
"session_id": 158384276970872,
"transaction": "3b043fce8650"
}
[10:32:49 DBG] Received from Janus: {
"janus": "ack",
"session_id": 158384276970872,
"transaction": "ffee6150ce27"
}
[10:32:49 DBG] Received from Janus: {
"janus": "ack",
"session_id": 158384276970872,
"transaction": "b4cb4c4e1c33"
}
[10:32:49 DBG] Received from Janus: {
"janus": "event",
"session_id": 158384276970872,
"sender": 2699408990676378,
"plugindata": {
"plugin": "janus.plugin.ustreamer",
"data": {
"ustreamer": "event",
"result": {
"status": "started"
}
}
}
}
[10:32:49 DBG] ICE RTP channel remote peer nominated entry from binding request: udp:192.168.29.198:33288 (host).
[10:32:49 DBG] ICE RTP channel stopping ICE server checks in gathering state complete and connection state checking.
[10:32:49 DBG] Received from Janus: {
"janus": "success",
"session_id": 158384276970872,
"transaction": "f29acb601c0c4a0780206e01aff0a1ae",
"sender": 2699408990676378,
"plugindata": {
"plugin": "janus.plugin.ustreamer",
"data": {
"ok": true
}
}
}
[10:32:49 DBG] ICE RTP channel connected after 393ms udp:192.168.28.224:51974 (host)->udp:192.168.29.198:33288 (host).
[10:32:49 DBG] Received from Janus: {
"janus": "ack",
"session_id": 158384276970872,
"transaction": "3eac30b9418b"
}
[10:32:49 INF] PeerConnection state: connecting
[10:32:49 DBG] ICE connected to remote end point 192.168.29.198:33288.
[10:32:49 DBG] Starting DLS handshake with role active.
[10:32:49 DBG] RTCPeerConnection DoDtlsHandshake started.
[10:32:49 DBG] DTLS commencing handshake as client.
[10:32:49 WRN] ICE RTP channel received an unexpected STUN message 17 from 192.168.29.198:33288.
Json: SIPSorcery.Net.STUNMessage
[10:32:49 DBG] Received from Janus: {
"janus": "webrtcup",
"session_id": 158384276970872,
"sender": 2699408990676378
}
[10:32:49 WRN] RTP or RTCP packet received before secure context ready.
[10:32:49 WRN] RTP or RTCP packet received before secure context ready.
[10:32:49 DBG] RTCPeerConnection DTLS handshake result True, is handshake complete True.
[10:32:49 DBG] RTCPeerConnection remote certificate fingerprint matched expected value of CE:A9:32:FF:A6:6C:2F:DE:33:87:91:7F:C7:CD:CB:08:89:2F:0F:5F:4F:BB:8B:E3:65:C8:E8:A3:6D:DF:C4:60 for sha-256.
[10:32:49 INF] PeerConnection state: connected
[10:32:49 INF] WebRTC connected. Preparing for VLC playback.
[10:32:49 DBG] CreateRtpSocket attempting to create and bind RTP socket(s) on 192.168.28.224:0.
[10:32:49 DBG] Set remote track (video - index=0) SSRC to 2876871073 remote RTP endpoint 192.168.29.198:33288.
[10:32:49 DBG] CreateBoundSocket attempting to create and bind socket(s) on 192.168.28.224:0 using protocol Udp.
[10:32:49 DBG] CreateBoundSocket even port required, closing socket on 192.168.28.224:51975 and retrying on 51976.
[10:32:49 DBG] CreateBoundSocket attempting to create and bind socket(s) on 192.168.28.224:51977 using protocol Udp.
[10:32:49 DBG] CreateBoundSocket successfully bound on 192.168.28.224:51977.
[10:32:49 DBG] Successfully bound RTP socket 192.168.28.224:51976 and control socket 192.168.28.224:51977.
[10:32:49 DBG] RTPChannel for 192.168.28.224:51976 started.
v=0
o=- 1156375561 0 IN IP4 127.0.0.1
s=sipsorcery
c=IN IP4 192.168.28.224
t=0 0
m=video 5018 RTP/AVP 96 97
a=mid:0
a=rtpmap:96 H264/90000
a=rtcp-fb:96 transport-cc
a=fmtp:96 packetization-mode=1
a=rtpmap:97 rtx/90000
a=rtcp-fb:97 transport-cc
a=fmtp:97 apt=96
a=sendrecv
a=ssrc:1405650085 cname:a359c241-fdc2-4943-952f-466b69647110
[10:32:49 DBG] Video depacketisation codec set to H264 for SSRC 2876871073.
[10:32:49 DBG] Starting RTCP session for a359c241-fdc2-4943-952f-466b69647110.
[10:32:49 DBG] Starting RTCP session for 31750716-caeb-4964-bb9b-6f19afd1d91e.
[0000021d94af6660] main decoder error: buffer deadlock prevented
MultiFramedRTPSource::doGetNextFrame1(): The total received frame size exceeds the client's buffer size (250000). 66670 bytes of trailing data will be dropped!
[0000021d94896b40] main input error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 0 ms)
[0000021d94af6660] main decoder error: buffer deadlock prevented
[0000021d94896b40] main input error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 98 ms)
[0000021d94af6660] avcodec decoder: Using D3D11VA (AMD Radeon(TM) Graphics, vendor 1002(ATI), device 1636, revision d1)for hardware decoding
[0000021d94af6660] main decoder error: buffer deadlock prevented
[0000021d94896b40] main input error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 112 ms)
[0000021d94af6660] main decoder error: buffer deadlock prevented
[10:32:53 DBG] Sending key video RTCP packet size 76 to 192.168.28.224:5019.
[0000021d94bd8c60] direct3d11 vout display error: Could not create the depth stencil texture. (hr=0x80070057)
log: