diff --git a/README.md b/README.md index 5362a8a..431a277 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ The package can be installed by adding `membrane_rtp_h264_plugin` to your list o ```elixir def deps do [ - {:membrane_rtp_h264_plugin, "~> 0.19.4"} + {:membrane_rtp_h264_plugin, "~> 0.20.0"} ] end ``` diff --git a/lib/rtp_h264/depayloader.ex b/lib/rtp_h264/depayloader.ex index bba0f53..861a8c2 100644 --- a/lib/rtp_h264/depayloader.ex +++ b/lib/rtp_h264/depayloader.ex @@ -65,9 +65,7 @@ defmodule Membrane.RTP.H264.Depayloader do end defp handle_unit_type(:fu_a, {header, data}, buffer, state) do - %Buffer{metadata: %{rtp: %{sequence_number: seq_num}}} = buffer - - case FU.parse(data, seq_num, map_state_to_fu(state)) do + case FU.parse(data, map_state_to_fu(state)) do {:ok, {data, type}} -> data = NAL.Header.add_header(data, 0, header.nal_ref_idc, type) result = buffer_output(data, buffer, %State{state | parser_acc: nil}) diff --git a/lib/rtp_h264/nal_formats/fu.ex b/lib/rtp_h264/nal_formats/fu.ex index 22ffdba..3333f9e 100644 --- a/lib/rtp_h264/nal_formats/fu.ex +++ b/lib/rtp_h264/nal_formats/fu.ex @@ -6,14 +6,9 @@ defmodule Membrane.RTP.H264.FU do alias __MODULE__ alias Membrane.RTP.H264.NAL - defstruct [:last_seq_num, data: []] + defstruct data: [] - @type t :: %__MODULE__{ - data: [binary()], - last_seq_num: nil | non_neg_integer() - } - - defguardp is_next(last_seq_num, next_seq_num) when rem(last_seq_num + 1, 65_536) == next_seq_num + @type t :: %__MODULE__{data: [binary()]} @doc """ Parses H264 Fragmentation Unit @@ -23,13 +18,13 @@ defmodule Membrane.RTP.H264.FU do In case of last packet `{:ok, {type, data}}` tuple will be returned, where data is `NAL Unit` created by concatenating subsequent Fragmentation Units. """ - @spec parse(binary(), non_neg_integer(), t) :: + @spec parse(binary(), t) :: {:ok, {binary(), NAL.Header.type()}} | {:error, :packet_malformed | :invalid_first_packet} | {:incomplete, t()} - def parse(data, seq_num, acc) do - with {:ok, {header, value}} <- FU.Header.parse(data) do - do_parse(header, value, seq_num, acc) + def parse(packet, acc) do + with {:ok, {header, value}} <- FU.Header.parse(packet) do + do_parse(header, value, acc) end end @@ -73,30 +68,23 @@ defmodule Membrane.RTP.H264.FU do end end - defp do_parse(header, data, seq_num, acc) + defp do_parse(header, packet, acc) - defp do_parse(%FU.Header{start_bit: true}, data, seq_num, acc), - do: {:incomplete, %__MODULE__{acc | data: [data], last_seq_num: seq_num}} + defp do_parse(%FU.Header{start_bit: true}, packet, acc), + do: {:incomplete, %__MODULE__{acc | data: [packet]}} - defp do_parse(%FU.Header{start_bit: false}, _data, _seq_num, %__MODULE__{last_seq_num: nil}), + defp do_parse(%FU.Header{start_bit: false}, _data, %__MODULE__{data: []}), do: {:error, :invalid_first_packet} - defp do_parse(%FU.Header{end_bit: true, type: type}, data, seq_num, %__MODULE__{ - data: acc, - last_seq_num: last - }) - when is_next(last, seq_num) do + defp do_parse(%FU.Header{end_bit: true, type: type}, packet, %__MODULE__{data: acc_data}) do result = - [data | acc] + [packet | acc_data] |> Enum.reverse() |> Enum.join() {:ok, {result, type}} end - defp do_parse(_header, data, seq_num, %__MODULE__{data: acc, last_seq_num: last} = fu) - when is_next(last, seq_num), - do: {:incomplete, %__MODULE__{fu | data: [data | acc], last_seq_num: seq_num}} - - defp do_parse(_header, _data, _seq_num, _fu), do: {:error, :missing_packet} + defp do_parse(_header, packet, %__MODULE__{data: acc_data} = fu), + do: {:incomplete, %__MODULE__{fu | data: [packet | acc_data]}} end diff --git a/mix.exs b/mix.exs index cbdd3cd..38a3f3b 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Membrane.RTP.H264.MixProject do use Mix.Project - @version "0.19.4" + @version "0.20.0" @github_url "https://github.com/membraneframework/membrane_rtp_h264_plugin" def project do diff --git a/test/nal_formaters/fu_a_test.exs b/test/nal_formaters/fu_a_test.exs index 3915b74..90c3f25 100644 --- a/test/nal_formaters/fu_a_test.exs +++ b/test/nal_formaters/fu_a_test.exs @@ -5,14 +5,11 @@ defmodule Membrane.RTP.H264.FUTest do alias Membrane.RTP.H264.FU alias Membrane.Support.Formatters.FUFactory - @base_seq_num 4567 - describe "Fragmentation Unit parser" do test "parses first packet" do packet = FUFactory.first() - assert {:incomplete, fu} = FU.parse(packet, @base_seq_num, %FU{}) - assert %FU{last_seq_num: @base_seq_num} = fu + assert {:incomplete, _fu} = FU.parse(packet, %FU{}) end test "parses packet sequence" do @@ -20,9 +17,8 @@ defmodule Membrane.RTP.H264.FUTest do result = fixtures - |> Enum.zip(1..Enum.count(fixtures)) - |> Enum.reduce(%FU{}, fn {elem, seq_num}, acc -> - FU.parse(elem, seq_num, acc) + |> Enum.reduce(%FU{}, fn elem, acc -> + FU.parse(elem, acc) ~> ({_command, value} -> value) end) @@ -30,25 +26,13 @@ defmodule Membrane.RTP.H264.FUTest do assert result == {expected_result, 1} end - test "returns error when one of non edge packets dropped" do - fixtures = FUFactory.get_all_fixtures() - - assert {:error, :missing_packet} == - fixtures - |> Enum.zip([0, 1, 3, 4, 5]) - |> Enum.reduce(%FU{}, fn {elem, seq_num}, acc -> - FU.parse(elem, seq_num, acc) - ~>> ({command, fu} when command in [:incomplete, :ok] -> fu) - end) - end - test "returns error when first packet is not starting packet" do invalid_first_packet = <<0::5, 3::3>> - assert {:error, :invalid_first_packet} == FU.parse(invalid_first_packet, 2, %FU{}) + assert {:error, :invalid_first_packet} == FU.parse(invalid_first_packet, %FU{}) end test "returns error when header is not valid" do - assert {:error, :packet_malformed} == FU.parse(<<0::2, 1::1, 1::5>>, 0, %FU{}) + assert {:error, :packet_malformed} == FU.parse(<<0::2, 1::1, 1::5>>, %FU{}) end end end