Skip to content

Rework defining output stream formats - #25

Open
Noarkhh wants to merge 17 commits into
masterfrom
transcoder-api-rework
Open

Rework defining output stream formats#25
Noarkhh wants to merge 17 commits into
masterfrom
transcoder-api-rework

Conversation

@Noarkhh

@Noarkhh Noarkhh commented Jun 25, 2026

Copy link
Copy Markdown

closes membraneframework/membrane_core#1152

Changes introduced by this PR:

  • Previously output format specification relied on stream formats, now OutputFormat provides module to be used when specifying the desired output format
  • Wrapped instantiation of VKVideo structs with Code.ensure_loaded?/1 calls
  • Previously, when input and output formats were structs of the same module, the transcoder just forwarded buffers and didn't create any elements. This approach ignored any differences between fields of these two stream formats. Now a parser is always inserted, making the stream conformant with output format

@Noarkhh Noarkhh self-assigned this Jun 25, 2026
@Noarkhh Noarkhh added this to Smackore Jun 25, 2026
@Noarkhh Noarkhh moved this to In Progress in Smackore Jun 25, 2026
@Noarkhh Noarkhh changed the title wrap VKVideo elements with ensure_loaded? Rework defining output stream formats Jun 25, 2026
@Noarkhh
Noarkhh force-pushed the transcoder-api-rework branch from d976cf3 to 5b20a5c Compare June 26, 2026 13:28
@Noarkhh
Noarkhh requested review from FelonEkonom and varsill June 29, 2026 16:08
@Noarkhh Noarkhh moved this from In Progress to In Review in Smackore Jun 29, 2026
Comment thread lib/transcoder/audio.ex Outdated
Comment thread lib/transcoder/audio.ex
Comment thread lib/transcoder/audio.ex
Comment thread lib/transcoder/video.ex Outdated
Comment thread lib/transcoder/video.ex Outdated
Comment thread lib/transcoder/video.ex Outdated
Comment thread lib/transcoder/video.ex Outdated
Comment thread test/integration_test.exs Outdated
@FelonEkonom

Copy link
Copy Markdown
Member

Please, fix CI

@Noarkhh
Noarkhh requested a review from FelonEkonom July 1, 2026 09:10

@FelonEkonom FelonEkonom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There one last thread unresolved

@Noarkhh
Noarkhh requested a review from FelonEkonom July 1, 2026 09:42

@FelonEkonom FelonEkonom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 🚀 🚀

Comment thread mix.exs
defp deps do
[
{:membrane_vk_video_plugin, "~> 0.2.0", optional: true},
# {:membrane_vk_video_plugin, "~> 0.2.0", optional: true},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you commit it ;)

Comment thread test/integration_test.exs Outdated
@test_cases @video_cases ++ @audio_cases

Enum.map(@test_cases, fn test_case ->
@tag :base

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@tag :base

Comment thread lib/transcoder.ex
@Noarkhh
Noarkhh requested a review from varsill July 1, 2026 13:25
@FelonEkonom
FelonEkonom self-requested a review July 1, 2026 13:49

@FelonEkonom FelonEkonom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I see that examples are not updated to the new API. Take a look at examples dir. It would be nice to have a test that runs examples and checks whenever they crash, to detect situations like this one.

@Noarkhh
Noarkhh requested a review from FelonEkonom July 2, 2026 07:36

@FelonEkonom FelonEkonom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What with running examples on CI? We could have a test, that runs both examples and checks if there is no error

Comment thread examples/multivariant_output.exs Outdated
defmodule Example do
alias Membrane.{H264, H265, VP8, RCPipeline}
alias Membrane.{H264, RCPipeline}
alias Membrane.Transcoder.OutputFormat

@FelonEkonom FelonEkonom Jul 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that having alias for Membrane.Transcoder would be the prettiest in the example, right now we have Membrane.Transcoder in the child spec and OutputFormat.* in its opts, Trascoder and Transcoder.OutputFormat.* would be cleaner.

EDIT: it applies to the second example as well

Comment thread lib/transcoder/audio.ex Outdated
Comment thread lib/transcoder/audio.ex Outdated
Comment thread lib/transcoder/audio.ex Outdated
Comment thread lib/transcoder/output_format.ex
@Noarkhh

Noarkhh commented Jul 2, 2026

Copy link
Copy Markdown
Author

What with running examples on CI? We could have a test, that runs both examples and checks if there is no error

I think this something we should address in general, not just in this plugin. Maybe add a CI step that does that in test, it should be pretty straightforward

@Noarkhh
Noarkhh requested a review from varsill July 6, 2026 13:55
@Noarkhh
Noarkhh requested a review from FelonEkonom July 6, 2026 13:55

@varsill varsill left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥈 - just fix the CI ;)

@FelonEkonom

FelonEkonom commented Jul 8, 2026

Copy link
Copy Markdown
Member

I think this something we should address in general, not just in this plugin. Maybe add a CI step that does that in test, it should be pretty straightforward

What with examples that require some interaction, like opening a browser tab to inject a WebRTC stream?

Please, open an issue in membrane_core documenting this idea (or just implement it here 😉)

@FelonEkonom FelonEkonom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understood you correctly during todays meeting, this won't be ready to review until you implement these phillars, am I right?

@Noarkhh
Noarkhh force-pushed the transcoder-api-rework branch from c0ebaa7 to b295c5d Compare July 27, 2026 10:19
@Noarkhh
Noarkhh requested a review from varsill July 27, 2026 12:04
Comment thread lib/transcoder.ex Outdated
Comment on lines 434 to 438
format when is_struct(format) ->
format

module when is_atom(module) ->
struct(module)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we check agains a list of available OutputFormats here?
If somebody passes the old Membrane.H264, it will silently pass.

Comment thread lib/transcoder/video.ex
)

_other ->
builder

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it mean that e.g. for %Membrane.RemoteStream{content_format: Membrane.VP8} input and OutputFormat.V8 output configuration we will receive "unparsed" %Membrane.RemoteStream{content_format: Membrane.VP8} stream format from the output pad?

(I know that we don't have VP8 parser but I am just asking :D)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's right, for now I thought that transcoding the stream just to parse it is ugly, but I'm not sure what would be the best

Comment thread lib/transcoder/video.ex Outdated
) :: boolean()
defp should_be_transcoded(input_format, output_format, transcoding_policy, output_spec) do
transcoding_policy == :always or
output_spec.resolution != :keep or

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what if output resolution is explicitly provided, but equal to the input format resolution?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then it will be transcoded and rescaled nonetheless, I didn't add it for now


defmodule MPEGAudio do
@moduledoc """
Struct defining the desired output Membrane stream format.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Struct defining the desired output Membrane stream format.
Struct defining the desired output MPEGAudio stream format.

Comment thread lib/transcoder/audio.ex
Comment thread lib/transcoder.ex
Comment on lines +111 to +119
spec: bitrate_option() | :default,
default: :default,
description: """
Per-output bitrate setting for video streams. Inherits from bin's `bitrate` option if nil.
Per-output bitrate setting for video streams.

Can be either:
* a `Membrane.Transcoder.Video.ConstantBitrate` struct for constant bitrate encoding
* a `Membrane.Transcoder.Video.VariableBitrate` struct for variable bitrate encoding
* `:default` - use encoder defaults

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could raise if this option is set for audio pad? It might be misleading otherwise

Comment thread test/integration_test.exs
Comment thread lib/transcoder.ex
| %Membrane.RemoteStream{content_format: Membrane.H264 | Membrane.H265}

An alternative to `t:#{inspect(__MODULE__)}.stream_format/0`.
@type audio_input_format ::

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a duplicate of

@type audio_input_format ::

Comment thread lib/transcoder.ex Outdated
@@ -259,18 +300,40 @@ defmodule Membrane.Transcoder do

spec = child(funnel_name, Funnel) |> bin_output(pad_ref)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT] I know it's not a part of your change, but this Funnel could be Membrane.Connector

Comment thread lib/transcoder.ex Outdated
Comment thread lib/transcoder.ex

other_format ->
module_suffix = other_format.__struct__ |> Module.split() |> List.last()
struct!(Module.concat(OutputFormat, module_suffix))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it would be good to have a whitelist of expected struct modules?

@Noarkhh
Noarkhh requested a review from varsill July 28, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

[Transcoder] Rework output stream format specification

3 participants