Skip to main content

fuchsia_audio_codec/
stream_processor.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::{Context as _, Error, format_err};
6use fidl::endpoints::ClientEnd;
7use fidl_fuchsia_media::*;
8use fidl_fuchsia_mediacodec::*;
9use fidl_fuchsia_sysmem2::*;
10use fuchsia_stream_processors::*;
11use fuchsia_sync::{Mutex, RwLock};
12use futures::future::{MaybeDone, maybe_done};
13use futures::io::{self, AsyncWrite};
14use futures::stream::{FusedStream, Stream};
15use futures::task::{Context, Poll, Waker};
16use futures::{Future, StreamExt, ready};
17use log::{trace, warn};
18use std::collections::{HashSet, VecDeque};
19use std::mem;
20use std::pin::Pin;
21use std::sync::Arc;
22use zx::StatusExt;
23
24use crate::buffer_collection_constraints::buffer_collection_constraints_default;
25use crate::sysmem_allocator::{BufferName, SysmemAllocatedBuffers, SysmemAllocation};
26
27fn fidl_error_to_io_error(e: fidl::Error) -> io::Error {
28    io::Error::other(format_err!("Fidl Error: {}", e))
29}
30
31#[derive(Debug)]
32/// Listener is a three-valued Option that captures the waker that a listener needs to be woken
33/// upon when it polls the future instead of at registration time.
34enum Listener {
35    /// No one is listening.
36    None,
37    /// Someone is listening, but either have been woken and not repolled, or never polled yet.
38    New,
39    /// Someone is listening, and can be woken with the waker.
40    Some(Waker),
41}
42
43impl Listener {
44    /// Adds a waker to be awoken with `Listener::wake`.
45    /// Panics if no one is listening.
46    fn register(&mut self, waker: Waker) {
47        *self = match mem::replace(self, Listener::None) {
48            Listener::None => panic!("Polled a listener with no pollers"),
49            _ => Listener::Some(waker),
50        };
51    }
52
53    /// If a listener has polled, wake the listener and replace it with New.
54    /// Noop if no one has registered.
55    fn wake(&mut self) {
56        if let Listener::None = self {
57            return;
58        }
59        match mem::replace(self, Listener::New) {
60            Listener::None => panic!("Should have been polled"),
61            Listener::Some(waker) => waker.wake(),
62            Listener::New => {}
63        }
64    }
65
66    /// Get a reference to the waker, if there is one waiting.
67    fn waker(&self) -> Option<&Waker> {
68        if let Listener::Some(waker) = self { Some(waker) } else { None }
69    }
70}
71
72impl Default for Listener {
73    fn default() -> Self {
74        Listener::None
75    }
76}
77
78/// A queue of encoded packets, to be sent to the `listener` when it polls next.
79struct OutputQueue {
80    /// The listener. Woken when a packet arrives after a previous poll() returned Pending.
81    listener: Listener,
82    /// A queue of encoded packets to be delivered to the receiver.
83    queue: VecDeque<Packet>,
84    /// True when the stream has received an end-of-stream message. The stream will return None
85    /// after the `queue` is empty.
86    ended: bool,
87}
88
89impl OutputQueue {
90    /// Adds a packet to the queue and wakes the listener if necessary.
91    fn enqueue(&mut self, packet: Packet) {
92        self.queue.push_back(packet);
93        self.listener.wake();
94    }
95
96    /// Signals the end of the stream has happened.
97    /// Wakes the listener if necessary.
98    fn mark_ended(&mut self) {
99        self.ended = true;
100        self.listener.wake();
101    }
102
103    fn waker(&self) -> Option<&Waker> {
104        self.listener.waker()
105    }
106
107    /// Wakes the listener so that it will repoll, if it is waiting.
108    fn wake(&mut self) {
109        self.listener.wake();
110    }
111}
112
113impl Default for OutputQueue {
114    fn default() -> Self {
115        OutputQueue { listener: Listener::default(), queue: VecDeque::new(), ended: false }
116    }
117}
118
119impl Stream for OutputQueue {
120    type Item = Packet;
121
122    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
123        match self.queue.pop_front() {
124            Some(packet) => Poll::Ready(Some(packet)),
125            None if self.ended => Poll::Ready(None),
126            None => {
127                self.listener.register(cx.waker().clone());
128                Poll::Pending
129            }
130        }
131    }
132}
133
134// The minimum specified by codec is too small to contain the typical pcm frame chunk size for the
135// encoder case (1024). Increase to a reasonable amount.
136const MIN_INPUT_BUFFER_SIZE: u32 = 4096;
137// Go with codec default for output, for frame alignment.
138const DEFAULT_MIN_OUTPUT_BUFFER_SIZE: u32 = 0;
139// The CVSD encoder's minimum output frame size is 1 byte (16 bytes of 64kHz 16-bit mono PCM at
140// 16:1 compression), and it fills each output buffer to capacity before emitting an output packet.
141// HFP inband SCO expects output packets in multiples of the 60-byte SCO packet size (7.5ms of
142// CVSD audio).
143const CVSD_MIN_OUTPUT_BUFFER_SIZE: u32 = 60;
144
145/// Index of an input buffer to be shared between the client and the StreamProcessor.
146#[derive(PartialEq, Eq, Hash, Clone, Debug)]
147struct InputBufferIndex(u32);
148
149/// The StreamProcessorInner handles the events that come from the StreamProcessor, mostly related
150/// to setup of the buffers and handling the output packets as they arrive.
151struct StreamProcessorInner {
152    /// The proxy to the stream processor.
153    processor: StreamProcessorProxy,
154    /// The proxy to the sysmem allocator.
155    sysmem_client: AllocatorProxy,
156    /// The event stream from the StreamProcessor.  We handle these internally.
157    events: StreamProcessorEventStream,
158    /// The size in bytes of each input packet
159    input_packet_size: u64,
160    /// The set of input buffers that are available for writing by the client, without the one
161    /// possibly being used by the input_cursor.
162    client_owned: HashSet<InputBufferIndex>,
163    /// A cursor on the next input buffer location to be written to when new input data arrives.
164    input_cursor: Option<(InputBufferIndex, u64)>,
165    /// An queue of the indexes of output buffers that have been filled by the processor and a
166    /// waiter if someone is waiting on it.
167    /// Also holds the output waker, if it is registered.
168    output_queue: Mutex<OutputQueue>,
169    /// Waker that is waiting on input to be ready.
170    input_waker: Option<Waker>,
171    /// Allocation for the input buffers.
172    input_allocation: MaybeDone<SysmemAllocation>,
173    /// Allocation for the output buffers.
174    output_allocation: MaybeDone<SysmemAllocation>,
175    /// The minimum size of the output buffers.
176    min_output_buffer_size: u32,
177}
178
179impl StreamProcessorInner {
180    /// Handles an event from the StreamProcessor. A number of these events come on stream start to
181    /// setup the input and output buffers, and from then on the output packets and end of stream
182    /// marker, and the input packets are marked as usable after they are processed.
183    fn handle_event(&mut self, evt: StreamProcessorEvent) -> Result<(), Error> {
184        match evt {
185            StreamProcessorEvent::OnInputConstraints { input_constraints } => {
186                let _input_constraints = ValidStreamBufferConstraints::try_from(input_constraints)?;
187                let buffer_constraints =
188                    Self::buffer_constraints_from_min_size(MIN_INPUT_BUFFER_SIZE);
189                let processor = self.processor.clone();
190                let mut partial_settings = Self::partial_settings();
191                let token_fn = move |token: ClientEnd<BufferCollectionTokenMarker>| {
192                    // A sysmem token channel serves both sysmem(1) and sysmem2 token protocols, so
193                    // we can convert here until StreamProcessor has a sysmem2 token field.
194                    partial_settings.sysmem_token =
195                        Some(ClientEnd::<fidl_fuchsia_sysmem::BufferCollectionTokenMarker>::new(
196                            token.into_channel(),
197                        ));
198                    // FIDL failures will be caught via the request stream.
199                    if let Err(e) = processor.set_input_buffer_partial_settings(partial_settings) {
200                        warn!("Couldn't set input buffer settings: {:?}", e);
201                    }
202                };
203                self.input_allocation = maybe_done(SysmemAllocation::allocate(
204                    self.sysmem_client.clone(),
205                    BufferName { name: "StreamProcessorInput", priority: 1 },
206                    None,
207                    buffer_constraints,
208                    token_fn,
209                )?);
210            }
211            StreamProcessorEvent::OnOutputConstraints { output_config } => {
212                let output_constraints = ValidStreamOutputConstraints::try_from(output_config)?;
213                if !output_constraints.buffer_constraints_action_required {
214                    return Ok(());
215                }
216                let buffer_constraints =
217                    Self::buffer_constraints_from_min_size(self.min_output_buffer_size);
218                let processor = self.processor.clone();
219                let mut partial_settings = Self::partial_settings();
220                let token_fn = move |token: ClientEnd<BufferCollectionTokenMarker>| {
221                    // A sysmem token channel serves both sysmem(1) and sysmem2 token protocols, so
222                    // we can convert here until StreamProcessor has a sysmem2 token field.
223                    partial_settings.sysmem_token =
224                        Some(ClientEnd::<fidl_fuchsia_sysmem::BufferCollectionTokenMarker>::new(
225                            token.into_channel(),
226                        ));
227                    // FIDL failures will be caught via the request stream.
228                    if let Err(e) = processor.set_output_buffer_partial_settings(partial_settings) {
229                        warn!("Couldn't set output buffer settings: {:?}", e);
230                    }
231                };
232
233                self.output_allocation = maybe_done(SysmemAllocation::allocate(
234                    self.sysmem_client.clone(),
235                    BufferName { name: "StreamProcessorOutput", priority: 1 },
236                    None,
237                    buffer_constraints,
238                    token_fn,
239                )?);
240            }
241            StreamProcessorEvent::OnOutputPacket { output_packet, .. } => {
242                let mut lock = self.output_queue.lock();
243                lock.enqueue(output_packet);
244            }
245            StreamProcessorEvent::OnFreeInputPacket {
246                free_input_packet: PacketHeader { packet_index: Some(idx), .. },
247            } => {
248                if !self.client_owned.insert(InputBufferIndex(idx)) {
249                    warn!("Freed an input packet that was already freed: {:?}", idx);
250                }
251                self.setup_input_cursor();
252            }
253            StreamProcessorEvent::OnOutputEndOfStream { .. } => {
254                let mut lock = self.output_queue.lock();
255                lock.mark_ended();
256            }
257            StreamProcessorEvent::OnOutputFormat { .. } => {}
258            e => trace!("Unhandled stream processor event: {:?}", e),
259        }
260        Ok(())
261    }
262
263    /// Process one event, and return Poll::Ready if the item has been processed,
264    /// and Poll::Pending if no event has been processed and the waker will be woken if
265    /// another event happens.
266    fn process_event(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
267        match ready!(self.events.poll_next_unpin(cx)) {
268            Some(Err(e)) => Poll::Ready(Err(e.into())),
269            Some(Ok(event)) => Poll::Ready(self.handle_event(event)),
270            None => Poll::Ready(Err(format_err!("Client disconnected"))),
271        }
272    }
273
274    fn buffer_constraints_from_min_size(min_buffer_size: u32) -> BufferCollectionConstraints {
275        BufferCollectionConstraints {
276            buffer_memory_constraints: Some(BufferMemoryConstraints {
277                min_size_bytes: Some(min_buffer_size as u64),
278                ..Default::default()
279            }),
280            ..buffer_collection_constraints_default()
281        }
282    }
283
284    fn partial_settings() -> StreamBufferPartialSettings {
285        StreamBufferPartialSettings {
286            buffer_lifetime_ordinal: Some(1),
287            buffer_constraints_version_ordinal: Some(1),
288            sysmem_token: None,
289            ..Default::default()
290        }
291    }
292
293    fn input_buffers(&mut self) -> &mut SysmemAllocatedBuffers {
294        Pin::new(&mut self.input_allocation)
295            .output_mut()
296            .expect("allocation completed")
297            .as_mut()
298            .expect("succcessful allocation")
299    }
300
301    fn output_buffers(&mut self) -> &mut SysmemAllocatedBuffers {
302        Pin::new(&mut self.output_allocation)
303            .output_mut()
304            .expect("allocation completed")
305            .as_mut()
306            .expect("succcessful allocation")
307    }
308
309    /// Called when the input_allocation future finishes.
310    /// Takes the buffers out of the allocator, and sets up the input cursor to accept data.
311    fn input_allocation_complete(&mut self) -> Result<(), Error> {
312        let _ = Pin::new(&mut self.input_allocation)
313            .output_mut()
314            .ok_or_else(|| format_err!("allocation isn't complete"))?;
315
316        let settings = self.input_buffers().settings();
317        self.input_packet_size = (*settings.size_bytes.as_ref().unwrap()).try_into()?;
318        let buffer_count = self.input_buffers().len();
319        for i in 0..buffer_count {
320            let _ = self.client_owned.insert(InputBufferIndex(i.try_into()?));
321        }
322        // allocation is complete, and we can write to the input.
323        self.setup_input_cursor();
324        Ok(())
325    }
326
327    /// Called when the output allocation future finishes.
328    /// Takes the buffers out of the allocator, and sets up the output buffers for retrieval of output,
329    /// signaling to the processor that the output buffers are set.
330    fn output_allocation_complete(&mut self) -> Result<(), Error> {
331        let _ = Pin::new(&mut self.output_allocation)
332            .output_mut()
333            .ok_or_else(|| format_err!("allocation isn't complete"))?;
334        self.processor
335            .complete_output_buffer_partial_settings(/*buffer_lifetime_ordinal=*/ 1)
336            .context("setting output buffer settings")?;
337        Ok(())
338    }
339
340    /// Poll any of the allocations that are waiting to complete, returning Pending if
341    /// any are still waiting to finish, and Ready if one has failed or both have completed.
342    fn poll_buffer_allocation(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
343        if let MaybeDone::Future(_) = self.input_allocation {
344            match Pin::new(&mut self.input_allocation).poll(cx) {
345                Poll::Ready(()) => {
346                    if let Err(e) = self.input_allocation_complete() {
347                        return Poll::Ready(Err(e));
348                    }
349                }
350                Poll::Pending => {}
351            };
352        }
353        if let MaybeDone::Future(_) = self.output_allocation {
354            match Pin::new(&mut self.output_allocation).poll(cx) {
355                Poll::Ready(()) => {
356                    if let Err(e) = self.output_allocation_complete() {
357                        return Poll::Ready(Err(e));
358                    }
359                }
360                Poll::Pending => {}
361            };
362        }
363        Poll::Pending
364    }
365
366    /// Provides the current registered waiting context with priority given to the output waker.
367    fn waiting_waker(&self) -> Option<Waker> {
368        match (self.output_queue.lock().waker(), &self.input_waker) {
369            // No one is waiting.
370            (None, None) => None,
371            (Some(waker), _) => Some(waker.clone()),
372            (_, Some(waker)) => Some(waker.clone()),
373        }
374    }
375
376    /// Process all the events that are currently available from the StreamProcessor and Allocators,
377    /// waking any known waker to be woken when another event arrives.
378    /// Returns Ok(()) if this was accomplished or Err() if an error occurred while processing.
379    fn poll_events(&mut self) -> Result<(), Error> {
380        let waker = loop {
381            let waker = match self.waiting_waker() {
382                // No one still needs to be woken.  This means all the wakers have been awoke,
383                // and will repoll.
384                None => return Ok(()),
385                Some(waker) => waker,
386            };
387            match self.process_event(&mut Context::from_waker(&waker)) {
388                Poll::Pending => break waker,
389                Poll::Ready(Err(e)) => {
390                    warn!("Stream processing error: {:?}", e);
391                    return Err(e.into());
392                }
393                // Didn't set the waker to be awoken, so let's try again.
394                Poll::Ready(Ok(())) => {}
395            }
396        };
397
398        if let Poll::Ready(Err(e)) = self.poll_buffer_allocation(&mut Context::from_waker(&waker)) {
399            warn!("Stream buffer allocation error: {:?}", e);
400            return Err(e.into());
401        }
402        Ok(())
403    }
404
405    fn wake_output(&mut self) {
406        self.output_queue.lock().wake();
407    }
408
409    fn wake_input(&mut self) {
410        if let Some(w) = self.input_waker.take() {
411            w.wake();
412        }
413    }
414
415    /// Attempts to set up a new input cursor, out of the current set of client owned input buffers.
416    /// If the cursor is already set, this does nothing.
417    fn setup_input_cursor(&mut self) {
418        if self.input_cursor.is_some() {
419            // Nothing to be done
420            return;
421        }
422        let next_idx = match self.client_owned.iter().next() {
423            None => return,
424            Some(idx) => idx.clone(),
425        };
426        let _ = self.client_owned.remove(&next_idx);
427        self.input_cursor = Some((next_idx, 0));
428        self.wake_input();
429    }
430
431    /// Reads an output packet from the output buffers, and marks the packets as recycled so the
432    /// output buffer can be reused. Allocates a new vector to hold the data.
433    fn read_output_packet(&mut self, packet: Packet) -> Result<Vec<u8>, Error> {
434        let packet = ValidPacket::try_from(packet)?;
435
436        let output_size = packet.valid_length_bytes as usize;
437        let offset = packet.start_offset as u64;
438        let mut output = vec![0; output_size];
439        let buf_idx = packet.buffer_index;
440        let vmo = self.output_buffers().get_mut(buf_idx).expect("output vmo should exist");
441        vmo.read(&mut output, offset)?;
442        self.processor.recycle_output_packet(&packet.header.into())?;
443        Ok(output)
444    }
445}
446
447/// Struct representing a CodecFactory .
448/// Input sent to the encoder via `StreamProcessor::write_bytes` is queued for delivery, and delivered
449/// whenever a packet is full or `StreamProcessor::send_packet` is called.  Output can be retrieved using
450/// an `StreamProcessorStream` from `StreamProcessor::take_output_stream`.
451pub struct StreamProcessor {
452    inner: Arc<RwLock<StreamProcessorInner>>,
453}
454
455/// An StreamProcessorStream is a Stream of processed data from a stream processor.
456/// Returned from `StreamProcessor::take_output_stream`.
457pub struct StreamProcessorOutputStream {
458    inner: Arc<RwLock<StreamProcessorInner>>,
459}
460
461impl StreamProcessor {
462    /// Create a new StreamProcessor given the proxy.
463    /// Takes the event stream of the proxy.
464    fn create(
465        processor: StreamProcessorProxy,
466        sysmem_client: AllocatorProxy,
467        min_output_buffer_size: u32,
468    ) -> Self {
469        let events = processor.take_event_stream();
470        Self {
471            inner: Arc::new(RwLock::new(StreamProcessorInner {
472                processor,
473                sysmem_client,
474                events,
475                input_packet_size: 0,
476                client_owned: HashSet::new(),
477                input_cursor: None,
478                output_queue: Default::default(),
479                input_waker: None,
480                input_allocation: maybe_done(SysmemAllocation::pending()),
481                output_allocation: maybe_done(SysmemAllocation::pending()),
482                min_output_buffer_size,
483            })),
484        }
485    }
486
487    /// Create a new StreamProcessor encoder, with the given `input_domain` and `encoder_settings`.  See
488    /// stream_processor.fidl for descriptions of these parameters.  This is only meant for audio
489    /// encoding.
490    pub fn create_encoder(
491        input_domain: DomainFormat,
492        encoder_settings: EncoderSettings,
493    ) -> Result<StreamProcessor, Error> {
494        let sysmem_client = fuchsia_component::client::connect_to_protocol::<AllocatorMarker>()
495            .context("Connecting to sysmem")?;
496
497        let min_output_buffer_size = match &encoder_settings {
498            EncoderSettings::Cvsd(_) => CVSD_MIN_OUTPUT_BUFFER_SIZE,
499            _ => DEFAULT_MIN_OUTPUT_BUFFER_SIZE,
500        };
501
502        let format_details = FormatDetails {
503            domain: Some(input_domain),
504            encoder_settings: Some(encoder_settings),
505            format_details_version_ordinal: Some(1),
506            mime_type: Some("audio/pcm".to_string()),
507            oob_bytes: None,
508            pass_through_parameters: None,
509            timebase: None,
510            ..Default::default()
511        };
512
513        let encoder_params = CreateEncoderParams {
514            input_details: Some(format_details),
515            require_hw: Some(false),
516            ..Default::default()
517        };
518
519        let codec_svc = fuchsia_component::client::connect_to_protocol::<CodecFactoryMarker>()
520            .context("Failed to connect to Codec Factory")?;
521
522        let (processor, stream_processor_serverend) = fidl::endpoints::create_proxy();
523
524        codec_svc.create_encoder(&encoder_params, stream_processor_serverend)?;
525
526        Ok(StreamProcessor::create(processor, sysmem_client, min_output_buffer_size))
527    }
528
529    /// Create a new StreamProcessor decoder, with the given `mime_type` and optional `oob_bytes`.  See
530    /// stream_processor.fidl for descriptions of these parameters.  This is only meant for audio
531    /// decoding.
532    pub fn create_decoder(
533        mime_type: &str,
534        oob_bytes: Option<Vec<u8>>,
535    ) -> Result<StreamProcessor, Error> {
536        let sysmem_client = fuchsia_component::client::connect_to_protocol::<AllocatorMarker>()
537            .context("Connecting to sysmem")?;
538
539        let format_details = FormatDetails {
540            mime_type: Some(mime_type.to_string()),
541            oob_bytes: oob_bytes,
542            format_details_version_ordinal: Some(1),
543            encoder_settings: None,
544            domain: None,
545            pass_through_parameters: None,
546            timebase: None,
547            ..Default::default()
548        };
549
550        let decoder_params = CreateDecoderParams {
551            input_details: Some(format_details),
552            permit_lack_of_split_header_handling: Some(true),
553            ..Default::default()
554        };
555
556        let codec_svc = fuchsia_component::client::connect_to_protocol::<CodecFactoryMarker>()
557            .context("Failed to connect to Codec Factory")?;
558
559        let (processor, stream_processor_serverend) = fidl::endpoints::create_proxy();
560
561        codec_svc.create_decoder(&decoder_params, stream_processor_serverend)?;
562
563        Ok(StreamProcessor::create(processor, sysmem_client, DEFAULT_MIN_OUTPUT_BUFFER_SIZE))
564    }
565
566    /// Take a stream object which will produce the output of the processor.
567    /// Only one StreamProcessorOutputStream object can exist at a time, and this will return an Error if it is
568    /// already taken.
569    pub fn take_output_stream(&mut self) -> Result<StreamProcessorOutputStream, Error> {
570        {
571            let read = self.inner.read();
572            let mut lock = read.output_queue.lock();
573            if let Listener::None = lock.listener {
574                lock.listener = Listener::New;
575            } else {
576                return Err(format_err!("Output stream already taken"));
577            }
578        }
579        Ok(StreamProcessorOutputStream { inner: self.inner.clone() })
580    }
581
582    /// Deliver input to the stream processor.  Returns the number of bytes delivered.
583    fn write_bytes(&mut self, bytes: &[u8]) -> Result<usize, io::Error> {
584        let mut bytes_idx = 0;
585        while bytes.len() > bytes_idx {
586            {
587                let mut write = self.inner.write();
588                let (idx, size) = match write.input_cursor.take() {
589                    None => return Ok(bytes_idx),
590                    Some(x) => x,
591                };
592                let space_left = write.input_packet_size - size;
593                let left_to_write = bytes.len() - bytes_idx;
594                let buffer_vmo = write.input_buffers().get_mut(idx.0).expect("need buffer vmo");
595                if space_left as usize > left_to_write {
596                    let write_buf = &bytes[bytes_idx..];
597                    let write_len = write_buf.len();
598                    buffer_vmo.write(write_buf, size).map_err(|s| s.into_io_error())?;
599                    bytes_idx += write_len;
600                    write.input_cursor = Some((idx, size + write_len as u64));
601                    assert!(bytes.len() == bytes_idx);
602                    return Ok(bytes_idx);
603                }
604                let end_idx = bytes_idx + space_left as usize;
605                let write_buf = &bytes[bytes_idx..end_idx];
606                let write_len = write_buf.len();
607                buffer_vmo.write(write_buf, size).map_err(|s| s.into_io_error())?;
608                bytes_idx += write_len;
609                // this buffer is done, ship it!
610                assert_eq!(size + write_len as u64, write.input_packet_size);
611                write.input_cursor = Some((idx, write.input_packet_size));
612            }
613            self.send_packet()?;
614        }
615        Ok(bytes_idx)
616    }
617
618    /// Flush the input buffer to the processor, relinquishing the ownership of the buffer
619    /// currently in the input cursor, and picking a new input buffer.  If there is no input
620    /// buffer left, the input cursor is left as None.
621    pub fn send_packet(&mut self) -> Result<(), io::Error> {
622        let mut write = self.inner.write();
623        if write.input_cursor.is_none() {
624            // Nothing to flush, nothing can have been written to an empty input cursor.
625            return Ok(());
626        }
627        let (idx, size) = write.input_cursor.take().expect("input cursor is none");
628        if size == 0 {
629            // Can't send empty packet to processor.
630            write.input_cursor = Some((idx, size));
631            return Ok(());
632        }
633        let packet = Packet {
634            header: Some(PacketHeader {
635                buffer_lifetime_ordinal: Some(1),
636                packet_index: Some(idx.0),
637                ..Default::default()
638            }),
639            buffer_index: Some(idx.0),
640            stream_lifetime_ordinal: Some(1),
641            start_offset: Some(0),
642            valid_length_bytes: Some(size as u32),
643            start_access_unit: Some(true),
644            known_end_access_unit: Some(true),
645            ..Default::default()
646        };
647        write.processor.queue_input_packet(&packet).map_err(fidl_error_to_io_error)?;
648        // pick another buffer for the input cursor
649        write.setup_input_cursor();
650        Ok(())
651    }
652
653    /// Test whether it is possible to write to the StreamProcessor. If there are no input buffers
654    /// available, returns Poll::Pending and arranges for the input task to receive a
655    /// notification when an input buffer may be available or the encoder is closed.
656    fn poll_writable(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
657        let mut write = self.inner.write();
658        // Drop the current input waker, since we have a new one.
659        // If the output waker is set, it should already be queued to be woken for the codec.
660        write.input_waker = None;
661        if write.input_cursor.is_some() {
662            return Poll::Ready(Ok(()));
663        }
664        write.input_waker = Some(cx.waker().clone());
665        // This can:
666        //  - wake the input waker (somehow received a input packet)
667        //  - poll with the output waker, setting it up to be woken
668        //  - poll with the input waker to be woken
669        if let Err(e) = write.poll_events() {
670            return Poll::Ready(Err(io::Error::other(e)));
671        }
672        Poll::Pending
673    }
674
675    pub fn close(&mut self) -> Result<(), io::Error> {
676        self.send_packet()?;
677
678        let mut write = self.inner.write();
679
680        write.processor.queue_input_end_of_stream(1).map_err(fidl_error_to_io_error)?;
681        // TODO: indicate this another way so that we can send an error if someone tries to write
682        // it after it's closed.
683        write.input_cursor = None;
684        write.wake_input();
685        write.wake_output();
686        Ok(())
687    }
688}
689
690impl AsyncWrite for StreamProcessor {
691    fn poll_write(
692        mut self: Pin<&mut Self>,
693        cx: &mut Context<'_>,
694        buf: &[u8],
695    ) -> Poll<io::Result<usize>> {
696        ready!(self.poll_writable(cx))?;
697        match self.write_bytes(buf) {
698            Ok(written) => Poll::Ready(Ok(written)),
699            Err(e) => Poll::Ready(Err(e.into())),
700        }
701    }
702
703    fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
704        Poll::Ready(self.send_packet())
705    }
706
707    fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
708        Poll::Ready(self.send_packet())
709    }
710}
711
712impl Stream for StreamProcessorOutputStream {
713    type Item = Result<Vec<u8>, Error>;
714
715    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
716        let mut write = self.inner.write();
717        // If we have a item ready, just return it.
718        let packet = {
719            let mut queue = write.output_queue.lock();
720            match queue.poll_next_unpin(cx) {
721                Poll::Ready(Some(packet)) => Some(Some(packet)),
722                Poll::Ready(None) => Some(None),
723                Poll::Pending => {
724                    // The waker has been set for when the queue gets data.
725                    // We also need to set the same waker if an event happens.
726                    None
727                }
728            }
729        };
730        // We always need to set a waker for the events loop (this may be the same waker as above,
731        // or the input waker if the stream returned a packet)
732        if let Err(e) = write.poll_events() {
733            return Poll::Ready(Some(Err(e.into())));
734        }
735        match packet {
736            Some(Some(packet)) => Poll::Ready(Some(write.read_output_packet(packet))),
737            Some(None) => Poll::Ready(None),
738            None => Poll::Pending,
739        }
740    }
741}
742
743impl FusedStream for StreamProcessorOutputStream {
744    fn is_terminated(&self) -> bool {
745        self.inner.read().output_queue.lock().ended
746    }
747}
748
749#[cfg(test)]
750mod tests {
751    use super::*;
752
753    use async_test_helpers::run_while;
754    use byteorder::{ByteOrder, NativeEndian};
755    use fixture::fixture;
756    use fuchsia_async as fasync;
757    use futures::FutureExt;
758    use futures::io::AsyncWriteExt;
759    use futures_test::task::new_count_waker;
760    use sha2::{Digest as _, Sha256};
761    use std::fs::File;
762    use std::io::{Read, Write};
763    use std::pin::pin;
764
765    use stream_processor_test::ExpectedDigest;
766
767    const PCM_SAMPLE_SIZE: usize = 2;
768
769    #[derive(Clone, Debug)]
770    pub struct PcmAudio {
771        pcm_format: PcmFormat,
772        buffer: Vec<u8>,
773    }
774
775    impl PcmAudio {
776        pub fn create_saw_wave(pcm_format: PcmFormat, frame_count: usize) -> Self {
777            const FREQUENCY: f32 = 20.0;
778            const AMPLITUDE: f32 = 0.2;
779
780            let pcm_frame_size = PCM_SAMPLE_SIZE * pcm_format.channel_map.len();
781            let samples_per_frame = pcm_format.channel_map.len();
782            let sample_count = frame_count * samples_per_frame;
783
784            let mut buffer = vec![0; frame_count * pcm_frame_size];
785
786            for i in 0..sample_count {
787                let frame = (i / samples_per_frame) as f32;
788                let value =
789                    ((frame * FREQUENCY / (pcm_format.frames_per_second as f32)) % 1.0) * AMPLITUDE;
790                let sample = (value * i16::MAX as f32) as i16;
791
792                let mut sample_bytes = [0; std::mem::size_of::<i16>()];
793                NativeEndian::write_i16(&mut sample_bytes, sample);
794
795                let offset = i * PCM_SAMPLE_SIZE;
796                buffer[offset] = sample_bytes[0];
797                buffer[offset + 1] = sample_bytes[1];
798            }
799
800            Self { pcm_format, buffer }
801        }
802
803        pub fn frame_size(&self) -> usize {
804            self.pcm_format.channel_map.len() * PCM_SAMPLE_SIZE
805        }
806    }
807
808    // Note: stolen from audio_encoder_test, update to stream_processor_test lib when this gets
809    // moved.
810    pub struct BytesValidator {
811        pub output_file: Option<&'static str>,
812        pub expected_digest: ExpectedDigest,
813    }
814
815    impl BytesValidator {
816        fn write_and_hash(&self, mut file: impl Write, bytes: &[u8]) -> Result<(), Error> {
817            let mut hasher = Sha256::default();
818
819            file.write_all(&bytes)?;
820            hasher.update(&bytes);
821
822            let digest: [u8; 32] = hasher.finalize().into();
823            if self.expected_digest.bytes != digest {
824                return Err(format_err!(
825                    "Expected {}; got {}",
826                    self.expected_digest,
827                    hex::encode(digest)
828                ))
829                .into();
830            }
831
832            Ok(())
833        }
834
835        fn output_file(&self) -> Result<impl Write, Error> {
836            Ok(if let Some(file) = self.output_file {
837                Box::new(std::fs::File::create(file)?) as Box<dyn Write>
838            } else {
839                Box::new(std::io::sink()) as Box<dyn Write>
840            })
841        }
842
843        fn validate(&self, bytes: &[u8]) -> Result<(), Error> {
844            self.write_and_hash(self.output_file()?, &bytes)
845        }
846    }
847
848    #[fuchsia::test]
849    fn encode_sbc() {
850        let mut exec = fasync::TestExecutor::new();
851
852        let pcm_format = PcmFormat {
853            pcm_mode: AudioPcmMode::Linear,
854            bits_per_sample: 16,
855            frames_per_second: 44100,
856            channel_map: vec![AudioChannelId::Cf],
857        };
858
859        let sub_bands = SbcSubBands::SubBands4;
860        let block_count = SbcBlockCount::BlockCount8;
861
862        let input_frames = 3000;
863
864        let pcm_audio = PcmAudio::create_saw_wave(pcm_format.clone(), input_frames);
865
866        let sbc_encoder_settings = EncoderSettings::Sbc(SbcEncoderSettings {
867            sub_bands,
868            block_count,
869            allocation: SbcAllocation::AllocLoudness,
870            channel_mode: SbcChannelMode::Mono,
871            bit_pool: 59, // Recommended from the SBC spec for these parameters.
872        });
873
874        let input_domain = DomainFormat::Audio(AudioFormat::Uncompressed(
875            AudioUncompressedFormat::Pcm(pcm_format),
876        ));
877
878        let mut encoder = StreamProcessor::create_encoder(input_domain, sbc_encoder_settings)
879            .expect("to create Encoder");
880
881        let frames_per_packet: usize = 8; // Randomly chosen by fair d10 roll.
882        let packet_size = pcm_audio.frame_size() * frames_per_packet;
883        let mut packets = pcm_audio.buffer.as_slice().chunks(packet_size);
884        let first_packet = packets.next().unwrap();
885
886        // Write an initial frame to the encoder.
887        // This is required to get past allocating the input/output buffers.
888        let written =
889            exec.run_singlethreaded(&mut encoder.write(first_packet)).expect("successful write");
890        assert_eq!(written, first_packet.len());
891
892        let mut encoded_stream = encoder.take_output_stream().expect("Stream should be taken");
893
894        // Shouldn't be able to take the stream twice
895        assert!(encoder.take_output_stream().is_err());
896
897        // Polling the encoded stream before the encoder has started up should wake it when
898        // output starts happening, set up the poll here.
899        let encoded_fut = pin!(encoded_stream.next());
900
901        let (waker, encoder_fut_wake_count) = new_count_waker();
902        let mut counting_ctx = Context::from_waker(&waker);
903
904        assert!(encoded_fut.poll(&mut counting_ctx).is_pending());
905
906        let mut frames_sent = first_packet.len() / pcm_audio.frame_size();
907
908        for packet in packets {
909            let mut written_fut = encoder.write(&packet);
910
911            let written_bytes =
912                exec.run_singlethreaded(&mut written_fut).expect("to write to encoder");
913
914            assert_eq!(packet.len(), written_bytes);
915            frames_sent += packet.len() / pcm_audio.frame_size();
916        }
917
918        encoder.close().expect("stream should always be closable");
919
920        assert_eq!(input_frames, frames_sent);
921
922        // When an unprocessed event has happened on the stream, even if intervening events have been
923        // procesed by the input processes, it should wake the output future to process the events.
924        let woke_count = encoder_fut_wake_count.get();
925        while encoder_fut_wake_count.get() == woke_count {
926            let _ = exec.run_until_stalled(&mut futures::future::pending::<()>());
927        }
928        assert_eq!(encoder_fut_wake_count.get(), woke_count + 1);
929
930        // Get data from the output now.
931        let mut encoded = Vec::new();
932
933        loop {
934            let mut encoded_fut = encoded_stream.next();
935
936            match exec.run_singlethreaded(&mut encoded_fut) {
937                Some(Ok(enc_data)) => {
938                    assert!(!enc_data.is_empty());
939                    encoded.extend_from_slice(&enc_data);
940                }
941                Some(Err(e)) => {
942                    panic!("Unexpected error when polling encoded data: {}", e);
943                }
944                None => {
945                    break;
946                }
947            }
948        }
949
950        // Match the encoded data to the known hash.
951        let expected_digest = ExpectedDigest::new(
952            "Sbc: 44.1kHz/Loudness/Mono/bitpool 56/blocks 8/subbands 4",
953            "5c65a88bda3f132538966d87df34aa8675f85c9892b7f9f5571f76f3c7813562",
954        );
955        let hash_validator = BytesValidator { output_file: None, expected_digest };
956
957        assert_eq!(6110, encoded.len(), "Encoded size should be equal");
958
959        let validated = hash_validator.validate(encoded.as_slice());
960        assert!(validated.is_ok(), "Failed hash: {:?}", validated);
961    }
962
963    fn fix_sbc_test_file<F>(_name: &str, test: F)
964    where
965        F: FnOnce(Vec<u8>) -> (),
966    {
967        const SBC_TEST_FILE: &str = "/pkg/data/s16le44100mono.sbc";
968
969        let mut sbc_data = Vec::new();
970        let _ = File::open(SBC_TEST_FILE)
971            .expect("open test file")
972            .read_to_end(&mut sbc_data)
973            .expect("read test file");
974
975        test(sbc_data)
976    }
977
978    #[fixture(fix_sbc_test_file)]
979    #[fuchsia::test]
980    fn decode_sbc(sbc_data: Vec<u8>) {
981        let mut exec = fasync::TestExecutor::new();
982
983        const SBC_FRAME_SIZE: usize = 72;
984        const INPUT_FRAMES: usize = 23;
985
986        // SBC codec info corresponding to Mono reference stream.
987        let oob_data = Some([0x82, 0x00, 0x00, 0x00].to_vec());
988        let mut decoder =
989            StreamProcessor::create_decoder("audio/sbc", oob_data).expect("to create decoder");
990
991        let mut decoded_stream = decoder.take_output_stream().expect("Stream should be taken");
992
993        // Shouldn't be able to take the stream twice
994        assert!(decoder.take_output_stream().is_err());
995
996        let mut frames_sent = 0;
997
998        let frames_per_packet: usize = 1; // Randomly chosen by fair d10 roll.
999        let packet_size = SBC_FRAME_SIZE * frames_per_packet;
1000
1001        for frames in sbc_data.as_slice().chunks(packet_size) {
1002            let mut written_fut = decoder.write(&frames);
1003
1004            let written_bytes =
1005                exec.run_singlethreaded(&mut written_fut).expect("to write to decoder");
1006
1007            assert_eq!(frames.len(), written_bytes);
1008            frames_sent += frames.len() / SBC_FRAME_SIZE;
1009        }
1010
1011        assert_eq!(INPUT_FRAMES, frames_sent);
1012
1013        let mut flush_fut = pin!(decoder.flush());
1014        exec.run_singlethreaded(&mut flush_fut).expect("to flush the decoder");
1015
1016        decoder.close().expect("stream should always be closable");
1017
1018        // Get data from the output now.
1019        let mut decoded = Vec::new();
1020
1021        loop {
1022            let mut decoded_fut = decoded_stream.next();
1023
1024            match exec.run_singlethreaded(&mut decoded_fut) {
1025                Some(Ok(dec_data)) => {
1026                    assert!(!dec_data.is_empty());
1027                    decoded.extend_from_slice(&dec_data);
1028                }
1029                Some(Err(e)) => {
1030                    panic!("Unexpected error when polling decoded data: {}", e);
1031                }
1032                None => {
1033                    break;
1034                }
1035            }
1036        }
1037
1038        // Match the decoded data to the known hash.
1039        let expected_digest = ExpectedDigest::new(
1040            "Pcm: 44.1kHz/16bit/Mono",
1041            "ff2e7afea51217886d3df15b9a623b4e49c9bd9bd79c58ac01bc94c5511e08d6",
1042        );
1043        let hash_validator = BytesValidator { output_file: None, expected_digest };
1044
1045        assert_eq!(256 * INPUT_FRAMES, decoded.len(), "Decoded size should be equal");
1046
1047        let validated = hash_validator.validate(decoded.as_slice());
1048        assert!(validated.is_ok(), "Failed hash: {:?}", validated);
1049    }
1050
1051    #[fixture(fix_sbc_test_file)]
1052    #[fuchsia::test]
1053    fn decode_sbc_wakes_output_to_process_events(sbc_data: Vec<u8>) {
1054        let mut exec = fasync::TestExecutor::new();
1055        const SBC_FRAME_SIZE: usize = 72;
1056
1057        // SBC codec info corresponding to Mono reference stream.
1058        let oob_data = Some([0x82, 0x00, 0x00, 0x00].to_vec());
1059        let mut decoder =
1060            StreamProcessor::create_decoder("audio/sbc", oob_data).expect("to create decoder");
1061
1062        let mut chunks = sbc_data.as_slice().chunks(SBC_FRAME_SIZE);
1063        let next_frame = chunks.next().unwrap();
1064
1065        // Write an initial frame to the encoder.
1066        // This is required to get past allocating the input/output buffers.
1067        let written =
1068            exec.run_singlethreaded(&mut decoder.write(next_frame)).expect("successful write");
1069        assert_eq!(written, next_frame.len());
1070
1071        let mut decoded_stream = decoder.take_output_stream().expect("Stream should be taken");
1072
1073        // Polling the decoded stream before the decoder has started up should wake it when
1074        // output starts happening, set up the poll here.
1075        let decoded_fut = pin!(decoded_stream.next());
1076
1077        let (waker, decoder_fut_wake_count) = new_count_waker();
1078        let mut counting_ctx = Context::from_waker(&waker);
1079
1080        assert!(decoded_fut.poll(&mut counting_ctx).is_pending());
1081
1082        // Send only one frame. This is not eneough to automatically cause output to be generated
1083        // by pushing data.
1084        let frame = chunks.next().unwrap();
1085        let mut written_fut = decoder.write(&frame);
1086        let written_bytes = exec.run_singlethreaded(&mut written_fut).expect("to write to decoder");
1087        assert_eq!(frame.len(), written_bytes);
1088
1089        let mut flush_fut = pin!(decoder.flush());
1090        exec.run_singlethreaded(&mut flush_fut).expect("to flush the decoder");
1091
1092        // When an unprocessed event has happened on the stream, even if intervening events have been
1093        // procesed by the input processes, it should wake the output future to process the events.
1094        assert_eq!(decoder_fut_wake_count.get(), 0);
1095        while decoder_fut_wake_count.get() == 0 {
1096            let _ = exec.run_until_stalled(&mut futures::future::pending::<()>());
1097        }
1098        assert_eq!(decoder_fut_wake_count.get(), 1);
1099
1100        let mut decoded = Vec::new();
1101        // Drops the previous decoder future, which is fine.
1102        let mut decoded_fut = decoded_stream.next();
1103
1104        match exec.run_singlethreaded(&mut decoded_fut) {
1105            Some(Ok(dec_data)) => {
1106                assert!(!dec_data.is_empty());
1107                decoded.extend_from_slice(&dec_data);
1108            }
1109            x => panic!("Expected decoded frame, got {:?}", x),
1110        }
1111
1112        assert_eq!(512, decoded.len(), "Decoded size should be equal to one frame");
1113    }
1114
1115    #[fixture(fix_sbc_test_file)]
1116    #[fuchsia::test]
1117    fn decode_sbc_wakes_input_to_process_events(sbc_data: Vec<u8>) {
1118        let mut exec = fasync::TestExecutor::new();
1119        const SBC_FRAME_SIZE: usize = 72;
1120
1121        // SBC codec info corresponding to Mono reference stream.
1122        let oob_data = Some([0x82, 0x00, 0x00, 0x00].to_vec());
1123        let mut decoder =
1124            StreamProcessor::create_decoder("audio/sbc", oob_data).expect("to create decoder");
1125
1126        let mut decoded_stream = decoder.take_output_stream().expect("Stream should be taken");
1127
1128        let decoded_fut = pin!(decoded_stream.next());
1129
1130        let mut chunks = sbc_data.as_slice().chunks(SBC_FRAME_SIZE).cycle();
1131        let next_frame = chunks.next().unwrap();
1132
1133        // Write an initial frame to the encoder.
1134        // This is to get past allocating the input/output buffers stage.
1135        // TODO(https://fxbug.dev/42081385): Both futures need to be polled here even though it's only the
1136        // writer we really care about because currently decoded_fut is needed to drive the
1137        // allocation process.
1138        let (written_res, mut decoded_fut) =
1139            run_while(&mut exec, decoded_fut, decoder.write(next_frame));
1140        assert_eq!(written_res.expect("initial write should succeed"), next_frame.len());
1141
1142        // Write to the encoder until we cannot write anymore, because there are no input buffers
1143        // available.  This should happen when all the input buffers are full and and the input
1144        // buffers are waiting to be written.
1145        let (waker, write_fut_wake_count) = new_count_waker();
1146        let mut counting_ctx = Context::from_waker(&waker);
1147
1148        let mut wake_count_before_stall = 0;
1149        for frame in chunks {
1150            wake_count_before_stall = write_fut_wake_count.get();
1151            let mut written_fut = decoder.write(&frame);
1152            if written_fut.poll_unpin(&mut counting_ctx).is_pending() {
1153                // The poll_unpin can wake the input waker if an event arrived for it, meaning we should
1154                // continue filling.
1155                if write_fut_wake_count.get() != wake_count_before_stall {
1156                    continue;
1157                }
1158                // We should have never been woken until now, because we always were ready before,
1159                // and the output waker is not registered (so can't progress)
1160                break;
1161            }
1162            // Flush the packet, to make input buffers get spent faster.
1163            let mut flush_fut = pin!(decoder.flush());
1164            exec.run_singlethreaded(&mut flush_fut).expect("to flush the decoder");
1165        }
1166
1167        // We should be able to get a decoded output, once the codec does it's thing.
1168        let decoded_frame = exec.run_singlethreaded(&mut decoded_fut);
1169        assert_eq!(512, decoded_frame.unwrap().unwrap().len(), "Decoded frame size wrong");
1170
1171        // Fill the input buffer again so the input waker is registered.
1172        let chunks = sbc_data.as_slice().chunks(SBC_FRAME_SIZE).cycle();
1173        for frame in chunks {
1174            wake_count_before_stall = write_fut_wake_count.get();
1175            let mut written_fut = decoder.write(&frame);
1176            if written_fut.poll_unpin(&mut counting_ctx).is_pending() {
1177                // The poll_unpin can wake the input waker if an event arrived for it, meaning we should
1178                // continue filling.
1179                if write_fut_wake_count.get() != wake_count_before_stall {
1180                    continue;
1181                }
1182                break;
1183            }
1184            // Flush the packet, to make input buffers get spent faster.
1185            let mut flush_fut = pin!(decoder.flush());
1186            exec.run_singlethreaded(&mut flush_fut).expect("to flush the decoder");
1187        }
1188
1189        // The input waker should be the one waiting on events from the codec and get woken up,
1190        // even if an output event happens.
1191        // At some point, we will get an event from the encoder, with no output waker set, and this
1192        // should wake the input waker, which is waiting to be woken up.
1193        while write_fut_wake_count.get() == wake_count_before_stall {
1194            let _ = exec.run_until_stalled(&mut futures::future::pending::<()>());
1195        }
1196
1197        // Note: at this point, we may not be able to write another frame, but the waiter should
1198        // repoll, and set the waker again.
1199    }
1200}