aboutsummaryrefslogtreecommitdiff
path: root/flowy/src/motion/mod.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-11-18 01:28:39 +0100
committermetamuffin <metamuffin@disroot.org>2023-11-18 01:28:39 +0100
commit3deb911083605ad5b63a0ecd372e4ae437c11b4a (patch)
tree964cb681a01c695bc2dd46465e52c313de2fbbb3 /flowy/src/motion/mod.rs
parente3d15b63589ba41a559c55d2953ba1d166e833bb (diff)
downloadvideo-codec-experiments-3deb911083605ad5b63a0ecd372e4ae437c11b4a.tar
video-codec-experiments-3deb911083605ad5b63a0ecd372e4ae437c11b4a.tar.bz2
video-codec-experiments-3deb911083605ad5b63a0ecd372e4ae437c11b4a.tar.zst
new streaming system
Diffstat (limited to 'flowy/src/motion/mod.rs')
-rw-r--r--flowy/src/motion/mod.rs150
1 files changed, 150 insertions, 0 deletions
diff --git a/flowy/src/motion/mod.rs b/flowy/src/motion/mod.rs
new file mode 100644
index 0000000..acb1396
--- /dev/null
+++ b/flowy/src/motion/mod.rs
@@ -0,0 +1,150 @@
+pub mod dec;
+pub mod enc;
+
+use std::mem::size_of;
+use wgpu::{
+ Buffer, BufferUsages, CommandEncoder, Device, Extent3d, ImageCopyTexture, Origin3d, Queue,
+ Texture, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
+};
+
+pub struct Params {
+ pub width: usize,
+ pub height: usize,
+ pub extent: Extent3d,
+ pub block_width: usize,
+ pub block_height: usize,
+ pub blocks: usize,
+}
+
+pub struct RoundParams {
+ pub swap: usize,
+}
+
+pub struct CommonBuffers {
+ textures: [Texture; 2],
+ offsets: Buffer,
+ offsets_download: Option<Buffer>,
+ debug_output: Option<Texture>,
+ texture_download: Option<Buffer>,
+}
+
+#[repr(C)]
+pub struct BlockOffset {
+ score: f32,
+ _pad: u32,
+ offset: [f32; 2],
+}
+
+impl CommonBuffers {
+ pub fn create(device: &Device, params: &Params) -> Self {
+ let textures = [(), ()].map(|_| {
+ device.create_texture(&TextureDescriptor {
+ label: None,
+ size: params.extent,
+ mip_level_count: 1,
+ sample_count: 1,
+ dimension: TextureDimension::D2,
+ format: TextureFormat::Bgra8Unorm,
+ usage: TextureUsages::TEXTURE_BINDING
+ | TextureUsages::COPY_DST
+ | TextureUsages::COPY_SRC,
+ view_formats: &[],
+ })
+ });
+
+ let debug_output = Some(device.create_texture(&TextureDescriptor {
+ label: None,
+ size: params.extent,
+ mip_level_count: 1,
+ sample_count: 1,
+ dimension: TextureDimension::D2,
+ format: TextureFormat::Bgra8Unorm,
+ usage: TextureUsages::STORAGE_BINDING | TextureUsages::COPY_SRC,
+ view_formats: &[],
+ }));
+
+ let texture_download = Some(device.create_buffer(&wgpu::BufferDescriptor {
+ label: None,
+ size: (params.width * params.height * 4) as u64,
+ usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ,
+ mapped_at_creation: false,
+ }));
+
+ let offsets = device.create_buffer(&wgpu::BufferDescriptor {
+ label: None,
+ size: (params.blocks * size_of::<BlockOffset>()) as u64,
+ usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
+ mapped_at_creation: false,
+ });
+ let offsets_download = Some(device.create_buffer(&wgpu::BufferDescriptor {
+ label: None,
+ size: (params.blocks * size_of::<BlockOffset>()) as u64,
+ usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ,
+ mapped_at_creation: false,
+ }));
+
+ Self {
+ debug_output,
+ textures,
+ offsets_download,
+ offsets,
+ texture_download,
+ }
+ }
+
+ pub fn upload(&self, queue: &Queue, params: &Params, rp: &RoundParams, buffer: &[u8]) {
+ queue.write_texture(
+ ImageCopyTexture {
+ aspect: wgpu::TextureAspect::All,
+ mip_level: 0,
+ origin: Origin3d::ZERO,
+ texture: &self.textures[rp.swap],
+ },
+ buffer,
+ wgpu::ImageDataLayout {
+ offset: 0,
+ bytes_per_row: Some(params.extent.width * 4),
+ rows_per_image: Some(params.extent.height),
+ },
+ params.extent,
+ );
+ }
+
+ pub fn prepare_texture_download(
+ &self,
+ encoder: &mut CommandEncoder,
+ params: &Params,
+ rp: &RoundParams,
+ ) {
+ encoder.copy_texture_to_buffer(
+ wgpu::ImageCopyTexture {
+ texture: &self.textures[rp.swap],
+ mip_level: 0,
+ origin: wgpu::Origin3d::ZERO,
+ aspect: wgpu::TextureAspect::All,
+ },
+ wgpu::ImageCopyBuffer {
+ buffer: self.texture_download.as_ref().unwrap(),
+ layout: wgpu::ImageDataLayout {
+ offset: 0,
+ bytes_per_row: Some(params.extent.width * 4),
+ rows_per_image: Some(params.extent.height),
+ },
+ },
+ params.extent,
+ );
+ }
+
+ pub fn download(&self, device: &Device, buffer: &mut [u8]) {
+ let buffer_slice = self.texture_download.as_ref().unwrap().slice(..);
+ let (sender, receiver) = oneshot::channel();
+ buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
+ device.poll(wgpu::Maintain::Wait);
+ receiver.recv().unwrap().unwrap();
+ {
+ let view = buffer_slice.get_mapped_range();
+ buffer.copy_from_slice(&view[..]);
+ }
+ self.texture_download.as_ref().unwrap().unmap();
+ }
+}