Packages
membrane_rtp_plugin
0.31.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/sender_report_packet.ex
defmodule Membrane.RTCP.SenderReportPacket do
@moduledoc """
Parses and constructs RTCP Sender Report defined in
[RFC3550](https://tools.ietf.org/html/rfc3550#section-6.4.1)
"""
@behaviour Membrane.RTCP.Packet
alias Membrane.RTCP.ReportPacketBlock
alias Membrane.RTP
defstruct [:ssrc, :reports, :sender_info]
@type sender_info_t :: %{
wallclock_timestamp: Membrane.Time.t(),
rtp_timestamp: non_neg_integer(),
sender_packet_count: non_neg_integer(),
sender_octet_count: non_neg_integer()
}
@type t :: %__MODULE__{
ssrc: RTP.ssrc(),
reports: [ReportPacketBlock.t()],
sender_info: sender_info_t()
}
@impl true
def encode(report) do
sender_info = encode_sender_info(report.sender_info)
blocks = report.reports |> Enum.map_join(&ReportPacketBlock.encode/1)
reports_count = report.reports |> length()
body = <<report.ssrc::32>> <> sender_info <> blocks
{body, reports_count}
end
defp encode_sender_info(sender_info) do
ntp_timestamp = Membrane.Time.to_ntp_timestamp(sender_info.wallclock_timestamp)
<<ntp_timestamp::bitstring-size(64), sender_info.rtp_timestamp::32,
sender_info.sender_packet_count::32, sender_info.sender_octet_count::32>>
end
@impl true
def decode(
<<ssrc::32, ntp_timestamp::bitstring-size(64), rtp_time::32, packet_count::32,
octet_count::32, blocks::binary>>,
reports_count
) do
wallclock_ts = Membrane.Time.from_ntp_timestamp(ntp_timestamp)
sender_info = %{
wallclock_timestamp: wallclock_ts,
rtp_timestamp: rtp_time,
sender_packet_count: packet_count,
sender_octet_count: octet_count
}
with {:ok, reports} <- ReportPacketBlock.decode(blocks),
true <- reports_count == length(reports) do
{:ok, %__MODULE__{ssrc: ssrc, reports: reports, sender_info: sender_info}}
else
false -> {:error, :invalid_reports_count}
err -> err
end
end
def decode(_packet, _reports_count) do
{:error, :sr_too_short}
end
end