From b4d16fca22cdeb64c1d82563b4fea11c6dfb0800 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Mon, 8 Jul 2024 18:34:32 +0200 Subject: [PATCH 01/17] Start implementing DemangKeyframeEvent for encoders --- lib/membrane_vpx/demand_keyframe_event.ex | 9 +++++++++ lib/membrane_vpx/encoder/vpx_encoder.ex | 7 ++++++- mix.exs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 lib/membrane_vpx/demand_keyframe_event.ex diff --git a/lib/membrane_vpx/demand_keyframe_event.ex b/lib/membrane_vpx/demand_keyframe_event.ex new file mode 100644 index 0000000..ee972c7 --- /dev/null +++ b/lib/membrane_vpx/demand_keyframe_event.ex @@ -0,0 +1,9 @@ +defmodule Membrane.DemandKeyframeEvent do + @moduledoc """ + Event that causes the next frame produced by the encoder to be a keyframe + """ + @derive Membrane.EventProtocol + + @type t :: %__MODULE__{} + defstruct [] +end diff --git a/lib/membrane_vpx/encoder/vpx_encoder.ex b/lib/membrane_vpx/encoder/vpx_encoder.ex index 8eb96c5..cb5cf24 100644 --- a/lib/membrane_vpx/encoder/vpx_encoder.ex +++ b/lib/membrane_vpx/encoder/vpx_encoder.ex @@ -1,7 +1,7 @@ defmodule Membrane.VPx.Encoder do @moduledoc false - alias Membrane.{Buffer, RawVideo, VP8, VP9} + alias Membrane.{Buffer, DemandKeyframeEvent, RawVideo, VP8, VP9} alias Membrane.Element.CallbackContext alias Membrane.VPx.Encoder.Native @@ -75,6 +75,11 @@ defmodule Membrane.VPx.Encoder do {[buffer: {:output, buffers}], state} end + @spec handle_event(:output, DemandKeyframeEvent.t(), CallbackContext.t(), State.t()) :: + callback_return() + def handle_event(:output, %DemandKeyframeEvent{}, _ctx, state) do + end + @spec handle_end_of_stream(:input, CallbackContext.t(), State.t()) :: callback_return() def handle_end_of_stream(:input, _ctx, state) do buffers = flush(state.encoder_ref) diff --git a/mix.exs b/mix.exs index f82d0a0..f984aad 100644 --- a/mix.exs +++ b/mix.exs @@ -83,7 +83,7 @@ defmodule Membrane.VPx.Plugin.Mixfile do extras: ["README.md", "LICENSE"], formatters: ["html"], source_ref: "v#{@version}", - nest_modules_by_prefix: [Membrane.VPX] + nest_modules_by_prefix: [Membrane.VPx] ] end end From 85031b96c778ac4fa0a10e398b557c4344fcfd3f Mon Sep 17 00:00:00 2001 From: noarkhh Date: Tue, 9 Jul 2024 11:31:06 +0200 Subject: [PATCH 02/17] Add ForceKeyframeEvent --- c_src/membrane_vpx_plugin/vpx_encoder.c | 110 +++++++++--------- .../membrane_vpx_plugin/vpx_encoder.spec.exs | 4 +- lib/membrane_vpx/encoder/vpx_encoder.ex | 32 ++--- ...frame_event.ex => force_keyframe_event.ex} | 2 +- mix.lock | 2 +- 5 files changed, 81 insertions(+), 69 deletions(-) rename lib/membrane_vpx/{demand_keyframe_event.ex => force_keyframe_event.ex} (80%) diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.c b/c_src/membrane_vpx_plugin/vpx_encoder.c index 942c0b8..e4151a0 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.c +++ b/c_src/membrane_vpx_plugin/vpx_encoder.c @@ -26,14 +26,9 @@ vpx_img_fmt_t translate_pixel_format(PixelFormat pixel_format) { } } -UNIFEX_TERM create( - UnifexEnv *env, - Codec codec, - unsigned int width, - unsigned int height, - PixelFormat pixel_format, - unsigned int encoding_deadline -) { +UNIFEX_TERM create(UnifexEnv *env, Codec codec, unsigned int width, + unsigned int height, PixelFormat pixel_format, + unsigned int encoding_deadline) { UNIFEX_TERM result; State *state = unifex_alloc_state(env); vpx_codec_enc_cfg_t config; @@ -49,9 +44,8 @@ UNIFEX_TERM create( state->encoding_deadline = encoding_deadline; if (vpx_codec_enc_config_default(state->codec_interface, &config, 0)) { - return result_error( - env, "Failed to get default codec config", create_result_error, NULL, state - ); + return result_error(env, "Failed to get default codec config", + create_result_error, NULL, state); } config.g_h = height; @@ -60,13 +54,15 @@ UNIFEX_TERM create( config.g_timebase.den = 1000000000; // 1e9 config.g_error_resilient = 1; - if (vpx_codec_enc_init(&state->codec_context, state->codec_interface, &config, 0)) { - return result_error(env, "Failed to initialize encoder", create_result_error, NULL, state); + if (vpx_codec_enc_init(&state->codec_context, state->codec_interface, &config, + 0)) { + return result_error(env, "Failed to initialize encoder", + create_result_error, NULL, state); } - if (!vpx_img_alloc(&state->img, translate_pixel_format(pixel_format), width, height, 1)) { - return result_error( - env, "Failed to allocate image", create_result_error, &state->codec_context, state - ); + if (!vpx_img_alloc(&state->img, translate_pixel_format(pixel_format), width, + height, 1)) { + return result_error(env, "Failed to allocate image", create_result_error, + &state->codec_context, state); } result = create_result_ok(env, state); unifex_release_state(env, state); @@ -77,58 +73,67 @@ void get_image_from_raw_frame(vpx_image_t *img, UnifexPayload *raw_frame) { convert_between_image_and_raw_frame(img, raw_frame, RAW_FRAME_TO_IMAGE); } -void alloc_output_frame( - UnifexEnv *env, const vpx_codec_cx_pkt_t *packet, UnifexPayload **output_frame -) { +void alloc_output_frame(UnifexEnv *env, const vpx_codec_cx_pkt_t *packet, + UnifexPayload **output_frame) { *output_frame = unifex_alloc(sizeof(UnifexPayload)); - unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, packet->data.frame.sz, *output_frame); + unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, packet->data.frame.sz, + *output_frame); } -UNIFEX_TERM encode(UnifexEnv *env, vpx_image_t *img, vpx_codec_pts_t pts, State *state) { +UNIFEX_TERM encode(UnifexEnv *env, vpx_image_t *img, vpx_codec_pts_t pts, + int force_keyframe, State *state) { vpx_codec_iter_t iter = NULL; int flushing = (img == NULL), got_packets = 0; const vpx_codec_cx_pkt_t *packet = NULL; unsigned int frames_cnt = 0, allocated_frames = 1; - UnifexPayload **encoded_frames = unifex_alloc(allocated_frames * sizeof(UnifexPayload*)); + UnifexPayload **encoded_frames = + unifex_alloc(allocated_frames * sizeof(UnifexPayload *)); vpx_codec_pts_t *encoded_frames_timestamps = unifex_alloc(allocated_frames * sizeof(vpx_codec_pts_t)); do { - // Reasoning for the do-while and while loops comes from the description of vpx_codec_encode: + // Reasoning for the do-while and while loops comes from the description of + // vpx_codec_encode: // - // When the last frame has been passed to the encoder, this function should continue to be - // called, with the img parameter set to NULL. This will signal the end-of-stream condition to - // the encoder and allow it to encode any held buffers. Encoding is complete when - // vpx_codec_encode() is called and vpx_codec_get_cx_data() returns no data. - if (vpx_codec_encode(&state->codec_context, img, pts, 1, 0, state->encoding_deadline) != - VPX_CODEC_OK) { + // When the last frame has been passed to the encoder, this function should + // continue to be called, with the img parameter set to NULL. This will + // signal the end-of-stream condition to the encoder and allow it to encode + // any held buffers. Encoding is complete when vpx_codec_encode() is called + // and vpx_codec_get_cx_data() returns no data. + vpx_enc_frame_flags_t flags = force_keyframe ? VPX_EFLAG_FORCE_KF : 0; + if (vpx_codec_encode(&state->codec_context, img, pts, 1, flags, + state->encoding_deadline) != VPX_CODEC_OK) { if (flushing) { - return result_error( - env, "Encoding frame failed", flush_result_error, &state->codec_context, NULL - ); + return result_error(env, "Encoding frame failed", flush_result_error, + &state->codec_context, NULL); } else { - return result_error( - env, "Encoding frame failed", encode_frame_result_error, &state->codec_context, NULL - ); + return result_error(env, "Encoding frame failed", + encode_frame_result_error, &state->codec_context, + NULL); } } + force_keyframe = 0; got_packets = 0; - while ((packet = vpx_codec_get_cx_data(&state->codec_context, &iter)) != NULL) { + while ((packet = vpx_codec_get_cx_data(&state->codec_context, &iter)) != + NULL) { got_packets = 1; - if (packet->kind != VPX_CODEC_CX_FRAME_PKT) continue; + if (packet->kind != VPX_CODEC_CX_FRAME_PKT) + continue; if (frames_cnt >= allocated_frames) { allocated_frames *= 2; - encoded_frames = unifex_realloc(encoded_frames, allocated_frames * sizeof(*encoded_frames)); + encoded_frames = unifex_realloc( + encoded_frames, allocated_frames * sizeof(*encoded_frames)); encoded_frames_timestamps = unifex_realloc( - encoded_frames_timestamps, allocated_frames * sizeof(*encoded_frames_timestamps) - ); + encoded_frames_timestamps, + allocated_frames * sizeof(*encoded_frames_timestamps)); } alloc_output_frame(env, packet, &encoded_frames[frames_cnt]); - memcpy(encoded_frames[frames_cnt]->data, packet->data.frame.buf, packet->data.frame.sz); + memcpy(encoded_frames[frames_cnt]->data, packet->data.frame.buf, + packet->data.frame.sz); encoded_frames_timestamps[frames_cnt] = packet->data.frame.pts; frames_cnt++; } @@ -136,23 +141,24 @@ UNIFEX_TERM encode(UnifexEnv *env, vpx_image_t *img, vpx_codec_pts_t pts, State UNIFEX_TERM result; if (flushing) { - result = - flush_result_ok(env, encoded_frames, frames_cnt, encoded_frames_timestamps, frames_cnt); + result = flush_result_ok(env, encoded_frames, frames_cnt, + encoded_frames_timestamps, frames_cnt); } else { - result = encode_frame_result_ok( - env, encoded_frames, frames_cnt, encoded_frames_timestamps, frames_cnt - ); + result = encode_frame_result_ok(env, encoded_frames, frames_cnt, + encoded_frames_timestamps, frames_cnt); } free_payloads(encoded_frames, frames_cnt); return result; } -UNIFEX_TERM encode_frame( - UnifexEnv *env, UnifexPayload *raw_frame, vpx_codec_pts_t pts, State *state -) { +UNIFEX_TERM encode_frame(UnifexEnv *env, UnifexPayload *raw_frame, + vpx_codec_pts_t pts, int force_keyframe, + State *state) { get_image_from_raw_frame(&state->img, raw_frame); - return encode(env, &state->img, pts, state); + return encode(env, &state->img, pts, force_keyframe, state); } -UNIFEX_TERM flush(UnifexEnv *env, State *state) { return encode(env, NULL, 0, state); } +UNIFEX_TERM flush(UnifexEnv *env, int force_keyframe, State *state) { + return encode(env, NULL, 0, force_keyframe, state); +} diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs index 4283c92..a44866b 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs +++ b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs @@ -15,11 +15,11 @@ spec create( ) :: {:ok :: label, state} | {:error :: label, reason :: atom} -spec encode_frame(payload, pts :: int64, state) :: +spec encode_frame(payload, pts :: int64, force_keyframe :: bool, state) :: {:ok :: label, frames :: [payload], timestamps :: [int64]} | {:error :: label, reason :: atom} -spec flush(state) :: +spec flush(force_keyframe :: bool, state) :: {:ok :: label, frames :: [payload], timestamps :: [int64]} | {:error :: label, reason :: atom} diff --git a/lib/membrane_vpx/encoder/vpx_encoder.ex b/lib/membrane_vpx/encoder/vpx_encoder.ex index cb5cf24..988e4b4 100644 --- a/lib/membrane_vpx/encoder/vpx_encoder.ex +++ b/lib/membrane_vpx/encoder/vpx_encoder.ex @@ -1,7 +1,7 @@ defmodule Membrane.VPx.Encoder do @moduledoc false - alias Membrane.{Buffer, DemandKeyframeEvent, RawVideo, VP8, VP9} + alias Membrane.{Buffer, ForceKeyframeEvent, RawVideo, VP8, VP9} alias Membrane.Element.CallbackContext alias Membrane.VPx.Encoder.Native @@ -14,13 +14,15 @@ defmodule Membrane.VPx.Encoder do codec: :vp8 | :vp9, codec_module: VP8 | VP9, encoding_deadline: non_neg_integer(), - encoder_ref: reference() | nil + encoder_ref: reference() | nil, + force_next_keyframe: boolean() } @enforce_keys [:codec, :codec_module, :encoding_deadline] defstruct @enforce_keys ++ [ - encoder_ref: nil + encoder_ref: nil, + force_next_keyframe: false ] end @@ -57,32 +59,36 @@ defmodule Membrane.VPx.Encoder do {flushed_buffers, encoder_ref} = maybe_recreate_encoder(ctx.pads.input.stream_format, stream_format, state) + force_next_keyframe = if flushed_buffers == [], do: state.force_next_keyframe, else: false + { [buffer: {:output, flushed_buffers}, stream_format: {:output, output_stream_format}], - %{state | encoder_ref: encoder_ref} + %{state | encoder_ref: encoder_ref, force_next_keyframe: force_next_keyframe} } end @spec handle_buffer(:input, Membrane.Buffer.t(), CallbackContext.t(), State.t()) :: callback_return() def handle_buffer(:input, %Buffer{payload: payload, pts: pts}, _ctx, state) do - {:ok, encoded_frames, timestamps} = Native.encode_frame(payload, pts, state.encoder_ref) + {:ok, encoded_frames, timestamps} = + Native.encode_frame(payload, pts, state.force_next_keyframe, state.encoder_ref) buffers = Enum.zip(encoded_frames, timestamps) |> Enum.map(fn {frame, frame_pts} -> %Buffer{payload: frame, pts: frame_pts} end) - {[buffer: {:output, buffers}], state} + {[buffer: {:output, buffers}], %{state | force_next_keyframe: false}} end - @spec handle_event(:output, DemandKeyframeEvent.t(), CallbackContext.t(), State.t()) :: + @spec handle_event(:output, ForceKeyframeEvent.t(), CallbackContext.t(), State.t()) :: callback_return() - def handle_event(:output, %DemandKeyframeEvent{}, _ctx, state) do + def handle_event(:output, %ForceKeyframeEvent{}, _ctx, state) do + {[], %{state | force_next_keyframe: true}} end @spec handle_end_of_stream(:input, CallbackContext.t(), State.t()) :: callback_return() def handle_end_of_stream(:input, _ctx, state) do - buffers = flush(state.encoder_ref) + buffers = flush(state.force_next_keyframe, state.encoder_ref) {[buffer: {:output, buffers}, end_of_stream: :output], state} end @@ -115,13 +121,13 @@ defmodule Membrane.VPx.Encoder do case state.encoder_ref do nil -> {[], new_encoder_ref} - old_encoder_ref -> {flush(old_encoder_ref), new_encoder_ref} + old_encoder_ref -> {flush(state.force_next_keyframe, old_encoder_ref), new_encoder_ref} end end - @spec flush(reference()) :: [Membrane.Buffer.t()] - defp flush(encoder_ref) do - {:ok, encoded_frames, timestamps} = Native.flush(encoder_ref) + @spec flush(boolean(), reference()) :: [Membrane.Buffer.t()] + defp flush(force_next_keyframe, encoder_ref) do + {:ok, encoded_frames, timestamps} = Native.flush(force_next_keyframe, encoder_ref) Enum.zip(encoded_frames, timestamps) |> Enum.map(fn {frame, frame_pts} -> %Buffer{payload: frame, pts: frame_pts} end) diff --git a/lib/membrane_vpx/demand_keyframe_event.ex b/lib/membrane_vpx/force_keyframe_event.ex similarity index 80% rename from lib/membrane_vpx/demand_keyframe_event.ex rename to lib/membrane_vpx/force_keyframe_event.ex index ee972c7..dcfc828 100644 --- a/lib/membrane_vpx/demand_keyframe_event.ex +++ b/lib/membrane_vpx/force_keyframe_event.ex @@ -1,4 +1,4 @@ -defmodule Membrane.DemandKeyframeEvent do +defmodule Membrane.ForceKeyframeEvent do @moduledoc """ Event that causes the next frame produced by the encoder to be a keyframe """ diff --git a/mix.lock b/mix.lock index 33e7098..5eeeba9 100644 --- a/mix.lock +++ b/mix.lock @@ -21,7 +21,7 @@ "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, "membrane_core": {:hex, :membrane_core, "1.1.0", "c3bbaa5af7c26a7c3748e573efe343c2104801e3463b9e491a607e82860334a4", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3209d7f7e86d736cb7caffbba16b075c571cebb9439ab939ed6119c50fb59a5"}, "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.1", "055a904823506e806e1e1a43643de2dfbe9baf3c1fe2f6f055d2e9b3710767dd", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0b209e17a7bafb8e281fe5d15b3760d9c6f8b3af628ed4589267ba01b7774d8f"}, - "membrane_ivf_plugin": {:git, "https://github.com/membraneframework/membrane_ivf_plugin.git", "e112040f22fe87dbe6142ee85c551abf202b426f", [branch: "fix-plugin"]}, + "membrane_ivf_plugin": {:hex, :membrane_ivf_plugin, "0.8.0", "0495a4fd34a1b9841d288b3a078d2b09c48020294a6452ce08e8954711648ac8", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}], "hexpm", "b17805a451f1066dab68c19577efad7819200c20970e3ba5f7d6fbbc751240e9"}, "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"}, "membrane_raw_video_format": {:hex, :membrane_raw_video_format, "0.4.1", "d7344499c2d80f236a7ef962b5490c651341a501052ee43dec56cf0319fa3936", [:mix], [], "hexpm", "9920b7d445b5357608a364fec5685acdfce85334c647f745045237a0d296c442"}, "membrane_raw_video_parser_plugin": {:hex, :membrane_raw_video_parser_plugin, "0.12.2", "7a1f11e122dfc1481654fd5a9ac43db80f7851ad569662cfca2e8a818403101c", [:mix], [{:bunch, "~> 1.3", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_raw_video_format, "~> 0.4.0", [hex: :membrane_raw_video_format, repo: "hexpm", optional: false]}], "hexpm", "c9254cc52c96ba0b575a65e4ab41f9218cef91ee5953cf6c1180835a21873907"}, From 81f5214f57a887cfebfd750e932daa06b91e4454 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Tue, 9 Jul 2024 13:41:54 +0200 Subject: [PATCH 03/17] Add tests --- c_src/membrane_vpx_plugin/vpx_encoder.c | 1 + lib/membrane_vpx/encoder/vp8_encoder.ex | 8 +- lib/membrane_vpx/encoder/vp9_encoder.ex | 8 +- lib/membrane_vpx/encoder/vpx_encoder.ex | 8 +- lib/membrane_vpx/force_keyframe_event.ex | 2 +- mix.exs | 2 + mix.lock | 2 + .../force_keyframe_test.exs | 80 +++++++++++++++++++ 8 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 test/membrane_vpx_plugin/force_keyframe_test.exs diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.c b/c_src/membrane_vpx_plugin/vpx_encoder.c index e4151a0..b1512c8 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.c +++ b/c_src/membrane_vpx_plugin/vpx_encoder.c @@ -1,4 +1,5 @@ #include "vpx_encoder.h" +#include // The following code is based on the simple_encoder example provided by libvpx // (https://github.com/webmproject/libvpx/blob/main/examples/simple_encoder.c) diff --git a/lib/membrane_vpx/encoder/vp8_encoder.ex b/lib/membrane_vpx/encoder/vp8_encoder.ex index aa0c27b..1a7e673 100644 --- a/lib/membrane_vpx/encoder/vp8_encoder.ex +++ b/lib/membrane_vpx/encoder/vp8_encoder.ex @@ -1,6 +1,9 @@ defmodule Membrane.VP8.Encoder do @moduledoc """ - Element that encodes a VP8 stream + Element that encodes a VP8 stream. + + This element can receive a `Membrane.VPx.ForceKeyframeEvent` on it's `:output` pad to force the + next frame to be a keyframe. """ use Membrane.Filter @@ -36,6 +39,9 @@ defmodule Membrane.VP8.Encoder do @impl true defdelegate handle_buffer(pad, buffer, ctx, state), to: VPx.Encoder + @impl true + defdelegate handle_event(pad, event, ctx, state), to: VPx.Encoder + @impl true defdelegate handle_end_of_stream(pad, ctx, state), to: VPx.Encoder end diff --git a/lib/membrane_vpx/encoder/vp9_encoder.ex b/lib/membrane_vpx/encoder/vp9_encoder.ex index 5e1c85d..e581056 100644 --- a/lib/membrane_vpx/encoder/vp9_encoder.ex +++ b/lib/membrane_vpx/encoder/vp9_encoder.ex @@ -1,6 +1,9 @@ defmodule Membrane.VP9.Encoder do @moduledoc """ - Element that encodes a VP9 stream + Element that encodes a VP9 stream. + + This element can receive a `Membrane.VPx.ForceKeyframeEvent` on it's `:output` pad to force the + next frame to be a keyframe. """ use Membrane.Filter @@ -36,6 +39,9 @@ defmodule Membrane.VP9.Encoder do @impl true defdelegate handle_buffer(pad, buffer, ctx, state), to: VPx.Encoder + @impl true + defdelegate handle_event(pad, event, ctx, state), to: VPx.Encoder + @impl true defdelegate handle_end_of_stream(pad, ctx, state), to: VPx.Encoder end diff --git a/lib/membrane_vpx/encoder/vpx_encoder.ex b/lib/membrane_vpx/encoder/vpx_encoder.ex index 988e4b4..8db255d 100644 --- a/lib/membrane_vpx/encoder/vpx_encoder.ex +++ b/lib/membrane_vpx/encoder/vpx_encoder.ex @@ -1,9 +1,10 @@ defmodule Membrane.VPx.Encoder do @moduledoc false - alias Membrane.{Buffer, ForceKeyframeEvent, RawVideo, VP8, VP9} + alias Membrane.{Buffer, RawVideo, VP8, VP9} alias Membrane.Element.CallbackContext alias Membrane.VPx.Encoder.Native + alias Membrane.VPx.ForceKeyframeEvent @default_encoding_deadline Membrane.Time.milliseconds(10) @@ -28,6 +29,11 @@ defmodule Membrane.VPx.Encoder do @type callback_return :: {[Membrane.Element.Action.t()], State.t()} + @spec dupa() :: :ok + def dupa() do + :ok + end + @spec handle_init(CallbackContext.t(), VP8.Encoder.t() | VP9.Encoder.t(), :vp8 | :vp9) :: callback_return() def handle_init(_ctx, opts, codec) do diff --git a/lib/membrane_vpx/force_keyframe_event.ex b/lib/membrane_vpx/force_keyframe_event.ex index dcfc828..bcbec2d 100644 --- a/lib/membrane_vpx/force_keyframe_event.ex +++ b/lib/membrane_vpx/force_keyframe_event.ex @@ -1,4 +1,4 @@ -defmodule Membrane.ForceKeyframeEvent do +defmodule Membrane.VPx.ForceKeyframeEvent do @moduledoc """ Event that causes the next frame produced by the encoder to be a keyframe """ diff --git a/mix.exs b/mix.exs index f984aad..4711c28 100644 --- a/mix.exs +++ b/mix.exs @@ -47,6 +47,8 @@ defmodule Membrane.VPx.Plugin.Mixfile do {:membrane_ivf_plugin, "~> 0.8.0", only: :test}, {:membrane_raw_video_parser_plugin, "~> 0.12.1", only: :test}, {:membrane_file_plugin, "~> 0.17.0", only: :test}, + {:membrane_fake_plugin, "~> 0.11.0", only: :test}, + {:membrane_realtimer_plugin, "~> 0.9.0", only: :test}, {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, {:dialyxir, ">= 0.0.0", only: :dev, runtime: false}, {:credo, ">= 0.0.0", only: :dev, runtime: false} diff --git a/mix.lock b/mix.lock index 5eeeba9..cee1fdd 100644 --- a/mix.lock +++ b/mix.lock @@ -20,11 +20,13 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, "membrane_core": {:hex, :membrane_core, "1.1.0", "c3bbaa5af7c26a7c3748e573efe343c2104801e3463b9e491a607e82860334a4", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3209d7f7e86d736cb7caffbba16b075c571cebb9439ab939ed6119c50fb59a5"}, + "membrane_fake_plugin": {:hex, :membrane_fake_plugin, "0.11.0", "3a2d26f15ad4940a4d44cee3354dff38fa9a39963e9b2dcb49802e150ff9a9dc", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "7c6b6a06eaa4e820d1e4836510ddb4bcb386c8918d0b37542a21caf6b87cbe72"}, "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.1", "055a904823506e806e1e1a43643de2dfbe9baf3c1fe2f6f055d2e9b3710767dd", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0b209e17a7bafb8e281fe5d15b3760d9c6f8b3af628ed4589267ba01b7774d8f"}, "membrane_ivf_plugin": {:hex, :membrane_ivf_plugin, "0.8.0", "0495a4fd34a1b9841d288b3a078d2b09c48020294a6452ce08e8954711648ac8", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}], "hexpm", "b17805a451f1066dab68c19577efad7819200c20970e3ba5f7d6fbbc751240e9"}, "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"}, "membrane_raw_video_format": {:hex, :membrane_raw_video_format, "0.4.1", "d7344499c2d80f236a7ef962b5490c651341a501052ee43dec56cf0319fa3936", [:mix], [], "hexpm", "9920b7d445b5357608a364fec5685acdfce85334c647f745045237a0d296c442"}, "membrane_raw_video_parser_plugin": {:hex, :membrane_raw_video_parser_plugin, "0.12.2", "7a1f11e122dfc1481654fd5a9ac43db80f7851ad569662cfca2e8a818403101c", [:mix], [{:bunch, "~> 1.3", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_raw_video_format, "~> 0.4.0", [hex: :membrane_raw_video_format, repo: "hexpm", optional: false]}], "hexpm", "c9254cc52c96ba0b575a65e4ab41f9218cef91ee5953cf6c1180835a21873907"}, + "membrane_realtimer_plugin": {:hex, :membrane_realtimer_plugin, "0.9.0", "27210d5e32a5e8bfd101c41e4d8c1876e873a52cc129ebfbee4d0ccbea1cbd21", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "b2e96d62135ee57ef9a5fdea94b3a9ab1198e5ea8ee248391b89c671125d1b51"}, "membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"}, "membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, diff --git a/test/membrane_vpx_plugin/force_keyframe_test.exs b/test/membrane_vpx_plugin/force_keyframe_test.exs new file mode 100644 index 0000000..43ef0c1 --- /dev/null +++ b/test/membrane_vpx_plugin/force_keyframe_test.exs @@ -0,0 +1,80 @@ +defmodule Membrane.VPx.ForceKeyframeEventTest do + use ExUnit.Case, async: true + + import Membrane.Testing.Assertions + import Membrane.ChildrenSpec + + defmodule KeyframeForcer do + use Membrane.Filter + alias Membrane.VPx.ForceKeyframeEvent + alias Membrane.{VP8, VP9} + + def_input_pad :input, + accepted_format: any_of(VP8, VP9) + + def_output_pad :output, + accepted_format: any_of(VP8, VP9) + + @impl true + def handle_init(_ctx, _opts) do + {[], %{frames_since_last_keyframe: 0}} + end + + @impl true + def handle_buffer(:input, buffer, _ctx, state) do + {maybe_event_action, frames_since_last_keyframe} = + if state.frames_since_last_keyframe == 10 do + {[event: {:input, %ForceKeyframeEvent{}}], 0} + else + {[], state.frames_since_last_keyframe + 1} + end + + { + maybe_event_action ++ [buffer: {:output, buffer}], + %{state | frames_since_last_keyframe: frames_since_last_keyframe} + } + end + end + + @fixtures_dir "test/fixtures" + + describe "Keyframes are forced correctly for" do + test "VP8 codec" do + perform_test( + "ref_vp8.raw", + %Membrane.VP8.Encoder{encoding_deadline: 0} + ) + end + + test "VP9 codec" do + perform_test( + "ref_vp9.raw", + %Membrane.VP9.Encoder{encoding_deadline: 0} + ) + end + end + + defp perform_test(input_file, encoder_struct) do + pid = + Membrane.Testing.Pipeline.start_link_supervised!( + spec: + child(:source, %Membrane.File.Source{ + location: Path.join(@fixtures_dir, input_file) + }) + |> child(:parser, %Membrane.RawVideo.Parser{ + pixel_format: :I420, + width: 1080, + height: 720, + framerate: {30, 1} + }) + |> child(:realtimer, Membrane.Realtimer) + |> child(:encoder, encoder_struct) + |> child(:keyframe_forcer, KeyframeForcer) + |> child(:sink, Membrane.Fake.Sink.Buffers) + ) + + assert_end_of_stream(pid, :sink, :input, 10_000) + + Membrane.Testing.Pipeline.terminate(pid) + end +end From f30d06a1b5e61fa2538cb3c2bfc2496cceaaeaa7 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 11 Jul 2024 07:43:35 +0200 Subject: [PATCH 04/17] Add is_keyframe field to metadata --- c_src/membrane_vpx_plugin/vpx_common.c | 10 -- c_src/membrane_vpx_plugin/vpx_common.h | 8 +- c_src/membrane_vpx_plugin/vpx_decoder.c | 4 +- c_src/membrane_vpx_plugin/vpx_encoder.c | 113 ++++++++++-------- .../membrane_vpx_plugin/vpx_encoder.spec.exs | 10 +- lib/membrane_vpx/encoder/vpx_encoder.ex | 48 ++++---- lib/membrane_vpx/force_keyframe_event.ex | 9 -- .../{ => decoder}/vpx_decoder_test.exs | 0 .../{force_keyframe_test.exs => encoder} | 15 ++- test/membrane_vpx_plugin/vpx_encoder_test.exs | 61 ---------- 10 files changed, 109 insertions(+), 169 deletions(-) delete mode 100644 lib/membrane_vpx/force_keyframe_event.ex rename test/membrane_vpx_plugin/{ => decoder}/vpx_decoder_test.exs (100%) rename test/membrane_vpx_plugin/{force_keyframe_test.exs => encoder} (82%) delete mode 100644 test/membrane_vpx_plugin/vpx_encoder_test.exs diff --git a/c_src/membrane_vpx_plugin/vpx_common.c b/c_src/membrane_vpx_plugin/vpx_common.c index d9efffe..3b6113d 100644 --- a/c_src/membrane_vpx_plugin/vpx_common.c +++ b/c_src/membrane_vpx_plugin/vpx_common.c @@ -73,13 +73,3 @@ void convert_between_image_and_raw_frame( } } } - -void free_payloads(UnifexPayload **payloads, unsigned int payloads_cnt) { - for (unsigned int i = 0; i < payloads_cnt; i++) { - if (payloads[i] != NULL) { - unifex_payload_release(payloads[i]); - unifex_free(payloads[i]); - } - } - unifex_free(payloads); -} diff --git a/c_src/membrane_vpx_plugin/vpx_common.h b/c_src/membrane_vpx_plugin/vpx_common.h index 0d492ea..c2df6e6 100644 --- a/c_src/membrane_vpx_plugin/vpx_common.h +++ b/c_src/membrane_vpx_plugin/vpx_common.h @@ -1,8 +1,8 @@ #pragma once +#include "unifex/payload.h" +#include "unifex/unifex.h" #include "vpx/vpx_codec.h" #include "vpx/vpx_image.h" -#include -#include typedef struct Dimensions { unsigned int width; @@ -21,8 +21,6 @@ typedef enum ConversionType { IMAGE_TO_RAW_FRAME, RAW_FRAME_TO_IMAGE } Conversio Dimensions get_plane_dimensions(const vpx_image_t *img, int plane); -void free_payloads(UnifexPayload **payloads, unsigned int payloads_cnt); - void convert_between_image_and_raw_frame( vpx_image_t *img, UnifexPayload *raw_frame, ConversionType conversion_type -); \ No newline at end of file +); diff --git a/c_src/membrane_vpx_plugin/vpx_decoder.c b/c_src/membrane_vpx_plugin/vpx_decoder.c index 06db615..7596698 100644 --- a/c_src/membrane_vpx_plugin/vpx_decoder.c +++ b/c_src/membrane_vpx_plugin/vpx_decoder.c @@ -52,6 +52,8 @@ void alloc_output_frame(UnifexEnv *env, const vpx_image_t *img, UnifexPayload ** unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, get_image_byte_size(img), *output_frame); } +void free_payloads(UnifexPayload **payloads, unsigned int payloads_cnt); + PixelFormat get_pixel_format_from_image(vpx_image_t *img) { switch (img->fmt) { case VPX_IMG_FMT_I422: @@ -74,7 +76,7 @@ UNIFEX_TERM decode_frame(UnifexEnv *env, UnifexPayload *frame, State *state) { vpx_image_t *img = NULL; PixelFormat pixel_format = PIXEL_FORMAT_I420; unsigned int frames_cnt = 0, allocated_frames = 1; - UnifexPayload **output_frames = unifex_alloc(allocated_frames * sizeof(UnifexPayload*)); + UnifexPayload **output_frames = unifex_alloc(allocated_frames * sizeof(UnifexPayload *)); if (vpx_codec_decode(&state->codec_context, frame->data, frame->size, NULL, 0)) { return result_error( diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.c b/c_src/membrane_vpx_plugin/vpx_encoder.c index b1512c8..cf2861b 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.c +++ b/c_src/membrane_vpx_plugin/vpx_encoder.c @@ -1,4 +1,6 @@ #include "vpx_encoder.h" +#include "membrane_vpx_plugin/_generated/nif/vpx_encoder.h" +#include "unifex/payload.h" #include // The following code is based on the simple_encoder example provided by libvpx @@ -27,9 +29,14 @@ vpx_img_fmt_t translate_pixel_format(PixelFormat pixel_format) { } } -UNIFEX_TERM create(UnifexEnv *env, Codec codec, unsigned int width, - unsigned int height, PixelFormat pixel_format, - unsigned int encoding_deadline) { +UNIFEX_TERM create( + UnifexEnv *env, + Codec codec, + unsigned int width, + unsigned int height, + PixelFormat pixel_format, + unsigned int encoding_deadline +) { UNIFEX_TERM result; State *state = unifex_alloc_state(env); vpx_codec_enc_cfg_t config; @@ -45,8 +52,9 @@ UNIFEX_TERM create(UnifexEnv *env, Codec codec, unsigned int width, state->encoding_deadline = encoding_deadline; if (vpx_codec_enc_config_default(state->codec_interface, &config, 0)) { - return result_error(env, "Failed to get default codec config", - create_result_error, NULL, state); + return result_error( + env, "Failed to get default codec config", create_result_error, NULL, state + ); } config.g_h = height; @@ -55,15 +63,13 @@ UNIFEX_TERM create(UnifexEnv *env, Codec codec, unsigned int width, config.g_timebase.den = 1000000000; // 1e9 config.g_error_resilient = 1; - if (vpx_codec_enc_init(&state->codec_context, state->codec_interface, &config, - 0)) { - return result_error(env, "Failed to initialize encoder", - create_result_error, NULL, state); + if (vpx_codec_enc_init(&state->codec_context, state->codec_interface, &config, 0)) { + return result_error(env, "Failed to initialize encoder", create_result_error, NULL, state); } - if (!vpx_img_alloc(&state->img, translate_pixel_format(pixel_format), width, - height, 1)) { - return result_error(env, "Failed to allocate image", create_result_error, - &state->codec_context, state); + if (!vpx_img_alloc(&state->img, translate_pixel_format(pixel_format), width, height, 1)) { + return result_error( + env, "Failed to allocate image", create_result_error, &state->codec_context, state + ); } result = create_result_ok(env, state); unifex_release_state(env, state); @@ -74,24 +80,33 @@ void get_image_from_raw_frame(vpx_image_t *img, UnifexPayload *raw_frame) { convert_between_image_and_raw_frame(img, raw_frame, RAW_FRAME_TO_IMAGE); } -void alloc_output_frame(UnifexEnv *env, const vpx_codec_cx_pkt_t *packet, - UnifexPayload **output_frame) { - *output_frame = unifex_alloc(sizeof(UnifexPayload)); - unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, packet->data.frame.sz, - *output_frame); +void alloc_output_frame( + UnifexEnv *env, const vpx_codec_cx_pkt_t *packet, encoded_frame *output_frame +) { + output_frame->payload = unifex_alloc(sizeof(UnifexPayload)); + unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, packet->data.frame.sz, output_frame->payload); } -UNIFEX_TERM encode(UnifexEnv *env, vpx_image_t *img, vpx_codec_pts_t pts, - int force_keyframe, State *state) { +void free_frames(encoded_frame *frames, unsigned int frames_cnt) { + for (unsigned int i = 0; i < frames_cnt; i++) { + UnifexPayload *payload = frames[i].payload; + if (payload != NULL) { + unifex_payload_release(payload); + unifex_free(payload); + } + } + unifex_free(frames); +} + +UNIFEX_TERM encode( + UnifexEnv *env, vpx_image_t *img, vpx_codec_pts_t pts, int force_keyframe, State *state +) { vpx_codec_iter_t iter = NULL; int flushing = (img == NULL), got_packets = 0; const vpx_codec_cx_pkt_t *packet = NULL; unsigned int frames_cnt = 0, allocated_frames = 1; - UnifexPayload **encoded_frames = - unifex_alloc(allocated_frames * sizeof(UnifexPayload *)); - vpx_codec_pts_t *encoded_frames_timestamps = - unifex_alloc(allocated_frames * sizeof(vpx_codec_pts_t)); + encoded_frame *encoded_frames = unifex_alloc(allocated_frames * sizeof(encoded_frame)); do { // Reasoning for the do-while and while loops comes from the description of @@ -103,59 +118,53 @@ UNIFEX_TERM encode(UnifexEnv *env, vpx_image_t *img, vpx_codec_pts_t pts, // any held buffers. Encoding is complete when vpx_codec_encode() is called // and vpx_codec_get_cx_data() returns no data. vpx_enc_frame_flags_t flags = force_keyframe ? VPX_EFLAG_FORCE_KF : 0; - if (vpx_codec_encode(&state->codec_context, img, pts, 1, flags, - state->encoding_deadline) != VPX_CODEC_OK) { + if (vpx_codec_encode(&state->codec_context, img, pts, 1, flags, state->encoding_deadline) != + VPX_CODEC_OK) { if (flushing) { - return result_error(env, "Encoding frame failed", flush_result_error, - &state->codec_context, NULL); + return result_error( + env, "Encoding frame failed", flush_result_error, &state->codec_context, NULL + ); } else { - return result_error(env, "Encoding frame failed", - encode_frame_result_error, &state->codec_context, - NULL); + return result_error( + env, "Encoding frame failed", encode_frame_result_error, &state->codec_context, NULL + ); } } force_keyframe = 0; got_packets = 0; - while ((packet = vpx_codec_get_cx_data(&state->codec_context, &iter)) != - NULL) { + while ((packet = vpx_codec_get_cx_data(&state->codec_context, &iter)) != NULL) { got_packets = 1; - if (packet->kind != VPX_CODEC_CX_FRAME_PKT) - continue; + if (packet->kind != VPX_CODEC_CX_FRAME_PKT) continue; if (frames_cnt >= allocated_frames) { allocated_frames *= 2; - encoded_frames = unifex_realloc( - encoded_frames, allocated_frames * sizeof(*encoded_frames)); - - encoded_frames_timestamps = unifex_realloc( - encoded_frames_timestamps, - allocated_frames * sizeof(*encoded_frames_timestamps)); + encoded_frames = unifex_realloc(encoded_frames, allocated_frames * sizeof(encoded_frame)); } alloc_output_frame(env, packet, &encoded_frames[frames_cnt]); - memcpy(encoded_frames[frames_cnt]->data, packet->data.frame.buf, - packet->data.frame.sz); - encoded_frames_timestamps[frames_cnt] = packet->data.frame.pts; + memcpy( + encoded_frames[frames_cnt].payload->data, packet->data.frame.buf, packet->data.frame.sz + ); + encoded_frames[frames_cnt].pts = packet->data.frame.pts; + encoded_frames[frames_cnt].is_keyframe = ((packet->data.frame.flags & VPX_FRAME_IS_KEY) != 0); frames_cnt++; } } while (got_packets && flushing); UNIFEX_TERM result; if (flushing) { - result = flush_result_ok(env, encoded_frames, frames_cnt, - encoded_frames_timestamps, frames_cnt); + result = flush_result_ok(env, encoded_frames, frames_cnt); } else { - result = encode_frame_result_ok(env, encoded_frames, frames_cnt, - encoded_frames_timestamps, frames_cnt); + result = encode_frame_result_ok(env, encoded_frames, frames_cnt); } - free_payloads(encoded_frames, frames_cnt); + free_frames(encoded_frames, frames_cnt); return result; } -UNIFEX_TERM encode_frame(UnifexEnv *env, UnifexPayload *raw_frame, - vpx_codec_pts_t pts, int force_keyframe, - State *state) { +UNIFEX_TERM encode_frame( + UnifexEnv *env, UnifexPayload *raw_frame, vpx_codec_pts_t pts, int force_keyframe, State *state +) { get_image_from_raw_frame(&state->img, raw_frame); return encode(env, &state->img, pts, force_keyframe, state); } diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs index a44866b..531a780 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs +++ b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs @@ -6,6 +6,12 @@ type codec :: :vp8 | :vp9 type pixel_format :: :I420 | :I422 | :I444 | :NV12 | :YV12 +type encoded_frame :: %EncodedFrame{ + payload: payload, + pts: int64, + is_keyframe: bool +} + spec create( codec, width :: unsigned, @@ -16,11 +22,11 @@ spec create( {:ok :: label, state} | {:error :: label, reason :: atom} spec encode_frame(payload, pts :: int64, force_keyframe :: bool, state) :: - {:ok :: label, frames :: [payload], timestamps :: [int64]} + {:ok :: label, frames :: [encoded_frame]} | {:error :: label, reason :: atom} spec flush(force_keyframe :: bool, state) :: - {:ok :: label, frames :: [payload], timestamps :: [int64]} + {:ok :: label, frames :: [encoded_frame]} | {:error :: label, reason :: atom} dirty :cpu, [:create, :encode_frame, :flush] diff --git a/lib/membrane_vpx/encoder/vpx_encoder.ex b/lib/membrane_vpx/encoder/vpx_encoder.ex index 8db255d..a694d4b 100644 --- a/lib/membrane_vpx/encoder/vpx_encoder.ex +++ b/lib/membrane_vpx/encoder/vpx_encoder.ex @@ -1,10 +1,9 @@ defmodule Membrane.VPx.Encoder do @moduledoc false - alias Membrane.{Buffer, RawVideo, VP8, VP9} + alias Membrane.{Buffer, KeyframeRequestEvent, RawVideo, VP8, VP9} alias Membrane.Element.CallbackContext alias Membrane.VPx.Encoder.Native - alias Membrane.VPx.ForceKeyframeEvent @default_encoding_deadline Membrane.Time.milliseconds(10) @@ -29,13 +28,9 @@ defmodule Membrane.VPx.Encoder do @type callback_return :: {[Membrane.Element.Action.t()], State.t()} - @spec dupa() :: :ok - def dupa() do - :ok - end - @spec handle_init(CallbackContext.t(), VP8.Encoder.t() | VP9.Encoder.t(), :vp8 | :vp9) :: callback_return() + def handle_init(_ctx, opts, codec) do state = %State{ codec: codec, @@ -76,25 +71,23 @@ defmodule Membrane.VPx.Encoder do @spec handle_buffer(:input, Membrane.Buffer.t(), CallbackContext.t(), State.t()) :: callback_return() def handle_buffer(:input, %Buffer{payload: payload, pts: pts}, _ctx, state) do - {:ok, encoded_frames, timestamps} = + {:ok, encoded_frames} = Native.encode_frame(payload, pts, state.force_next_keyframe, state.encoder_ref) - buffers = - Enum.zip(encoded_frames, timestamps) - |> Enum.map(fn {frame, frame_pts} -> %Buffer{payload: frame, pts: frame_pts} end) + buffers = get_buffers_from_frames(encoded_frames, state.codec) {[buffer: {:output, buffers}], %{state | force_next_keyframe: false}} end - @spec handle_event(:output, ForceKeyframeEvent.t(), CallbackContext.t(), State.t()) :: + @spec handle_event(:output, KeyframeRequestEvent.t(), CallbackContext.t(), State.t()) :: callback_return() - def handle_event(:output, %ForceKeyframeEvent{}, _ctx, state) do + def handle_event(:output, %KeyframeRequestEvent{}, _ctx, state) do {[], %{state | force_next_keyframe: true}} end @spec handle_end_of_stream(:input, CallbackContext.t(), State.t()) :: callback_return() def handle_end_of_stream(:input, _ctx, state) do - buffers = flush(state.force_next_keyframe, state.encoder_ref) + buffers = flush(state.force_next_keyframe, state.encoder_ref, state.codec) {[buffer: {:output, buffers}, end_of_stream: :output], state} end @@ -126,16 +119,29 @@ defmodule Membrane.VPx.Encoder do Native.create!(state.codec, width, height, pixel_format, encoding_deadline) case state.encoder_ref do - nil -> {[], new_encoder_ref} - old_encoder_ref -> {flush(state.force_next_keyframe, old_encoder_ref), new_encoder_ref} + nil -> + {[], new_encoder_ref} + + old_encoder_ref -> + {flush(state.force_next_keyframe, old_encoder_ref, state.codec), new_encoder_ref} end end - @spec flush(boolean(), reference()) :: [Membrane.Buffer.t()] - defp flush(force_next_keyframe, encoder_ref) do - {:ok, encoded_frames, timestamps} = Native.flush(force_next_keyframe, encoder_ref) + @spec flush(boolean(), reference(), :vp8 | :vp9) :: [Membrane.Buffer.t()] + defp flush(force_next_keyframe, encoder_ref, codec) do + {:ok, encoded_frames} = Native.flush(force_next_keyframe, encoder_ref) + + get_buffers_from_frames(encoded_frames, codec) + end - Enum.zip(encoded_frames, timestamps) - |> Enum.map(fn {frame, frame_pts} -> %Buffer{payload: frame, pts: frame_pts} end) + @spec get_buffers_from_frames([EncodedFrame.t()], :vp8 | :vp9) :: [Buffer.t()] + def get_buffers_from_frames(encoded_frames, codec) do + Enum.map(encoded_frames, fn %{payload: payload, pts: pts, is_keyframe: is_keyframe} -> + %Buffer{ + payload: payload, + pts: pts, + metadata: %{codec => %{is_keyframe: is_keyframe}} + } + end) end end diff --git a/lib/membrane_vpx/force_keyframe_event.ex b/lib/membrane_vpx/force_keyframe_event.ex deleted file mode 100644 index bcbec2d..0000000 --- a/lib/membrane_vpx/force_keyframe_event.ex +++ /dev/null @@ -1,9 +0,0 @@ -defmodule Membrane.VPx.ForceKeyframeEvent do - @moduledoc """ - Event that causes the next frame produced by the encoder to be a keyframe - """ - @derive Membrane.EventProtocol - - @type t :: %__MODULE__{} - defstruct [] -end diff --git a/test/membrane_vpx_plugin/vpx_decoder_test.exs b/test/membrane_vpx_plugin/decoder/vpx_decoder_test.exs similarity index 100% rename from test/membrane_vpx_plugin/vpx_decoder_test.exs rename to test/membrane_vpx_plugin/decoder/vpx_decoder_test.exs diff --git a/test/membrane_vpx_plugin/force_keyframe_test.exs b/test/membrane_vpx_plugin/encoder similarity index 82% rename from test/membrane_vpx_plugin/force_keyframe_test.exs rename to test/membrane_vpx_plugin/encoder index 43ef0c1..6055602 100644 --- a/test/membrane_vpx_plugin/force_keyframe_test.exs +++ b/test/membrane_vpx_plugin/encoder @@ -1,13 +1,12 @@ -defmodule Membrane.VPx.ForceKeyframeEventTest do +defmodule Membrane.VPx.KeyframesTest do use ExUnit.Case, async: true import Membrane.Testing.Assertions import Membrane.ChildrenSpec - defmodule KeyframeForcer do + defmodule KeyframeRequester do use Membrane.Filter - alias Membrane.VPx.ForceKeyframeEvent - alias Membrane.{VP8, VP9} + alias Membrane.{KeyframeRequestEvent, VP8, VP9} def_input_pad :input, accepted_format: any_of(VP8, VP9) @@ -23,8 +22,8 @@ defmodule Membrane.VPx.ForceKeyframeEventTest do @impl true def handle_buffer(:input, buffer, _ctx, state) do {maybe_event_action, frames_since_last_keyframe} = - if state.frames_since_last_keyframe == 10 do - {[event: {:input, %ForceKeyframeEvent{}}], 0} + if state.frames_since_last_keyframe == 4 do + {[event: {:input, %KeyframeRequestEvent{}}], 0} else {[], state.frames_since_last_keyframe + 1} end @@ -69,8 +68,8 @@ defmodule Membrane.VPx.ForceKeyframeEventTest do }) |> child(:realtimer, Membrane.Realtimer) |> child(:encoder, encoder_struct) - |> child(:keyframe_forcer, KeyframeForcer) - |> child(:sink, Membrane.Fake.Sink.Buffers) + |> child(:keyframe_forcer, KeyframeRequester) + |> child(:sink, Membrane.Testing.Sink) ) assert_end_of_stream(pid, :sink, :input, 10_000) diff --git a/test/membrane_vpx_plugin/vpx_encoder_test.exs b/test/membrane_vpx_plugin/vpx_encoder_test.exs deleted file mode 100644 index 1843eb1..0000000 --- a/test/membrane_vpx_plugin/vpx_encoder_test.exs +++ /dev/null @@ -1,61 +0,0 @@ -defmodule Membrane.VPx.EncoderTest do - use ExUnit.Case, async: true - - import Membrane.Testing.Assertions - import Membrane.ChildrenSpec - - @fixtures_dir "test/fixtures" - - describe "Encoder encodes correctly for" do - @describetag :tmp_dir - test "VP8 codec", %{tmp_dir: tmp_dir} do - perform_encoder_test( - tmp_dir, - "ref_vp8.raw", - "output_vp8.ivf", - "ref_vp8.ivf", - %Membrane.VP8.Encoder{encoding_deadline: 0} - ) - end - - test "VP9 codec", %{tmp_dir: tmp_dir} do - perform_encoder_test( - tmp_dir, - "ref_vp9.raw", - "output_vp9.ivf", - "ref_vp9.ivf", - %Membrane.VP9.Encoder{encoding_deadline: 0} - ) - end - end - - defp perform_encoder_test(tmp_dir, input_file, output_file, ref_file, encoder_struct) do - output_path = Path.join(tmp_dir, output_file) - ref_path = Path.join(@fixtures_dir, ref_file) - - pid = - Membrane.Testing.Pipeline.start_link_supervised!( - spec: - child(:source, %Membrane.File.Source{ - location: Path.join(@fixtures_dir, input_file) - }) - |> child(:parser, %Membrane.RawVideo.Parser{ - pixel_format: :I420, - width: 1080, - height: 720, - framerate: {30, 1} - }) - |> child(:encoder, encoder_struct) - |> child(:serializer, %Membrane.IVF.Serializer{ - timebase: {1, 30} - }) - |> child(:sink, %Membrane.File.Sink{location: output_path}) - ) - - assert_end_of_stream(pid, :sink, :input, 10_000) - - assert File.read!(ref_path) == File.read!(output_path) - - Membrane.Testing.Pipeline.terminate(pid) - end -end From 2b44b23834ffd327c427f81c8f79a3764a5e0d7a Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 11 Jul 2024 07:48:57 +0200 Subject: [PATCH 05/17] Add docs for metadata --- lib/membrane_vpx/encoder/vp8_encoder.ex | 6 ++++++ lib/membrane_vpx/encoder/vp9_encoder.ex | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/lib/membrane_vpx/encoder/vp8_encoder.ex b/lib/membrane_vpx/encoder/vp8_encoder.ex index 1a7e673..d9d0812 100644 --- a/lib/membrane_vpx/encoder/vp8_encoder.ex +++ b/lib/membrane_vpx/encoder/vp8_encoder.ex @@ -4,6 +4,12 @@ defmodule Membrane.VP8.Encoder do This element can receive a `Membrane.VPx.ForceKeyframeEvent` on it's `:output` pad to force the next frame to be a keyframe. + + Buffers produced by this element will have the following metadata that inform whether the buffer + contains a keyframe: + ```elixir + %{vp8: %{is_keyframe: is_keyframe :: boolean()}} + ``` """ use Membrane.Filter diff --git a/lib/membrane_vpx/encoder/vp9_encoder.ex b/lib/membrane_vpx/encoder/vp9_encoder.ex index e581056..dd20f8b 100644 --- a/lib/membrane_vpx/encoder/vp9_encoder.ex +++ b/lib/membrane_vpx/encoder/vp9_encoder.ex @@ -4,6 +4,12 @@ defmodule Membrane.VP9.Encoder do This element can receive a `Membrane.VPx.ForceKeyframeEvent` on it's `:output` pad to force the next frame to be a keyframe. + + Buffers produced by this element will have the following metadata that inform whether the buffer + contains a keyframe: + ```elixir + %{vp9: %{is_keyframe: is_keyframe :: boolean()}} + ``` """ use Membrane.Filter From ff02b12d38f942b6aadf407151d0ebef57491438 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 11 Jul 2024 08:43:46 +0200 Subject: [PATCH 06/17] FIx encoder tests --- .../{encoder => encoder/keyframe_test.exs} | 0 .../encoder/vpx_encoder_test.exs | 61 +++++++++++++++++++ 2 files changed, 61 insertions(+) rename test/membrane_vpx_plugin/{encoder => encoder/keyframe_test.exs} (100%) create mode 100644 test/membrane_vpx_plugin/encoder/vpx_encoder_test.exs diff --git a/test/membrane_vpx_plugin/encoder b/test/membrane_vpx_plugin/encoder/keyframe_test.exs similarity index 100% rename from test/membrane_vpx_plugin/encoder rename to test/membrane_vpx_plugin/encoder/keyframe_test.exs diff --git a/test/membrane_vpx_plugin/encoder/vpx_encoder_test.exs b/test/membrane_vpx_plugin/encoder/vpx_encoder_test.exs new file mode 100644 index 0000000..1843eb1 --- /dev/null +++ b/test/membrane_vpx_plugin/encoder/vpx_encoder_test.exs @@ -0,0 +1,61 @@ +defmodule Membrane.VPx.EncoderTest do + use ExUnit.Case, async: true + + import Membrane.Testing.Assertions + import Membrane.ChildrenSpec + + @fixtures_dir "test/fixtures" + + describe "Encoder encodes correctly for" do + @describetag :tmp_dir + test "VP8 codec", %{tmp_dir: tmp_dir} do + perform_encoder_test( + tmp_dir, + "ref_vp8.raw", + "output_vp8.ivf", + "ref_vp8.ivf", + %Membrane.VP8.Encoder{encoding_deadline: 0} + ) + end + + test "VP9 codec", %{tmp_dir: tmp_dir} do + perform_encoder_test( + tmp_dir, + "ref_vp9.raw", + "output_vp9.ivf", + "ref_vp9.ivf", + %Membrane.VP9.Encoder{encoding_deadline: 0} + ) + end + end + + defp perform_encoder_test(tmp_dir, input_file, output_file, ref_file, encoder_struct) do + output_path = Path.join(tmp_dir, output_file) + ref_path = Path.join(@fixtures_dir, ref_file) + + pid = + Membrane.Testing.Pipeline.start_link_supervised!( + spec: + child(:source, %Membrane.File.Source{ + location: Path.join(@fixtures_dir, input_file) + }) + |> child(:parser, %Membrane.RawVideo.Parser{ + pixel_format: :I420, + width: 1080, + height: 720, + framerate: {30, 1} + }) + |> child(:encoder, encoder_struct) + |> child(:serializer, %Membrane.IVF.Serializer{ + timebase: {1, 30} + }) + |> child(:sink, %Membrane.File.Sink{location: output_path}) + ) + + assert_end_of_stream(pid, :sink, :input, 10_000) + + assert File.read!(ref_path) == File.read!(output_path) + + Membrane.Testing.Pipeline.terminate(pid) + end +end From 35778e8736bae5cee00bf571977ca432cc4f0013 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 11 Jul 2024 08:45:25 +0200 Subject: [PATCH 07/17] Fix decoder --- c_src/membrane_vpx_plugin/vpx_decoder.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/c_src/membrane_vpx_plugin/vpx_decoder.c b/c_src/membrane_vpx_plugin/vpx_decoder.c index 7596698..78858d6 100644 --- a/c_src/membrane_vpx_plugin/vpx_decoder.c +++ b/c_src/membrane_vpx_plugin/vpx_decoder.c @@ -52,7 +52,15 @@ void alloc_output_frame(UnifexEnv *env, const vpx_image_t *img, UnifexPayload ** unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, get_image_byte_size(img), *output_frame); } -void free_payloads(UnifexPayload **payloads, unsigned int payloads_cnt); +void free_payloads(UnifexPayload **payloads, unsigned int payloads_cnt) { + for (unsigned int i = 0; i < payloads_cnt; i++) { + if (payloads[i] != NULL) { + unifex_payload_release(payloads[i]); + unifex_free(payloads[i]); + } + } + unifex_free(payloads); +} PixelFormat get_pixel_format_from_image(vpx_image_t *img) { switch (img->fmt) { From 79618aea857eb4d2197b5d9901dd47fb348c7b6b Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 11 Jul 2024 09:12:52 +0200 Subject: [PATCH 08/17] Reformat --- c_src/membrane_vpx_plugin/vpx_encoder.spec.exs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs index 531a780..cde0ef9 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs +++ b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs @@ -7,10 +7,10 @@ type codec :: :vp8 | :vp9 type pixel_format :: :I420 | :I422 | :I444 | :NV12 | :YV12 type encoded_frame :: %EncodedFrame{ - payload: payload, - pts: int64, - is_keyframe: bool -} + payload: payload, + pts: int64, + is_keyframe: bool + } spec create( codec, From 413d2f1a90ad0337f905d206272f9e63ac8a10b8 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 11 Jul 2024 09:35:22 +0200 Subject: [PATCH 09/17] Rename keyframes_test --- .../encoder/{keyframe_test.exs => keyframes_test.exs} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename test/membrane_vpx_plugin/encoder/{keyframe_test.exs => keyframes_test.exs} (95%) diff --git a/test/membrane_vpx_plugin/encoder/keyframe_test.exs b/test/membrane_vpx_plugin/encoder/keyframes_test.exs similarity index 95% rename from test/membrane_vpx_plugin/encoder/keyframe_test.exs rename to test/membrane_vpx_plugin/encoder/keyframes_test.exs index 6055602..4681806 100644 --- a/test/membrane_vpx_plugin/encoder/keyframe_test.exs +++ b/test/membrane_vpx_plugin/encoder/keyframes_test.exs @@ -41,14 +41,14 @@ defmodule Membrane.VPx.KeyframesTest do test "VP8 codec" do perform_test( "ref_vp8.raw", - %Membrane.VP8.Encoder{encoding_deadline: 0} + %Membrane.VP8.Encoder{encoding_deadline: 1} ) end test "VP9 codec" do perform_test( "ref_vp9.raw", - %Membrane.VP9.Encoder{encoding_deadline: 0} + %Membrane.VP9.Encoder{encoding_deadline: 1} ) end end From f01c389ae54c83e6a846dc198560bb3cebc5237f Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 13:06:58 +0200 Subject: [PATCH 10/17] Fix moduledocs --- lib/membrane_vpx/encoder/vp8_encoder.ex | 2 +- lib/membrane_vpx/encoder/vp9_encoder.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/membrane_vpx/encoder/vp8_encoder.ex b/lib/membrane_vpx/encoder/vp8_encoder.ex index d9d0812..25b1659 100644 --- a/lib/membrane_vpx/encoder/vp8_encoder.ex +++ b/lib/membrane_vpx/encoder/vp8_encoder.ex @@ -2,7 +2,7 @@ defmodule Membrane.VP8.Encoder do @moduledoc """ Element that encodes a VP8 stream. - This element can receive a `Membrane.VPx.ForceKeyframeEvent` on it's `:output` pad to force the + This element can receive a `Membrane.KeyframeRequestEvent` on it's `:output` pad to force the next frame to be a keyframe. Buffers produced by this element will have the following metadata that inform whether the buffer diff --git a/lib/membrane_vpx/encoder/vp9_encoder.ex b/lib/membrane_vpx/encoder/vp9_encoder.ex index dd20f8b..14e2f7b 100644 --- a/lib/membrane_vpx/encoder/vp9_encoder.ex +++ b/lib/membrane_vpx/encoder/vp9_encoder.ex @@ -2,7 +2,7 @@ defmodule Membrane.VP9.Encoder do @moduledoc """ Element that encodes a VP9 stream. - This element can receive a `Membrane.VPx.ForceKeyframeEvent` on it's `:output` pad to force the + This element can receive a `Membrane.KeyframeRequestEvent` on it's `:output` pad to force the next frame to be a keyframe. Buffers produced by this element will have the following metadata that inform whether the buffer From a5396a4ec2b844e963e02a0f503793510791b5c7 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 13:07:20 +0200 Subject: [PATCH 11/17] Update deps --- mix.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mix.lock b/mix.lock index cee1fdd..00625cb 100644 --- a/mix.lock +++ b/mix.lock @@ -1,27 +1,27 @@ %{ "bunch": {:hex, :bunch, "1.6.1", "5393d827a64d5f846092703441ea50e65bc09f37fd8e320878f13e63d410aec7", [:mix], [], "hexpm", "286cc3add551628b30605efbe2fca4e38cc1bea89bcd0a1a7226920b3364fe4a"}, "bunch_native": {:hex, :bunch_native, "0.5.0", "8ac1536789a597599c10b652e0b526d8833348c19e4739a0759a2bedfd924e63", [:mix], [{:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "24190c760e32b23b36edeb2dc4852515c7c5b3b8675b1a864e0715bdd1c8f80d"}, - "bundlex": {:hex, :bundlex, "1.5.1", "a85890a9d0a70366afa538c8589a4ba75e1319d32a771e1f5f3b7566beea9c26", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, "~> 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "aae447d63230fe1f3b788c429ac02bc696f30163d0f23f52fcfe6ed38372c7ea"}, + "bundlex": {:hex, :bundlex, "1.5.3", "35d01e5bc0679510dd9a327936ffb518f63f47175c26a35e708cc29eaec0890b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, ">= 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "debd0eac151b404f6216fc60222761dff049bf26f7d24d066c365317650cd118"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, + "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, - "ex_doc": {:hex, :ex_doc, "0.34.1", "9751a0419bc15bc7580c73fde506b17b07f6402a1e5243be9e0f05a68c723368", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d441f1a86a235f59088978eff870de2e815e290e44a8bd976fe5d64470a4c9d2"}, + "ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"}, "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, - "hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, + "jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"}, "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, - "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, - "membrane_core": {:hex, :membrane_core, "1.1.0", "c3bbaa5af7c26a7c3748e573efe343c2104801e3463b9e491a607e82860334a4", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3209d7f7e86d736cb7caffbba16b075c571cebb9439ab939ed6119c50fb59a5"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, + "membrane_core": {:hex, :membrane_core, "1.1.1", "4dcff6e9f3b2ecd4f437c20e201e53957731772c0f15b3005062c41f7f58f500", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3802f3fc071505c59d48792487d9927e803d4edb4039710ffa52cdb60bb0aecc"}, "membrane_fake_plugin": {:hex, :membrane_fake_plugin, "0.11.0", "3a2d26f15ad4940a4d44cee3354dff38fa9a39963e9b2dcb49802e150ff9a9dc", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "7c6b6a06eaa4e820d1e4836510ddb4bcb386c8918d0b37542a21caf6b87cbe72"}, - "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.1", "055a904823506e806e1e1a43643de2dfbe9baf3c1fe2f6f055d2e9b3710767dd", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0b209e17a7bafb8e281fe5d15b3760d9c6f8b3af628ed4589267ba01b7774d8f"}, + "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.2", "650e134c2345d946f930082fac8bac9f5aba785a7817d38a9a9da41ffc56fa92", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "df50c6040004cd7b901cf057bd7e99c875bbbd6ae574efc93b2c753c96f43b9d"}, "membrane_ivf_plugin": {:hex, :membrane_ivf_plugin, "0.8.0", "0495a4fd34a1b9841d288b3a078d2b09c48020294a6452ce08e8954711648ac8", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}], "hexpm", "b17805a451f1066dab68c19577efad7819200c20970e3ba5f7d6fbbc751240e9"}, "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"}, "membrane_raw_video_format": {:hex, :membrane_raw_video_format, "0.4.1", "d7344499c2d80f236a7ef962b5490c651341a501052ee43dec56cf0319fa3936", [:mix], [], "hexpm", "9920b7d445b5357608a364fec5685acdfce85334c647f745045237a0d296c442"}, @@ -29,8 +29,8 @@ "membrane_realtimer_plugin": {:hex, :membrane_realtimer_plugin, "0.9.0", "27210d5e32a5e8bfd101c41e4d8c1876e873a52cc129ebfbee4d0ccbea1cbd21", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "b2e96d62135ee57ef9a5fdea94b3a9ab1198e5ea8ee248391b89c671125d1b51"}, "membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"}, "membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"}, - "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, - "mint": {:hex, :mint, "1.6.1", "065e8a5bc9bbd46a41099dfea3e0656436c5cbcb6e741c80bd2bad5cd872446f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4fc518dcc191d02f433393a72a7ba3f6f94b101d094cb6bf532ea54c89423780"}, + "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, + "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, @@ -38,7 +38,7 @@ "numbers": {:hex, :numbers, "5.2.4", "f123d5bb7f6acc366f8f445e10a32bd403c8469bdbce8ce049e1f0972b607080", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "eeccf5c61d5f4922198395bf87a465b6f980b8b862dd22d28198c5e6fab38582"}, "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, "ratio": {:hex, :ratio, "4.0.1", "3044166f2fc6890aa53d3aef0c336f84b2bebb889dc57d5f95cc540daa1912f8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "c60cbb3ccdff9ffa56e7d6d1654b5c70d9f90f4d753ab3a43a6bf40855b881ce"}, - "req": {:hex, :req, "0.4.14", "103de133a076a31044e5458e0f850d5681eef23dfabf3ea34af63212e3b902e2", [:mix], [{:aws_signature, "~> 0.3.2", [hex: :aws_signature, repo: "hexpm", optional: true]}, {:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:nimble_ownership, "~> 0.2.0 or ~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2ddd3d33f9ab714ced8d3c15fd03db40c14dbf129003c4a3eb80fac2cc0b1b08"}, + "req": {:hex, :req, "0.5.4", "e375e4812adf83ffcf787871d7a124d873e983e3b77466e6608b973582f7f837", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a17998ffe2ef54f79bfdd782ef9f4cbf987d93851e89444cbc466a6a25eee494"}, "shmex": {:hex, :shmex, "0.5.1", "81dd209093416bf6608e66882cb7e676089307448a1afd4fc906c1f7e5b94cf4", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "c29f8286891252f64c4e1dac40b217d960f7d58def597c4e606ff8fbe71ceb80"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "unifex": {:hex, :unifex, "1.2.0", "90d1ec5e6d788350e07e474f7bd8b0ee866d6606beb9ca4e20dbb26328712a84", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.5.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "7a8395aabc3ba6cff04bbe5b995de7f899a38eb57f189e49927d6b8b6ccb6883"}, From f9f13f081bfad7a8c8837c95fd8fae1dbb6682c3 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 13:26:48 +0200 Subject: [PATCH 12/17] Revert "Update deps" This reverts commit a5396a4ec2b844e963e02a0f503793510791b5c7. --- mix.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mix.lock b/mix.lock index 00625cb..cee1fdd 100644 --- a/mix.lock +++ b/mix.lock @@ -1,27 +1,27 @@ %{ "bunch": {:hex, :bunch, "1.6.1", "5393d827a64d5f846092703441ea50e65bc09f37fd8e320878f13e63d410aec7", [:mix], [], "hexpm", "286cc3add551628b30605efbe2fca4e38cc1bea89bcd0a1a7226920b3364fe4a"}, "bunch_native": {:hex, :bunch_native, "0.5.0", "8ac1536789a597599c10b652e0b526d8833348c19e4739a0759a2bedfd924e63", [:mix], [{:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "24190c760e32b23b36edeb2dc4852515c7c5b3b8675b1a864e0715bdd1c8f80d"}, - "bundlex": {:hex, :bundlex, "1.5.3", "35d01e5bc0679510dd9a327936ffb518f63f47175c26a35e708cc29eaec0890b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, ">= 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "debd0eac151b404f6216fc60222761dff049bf26f7d24d066c365317650cd118"}, + "bundlex": {:hex, :bundlex, "1.5.1", "a85890a9d0a70366afa538c8589a4ba75e1319d32a771e1f5f3b7566beea9c26", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, "~> 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "aae447d63230fe1f3b788c429ac02bc696f30163d0f23f52fcfe6ed38372c7ea"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, + "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, - "ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"}, + "ex_doc": {:hex, :ex_doc, "0.34.1", "9751a0419bc15bc7580c73fde506b17b07f6402a1e5243be9e0f05a68c723368", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d441f1a86a235f59088978eff870de2e815e290e44a8bd976fe5d64470a4c9d2"}, "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, - "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, - "jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"}, + "hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, - "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, - "membrane_core": {:hex, :membrane_core, "1.1.1", "4dcff6e9f3b2ecd4f437c20e201e53957731772c0f15b3005062c41f7f58f500", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3802f3fc071505c59d48792487d9927e803d4edb4039710ffa52cdb60bb0aecc"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, + "membrane_core": {:hex, :membrane_core, "1.1.0", "c3bbaa5af7c26a7c3748e573efe343c2104801e3463b9e491a607e82860334a4", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3209d7f7e86d736cb7caffbba16b075c571cebb9439ab939ed6119c50fb59a5"}, "membrane_fake_plugin": {:hex, :membrane_fake_plugin, "0.11.0", "3a2d26f15ad4940a4d44cee3354dff38fa9a39963e9b2dcb49802e150ff9a9dc", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "7c6b6a06eaa4e820d1e4836510ddb4bcb386c8918d0b37542a21caf6b87cbe72"}, - "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.2", "650e134c2345d946f930082fac8bac9f5aba785a7817d38a9a9da41ffc56fa92", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "df50c6040004cd7b901cf057bd7e99c875bbbd6ae574efc93b2c753c96f43b9d"}, + "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.1", "055a904823506e806e1e1a43643de2dfbe9baf3c1fe2f6f055d2e9b3710767dd", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0b209e17a7bafb8e281fe5d15b3760d9c6f8b3af628ed4589267ba01b7774d8f"}, "membrane_ivf_plugin": {:hex, :membrane_ivf_plugin, "0.8.0", "0495a4fd34a1b9841d288b3a078d2b09c48020294a6452ce08e8954711648ac8", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}], "hexpm", "b17805a451f1066dab68c19577efad7819200c20970e3ba5f7d6fbbc751240e9"}, "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"}, "membrane_raw_video_format": {:hex, :membrane_raw_video_format, "0.4.1", "d7344499c2d80f236a7ef962b5490c651341a501052ee43dec56cf0319fa3936", [:mix], [], "hexpm", "9920b7d445b5357608a364fec5685acdfce85334c647f745045237a0d296c442"}, @@ -29,8 +29,8 @@ "membrane_realtimer_plugin": {:hex, :membrane_realtimer_plugin, "0.9.0", "27210d5e32a5e8bfd101c41e4d8c1876e873a52cc129ebfbee4d0ccbea1cbd21", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "b2e96d62135ee57ef9a5fdea94b3a9ab1198e5ea8ee248391b89c671125d1b51"}, "membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"}, "membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"}, - "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, - "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, + "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, + "mint": {:hex, :mint, "1.6.1", "065e8a5bc9bbd46a41099dfea3e0656436c5cbcb6e741c80bd2bad5cd872446f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4fc518dcc191d02f433393a72a7ba3f6f94b101d094cb6bf532ea54c89423780"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, @@ -38,7 +38,7 @@ "numbers": {:hex, :numbers, "5.2.4", "f123d5bb7f6acc366f8f445e10a32bd403c8469bdbce8ce049e1f0972b607080", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "eeccf5c61d5f4922198395bf87a465b6f980b8b862dd22d28198c5e6fab38582"}, "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, "ratio": {:hex, :ratio, "4.0.1", "3044166f2fc6890aa53d3aef0c336f84b2bebb889dc57d5f95cc540daa1912f8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "c60cbb3ccdff9ffa56e7d6d1654b5c70d9f90f4d753ab3a43a6bf40855b881ce"}, - "req": {:hex, :req, "0.5.4", "e375e4812adf83ffcf787871d7a124d873e983e3b77466e6608b973582f7f837", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a17998ffe2ef54f79bfdd782ef9f4cbf987d93851e89444cbc466a6a25eee494"}, + "req": {:hex, :req, "0.4.14", "103de133a076a31044e5458e0f850d5681eef23dfabf3ea34af63212e3b902e2", [:mix], [{:aws_signature, "~> 0.3.2", [hex: :aws_signature, repo: "hexpm", optional: true]}, {:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:nimble_ownership, "~> 0.2.0 or ~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2ddd3d33f9ab714ced8d3c15fd03db40c14dbf129003c4a3eb80fac2cc0b1b08"}, "shmex": {:hex, :shmex, "0.5.1", "81dd209093416bf6608e66882cb7e676089307448a1afd4fc906c1f7e5b94cf4", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "c29f8286891252f64c4e1dac40b217d960f7d58def597c4e606ff8fbe71ceb80"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "unifex": {:hex, :unifex, "1.2.0", "90d1ec5e6d788350e07e474f7bd8b0ee866d6606beb9ca4e20dbb26328712a84", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.5.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "7a8395aabc3ba6cff04bbe5b995de7f899a38eb57f189e49927d6b8b6ccb6883"}, From 76e49a630c81a58f356e2b839db516f9a6ce607b Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 13:33:09 +0200 Subject: [PATCH 13/17] Update bundlex --- mix.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mix.lock b/mix.lock index cee1fdd..47f12e0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,9 +1,9 @@ %{ "bunch": {:hex, :bunch, "1.6.1", "5393d827a64d5f846092703441ea50e65bc09f37fd8e320878f13e63d410aec7", [:mix], [], "hexpm", "286cc3add551628b30605efbe2fca4e38cc1bea89bcd0a1a7226920b3364fe4a"}, "bunch_native": {:hex, :bunch_native, "0.5.0", "8ac1536789a597599c10b652e0b526d8833348c19e4739a0759a2bedfd924e63", [:mix], [{:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "24190c760e32b23b36edeb2dc4852515c7c5b3b8675b1a864e0715bdd1c8f80d"}, - "bundlex": {:hex, :bundlex, "1.5.1", "a85890a9d0a70366afa538c8589a4ba75e1319d32a771e1f5f3b7566beea9c26", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, "~> 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "aae447d63230fe1f3b788c429ac02bc696f30163d0f23f52fcfe6ed38372c7ea"}, + "bundlex": {:hex, :bundlex, "1.5.3", "35d01e5bc0679510dd9a327936ffb518f63f47175c26a35e708cc29eaec0890b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, ">= 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "debd0eac151b404f6216fc60222761dff049bf26f7d24d066c365317650cd118"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, + "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, @@ -13,8 +13,8 @@ "ex_doc": {:hex, :ex_doc, "0.34.1", "9751a0419bc15bc7580c73fde506b17b07f6402a1e5243be9e0f05a68c723368", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d441f1a86a235f59088978eff870de2e815e290e44a8bd976fe5d64470a4c9d2"}, "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, - "hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, + "jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"}, "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, @@ -29,8 +29,8 @@ "membrane_realtimer_plugin": {:hex, :membrane_realtimer_plugin, "0.9.0", "27210d5e32a5e8bfd101c41e4d8c1876e873a52cc129ebfbee4d0ccbea1cbd21", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "b2e96d62135ee57ef9a5fdea94b3a9ab1198e5ea8ee248391b89c671125d1b51"}, "membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"}, "membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"}, - "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, - "mint": {:hex, :mint, "1.6.1", "065e8a5bc9bbd46a41099dfea3e0656436c5cbcb6e741c80bd2bad5cd872446f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4fc518dcc191d02f433393a72a7ba3f6f94b101d094cb6bf532ea54c89423780"}, + "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, + "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, @@ -38,7 +38,7 @@ "numbers": {:hex, :numbers, "5.2.4", "f123d5bb7f6acc366f8f445e10a32bd403c8469bdbce8ce049e1f0972b607080", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "eeccf5c61d5f4922198395bf87a465b6f980b8b862dd22d28198c5e6fab38582"}, "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, "ratio": {:hex, :ratio, "4.0.1", "3044166f2fc6890aa53d3aef0c336f84b2bebb889dc57d5f95cc540daa1912f8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "c60cbb3ccdff9ffa56e7d6d1654b5c70d9f90f4d753ab3a43a6bf40855b881ce"}, - "req": {:hex, :req, "0.4.14", "103de133a076a31044e5458e0f850d5681eef23dfabf3ea34af63212e3b902e2", [:mix], [{:aws_signature, "~> 0.3.2", [hex: :aws_signature, repo: "hexpm", optional: true]}, {:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:nimble_ownership, "~> 0.2.0 or ~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2ddd3d33f9ab714ced8d3c15fd03db40c14dbf129003c4a3eb80fac2cc0b1b08"}, + "req": {:hex, :req, "0.5.4", "e375e4812adf83ffcf787871d7a124d873e983e3b77466e6608b973582f7f837", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a17998ffe2ef54f79bfdd782ef9f4cbf987d93851e89444cbc466a6a25eee494"}, "shmex": {:hex, :shmex, "0.5.1", "81dd209093416bf6608e66882cb7e676089307448a1afd4fc906c1f7e5b94cf4", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "c29f8286891252f64c4e1dac40b217d960f7d58def597c4e606ff8fbe71ceb80"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "unifex": {:hex, :unifex, "1.2.0", "90d1ec5e6d788350e07e474f7bd8b0ee866d6606beb9ca4e20dbb26328712a84", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.5.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "7a8395aabc3ba6cff04bbe5b995de7f899a38eb57f189e49927d6b8b6ccb6883"}, From 5c83bc79425eb4a9a6c3bcd56e5cb1225185ad7a Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 13:36:21 +0200 Subject: [PATCH 14/17] Update circleci cache version --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index c077fb4..f00f4dd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,12 +10,15 @@ workflows: filters: &filters tags: only: /v.*/ + cache-version: 2 - elixir/test: filters: <<: *filters + cache-version: 2 - elixir/lint: filters: <<: *filters + cache-version: 2 - elixir/hex_publish: requires: - elixir/build_test @@ -28,3 +31,4 @@ workflows: ignore: /.*/ tags: only: /v.*/ + cache-version: 2 From b1dd74b807b6874044d681bdfcc2370b662e77ed Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 13:37:58 +0200 Subject: [PATCH 15/17] Unlock unused deps --- mix.lock | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mix.lock b/mix.lock index 47f12e0..8b2fb1b 100644 --- a/mix.lock +++ b/mix.lock @@ -7,10 +7,10 @@ "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, - "ex_doc": {:hex, :ex_doc, "0.34.1", "9751a0419bc15bc7580c73fde506b17b07f6402a1e5243be9e0f05a68c723368", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d441f1a86a235f59088978eff870de2e815e290e44a8bd976fe5d64470a4c9d2"}, + "ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"}, "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, @@ -18,10 +18,10 @@ "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, - "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, - "membrane_core": {:hex, :membrane_core, "1.1.0", "c3bbaa5af7c26a7c3748e573efe343c2104801e3463b9e491a607e82860334a4", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3209d7f7e86d736cb7caffbba16b075c571cebb9439ab939ed6119c50fb59a5"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, + "membrane_core": {:hex, :membrane_core, "1.1.1", "4dcff6e9f3b2ecd4f437c20e201e53957731772c0f15b3005062c41f7f58f500", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3802f3fc071505c59d48792487d9927e803d4edb4039710ffa52cdb60bb0aecc"}, "membrane_fake_plugin": {:hex, :membrane_fake_plugin, "0.11.0", "3a2d26f15ad4940a4d44cee3354dff38fa9a39963e9b2dcb49802e150ff9a9dc", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "7c6b6a06eaa4e820d1e4836510ddb4bcb386c8918d0b37542a21caf6b87cbe72"}, - "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.1", "055a904823506e806e1e1a43643de2dfbe9baf3c1fe2f6f055d2e9b3710767dd", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0b209e17a7bafb8e281fe5d15b3760d9c6f8b3af628ed4589267ba01b7774d8f"}, + "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.2", "650e134c2345d946f930082fac8bac9f5aba785a7817d38a9a9da41ffc56fa92", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "df50c6040004cd7b901cf057bd7e99c875bbbd6ae574efc93b2c753c96f43b9d"}, "membrane_ivf_plugin": {:hex, :membrane_ivf_plugin, "0.8.0", "0495a4fd34a1b9841d288b3a078d2b09c48020294a6452ce08e8954711648ac8", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}], "hexpm", "b17805a451f1066dab68c19577efad7819200c20970e3ba5f7d6fbbc751240e9"}, "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"}, "membrane_raw_video_format": {:hex, :membrane_raw_video_format, "0.4.1", "d7344499c2d80f236a7ef962b5490c651341a501052ee43dec56cf0319fa3936", [:mix], [], "hexpm", "9920b7d445b5357608a364fec5685acdfce85334c647f745045237a0d296c442"}, @@ -32,7 +32,6 @@ "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, - "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "numbers": {:hex, :numbers, "5.2.4", "f123d5bb7f6acc366f8f445e10a32bd403c8469bdbce8ce049e1f0972b607080", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "eeccf5c61d5f4922198395bf87a465b6f980b8b862dd22d28198c5e6fab38582"}, From 074cd277bb3899397b5733c01e9e09e3d8a1cde6 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Thu, 25 Jul 2024 14:22:36 +0200 Subject: [PATCH 16/17] Fix spec --- lib/membrane_vpx/encoder/vpx_encoder.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/membrane_vpx/encoder/vpx_encoder.ex b/lib/membrane_vpx/encoder/vpx_encoder.ex index a694d4b..23d44d9 100644 --- a/lib/membrane_vpx/encoder/vpx_encoder.ex +++ b/lib/membrane_vpx/encoder/vpx_encoder.ex @@ -28,6 +28,8 @@ defmodule Membrane.VPx.Encoder do @type callback_return :: {[Membrane.Element.Action.t()], State.t()} + @type encoded_frame :: %{payload: binary(), pts: non_neg_integer(), is_keyframe: boolean()} + @spec handle_init(CallbackContext.t(), VP8.Encoder.t() | VP9.Encoder.t(), :vp8 | :vp9) :: callback_return() @@ -134,12 +136,12 @@ defmodule Membrane.VPx.Encoder do get_buffers_from_frames(encoded_frames, codec) end - @spec get_buffers_from_frames([EncodedFrame.t()], :vp8 | :vp9) :: [Buffer.t()] + @spec get_buffers_from_frames([encoded_frame()], :vp8 | :vp9) :: [Buffer.t()] def get_buffers_from_frames(encoded_frames, codec) do Enum.map(encoded_frames, fn %{payload: payload, pts: pts, is_keyframe: is_keyframe} -> %Buffer{ payload: payload, - pts: pts, + pts: Membrane.Time.nanoseconds(pts), metadata: %{codec => %{is_keyframe: is_keyframe}} } end) From a1988da662fbc85e477eb5c694d7c2580aaf8402 Mon Sep 17 00:00:00 2001 From: noarkhh Date: Fri, 26 Jul 2024 08:48:59 +0200 Subject: [PATCH 17/17] Remove forcing keyframe from flush --- c_src/membrane_vpx_plugin/vpx_encoder.c | 4 +--- c_src/membrane_vpx_plugin/vpx_encoder.spec.exs | 2 +- lib/membrane_vpx/encoder/vpx_encoder.ex | 10 +++++----- mix.lock | 1 + 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.c b/c_src/membrane_vpx_plugin/vpx_encoder.c index cf2861b..c292bde 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.c +++ b/c_src/membrane_vpx_plugin/vpx_encoder.c @@ -169,6 +169,4 @@ UNIFEX_TERM encode_frame( return encode(env, &state->img, pts, force_keyframe, state); } -UNIFEX_TERM flush(UnifexEnv *env, int force_keyframe, State *state) { - return encode(env, NULL, 0, force_keyframe, state); -} +UNIFEX_TERM flush(UnifexEnv *env, State *state) { return encode(env, NULL, 0, 0, state); } diff --git a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs index cde0ef9..f9f30cf 100644 --- a/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs +++ b/c_src/membrane_vpx_plugin/vpx_encoder.spec.exs @@ -25,7 +25,7 @@ spec encode_frame(payload, pts :: int64, force_keyframe :: bool, state) :: {:ok :: label, frames :: [encoded_frame]} | {:error :: label, reason :: atom} -spec flush(force_keyframe :: bool, state) :: +spec flush(state) :: {:ok :: label, frames :: [encoded_frame]} | {:error :: label, reason :: atom} diff --git a/lib/membrane_vpx/encoder/vpx_encoder.ex b/lib/membrane_vpx/encoder/vpx_encoder.ex index 23d44d9..4e9c7bd 100644 --- a/lib/membrane_vpx/encoder/vpx_encoder.ex +++ b/lib/membrane_vpx/encoder/vpx_encoder.ex @@ -89,7 +89,7 @@ defmodule Membrane.VPx.Encoder do @spec handle_end_of_stream(:input, CallbackContext.t(), State.t()) :: callback_return() def handle_end_of_stream(:input, _ctx, state) do - buffers = flush(state.force_next_keyframe, state.encoder_ref, state.codec) + buffers = flush(state.encoder_ref, state.codec) {[buffer: {:output, buffers}, end_of_stream: :output], state} end @@ -125,13 +125,13 @@ defmodule Membrane.VPx.Encoder do {[], new_encoder_ref} old_encoder_ref -> - {flush(state.force_next_keyframe, old_encoder_ref, state.codec), new_encoder_ref} + {flush(old_encoder_ref, state.codec), new_encoder_ref} end end - @spec flush(boolean(), reference(), :vp8 | :vp9) :: [Membrane.Buffer.t()] - defp flush(force_next_keyframe, encoder_ref, codec) do - {:ok, encoded_frames} = Native.flush(force_next_keyframe, encoder_ref) + @spec flush(reference(), :vp8 | :vp9) :: [Membrane.Buffer.t()] + defp flush(encoder_ref, codec) do + {:ok, encoded_frames} = Native.flush(encoder_ref) get_buffers_from_frames(encoded_frames, codec) end diff --git a/mix.lock b/mix.lock index 0341896..8b2fb1b 100644 --- a/mix.lock +++ b/mix.lock @@ -20,6 +20,7 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, "membrane_core": {:hex, :membrane_core, "1.1.1", "4dcff6e9f3b2ecd4f437c20e201e53957731772c0f15b3005062c41f7f58f500", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3802f3fc071505c59d48792487d9927e803d4edb4039710ffa52cdb60bb0aecc"}, + "membrane_fake_plugin": {:hex, :membrane_fake_plugin, "0.11.0", "3a2d26f15ad4940a4d44cee3354dff38fa9a39963e9b2dcb49802e150ff9a9dc", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "7c6b6a06eaa4e820d1e4836510ddb4bcb386c8918d0b37542a21caf6b87cbe72"}, "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.2", "650e134c2345d946f930082fac8bac9f5aba785a7817d38a9a9da41ffc56fa92", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "df50c6040004cd7b901cf057bd7e99c875bbbd6ae574efc93b2c753c96f43b9d"}, "membrane_ivf_plugin": {:hex, :membrane_ivf_plugin, "0.8.0", "0495a4fd34a1b9841d288b3a078d2b09c48020294a6452ce08e8954711648ac8", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_file_plugin, "~> 0.17.0", [hex: :membrane_file_plugin, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}], "hexpm", "b17805a451f1066dab68c19577efad7819200c20970e3ba5f7d6fbbc751240e9"}, "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"},