use nihav_core::codecs::*;
use nihav_core::scale::*;
-use super::{DecoderStuff, DispQueue, FrameRecord, PktSendEvent, FRAME_QUEUE_LEN};
+use super::{DecoderStuff, DecoderType, DispQueue, FrameRecord, PktSendEvent, FRAME_QUEUE_LEN};
static SKIP_VDECODING: AtomicBool = AtomicBool::new(false);
static VIDEO_END: AtomicBool = AtomicBool::new(false);
+static GET_FRAMES_END: AtomicBool = AtomicBool::new(false);
pub const FRAME_QUEUE_SIZE: usize = 25;
Some((opic, time))
}
pub fn next_frame(&mut self, pkt: &NAPacket) -> Option<FrameRecord> {
- if let Ok(frm) = self.dec.dec.decode(&mut self.dec.dsupp, pkt) {
- self.dec.reord.add_frame(frm);
- while let Some(frm) = self.dec.reord.get_frame() {
- let bt = frm.get_buffer();
- if let NABufferType::None = bt { continue; }
- let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
- return self.convert_buf(bt, ts);
- }
- }
+ match self.dec.dec {
+ DecoderType::Video(ref mut vdec, ref mut reord) => {
+ if let Ok(frm) = vdec.decode(&mut self.dec.dsupp, pkt) {
+ reord.add_frame(frm);
+ while let Some(frm) = reord.get_frame() {
+ let bt = frm.get_buffer();
+ if let NABufferType::None = bt { continue; }
+ let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
+ return self.convert_buf(bt, ts);
+ }
+ }
+ },
+ DecoderType::VideoMT(ref mut vdec, ref mut reord) => {
+ let queue_id = reord.register_frame();
+ match vdec.queue_pkt(&mut self.dec.dsupp, &pkt, queue_id) {
+ Ok(true) => {},
+ Ok(false) => {
+ while !vdec.can_take_input() || vdec.has_output() {
+ match vdec.get_frame() {
+ (Ok(frm), id) => {
+ reord.add_frame(frm, id);
+ },
+ (Err(err), id) => {
+ reord.drop_frame(id);
+ panic!("frame {} decoding error {:?}", id, err);
+ },
+ };
+ }
+ match vdec.queue_pkt(&mut self.dec.dsupp, &pkt, queue_id) {
+ Ok(true) => {},
+ Ok(false) => panic!("still can't queue frame!"),
+ Err(err) => panic!("queueing error {:?}", err),
+ };
+ },
+ Err(err) => panic!("queueing error {:?}", err),
+ };
+ while let Some(frm) = reord.get_frame() {
+ let bt = frm.get_buffer();
+ if let NABufferType::None = bt { continue; }
+ let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
+ return self.convert_buf(bt, ts);
+ }
+ },
+ _ => panic!("not a video decoder!"),
+ };
+ None
+ }
+ pub fn more_frames(&mut self, do_not_wait: bool) -> Option<FrameRecord> {
+ match self.dec.dec {
+ DecoderType::Video(ref mut _dec, ref mut reord) => {
+ while let Some(frm) = reord.get_frame() {
+ let bt = frm.get_buffer();
+ if let NABufferType::None = bt { continue; }
+ let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
+ return self.convert_buf(bt, ts);
+ }
+ },
+ DecoderType::VideoMT(ref mut vdec, ref mut reord) => {
+ let mut got_some = false;
+ while vdec.has_output() {
+ match vdec.get_frame() {
+ (Ok(frm), id) => {
+ reord.add_frame(frm, id);
+ got_some = true;
+ },
+ (Err(err), id) => {
+ reord.drop_frame(id);
+ panic!("frame {} decoding error {:?}", id, err);
+ },
+ };
+ }
+ if !got_some && !do_not_wait {
+ match vdec.get_frame() {
+ (Ok(frm), id) => {
+ reord.add_frame(frm, id);
+ },
+ (Err(DecoderError::NoFrame), _) => {},
+ (Err(err), id) => {
+ reord.drop_frame(id);
+ panic!("frame {} decoding error {:?}", id, err);
+ },
+ };
+ }
+ while let Some(frm) = reord.get_frame() {
+ let bt = frm.get_buffer();
+ if let NABufferType::None = bt { continue; }
+ let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
+ return self.convert_buf(bt, ts);
+ }
+ },
+ _ => {},
+ };
None
}
pub fn last_frame(&mut self) -> Option<FrameRecord> {
- while let Some(frm) = self.dec.reord.get_last_frames() {
- let bt = frm.get_buffer();
- if let NABufferType::None = bt { continue; }
- let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
- return self.convert_buf(bt, ts);
- }
+ match self.dec.dec {
+ DecoderType::Video(ref mut _dec, ref mut reord) => {
+ while let Some(frm) = reord.get_last_frames() {
+ let bt = frm.get_buffer();
+ if let NABufferType::None = bt { continue; }
+ let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
+ return self.convert_buf(bt, ts);
+ }
+ },
+ DecoderType::VideoMT(ref mut _dec, ref mut reord) => {
+ while let Some(frm) = reord.get_last_frames() {
+ let bt = frm.get_buffer();
+ if let NABufferType::None = bt { continue; }
+ let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0));
+ return self.convert_buf(bt, ts);
+ }
+ },
+ _ => {},
+ };
None
}
pub fn flush(&mut self) {
- self.dec.dec.flush();
- self.dec.reord.flush();
+ match self.dec.dec {
+ DecoderType::Video(ref mut dec, ref mut reord) => {
+ dec.flush();
+ reord.flush();
+ },
+ DecoderType::VideoMT(ref mut dec, ref mut reord) => {
+ dec.flush();
+ reord.flush();
+ },
+ _ => {},
+ };
}
}
if let Some((buf, time)) = vdec.next_frame(&pkt) {
vfsend.send((buf, time)).unwrap();
}
+ while let Some((buf, time)) = vdec.more_frames(true) {
+ vfsend.send((buf, time)).unwrap();
+ }
+ }
+ },
+ Ok(PktSendEvent::GetFrames) => {
+ while let Some((buf, time)) = vdec.more_frames(false) {
+ vfsend.send((buf, time)).unwrap();
}
+ GET_FRAMES_END.store(true, Ordering::Relaxed);
},
Ok(PktSendEvent::Flush) => {
vdec.flush();
},
Ok(PktSendEvent::HurryUp) => {
skip_mode = skip_mode.advance();
- vdec.dec.dec.set_options(&[NAOption{
+ if let DecoderType::Video(ref mut dec, ref mut _reord) = vdec.dec.dec {
+ dec.set_options(&[NAOption{
name: FRAME_SKIP_OPTION,
value: NAValue::String(skip_mode.to_string()),
}]);
+ }
},
Err(_) => {
break;
pub fn is_video_end(&self) -> bool {
VIDEO_END.load(Ordering::Relaxed)
}
+ pub fn wait_for_frames(&mut self) {
+ GET_FRAMES_END.store(false, Ordering::Relaxed);
+ self.try_send_event(PktSendEvent::GetFrames);
+ while !self.try_send_queued() {
+ }
+ while !GET_FRAMES_END.load(Ordering::Relaxed) {
+ thread::yield_now();
+ }
+ }
pub fn is_yuv(&self) -> bool { self.do_yuv }