Skip to content

Commit 56fde0d

Browse files
committed
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`.
1 parent 1b64913 commit 56fde0d

File tree

3 files changed

+12
-35
lines changed

3 files changed

+12
-35
lines changed

examples/client/mp4.rs

+4-17
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,6 @@ macro_rules! write_box {
9393
}};
9494
}
9595

96-
async fn write_all_buf<W: AsyncWrite + Unpin, B: Buf>(
97-
writer: &mut W,
98-
buf: &mut B,
99-
) -> Result<(), Error> {
100-
// TODO: this doesn't use vectored I/O. Annoying.
101-
while buf.has_remaining() {
102-
writer.write_buf(buf).await?;
103-
}
104-
Ok(())
105-
}
106-
10796
/// Writes `.mp4` data to a sink.
10897
/// See module-level documentation for details.
10998
pub struct Mp4Writer<W: AsyncWrite + AsyncSeek + Send + Unpin> {
@@ -262,7 +251,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
262251
});
263252
buf.extend_from_slice(&b"\0\0\0\0mdat"[..]);
264253
let mdat_start = u32::try_from(buf.len())?;
265-
write_all_buf(&mut inner, &mut buf).await?;
254+
inner.write_all(&buf).await?;
266255
Ok(Mp4Writer {
267256
inner,
268257
video_params: Vec::new(),
@@ -311,7 +300,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
311300
self.write_audio_trak(&mut buf, self.audio_params.as_ref().unwrap())?;
312301
}
313302
});
314-
write_all_buf(&mut self.inner, &mut buf.freeze()).await?;
303+
self.inner.write_all(&buf).await?;
315304
self.inner
316305
.seek(SeekFrom::Start(u64::from(self.mdat_start - 8)))
317306
.await?;
@@ -594,8 +583,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
594583
self.video_sync_sample_nums
595584
.push(u32::try_from(self.video_trak.samples)?);
596585
}
597-
let mut data = frame.into_data();
598-
write_all_buf(&mut self.inner, &mut data).await?;
586+
self.inner.write_all(frame.data()).await?;
599587
Ok(())
600588
}
601589

@@ -618,8 +606,7 @@ impl<W: AsyncWrite + AsyncSeek + Send + Unpin> Mp4Writer<W> {
618606
.mdat_pos
619607
.checked_add(size)
620608
.ok_or_else(|| anyhow!("mdat_pos overflow"))?;
621-
let mut data = frame.into_data();
622-
write_all_buf(&mut self.inner, &mut data).await?;
609+
self.inner.write_all(frame.data()).await?;
623610
Ok(())
624611
}
625612
}

src/codec/h264.rs

-1
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ impl Depacketizer {
492492
piece_idx = next_piece_idx;
493493
}
494494
debug_assert_eq!(retained_len, data.len());
495-
let data = Bytes::from(data);
496495
self.nals.clear();
497496
self.pieces.clear();
498497

src/codec/mod.rs

+8-17
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
1010
use std::num::{NonZeroU16, NonZeroU32};
1111

12+
use bytes::Bytes;
13+
1214
use crate::rtp::ReceivedPacket;
1315
use crate::ConnectionContext;
1416
use crate::Error;
1517
use crate::StreamContext;
16-
use bytes::Bytes;
1718

1819
pub(crate) mod aac;
1920
pub(crate) mod g723;
@@ -112,7 +113,7 @@ impl VideoParameters {
112113

113114
/// The codec-specific "extra data" to feed to eg ffmpeg to decode the video frames.
114115
/// * H.264: an AvcDecoderConfig.
115-
pub fn extra_data(&self) -> &Bytes {
116+
pub fn extra_data(&self) -> &[u8] {
116117
&self.extra_data
117118
}
118119
}
@@ -226,14 +227,9 @@ impl AudioFrame {
226227
}
227228

228229
#[inline]
229-
pub fn data(&self) -> &Bytes {
230+
pub fn data(&self) -> &[u8] {
230231
&self.data
231232
}
232-
233-
#[inline]
234-
pub fn into_data(self) -> Bytes {
235-
self.data
236-
}
237233
}
238234

239235
impl std::fmt::Debug for AudioFrame {
@@ -301,14 +297,9 @@ impl MessageFrame {
301297
}
302298

303299
#[inline]
304-
pub fn data(&self) -> &Bytes {
300+
pub fn data(&self) -> &[u8] {
305301
&self.data
306302
}
307-
308-
#[inline]
309-
pub fn into_data(self) -> Bytes {
310-
self.data
311-
}
312303
}
313304

314305
/// A single video frame (aka video sample or video access unit).
@@ -330,7 +321,7 @@ pub struct VideoFrame {
330321
stream_id: usize,
331322
is_random_access_point: bool,
332323
is_disposable: bool,
333-
data: bytes::Bytes,
324+
data: Vec<u8>,
334325
}
335326

336327
impl VideoFrame {
@@ -400,12 +391,12 @@ impl VideoFrame {
400391
/// In the future, a configuration parameter may allow the caller to request Annex B encoding
401392
/// instead. See [#44](https://github.com/scottlamb/retina/issues/44).
402393
#[inline]
403-
pub fn data(&self) -> &Bytes {
394+
pub fn data(&self) -> &[u8] {
404395
&self.data
405396
}
406397

407398
#[inline]
408-
pub fn into_data(self) -> Bytes {
399+
pub fn into_data(self) -> Vec<u8> {
409400
self.data
410401
}
411402
}

0 commit comments

Comments
 (0)