1use crate::buffer_set::*;
6use crate::elementary_stream::*;
7use crate::input_packet_stream::*;
8use crate::output_validator::*;
9use crate::{FatalError, Result};
10use fidl_fuchsia_media::*;
11use fidl_fuchsia_sysmem2::BufferCollectionConstraints;
12use fuchsia_stream_processors::*;
13use log::debug;
14use std::rc::Rc;
15
16pub type OrdinalSequence = <OrdinalPattern as IntoIterator>::IntoIter;
17
18#[derive(Debug, Clone)]
19pub struct StreamOptions {
20 pub queue_format_details: bool,
23 pub release_input_buffers_at_end: bool,
24 pub release_output_buffers_at_end: bool,
25 pub input_buffer_collection_constraints: Option<BufferCollectionConstraints>,
26 pub output_buffer_collection_constraints: Option<BufferCollectionConstraints>,
27 pub stop_after_first_output: bool,
28 pub stop_after_n_output: Option<usize>,
29 pub close_on_stop: bool,
30}
31
32impl Default for StreamOptions {
33 fn default() -> Self {
34 Self {
35 queue_format_details: true,
36 release_input_buffers_at_end: false,
37 release_output_buffers_at_end: false,
38 input_buffer_collection_constraints: None,
39 output_buffer_collection_constraints: None,
40 stop_after_first_output: false,
41 stop_after_n_output: None,
42 close_on_stop: true,
43 }
44 }
45}
46
47pub struct Stream<'a> {
48 pub format_details_version_ordinal: u64,
49 pub stream_lifetime_ordinal: u64,
50 pub input_buffer_ordinals: &'a mut OrdinalSequence,
51 pub input_packet_stream:
52 Option<InputPacketStream<Box<dyn Iterator<Item = ElementaryStreamChunk> + 'a>>>,
53 pub output_buffer_ordinals: &'a mut OrdinalSequence,
54 pub output_buffer_set: Option<BufferSet>,
55 pub current_output_format: Option<Rc<ValidStreamOutputFormat>>,
56 pub stream_processor: &'a mut StreamProcessorProxy,
57 pub stream: &'a dyn ElementaryStream,
58 pub options: StreamOptions,
59 pub output: Vec<Output>,
60 pub closing: bool,
61}
62
63pub enum StreamControlFlow {
64 Continue,
65 Stop,
66}
67
68impl<'a: 'b, 'b> Stream<'a> {
69 pub async fn start(&'b mut self) -> Result<()> {
70 if self.options.queue_format_details && self.input_packet_stream.is_some() {
71 debug!("Sending input format details for follow-up stream.");
72 self.stream_processor.queue_input_format_details(
73 self.stream_lifetime_ordinal,
74 &self.stream.format_details(self.format_details_version_ordinal),
75 )?;
76 }
77
78 self.send_available_input()?;
79
80 Ok(())
81 }
82
83 pub async fn handle_event(
84 &'b mut self,
85 event: StreamProcessorEvent,
86 ) -> Result<StreamControlFlow> {
87 match event {
88 StreamProcessorEvent::OnInputConstraints { input_constraints } => {
89 debug!("Received input constraints.");
90 debug!("Input constraints are: {:#?}", input_constraints);
91
92 let buffer_set = Box::pin(BufferSetFactory::buffer_set(
93 get_ordinal(self.input_buffer_ordinals),
94 ValidStreamBufferConstraints::try_from(input_constraints)?,
95 self.stream_processor,
96 BufferSetType::Input,
97 self.options.input_buffer_collection_constraints.clone(),
98 ))
99 .await?;
100
101 debug!("Sending input format details in response to input constraints.");
102 self.stream_processor.queue_input_format_details(
103 self.stream_lifetime_ordinal,
104 &self.stream.format_details(self.format_details_version_ordinal),
105 )?;
106
107 let chunk_stream = self.stream.capped_chunks(buffer_set.buffer_size);
108 self.input_packet_stream = Some(InputPacketStream::new(
109 buffer_set,
110 chunk_stream,
111 self.stream_lifetime_ordinal,
112 ));
113 self.send_available_input()?;
114 }
115 StreamProcessorEvent::OnOutputConstraints { output_config } => {
116 debug!("Received output constraints.");
117 debug!("Output constraints are: {:#?}", output_config);
118
119 let constraints = ValidStreamOutputConstraints::try_from(output_config)?;
120 if constraints.stream_lifetime_ordinal < self.stream_lifetime_ordinal {
121 debug!(
122 "Ignoring stale output constraints for stream {}",
123 constraints.stream_lifetime_ordinal
124 );
125 return Ok(StreamControlFlow::Continue);
126 }
127 if constraints.buffer_constraints_action_required {
128 self.output_buffer_set = Some(
129 Box::pin(BufferSetFactory::buffer_set(
130 get_ordinal(self.output_buffer_ordinals),
131 constraints.buffer_constraints,
132 self.stream_processor,
133 BufferSetType::Output,
134 self.options.output_buffer_collection_constraints.clone(),
135 ))
136 .await?,
137 );
138 }
139 }
140 StreamProcessorEvent::OnFreeInputPacket { free_input_packet } => {
141 debug!("Received freed input packet.");
142 debug!("Freed input packet is: {:#?}", free_input_packet);
143
144 let free_input_packet = ValidPacketHeader::try_from(free_input_packet)?;
145 let input_packet_stream = self.input_packet_stream.as_mut().expect(concat!(
146 "Unwrapping packet stream; ",
147 "it should be set before we ",
148 "get free input packets back."
149 ));
150 input_packet_stream.add_free_packet(free_input_packet)?;
151 if self.closing {
152 if self.all_input_packets_free() {
153 debug!("All input packets are free after OnFreeInputPacket. Stopping.");
154 return Ok(StreamControlFlow::Stop);
155 }
156 } else {
157 self.send_available_input()?;
158 }
159 }
160 StreamProcessorEvent::OnOutputFormat { output_format } => {
161 debug!("Received output format.");
162 debug!("Output format is: {:#?}", output_format);
163
164 let output_format = ValidStreamOutputFormat::try_from(output_format)?;
165 if output_format.stream_lifetime_ordinal < self.stream_lifetime_ordinal {
166 debug!(
167 "Ignoring stale output format for stream {}",
168 output_format.stream_lifetime_ordinal
169 );
170 return Ok(StreamControlFlow::Continue);
171 }
172 assert_eq!(output_format.stream_lifetime_ordinal, self.stream_lifetime_ordinal);
173 self.current_output_format = Some(Rc::new(output_format));
174 }
175 StreamProcessorEvent::OnOutputPacket {
176 output_packet,
177 error_detected_before,
178 error_detected_during,
179 } => {
180 assert!(!error_detected_before);
181 assert!(!error_detected_during);
182 debug!("Received output packet.");
183 debug!("Output packet is: {:#?}", output_packet);
184
185 let output_packet = ValidPacket::try_from(output_packet)?;
186 if output_packet.stream_lifetime_ordinal < self.stream_lifetime_ordinal {
187 debug!(
188 "Ignoring stale output packet for stream {}",
189 output_packet.stream_lifetime_ordinal
190 );
191 self.stream_processor.recycle_output_packet(&PacketHeader {
192 buffer_lifetime_ordinal: Some(output_packet.header.buffer_lifetime_ordinal),
193 packet_index: Some(output_packet.header.packet_index),
194 ..Default::default()
195 })?;
196 return Ok(StreamControlFlow::Continue);
197 }
198
199 let reached_limit = if let Some(n) = self.options.stop_after_n_output {
200 let packet_count =
201 self.output.iter().filter(|o| matches!(o, Output::Packet(_))).count();
202 packet_count >= n
203 } else {
204 false
205 };
206
207 if !reached_limit {
208 self.output.push(Output::Packet(OutputPacket {
209 data: self
210 .output_buffer_set
211 .as_ref()
212 .ok_or_else(|| {
213 FatalError(String::from(concat!(
214 "There should be an output buffer set ",
215 "if we are receiving output packets"
216 )))
217 })?
218 .read_packet(&output_packet)?,
219 format: self.current_output_format.clone().ok_or_else(|| {
220 FatalError(String::from(concat!(
221 "There should be an output format set ",
222 "if we are receiving output packets"
223 )))
224 })?,
225 packet: output_packet,
226 }));
227 }
228
229 self.stream_processor.recycle_output_packet(&PacketHeader {
230 buffer_lifetime_ordinal: Some(output_packet.header.buffer_lifetime_ordinal),
231 packet_index: Some(output_packet.header.packet_index),
232 ..Default::default()
233 })?;
234
235 let should_stop = if let Some(n) = self.options.stop_after_n_output {
236 let packet_count =
237 self.output.iter().filter(|o| matches!(o, Output::Packet(_))).count();
238 packet_count >= n
239 } else {
240 self.options.stop_after_first_output
241 };
242
243 if should_stop && !self.closing {
244 return self.close_stream_and_wait_for_free_packets().await;
245 }
246 }
247 StreamProcessorEvent::OnOutputEndOfStream {
248 stream_lifetime_ordinal,
249 error_detected_before,
250 } => {
251 assert!(!error_detected_before);
252 debug!("Received output end of stream.");
253 debug!("End of stream is for stream {}", stream_lifetime_ordinal);
254
255 if stream_lifetime_ordinal < self.stream_lifetime_ordinal {
256 debug!("Ignoring stale end of stream for stream {}", stream_lifetime_ordinal);
257 return Ok(StreamControlFlow::Continue);
258 }
259
260 self.output.push(Output::Eos { stream_lifetime_ordinal });
262 if self.options.close_on_stop {
263 self.stream_processor.close_current_stream(
264 self.stream_lifetime_ordinal,
265 self.options.release_input_buffers_at_end,
266 self.options.release_output_buffers_at_end,
267 )?;
268 self.stream_processor.sync().await?;
269 }
270
271 return Ok(StreamControlFlow::Stop);
276 }
277 e => {
278 debug!("Got other event: {:#?}", e);
279 }
280 }
281
282 Ok(StreamControlFlow::Continue)
283 }
284
285 fn send_available_input(&'b mut self) -> Result<()> {
286 if self.closing {
287 return Ok(());
288 }
289 let input_packet_stream =
290 if let Some(input_packet_stream) = self.input_packet_stream.as_mut() {
291 input_packet_stream
292 } else {
293 return Ok(());
294 };
295
296 loop {
297 match input_packet_stream.next_packet()? {
298 PacketPoll::Ready(input_packet) => {
299 debug!("Sending input packet. {:?}", input_packet.valid_length_bytes);
300 self.stream_processor.queue_input_packet(&input_packet)?;
301 }
302 PacketPoll::Eos => {
303 debug!("Sending end of stream.");
304 break Ok(self
305 .stream_processor
306 .queue_input_end_of_stream(self.stream_lifetime_ordinal)?);
307 }
308 PacketPoll::NotReady => break Ok(()),
309 }
310 }
311 }
312
313 async fn close_stream_and_wait_for_free_packets(&mut self) -> Result<StreamControlFlow> {
314 if !self.options.close_on_stop {
315 return Ok(StreamControlFlow::Stop);
316 }
317 self.closing = true;
318 debug!(
319 "Closing stream {} early, waiting for input packets to be freed...",
320 self.stream_lifetime_ordinal
321 );
322 self.stream_processor.close_current_stream(
323 self.stream_lifetime_ordinal,
324 self.options.release_input_buffers_at_end,
325 self.options.release_output_buffers_at_end,
326 )?;
327 self.stream_processor.sync().await?;
328
329 if self.all_input_packets_free() {
330 debug!("All input packets are already free. Stopping.");
331 Ok(StreamControlFlow::Stop)
332 } else {
333 Ok(StreamControlFlow::Continue)
334 }
335 }
336
337 fn all_input_packets_free(&self) -> bool {
338 self.input_packet_stream.as_ref().map(|s| s.all_packets_free()).unwrap_or(true)
339 }
340}