j2k_cuda/encode/
resident.rs1use std::time::Duration;
4
5use j2k_core::{BackendKind, DeviceSubmission, PixelFormat, ReadySubmission};
6use j2k_cuda_runtime::CudaDeviceBuffer;
7
8use crate::runtime::cuda_error;
9
10use super::CudaEncodeStageTimings;
11
12#[derive(Debug, Clone, Copy)]
14pub struct CudaLosslessEncodeTile<'a> {
15 pub buffer: &'a CudaDeviceBuffer,
17 pub byte_offset: usize,
19 pub width: u32,
21 pub height: u32,
23 pub pitch_bytes: usize,
25 pub output_width: u32,
27 pub output_height: u32,
29 pub format: PixelFormat,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub struct CudaLosslessEncodeResidency {
36 pub coefficient_prep_used: bool,
38 pub packetization_used: bool,
40 pub codestream_assembly_used: bool,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
46#[doc(hidden)]
47pub struct CudaLosslessEncodeOutcome {
48 pub encoded: j2k::EncodedJ2k,
50 pub input_copy_used: bool,
52 pub resident: CudaLosslessEncodeResidency,
54 pub input_copy_duration: Duration,
56 pub encode_duration: Duration,
58 pub gpu_duration: Option<Duration>,
60 pub validation_duration: Duration,
62 pub host_readback_duration: Duration,
64 pub stage_timings: CudaEncodeStageTimings,
66}
67
68#[derive(Debug)]
70pub struct CudaResidentCodestreamBuffer {
71 pub(super) buffer: CudaDeviceBuffer,
72 pub(super) byte_len: usize,
73}
74
75impl CudaResidentCodestreamBuffer {
76 pub fn buffer(&self) -> &CudaDeviceBuffer {
78 &self.buffer
79 }
80
81 pub fn byte_len(&self) -> usize {
83 self.byte_len
84 }
85
86 pub fn download(&self) -> Result<Vec<u8>, crate::Error> {
88 let mut bytes = crate::allocation::try_vec_filled(
89 self.byte_len,
90 0u8,
91 "CUDA-resident j2k codestream download",
92 )?;
93 self.buffer.copy_to_host(&mut bytes).map_err(cuda_error)?;
94 Ok(bytes)
95 }
96
97 pub fn into_buffer(self) -> CudaDeviceBuffer {
99 self.buffer
100 }
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub struct CudaEncodedJ2kMetadata {
106 pub backend: BackendKind,
108 pub dispatch_report: j2k::J2kEncodeDispatchReport,
110 pub width: u32,
112 pub height: u32,
114 pub components: u16,
116 pub bit_depth: u8,
118 pub signed: bool,
120}
121
122impl CudaEncodedJ2kMetadata {
123 pub(super) fn from_host_encoded(encoded: &j2k::EncodedJ2k) -> Self {
124 Self {
125 backend: encoded.backend,
126 dispatch_report: encoded.dispatch_report,
127 width: encoded.width,
128 height: encoded.height,
129 components: encoded.components,
130 bit_depth: encoded.bit_depth,
131 signed: encoded.signed,
132 }
133 }
134}
135
136#[derive(Debug)]
144pub struct CudaEncodedJ2k {
145 pub metadata: CudaEncodedJ2kMetadata,
147 pub codestream: CudaResidentCodestreamBuffer,
149}
150
151impl CudaEncodedJ2k {
152 pub fn metadata(&self) -> &CudaEncodedJ2kMetadata {
154 &self.metadata
155 }
156
157 pub fn codestream(&self) -> &CudaResidentCodestreamBuffer {
159 &self.codestream
160 }
161
162 pub fn into_parts(self) -> (CudaEncodedJ2kMetadata, CudaResidentCodestreamBuffer) {
164 (self.metadata, self.codestream)
165 }
166}
167
168#[derive(Debug)]
170#[doc(hidden)]
171pub struct CudaLosslessBufferEncodeOutcome {
172 pub encoded: CudaEncodedJ2k,
174 pub input_copy_used: bool,
176 pub resident: CudaLosslessEncodeResidency,
178 pub input_copy_duration: Duration,
180 pub encode_duration: Duration,
182 pub gpu_duration: Option<Duration>,
184 pub validation_duration: Duration,
186 pub host_readback_duration: Duration,
188 pub stage_timings: CudaEncodeStageTimings,
190 pub codestream_upload_duration: Duration,
192}
193
194#[derive(Debug)]
196pub struct SubmittedJ2kLosslessCudaEncode {
197 pub(super) inner: ReadySubmission<j2k::EncodedJ2k, crate::Error>,
198}
199
200#[derive(Debug)]
202pub struct SubmittedJ2kLosslessCudaEncodeBatch {
203 pub(super) inner: ReadySubmission<Vec<j2k::EncodedJ2k>, crate::Error>,
204}
205
206#[doc(hidden)]
207impl DeviceSubmission for SubmittedJ2kLosslessCudaEncode {
208 type Output = j2k::EncodedJ2k;
209 type Error = crate::Error;
210
211 fn wait(self) -> Result<Self::Output, Self::Error> {
212 self.inner.wait()
213 }
214}
215
216#[doc(hidden)]
217impl DeviceSubmission for SubmittedJ2kLosslessCudaEncodeBatch {
218 type Output = Vec<j2k::EncodedJ2k>;
219 type Error = crate::Error;
220
221 fn wait(self) -> Result<Self::Output, Self::Error> {
222 self.inner.wait()
223 }
224}