Skip to content
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

Adapt plugin for general Membrane use cases #1

Merged
merged 23 commits into from
Jun 6, 2024
Merged

Conversation

Noarkhh
Copy link
Collaborator

@Noarkhh Noarkhh commented May 8, 2024

closes membraneframework/membrane_core#787 (comment)

This PR:

  • removes Membrane.RTSP.Source.TCP and instead uses Membrane.TCP.Source, which was tweaked to use socket's active mode and have much better CPU performance.
  • replaces Membrane.RTSP.Source.Decapsulator with Membrane.RTSP.TCP.Decapsulator, which has since been updated to pick up interleaved RTSP messages more reliably and forward packets from all channels (including RTCP packets).
  • removes Membrane.RTSP.Source.Transport.TCPWrapper, because the functionality of passing socket control has since been added to Membrane.RTSP.
  • removes retrying mechanisms, as it would be more appropriate to handle connection failures by letting the element crash and handling it on a higher level with crash groups.
  • changes behavior of choosing ports for UDP.Sources in case of :udp transport, from choosing randomly from a fixed, wide range, to choosing successively from a range passed via options. This decision was made to prevent situations where a port is free during the SETUP phase but taken by a different, unrelated process during PLAY phase. The ability to pass the port range via options is also needed when the ports available are limited by things like docker mappings or firewall.

Notes:

  • Passing control of the TCP socket from the RTSP session to the TCP.Source goes as follows:
    • TCP.Source sends {:request_socket_control, socket, pid} notification to RTSP.Source
    • RTSP.Source calls RTSP.Source.ConnectionManager.transfer_socket_control/2 with TCP.Source's pid
    • RTSP.Source.ConnectionManager calls RTSP.transfer_socket_control/2with TCP.Source's pid
    • RTSP calls :gen_tcp.controlling_process/2 with the socket handle and TCP.Source's pid

@Noarkhh Noarkhh requested a review from mat-hek May 8, 2024 13:31
Copy link

@mat-hek mat-hek left a comment

Choose a reason for hiding this comment

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

Please add a summary of what has changed in the PR description

@@ -58,18 +67,28 @@ defmodule Membrane.RTSP.Source do
accepted_format: _any,
availability: :on_request

defmodule ReadyNotifier do
@moduledoc false
Copy link

Choose a reason for hiding this comment

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

let's add a comment on why it's needed

]
common_spec ++
Enum.map(min_port..max_port, fn port ->
child({:udp_source, make_ref()}, %Membrane.UDP.Source{local_port_no: port})
Copy link

Choose a reason for hiding this comment

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

Why do we listen on all the ports from the range?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this range includes only ports negotiated with setup messages, see connection_manager.ex:147, I'll make it more readable

Copy link

Choose a reason for hiding this comment

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

I think we should only choose the free ports though

Copy link

Choose a reason for hiding this comment

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

bump @Noarkhh

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There was this slight concern, that the original version checked for a free port only during the SETUP phase and didn't claim it, so theoretically the port could be taken by some other process after SETUP and before the UDP sources are spawned. To eliminate this possibility entirely we would need to add an option to UDP Source to pass an already connected socket to it, but that could complicate the code a bit.

@Noarkhh
Copy link
Collaborator Author

Noarkhh commented May 15, 2024

Please add a summary of what has changed in the PR description

I planned to do that for the second, contributing PR, would you like it here too?

@Noarkhh Noarkhh requested a review from mat-hek May 15, 2024 10:54
%{state | keep_alive_timer: start_keep_alive_timer(state)}
tracks
|> Enum.with_index()
|> Enum.reduce_while({:ok, []}, fn {track, idx}, {:ok, set_up_tracks} ->
Copy link

Choose a reason for hiding this comment

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

you can use Bunch.Enum.try_reduce_while

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think it's necessary, since I want to break prematurely only on error

@Noarkhh Noarkhh merged commit e0d61a2 into master Jun 6, 2024
3 checks passed
@Noarkhh Noarkhh deleted the adapt-plugin branch June 6, 2024 15:51
Noarkhh added a commit that referenced this pull request Jun 11, 2024
* Make the plugin work using official elements

* Crash on connection failure

* Improve docs, refactor

* Adjust tests, remove restarting functionalities

* Migrate rtsp_decapsulator from rtp_plugin to here

* Change behavior to not allow for taken ports

* Add typespecs
Noarkhh added a commit that referenced this pull request Jun 12, 2024
* Adapt plugin for general Membrane use cases (#1)

* Make the plugin work using official elements

* Crash on connection failure

* Improve docs, refactor

* Adjust tests, remove restarting functionalities

* Migrate rtsp_decapsulator from rtp_plugin to here

* Change behavior to not allow for taken ports

* Add typespecs

* Receive responses to all requests for auth

* Use released rtp_plugin

* Try rerequesting

* Use membrane_core 1.1, fix typo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create Membrane.RTSP.Plugin
2 participants