From 897bc601a853f689adcf7bccd17e0ce764b8650e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Thu, 27 Jun 2024 10:27:06 +0200 Subject: [PATCH] Handle VP8.Payload.parse errors --- .formatter.exs | 3 +- lib/ex_webrtc/rtp/vp8/depayloader.ex | 87 ++++++++++++++++------------ 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index c185fe1..ae4b4d1 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,5 @@ # Used by "mix format" [ - inputs: ["{mix,.formatter}.exs", "{config,lib,test,examples}/**/*.{ex,exs}"] + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], + subdirectories: ["examples/*"] ] diff --git a/lib/ex_webrtc/rtp/vp8/depayloader.ex b/lib/ex_webrtc/rtp/vp8/depayloader.ex index f8067b8..c56cf15 100644 --- a/lib/ex_webrtc/rtp/vp8/depayloader.ex +++ b/lib/ex_webrtc/rtp/vp8/depayloader.ex @@ -26,51 +26,64 @@ defmodule ExWebRTC.RTP.VP8.Depayloader do def write(depayloader, %ExRTP.Packet{payload: <<>>, padding: true}), do: {:ok, depayloader} def write(depayloader, packet) do - with {:ok, vp8_payload} <- Payload.parse(packet.payload) do - depayloader = - case {depayloader.current_frame, vp8_payload} do - {nil, %Payload{s: 1, pid: 0}} -> - %{ - depayloader - | current_frame: vp8_payload.payload, - current_timestamp: packet.timestamp - } - - {nil, _vp8_payload} -> - Logger.debug("Dropping vp8 payload as it doesn't start a new frame") - depayloader + case Payload.parse(packet.payload) do + {:ok, vp8_payload} -> + do_write(depayloader, packet, vp8_payload) - {_current_frame, %Payload{s: 1, pid: 0}} -> - Logger.debug(""" - Received packet that starts a new frame without finishing the previous frame. \ - Dropping previous frame.\ - """) + {:error, reason} -> + Logger.warning(""" + Couldn't parse payload, reason: #{reason}. \ + Resetting depayloader state. Payload: #{inspect(packet.payload)}.\ + """) - %{ - depayloader - | current_frame: vp8_payload.payload, - current_timestamp: packet.timestamp - } + {:ok, %{depayloader | current_frame: nil, current_timestamp: nil}} + end + end - _ when packet.timestamp != depayloader.current_timestamp -> - Logger.debug(""" - Received packet with timestamp from a new frame that is not a beginning of this frame \ - and without finishing the previous frame. Dropping both.\ - """) + defp do_write(depayloader, packet, vp8_payload) do + depayloader = + case {depayloader.current_frame, vp8_payload} do + {nil, %Payload{s: 1, pid: 0}} -> + %{ + depayloader + | current_frame: vp8_payload.payload, + current_timestamp: packet.timestamp + } - %{depayloader | current_frame: nil, current_timestamp: nil} + {nil, _vp8_payload} -> + Logger.debug("Dropping vp8 payload as it doesn't start a new frame") + depayloader - {current_frame, vp8_payload} -> - %{depayloader | current_frame: current_frame <> vp8_payload.payload} - end + {_current_frame, %Payload{s: 1, pid: 0}} -> + Logger.debug(""" + Received packet that starts a new frame without finishing the previous frame. \ + Dropping previous frame.\ + """) - case {depayloader.current_frame, packet.marker} do - {current_frame, true} when current_frame != nil -> - {:ok, current_frame, %{depayloader | current_frame: nil, current_timestamp: nil}} + %{ + depayloader + | current_frame: vp8_payload.payload, + current_timestamp: packet.timestamp + } + + _ when packet.timestamp != depayloader.current_timestamp -> + Logger.debug(""" + Received packet with timestamp from a new frame that is not a beginning of this frame \ + and without finishing the previous frame. Dropping both.\ + """) + + %{depayloader | current_frame: nil, current_timestamp: nil} - _ -> - {:ok, depayloader} + {current_frame, vp8_payload} -> + %{depayloader | current_frame: current_frame <> vp8_payload.payload} end + + case {depayloader.current_frame, packet.marker} do + {current_frame, true} when current_frame != nil -> + {:ok, current_frame, %{depayloader | current_frame: nil, current_timestamp: nil}} + + _ -> + {:ok, depayloader} end end end