1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use crate::{
    error::try_map_opus_error,
    ffi,
    packet::{MutPacket, Packet},
    Result, TryInto,
};

/// Returns Opus' internal `OpusRepacketizer`'s size in bytes.
pub fn repacketizer_size() -> usize {
    unsafe { ffi::opus_repacketizer_get_size() as usize }
}

pub fn multistream_packet_pad<'a, TP>(data: TP, new_len: usize, nb_streams: usize) -> Result<()>
where
    TP: TryInto<MutPacket<'a>>,
{
    let mut data = data.try_into()?;

    try_map_opus_error(unsafe {
        ffi::opus_multistream_packet_pad(
            data.as_mut_ptr(),
            data.i32_len()?,
            new_len as i32,
            nb_streams as i32,
        )
    })
    .map(|_| ())
}

pub fn multistream_packet_unpad<'a, TP>(data: TP, nb_streams: usize) -> Result<()>
where
    TP: TryInto<MutPacket<'a>>,
{
    let mut data = data.try_into()?;

    try_map_opus_error(unsafe {
        ffi::opus_multistream_packet_unpad(data.as_mut_ptr(), data.i32_len()?, nb_streams as i32)
    })
    .map(|_| ())
}

pub fn packet_pad<'a, TP>(data: TP, new_len: i32) -> Result<()>
where
    TP: TryInto<MutPacket<'a>>,
{
    let mut data = data.try_into()?;

    try_map_opus_error(unsafe { ffi::opus_packet_pad(data.as_mut_ptr(), data.i32_len()?, new_len) })
        .map(|_| ())
}

pub fn packet_unpad<'a, TP>(data: TP) -> Result<()>
where
    TP: TryInto<MutPacket<'a>>,
{
    let mut data = data.try_into()?;

    try_map_opus_error(unsafe { ffi::opus_packet_unpad(data.as_mut_ptr(), data.i32_len()?) })
        .map(|_| ())
}

#[derive(Debug)]
pub struct Repacketizer {
    pointer: *mut ffi::OpusRepacketizer,
}

impl Default for Repacketizer {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for Repacketizer {
    /// We have to ensure that the resource our wrapping Opus-struct is pointing
    /// to is deallocated properly.
    fn drop(&mut self) {
        unsafe { ffi::opus_repacketizer_destroy(self.pointer) }
    }
}

impl Repacketizer {
    pub fn new() -> Self {
        let pointer = unsafe { ffi::opus_repacketizer_create() };

        Self { pointer }
    }

    pub fn nb_frames(&self) -> usize {
        unsafe { ffi::opus_repacketizer_get_nb_frames(self.pointer) as usize }
    }

    pub fn repacketizer_out<'a, TP>(&self, data_out: TP, max_len: i32) -> Result<()>
    where
        TP: TryInto<MutPacket<'a>>,
    {
        let mut data_out = data_out.try_into()?;

        try_map_opus_error(unsafe {
            ffi::opus_repacketizer_out(self.pointer, data_out.as_mut_ptr(), max_len)
        })
        .map(|_| ())
    }

    pub fn repacketizer_out_range<'a, TP>(
        &self,
        begin: i32,
        end: i32,
        data_out: TP,
        max_len: i32,
    ) -> Result<()>
    where
        TP: TryInto<MutPacket<'a>>,
    {
        let mut data_out = data_out.try_into()?;

        try_map_opus_error(unsafe {
            ffi::opus_repacketizer_out_range(
                self.pointer,
                begin,
                end,
                data_out.as_mut_ptr(),
                max_len,
            )
        })
        .map(|_| ())
    }

    pub fn repacketizer_cat<'a, TP>(&self, data: TP) -> Result<()>
    where
        TP: TryInto<Packet<'a>>,
    {
        let data = data.try_into()?;

        try_map_opus_error(unsafe {
            ffi::opus_repacketizer_cat(self.pointer, data.as_ptr(), data.i32_len())
        })
        .map(|_| ())
    }
}