Packages
membrane_rtp_plugin
0.7.0-alpha.2
0.31.5
0.31.4
0.31.3
0.31.2
0.31.1
0.31.0
0.30.0
0.29.1
0.29.0
0.28.0
0.27.1
0.27.0
0.26.0
0.25.0
0.24.1
0.24.0
0.23.2
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.1
0.19.0
0.18.0
0.17.1
0.17.0
0.16.0
0.15.0
0.15.0-rc.1
0.14.0
0.13.0
0.12.2
0.12.1
0.12.0
0.11.0
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.1-alpha.3
0.7.1-alpha.2
0.7.0-alpha.2
0.7.0-alpha.1
0.7.0-alpha
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0-alpha
Membrane Multimedia Framework plugin for RTP
Current section
Files
Jump to
Current section
Files
lib/membrane/rtcp/packet.ex
defmodule Membrane.RTCP.Packet do
@moduledoc """
Functions common to all RTCP Packets
"""
alias Membrane.RTCP.{
AppPacket,
ByePacket,
FeedbackPacket,
Header,
ReceiverReportPacket,
SdesPacket,
SenderReportPacket
}
alias Membrane.RTP
@type t ::
AppPacket.t()
| ByePacket.t()
| FeedbackPacket.t()
| ReceiverReportPacket.t()
| SenderReportPacket.t()
| SdesPacket.t()
@doc """
Decodes binary with packet body (without header) into packet struct. Used by `parse/1`
"""
@callback decode(binary(), packet_specific :: Header.packet_specific_t()) ::
{:ok, struct()} | {:error, atom()}
@doc """
Encodes packet struct into the tuple used by `serialize/1`
"""
@callback encode(struct()) :: {body :: binary(), packet_specific :: Header.packet_specific_t()}
@packet_type_module BiMap.new(%{
200 => SenderReportPacket,
201 => ReceiverReportPacket,
202 => SdesPacket,
203 => ByePacket,
204 => AppPacket,
206 => FeedbackPacket
})
@doc """
Converts packet structure into binary
"""
@spec serialize(t() | [t()]) :: binary()
def serialize(%packet_module{} = packet) do
{body, packet_specific} = packet_module.encode(packet)
packet_type = BiMap.fetch_key!(@packet_type_module, packet_module)
header =
%Header{packet_type: packet_type, packet_specific: packet_specific}
|> Header.serialize(body_size: byte_size(body))
header <> body
end
def serialize(packets) when is_list(packets) do
Enum.map_join(packets, &serialize/1)
end
@spec parse(binary()) :: {:ok, [t()]} | {:error, any()}
def parse(packets) do
do_parse(packets, [])
end
defp do_parse(<<>>, acc), do: {:ok, Enum.reverse(acc)}
defp do_parse(<<raw_header::binary-size(4), body_and_rest::binary>>, acc) do
with {:ok, %{header: header, body_size: length, padding?: padding?}} <-
Header.parse(raw_header),
<<body::binary-size(length), rest::binary>> <- body_and_rest,
{:ok, {body, _padding}} <- RTP.Utils.strip_padding(body, padding?),
{:ok, packet_module} <- BiMap.fetch(@packet_type_module, header.packet_type),
{:ok, packet} <- packet_module.decode(body, header.packet_specific) do
do_parse(rest, [packet | acc])
else
{:error, reason} -> {:error, reason}
_error -> {:error, :malformed_packet}
end
end
defp do_parse(_binary, _acc), do: {:error, :malformed_packet}
end