Packages
membrane_rtp_plugin
0.31.0
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/rtp/tcp_decapsulator.ex
defmodule Membrane.RTP.TCP.Decapsulator do
@moduledoc """
This element provides functionality of packetizing bytestream from TCP
into RTP and RTCP Packets. The encapsulation is described in RFC 4571.
Packets in the stream will have the following structure:
[Length :: 2 bytes][packet :: <Length> bytes]
"""
use Membrane.Filter
alias Membrane.{Buffer, RemoteStream, RTP}
def_input_pad :input, accepted_format: %RemoteStream{type: :bytestream}
def_output_pad :output, accepted_format: %RemoteStream{type: :packetized, content_format: RTP}
@impl true
def handle_init(_ctx, _opts) do
{[], %{unprocessed_data: <<>>}}
end
@impl true
def handle_playing(_ctx, state) do
stream_format = %RemoteStream{type: :packetized, content_format: RTP}
{[stream_format: {:output, stream_format}], state}
end
@impl true
def handle_stream_format(:input, _stream_format, _ctx, state) do
{[], state}
end
@impl true
def handle_buffer(:input, %Buffer{payload: payload, metadata: metadata}, _ctx, state) do
packets_binary = state.unprocessed_data <> payload
{unprocessed_data, complete_packets_binaries} = get_complete_packets(packets_binary)
packets_buffers =
Enum.map(complete_packets_binaries, &%Buffer{payload: &1, metadata: metadata})
{[buffer: {:output, packets_buffers}], %{state | unprocessed_data: unprocessed_data}}
end
@spec get_complete_packets(binary()) ::
{unprocessed_data :: binary(), complete_packets :: [binary()]}
defp get_complete_packets(packets_binary, complete_packets \\ [])
defp get_complete_packets(
<<payload_length::16, payload::binary-size(payload_length), rest::binary>>,
complete_packets
) do
get_complete_packets(rest, [payload | complete_packets])
end
defp get_complete_packets(unprocessed_data, complete_packets) do
{unprocessed_data, Enum.reverse(complete_packets)}
end
end