Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Commit

Permalink
Fix skipping parameters (#9)
Browse files Browse the repository at this point in the history
* Fix skipping parameters

* Update version
  • Loading branch information
gBillal authored Oct 16, 2023
1 parent f971f60 commit 7cf4436
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 38 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The package can be installed by adding `membrane_h265_plugin` to your list of de
```elixir
def deps do
[
{:membrane_h265_plugin, "~> 0.3.0"}
{:membrane_h265_plugin, "~> 0.3.1"}
]
end
```
Expand Down
50 changes: 22 additions & 28 deletions lib/membrane_h265_plugin/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ defmodule Membrane.H265.Parser do
output_stream_structure =
case opts.output_stream_structure do
:hvc1 -> {:hvc1, @nalu_length_size}
:hev1 -> {:hvc1, @nalu_length_size}
:hev1 -> {:hev1, @nalu_length_size}
stream_structure -> stream_structure
end

Expand Down Expand Up @@ -286,7 +286,6 @@ defmodule Membrane.H265.Parser do
{nalus, nalu_parser} = NALuParser.parse_nalus(nalus_payloads, timestamps, state.nalu_parser)
is_au_aligned = state.mode == :au_aligned
{access_units, au_splitter} = AUSplitter.split(nalus, is_au_aligned, state.au_splitter)
{access_units, state} = skip_improper_aus(access_units, state)
{actions, state} = prepare_actions_for_aus(access_units, ctx, state)

state = %{
Expand All @@ -304,8 +303,7 @@ defmodule Membrane.H265.Parser do
{last_nalu_payload, nalu_splitter} = NALuSplitter.split(<<>>, true, state.nalu_splitter)
{last_nalu, nalu_parser} = NALuParser.parse_nalus(last_nalu_payload, state.nalu_parser)
{maybe_improper_aus, au_splitter} = AUSplitter.split(last_nalu, true, state.au_splitter)
{aus, state} = skip_improper_aus(maybe_improper_aus, state)
{actions, state} = prepare_actions_for_aus(aus, ctx, state)
{actions, state} = prepare_actions_for_aus(maybe_improper_aus, ctx, state)

actions = if stream_format_sent?(actions, ctx), do: actions, else: []

Expand Down Expand Up @@ -511,23 +509,16 @@ defmodule Membrane.H265.Parser do
defp is_input_stream_structure_change_allowed?(_stream_structure1, _stream_structure2),
do: false

defp skip_improper_aus(aus, state) do
Enum.flat_map_reduce(aus, state, fn au, state ->
has_seen_keyframe? =
Enum.all?(au, &(&1.status == :valid)) and
Enum.any?(au, &(&1.type in NALuTypes.irap_nalus()))
@spec skip_au?(AUSplitter.access_unit(), state()) :: {boolean(), state()}
defp skip_au?(au, state) do
has_seen_keyframe? = Enum.all?(au, &(&1.status == :valid)) and irap_au?(au)

state = %{
state
| skip_until_keyframe: state.skip_until_keyframe and not has_seen_keyframe?
}
state = %{
state
| skip_until_keyframe: state.skip_until_keyframe and not has_seen_keyframe?
}

if Enum.any?(au, &(&1.status == :error)) or state.skip_until_keyframe do
{[], state}
else
{[au], state}
end
end)
{Enum.any?(au, &(&1.status == :error)) or state.skip_until_keyframe, state}
end

@spec prepare_actions_for_aus(
Expand All @@ -540,12 +531,17 @@ defmodule Membrane.H265.Parser do
{au, stream_format_actions, state} = process_au_parameter_sets(au, ctx, state)

{{pts, dts}, state} = prepare_timestamps(au, state)
{shoud_skip_au, state} = skip_au?(au, state)

buffers_actions = [
buffer:
{:output,
wrap_into_buffer(au, pts, dts, state.output_alignment, state.output_stream_structure)}
]
buffers_actions =
if shoud_skip_au do
[]
else
buffers =
wrap_into_buffer(au, pts, dts, state.output_alignment, state.output_stream_structure)

[buffer: {:output, buffers}]
end

{stream_format_actions ++ buffers_actions, state}
end)
Expand Down Expand Up @@ -597,17 +593,15 @@ defmodule Membrane.H265.Parser do
Membrane.Time.t(),
:au | :nalu,
stream_structure()
) :: Buffer.t()
) :: Buffer.t() | [Buffer.t()]
defp wrap_into_buffer(access_unit, pts, dts, :au, output_stream_structure) do
metadata = prepare_au_metadata(access_unit)

buffer =
access_unit
|> Enum.reduce(<<>>, fn nalu, acc ->
acc <> NALuParser.get_prefixed_nalu_payload(nalu, output_stream_structure)
end)
|> then(fn payload ->
%Buffer{payload: payload, metadata: metadata, pts: pts, dts: dts}
%Buffer{payload: payload, metadata: prepare_au_metadata(access_unit), pts: pts, dts: dts}
end)

buffer
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.H265.Plugin.Mixfile do
use Mix.Project

@version "0.3.0"
@version "0.3.1"
@github_url "https://github.com/gBillal/membrane_h265_plugin"

def project do
Expand Down
Binary file added test/fixtures/input-32-640x360-main.h265
Binary file not shown.
40 changes: 32 additions & 8 deletions test/integration/timestamp_generation_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,43 @@ defmodule Membrane.H265.TimestampGenerationTest do
end
end

@h265_input_file_main "test/fixtures/input-10-640x480-main10.h265"
@h265_input_file_main "test/fixtures/input-32-640x360-main.h265"
@h265_input_timestamps_main [
{0, -500},
{33, -467},
{167, -433},
{67, -467},
{33, -433},
{100, -400},
{67, -367},
{167, -367},
{133, -333},
{300, -300},
{233, -267},
{200, -233},
{267, -200}
{233, -300},
{200, -267},
{300, -233},
{267, -200},
{367, -167},
{333, -133},
{400, -100},
{467, -67},
{433, -33},
{533, 0},
{500, 33},
{600, 67},
{567, 100},
{667, 133},
{633, 167},
{700, 200},
{767, 233},
{733, 267},
{833, 300},
{800, 333},
{900, 367},
{867, 400},
{967, 433},
{933, 467},
{1000, 500},
{1067, 533},
{1033, 567}
]

@h265_input_file_baseline "test/fixtures/input-10-1920x1080.h265"
@h265_input_timestamps_baseline [0, 33, 67, 100, 133, 167, 200, 233, 267, 300]
|> Enum.map(&{&1, &1 - 500})
Expand Down

0 comments on commit 7cf4436

Please sign in to comment.