@@ -15,7 +15,8 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
1515 :tracks_number ,
1616 :timescales ,
1717 :last_dts ,
18- :sample_tables
18+ :sample_tables ,
19+ :mdat_iterator
1920 ]
2021
2122 defstruct @ enforce_keys
@@ -42,7 +43,8 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
4243 ( track_id :: pos_integer ( ) ) => last_dts :: Ratio . t ( ) | nil
4344 } ,
4445 tracks_number: pos_integer ( ) ,
45- sample_tables: % { ( track_id :: pos_integer ( ) ) => SampleTable . t ( ) }
46+ sample_tables: % { ( track_id :: pos_integer ( ) ) => SampleTable . t ( ) } ,
47+ mdat_iterator: non_neg_integer ( )
4648 }
4749
4850 @ doc """
@@ -51,9 +53,10 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
5153 a whole sample, and has yet to be parsed.
5254 """
5355 @ spec get_samples ( t , data :: binary ( ) ) ::
54- { [ { Buffer . t ( ) , track_id :: pos_integer ( ) } ] , rest :: binary , t }
56+ { [ { Buffer . t ( ) , track_id :: pos_integer ( ) } ] , rest :: binary ( ) , t ( ) }
5557 def get_samples ( samples_info , data ) do
56- { samples_info , rest , buffers } = do_get_samples ( samples_info , data , [ ] )
58+ { samples_info , rest , buffers } =
59+ do_get_samples ( samples_info , data , [ ] )
5760
5861 { buffers , rest , samples_info }
5962 end
@@ -63,24 +66,32 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
6366 end
6467
6568 defp do_get_samples ( samples_info , data , buffers ) do
66- [ % { size: size , track_id: track_id } = sample | samples ] = samples_info . samples
69+ [ % { size: size , track_id: track_id , sample_offset: sample_offset } = sample | samples ] =
70+ samples_info . samples
6771
68- if size <= byte_size ( data ) do
69- << payload :: binary - size ( size ) , rest :: binary >> = data
72+ to_skip = sample_offset - samples_info . mdat_iterator
7073
71- { dts , pts , samples_info } = get_dts_and_pts ( samples_info , sample )
74+ case data do
75+ << _to_skip :: binary - size ( to_skip ) , payload :: binary - size ( size ) , rest :: binary >> ->
76+ { dts , pts , samples_info } = get_dts_and_pts ( samples_info , sample )
7277
73- buffer =
74- { % Buffer {
75- payload: payload ,
76- dts: dts ,
77- pts: pts
78- } , track_id }
78+ buffer =
79+ { % Buffer {
80+ payload: payload ,
81+ dts: dts ,
82+ pts: pts
83+ } , track_id }
7984
80- samples_info = % { samples_info | samples: samples }
81- do_get_samples ( samples_info , rest , [ buffer | buffers ] )
82- else
83- { samples_info , data , Enum . reverse ( buffers ) }
85+ samples_info = % { samples_info | samples: samples }
86+
87+ do_get_samples (
88+ % { samples_info | mdat_iterator: samples_info . mdat_iterator + to_skip + size } ,
89+ rest ,
90+ [ buffer | buffers ]
91+ )
92+
93+ _other ->
94+ { samples_info , data , Enum . reverse ( buffers ) }
8495 end
8596 end
8697
@@ -118,8 +129,8 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
118129 present in the `mdat` box.
119130 The list of samples in the returned struct is used to extract data from the `mdat` box and get output buffers.
120131 """
121- @ spec get_samples_info ( % { children: boxes :: Container . t ( ) } ) :: t
122- def get_samples_info ( % { children: boxes } ) do
132+ @ spec get_samples_info ( % { children: boxes :: Container . t ( ) } , non_neg_integer ( ) ) :: t
133+ def get_samples_info ( % { children: boxes } , mdat_beginning ) do
123134 tracks =
124135 boxes
125136 |> Enum . filter ( fn { type , _content } -> type == :trak end )
@@ -159,15 +170,18 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
159170 :decoding_deltas ,
160171 :sample_sizes ,
161172 :samples_per_chunk ,
162- :composition_offsets
173+ :composition_offsets ,
174+ :chunk_offset
163175 ] ) }
164176 end )
165177
166178 # Create a samples' description list for each chunk and flatten it
167179 { samples , _acc } =
168180 chunk_offsets
169181 |> Enum . flat_map_reduce ( tracks_data , fn % { track_id: track_id } = chunk , tracks_data ->
170- { new_samples , track_data } = get_chunk_samples ( chunk , tracks_data [ track_id ] )
182+ { new_samples , { track_data , _sample_offset } } =
183+ get_chunk_samples ( chunk , tracks_data [ track_id ] )
184+
171185 { new_samples , % { tracks_data | track_id => track_data } }
172186 end )
173187
@@ -183,19 +197,28 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
183197 tracks_number: map_size ( tracks ) ,
184198 timescales: timescales ,
185199 last_dts: last_dts ,
186- sample_tables: sample_tables
200+ sample_tables: sample_tables ,
201+ mdat_iterator: mdat_beginning
187202 }
188203 end
189204
190205 defp get_chunk_samples ( chunk , track_data ) do
191- % { chunk_no: chunk_no , track_id: track_id } = chunk
206+ % { chunk_no: chunk_no , track_id: track_id , chunk_offset: chunk_offset } = chunk
192207
193208 { track_data , samples_no } = get_samples_no ( chunk_no , track_data )
194209
195- Enum . map_reduce ( 1 .. samples_no , track_data , fn _no , track_data ->
210+ Enum . map_reduce ( 1 .. samples_no , { track_data , chunk_offset } , fn _no ,
211+ { track_data , sample_offset } ->
196212 { sample , track_data } = get_sample_description ( track_data )
197- sample = Map . put ( sample , :track_id , track_id )
198- { sample , track_data }
213+
214+ sample =
215+ Map . merge ( sample , % {
216+ track_id: track_id ,
217+ chunk_offset: chunk_offset ,
218+ sample_offset: sample_offset
219+ } )
220+
221+ { sample , { track_data , sample_offset + sample . size } }
199222 end )
200223 end
201224
@@ -250,14 +273,19 @@ defmodule Membrane.MP4.Demuxer.ISOM.SamplesInfo do
250273
251274 { sample_composition_offset , composition_offsets } =
252275 case composition_offsets do
253- [ % { sample_count: 1 , sample_offset : offset } | composition_offsets ] ->
276+ [ % { sample_count: 1 , sample_composition_offset : offset } | composition_offsets ] ->
254277 { offset , composition_offsets }
255278
256- [ % { sample_count: count , sample_offset: offset } | composition_offsets ] ->
257- { offset , [ % { sample_count: count - 1 , sample_offset: offset } | composition_offsets ] }
279+ [ % { sample_count: count , sample_composition_offset: offset } | composition_offsets ] ->
280+ { offset ,
281+ [ % { sample_count: count - 1 , sample_composition_offset: offset } | composition_offsets ] }
258282 end
259283
260- { % { size: size , sample_delta: delta , sample_composition_offset: sample_composition_offset } ,
284+ { % {
285+ size: size ,
286+ sample_delta: delta ,
287+ sample_composition_offset: sample_composition_offset
288+ } ,
261289 % {
262290 track_data
263291 | decoding_deltas: deltas ,
0 commit comments