restructured to allow qtables
This commit is contained in:
parent
d670f8f880
commit
af6d436079
3 changed files with 36 additions and 7 deletions
|
@ -58,10 +58,10 @@ fn get_opts() !util.Options {
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const opts = try get_opts();
|
const opts = try get_opts();
|
||||||
|
|
||||||
var buffs = try util.Buffers.init(std.heap.page_allocator, opts.width, opts.height, 1000);
|
var buffs = try util.Buffers.init(std.heap.page_allocator, opts.width, opts.height, 1000, opts.quality);
|
||||||
defer buffs.deinit();
|
defer buffs.deinit();
|
||||||
|
|
||||||
var thread_manager = try threads.ThreadManager.init(std.heap.page_allocator, opts.n_quant_jobs);
|
var thread_manager = try threads.ThreadManager.init(std.heap.page_allocator, opts.n_quant_jobs, buffs.Q_Lum, buffs.Q_Chrom);
|
||||||
defer thread_manager.deinit();
|
defer thread_manager.deinit();
|
||||||
|
|
||||||
var f = std.io.getStdIn();
|
var f = std.io.getStdIn();
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub const ThreadManager = struct {
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator, n_quant_jobs: usize) !Self {
|
pub fn init(alloc: std.mem.Allocator, n_quant_jobs: usize, Q_Lum: *util.QTable, Q_Chrom: *util.QTable) !Self {
|
||||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
var arena_alloc = arena.allocator();
|
var arena_alloc = arena.allocator();
|
||||||
var job_pool = util.JobPool.init(alloc);
|
var job_pool = util.JobPool.init(alloc);
|
||||||
|
@ -59,7 +59,7 @@ pub const ThreadManager = struct {
|
||||||
thread_mgr.signals.* = Signals.init();
|
thread_mgr.signals.* = Signals.init();
|
||||||
|
|
||||||
for (0..n_quant_jobs) |_| {
|
for (0..n_quant_jobs) |_| {
|
||||||
try thread_mgr.threads.append(try std.Thread.spawn(.{}, quantize_loop, .{ thread_mgr.queue_wrp.queue, thread_mgr.signals }));
|
try thread_mgr.threads.append(try std.Thread.spawn(.{}, quantize_loop, .{ thread_mgr.queue_wrp.queue, thread_mgr.signals, Q_Lum, Q_Chrom }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return thread_mgr;
|
return thread_mgr;
|
||||||
|
@ -71,10 +71,10 @@ pub const ThreadManager = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn quantize_loop(queue: *util.JobQueue, signals: *Signals) void {
|
fn quantize_loop(queue: *util.JobQueue, signals: *Signals, Q_Lum: *util.QTable, Q_Chrom: *util.QTable) void {
|
||||||
while (queue.HasJobs() or !signals.quit.load(std.builtin.AtomicOrder.Acquire)) : (std.time.sleep(1)) {
|
while (queue.HasJobs() or !signals.quit.load(std.builtin.AtomicOrder.Acquire)) : (std.time.sleep(1)) {
|
||||||
const job = queue.pop() orelse continue;
|
const job = queue.pop() orelse continue;
|
||||||
transform.quantize(job.source, job.target);
|
transform.quantize(job.source, job.target, if (job.is_lum) Q_Lum else Q_Chrom);
|
||||||
_ = @atomicRmw(u32, &signals.processed.value, .Add, 1, .SeqCst);
|
_ = @atomicRmw(u32, &signals.processed.value, .Add, 1, .SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
src/util.zig
31
src/util.zig
|
@ -9,11 +9,13 @@ pub const Options = struct {
|
||||||
|
|
||||||
pub const Block = [64]u8;
|
pub const Block = [64]u8;
|
||||||
pub const BlockQuantized = [64]i16;
|
pub const BlockQuantized = [64]i16;
|
||||||
|
pub const QTable = @Vector(64, f16);
|
||||||
|
|
||||||
pub const ThreadList = std.ArrayList(std.Thread);
|
pub const ThreadList = std.ArrayList(std.Thread);
|
||||||
pub const Job = struct {
|
pub const Job = struct {
|
||||||
source: *Block,
|
source: *Block,
|
||||||
target: *BlockQuantized,
|
target: *BlockQuantized,
|
||||||
|
is_lum: bool,
|
||||||
};
|
};
|
||||||
pub const JobQueue = struct {
|
pub const JobQueue = struct {
|
||||||
const List = std.TailQueue(Job);
|
const List = std.TailQueue(Job);
|
||||||
|
@ -65,6 +67,9 @@ pub const Buffers = struct {
|
||||||
U: [][]Block,
|
U: [][]Block,
|
||||||
V: [][]Block,
|
V: [][]Block,
|
||||||
|
|
||||||
|
Q_Lum: *QTable,
|
||||||
|
Q_Chrom: *QTable,
|
||||||
|
|
||||||
Y_quant: [][][4]BlockQuantized,
|
Y_quant: [][][4]BlockQuantized,
|
||||||
U_quant: [][]BlockQuantized,
|
U_quant: [][]BlockQuantized,
|
||||||
V_quant: [][]BlockQuantized,
|
V_quant: [][]BlockQuantized,
|
||||||
|
@ -76,7 +81,7 @@ pub const Buffers = struct {
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn init(root_alloc: std.mem.Allocator, w: usize, h: usize, output_buff_len: usize) !Self {
|
pub fn init(root_alloc: std.mem.Allocator, w: usize, h: usize, output_buff_len: usize, q: f16) !Self {
|
||||||
var arena = std.heap.ArenaAllocator.init(root_alloc);
|
var arena = std.heap.ArenaAllocator.init(root_alloc);
|
||||||
var alloc = arena.allocator();
|
var alloc = arena.allocator();
|
||||||
const block_w = w / 16;
|
const block_w = w / 16;
|
||||||
|
@ -88,6 +93,9 @@ pub const Buffers = struct {
|
||||||
.U = try alloc.alloc([]Block, block_h),
|
.U = try alloc.alloc([]Block, block_h),
|
||||||
.V = try alloc.alloc([]Block, block_h),
|
.V = try alloc.alloc([]Block, block_h),
|
||||||
|
|
||||||
|
.Q_Lum = try alloc.create(QTable),
|
||||||
|
.Q_Chrom = try alloc.create(QTable),
|
||||||
|
|
||||||
.Y_quant = try alloc.alloc([][4]BlockQuantized, block_h),
|
.Y_quant = try alloc.alloc([][4]BlockQuantized, block_h),
|
||||||
.U_quant = try alloc.alloc([]BlockQuantized, block_h),
|
.U_quant = try alloc.alloc([]BlockQuantized, block_h),
|
||||||
.V_quant = try alloc.alloc([]BlockQuantized, block_h),
|
.V_quant = try alloc.alloc([]BlockQuantized, block_h),
|
||||||
|
@ -106,6 +114,8 @@ pub const Buffers = struct {
|
||||||
buffs.U_quant[i] = try alloc.alloc(BlockQuantized, block_w);
|
buffs.U_quant[i] = try alloc.alloc(BlockQuantized, block_w);
|
||||||
buffs.V_quant[i] = try alloc.alloc(BlockQuantized, block_w);
|
buffs.V_quant[i] = try alloc.alloc(BlockQuantized, block_w);
|
||||||
}
|
}
|
||||||
|
buffs.Q_Lum.* = gen_qtable(255, q, 12);
|
||||||
|
buffs.Q_Chrom.* = gen_qtable(255, q, 6);
|
||||||
return buffs;
|
return buffs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,3 +123,22 @@ pub const Buffers = struct {
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn gen_qtable(q_max: usize, q: f16, band_range: usize) @Vector(64, f16) {
|
||||||
|
var ret: @Vector(64, f16) = [_]f16{0.0} ** 64;
|
||||||
|
const q_min: usize = @intFromFloat(255 - 100 * q);
|
||||||
|
var step = (q_max - q_min) / band_range;
|
||||||
|
var idx: usize = 0;
|
||||||
|
for (0..16) |band_i| {
|
||||||
|
const band_len = band_i + 1;
|
||||||
|
for (0..band_len) |j| {
|
||||||
|
if (band_i < band_range) {
|
||||||
|
ret[idx + j] = @floatFromInt(q_min + step * band_i);
|
||||||
|
} else {
|
||||||
|
ret[idx + j] = @floatFromInt(q_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx += band_len;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue