media-pp 0.1.6

A small, GStreamer-flavored media pipeline library built on FFmpeg.
Documentation
use std::sync::{
    Arc,
    atomic::{AtomicUsize, Ordering},
};

use crate::pp_log::{PpLog, pp_info};

use crate::{
    buffer::MediaBuffer,
    control::ControlMsg,
    element::{Element, ElementType, Sink, element_pp_log},
    error::Result,
};

/// Terminal sink that counts decoded frames (video or audio). Backed by
/// an `Arc<AtomicUsize>` so the count can be read from outside the
/// pipeline even when this sink ends up running on a `Queue` worker
/// thread.
pub struct FrameCounter {
    pp_log: PpLog,
    name: Arc<str>,
    count: Arc<AtomicUsize>,
}

impl FrameCounter {
    pub fn new(name: impl Into<String>) -> (Self, Arc<AtomicUsize>) {
        let count = Arc::new(AtomicUsize::new(0));
        let name: Arc<str> = name.into().into();
        let pp_log = element_pp_log(ElementType::FrameCounter, &name, None);
        pp_info!(pp_log: &pp_log, "created");
        (
            Self {
                name,
                pp_log,
                count: count.clone(),
            },
            count,
        )
    }
}

impl Element for FrameCounter {
    fn name(&self) -> Arc<str> {
        self.name.clone()
    }

    fn element_type(&self) -> ElementType {
        ElementType::FrameCounter
    }

    fn pp_log(&self) -> &PpLog {
        &self.pp_log
    }

    fn pp_log_mut(&mut self) -> &mut PpLog {
        &mut self.pp_log
    }
}

impl Sink for FrameCounter {
    fn consume(&mut self, buf: MediaBuffer) -> Result<()> {
        if let MediaBuffer::Video(_) | MediaBuffer::Audio(_) = buf {
            self.count.fetch_add(1, Ordering::Relaxed);
        }
        Ok(())
    }

    fn control(&mut self, _msg: ControlMsg) -> Result<()> {
        // Terminal, nothing to flush or forward.
        Ok(())
    }
}