@@ -12,15 +12,11 @@ defmodule Membrane.HLS.Source do
1212
1313 def_output_pad :video_output ,
1414 accepted_format: any_of ( H264 , % RemoteStream { content_format: H264 } ) ,
15- availability: :on_request ,
16- max_instances: 1 ,
1715 flow_control: :manual ,
1816 demand_unit: :buffers
1917
2018 def_output_pad :audio_output ,
2119 accepted_format: any_of ( AAC , % RemoteStream { content_format: AAC } ) ,
22- availability: :on_request ,
23- max_instances: 1 ,
2420 flow_control: :manual ,
2521 demand_unit: :buffers
2622
@@ -34,7 +30,6 @@ defmodule Membrane.HLS.Source do
3430
3531 def_options url: [ spec: String . t ( ) ] ,
3632 buffer_size: [ spec: pos_integer ( ) , default: 0 ] ,
37- container: [ spec: :mpeg_ts | :fmp4 , default: :mpeg_ts ] ,
3833 variant_selection_policy: [
3934 spec: variant_selection_policy ( ) ,
4035 default: :highest_resolution
@@ -45,8 +40,8 @@ defmodule Membrane.HLS.Source do
4540 state =
4641 Map . from_struct ( opts )
4742 |> Map . merge ( % {
48- audio_output: % { pad_ref: nil , requested: 0 , qex: Qex . new ( ) , qex_size: 0 } ,
49- video_output: % { pad_ref: nil , requested: 0 , qex: Qex . new ( ) , qex_size: 0 } ,
43+ audio_output: % { requested: 0 , qex: Qex . new ( ) , qex_size: 0 } ,
44+ video_output: % { requested: 0 , qex: Qex . new ( ) , qex_size: 0 } ,
5045 client_genserver: nil
5146 } )
5247
@@ -55,30 +50,14 @@ defmodule Membrane.HLS.Source do
5550
5651 @ impl true
5752 def handle_setup ( _ctx , state ) do
58- demuxing_engine =
59- case state . container do
60- :mpeg_ts -> ExHLS.DemuxingEngine.MPEGTS
61- :fmp4 -> ExHLS.DemuxingEngine.CMAF
62- end
63-
64- { :ok , clinet_genserver } =
65- ClientGenServer . start_link ( state . url , demuxing_engine , state . variant_selection_policy )
66-
67- { [ ] , % { state | client_genserver: clinet_genserver } }
68- end
53+ { :ok , client_genserver } =
54+ ClientGenServer . start_link ( state . url , state . variant_selection_policy )
6955
70- @ impl true
71- def handle_pad_added ( Pad . ref ( pad_name , _id ) = pad_ref , _ctx , state ) do
72- state = state |> put_in ( [ pad_name , :pad_ref ] , pad_ref )
73- { [ ] , state }
56+ { [ ] , % { state | client_genserver: client_genserver } }
7457 end
7558
7659 @ impl true
7760 def handle_playing ( ctx , state ) do
78- if ctx . pads |> map_size ( ) < 2 do
79- raise "HLS Source requires both audio and video output pads to be present"
80- end
81-
8261 { [ audio_stream_format ] , [ video_stream_format ] } =
8362 ClientGenServer . get_tracks_info ( state . client_genserver )
8463 |> Map . values ( )
@@ -90,8 +69,8 @@ defmodule Membrane.HLS.Source do
9069 end )
9170
9271 actions = [
93- stream_format: { state . audio_output . pad_ref , audio_stream_format } ,
94- stream_format: { state . video_output . pad_ref , video_stream_format }
72+ stream_format: { : audio_output, audio_stream_format } ,
73+ stream_format: { : video_output, video_stream_format }
9574 ]
9675
9776 { actions , state }
@@ -105,42 +84,42 @@ defmodule Membrane.HLS.Source do
10584 end
10685
10786 @ impl true
108- def handle_info ( { stream_type , frame } , _ctx , state )
109- when stream_type in [ :audio_stream , :video_stream ] do
110- pad_name =
111- case stream_type do
112- :audio_stream -> :audio_output
113- :video_stream -> :video_output
87+ def handle_info ( { data_type , sample } , _ctx , state )
88+ when data_type in [ :audio_sample_ , :video_sample ] do
89+ pad_ref =
90+ case data_type do
91+ :audio_sample -> :audio_output
92+ :video_sample -> :video_output
11493 end
11594
11695 state =
11796 state
118- |> update_in ( [ pad_name , :qex ] , & Qex . push ( & 1 , frame ) )
119- |> update_in ( [ pad_name , :qex_size ] , & ( & 1 + 1 ) )
120- |> update_in ( [ pad_name , :requested ] , & ( & 1 - 1 ) )
97+ |> update_in ( [ pad_ref , :qex ] , & Qex . push ( & 1 , sample ) )
98+ |> update_in ( [ pad_ref , :qex_size ] , & ( & 1 + 1 ) )
99+ |> update_in ( [ pad_ref , :requested ] , & ( & 1 - 1 ) )
121100
122- { [ redemand: state [ pad_name ] . pad_ref ] , state }
101+ { [ redemand: pad_ref ] , state }
123102 end
124103
125- defp pop_buffers ( Pad . ref ( pad_name , _id ) , demand , state ) do
126- range_upperbound = min ( state [ pad_name ] . qex_size , demand )
104+ defp pop_buffers ( pad_ref , demand , state ) do
105+ range_upperbound = min ( state [ pad_ref ] . qex_size , demand )
127106
128107 if range_upperbound > 0 do
129108 1 .. range_upperbound
130109 |> Enum . map_reduce ( state , fn _i , state ->
131- { frame , qex } = state [ pad_name ] . qex |> Qex . pop! ( )
110+ { % ExHLS.Sample { } = sample , qex } = state [ pad_ref ] . qex |> Qex . pop! ( )
132111
133112 buffer = % Membrane.Buffer {
134- payload: frame . payload ,
135- pts: frame . pts |> Membrane.Time . milliseconds ( ) ,
136- dts: frame . dts |> Membrane.Time . milliseconds ( ) ,
137- metadata: frame . metadata
113+ payload: sample . payload ,
114+ pts: sample . pts_ms |> Membrane.Time . milliseconds ( ) ,
115+ dts: sample . dts_ms |> Membrane.Time . milliseconds ( ) ,
116+ metadata: sample . metadata
138117 }
139118
140119 state =
141120 state
142- |> put_in ( [ pad_name , :qex ] , qex )
143- |> update_in ( [ pad_name , :qex_size ] , & ( & 1 - 1 ) )
121+ |> put_in ( [ pad_ref , :qex ] , qex )
122+ |> update_in ( [ pad_ref , :qex_size ] , & ( & 1 - 1 ) )
144123
145124 { buffer , state }
146125 end )
@@ -149,30 +128,24 @@ defmodule Membrane.HLS.Source do
149128 end
150129 end
151130
152- defp request_frames ( state ) do
131+ defp request_samples ( state ) do
153132 [ :audio_output , :video_output ]
154- |> Enum . reduce ( state , fn pad_name , state ->
155- request_size = state . buffer_size - state [ pad_name ] . qex_size - state [ pad_name ] . requested
156- :ok = do_request ( state , pad_name , request_size )
133+ |> Enum . reduce ( state , fn pad_ref , state ->
134+ request_size = state . buffer_size - state [ pad_ref ] . qex_size - state [ pad_ref ] . requested
135+
136+ if request_size > 0 do
137+ 1 .. request_size
138+ |> Enum . each ( fn _i -> reuqest_single_sample ( pad_ref , state ) end )
139+ end
157140
158141 state
159- |> update_in ( [ pad_name , :requested ] , & ( & 1 + request_size ) )
142+ |> update_in ( [ pad_ref , :requested ] , & ( & 1 + request_size ) )
160143 end )
161144 end
162145
163- defp do_request ( _state , _pad_name , request_size ) when request_size < 1 , do: :ok
146+ defp request_single_sample ( :audio_output , state ) ,
147+ do: ClientGenServer . request_audio_sample ( state . client_genserver )
164148
165- defp do_request ( state , :audio_output , request_size ) do
166- 1 .. request_size
167- |> Enum . each ( fn _i ->
168- ClientGenServer . request_audio ( state . client_genserver )
169- end )
170- end
171-
172- defp do_request ( state , :video_output , request_size ) do
173- 1 .. request_size
174- |> Enum . each ( fn _i ->
175- ClientGenServer . request_video ( state . client_genserver )
176- end )
177- end
149+ defp request_single_sample ( :video_output , state ) ,
150+ do: ClientGenServer . request_video_sample ( state . client_genserver )
178151end
0 commit comments