Skip to content

Commit

Permalink
Add hacky NALU completion handling (#39)
Browse files Browse the repository at this point in the history
* Add hacky NALU completion handling

* Add explanation for new AU start detection
  • Loading branch information
Qizot committed Aug 10, 2023
1 parent 5fbe30a commit 8b14257
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
4 changes: 2 additions & 2 deletions 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_h264_plugin` to your list of de
```elixir
def deps do
[
{:membrane_h264_plugin, "~> 0.5.0"}
{:membrane_h264_plugin, "~> 0.5.1"}
]
end
```
Expand All @@ -39,7 +39,7 @@ defmodule Decoding.Pipeline do

@impl true
def handle_init(_ctx, _opts) do
structure =
structure =
child(:source, %File.Source{location: "test/fixtures/input-10-720p-main.h264"})
|> child(:parser, H264.Parser)
|> child(:decoder, H264.FFmpeg.Decoder)
Expand Down
18 changes: 17 additions & 1 deletion lib/membrane_h264_plugin/parser/au_splitter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,19 @@ defmodule Membrane.H264.Parser.AUSplitter do
{state.nalus_acc, %{state | nalus_acc: []}}
end

# Reference source for the behaviour below:
# https://github.com/GStreamer/gst-plugins-bad/blob/ca8068c6d793d7aaa6f2e2cc6324fdedfe2f33fa/gst/videoparsers/gsth264parse.c#L1183C45-L1185C49
#
# NOTE: The following check is not a part of the original H264 specification unlike the other checks below.
#
# It happens that some streams have broken frame numbers (that are either non-monotically
# increasing or just reset on a key frame) but the `first_mb_in_slice` set to zero can mean that
# we are dealin with a new AU (given a proper `nal_unit_type`). It seems that it is sufficient
# condition to check for `first_mb_in_slice` set to zero to detect a new AU.
defguardp first_mb_in_slice_zero(a)
when a.first_mb_in_slice == 0 and
a.nal_unit_type in [1, 2, 5]

defguardp frame_num_differs(a, b) when a.frame_num != b.frame_num

defguardp pic_parameter_set_id_differs(a, b)
Expand Down Expand Up @@ -210,6 +223,7 @@ defmodule Membrane.H264.Parser.AUSplitter do
# Conditions based on 7.4.1.2.4 "Detection of the first VCL NAL unit of a primary coded picture"
# of the "ITU-T Rec. H.264 (01/2012)"
defp is_new_primary_coded_vcl_nalu(%{parsed_fields: nalu}, %{parsed_fields: last_nalu})
when first_mb_in_slice_zero(nalu)
when frame_num_differs(nalu, last_nalu)
when pic_parameter_set_id_differs(nalu, last_nalu)
when field_pic_flag_differs(nalu, last_nalu)
Expand All @@ -223,5 +237,7 @@ defmodule Membrane.H264.Parser.AUSplitter do
true
end

defp is_new_primary_coded_vcl_nalu(_nalu, _last_nalu), do: false
defp is_new_primary_coded_vcl_nalu(_nalu, _last_nalu) do
false
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Membrane.H264.Plugin.Mixfile do
use Mix.Project

@version "0.5.0"
@version "0.5.1"
@github_url "https://github.com/membraneframework-labs/membrane_h264_plugin"

def project do
Expand Down

0 comments on commit 8b14257

Please sign in to comment.