-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
codec/decoder/audio: impl Iterator for Audio::decode #74
base: master
Are you sure you want to change the base?
Changes from 1 commit
da6c261
cdcccad
313ea7f
610e095
aa4debf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,8 @@ use libc::c_int; | |
use ffi::*; | ||
|
||
use super::Opened; | ||
use ::{packet, Error, AudioService, ChannelLayout}; | ||
use ::{Error, AudioService, ChannelLayout}; | ||
use ::packet::{self, Mut}; | ||
use ::frame; | ||
use ::util::format; | ||
use ::codec::Context; | ||
|
@@ -23,6 +24,13 @@ impl Audio { | |
} | ||
} | ||
|
||
pub fn decode_iter<'a, 'b>(&'a mut self, packet: &'b mut packet::Packet) -> AudioFrameIter<'a, 'b> { | ||
AudioFrameIter { | ||
audio: self, | ||
packet: packet, | ||
} | ||
} | ||
|
||
pub fn rate(&self) -> u32 { | ||
unsafe { | ||
(*self.as_ptr()).sample_rate as u32 | ||
|
@@ -130,3 +138,38 @@ impl AsMut<Context> for Audio { | |
&mut self.0 | ||
} | ||
} | ||
|
||
pub struct AudioFrameIter<'a, 'b> { | ||
audio: &'a mut Audio, | ||
packet: &'b mut packet::Packet, | ||
} | ||
|
||
impl<'a, 'b> Iterator for AudioFrameIter<'a, 'b> { | ||
type Item = Result<Option<frame::Audio>, Error>; | ||
|
||
fn next(&mut self) -> Option<Result<Option<frame::Audio>, Error>> { | ||
unsafe { | ||
if !self.packet.is_empty() { | ||
let mut out = frame::Audio::empty(); | ||
let mut got: c_int = 0; | ||
let packet = self.packet.as_mut_ptr(); | ||
|
||
match avcodec_decode_audio4(self.audio.as_mut_ptr(), out.as_mut_ptr(), &mut got, packet) { | ||
e if e < 0 => Some(Err(Error::from(e))), | ||
n => { | ||
(*packet).data = (*packet).data.offset(n as isize); | ||
(*packet).size -= n; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better if the packet was borrowed immutably, and then copied over, then these two attributes modified in place in the internal packet. |
||
|
||
if got != 0 { | ||
Some(Ok(Some(out))) | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A problem here is the wrapped frame can live longer than the original frame. |
||
Some(Ok(None)) | ||
} | ||
} | ||
} | ||
} else { | ||
None | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid this, you could create and put the frame inside the
AudioFrameIter
itself, then you wouldn't need to create a new one on each iteration.