Skip to content

Commit

Permalink
Hide VP8 and Opus Payloader/Depayloader modules
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 committed Aug 8, 2024
1 parent b142d04 commit 9dd373a
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 172 deletions.
44 changes: 14 additions & 30 deletions lib/ex_webrtc/rtp/depayloader.ex
Original file line number Diff line number Diff line change
@@ -1,57 +1,41 @@
defmodule ExWebRTC.RTP.Depayloader do
@moduledoc """
Dispatcher module and behaviour for ExWebRTC Depayloaders.
"""

alias ExWebRTC.RTPCodecParameters

@type depayloader :: struct()
RTP depayloader.
@doc """
Creates a new depayloader struct.
It unpacks RTP pakcets into audio/video frames.
"""
@callback new(options :: any()) :: depayloader()

@doc """
Processes binary data from a single RTP packet, and outputs a frame if assembled.
alias ExWebRTC.RTPCodecParameters

Returns the frame (or `nil` if a frame could not be depayloaded yet)
together with the updated depayloader struct.
"""
@callback depayload(depayloader(), packet :: ExRTP.Packet.t()) ::
{binary() | nil, depayloader()}
@opaque depayloader :: struct()

@doc """
Creates a new depayloader struct that matches the passed codec parameters.
Refer to the modules implementing the behaviour for available options.
Creates a new depayloader that matches the passed codec parameters.
"""
@spec new(RTPCodecParameters.t(), any()) ::
@spec new(RTPCodecParameters.t()) ::
{:ok, depayloader()} | {:error, :no_depayloader_for_codec}
def new(codec_params, options \\ nil) do
with {:ok, module} <- match_depayloader_module(codec_params.mime_type) do
depayloader = if is_nil(options), do: module.new(), else: module.new(options)

def new(codec_params) do
with {:ok, module} <- to_depayloader_module(codec_params.mime_type) do
depayloader = module.new()
{:ok, depayloader}
end
end

@doc """
Processes binary data from a single RTP packet using the depayloader's module,
and outputs a frame if assembled.
Processes binary data from a single RTP packet, and outputs a frame if assembled.
Returns the frame (or `nil` if a frame could not be depayloaded yet)
together with the updated depayloader struct.
together with the updated depayloader.
"""
@spec depayload(depayloader(), ExRTP.Packet.t()) :: {binary() | nil, depayloader()}
def depayload(%module{} = depayloader, packet) do
module.depayload(depayloader, packet)
end

defp match_depayloader_module(mime_type) do
defp to_depayloader_module(mime_type) do
case String.downcase(mime_type) do
"video/vp8" -> {:ok, ExWebRTC.RTP.VP8.Depayloader}
"audio/opus" -> {:ok, ExWebRTC.RTP.Opus.Depayloader}
"video/vp8" -> {:ok, ExWebRTC.RTP.Depayloader.VP8}
"audio/opus" -> {:ok, ExWebRTC.RTP.Depayloader.Opus}
_other -> {:error, :no_depayloader_for_codec}
end
end
Expand Down
19 changes: 19 additions & 0 deletions lib/ex_webrtc/rtp/depayloader_behaviour.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule ExWebRTC.RTP.Depayloader.Behaviour do
@moduledoc false

@type depayloader :: struct()

@doc """
Creates a new depayloader struct.
"""
@callback new() :: depayloader()

@doc """
Processes binary data from a single RTP packet, and outputs a frame if assembled.
Returns the frame (or `nil` if a frame could not be depayloaded yet)
together with the updated depayloader struct.
"""
@callback depayload(depayloader(), packet :: ExRTP.Packet.t()) ::
{binary() | nil, depayloader()}
end
29 changes: 9 additions & 20 deletions lib/ex_webrtc/rtp/opus/depayloader.ex
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
defmodule ExWebRTC.RTP.Opus.Depayloader do
@moduledoc """
Decapsualtes Opus audio out of RTP packet.
Based on [RFC 7587: RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587).
"""
defmodule ExWebRTC.RTP.Depayloader.Opus do
@moduledoc false
# Decapsualtes Opus audio out of RTP packet.
#
# Based on [RFC 7587: RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587).

alias ExRTP.Packet

@behaviour ExWebRTC.RTP.Depayloader
@behaviour ExWebRTC.RTP.Depayloader.Behaviour

@opaque t :: %__MODULE__{}
@type t :: %__MODULE__{}

defstruct []

@doc """
Creates a new Opus depayloader struct.
Does not take any options/parameters.
"""
@impl true
@spec new(any()) :: t()
def new(_unused \\ nil) do
@spec new() :: t()
def new() do
%__MODULE__{}
end

@doc """
Takes Opus packet out of an RTP packet.
Always returns a binary as the first element.
"""
@impl true
@spec depayload(t(), Packet.t()) :: {binary(), t()}
def depayload(%__MODULE__{} = depayloader, %Packet{payload: payload}),
Expand Down
29 changes: 8 additions & 21 deletions lib/ex_webrtc/rtp/opus/payloader.ex
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
defmodule ExWebRTC.RTP.Opus.Payloader do
@moduledoc """
Encapsulates Opus audio packet into an RTP packet.
defmodule ExWebRTC.RTP.Payloader.Opus do
@moduledoc false
# Encapsulates Opus audio packet into an RTP packet.
#
# Based on [RFC 7587: RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587).

Based on [RFC 7587: RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587).
"""
@behaviour ExWebRTC.RTP.Payloader.Behaviour

@behaviour ExWebRTC.RTP.Payloader

@opaque t :: %__MODULE__{}
@type t :: %__MODULE__{}

defstruct []

@doc """
Creates a new Opus payloader struct.
Does not take any options/parameters.
"""
@impl true
@spec new(any()) :: t()
def new(_unused \\ nil) do
def new(_max_payload_size) do
%__MODULE__{}
end

@doc """
Packs Opus packet into an RTP packet.
Fields from RTP header like ssrc, timestamp etc. are set to 0.
Always returns a single RTP packet.
"""
@impl true
@spec payload(t(), binary()) :: {[ExRTP.Packet.t()], t()}
def payload(%__MODULE__{} = payloader, packet) when packet != <<>> do
Expand Down
42 changes: 16 additions & 26 deletions lib/ex_webrtc/rtp/payloader.ex
Original file line number Diff line number Diff line change
@@ -1,53 +1,43 @@
defmodule ExWebRTC.RTP.Payloader do
@moduledoc """
Dispatcher module and behaviour for ExWebRTC Payloaders.
"""

alias ExWebRTC.RTPCodecParameters
RTP payloader.
@type payloader :: struct()

@doc """
Creates a new payloader struct.
It packs audio/video frames into one or more RTP packets.
"""
@callback new(options :: any()) :: payloader()

@doc """
Packs a frame into one or more RTP packets.
alias ExWebRTC.RTPCodecParameters

Returns the packets together with the updated payloader struct.
"""
@callback payload(payloader(), frame :: binary()) :: {[ExRTP.Packet.t()], payloader()}
@opaque payloader :: struct()

@doc """
Creates a new payloader struct that matches the passed codec parameters.
Creates a new payloader that matches the passed codec parameters.
Refer to the modules implementing the behaviour for available options.
* max_payload_size - determines the maximum size of a single RTP packet outputted by the payloader.
It must be greater than `100`, and is set to `1000` by default.
"""
@spec new(RTPCodecParameters.t(), any()) ::
@spec new(RTPCodecParameters.t(), integer()) ::
{:ok, payloader()} | {:error, :no_payloader_for_codec}
def new(codec_params, options \\ nil) do
with {:ok, module} <- match_payloader_module(codec_params.mime_type) do
payloader = if is_nil(options), do: module.new(), else: module.new(options)

def new(codec_params, max_payload_size \\ 1000) do
with {:ok, module} <- to_payloader_module(codec_params.mime_type) do
payloader = module.new(max_payload_size)
{:ok, payloader}
end
end

@doc """
Packs a frame into one or more RTP packets using the payloader's module.
Packs a frame into one or more RTP packets.
Returns the packets together with the updated payloader struct.
Returns the packets together with the updated payloader.
"""
@spec payload(payloader(), binary()) :: {[ExRTP.Packet.t()], payloader()}
def payload(%module{} = payloader, frame) do
module.payload(payloader, frame)
end

defp match_payloader_module(mime_type) do
defp to_payloader_module(mime_type) do
case String.downcase(mime_type) do
"video/vp8" -> {:ok, ExWebRTC.RTP.VP8.Payloader}
"audio/opus" -> {:ok, ExWebRTC.RTP.Opus.Payloader}
"video/vp8" -> {:ok, ExWebRTC.RTP.Payloader.VP8}
"audio/opus" -> {:ok, ExWebRTC.RTP.Payloader.Opus}
_other -> {:error, :no_payloader_for_codec}
end
end
Expand Down
17 changes: 17 additions & 0 deletions lib/ex_webrtc/rtp/payloader_behaviour.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule ExWebRTC.RTP.Payloader.Behaviour do
@moduledoc false

@type payloader :: struct()

@doc """
Creates a new payloader struct.
"""
@callback new(max_payload_size :: integer()) :: payloader()

@doc """
Packs a frame into one or more RTP packets.
Returns the packets together with the updated payloader struct.
"""
@callback payload(payloader(), frame :: binary()) :: {[ExRTP.Packet.t()], payloader()}
end
40 changes: 13 additions & 27 deletions lib/ex_webrtc/rtp/vp8/depayloader.ex
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
defmodule ExWebRTC.RTP.VP8.Depayloader do
@moduledoc """
Reassembles VP8 frames from RTP packets.
defmodule ExWebRTC.RTP.Depayloader.VP8 do
@moduledoc false
# Reassembles VP8 frames from RTP packets.
#
# Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).

Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).
"""

@behaviour ExWebRTC.RTP.Depayloader
@behaviour ExWebRTC.RTP.Depayloader.Behaviour

require Logger

alias ExWebRTC.RTP.VP8.Payload

@opaque t() :: %__MODULE__{
current_frame: nil,
current_timestamp: nil
}
@type t() :: %__MODULE__{
current_frame: nil,
current_timestamp: nil
}

defstruct [:current_frame, :current_timestamp]

@doc """
Creates a new VP8 depayloader struct.
Does not take any options/parameters.
"""
@impl true
@spec new(any()) :: t()
def new(_unused \\ nil) do
def new() do
%__MODULE__{}
end

@doc """
Reassembles VP8 frames from subsequent RTP packets.
Returns the frame (or `nil` if a frame could not be depayloaded yet)
together with the updated depayloader struct.
"""
@impl true
@spec depayload(t(), ExRTP.Packet.t()) :: {binary() | nil, t()}
def depayload(depayloader, packet)

def depayload(depayloader, %ExRTP.Packet{payload: <<>>, padding: true}), do: {nil, depayloader}

def depayload(depayloader, packet) do
case Payload.parse(packet.payload) do
{:ok, vp8_payload} ->
do_write(depayloader, packet, vp8_payload)
do_depayload(depayloader, packet, vp8_payload)

{:error, reason} ->
Logger.warning("""
Expand All @@ -56,7 +42,7 @@ defmodule ExWebRTC.RTP.VP8.Depayloader do
end
end

defp do_write(depayloader, packet, vp8_payload) do
defp do_depayload(depayloader, packet, vp8_payload) do
depayloader =
case {depayloader.current_frame, vp8_payload} do
{nil, %Payload{s: 1, pid: 0}} ->
Expand Down
9 changes: 4 additions & 5 deletions lib/ex_webrtc/rtp/vp8/payload.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
defmodule ExWebRTC.RTP.VP8.Payload do
@moduledoc """
Defines VP8 payload structure stored in RTP packet payload.
Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).
"""
@moduledoc false
# Defines VP8 payload structure stored in RTP packet payload.
#
# Based on [RFC 7741: RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741).

@type t() :: %__MODULE__{
n: 0 | 1,
Expand Down
Loading

0 comments on commit 9dd373a

Please sign in to comment.