@@ -26,6 +26,9 @@ defmodule Membrane.Transcoder do
2626 Now, the only supported stream parameters are:
2727 * `:pixel_format` in `Membrane.RawVideo`
2828 * `:alignment` and `:stream_structure` in `Membrane.H264` and `Membrane.H265`
29+
30+ When the `membrane_vk_video_plugin` dependency is present and Vulkan hardware is available,
31+ H.264 encode/decode can be offloaded to the GPU by setting `native_acceleration: :if_available`.
2932 """
3033 use Membrane.Bin
3134
@@ -139,6 +142,17 @@ defmodule Membrane.Transcoder do
139142
140143 If nil or not set, the input stream format won't be overriden.
141144 """
145+ ] ,
146+ native_acceleration: [
147+ spec: :never | :if_available ,
148+ default: :never ,
149+ description: """
150+ Specifies whether to use Vulkan hardware acceleration for video transcoding.
151+
152+ Can be:
153+ * `:never` - Always use software-based transcoding (default)
154+ * `:if_available` - Use Vulkan acceleration when available on the system
155+ """
142156 ]
143157
144158 @ impl true
@@ -155,12 +169,31 @@ defmodule Membrane.Transcoder do
155169 opts
156170 |> Map . from_struct ( )
157171 |> Map . merge ( % {
158- input_stream_format: nil
172+ input_stream_format: nil ,
173+ use_hardware_acceleration?: should_use_hardware_acceleration? ( opts . native_acceleration )
159174 } )
160175
161176 { [ spec: spec ] , state }
162177 end
163178
179+ defp should_use_hardware_acceleration? ( :if_available ) , do: vulkan_available? ( )
180+ defp should_use_hardware_acceleration? ( _native_acceleration ) , do: false
181+
182+ @ doc """
183+ Returns `true` if the optional `membrane_vk_video_plugin` dependency is installed
184+ and its modules can be loaded in the current runtime.
185+
186+ Note: a `true` result only confirms the plugin is loadable - it does not guarantee that the
187+ host actually exposes Vulkan Video extensions with H.264 encode/decode capabilities. The
188+ underlying plugin may still fail at runtime if the GPU/driver does not support them.
189+ """
190+ @ spec vulkan_available? ( ) :: boolean ( )
191+ def vulkan_available? ( ) do
192+ Code . ensure_loaded? ( Membrane.VKVideo.Decoder ) and
193+ Code . ensure_loaded? ( Membrane.VKVideo.Encoder ) and
194+ Code . ensure_loaded? ( Membrane.VKVideo.Native )
195+ end
196+
164197 defp maybe_plug_stream_format_changer ( builder , nil ) , do: builder
165198
166199 defp maybe_plug_stream_format_changer ( builder , enforced_stream_format ) do
@@ -187,7 +220,8 @@ defmodule Membrane.Transcoder do
187220 |> plug_transcoding (
188221 format ,
189222 state . output_stream_format ,
190- state . transcoding_policy
223+ state . transcoding_policy ,
224+ state . use_hardware_acceleration?
191225 )
192226 |> get_child ( :output_funnel )
193227
@@ -232,15 +266,32 @@ defmodule Membrane.Transcoder do
232266 end
233267 end
234268
235- defp plug_transcoding ( builder , input_format , output_format , transcoding_policy )
269+ defp plug_transcoding (
270+ builder ,
271+ input_format ,
272+ output_format ,
273+ transcoding_policy ,
274+ _use_hardware_acceleration?
275+ )
236276 when Audio . is_audio_format ( input_format ) do
237277 builder
238278 |> Audio . plug_audio_transcoding ( input_format , output_format , transcoding_policy )
239279 end
240280
241- defp plug_transcoding ( builder , input_format , output_format , transcoding_policy )
281+ defp plug_transcoding (
282+ builder ,
283+ input_format ,
284+ output_format ,
285+ transcoding_policy ,
286+ use_hardware_acceleration?
287+ )
242288 when Video . is_video_format ( input_format ) do
243289 builder
244- |> Video . plug_video_transcoding ( input_format , output_format , transcoding_policy )
290+ |> Video . plug_video_transcoding (
291+ input_format ,
292+ output_format ,
293+ transcoding_policy ,
294+ use_hardware_acceleration?
295+ )
245296 end
246297end
0 commit comments