use std::time::Duration;
use j2k_core::{BackendKind, DeviceSubmission, PixelFormat, ReadySubmission};
use j2k_cuda_runtime::CudaDeviceBuffer;
use crate::runtime::cuda_error;
use super::CudaEncodeStageTimings;
#[derive(Debug, Clone, Copy)]
pub struct CudaLosslessEncodeTile<'a> {
pub buffer: &'a CudaDeviceBuffer,
pub byte_offset: usize,
pub width: u32,
pub height: u32,
pub pitch_bytes: usize,
pub output_width: u32,
pub output_height: u32,
pub format: PixelFormat,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CudaLosslessEncodeResidency {
pub coefficient_prep_used: bool,
pub packetization_used: bool,
pub codestream_assembly_used: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[doc(hidden)]
pub struct CudaLosslessEncodeOutcome {
pub encoded: j2k::EncodedJ2k,
pub input_copy_used: bool,
pub resident: CudaLosslessEncodeResidency,
pub input_copy_duration: Duration,
pub encode_duration: Duration,
pub gpu_duration: Option<Duration>,
pub validation_duration: Duration,
pub host_readback_duration: Duration,
pub stage_timings: CudaEncodeStageTimings,
}
#[derive(Debug)]
pub struct CudaResidentCodestreamBuffer {
pub(super) buffer: CudaDeviceBuffer,
pub(super) byte_len: usize,
}
impl CudaResidentCodestreamBuffer {
pub fn buffer(&self) -> &CudaDeviceBuffer {
&self.buffer
}
pub fn byte_len(&self) -> usize {
self.byte_len
}
pub fn download(&self) -> Result<Vec<u8>, crate::Error> {
let mut bytes = crate::allocation::try_vec_filled(
self.byte_len,
0u8,
"CUDA-resident j2k codestream download",
)?;
self.buffer.copy_to_host(&mut bytes).map_err(cuda_error)?;
Ok(bytes)
}
pub fn into_buffer(self) -> CudaDeviceBuffer {
self.buffer
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CudaEncodedJ2kMetadata {
pub backend: BackendKind,
pub dispatch_report: j2k::J2kEncodeDispatchReport,
pub width: u32,
pub height: u32,
pub components: u16,
pub bit_depth: u8,
pub signed: bool,
}
impl CudaEncodedJ2kMetadata {
pub(super) fn from_host_encoded(encoded: &j2k::EncodedJ2k) -> Self {
Self {
backend: encoded.backend,
dispatch_report: encoded.dispatch_report,
width: encoded.width,
height: encoded.height,
components: encoded.components,
bit_depth: encoded.bit_depth,
signed: encoded.signed,
}
}
}
#[derive(Debug)]
pub struct CudaEncodedJ2k {
pub metadata: CudaEncodedJ2kMetadata,
pub codestream: CudaResidentCodestreamBuffer,
}
impl CudaEncodedJ2k {
pub fn metadata(&self) -> &CudaEncodedJ2kMetadata {
&self.metadata
}
pub fn codestream(&self) -> &CudaResidentCodestreamBuffer {
&self.codestream
}
pub fn into_parts(self) -> (CudaEncodedJ2kMetadata, CudaResidentCodestreamBuffer) {
(self.metadata, self.codestream)
}
}
#[derive(Debug)]
#[doc(hidden)]
pub struct CudaLosslessBufferEncodeOutcome {
pub encoded: CudaEncodedJ2k,
pub input_copy_used: bool,
pub resident: CudaLosslessEncodeResidency,
pub input_copy_duration: Duration,
pub encode_duration: Duration,
pub gpu_duration: Option<Duration>,
pub validation_duration: Duration,
pub host_readback_duration: Duration,
pub stage_timings: CudaEncodeStageTimings,
pub codestream_upload_duration: Duration,
}
#[derive(Debug)]
pub struct SubmittedJ2kLosslessCudaEncode {
pub(super) inner: ReadySubmission<j2k::EncodedJ2k, crate::Error>,
}
#[derive(Debug)]
pub struct SubmittedJ2kLosslessCudaEncodeBatch {
pub(super) inner: ReadySubmission<Vec<j2k::EncodedJ2k>, crate::Error>,
}
#[doc(hidden)]
impl DeviceSubmission for SubmittedJ2kLosslessCudaEncode {
type Output = j2k::EncodedJ2k;
type Error = crate::Error;
fn wait(self) -> Result<Self::Output, Self::Error> {
self.inner.wait()
}
}
#[doc(hidden)]
impl DeviceSubmission for SubmittedJ2kLosslessCudaEncodeBatch {
type Output = Vec<j2k::EncodedJ2k>;
type Error = crate::Error;
fn wait(self) -> Result<Self::Output, Self::Error> {
self.inner.wait()
}
}