Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions src/codec/packet/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ impl Packet {
pub unsafe fn is_empty(&self) -> bool {
self.0.size == 0
}

#[inline(always)]
fn lacks_payload_and_side_data(&self) -> bool {
self.0.size == 0 && self.0.side_data_elems == 0
}
}

impl Packet {
Expand Down Expand Up @@ -226,7 +231,9 @@ impl Packet {
#[inline]
pub fn write(&self, format: &mut format::context::Output) -> Result<bool, Error> {
unsafe {
if self.is_empty() {
// FFmpeg allows zero-size packets that still carry side data, such as
// FLAC encoder flush packets with AV_PKT_DATA_NEW_EXTRADATA.
if self.lacks_payload_and_side_data() {
return Err(Error::InvalidData);
}

Expand All @@ -241,7 +248,9 @@ impl Packet {
#[inline]
pub fn write_interleaved(&self, format: &mut format::context::Output) -> Result<(), Error> {
unsafe {
if self.is_empty() {
// Keep wrapper behavior aligned with av_interleaved_write_frame():
// zero-size packets are still valid when they only carry side data.
if self.lacks_payload_and_side_data() {
return Err(Error::InvalidData);
}

Expand Down Expand Up @@ -338,4 +347,26 @@ impl<'a> Iterator for SideDataIter<'a> {
}
}

#[cfg(test)]
mod tests {
use super::Packet;

#[test]
fn empty_packet_without_side_data_is_still_empty_for_write_checks() {
let packet = Packet::empty();

assert!(unsafe { packet.is_empty() });
assert!(packet.lacks_payload_and_side_data());
}

#[test]
fn zero_sized_packet_with_side_data_is_not_treated_as_invalid_empty_packet() {
let mut packet = Packet::empty();
packet.0.side_data_elems = 1;

assert!(unsafe { packet.is_empty() });
assert!(!packet.lacks_payload_and_side_data());
}
}

impl<'a> ExactSizeIterator for SideDataIter<'a> {}