@@ -9,8 +9,8 @@ defmodule ExHLS.DemuxingEngine.MPEGTS do
99 alias Membrane . { AAC , H264 , RemoteStream }
1010 alias MPEG.TS.Demuxer
1111
12- @ enforce_keys [ :demuxer , :last_tden_tag ]
13- defstruct @ enforce_keys ++ [ track_timestamps_data: % { } ]
12+ @ enforce_keys [ :demuxer ]
13+ defstruct @ enforce_keys ++ [ track_timestamps_data: % { } , last_tden_tag: nil , packets_map: % { } ]
1414
1515 # using it a boundary expressed in nanoseconds, instead of the usual 90kHz clock ticks,
1616 # generates up to 1/10th of ms error per 26.5 hours of stream which is acceptable in
@@ -19,7 +19,8 @@ defmodule ExHLS.DemuxingEngine.MPEGTS do
1919
2020 @ type t :: % __MODULE__ {
2121 demuxer: Demuxer . t ( ) ,
22- last_tden_tag: String . t ( ) | nil
22+ last_tden_tag: String . t ( ) | nil ,
23+ packets_map: % { ( track_id :: non_neg_integer ( ) ) => Qex . t ( MPEG.TS.Demuxer.Container . t ( ) ) }
2324 }
2425
2526 @ impl true
@@ -28,31 +29,31 @@ defmodule ExHLS.DemuxingEngine.MPEGTS do
2829 # different demuxing engines
2930 def new ( _timestamp_offset_ms ) do
3031 demuxer = Demuxer . new ( )
31-
32- # we need to explicitly override that `waiting_random_access_indicator` as otherwise Demuxer
33- # discards all the input data
34- # TODO - figure out how to do it properly
35- demuxer = % { demuxer | waiting_random_access_indicator: false }
36-
37- % __MODULE__ { demuxer: demuxer , last_tden_tag: nil }
32+ % __MODULE__ { demuxer: demuxer }
3833 end
3934
4035 @ impl true
4136 def feed! ( % __MODULE__ { } = demuxing_engine , binary ) do
42- demuxing_engine
43- |> Map . update! ( :demuxer , & Demuxer . push_buffer ( & 1 , binary ) )
37+ { new_packets , demuxer } = Demuxer . demux ( demuxing_engine . demuxer , binary )
38+
39+ packets_map =
40+ Enum . reduce ( new_packets , demuxing_engine . packets_map , fn new_packet , packets_map ->
41+ Map . update ( packets_map , new_packet . pid , Qex . new ( [ new_packet ] ) , & Qex . push ( & 1 , new_packet ) )
42+ end )
43+
44+ % { demuxing_engine | demuxer: demuxer , packets_map: packets_map }
4445 end
4546
4647 @ impl true
4748 def get_tracks_info ( % __MODULE__ { } = demuxing_engine ) do
48- with % { streams: streams } <- demuxing_engine . demuxer . pmt do
49+ with % { streams: streams } <- demuxing_engine . demuxer do
4950 tracks_info =
5051 streams
5152 |> Enum . flat_map ( fn
52- { id , % { stream_type: :AAC } } ->
53+ { id , % { stream_type: :AAC_ADTS } } ->
5354 [ { id , % RemoteStream { content_format: AAC } } ]
5455
55- { id , % { stream_type: :H264 } } ->
56+ { id , % { stream_type: :H264_AVC } } ->
5657 [ { id , % RemoteStream { content_format: H264 } } ]
5758
5859 { id , unsupported_stream_info } ->
@@ -80,47 +81,56 @@ defmodule ExHLS.DemuxingEngine.MPEGTS do
8081
8182 @ impl true
8283 def pop_chunk ( % __MODULE__ { } = demuxing_engine , track_id ) do
83- with { [ packet ] , demuxer } <- Demuxer . take ( demuxing_engine . demuxer , track_id ) do
84- { maybe_tden_tag , demuxer } = maybe_read_tden_tag ( demuxer , packet . pts )
85- tden_tag = maybe_tden_tag || demuxing_engine . last_tden_tag
84+ with { [ packet ] , demuxing_engine } <- take_packets ( demuxing_engine , track_id ) do
85+ demuxing_engine = maybe_read_tden_tag ( demuxing_engine , packet . payload . pts )
8686
8787 { demuxing_engine , packet } =
88- % { demuxing_engine | demuxer: demuxer , last_tden_tag: tden_tag }
89- |> handle_possible_timestamps_rollover ( track_id , packet )
88+ demuxing_engine |> handle_possible_timestamps_rollover ( track_id , packet )
9089
9190 chunk = % ExHLS.Chunk {
92- payload: packet . data ,
93- pts_ms: packet . pts |> packet_ts_to_millis ( ) ,
94- dts_ms: packet . dts |> packet_ts_to_millis ( ) ,
91+ payload: packet . payload . data ,
92+ pts_ms: packet . payload . pts |> packet_ts_to_millis ( ) ,
93+ dts_ms: packet . payload . dts |> packet_ts_to_millis ( ) ,
9594 track_id: track_id ,
9695 metadata: % {
97- discontinuity: packet . discontinuity ,
98- is_aligned: packet . is_aligned ,
99- tden_tag: tden_tag
96+ discontinuity: packet . payload . discontinuity ,
97+ is_aligned: packet . payload . is_aligned ,
98+ tden_tag: demuxing_engine . last_tden_tag
10099 }
101100 }
102101
103102 { :ok , chunk , demuxing_engine }
104103 else
105- { [ ] , demuxer } ->
106- { :error , :empty_track_data , % { demuxing_engine | demuxer: demuxer } }
104+ { [ ] , demuxing_engine } ->
105+ { :error , :empty_track_data , demuxing_engine }
107106 end
108107 end
109108
110- defp maybe_read_tden_tag ( demuxer , packet_pts ) do
109+ defp take_packets ( demuxing_engine , track_id ) do
110+ with { :ok , packets } <- Map . fetch ( demuxing_engine . packets_map , track_id ) ,
111+ { { :value , packet } , rest } <- Qex . pop ( packets ) do
112+ demuxing_engine = put_in ( demuxing_engine . packets_map [ track_id ] , rest )
113+ { [ packet ] , demuxing_engine }
114+ else
115+ _other -> { [ ] , demuxing_engine }
116+ end
117+ end
118+
119+ defp maybe_read_tden_tag ( demuxing_engine , packet_pts ) do
111120 withl no_id3_stream:
112121 { id3_track_id , _stream_description } <-
113- demuxer . pmt . streams
122+ demuxing_engine . demuxer . streams
114123 |> Enum . find ( fn { _pid , stream_description } ->
115124 stream_description . stream_type == :METADATA_IN_PES
116125 end ) ,
117- no_id3_data: { [ id3 ] , demuxer } <- Demuxer . take ( demuxer , id3_track_id ) ,
118- id3_not_in_timerange: true <- id3 . pts <= packet_pts do
119- { parse_tden_tag ( id3 . data ) , demuxer }
126+ no_id3_data: { [ id3 ] , demuxing_engine } <- take_packets ( demuxing_engine , id3_track_id ) ,
127+ id3_not_in_timerange: true <- id3 . payload . pts <= packet_pts do
128+ tden_tag = parse_tden_tag ( id3 . payload . data ) || demuxing_engine . last_tden_tag
129+ % { demuxing_engine | last_tden_tag: tden_tag }
120130 else
121- no_id3_stream: nil -> { nil , demuxer }
122- no_id3_data: { [ ] , updated_demuxer } -> { nil , updated_demuxer }
123- id3_not_in_timerange: false -> { nil , demuxer }
131+ no_id3_stream: nil -> demuxing_engine
132+ no_id3_data: { [ ] , updated_demuxing_engine } -> updated_demuxing_engine
133+ id3_not_in_timerange: false -> demuxing_engine
124134 end
125135 end
126136
@@ -143,7 +153,7 @@ defmodule ExHLS.DemuxingEngine.MPEGTS do
143153
144154 @ impl true
145155 def end_stream ( % __MODULE__ { } = demuxing_engine ) do
146- demuxer = Demuxer . end_of_stream ( demuxing_engine . demuxer )
156+ { _flushed , demuxer } = Demuxer . flush ( demuxing_engine . demuxer )
147157 % { demuxing_engine | demuxer: demuxer }
148158 end
149159
@@ -155,32 +165,34 @@ defmodule ExHLS.DemuxingEngine.MPEGTS do
155165
156166 rollovers_offset = rollovers_count * @ timestamp_range_size_ns
157167
158- packet =
159- packet
168+ payload =
169+ packet . payload
160170 |> Map . update! ( :pts , & add_offset_if_not_nil ( & 1 , rollovers_offset ) )
161171 |> Map . update! ( :dts , & add_offset_if_not_nil ( & 1 , rollovers_offset ) )
162172
163- { demuxing_engine , packet } =
173+ { demuxing_engine , payload } =
164174 with last_ts when last_ts != nil <- last_dts || last_pts ,
165- true <- last_ts > ( packet . dts || packet . pts ) do
175+ true <- last_ts > ( payload . dts || payload . pts ) do
166176 demuxing_engine =
167177 demuxing_engine
168178 |> update_in ( [ :track_timestamps_data , track_id , :rollovers_count ] , & ( & 1 + 1 ) )
169179
170- packet =
171- packet
180+ payload =
181+ payload
172182 |> Map . update! ( :pts , & add_offset_if_not_nil ( & 1 , @ timestamp_range_size_ns ) )
173183 |> Map . update! ( :dts , & add_offset_if_not_nil ( & 1 , @ timestamp_range_size_ns ) )
174184
175- { demuxing_engine , packet }
185+ { demuxing_engine , payload }
176186 else
177- _other -> { demuxing_engine , packet }
187+ _other -> { demuxing_engine , payload }
178188 end
179189
180190 demuxing_engine =
181191 demuxing_engine
182- |> put_in ( [ :track_timestamps_data , track_id , :last_pts ] , packet . pts )
183- |> put_in ( [ :track_timestamps_data , track_id , :last_dts ] , packet . dts )
192+ |> put_in ( [ :track_timestamps_data , track_id , :last_pts ] , payload . pts )
193+ |> put_in ( [ :track_timestamps_data , track_id , :last_dts ] , payload . dts )
194+
195+ packet = % { packet | payload: payload }
184196
185197 { demuxing_engine , packet }
186198 end
0 commit comments