remove Bytes
from public codec API
Part of #47 The main benefit is that `VideoFrame::into_data` can cheaply return a `Vec<u8>` that the caller can mutate. In particular, they could convert H.264 data from Annex B to AVC form or skip non-VCL NALs. Neither of these transformations add bytes so they're both possible without allocation. Audio and message frames still use `Bytes` internally, as that allows them to avoid copying when the frame is wholly contained in a packet. I think this is much more common than for video. I didn't add an `AudioFrame::into_data` or `VideoFrame::into_data`.
This commit is contained in:
parent
1b6491370f
commit
56fde0d71b
@ -93,17 +93,6 @@ macro_rules! write_box {
|
||||
}};
|
||||
}
|
||||
|
||||
async fn write_all_buf<W: AsyncWrite + Unpin, B: Buf>(
|
||||
writer: &mut W,
|
||||
buf: &mut B,
|
||||
) -> Result<(), Error> {
|
||||
// TODO: this doesn't use vectored I/O. Annoying.
|
||||
while buf.has_remaining() {
|
||||
writer.write_buf(buf).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes `.mp4` data to a sink.
|
||||
/// See module-level documentation for details.
|
||||
pub struct Mp4Writer<W: AsyncWrite + AsyncSeek + Send + Unpin> {
|
||||
@ -262,7 +251,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
|
||||
});
|
||||
buf.extend_from_slice(&b"\0\0\0\0mdat"[..]);
|
||||
let mdat_start = u32::try_from(buf.len())?;
|
||||
write_all_buf(&mut inner, &mut buf).await?;
|
||||
inner.write_all(&buf).await?;
|
||||
Ok(Mp4Writer {
|
||||
inner,
|
||||
video_params: Vec::new(),
|
||||
@ -311,7 +300,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
|
||||
self.write_audio_trak(&mut buf, self.audio_params.as_ref().unwrap())?;
|
||||
}
|
||||
});
|
||||
write_all_buf(&mut self.inner, &mut buf.freeze()).await?;
|
||||
self.inner.write_all(&buf).await?;
|
||||
self.inner
|
||||
.seek(SeekFrom::Start(u64::from(self.mdat_start - 8)))
|
||||
.await?;
|
||||
@ -594,8 +583,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
|
||||
self.video_sync_sample_nums
|
||||
.push(u32::try_from(self.video_trak.samples)?);
|
||||
}
|
||||
let mut data = frame.into_data();
|
||||
write_all_buf(&mut self.inner, &mut data).await?;
|
||||
self.inner.write_all(frame.data()).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -618,8 +606,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
|
||||
.mdat_pos
|
||||
.checked_add(size)
|
||||
.ok_or_else(|| anyhow!("mdat_pos overflow"))?;
|
||||
let mut data = frame.into_data();
|
||||
write_all_buf(&mut self.inner, &mut data).await?;
|
||||
self.inner.write_all(frame.data()).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -492,7 +492,6 @@ impl Depacketizer {
|
||||
piece_idx = next_piece_idx;
|
||||
}
|
||||
debug_assert_eq!(retained_len, data.len());
|
||||
let data = Bytes::from(data);
|
||||
self.nals.clear();
|
||||
self.pieces.clear();
|
||||
|
||||
|
@ -9,11 +9,12 @@
|
||||
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
|
||||
use bytes::Bytes;
|
||||
|
||||
use crate::rtp::ReceivedPacket;
|
||||
use crate::ConnectionContext;
|
||||
use crate::Error;
|
||||
use crate::StreamContext;
|
||||
use bytes::Bytes;
|
||||
|
||||
pub(crate) mod aac;
|
||||
pub(crate) mod g723;
|
||||
@ -112,7 +113,7 @@ impl VideoParameters {
|
||||
|
||||
/// The codec-specific "extra data" to feed to eg ffmpeg to decode the video frames.
|
||||
/// * H.264: an AvcDecoderConfig.
|
||||
pub fn extra_data(&self) -> &Bytes {
|
||||
pub fn extra_data(&self) -> &[u8] {
|
||||
&self.extra_data
|
||||
}
|
||||
}
|
||||
@ -226,14 +227,9 @@ impl AudioFrame {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> &Bytes {
|
||||
pub fn data(&self) -> &[u8] {
|
||||
&self.data
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_data(self) -> Bytes {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for AudioFrame {
|
||||
@ -301,14 +297,9 @@ impl MessageFrame {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> &Bytes {
|
||||
pub fn data(&self) -> &[u8] {
|
||||
&self.data
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_data(self) -> Bytes {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
/// A single video frame (aka video sample or video access unit).
|
||||
@ -330,7 +321,7 @@ pub struct VideoFrame {
|
||||
stream_id: usize,
|
||||
is_random_access_point: bool,
|
||||
is_disposable: bool,
|
||||
data: bytes::Bytes,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl VideoFrame {
|
||||
@ -400,12 +391,12 @@ impl VideoFrame {
|
||||
/// In the future, a configuration parameter may allow the caller to request Annex B encoding
|
||||
/// instead. See [#44](https://github.com/scottlamb/retina/issues/44).
|
||||
#[inline]
|
||||
pub fn data(&self) -> &Bytes {
|
||||
pub fn data(&self) -> &[u8] {
|
||||
&self.data
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_data(self) -> Bytes {
|
||||
pub fn into_data(self) -> Vec<u8> {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user