-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get image width and height from the decoder #9
Changes from 6 commits
9007e35
5283842
bec5c48
172d9f2
db5f748
1498365
ed22bb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,29 @@ | ||
defmodule Membrane.VPx.Decoder do | ||
@moduledoc false | ||
|
||
alias Membrane.{Buffer, RawVideo, RemoteStream, VP8, VP9} | ||
require Membrane.Logger | ||
alias Hex.State | ||
alias Membrane.{Buffer, RawVideo, VP8, VP9} | ||
alias Membrane.Element.CallbackContext | ||
alias Membrane.VPx.Decoder.Native | ||
|
||
@type decoded_frame :: %{ | ||
payload: binary(), | ||
pixel_format: RawVideo.pixel_format(), | ||
width: non_neg_integer(), | ||
height: non_neg_integer() | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not used anywhere |
||
defmodule State do | ||
@moduledoc false | ||
|
||
@type t :: %__MODULE__{ | ||
codec: :vp8 | :vp9, | ||
width: pos_integer() | nil, | ||
height: pos_integer() | nil, | ||
framerate: {pos_integer(), pos_integer()} | nil, | ||
decoder_ref: reference() | nil | ||
} | ||
|
||
@enforce_keys [:codec, :width, :height, :framerate] | ||
@enforce_keys [:codec, :framerate] | ||
defstruct @enforce_keys ++ | ||
[ | ||
decoder_ref: nil | ||
|
@@ -28,12 +35,7 @@ defmodule Membrane.VPx.Decoder do | |
@spec handle_init(CallbackContext.t(), VP8.Decoder.t() | VP9.Decoder.t(), :vp8 | :vp9) :: | ||
callback_return() | ||
def handle_init(_ctx, opts, codec) do | ||
state_fields = | ||
opts | ||
|> Map.take([:width, :height, :framerate]) | ||
|> Map.put(:codec, codec) | ||
|
||
{[], struct(State, state_fields)} | ||
{[], %State{framerate: opts.framerate, codec: codec}} | ||
end | ||
|
||
@spec handle_setup(CallbackContext.t(), State.t()) :: callback_return() | ||
|
@@ -51,51 +53,24 @@ defmodule Membrane.VPx.Decoder 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, [decoded_frame], pixel_format} = Native.decode_frame(payload, state.decoder_ref) | ||
{:ok, [decoded_frame]} = Native.decode_frame(payload, state.decoder_ref) | ||
|
||
stream_format_action = | ||
if ctx.pads.output.stream_format == nil do | ||
output_stream_format = | ||
get_output_stream_format(ctx.pads.input.stream_format, pixel_format, state) | ||
new_stream_format = %RawVideo{ | ||
width: decoded_frame.width, | ||
height: decoded_frame.height, | ||
framerate: state.framerate, | ||
pixel_format: decoded_frame.pixel_format, | ||
aligned: true | ||
} | ||
|
||
[stream_format: {:output, output_stream_format}] | ||
stream_format_action = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's raise or warn if the frame shape get from native code is different than the shape defined in input stream format (if it has any information about it) |
||
if new_stream_format != ctx.pads.output.stream_format do | ||
[stream_format: {:output, new_stream_format}] | ||
else | ||
[] | ||
end | ||
|
||
{stream_format_action ++ [buffer: {:output, %Buffer{payload: decoded_frame, pts: pts}}], | ||
state} | ||
end | ||
|
||
@spec get_output_stream_format( | ||
RemoteStream.t() | VP8.t() | VP9.t(), | ||
RawVideo.pixel_format(), | ||
State.t() | ||
) :: RawVideo.t() | ||
defp get_output_stream_format(input_stream_format, pixel_format, state) do | ||
{width, height, framerate} = | ||
case input_stream_format do | ||
%RemoteStream{} -> | ||
{ | ||
state.width || raise("Width not provided"), | ||
state.height || raise("Height not provided"), | ||
state.framerate | ||
} | ||
|
||
%{width: width, height: height} -> | ||
{ | ||
width, | ||
height, | ||
state.framerate | ||
} | ||
end | ||
|
||
%RawVideo{ | ||
width: width, | ||
height: height, | ||
framerate: framerate, | ||
pixel_format: pixel_format, | ||
aligned: true | ||
} | ||
{stream_format_action ++ | ||
[buffer: {:output, %Buffer{payload: decoded_frame.payload, pts: pts}}], state} | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we don't need it here