Skip to content
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

[WIP] User api #508

Merged
merged 3 commits into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
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
149 changes: 149 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use encoder::*;
use context::CDFContext;
use partition::LAST_FRAME;

use std::collections::VecDeque;
use std::sync::Arc;

// TODO: use the num crate?
#[derive(Clone, Copy, Debug)]
pub struct Ratio {
pub num: usize,
pub den: usize
}

impl Ratio {
pub fn new(num: usize, den: usize) -> Self {
Ratio { num, den }
}
}

/// Here we store all the information we might receive from the cli
#[derive(Clone, Copy, Debug)]
pub struct Config {
pub width: usize,
pub height: usize,
pub bit_depth: usize,
pub chroma_sampling: ChromaSampling,
pub timebase: Ratio,
pub enc: EncoderConfig
}

impl Config {
pub fn new_context(&self) -> Context {
let fi = FrameInvariants::new(self.width, self.height, self.enc.clone());
let seq = Sequence::new(
self.width,
self.height,
self.bit_depth,
self.chroma_sampling
);

unsafe {
av1_rtcd();
aom_dsp_rtcd();
}

Context { fi, seq, frame_q: VecDeque::new() }
}
}

pub struct Context {
fi: FrameInvariants,
seq: Sequence,
// timebase: Ratio,
frame_q: VecDeque<Option<Arc<Frame>>> // packet_q: VecDeque<Packet>
}

#[derive(Clone, Copy, Debug)]
pub enum EncoderStatus {
/// The encoder needs more Frames to produce an output Packet
NeedMoreData,
/// There are enough Frames queue
EnoughData,
///
Failure
}

pub struct Packet {
pub data: Vec<u8>,
pub rec: Frame,
pub number: usize
}

impl Context {
pub fn new_frame(&self) -> Arc<Frame> {
Arc::new(Frame::new(self.fi.padded_w, self.fi.padded_h))
}

pub fn send_frame<F>(&mut self, frame: F) -> Result<(), EncoderStatus>
where
F: Into<Option<Arc<Frame>>>
{
self.frame_q.push_back(frame.into());
Ok(())
}

pub fn receive_packet(&mut self) -> Result<Packet, EncoderStatus> {
let f = self.frame_q.pop_front().ok_or(EncoderStatus::NeedMoreData)?;
if let Some(frame) = f {
let mut fs = FrameState {
input: frame,
rec: Frame::new(self.fi.padded_w, self.fi.padded_h),
qc: Default::default(),
cdfs: CDFContext::new(0),
};

self.fi.frame_type = if self.fi.number % 30 == 0 {
FrameType::KEY
} else {
FrameType::INTER
};

self.fi.refresh_frame_flags = if self.fi.frame_type == FrameType::KEY {
ALL_REF_FRAMES_MASK
} else {
1
};

self.fi.intra_only = self.fi.frame_type == FrameType::KEY
|| self.fi.frame_type == FrameType::INTRA_ONLY;
// self.fi.use_prev_frame_mvs =
// !(self.fi.intra_only || self.fi.error_resilient);

self.fi.base_q_idx = if self.fi.frame_type == FrameType::KEY {
let q_boost = 15;
self.fi.config.quantizer.max(1 + q_boost).min(255 + q_boost) - q_boost
} else {
self.fi.config.quantizer.max(1).min(255)
} as u8;

self.fi.primary_ref_frame = if self.fi.intra_only || self.fi.error_resilient {
PRIMARY_REF_NONE
} else {
(LAST_FRAME - LAST_FRAME) as u32
};

let data = encode_frame(&mut self.seq, &mut self.fi, &mut fs);

let number = self.fi.number as usize;

self.fi.number += 1;

fs.rec.pad();

// TODO avoid the clone by having rec Arc.
let rec = fs.rec.clone();

update_rec_buffer(&mut self.fi, fs);

Ok(Packet { data, rec, number })
} else {
unimplemented!("Flushing not implemented")
}
}

pub fn flush(&mut self) {
self.frame_q.push_back(None);
}
}
62 changes: 27 additions & 35 deletions src/bin/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use rav1e::*;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::sync::Arc;
use std::slice;
use y4m;

Expand Down Expand Up @@ -93,51 +94,44 @@ impl FromCli for EncoderConfig {
}

/// Encode and write a frame.
pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
pub fn process_frame(ctx: &mut Context,
output_file: &mut dyn Write,
y4m_dec: &mut y4m::Decoder<'_, Box<dyn Read>>,
y4m_enc: Option<&mut y4m::Encoder<'_, Box<dyn Write>>>) -> bool {
unsafe {
av1_rtcd();
aom_dsp_rtcd();
}
let width = fi.width;
let height = fi.height;
let width = y4m_dec.get_width();
let height = y4m_dec.get_height();
let y4m_bits = y4m_dec.get_bit_depth();
let y4m_bytes = y4m_dec.get_bytes_per_sample();
let csp = y4m_dec.get_colorspace();

match csp {
y4m::Colorspace::C420 |
y4m::Colorspace::C420jpeg |
y4m::Colorspace::C420paldv |
y4m::Colorspace::C420mpeg2 |
y4m::Colorspace::C420p10 |
y4m::Colorspace::C420p12 => {},
_ => {
panic!("Colorspace {:?} is not supported yet.", csp);
},
}
let bit_depth = y4m_dec.get_colorspace().get_bit_depth();

match y4m_dec.read_frame() {
Ok(y4m_frame) => {
let y4m_y = y4m_frame.get_y_plane();
let y4m_u = y4m_frame.get_u_plane();
let y4m_v = y4m_frame.get_v_plane();
eprintln!("{}", fi);
let mut fs = FrameState::new(&fi);
fs.input.planes[0].copy_from_raw_u8(&y4m_y, width * y4m_bytes, y4m_bytes);
fs.input.planes[1].copy_from_raw_u8(&y4m_u, width * y4m_bytes / 2, y4m_bytes);
fs.input.planes[2].copy_from_raw_u8(&y4m_v, width * y4m_bytes / 2, y4m_bytes);
let mut input = ctx.new_frame();
{
let input = Arc::get_mut(&mut input).unwrap();
input.planes[0].copy_from_raw_u8(&y4m_y, width * y4m_bytes, y4m_bytes);
input.planes[1].copy_from_raw_u8(&y4m_u, width * y4m_bytes / 2, y4m_bytes);
input.planes[2].copy_from_raw_u8(&y4m_v, width * y4m_bytes / 2, y4m_bytes);
}

match y4m_bits {
8 | 10 | 12 => {},
_ => panic! ("unknown input bit depth!"),
}

let packet = encode_frame(sequence, fi, &mut fs);
write_ivf_frame(output_file, fi.number, packet.as_ref());
let _ = ctx.send_frame(input);

let pkt = ctx.receive_packet().unwrap();
write_ivf_frame(output_file, pkt.number as u64, pkt.data.as_ref());
if let Some(mut y4m_enc) = y4m_enc {
let pitch_y = if sequence.bit_depth > 8 {
let pitch_y = if bit_depth > 8 {
width * 2
} else {
width
Expand All @@ -150,12 +144,12 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
vec![128u8; pitch_uv * (height / 2)]);

let (stride_y, stride_u, stride_v) = (
fs.rec.planes[0].cfg.stride,
fs.rec.planes[1].cfg.stride,
fs.rec.planes[2].cfg.stride);
pkt.rec.planes[0].cfg.stride,
pkt.rec.planes[1].cfg.stride,
pkt.rec.planes[2].cfg.stride);

for (line, line_out) in fs.rec.planes[0].data_origin().chunks(stride_y).zip(rec_y.chunks_mut(pitch_y)) {
if sequence.bit_depth > 8 {
for (line, line_out) in pkt.rec.planes[0].data_origin().chunks(stride_y).zip(rec_y.chunks_mut(pitch_y)) {
if bit_depth > 8 {
unsafe {
line_out.copy_from_slice(
slice::from_raw_parts::<u8>(line.as_ptr() as (*const u8), pitch_y));
Expand All @@ -165,8 +159,8 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
&line.iter().map(|&v| v as u8).collect::<Vec<u8>>()[..pitch_y]);
}
}
for (line, line_out) in fs.rec.planes[1].data_origin().chunks(stride_u).zip(rec_u.chunks_mut(pitch_uv)) {
if sequence.bit_depth > 8 {
for (line, line_out) in pkt.rec.planes[1].data_origin().chunks(stride_u).zip(rec_u.chunks_mut(pitch_uv)) {
if bit_depth > 8 {
unsafe {
line_out.copy_from_slice(
slice::from_raw_parts::<u8>(line.as_ptr() as (*const u8), pitch_uv));
Expand All @@ -176,8 +170,8 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
&line.iter().map(|&v| v as u8).collect::<Vec<u8>>()[..pitch_uv]);
}
}
for (line, line_out) in fs.rec.planes[2].data_origin().chunks(stride_v).zip(rec_v.chunks_mut(pitch_uv)) {
if sequence.bit_depth > 8 {
for (line, line_out) in pkt.rec.planes[2].data_origin().chunks(stride_v).zip(rec_v.chunks_mut(pitch_uv)) {
if bit_depth > 8 {
unsafe {
line_out.copy_from_slice(
slice::from_raw_parts::<u8>(line.as_ptr() as (*const u8), pitch_uv));
Expand All @@ -192,8 +186,6 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
y4m_enc.write_frame(&rec_frame).unwrap();
}

fs.rec.pad();
update_rec_buffer(fi, fs);
true
},
_ => false
Expand Down
48 changes: 16 additions & 32 deletions src/bin/rav1e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ extern crate y4m;
mod common;
use common::*;

use rav1e::partition::LAST_FRAME;
use rav1e::*;

fn main() {
let (mut io, config) = EncoderConfig::from_cli();
let (mut io, enc) = EncoderConfig::from_cli();
let mut y4m_dec = y4m::decode(&mut io.input).unwrap();
let width = y4m_dec.get_width();
let height = y4m_dec.get_height();
let framerate = y4m_dec.get_framerate();
let color_space = y4m_dec.get_colorspace();

let mut limit = enc.limit;
let mut y4m_enc = match io.rec.as_mut() {
Some(rec) => Some(
y4m::encode(width, height, framerate)
Expand All @@ -34,8 +35,6 @@ fn main() {
None => None
};

let mut fi = FrameInvariants::new(width, height, config);

let chroma_sampling = match color_space {
y4m::Colorspace::C420
| y4m::Colorspace::C420jpeg
Expand All @@ -52,8 +51,12 @@ fn main() {
_ => panic!("Chroma sampling unknown for the specified color space.")
};

let mut sequence =
Sequence::new(width, height, color_space.get_bit_depth(), chroma_sampling);
let bit_depth = color_space.get_bit_depth();

let cfg = Config {width, height, bit_depth, chroma_sampling, timebase: Ratio::new(framerate.den, framerate.num), enc };

let mut ctx = cfg.new_context();

write_ivf_header(
&mut io.output,
width,
Expand All @@ -63,40 +66,21 @@ fn main() {
);

loop {
fi.frame_type =
if fi.number % 30 == 0 { FrameType::KEY } else { FrameType::INTER };

fi.base_q_idx = if fi.frame_type == FrameType::KEY {
let q_boost = 15;
fi.config.quantizer.max(1 + q_boost).min(255 + q_boost) - q_boost
} else {
fi.config.quantizer.max(1).min(255)
} as u8;

fi.refresh_frame_flags =
if fi.frame_type == FrameType::KEY { ALL_REF_FRAMES_MASK } else { 1 };
fi.intra_only = fi.frame_type == FrameType::KEY
|| fi.frame_type == FrameType::INTRA_ONLY;
fi.primary_ref_frame = if fi.intra_only || fi.error_resilient {
PRIMARY_REF_NONE
} else {
(LAST_FRAME - LAST_FRAME) as u32
};

if !process_frame(
&mut sequence,
&mut fi,
&mut ctx,
&mut io.output,
&mut y4m_dec,
y4m_enc.as_mut()
y4m_enc.as_mut(),
) {
break;
}
fi.number += 1;
//fi.show_existing_frame = fi.number % 2 == 1;
if fi.number == config.limit {

limit -= 1;

if limit == 0 {
break;
}

io.output.flush().unwrap();
}
}
Loading