-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add behaviour and dynamic dispatch for (de)payloaders (#147)
Co-authored-by: Michał Śledź <[email protected]>
- Loading branch information
Showing
15 changed files
with
329 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
defmodule ExWebRTC.RTP.Depayloader do | ||
@moduledoc """ | ||
RTP depayloader. | ||
It unpacks RTP pakcets into audio/video frames. | ||
""" | ||
|
||
alias ExWebRTC.RTPCodecParameters | ||
|
||
@opaque depayloader :: struct() | ||
|
||
@doc """ | ||
Creates a new depayloader that matches the passed codec parameters. | ||
""" | ||
@spec new(RTPCodecParameters.t()) :: | ||
{:ok, depayloader()} | {:error, :no_depayloader_for_codec} | ||
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, and outputs a frame if assembled. | ||
Returns the frame (or `nil` if a frame could not be depayloaded yet) | ||
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 to_depayloader_module(mime_type) do | ||
case String.downcase(mime_type) do | ||
"video/vp8" -> {:ok, ExWebRTC.RTP.Depayloader.VP8} | ||
"audio/opus" -> {:ok, ExWebRTC.RTP.Depayloader.Opus} | ||
_other -> {:error, :no_depayloader_for_codec} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,25 @@ | ||
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 | ||
|
||
@doc """ | ||
Takes Opus packet out of an RTP packet. | ||
""" | ||
@spec depayload(Packet.t()) :: binary() | ||
def depayload(%Packet{payload: payload}), do: payload | ||
@behaviour ExWebRTC.RTP.Depayloader.Behaviour | ||
|
||
@type t :: %__MODULE__{} | ||
|
||
defstruct [] | ||
|
||
@impl true | ||
@spec new() :: t() | ||
def new() do | ||
%__MODULE__{} | ||
end | ||
|
||
@impl true | ||
@spec depayload(t(), Packet.t()) :: {binary(), t()} | ||
def depayload(%__MODULE__{} = depayloader, %Packet{payload: payload}), | ||
do: {payload, depayloader} | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,23 @@ | ||
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 | ||
|
||
@doc """ | ||
Packs Opus packet into an RTP packet. | ||
@type t :: %__MODULE__{} | ||
|
||
Fields from RTP header like ssrc, timestamp etc. are set to 0. | ||
""" | ||
@spec payload(binary()) :: ExRTP.Packet.t() | ||
def payload(packet) when packet != <<>> do | ||
ExRTP.Packet.new(packet) | ||
defstruct [] | ||
|
||
@impl true | ||
def new(_max_payload_size) do | ||
%__MODULE__{} | ||
end | ||
|
||
@impl true | ||
@spec payload(t(), binary()) :: {[ExRTP.Packet.t()], t()} | ||
def payload(%__MODULE__{} = payloader, packet) when packet != <<>> do | ||
{[ExRTP.Packet.new(packet)], payloader} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
defmodule ExWebRTC.RTP.Payloader do | ||
@moduledoc """ | ||
RTP payloader. | ||
It packs audio/video frames into one or more RTP packets. | ||
""" | ||
|
||
alias ExWebRTC.RTPCodecParameters | ||
|
||
@opaque payloader :: struct() | ||
|
||
@doc """ | ||
Creates a new payloader that matches the passed codec parameters. | ||
Opts: | ||
* 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(), max_payload_size: integer()) :: | ||
{:ok, payloader()} | {:error, :no_payloader_for_codec} | ||
def new(codec_params, opts \\ []) do | ||
with {:ok, module} <- to_payloader_module(codec_params.mime_type) do | ||
max_payload_size = opts[:max_payload_size] || 1000 | ||
payloader = module.new(max_payload_size) | ||
{:ok, payloader} | ||
end | ||
end | ||
|
||
@doc """ | ||
Packs a frame into one or more RTP packets. | ||
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 to_payloader_module(mime_type) do | ||
case String.downcase(mime_type) do | ||
"video/vp8" -> {:ok, ExWebRTC.RTP.Payloader.VP8} | ||
"audio/opus" -> {:ok, ExWebRTC.RTP.Payloader.Opus} | ||
_other -> {:error, :no_payloader_for_codec} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.