Skip to content

Commit

Permalink
skip persumed AUs that don't have any VCL NALus (#62)
Browse files Browse the repository at this point in the history
* skip persumed AUs that don't have any VCL NALus

* add typespec

* forward_au? -> should_forward_au

* bump version
  • Loading branch information
mat-hek authored May 14, 2024
1 parent a43f00e commit 89ce132
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The package can be installed by adding `membrane_h26x_plugin` to your list of de
```elixir
def deps do
[
{:membrane_h26x_plugin, "~> 0.10.1"}
{:membrane_h26x_plugin, "~> 0.10.2"}
]
end
```
Expand Down
58 changes: 30 additions & 28 deletions lib/membrane_h264_plugin/h26x_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -354,18 +354,15 @@ defmodule Membrane.H26x.Parser do

@spec prepare_actions_for_au(AUSplitter.access_unit(), boolean(), state()) :: callback_return()
def prepare_actions_for_au(au, keyframe?, state) do
{{pts, dts}, state} = prepare_timestamps(au, state)
{should_skip_au, state} = skip_au?(au, keyframe?, state)
{should_forward_au, state} = should_forward_au(au, keyframe?, state)

buffers_actions =
if should_skip_au do
[]
else
buffers = wrap_into_buffer(au, pts, dts, keyframe?, state)
[buffer: {:output, buffers}]
end

{buffers_actions, state}
if should_forward_au do
{{pts, dts}, state} = prepare_timestamps(au, state)
buffers = wrap_into_buffer(au, pts, dts, keyframe?, state)
{[buffer: {:output, buffers}], state}
else
{[], state}
end
end

@spec flatten_parameter_sets(parameter_sets()) :: list()
Expand Down Expand Up @@ -407,28 +404,33 @@ defmodule Membrane.H26x.Parser do

{timestamps, %{state | au_timestamp_generator: timestamp_generator}}
else
case state.nalu_parser_mod do
Membrane.H264.NALuParser ->
require Membrane.H264.NALuTypes, as: NALuTypes
{Enum.find(au, &NALuTypes.is_vcl_nalu_type(&1.type)).timestamps, state}

Membrane.H265.NALuParser ->
require Membrane.H265.NALuTypes, as: NALuTypes
{Enum.find(au, &NALuTypes.is_vcl_nalu_type(&1.type)).timestamps, state}
end
{first_vcl_nalu(au, state).timestamps, state}
end
end

@spec skip_au?(AUSplitter.access_unit(), boolean(), state()) :: {boolean(), state()}
defp skip_au?(au, keyframe?, state) do
has_seen_keyframe? = keyframe? and Enum.all?(au, &(&1.status == :valid))
@spec should_forward_au(AUSplitter.access_unit(), boolean(), state()) :: {boolean(), state()}
defp should_forward_au(au, keyframe?, state) do
with true <- Enum.all?(au, &(&1.status == :valid)),
true <- first_vcl_nalu(au, state) != nil do
skip_until_keyframe? = state.skip_until_keyframe and not keyframe?
state = %{state | skip_until_keyframe: skip_until_keyframe?}
{not skip_until_keyframe?, state}
else
false -> {false, state}
end
end

state = %{
state
| skip_until_keyframe: state.skip_until_keyframe and not has_seen_keyframe?
}
@spec first_vcl_nalu(AUSplitter.access_unit(), state()) :: Membrane.H26x.NALu.t()
defp first_vcl_nalu(au, state) do
case state.nalu_parser_mod do
Membrane.H264.NALuParser ->
require Membrane.H264.NALuTypes, as: NALuTypes
Enum.find(au, &NALuTypes.is_vcl_nalu_type(&1.type))

{Enum.any?(au, &(&1.status == :error)) or state.skip_until_keyframe, state}
Membrane.H265.NALuParser ->
require Membrane.H265.NALuTypes, as: NALuTypes
Enum.find(au, &NALuTypes.is_vcl_nalu_type(&1.type))
end
end

@spec wrap_into_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.H26x.Plugin.Mixfile do
use Mix.Project

@version "0.10.1"
@version "0.10.2"
@github_url "https://github.com/membraneframework/membrane_h26x_plugin"

def project do
Expand Down

0 comments on commit 89ce132

Please sign in to comment.