Skip to content

Commit

Permalink
Merge pull request #58 from membraneframework/pts_bad_arthmetic_fix
Browse files Browse the repository at this point in the history
PTS integrity check crashing with nil pts fix
  • Loading branch information
bartkrak authored Apr 17, 2024
2 parents 99c2843 + 965446d commit bd42666
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The package can be installed by adding `membrane_aac_fdk_plugin` to your list of
```elixir
def deps do
[
{:membrane_aac_fdk_plugin, "~> 0.18.7"}
{:membrane_aac_fdk_plugin, "~> 0.18.8"}
]
end
```
Expand Down
3 changes: 2 additions & 1 deletion lib/membrane_aac_fdk_plugin/encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ defmodule Membrane.AAC.FDK.Encoder do
end

defp validate_pts_integrity(packets, input_pts) do
with [%Buffer{pts: first_pts}, %Buffer{pts: second_pts} | _tail] <- packets do
with [%Buffer{pts: first_pts}, %Buffer{pts: second_pts} | _tail]
when first_pts != nil and second_pts != nil <- packets do
duration = second_pts - first_pts
epsilon = duration / 10

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Membrane.AAC.FDK.Plugin.MixProject do
use Mix.Project

@version "0.18.7"
@version "0.18.8"
@github_url "https://github.com/membraneframework/membrane_aac_fdk_plugin"

def project do
Expand Down
77 changes: 77 additions & 0 deletions test/membrane_element_fdk_aac/pts_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
defmodule Membrane.FLAC.Parser.IntegrationTest do
use ExUnit.Case, async: true
import Membrane.Testing.Assertions
alias Membrane.{Pipeline, Time}

test "encode with timestamps" do
pipeline = prepare_pts_test_pipeline(true)

Enum.each(0..294, fn index ->
assert_sink_buffer(pipeline, :sink, %Membrane.Buffer{pts: out_pts})

# every other buffer gets queued and concated with next one to be big enough, because of that we expect different pts than on input
assert out_pts == (index * 2 * 1000) |> Time.nanoseconds()
end)

Pipeline.terminate(pipeline)
end

test "encode without timestamps" do
pipeline = prepare_pts_test_pipeline(false)

Enum.each(0..294, fn _index ->
assert_sink_buffer(pipeline, :sink, %Membrane.Buffer{pts: out_pts})
assert out_pts == nil
end)

Pipeline.terminate(pipeline)
end

defp prepare_pts_test_pipeline(with_pts?) do
import Membrane.ChildrenSpec

spec =
child(:source, %Membrane.Testing.Source{
output: buffers_from_file(with_pts?),
stream_format: %Membrane.RawAudio{
sample_format: :s16le,
sample_rate: 16_000,
channels: 1
}
})
|> child(:aac_encoder, Membrane.AAC.FDK.Encoder)
|> child(:sink, Membrane.Testing.Sink)

Membrane.Testing.Pipeline.start_link_supervised!(spec: spec)
end

defp buffers_from_file(with_pts?) do
# 589 buffers is generated from this binary
binary = "../fixtures/input-encoder.raw" |> Path.expand(__DIR__) |> File.read!()

split_binary(binary)
|> Enum.with_index()
|> Enum.map(fn {payload, index} ->
%Membrane.Buffer{
payload: payload,
pts:
if with_pts? do
(index * 1000) |> Time.nanoseconds()
else
nil
end
}
end)
end

@spec split_binary(binary(), list(binary())) :: list(binary())
def split_binary(binary, acc \\ [])

def split_binary(<<binary::binary-size(1024), rest::binary>>, acc) do
split_binary(rest, [binary] ++ acc)
end

def split_binary(rest, acc) when byte_size(rest) <= 1024 do
Enum.reverse(acc) ++ [rest]
end
end

0 comments on commit bd42666

Please sign in to comment.