nvJPEG
一个 GPU 加速的 JPEG 编解码器库。
1. 简介
1.1. nvJPEG 解码器
nvJPEG 库为深度学习和超大规模多媒体应用中常用的图像格式提供高性能、GPU 加速的 JPEG 解码功能。该库提供单张和批量 JPEG 解码能力,可有效利用可用的 GPU 资源以获得最佳性能;并为用户管理解码所需的内存分配提供灵活性。
nvJPEG 库启用以下功能:使用 JPEG 图像数据流作为输入;从数据流中检索图像的宽度和高度,并使用检索到的信息来管理 GPU 内存分配和解码。提供专用 API 用于从原始 JPEG 图像数据流中检索图像信息。
注意
在本文档中,“CPU”和“主机”术语同义使用。 同样,“GPU”和“设备”术语也是同义的。
nvJPEG 库支持以下
JPEG 选项
基线和渐进式 JPEG 解码/编码
每像素 8 位
Huffman 比特流解码
最多 4 通道 JPEG 比特流
8 位和 16 位量化表
-
以下是 3 个颜色通道 Y、Cb、Cr (Y、U、V) 的色度子采样
4:4:4
4:2:2
4:2:0
4:4:0
4:1:1
4:1:0
特性
使用 CPU(即主机)和 GPU(即设备)的混合解码。
基线 JPEG 解码的硬件加速,请参阅 硬件加速。
库的输入在主机内存中,输出在 GPU 内存中。
单张图像和批量图像解码。
单阶段和多阶段解码。
色彩空间转换。
用户提供的设备和页锁定主机内存分配的内存管理器。
1.2. nvJPEG 编码器
nvJPEG 库的编码功能执行 GPU 加速的用户图像数据压缩到 JPEG 比特流。用户可以提供多种格式和色彩空间的输入数据,并使用参数控制编码过程。编码功能将使用用户提供的内存分配器分配临时缓冲区。
在调用编码功能之前,用户应使用 nvJPEG 编码器辅助 API 参考 中描述的辅助功能执行一些先决步骤。
1.3. 线程安全
并非所有 nvJPEG 类型都是线程安全的。
当跨多个线程使用解码器 API 时,以下解码器类型应为每个线程单独实例化:nvJPEG 比特流句柄、nvJPEG 不透明 JPEG 解码状态句柄、nvJPEG 解码设备缓冲区句柄、nvJPEG 解码页锁定缓冲区句柄
当跨多个线程使用编码器 API 时,nvjpegEncoderState_t 应为每个线程单独实例化。
对于用户提供的分配器(nvjpegCreateEx() 的输入),用户需要确保线程安全。
1.4. 多 GPU 支持
nvJPEG 状态和句柄绑定到创建时设置为当前的设备。将这些状态和句柄与设置为另一个当前的设备一起使用是未定义的。用户负责跟踪当前设备。
1.5. 硬件加速
硬件加速 JPEG 解码在以下 GPU 架构上可用 -
Ampere (A100, A30)
Hopper
Ada
Blackwell
支持硬件加速 JPEG 解码的平台
Windows
Linux (x86_64, PowerPC, ARM64)
2. JPEG 解码
2.1. 使用 JPEG 解码
nvJPEG 库为单张图像解码和多张图像的批量解码提供功能。
2.1.1. 单张图像解码
对于单张图像解码,您提供数据大小和指向文件数据的指针,解码后的图像将放置在输出缓冲区中。
要使用 nvJPEG 库,请首先调用辅助函数进行初始化。
使用辅助函数
nvjpegCreateSimple() 或 nvjpegCreateEx()
创建 nvJPEG 库句柄。-
使用辅助函数
nvjpegJpegStateCreate()
创建 JPEG 状态。 请参阅 nvJPEG 类型声明 和nvjpegJpegStateCreate()
。以下辅助函数在 nvJPEG 库中可用
nvjpegStatus_t nvjpegGetProperty(libraryPropertyType type, int *value);
[已弃用] nvjpegStatus_t nvjpegCreate(nvjpegBackend_t backend, nvjpegHandle_t *handle , nvjpeg_dev_allocator allocator);
nvjpegStatus_t nvjpegCreateSimple(nvjpegHandle_t *handle);
nvjpegStatus_t nvjpegCreateEx(nvjpegBackend_t backend, nvjpegDevAllocator_t *dev_allocator, nvjpegPinnedAllocator_t *pinned_allocator, unsigned int flags, nvjpegHandle_t *handle);
nvjpegStatus_t nvjpegDestroy(nvjpegHandle_t handle);
nvjpegStatus_t nvjpegJpegStateCreate(nvjpegHandle_t handle, nvjpegJpegState_t *jpeg_handle);
nvjpegStatus_t nvjpegJpegStateDestroy(nvjpegJpegState handle);
其他辅助函数,如
nvjpegSet*()
和nvjpegGet*()
可用于配置每个句柄的库功能。 有关更多详细信息,请参阅 nvJPEG 辅助 API 参考。
-
通过使用
nvjpegGetImageInfo()
函数从 JPEG 编码的图像中检索宽度和高度信息。以下是
nvjpegGetImageInfo()
函数的签名nvjpegStatus_t nvjpegGetImageInfo( nvjpegHandle_t handle, const unsigned char *data, size_t length, int *nComponents, nvjpegChromaSubsampling_t *subsampling, int *widths, int *heights);
对于要解码的每张图像,将 JPEG 数据指针和数据长度传递给上述函数。
nvjpegGetImageInfo()
函数是线程安全的。 上述
nvjpegGetImageInfo()
函数的输出之一是nvjpegChromaSubsampling_t
。 此参数是枚举类型,其枚举器列表由从 JPEG 图像检索的色度子采样属性组成。 请参阅 nvJPEG 色度子采样。-
使用 nvJPEG 库中的
nvjpegDecode()
函数解码此单张 JPEG 图像。 请参阅以下此函数的签名nvjpegStatus_t nvjpegDecode( nvjpegHandle_t handle, nvjpegJpegState_t jpeg_handle, const unsigned char *data, size_t length, nvjpegOutputFormat_t output_format, nvjpegImage_t *destination, cudaStream_t stream);
在上述
nvjpegDecode()
函数中,参数nvjpegOutputFormat_t
、nvjpegImage_t
和cudaStream_t
可用于设置nvjpegDecode()
函数的输出行为。 您提供cudaStream_t
参数以指示异步任务提交到的流。 -
``nvjpegOutputFormat_t`` 参数
nvjpegOutputFormat_t
参数可以设置为以下output_format
设置之一output_format
含义
NVJPEG_OUTPUT_UNCHANGED
返回解码后的图像平面格式。
NVJPEG_OUTPUT_RGB
转换为平面 RGB。
NVJPEG_OUTPUT_BGR
转换为平面 BGR。
NVJPEG_OUTPUT_RGBI
转换为交错 RGB。
NVJPEG_OUTPUT_BGRI
转换为交错 BGR。
NVJPEG_OUTPUT_Y
仅返回 Y 分量。
NVJPEG_OUTPUT_YUV
以 YUV 平面格式返回。
NVJPEG_OUTPUT_UNCHANGEDI_U16
返回解码后的图像交错格式。
例如,如果
output_format
设置为NVJPEG_OUTPUT_Y
或NVJPEG_OUTPUT_RGBI
,或NVJPEG_OUTPUT_BGRI
,则输出仅写入nvjpegImage_t
的 channel[0],其他通道不会被触及。或者,在平面输出的情况下,数据将写入
nvjpegImage_t
目标结构的相应通道。最后,在灰度 JPEG 和 RGB 输出的情况下,亮度用于创建灰度 RGB。
下表解释了库支持的输出格式和通道数的组合。
比特流中的通道数 |
1 |
2 |
3 |
4 |
输出格式 |
||||
NVJPEG_OUTPUT_UNCHANGED |
是 |
是 |
是 |
是 |
NVJPEG_OUTPUT_YUV |
仅填充输出的第一个通道 |
否 |
是 |
否 |
NVJPEG_OUTPUT_Y |
是 |
否 |
是 |
是(a) :ref:`nvjpeg-single-image-decoding__first |
NVJPEG_OUTPUT_RGB |
是(b) :ref:`nvjpeg-single-image-decoding__second |
否 |
是 |
是(a) :ref:`nvjpeg-single-image-decoding__first |
NVJPEG_OUTPUT_BGR |
是(b) :ref:`nvjpeg-single-image-decoding__second |
否 |
是 |
是(a) :ref:`nvjpeg-single-image-decoding__first |
NVJPEG_OUTPUT_RGBI |
是(b) :ref:`nvjpeg-single-image-decoding__second |
否 |
是 |
是(a) :ref:`nvjpeg-single-image-decoding__first |
NVJPEG_OUTPUT_BGRI |
是(b) :ref:`nvjpeg-single-image-decoding__second |
否 |
是 |
是(a) :ref:`nvjpeg-single-image-decoding__first |
NVJPEG_OUTPUT_UNCHANGEDI_U16 |
是(c) |
是 |
否 |
否 |
注释
|
-
如上所述,
nvjpegGetImageInfo()
函数的一个重要好处是能够利用从输入 JPEG 图像检索的图像信息,为解码操作分配适当的 GPU 内存。nvjpegGetImageInfo()
函数返回widths
、heights
和nComponents
参数。nvjpegStatus_t nvjpegGetImageInfo( nvjpegHandle_t handle, const unsigned char *data, size_t length, int *nComponents, nvjpegChromaSubsampling_t *subsampling, int *widths, int *heights);
您可以使用检索到的参数
widths
、heights
和nComponents
来计算输出缓冲区所需的大小,无论是对于单个解码的 JPEG,还是对于批处理中的每个解码的 JPEG。为了最佳地设置
nvjpegDecode()
函数的destination
参数,请使用以下指南对于 output_format
NVJPEG_OUTPUT_Y
destination.pitch[0] 应至少为: width[0]
destination.channel[0] 的大小应至少为: destination.pitch[0]*height[0]
对于 output_format
destination.pitch[c] 应至少为
destination.channel[c] 的大小应至少为
NVJPEG_OUTPUT_YUV
c = 0、1、2 的 width[c]
c = 0、1、2 的 destination.pitch[c]*height[c]
NVJPEG_OUTPUT_RGB 和 NVJPEG_OUTPUT_BGR
c = 0、1、2 的 width[0]
c = 0、1、2 的 destination.pitch[0]*height[0]
NVJPEG_OUTPUT_RGBI 和 NVJPEG_OUTPUT_BGRI
width[0]*3
destination.pitch[0]*height[0]
NVJPEG_OUTPUT_UNCHANGED
c = [ 0, nComponents - 1 ] 的 width[c]
c = [ 0, nComponents - 1] 的 destination.pitch[c]*height[c]
NVJPEG_OUTPUT_UNCHANGEDI_U16
width[c]* nComponents* sizeof(unsigned short)
c = [ 0, nComponents - 1] 的 destination.pitch[c]*height[c]
-
确保 nvJPEG 图像 结构(或结构,在批量解码的情况下)填充了已分配缓冲区的指针和步幅。 保持输出指针的
nvjpegImage_t
结构定义如下typedef struct { unsigned char * channel[NVJPEG_MAX_COMPONENT]; size_t pitch[NVJPEG_MAX_COMPONENT]; } nvjpegImage_t;
NVJPEG_MAX_COMPONENT 是 nvJPEG 库在当前版本中支持的最大颜色分量数。 对于通用图像,这是库能够解压缩的最大编码通道数。
最后,当您使用如上所述的参数调用
nvjpegDecode()
函数时,nvjpegDecode()
函数将用解码后的数据填充输出缓冲区。
2.1.2. 使用解耦阶段解码
nvJPEG 库允许进一步分离解码过程的主机和设备阶段。 解码的主机阶段将不需要访问设备资源。
一些解耦 API 的示例可以在 解码 API—解耦解码 下找到。
以下是解码单张图像的 API 调用序列
-
初始化解码过程中使用的所有项目
使用库句柄初始化例程之一创建库句柄。
选择解码器实现
nvjpegBackend_t
,并使用nvjpegDecoderCreate()
创建解码器。使用
nvjpegDecoderStateCreate()
创建 JPEG 解码器状态。使用
nvjpegJpegStreamCreate()
创建 JPEG 流。-
分别使用以下 API 创建解码器使用的页锁定缓冲区和设备缓冲区。 这些缓冲区用于存储中间解码结果。
nvjpegBufferPinnedCreate()
nvjpegBufferDeviceCreate()
-
分别使用以下 API 将缓冲区链接到 JPEG 状态
nvjpegStateAttachPinnedBuffer()
nvjpegStateAttachDeviceBuffer()
-
使用以下 API 创建解码参数。 这用于设置输出格式,并启用 ROI 解码
nvjpegDecodeParamsCreate()
-
执行解码
-
使用
nvjpegJpegStreamParse()
解析 jpeg 比特流-
编码比特流信息,如通道维度,可以使用以下 API 检索。 此信息用于在
nvjpegImage_t
中分配输出指针。nvjpegJpegStreamGetComponentsNum()
nvjpegJpegStreamGetComponentDimensions()
-
-
按以下顺序调用解码 API 以解码图像
nvjpegDecodeJpegHost()
nvjpegDecodeJpegTransferToDevice()
nvjpegDecodeJpegDevice()
-
2.1.3. 批量图像解码
对于批量图像解码,您提供指向内存中多个文件数据的指针,并为每个文件数据提供缓冲区大小。 nvJPEG 库将解码这些多张图像,并将解码后的数据放置在您在参数中指定的输出缓冲区中。
2.1.3.1. 单阶段
对于单阶段批量图像解码,请按照以下步骤操作
调用
nvjpegDecodeBatchedInitialize()
函数以初始化批量解码器。 在batch_size
参数中指定批量大小。 请参阅nvjpegDecodeBatchedInitialize()
。接下来,为每个新批次调用
nvjpegDecodeBatched()
。 确保传递的参数对于特定批次的图像是正确的。 如果批次的大小发生变化,或者批次解码失败,则再次调用nvjpegDecodeBatchedInitialize()
函数。
2.2. nvJPEG 类型声明
2.2.1. nvJPEG 后端
typedef enum {
NVJPEG_BACKEND_DEFAULT = 0,
NVJPEG_BACKEND_HYBRID = 1,
NVJPEG_BACKEND_GPU_HYBRID = 2,
NVJPEG_BACKEND_HARDWARE = 3,
NVJPEG_BACKEND_GPU_HYBRID_DEVICE = 4,
NVJPEG_BACKEND_HARDWARE_DEVICE = 5,
NVJPEG_BACKEND_LOSSLESS_JPEG = 6
} nvjpegBackend_t;
nvjpegBackend_t
枚举用于默认选择默认后端,或对基线 JPEG 图像使用 GPU 解码,或对 Huffman 解码使用 CPU。
成员 |
描述 |
NVJPEG_BACKEND_DEFAULT |
后端在内部选择。 |
NVJPEG_BACKEND_HYBRID |
使用 CPU 进行 Huffman 解码。 |
NVJPEG_BACKEND_GPU_HYBRID |
使用 GPU 进行 Huffman 解码。 当批量大小大于 50 时, |
NVJPEG_BACKEND_HARDWARE |
使用 硬件加速 进行解码。 支持具有 1 个或 3 个通道的单次扫描的基线 JPEG 图像。 不支持 410 和 411 色度子采样。 |
NVJPEG_BACKEND_GPU_HYBRID_DEVICE |
支持设备内存上的输入比特流。 只能与无重启间隔的基线 JPEG 图像的批量解码 API 一起使用。 |
NVJPEG_BACKEND_HARDWARE_DEVICE |
支持设备内存上的输入比特流。 只能与批量解码 API 一起使用。 使用 硬件加速 进行解码。 支持具有 1 个或 3 个通道的单次扫描的基线 JPEG 图像。 不支持 410 和 411 色度子采样。 |
NVJPEG_BACKEND_LOSSLESS_JPEG |
支持 jpeg 92 标准中定义的无损 jpeg 比特流。 支持最多 2 个通道和预测模式 1 的比特流。 |
2.2.2. nvJPEG 比特流句柄
struct nvjpegJpegStream;
typedef struct nvjpegJpegStream* nvjpegJpegStream_t;
此句柄在主机上存储比特流参数。 这有助于使用 nvJPEG 流 API 中定义的 API 检索比特流元数据。
2.2.3. nvJPEG 解码设备缓冲区句柄
struct nvjpegBufferDevice;
typedef struct nvjpegBufferDevice* nvjpegBufferDevice_t;
解码器状态使用此 nvjpegBufferDevice_t
在设备内存中存储中间信息。
2.2.4. nvJPEG 解码参数句柄
struct nvjpegDecodeParams;
typedef struct nvjpegDecodeParams* nvjpegDecodeParams_t;
此解码器参数句柄存储参数,如输出格式和使用 nvJPEG 色度子采样 中定义的 API 设置的 ROI 解码参数。
2.2.5. nvJPEG 解码页锁定缓冲区句柄
struct nvjpegBufferPinned;
typedef struct nvjpegBufferPinned* nvjpegBufferPinned_t;
解码器状态使用此 nvjpegBufferPinned_t
句柄在页锁定内存上存储中间信息。
2.2.6. nvJPEG 解码器句柄
struct nvjpegJpegDecoder;
typedef struct nvjpegJpegDecoder* nvjpegJpegDecoder_t;
此解码器句柄存储跨解码阶段共享的中间解码器数据。 此解码器句柄针对给定的 nvjpegBackend_t
初始化。 它用作 解码 API—解耦解码 的输入。
2.2.7. nvJPEG 主机页锁定内存分配器接口
typedef int (*tPinnedMalloc)(void**, size_t, unsigned int flags);
typedef int (*tPinnedFree)(void*);
typedef struct {
tPinnedMalloc pinned_malloc;
tPinnedFree pinned_free;
} nvjpegPinnedAllocator_t;
当 nvjpegCreateEx()
函数中的 nvjpegPinnedAllocator_t *allocator
参数设置为指向上述 nvjpegPinnedAllocator_t
结构的指针时,则此结构将用于分配和释放主机页锁定内存,以便将数据复制到/从设备复制数据。 内存分配和内存释放函数的函数原型类似于 cudaHostAlloc()
和 cudaFreeHost()
函数。 成功时它们将返回 0,否则返回非零值。
但是,如果 nvjpegCreateEx()
函数中的 nvjpegPinnedAllocator_t *allocator
参数设置为 NULL,则将使用默认内存分配函数 cudaHostAlloc()
和 cudaFreeHost()
。 当使用 nvjpegCreate()
或 nvjpegCreateSimple()
函数创建库句柄时,将使用默认的主机页锁定内存分配器。
2.2.8. nvJPEG 扩展主机页锁定内存分配器接口
typedef int (*tPinnedMallocV2)(void* ctx, void **ptr, size_t size, cudaStream_t stream);
typedef int (*tPinnedFreeV2)(void* ctx, void *ptr, size_t size, cudaStream_t stream);
typedef struct
{
tPinnedMallocV2 pinned_malloc;
tPinnedFreeV2 pinned_free;
void *pinned_ctx;
} nvjpegPinnedAllocatorV2_t;
扩展的页锁定分配器支持流有序分配以及用户定义的上下文信息 pinned_ctx
。当调用分配器时,nvJPEG 将传递 pinned_ctx
作为扩展的页锁定分配器的输入。
2.2.9. nvJPEG 图像
typedef struct {
unsigned char * channel[NVJPEG_MAX_COMPONENT];
size_t pitch[NVJPEG_MAX_COMPONENT];
} nvjpegImage_t;
nvjpegImage_t
结构(或在批量解码的情况下为多个结构)用于填充已分配缓冲区的指针和步幅。nvjpegImage_t
结构保存输出指针。
成员 |
描述 |
NVJPEG_MAX_COMPONENT |
nvJPEG 库支持的最大颜色分量数。对于通用图像,这是库能够解压缩的最大编码通道数。 |
2.2.10. nvJPEG 设备内存分配器接口
typedef int (*tDevMalloc)(void**, size_t);
typedef int (*tDevFree)(void*);
typedef struct {
tDevMalloc dev_malloc;
tDevFree dev_free;
} nvjpegDevAllocator_t;
用户可以告知库使用他们自己的设备内存分配器。内存分配和内存释放函数的函数原型类似于 cudaMalloc()
和 cudaFree()
函数。成功时应返回 0,否则返回非零值。应将指向 nvjpegDevAllocator_t
结构的指针(已正确填充字段)提供给 nvjpegCreate()
函数。接受 NULL,在这种情况下,将使用默认内存分配函数 cudaMalloc()
和 cudaFree()
。
当 nvjpegDevAllocator_t *allocator
参数在 nvjpegCreate()
或 nvjpegCreateEx()
函数中设置为指向上述 nvjpegDevAllocator_t
结构的指针时,则此结构用于分配和释放设备内存。内存分配和内存释放函数的函数原型类似于 cudaMalloc()
和 cudaFree()
函数。成功时应返回 0,否则返回非零值。
但是,如果 nvjpegDevAllocator_t *allocator
参数在 nvjpegCreate()
或 nvjpegCreateEx()
函数中设置为 NULL,则将使用默认内存分配函数 cudaMalloc()
和 cudaFree()
。当使用 nvjpegCreateSimple()
函数创建库句柄时,将使用默认设备内存分配器。
2.2.11. nvJPEG 扩展设备内存分配器接口
typedef int (*tDevMallocV2)(void* ctx, void **ptr, size_t size, cudaStream_t stream);
typedef int (*tDevFreeV2)(void* ctx, void *ptr, size_t size, cudaStream_t stream);
typedef struct
{
tDevMallocV2 dev_malloc;
tDevFreeV2 dev_free;
void *dev_ctx;
} nvjpegDevAllocatorV2_t;
扩展的设备分配器支持流有序分配以及用户定义的上下文信息 dev_ctx
。当调用分配器时,nvJPEG 将传递 dev_ctx
作为扩展的设备分配器的输入。
2.2.12. nvJPEG 不透明 JPEG 解码状态句柄
struct nvjpegJpegState;
typedef struct nvjpegJpegState* nvjpegJpegState_t;
nvjpegJpegState
结构存储临时的 JPEG 信息。应在任何使用之前对其进行初始化。此 JPEG 状态句柄可以在另一次解码中使用后重复使用。对于同一图像或批次,在解码阶段应使用相同的 JPEG 句柄。仅当在第一阶段 (nvjpegDecodePhaseOne
) 处理同一批次时,才允许多个线程共享 JPEG 状态句柄。
2.2.13. nvJPEG 不透明库句柄结构
struct nvjpegHandle;
typedef struct nvjpegHandle* nvjpegHandle_t;
库句柄用于任何连续的 nvJPEG 库调用,应首先初始化。
库句柄是线程安全的,可以由多个线程同时使用。
2.2.14. nvJPEG 输出指针结构
typedef struct {
unsigned char * channel[NVJPEG_MAX_COMPONENT];
size_t pitch[NVJPEG_MAX_COMPONENT];
} nvjpegImage_t;
nvjpegImage_t
结构保存指向输出缓冲区的指针,并保存图像解码的这些缓冲区的相应步幅。
有关如何设置 nvjpegImage_t
结构的详细信息,请参阅 单图像解码。
2.2.15. nvJPEG Jpeg 编码
typedef enum {
NVJPEG_ENCODING_UNKNOWN = 0x0,
NVJPEG_ENCODING_BASELINE_DCT = 0xc0,
NVJPEG_ENCODING_EXTENDED_SEQUENTIAL_DCT_HUFFMAN = 0xc1,
NVJPEG_ENCODING_PROGRESSIVE_DCT_HUFFMAN = 0xc2,
NVJPEG_ENCODING_LOSSLESS_HUFFMAN = 0xc3
} nvjpegJpegEncoding_t;
nvjpegJpegEncoding_t
枚举列出了 nvJPEG 库支持的 JPEG 编码类型。枚举值基于 JPEG 规范中定义的标记
成员 |
描述 |
NVJPEG_ENCODING_UNKNOWN |
此值针对 nvJPEG 库不支持的所有 JPEG 标记返回。 |
NVJPEG_ENCODING_BASELINE_DCT |
对应于 JPEG 标记 0xc0,有关更多详细信息,请参阅 JPEG 规范。 |
NVJPEG_ENCODING_EXTENDED_SEQUENTIAL_DCT_HUFFMAN |
对应于 JPEG 标记 0xc1,有关更多详细信息,请参阅 JPEG 规范。 |
NVJPEG_ENCODING_PROGRESSIVE_DCT_HUFFMAN |
对应于 JPEG 标记 0xc2,有关更多详细信息,请参阅 JPEG 规范。 |
NVJPEG_ENCODING_LOSSLESS_HUFFMAN |
对应于 JPEG 标记 0xc3,有关更多详细信息,请参阅 JPEG 规范。 |
2.2.16. nvJPEG 缩放因子
typedef enum {
NVJPEG_SCALE_NONE = 0,
NVJPEG_SCALE_1_BY_2 = 1,
NVJPEG_SCALE_1_BY_4 = 2,
NVJPEG_SCALE_1_BY_8 = 3
} nvjpegScaleFactor_t;
nvjpegScaleFactor_t
枚举列出了库支持的所有缩放因子。当使用 NVJPEG_BACKEND_HARDWARE 实例化 nvjpeg 句柄时,支持此功能
成员 |
描述 |
NVJPEG_SCALE_NONE |
解码输出未缩放 |
NVJPEG_SCALE_1_BY_2 |
解码输出宽度和高度按 1/2 的因子缩放 |
NVJPEG_SCALE_1_BY_4 |
解码输出宽度和高度按 1/4 的因子缩放 |
NVJPEG_SCALE_1_BY_8 |
解码输出宽度和高度按 1/8 的因子缩放 |
2.2.17. nvJPEG 标志
#define NVJPEG_FLAGS_DEFAULT 0
#define NVJPEG_FLAGS_HW_DECODE_NO_PIPELINE 1
#define NVJPEG_FLAGS_ENABLE_MEMORY_POOLS 2
#define NVJPEG_FLAGS_BITSTREAM_STRICT 4
#define NVJPEG_FLAGS_REDUCED_MEMORY_DECODE 8
#define NVJPEG_FLAGS_REDUCED_MEMORY_DECODE_ZERO_COPY 16
#define NVJPEG_FLAGS_UPSAMPLING_WITH_INTERPOLATION 32
当使用 nvjpegCreateEx() 或 nvjpegCreateExV2() 初始化库时,nvJPEG 标志提供额外的控制。可以组合这些标志,因为它们是位字段。
成员 |
描述 |
NVJPEG_FLAGS_DEFAULT |
对应于默认库行为。 |
NVJPEG_FLAGS_HW_DECODE_NO_PIPELINE |
当使用 NVJPEG_BACKEND_HARDWARE 初始化库时使用。对于其他后端,它将被忽略。nvjpeg 在批量解码模式下缓冲额外的图像以实现最佳性能。使用此标志禁用缓冲额外的图像。 |
NVJPEG_FLAGS_ENABLE_MEMORY_POOLS [已弃用] |
从 CUDA 11.1 开始,此标志将被忽略。 |
NVJPEG_FLAGS_BITSTREAM_STRICT |
即使比特流不严格遵循 JPEG 规范,nvJPEG 库也会尝试解码比特流。在这种情况下使用此标志将返回错误。 |
NVJPEG_FLAGS_REDUCED_MEMORY_DECODE |
当使用 |
NVJPEG_FLAGS_REDUCED_MEMORY_DECODE_ZERO_COPY |
在支持的平台上,使用此标志可以在可行时启用零拷贝内存。 |
NVJPEG_FLAGS_UPSAMPLING_WITH_INTERPOLATION |
使用此标志使解码器能够在 YCbCr 到 RGB 转换阶段执行色度上采样时使用插值。 |
2.2.18. nvJPEG Exif 方向
typedef enum {
NVJPEG_ORIENTATION_UNKNOWN = 0,
NVJPEG_ORIENTATION_NORMAL = 1,
NVJPEG_ORIENTATION_FLIP_HORIZONTAL = 2,
NVJPEG_ORIENTATION_ROTATE_180 = 3,
NVJPEG_ORIENTATION_FLIP_VERTICAL = 4,
NVJPEG_ORIENTATION_TRANSPOSE = 5,
NVJPEG_ORIENTATION_ROTATE_90 = 6,
NVJPEG_ORIENTATION_TRANSVERSE = 7,
NVJPEG_ORIENTATION_ROTATE_270 = 8
} nvjpegExifOrientation_t;
nvjpegExifOrientation_t
枚举表示 jfif(jpeg) 文件中的 exif 方向。Exif 方向信息通常用于表示图像捕获时数码相机传感器的方向。
成员 |
描述 |
NVJPEG_ORIENTATION_UNKNOWN |
比特流中不提供 Exif 方向信息。 |
NVJPEG_ORIENTATION_NORMAL |
解码输出保持不变。 |
NVJPEG_ORIENTATION_FLIP_HORIZONTAL |
解码输出应水平镜像/翻转。 |
NVJPEG_ORIENTATION_ROTATE_180 |
解码输出应旋转 180 度。 |
NVJPEG_ORIENTATION_FLIP_VERTICAL |
解码输出应垂直镜像/翻转。 |
NVJPEG_ORIENTATION_TRANSPOSE |
解码输出应水平翻转/镜像,然后逆时针旋转 90 度。 |
NVJPEG_ORIENTATION_ROTATE_90 |
解码输出应逆时针旋转 90 度。 |
NVJPEG_ORIENTATION_TRANSVERSE |
解码输出应水平翻转/镜像,然后逆时针旋转 270 度。 |
NVJPEG_ORIENTATION_ROTATE_270 |
解码输出应逆时针旋转 270 度。 |
2.3. nvJPEG API 参考
本节介绍 nvJPEG 解码器 API。
2.3.1. nvJPEG 辅助 API 参考
2.3.1.1. nvjpegGetProperty()
获取 nvJPEG 库的主版本号、次版本号或补丁级别的数值。
签名
nvjpegStatus_t nvjpegGetProperty(
libraryPropertyType type,
int *value);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
支持的 |
|
输出 |
主机 |
与请求的特定 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.2. nvjpegGetCudartProperty()
获取用于构建 nvJPEG 库的 CUDA 工具包的主版本号、次版本号或补丁级别的数值。有关 nvJPEG 库本身的相同信息,请参阅 nvjpegGetProperty()。
签名
nvjpegStatus_t nvjpegGetCudartProperty(
libraryPropertyType type,
int *value);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
支持的 |
|
输出 |
主机 |
与请求的特定 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.3. nvjpegCreate() [已弃用]
分配和初始化库句柄。
注意
此函数已弃用。请使用 nvjpegCreateSimple()
或 nvjpegCreateEx()
函数创建库句柄。
签名
nvjpegStatus_t nvjpegCreate(
nvjpegBackend_t backend,
nvjpegDevAllocator_t *allocator,
nvjpegHandle_t *handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvjpegDecodeBatched() API 的后端参数。如果设置为 DEFAULT,则自动选择其中一个底层算法。 |
|
输入 |
主机 |
设备内存分配器。请参阅 nvJPEG 设备内存分配器接口 结构描述。如果提供 NULL,则将使用默认 CUDA 运行时 |
|
输入/输出 |
主机 |
库句柄。 |
nvjpegBackend_t
参数是 enum
类型,具有以下枚举列表值
typedef enum {
NVJPEG_BACKEND_DEFAULT = 0,
NVJPEG_BACKEND_HYBRID = 1,
} nvjpegBackend_t;
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.4. nvjpegCreateSimple()
分配和初始化库句柄,并选择库选择的默认编解码器实现和默认内存分配器。
签名
nvjpegStatus_t nvjpegCreateSimple(nvjpegHandle_t *handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.5. nvjpegCreateEx()
使用提供的参数分配和初始化库句柄。
签名
nvjpegStatus_t nvjpegCreateEx(nvjpegBackend_t backend,
nvjpegDevAllocator_t *dev_allocator,
nvjpegPinnedAllocator_t *pinned_allocator,
unsigned int flags,
nvjpegHandle_t *handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvjpegDecodeBatched() API 的后端参数。如果设置为 DEFAULT,则自动选择其中一个底层算法。 |
|
输入 |
主机 |
设备内存分配器。请参阅 |
|
输入 |
主机 |
页锁定主机内存分配器。请参阅 |
|
输入 |
主机 |
有关详细信息,请参阅 nvJPEG 标志。 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.6. nvjpegCreateExV2()
使用提供的参数分配和初始化库句柄。
签名
nvjpegStatus_t nvjpegCreateExV2(nvjpegBackend_t backend,
nvjpegDevAllocatorV2_t *dev_allocator,
nvjpegPinnedAllocatorV2_t *pinned_allocator,
unsigned int flags,
nvjpegHandle_t *handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvjpegDecodeBatched() API 的后端参数。如果设置为 DEFAULT,则自动选择其中一个底层算法。 |
|
输入 |
主机 |
扩展设备内存分配器。请参阅 |
|
输入 |
主机 |
扩展的页锁定内存分配器。请参阅 |
|
输入 |
主机 |
有关详细信息,请参阅 nvJPEG 标志。 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.7. nvjpegDestroy()
释放库句柄。
签名
nvjpegStatus_t nvjpegDestroy(nvjpegHandle_t handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
要释放的库句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.8. nvjpegSetDeviceMemoryPadding()
对具有指定库句柄的所有设备内存分配使用提供的填充。较大的数字将有助于分摊需要时重新分配设备内存的需求。
签名
nvjpegStatus_t nvjpegSetDeviceMemoryPadding(
size_t padding,
nvjpegHandle_t handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
用于所有后续设备内存分配的设备内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.9. nvjpegGetDeviceMemoryPadding()
检索当前用于指定库句柄的设备内存填充。
签名
nvjpegStatus_t nvjpegGetDeviceMemoryPadding(
size_t *padding,
nvjpegHandle_t handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输出 |
主机 |
当前用于设备内存分配的设备内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.10. nvjpegSetPinnedMemoryPadding()
对具有指定库句柄的所有页锁定主机内存分配使用提供的填充。较大的数字将有助于分摊需要时重新分配页锁定主机内存的需求。
签名
nvjpegStatus_t nvjpegSetPinnedMemoryPadding(
size_t padding,
nvjpegHandle_t handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
用于所有后续页锁定主机内存分配的页锁定主机内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.11. nvjpegGetPinnedMemoryPadding()
检索当前用于指定库句柄的页锁定主机内存填充。
签名
nvjpegStatus_t nvjpegGetPinnedMemoryPadding(
size_t *padding,
nvjpegHandle_t handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输出 |
主机 |
当前用于页锁定主机内存分配的页锁定主机内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.12. nvjpegGetHardwareDecoderInfo()
检索硬件解码器详细信息,例如引擎数量和每个引擎中可用的核心数量。
签名
nvjpegStatus_t nvjpegGetHardwareDecoderInfo(nvjpegHandle_t handle,
unsigned int* num_engines,
unsigned int* num_cores_per_engine);
参数
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
检索可用于解码的引擎数量。返回值为 0 表示硬件解码器不可用。 |
|
输入/输出 |
主机 |
检索每个引擎的核心数量。返回值为 0 表示硬件解码器不可用。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.13. nvjpegJpegStateCreate()
分配和初始化 JPEG 处理所需的内部结构。
签名
nvjpegStatus_t nvjpegJpegStateCreate(
nvjpegHandle_t handle,
nvjpegJpegState_t *jpeg_handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
图像状态句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.14. nvjpegJpegStateDestroy()
释放图像内部结构。
签名
nvjpegStatus_t nvjpegJpegStateDestroy(nvjpegJpegState handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
图像状态句柄。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.15. nvjpegDecoderCreate()
创建解码器句柄。
签名
nvjpegStatus_t nvjpegDecoderCreate(
nvjpegHandle_t nvjpeg_handle,
nvjpegBackend_t implementation,
nvjpegJpegDecoder_t* decoder_handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
decoder_handle 的后端参数。后端适用于 解耦 API 下的所有函数,当使用此句柄调用时。 |
|
输入/输出 |
主机 |
解码器状态句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.16. nvjpegDecoderDestroy()
销毁解码器句柄。
签名
nvjpegStatus_t nvjpegDecoderDestroy(
nvjpegJpegDecoder_t decoder_handle);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
解码器句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.17. nvjpegDecoderJpegSupported()
确定 decoder_handle
是否能够处理存储在 jpeg_stream
中的比特流。
签名
nvjpegStatus_t nvjpegDecoderJpegSupported(
nvjpegJpegDecoder_t decoder_handle,
nvjpegJpegStream_t jpeg_stream,
nvjpegDecodeParams_t decode_params,
int* is_supported);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码器状态句柄 |
|
输入 |
主机 |
比特流元数据 |
|
输入 |
主机 |
解码器输出配置 |
|
输出 |
主机 |
返回值为 0 表示比特流可以由 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.18. nvjpegDecoderStateCreate()
创建 decoder_state
内部结构。decoder_state
与用于创建 decoder_handle
的 nvJPEG 后端 实现相关联。
签名
nvjpegStatus_t nvjpegDecoderStateCreate(
nvjpegHandle_t nvjpeg_handle,
nvjpegJpegDecoder_t decoder_handle,
nvjpegJpegState_t* decoder_state);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
解码器句柄。 |
|
输入/输出 |
主机 |
nvJPEG 图像状态句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.19. nvjpegJpegStreamCreate()
创建 jpeg_stream
,用于解析 JPEG 比特流并存储比特流参数。
签名
nvjpegStatus_t nvjpegJpegStreamCreate(
nvjpegHandle_t handle,
nvjpegJpegStream_t *jpeg_stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄 |
|
输入 |
主机 |
比特流句柄 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.20. nvjpegJpegStreamDestroy()
销毁 jpeg_stream
结构。
签名
nvjpegStatus_t nvjpegJpegStreamDestroy(
nvjpegJpegStream_t *jpeg_stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.21. nvjpegBufferPinnedCreate()
创建页锁定缓冲区句柄。
签名
nvjpegStatus_t nvjpegBufferPinnedCreate(
nvjpegHandle_t handle,
nvjpegPinnedAllocator_t* pinned_allocator,
nvjpegBufferPinned_t* buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
页锁定主机内存分配器。请参阅 |
|
输入/输出 |
主机 |
nvJPEG 页锁定缓冲区对象。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.22. nvjpegBufferPinnedCreateV2()
使用扩展分配器创建页锁定缓冲区句柄。
签名
nvjpegStatus_t nvjpegBufferPinnedCreateV2(
nvjpegHandle_t handle,
nvjpegPinnedAllocatorV2_t* pinned_allocator,
nvjpegBufferPinned_t* buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
nvjpegHandle_t handle |
输入 |
主机 |
库句柄。 |
nvjpegPinnedAllocatorV2_t* pinned_allocator |
输入 |
主机 |
扩展的页锁定主机内存分配器。请参阅 nvJPEG 扩展主机页锁定内存分配器接口 结构描述。 |
nvjpegBufferPinned_t* buffer |
输入/输出 |
主机 |
nvJPEG 页锁定缓冲区对象。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.23. nvjpegBufferPinnedDestroy()
销毁页锁定缓冲区句柄。
签名
nvjpegStatus_t nvjpegBufferPinnedDestroy(
nvjpegBufferPinned_t buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 页锁定缓冲区对象。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.24. nvjpegStateAttachPinnedBuffer()
将 nvJPEG 页锁定缓冲区句柄链接到 decoder_state
。pinned_buffer
由解码器用于存储跨解码阶段使用的中间信息。页锁定缓冲区可以附加到不同的解码器状态,这有助于在实现之间切换而无需分配额外的内存。
签名
nvjpegStatus_t nvjpegStateAttachPinnedBuffer(
nvjpegJpegState_t decoder_state,
nvjpegBufferPinned_t pinned_buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 解码器状态。 |
|
输入 |
主机 |
nvJPEG 页锁定缓冲区容器。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.25. nvjpegBufferPinnedRetrieve()
从 nvJPEG 页锁定缓冲区句柄检索页锁定内存指针和大小。允许应用程序在解码完成后重复使用内存。
签名
nvjpegStatus_t nvjpegBufferPinnedRetrieve(
nvjpegBufferPinned_t buffer,
size_t* size, void** ptr);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 页锁定缓冲区容器。 |
|
输入/输出 |
主机 |
页锁定缓冲区的大小(以字节为单位)。 |
|
输入/输出 |
主机 |
指向页锁定缓冲区的指针。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.26. nvjpegBufferPinnedResize()
将页锁定缓冲区调整为指定大小(以字节为单位)。此 API 可用于将页锁定缓冲区预分配为较大的值,并避免在解码期间调用分配器。
签名
nvjpegStatus_t nvjpegBufferPinnedResize(nvjpegBufferPinned_t buffer,
size_t size,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 页锁定缓冲区容器。 |
|
输入 |
主机 |
页锁定缓冲区的大小(以字节为单位)。 |
|
输入 |
主机 |
当使用流有序分配器初始化 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.27. nvjpegBufferDeviceCreate()
创建设备缓冲区句柄。
签名
nvjpegStatus_t nvjpegBufferDeviceCreate(
nvjpegHandle_t handle,
nvjpegDevAllocator_t* device_allocator,
nvjpegBufferDevice_t* buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
设备内存分配器。请参阅 nvJPEG 设备内存分配器接口 结构描述。 |
|
输入/输出 |
主机 |
nvJPEG 设备缓冲区容器。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.28. nvjpegBufferDeviceCreateV2()
使用扩展分配器创建设备缓冲区句柄。
签名
nvjpegStatus_t nvjpegBufferDeviceCreateV2(
nvjpegHandle_t handle,
nvjpegDevAllocatorV2_t* device_allocator,
nvjpegBufferDevice_t* buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
nvjpegHandle_t handle |
输入 |
主机 |
库句柄。 |
nvjpegDevAllocatorV2_t* device_allocator |
输入 |
主机 |
扩展设备内存分配器。请参阅 |
nvjpegBufferDevice_t* buffer |
输入/输出 |
主机 |
nvJPEG 设备缓冲区容器。 |
返回值
nvjpegStatus_t
- 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.29. nvjpegBufferDeviceDestroy()
销毁设备缓冲区句柄。
签名
nvjpegStatus_t nvjpegBufferDeviceDestroy(
nvjpegBufferDevice_t buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机/设备 |
nvJPEG 设备缓冲区容器。设备指针存储在主机结构中。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.30. nvjpegStateAttachDeviceBuffer()
将 nvJPEG 设备缓冲区句柄链接到 decoder_state
。device_buffer
由解码器用于存储跨解码阶段使用的中间信息。设备缓冲区可以附加到不同的解码器状态,这有助于在实现之间切换而无需分配额外的内存。
签名
nvjpegStatus_t nvjpegStateAttachDeviceBuffer(
nvjpegJpegState_t decoder_state,
nvjpegBufferDevice_t device_buffer);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 解码器状态。 |
|
输入 |
主机/设备 |
nvJPEG 设备缓冲区容器。设备指针存储在主机结构中。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.31. nvjpegBufferDeviceRetrieve()
从 nvJPEG 设备缓冲区句柄检索设备内存指针和大小。允许应用程序在解码完成后重复使用内存。
签名
nvjpegStatus_t nvjpegBufferDeviceRetrieve(
nvjpegBufferDevice_t buffer,
size_t* size,
void** ptr);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 设备缓冲区容器。 |
|
输入/输出 |
主机 |
设备缓冲区大小(以字节为单位)。 |
|
输入/输出 |
主机 |
指向设备缓冲区的指针。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.32. nvjpegBufferDeviceResize()
将设备缓冲区调整为指定大小(以字节为单位)。此 API 可用于将设备缓冲区预分配为较大的值,并避免在解码期间调用分配器。
签名
nvjpegStatus_t nvjpegBufferDeviceResize(nvjpegBufferDevice_t buffer,
size_t size,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 设备缓冲区容器。 |
|
输入 |
主机 |
设备缓冲区的大小(以字节为单位)。 |
|
输入 |
主机 |
当使用流有序分配器初始化 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.33. nvjpegDecodeParamsCreate()
创建参数句柄。可以编程的参数包括:输出格式、ROI 解码、CMYK 到 RGB 转换。
签名
nvjpegStatus_t nvjpegDecodeParamsCreate(
nvjpegHandle_t handle,
nvjpegDecodeParams_t *decode_params);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
解码输出参数。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.1.34. nvjpegDecodeParamsDestroy()
销毁 decode_params
句柄。
签名
nvjpegStatus_t nvjpegDecodeParamsDestroy(
nvjpegDecodeParams_t *decode_params);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
解码输出参数。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2. 检索编码图像信息 API
用于检索编码图像信息的辅助函数。
2.3.2.1. nvjpegGetImageInfo()
解码 JPEG 标头并检索有关图像的基本信息。
签名
nvjpegStatus_t nvjpegGetImageInfo(
nvjpegHandle_t handle,
const unsigned char *data,
size_t length,
int *nComponents,
nvjpegChromaSubsampling_t *subsampling,
int *widths,
int *heights);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
指向编码数据的指针。 |
|
输入 |
主机 |
编码数据的大小(以字节为单位)。 |
|
输出 |
主机 |
jpeg 编码数据中的通道数。 |
|
输出 |
主机 |
1 通道或 3 通道编码的色度子采样。 |
|
输出 |
主机 |
指向大小为 NVJPEG_MAX_COMPONENT 的数组的第一个元素的指针,其中将保存每个通道的宽度(最多 NVJPEG_MAX_COMPONENT)。如果未对通道进行编码,则对应的值将为零。 |
|
输出 |
主机 |
指向大小为 NVJPEG_MAX_COMPONENT 的数组的第一个元素的指针,其中将保存每个通道的高度(最多 NVJPEG_MAX_COMPONENT)。如果未对通道进行编码,则对应的值将为零。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2. nvJPEG 流 API
这些函数在主机上存储解析的比特流数据。
2.3.2.2.1. nvjpegJpegStreamParse()
解析比特流并将元数据存储在 jpeg_stream
结构中。
签名
nvjpegStatus_t nvjpegJpegStreamParse(
nvjpegHandle_t handle,
const unsigned char *data,
size_t length,
int save_metadata,
int save_stream,
nvjpegJpegStream_t jpeg_stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
指向比特流的指针。 |
|
输入 |
主机 |
比特流大小。 |
|
输入 |
主机 |
(未启用。标记为将来使用)。如果不为 0,则 JPEG 流元数据(标头、App 标记等)将保存在内部 |
|
输入 |
主机 |
如果不为 0,则整个 JPEG 流将被复制到内部 JpegStream 结构中,并且在此调用之后将不再需要指向 JPEG 文件数据的指针。如果为 0,则 |
|
输入/输出 |
主机/设备 |
存储已解析的比特流信息的 nvJPEG 比特流句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.2. nvjpegJpegStreamParseHeader()
仅解析比特流的标头,并将标头信息存储在 jpeg_stream
结构中。
签名
nvjpegStatus_t nvjpegJpegStreamParseHeader(
nvjpegHandle_t handle,
const unsigned char *data,
size_t length,
nvjpegJpegStream_t jpeg_stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
指向比特流的指针。 |
|
输入 |
主机 |
比特流大小。 |
|
输入/输出 |
主机/设备 |
存储已解析的比特流信息的 nvJPEG 比特流句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.3. nvjpegJpegStreamParseTables()
用于解码使用 JPEG 压缩的 TIFF 文件。解析 JPEG 表比特流并将 JPEG 表存储在 jpeg_stream
中
签名
nvjpegStatus_t nvjpegJpegStreamParseHeader(
nvjpegHandle_t handle,
const unsigned char *data,
size_t length,
nvjpegJpegStream_t jpeg_stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
指向 JPEG 表比特流的指针。可以设置为 NULL 以重置 JPEG 表。 |
|
输入 |
主机 |
JPEG 表比特流大小。 |
|
输入/输出 |
主机 |
存储已解析的比特流信息的 nvJPEG 比特流句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.4. nvjpegJpegStreamGetFrameDimensions()
从比特流中提取 JPEG 帧维度。
签名
nvjpegStatus_t nvjpegJpegStreamGetFrameDimensions(
nvjpegJpegStream_t jpeg_stream,
unsigned int* width,
unsigned int* height);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
帧高度。 |
|
输出 |
主机 |
帧宽度。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.5. nvjpegJpegStreamGetComponentsNum()
从比特流中提取 JPEG 帧维度。
签名
nvjpegStatus_t nvjpegJpegStreamGetComponentsNum(
nvjpegJpegStream_t jpeg_stream,
unsigned int* components_num);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
输入中编码的通道数。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.6. nvjpegJpegStreamGetComponentDimensions()
从比特流中提取组件维度。
签名
nvjpegStatus_t nvjpegJpegStreamGetComponentDimensions(
nvjpegJpegStream_t jpeg_stream,
unsigned int component,
unsigned int* width,
unsigned int* height)
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输入 |
主机 |
组件索引。 |
|
输出 |
主机 |
组件高度。 |
|
输出 |
主机 |
组件宽度。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.7. nvjpegJpegStreamGetChromaSubsampling()
从 jpeg_stream
获取色度二次采样。对于灰度(单通道)图像,它返回 NVJPEG_CSS_GRAY。对于 3 通道图像,它会尝试根据比特流中存在的采样信息分配已知的色度二次采样值之一,否则返回 NVJPEG_CSS_UNKNOWN。如果通道数为 2 或 4,则返回 NVJPEG_CSS_UNKNOWN。
签名
nvjpegStatus_t nvjpegJpegStreamGetChromaSubsampling(
nvjpegJpegStream_t jpeg_stream,
nvjpegChromaSubsampling_t* chroma_subsampling);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
1 通道或 3 通道编码的色度子采样。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.8. nvjpegJpegStreamGetJpegEncoding()
此函数从 jpeg_stream
获取 JPEG 编码类型。对于基线图像,它返回 NVJPEG_ENCODING_BASELINE_DCT。对于渐进式图像,它返回 NVJPEG_ENCODING_PROGRESSIVE_DCT_HUFFMAN。
签名
nvjpegStatus_t nvjpegJpegStreamGetJpegEncoding(
nvjpegJpegStream_t jpeg_stream,
nvjpegJpegEncoding_t* jpeg_encoding);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
输入比特流句柄。 |
|
输出 |
主机 |
获取的编码类型——基线或渐进式。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.9. nvjpegJpegStreamGetExifOrientation()
从比特流中提取 Exif 方向。如果 Exif 标记/方向信息不存在,则返回 NVJPEG_ORIENTATION_UNKNOWN
。
签名
nvjpegStatus_t NVJPEGAPI nvjpegJpegStreamGetExifOrientation(
nvjpegJpegStream_t jpeg_stream,
nvjpegExifOrientation_t *orientation_flag);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
JPEG 流中的 Exif 方向。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.2.2.10. nvjpegJpegStreamGetSamplePrecision()
从比特流中提取样本精度(位深度)。
签名
nvjpegStatus_t NVJPEGAPI nvjpegJpegStreamGetSamplePrecision(
nvjpegJpegStream_t jpeg_stream,
unsigned int *precision);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
样本精度值。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3. 解码 API—单阶段
用于在单阶段解码单个图像或批量图像的函数。
2.3.3.1. nvjpegDecode()
解码单个图像,并将解码后的图像以所需格式写入输出缓冲区。此函数相对于主机是异步的。此函数的所有 GPU 任务都将提交到提供的流。
从 CUDA 11 开始,nvjpegDecode()
为给定图像选择最佳可用后端,用户不再对此进行控制。如果需要选择后端,请考虑使用 nvjpegDecodeJpeg()。这是 CUDA 11 中添加的新 API,允许用户控制后端。
签名
nvjpegStatus_t nvjpegDecode(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
const unsigned char *data,
size_t length,
nvjpegOutputFormat_t output_format,
nvjpegImage_t *destination,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
图像状态句柄。 |
|
输入 |
主机 |
指向编码数据的指针。 |
|
输入 |
主机 |
编码数据的大小(以字节为单位)。 |
|
输入 |
主机 |
将保存解码输出的格式。 |
|
输入/输出 |
主机/设备 |
指向描述输出目标的结构的指针。此结构应位于主机 (CPU) 上,但此结构中的指针应指向设备(即 GPU)内存。请参阅 |
|
输入 |
主机 |
所有 GPU 工作将提交到的 CUDA 流。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.2. nvjpegDecodeBatchedInitialize()
此函数初始化批量解码器状态。初始化参数包括批处理大小、最大 CPU 线程数以及将保存解码图像的特定输出格式。此函数应在解码批量图像之前调用一次。任何当前正在运行的批量解码应在调用此函数之前完成。
签名
nvjpegStatus_t nvjpegDecodeBatchedInitialize(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
int batch_size,
int max_cpu_threads,
nvjpegOutputFormat_t output_format);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
图像状态句柄。 |
|
输入 |
主机 |
批处理大小。 |
|
输入 |
主机 |
此参数不再被库使用。 |
|
输入 |
主机 |
将保存解码输出的格式。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.3. nvjpegDecodeBatched()
解码批量图像,并将它们写入 destination
参数中描述的缓冲区,格式在 nvjpegDecodeBatchedInitialize()
函数中提供。此函数相对于主机是异步的。此函数的所有 GPU 任务都将提交到提供的流。
签名
nvjpegStatus_t nvjpegDecodeBatched(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
const unsigned char *const *data,
const size_t *lengths,
nvjpegImage_t *destinations,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
图像状态句柄。 |
|
输入 |
主机 |
指向输入数据数组的第一个元素的指针。数组的大小假定为提供给 |
|
输入 |
主机 |
指向输入大小数组的第一个元素的指针。数组的大小假定为提供给 |
|
输入/输出 |
主机/设备 |
指向输出描述符数组的第一个元素的指针。数组的大小假定为提供给 |
|
输入 |
主机 |
所有 GPU 工作将提交到的 CUDA 流。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.4. nvjpegDecodeBatchedEx()
此 API 帮助解码具有 ROI 的批量图像,并将它们写入 destination
参数中描述的缓冲区,格式在 nvjpegDecodeBatchedInitialize()
函数中提供。此函数相对于主机是异步的。此函数的所有 GPU 任务都将提交到提供的流。
签名
nvjpegStatus_t nvjpegDecodeBatchedEx(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
const unsigned char *const *data,
const size_t *lengths,
nvjpegImage_t *destinations,
nvjpegDecodeParams_t *decode_params,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvjpeg 库句柄。 |
|
输入 |
主机 |
图像状态句柄。 |
|
输入 |
主机 |
指向输入数据数组的第一个元素的指针。数组的大小假定为提供给 |
|
输入 |
主机 |
指向输入大小数组的第一个元素的指针。 |
|
输入/输出 |
主机/设备 |
指向输出描述符数组的第一个元素的指针。数组的大小假定为提供给 |
|
输入 |
主机 |
设置 ROI 解码参数 |
|
输入 |
主机 |
所有 GPU 工作将提交到的 CUDA 流。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.5. nvjpegDecodeBatchedSupported()
此 API 帮助确定图像是否可以由 nvjpegDecodeBatched() 解码。用户可以使用 nvjpegJpegStreamParseHeader() 解析比特流标头,然后调用此 API 以确定图像是否可以解码。
签名
nvjpegStatus_t nvjpegDecodeBatchedSupported(
nvjpegHandle_t handle,
nvjpegJpegStream_t jpeg_stream,
int* is_supported);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvjpeg 库句柄。 |
|
输入 |
主机 |
比特流元数据。 |
|
输出 |
主机 |
返回值 0 表示比特流可以由 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.6. nvjpegDecodeBatchedSupportedEx()
此 API 帮助确定图像是否可以由 nvjpegDecodeBatched() 解码。用户可以使用 nvjpegJpegStreamParseHeader() 解析比特流标头,并在解码参数中设置 ROI,然后调用此 API 以确定图像是否可以解码。
签名
nvjpegStatus_t nvjpegDecodeBatchedSupportedEx(
nvjpegHandle_t handle,
nvjpegJpegStream_t jpeg_stream,
nvjpegDecodeParams_t decode_params,
int* is_supported);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvjpeg 库句柄。 |
|
输入 |
主机 |
比特流元数据。 |
|
输入 |
主机 |
设置 ROI 解码参数。 |
|
输出 |
主机 |
返回值 0 表示比特流可以由 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.7. nvjpegDecodeBatchedPreAllocate()
这是一个实验性 API,可以与 nvjpegDecodeBatched() 一起使用。当解码具有不同大小和色度二次采样的图像时,性能受限于库重复调用 CUDA 来释放/分配设备内存。此 API 尝试通过在实际解码之前分配设备内存来避免此问题。用户可以选择使用不太可能超过的值调用此 API,当调用 nvjpegDecodeBatched() 时。
注意
注意:此功能仅在使用 NVJPEG_BACKEND_HARDWARE 实例化 nvjpegHandle_t
时可用。目前对于其他后端来说是空操作。
此 API 仅提供初始分配的提示。如果在解码时图像尺寸超过提供的值,则库将调整设备缓冲区的大小。
如果正在解码的图像具有不同的色度二次采样,则应将 chroma_subsampling
字段设置为 NVJPEG_CSS_444,以确保设备内存可以重复使用。
签名
nvjpegStatus_t nvjpegDecodeBatchedPreAllocate(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
int batch_size,
int width,
int height,
nvjpegChromaSubsampling_t chroma_subsampling,
nvjpegOutputFormat_t output_format);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
图像状态句柄。 |
|
输入 |
主机 |
批处理大小。 |
|
输入 |
主机 |
将解码的图像的最大宽度。 |
|
输入 |
主机 |
将解码的图像的最大高度。 |
|
输入 |
主机 |
图像的色度二次采样。 |
|
输入 |
主机 |
将保存解码输出的格式。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.3.8. nvjpegDecodeBatchedParseJpegTables()
与批量解码 API 一起使用,用于从 TIFF 文件解码 JPEG 比特流。此函数解析 JPEG 表比特流以提取 JPEG 表。外部 Huffman 表和量化表将应用于批处理中的所有 JPEG 比特流。
签名
nvjpegStatus_t nvjpegDecodeBatchedParseJpegTables(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
const unsigned char *data,
const size_t length);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机/设备 |
图像状态句柄。 |
|
输入 |
主机 |
指向 JPEG 表比特流的指针。可以设置为 NULL 以重置 jpeg 表。 |
|
输入 |
主机 |
JPEG 表比特流大小。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.4. 解码 API—解耦解码
这组解码 API 使用比特流句柄、解码参数句柄、pinned 缓冲区和设备缓冲区句柄作为输入,从而将 JPEG 比特流解析、缓冲区管理和设置解码器参数与解码过程本身解耦。
目前仅提供多阶段解码。多阶段解耦单图像解码包括三个阶段
主机
混合
设备
上述每个解码都根据其各自的语义进行。不同图像上的阶段可以同时使用不同的解码状态句柄进行,同时可以共享一些辅助对象。请参阅各个阶段描述中的语义详细信息。
以下是使用解耦 API 的几个示例。
以下代码片段解释了如何使用 API 预取处理的主机阶段:首先在主机上完成所有主机工作,然后将剩余的解码工作提交给设备。
#define BATCH_SIZE 2
nvjpegHandle_t nvjpeg_handle;
nvjpegJpegState_t nvjpeg_decoder_state[BATCH_SIZE];
nvjpegBufferPinned_t nvjpeg_pinned_buffer[BATCH_SIZE];
nvjpegBufferDevice_t nvjpeg_device_buffer;
nvjpegJpegStream_t nvjpeg_jpeg_stream[BATCH_SIZE];
nvjpegDecodeParams_t nvjpeg_decode_params;
nvjpegJpegDecoder_t nvjpeg_decoder;
nvjpegBackend_t impl = NVJPEG_BACKEND_DEFAULT;
unsigned char* bitstream[BATCH_SIZE] // pointers jpeg bitstreams
size_t length[BATCH_SIZE]; // bitstream sizes
nvjpegImage_t output_images[BATCH_SIZE];
// all the images in the batch will be decoded as RGBI
nvjpegDecodeParamsSetOutputFormat(nvjpeg_decode_params,NVJPEG_OUTPUT_RGBI );
// call host phase for two bitstreams
for (int i = 0; i < BATCH_SIZE; i++)
{
nvjpegJpegStreamParse(nvjpeg_handle, bitstream[i], length[i], 0, 0, nvjpeg_jpeg_stream[i]);
nvjpegStateAttachPinnedBuffer(nvjpeg_decoder_state[i], nvjpeg_pinned_buffer[i]);
nvjpegDecodeJpegHost(nvjpeg_handle, nvjpeg_decoder, nvjpeg_decoder_state[i], nvjpeg_decode_params, nvjpeg_jpeg_stream[i])
}
for (int i = 0; i < BATCH_SIZE; i++)
{
// same device buffer being used for decoding bitstreams
nvjpegStateAttachDeviceBuffer(nvjpeg_decoder_state[i], nvjpeg_device_buffer);
// cuda stream set to NULL
nvjpegDecodeJpegTransferToDevice(nvjpeg_handle, nvjpeg_decoder, nvjpeg_decoder_state[i], nvjpeg_jpeg_stream[i], NULL);
// cuda stream set to NULL
nvjpegDecodeJpegDevice(nvjpeg_handle, nvjpeg_decoder, nvjpeg_decoder_state[i], &output_images[i], NULL);
cudaDeviceSynchronize();
}
以下代码片段解释了如何在 nvJPEG 解码器句柄 的两个实例之间共享 pinned 缓冲区和设备缓冲区。
#define BATCH_SIZE 4
nvjpegHandle_t nvjpeg_handle;
nvjpegJpegDecoder_t nvjpeg_decoder_impl1;
nvjpegJpegDecoder_t nvjpeg_decoder_impl2;
nvjpegJpegState_t nvjpeg_decoder_state_impl1;
nvjpegJpegState_t nvjpeg_decoder_state_impl2;
nvjpegBufferPinned_t nvjpeg_pinned_buffer;
nvjpegBufferDevice_t nvjpeg_device_buffer;
nvjpegJpegStream_t nvjpeg_jpeg_stream;
nvjpegDecodeParams_t nvjpeg_decode_params;
unsigned char* bitstream[BATCH_SIZE] // pointers jpeg bitstreams
size_t length[BATCH_SIZE]; // bitstream sizes
// populate bitstream and length correctly for this code to work
nvjpegImage_t output_images[BATCH_SIZE];
// allocate device memory for output images, for this snippet to work
nvjpegStateAttachPinnedBuffer(nvjpeg_decoder_state_impl1, nvjpeg_pinned_buffer);
nvjpegStateAttachPinnedBuffer(nvjpeg_decoder_state_impl2, nvjpeg_pinned_buffer);
nvjpegStateAttachDeviceBuffer(nvjpeg_decoder_state_impl1, nvjpeg_device_buffer);
nvjpegStateAttachDeviceBuffer(nvjpeg_decoder_state_impl2, nvjpeg_device_buffer);
// all the images in the batch will be decoded as RGBI
nvjpegDecodeParamsSetOutputFormat(nvjpeg_decode_params,NVJPEG_OUTPUT_RGBI );
for (int i = 0; i < BATCH_SIZE; i++)
{
nvjpegJpegStreamParse(nvjpeg_handle,bitstream[i],length[i],0,0,nvjpeg_jpeg_stream);
// decide which implementation to use, based on image size
unsigned int frame_width;
unsigned int frame_height;
nvjpegJpegStreamGetFrameDimensions(nvjpeg_jpeg_stream,&frame_width, &frame_height));
nvjpegJpegDecoder_t& decoder = (frame_height*frame_width > 1024 * 768 ) ? nvjpeg_decoder_impl2: nvjpeg_decoder_impl1;
nvjpegJpegState_t& decoder_state = (frame_height * frame_width > 1024 * 768) ? nvjpeg_decoder_state_impl2:nvjpeg_decoder_state_impl1;
nvjpegDecodeJpegHost(nvjpeg_handle,decoder,decoder_state,nvjpeg_decode_params,nvjpeg_jpeg_stream);
// cuda stream set to NULL
nvjpegDecodeJpegTransferToDevice(nvjpeg_handle,decoder,decoder_state,nvjpeg_jpeg_stream,NULL);
// cuda stream set to NULL
nvjpegDecodeJpegDevice(nvjpeg_handle,nvjpeg_decoder,decoder_state,&output_images, NULL);
cudaDeviceSynchronize();
}
2.3.4.1. nvjpegDecodeJpegHost()
这是解耦解码过程的第一阶段。它完全在主机上完成,因此相对于主机是同步的。
如果 pinned 缓冲区附加到解码器状态,则 pinned 缓冲区对象将用于分配主机解码阶段所需的 pinned 内存。如果 pinned 缓冲区对象已处理所需的 pinned 内存量,则不会进行分配。
如果未附加 pinned 缓冲区对象,则状态将使用堆主机内存来分配主机处理所需的内存。
在此阶段,设备不参与。因此,设备选择、设备初始化和设备内存初始化可以在解码过程的稍后阶段完成。
此函数作用于已解析的流。调用 nvjpegJpegStreamParse() 函数后可用的已解析流句柄应提供给此函数。
签名
nnvjpegStatus_t nvjpegDecodeJpegHost(
nvjpegHandle_t handle,
nvjpegJpegDecoder_t decoder,
nvjpegJpegState_t decoder_state,
nvjpegDecodeParams_t decode_params,
nvjpegJpegStream_t jpeg_stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
nvJPEG 解码器句柄。 |
|
输入 |
主机 |
nvJPEG 解码器状态句柄。 |
|
输入 |
主机 |
解码输出属性的句柄。 |
|
输入 |
主机 |
已解析的比特流数据的句柄。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.4.2. nvjpegDecodeJpegTransferToDevice()
此阶段包含主机和设备操作。因此,它相对于主机是同步和异步操作的混合。所有设备操作都将提交到提供的流。
此阶段应仅在主机阶段之后调用,并使用相同的解码器句柄、解码器状态句柄和已解析的 jpeg 流句柄。设备应已初始化,并且设备缓冲区应在使用 nvjpegStateAttachDeviceBuffer() 调用此 API 之前附加到 decoder_state
句柄。如果需要,此设备缓冲区对象将调整为所需的内存量。对于主机内存缓冲区,此阶段将使用主机阶段中使用的任何缓冲区:附加的 pinned 缓冲区或状态的主机内存缓冲区。
签名
nvjpegStatus_t nvjpegDecodeJpegTransferToDevice(
nvjpegHandle_t handle,
nvjpegJpegDecoder_t decoder,
nvjpegJpegState_t decoder_state,
nvjpegJpegStream_t jpeg_stream,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
nvJPEG 解码器句柄。 |
|
输入 |
主机 |
nvJPEG 解码器状态句柄。 |
|
输入 |
主机 |
已解析的比特流数据的句柄。 |
|
输入 |
主机 |
所有 GPU 任务将提交到的 CUDA 流。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.4.3. nvjpegDecodeJpegDevice()
此阶段由主要在设备上发生的解码操作组成(不进行重要的主机端计算)。因此,此阶段相对于主机是异步的。此阶段应在给定 decoder_state
句柄和解码器句柄的 nvjpegDecodeJpegTransferToDevice() 之后调用。
在此函数调用中,不使用主机内存缓冲区,因此如果 pinned 缓冲区附加到状态,则可以在其他地方重用它。请注意,此时不再需要 Jpeg 流句柄,因为设备解码所需的部分将在上一阶段复制到设备内存中。
签名
nvjpegStatus_t nvjpegDecodeJpegDevice(
nvjpegHandle_t handle,
nvjpegJpegDecoder_t decoder,
nvjpegJpegState_t decoder_state,
nvjpegImage_t *destination,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
nvJPEG 解码器句柄。 |
|
输入 |
主机 |
nvJPEG 解码器状态句柄。 |
|
输入/输出 |
主机/设备 |
指向描述输出目标的结构的指针。此结构应位于主机上,但此结构中的指针应指向设备内存。有关详细信息,请参阅 nvJPEG 图像。 |
|
输入 |
主机 |
所有 GPU 任务将提交到的 CUDA 流。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.4.4. nvjpegDecodeJpeg()
这是一个单阶段 API,在创建 nvjpegJpegDecoder_t
对象时具有选择 nvJPEG 后端的灵活性。用户可以选择调用此 API,而不是分别调用 nvjpegDecodeJpegHost()、nvjpegDecodeJpegTransferToDevice() 和 nvjpegDecodeJpegDevice() 这三个 API。
在调用此 API 之前,需要将设备缓冲区附加到解码器状态。pinned 缓冲区是可选的。如果未附加 pinned 缓冲区,则堆内存将用于主机处理。
此函数作用于已解析的流。调用 nvjpegJpegStreamParse() 函数后可用的已解析流句柄应提供给此函数。
签名
nvjpegStatus_t nvjpegDecodeJpeg(
nvjpegHandle_t handle,
nvjpegJpegDecoder_t decoder,
nvjpegJpegState_t decoder_state,
nvjpegJpegStream_t jpeg_bitstream,
nvjpegImage_t *destination,
nvjpegDecodeParams_t decode_params,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
nvJPEG 解码器句柄。 |
|
输入 |
主机 |
nvJPEG 解码器状态句柄。 |
|
输入 |
主机 |
已解析的比特流数据的句柄。 |
|
输入/输出 |
主机/设备 |
指向描述输出目标的结构的指针。此结构应位于主机上,但此结构中的指针应指向设备内存。有关详细信息,请参阅 nvJPEG 图像。 |
|
输入 |
主机 |
存储解码输出属性的句柄。 |
|
输入 |
主机 |
所有 GPU 任务将提交到的 CUDA 流。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.5. nvJPEG 解码参数
此类别 API 用于设置解码参数。这些 API 应与 解码 API—解耦解码 中定义的解码 API 一起使用。
2.3.5.1. nvjpegDecodeParamsSetOutputFormat()
此函数用于设置解码输出格式。请参阅 单图像解码 的步骤 6 中描述的 nvjpegOutputFormat_t
。nvjpegOutputFormat_t
的输出参数如果未使用此 API 设置,则默认为 NVJPEG_OUTPUT_UNCHANGED
。
签名
nvjpegStatus_t nvjpegDecodeParamsSetOutputFormat(
nvjpegDecodeParams_t decode_params,
nvjpegOutputFormat_t output_format);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
请参阅 单图像解码 的步骤 6。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.5.2. nvjpegDecodeParamsSetROI()
此函数启用仅感兴趣区域 (ROI-only) 解码。要禁用仅 ROI,即解码整个图像,请设置
offset_x
= 0,offset_y
= 0,roi_width
= -1,以及roi_height
= -1.
注意
默认情况下禁用 ROI 解码。当使用 NVJPEG_BACKEND_HARDWARE 创建 nvJPEG 解码器句柄时,不支持 ROI 解码。
ROI 窗口不能超出图像边界。即
offset_x
不能低于零,或者offset_x + roi_width
不能大于 JPEG 图像宽度。
如果输出格式为 NVJPEG_OUTPUT_YUV 或 NVJPEG_OUTPUT_UNCHANGED,则 offset_x
和 offset_y
值必须是最大二次采样因子的倍数,如 JPEG 标准中定义的那样。
签名
nvjpegStatus_t nvjpegDecodeParamsSetROI(
nvjpegDecodeParams_t decode_params,
int offset_x,
int offset_y,
int roi_width,
int roi_height);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
相对于左上角的水平方向图像偏移。 |
|
输入 |
主机 |
相对于左上角的垂直方向图像偏移。 |
|
输入 |
主机 |
相对于 |
|
输入 |
主机 |
相对于 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.5.3. nvjpegDecodeParamsSetAllowCMYK()
如果启用,nvJPEG 库会假定具有 4 个编码颜色分量的 JPEG 处于 CMYK 色彩空间,并启用转换为 RGB/YUV 色彩空间。默认情况下禁用 CMYK 到 RGB 的转换。转换基于减色方案——此行为与 OpenCV 对 4 分量 JPEG 的处理相匹配。
签名
nvjpegStatus_t nvjpegDecodeParamsSetAllowCMYK(
nvjpegDecodeParams_t decode_params,
int allow_cmyk);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
启用 CMYK 到 RGB 的转换。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.5.4. nvjpegDecodeParamsSetScaleFactor()
允许用户缩放解码输出。
注意
此功能目前仅在使用 NVJPEG_BACKEND_HARDWARE 创建 nvJPEG 解码器句柄时受支持。
签名
nvjpegStatus_t nvjpegDecodeParamsSetScaleFactor(
nvjpegDecodeParams_t decode_params,
nvjpegScaleFactor_t scale_factor);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
设置解码输出的缩放因子。 |
默认情况下,缩放因子设置为 NVJPEG_SCALE_NONE。支持的值在 nvJPEG 缩放因子 中列出。
当设置缩放因子值时,建议的目标参数分配如下
使用 nvjpegGetImageInfo() 或 nvjpegJpegStreamGetFrameDimensions() 提取每个通道的维度。
令 height[NVJPEG_MAX_COMPONENT] 和 width[NVJPEG_MAX_COMPONENT] 为 2 个数组,它们存储高度和宽度。这些数组的索引对应于通道 ID。
-
对于通道 c,缩放后的维度计算如下
scaled_height[c] = (height[c] + rounding_factor - 1)/rounding_factor
scaled_width[c] = (width[c] + rounding_factor - 1)/rounding_factor
当 scale_factor = NVJPEG_SCALE_NONE 时,rounding_factor = 1
当 scale_factor = NVJPEG_SCALE_1_BY_2 时,rounding_factor = 2
当 scale_factor = NVJPEG_SCALE_1_BY_4 时,rounding_factor = 4
当 scale_factor = NVJPEG_SCALE_1_BY_8 时,rounding_factor = 8
对于 output_format NVJPEG_OUTPUT_Y |
destination.pitch[0] 应至少为: width[0] |
destination.channel[0] 的大小应至少为: destination.pitch[0]*height[0] |
对于 output_format |
destination.pitch[c] 应至少为 |
destination.channel[c] 的大小应至少为 |
NVJPEG_OUTPUT_YUV |
c = 0、1、2 的 width[c] |
c = 0、1、2 的 destination.pitch[c]*height[c] |
NVJPEG_OUTPUT_RGB 和 NVJPEG_OUTPUT_BGR |
c = 0、1、2 的 width[0] |
c = 0、1、2 的 destination.pitch[0]*height[0] |
NVJPEG_OUTPUT_RGBI 和 NVJPEG_OUTPUT_BGRI |
width[0]*3 |
destination.pitch[0]*height[0] |
NVJPEG_OUTPUT_UNCHANGED |
c = [ 0, nComponents - 1 ] 的 width[c] |
c = [ 0, nComponents - 1] 的 destination.pitch[c]*height[c] |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.5.5. nvjpegDecodeParamsSetExifOrientation()
此函数用于根据 Exif 方向参数生成解码输出。当启用 ExifOrientation 时,应根据旋转后的维度分配输出缓冲区。如果方向设置为 NVJPEG_ORIENTATION_UNKNOWN
,则库将默认为 NVJPEG_ORIENTATION_HORIZONTAL
。
ROI 解码和 EXIF 旋转
Exif 旋转和 ROI 解码可以同时启用。ROI 坐标应位于旋转空间中。
签名
nvjpegStatus_t nvjpegDecodeParamsSetExifOrientation(
nvjpegDecodeParams_t decode_params,
nvjpegExifOrientation_t orientation);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
设置解码输出的 Exif 方向。 |
返回值
nvjpegStatus_t
— 错误代码,如 nvJPEG API 返回代码 中指定。
2.3.6. nvJPEG API 返回代码
nvJPEG API 遵循以下返回代码及其指示
typedef enum {
NVJPEG_STATUS_SUCCESS = 0,
NVJPEG_STATUS_NOT_INITIALIZED = 1,
NVJPEG_STATUS_INVALID_PARAMETER = 2,
NVJPEG_STATUS_BAD_JPEG = 3,
NVJPEG_STATUS_JPEG_NOT_SUPPORTED = 4,
NVJPEG_STATUS_ALLOCATOR_FAILURE = 5,
NVJPEG_STATUS_EXECUTION_FAILED = 6,
NVJPEG_STATUS_ARCH_MISMATCH = 7,
NVJPEG_STATUS_INTERNAL_ERROR = 8,
NVJPEG_STATUS_IMPLEMENTATION_NOT_SUPPORTED = 9
} nvjpegStatus_t;
返回的错误代码的描述
返回的错误(返回代码) |
描述 |
|
API 调用已成功完成。请注意,许多调用是异步的,一些错误可能仅在同步后才能看到。 |
|
库句柄未初始化。需要调用 |
|
传递了错误的参数。例如,空指针作为输入数据,或图像索引不在允许的范围内。 |
|
无法解析 JPEG 流。检查编码的 JPEG 流及其大小参数是否正确。 |
|
尝试解码 nvJPEG 库不支持的 JPEG 流。 |
|
用户提供的分配器函数(用于内存分配或释放内存)返回了非零代码。 |
|
设备任务执行期间出错。 |
|
设备功能不足以满足提供的输入参数集(输入参数如后端、编码流参数、输出格式)。 |
|
设备任务执行期间出错。 |
|
不支持。 |
|
比特流输入数据不完整 |
2.3.7. nvJPEG 色度二次采样
nvjpegGetImageInfo()
API 的输出之一是 nvjpegChromaSubsampling_t
。此参数是 enum
类型,其枚举器列表包含从编码的 JPEG 图像检索的色度二次采样属性。nvjpegGetImageInfo()
函数当前支持以下色度二次采样类型
typedef enum {
NVJPEG_CSS_444,
NVJPEG_CSS_422,
NVJPEG_CSS_420,
NVJPEG_CSS_440,
NVJPEG_CSS_411,
NVJPEG_CSS_410,
NVJPEG_CSS_GRAY,
NVJPEG_CSS_410V,
NVJPEG_CSS_UNKNOWN
} nvjpegChromaSubsampling_t;
2.3.8. 参考文档
请参阅 JPEG 标准:https://jpeg.org/jpeg/
2.4. nvJPEG 示例
nvJPEG 解码示例可以在这里找到:https://github.com/NVIDIA/CUDALibrarySamples/tree/master/nvJPEG/nvJPEG-Decoder
3. JPEG 编码
本节介绍 nvJPEG 库的编码函数。
3.1. 使用编码器
用户应在调用 nvJPEG 编码函数之前执行以下先决步骤。另请参阅 nvJPEG 编码器辅助 API 参考。
3.1.1. 编码参数
用户应使用 nvjpegEncoderParamsCreate()
函数创建编码参数结构。该函数将使用默认参数进行初始化。用户可以使用适当的 nvjpegEncoderParamsSet*()
函数来设置特定参数。
可以使用 nvjpegEncoderParamsSetQuality()
函数将质量参数设置为介于 1 到 100 之间的整数值,此质量参数将用作生成 JPEG 量化表的基准。
参数结构应传递给压缩函数。
注意
编码参数结构可以重复使用以同时压缩多个图像,但在正在进行的编码期间不应更改参数,否则编码结果将是未定义的。
3.1.2. 编码状态
用户应使用 nvjpegEncoderStateCreate()
函数创建编码状态结构。此函数将保存编码过程的中间缓冲区。此状态应传递给压缩函数。
注意
编码状态结构可以重复使用以编码一系列图像,但不应同时对具有相同编码状态的多个图像执行编码——否则编码结果将是未定义的。
3.1.3. 编码图像
nvJPEG 库提供了几个接口,用于以不同的格式和颜色空间压缩图像。 请参见下文。
3.1.3.1. nvjpegEncodeYUV
此函数的输入是 YUV 颜色空间中的图像。请参阅 nvjpegEncodeYUV()
。 source
参数应填充相应的 YUV 平面数据。 chroma_subsampling
参数应具有输入数据的色度二次采样。如果编码参数中的色度二次采样与输入色度二次采样相同,则用户的输入数据将直接用于 JPEG 压缩。否则,色度将被重新采样以匹配编码参数的色度二次采样。
应根据二次采样因子提供输入数据。也就是说,色度图像平面的尺寸应与相应的二次采样对齐。例如
图像尺寸:123x321
输入色度二次采样:NVJPEG_CSS_410
此色度二次采样的色度二次采样因子:4x2
-
鉴于以上情况,编码器库期望用户提供
Y 平面,尺寸:123 x 321
Cb 和 Cr 平面,尺寸:31 x 161
3.1.3.2. nvjpegEncodeImage
请参阅 nvjpegEncodeImage()
。此函数的输入,即应如何在 source
参数中提供数据,由 input_format
参数确定。对于交错格式(以 I 结尾),仅使用第一个通道。对于非交错格式,使用输入格式中的所有通道。
例如,如果用户具有尺寸为 W x H
的交错 RGB 图像,并连续存储,并且指向它的指针为 pImage
,则 source
应为
source.channel[0] = pImage
source.pitch[0] = W*3
当相同的图像以平面格式存储时,图像平面指针连续存储在数组 pImage[3]
中,则 source
应为
source.channel[0] = pImage[0]
source.channel[1] = pImage[1]
source.channel[2] = pImage[2]
source
参数中每个通道的 pitch
值应根据数据布局进行设置。
nvJPEG 库将执行到 YCbCr 的颜色转换,并将压缩结果。
3.1.4. 检索压缩流
通常,对于任何输入数据和参数,准确预测最终 JPEG 流的最终压缩数据大小是不可行的。 nvJPEG 库在编码时,将计算最终流的大小,在编码器状态中分配临时缓冲区,并将压缩数据保存在编码器状态的缓冲区中。为了获得最终的压缩 JPEG 流,用户应提供足够大的内存缓冲区来存储此压缩数据。有两种方法可以做到这一点
-
对给定参数和图像尺寸使用压缩 JPEG 流大小的上限
使用
nvjpegEncodeRetrieveBitstream()
函数在任何给定时间检索最大可能的 JPEG 流大小。在任何给定时间分配内存缓冲区。
使用其中一个编码函数编码图像。
成功编码后,使用
nvjpegEncodeRetrieveBitstream()
和分配的缓冲区从编码器状态检索压缩的 JPEG 流。
-
等待编码完成,并检索所需缓冲区的确切大小,如下所示
使用其中一个编码函数编码图像。
使用
nvjpegEncodeRetrieveBitstream()
函数检索压缩 JPEG 流的大小(以字节为单位)。分配至少此大小的内存缓冲区。
使用
nvjpegEncodeRetrieveBitstream()
函数使用压缩的 JPEG 流填充缓冲区。
注意
由于相同的编码图像状态可以重复使用以压缩一系列图像,因此 nvjpegEncodeRetrieveBitstream()
函数将返回上次压缩图像的结果。
3.1.5. JPEG 编码示例
请参阅下面的示例代码,以及 图 1 <nvjpeg-encode-examples__fig-nvjpeg-encode-example> 中所示的框图,了解如何使用 nvJPEG 编码器进行编码。

使用 nvJPEG 编码器的 JPEG 编码
nvjpegHandle_t nv_handle;
nvjpegEncoderState_t nv_enc_state;
nvjpegEncoderParams_t nv_enc_params;
cudaStream_t stream;
// initialize nvjpeg structures
nvjpegCreateSimple(&nv_handle);
nvjpegEncoderStateCreate(nv_handle, &nv_enc_state, stream);
nvjpegEncoderParamsCreate(nv_handle, &nv_enc_params, stream);
nvjpegImage_t nv_image;
// Fill nv_image with image data, let's say 640x480 image in RGB format
// Compress image
nvjpegEncodeImage(nv_handle, nv_enc_state, nv_enc_params,
&nv_image, NVJPEG_INPUT_RGB, 640, 480, stream);
// get compressed stream size
size_t length;
nvjpegEncodeRetrieveBitstream(nv_handle, nv_enc_state, NULL, &length, stream);
// get stream itself
cudaStreamSynchronize(stream);
std::vector<char> jpeg(length);
nvjpegEncodeRetrieveBitstream(nv_handle, nv_enc_state, jpeg.data(), &length, 0);
// write stream to file
cudaStreamSynchronize(stream);
std::ofstream output_file("test.jpg", std::ios::out | std::ios::binary);
output_file.write(jpeg.data(), length);
output_file.close();
3.2. nvJPEG 编码器类型声明
本节介绍 nvJPEG 编码器类型声明。
3.2.1. nvjpegInputFormat_t
typedef enum {
NVJPEG_INPUT_RGB = 3,
NVJPEG_INPUT_BGR = 4,
NVJPEG_INPUT_RGBI = 5,
NVJPEG_INPUT_BGRI = 6
} nvjpegInputFormat_t;
nvjpegInputFormat_t
枚举用于选择输入图像的颜色模型和像素格式。它用于在编码期间转换为 YCbCr。
成员 |
描述 |
NVJPEG_INPUT_RGB |
输入图像采用 RGB 颜色模型。像素格式为 RGB。 |
NVJPEG_INPUT_BGR |
输入图像采用 RGB 颜色模型。像素格式为 BGR。 |
NVJPEG_INPUT_RGBI |
输入图像采用 RGB 颜色模型。像素格式为交错 RGB。 |
NVJPEG_INPUT_BGRI |
输入图像采用 RGB 颜色模型。像素格式为交错 BGR。 |
3.2.2. nvjpegEncoderState_t
nvjpegEncoderState_t
结构存储用于压缩的中间缓冲区和变量。
3.2.3. nvjpegEncoderParams_t
nvjpegEncoderParams_t
结构存储 JPEG 编码参数。
3.3. nvJPEG 编码器辅助 API 参考
nvJPEG 编码器辅助函数用于初始化。
3.3.1. nvjpegEncoderStateCreate()
创建编码器状态,用于存储压缩中使用的中间缓冲区。
签名
nvjpegStatus_t nvjpegEncoderStateCreate(
nvjpegHandle_t handle,
nvjpegEncoderState_t *encoder_state,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄 |
|
输出 |
主机 |
指向编码器状态结构的指针,新状态将放置在此处。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.3.2. nvjpegEncoderStateDestroy()
销毁编码器状态。
签名
nvjpegStatus_t nvjpegEncoderStateDestroy(
nvjpegEncoderState_t encoder_state);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
将要释放的编码器状态结构。 |
3.3.3. nvjpegEncoderParamsCreate()
创建保存压缩参数的结构。
签名
nvjpegStatus_t nvjpegEncoderParamsCreate(
nvjpegHandle_t handle,
nvjpegEncoderParams_t *encoder_params,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输出 |
主机 |
指向将放置新参数结构的位置的指针。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.3.4. nvjpegEncoderParamsDestroy()
销毁编码器参数结构。
签名
nvjpegEncoderParamsDestroy(
nvjpegEncoderParams_t encoder_params);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
将要释放的编码器参数结构。 |
3.3.5. nvjpegEncoderParamsSetEncoding()
在编码器参数结构中设置参数质量。
签名
nvjpegStatus_t nvjpegEncoderParamsSetEncoding(
nvjpegEncoderParams_t encoder_params,
nvjpegJpegEncoding_t etype,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
编码类型选择(基线/渐进)。默认为基线。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.3.6. nvjpegEncoderParamsSetQuality()
在编码器参数结构中设置参数质量。
签名
nvjpegStatus_t nvjpegEncoderParamsSetQuality(
nvjpegEncoderParams_t encoder_params,
const int quality,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
介于 1 和 100 之间的整数质量值,其中 100 为最高质量。默认值为 70。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.3.7. nvjpegEncoderParamsSetOptimizedHuffman()
设置是否使用优化的霍夫曼编码。使用优化的霍夫曼编码可以产生更小的 JPEG 比特流大小,并具有相同的质量,但性能较慢。
签名
nvjpegStatus_t nvjpegEncoderParamsSetOptimizedHuffman(
nvjpegEncoderParams_t encoder_params,
const int optimized,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
如果此值为 0,则将使用非优化的霍夫曼编码。否则将使用优化版本。默认值为 0。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.3.8. nvjpegEncoderParamsSetSamplingFactors()
设置将用于 JPEG 压缩的色度二次采样。
签名
nvjpegStatus_t nvjpegEncoderParamsSetSamplingFactors(
nvjpegEncoderParams_t encoder_params,
const nvjpegChromaSubsampling_t chroma_subsampling,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
将用于 JPEG 压缩的色度二次采样。如果输入采用 YUV 颜色模型,并且 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.4. nvJPEG 编码器 API 参考
本节介绍 nvJPEG 编码器 API。
3.4.1. nvjpegEncodeGetBufferSize()
返回存储压缩 JPEG 流所需的最大可能缓冲区大小(对于给定的输入参数)。
签名
nvjpegStatus_t nvjpegEncodeGetBufferSize(
nvjpegHandle_t handle,
const nvjpegEncoderParams_t encoder_params,
int image_width,
int image_height,
size_t *max_stream_length);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
输入图像宽度。 |
|
输入 |
主机 |
输入图像高度。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.4.2. nvjpegEncodeYUV()
使用提供的参数将 YUV 颜色空间中的图像压缩为 JPEG 流,并将其存储在状态结构中。
签名
nvjpegStatus_t nvjpegEncodeYUV(
nvjpegHandle_t handle,
nvjpegEncoderState_t encoder_state,
const nvjpegEncoderParams_t encoder_params,
const nvjpegImage_t *source,
nvjpegChromaSubsampling_t chroma_subsampling,
int image_width,
int image_height,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
encoder_state |
|
输入 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
指向 |
|
输入 |
主机 |
chroma_subsampling |
|
输入 |
主机 |
输入图像宽度。 |
|
输入 |
主机 |
输入图像高度。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
输入数据的色度二次采样。
3.4.3. nvjpegEncodeImage()
签名
nvjpegStatus_t nvjpegEncodeImage(
nvjpegHandle_t handle,
nvjpegEncoderState_t encoder_state,
const nvjpegEncoderParams_t encoder_params,
const nvjpegImage_t *source,
nvjpegInputFormat_t input_format,
int image_width,
int image_height,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
encoder_state |
|
输入 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
指向 |
|
输入 |
主机 |
|
|
输入 |
主机 |
输入图像宽度。 |
|
输入 |
主机 |
输入图像高度。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.4.4. nvjpegEncodeRetrieveBitstream()
从先前在其中一个编码器函数中使用的编码器状态检索压缩流。
如果
data
参数为 NULL,则编码器将在length
参数中返回压缩流大小。如果
data
不为 NULL,则提供的length
参数应包含data
缓冲区大小。如果提供的
length
小于压缩流大小,则将返回错误。否则,压缩流将存储在data
缓冲区中,实际压缩缓冲区大小将存储在length
参数中。
签名
nvjpegStatus_t nvjpegEncodeRetrieveBitstream(
nvjpegHandle_t handle,
nvjpegEncoderState_t encoder_state,
unsigned char *data,
size_t *length,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
encoder_state |
|
输入/输出 |
主机 |
指向主机内存中将存储压缩流的缓冲区的指针。可以为 NULL(请参阅说明)。 |
|
输入/输出 |
主机 |
指向输入缓冲区大小的指针。返回时,NVJPEG 库会将实际压缩流大小存储在此参数中。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
3.4.5. nvjpegEncodeRetrieveBitstreamDevice()
从先前在其中一个编码器函数中使用的编码器状态检索压缩流。
data
参数应位于设备内存上如果
data
参数为 NULL,则编码器将在length
参数中返回压缩流大小。如果
data
不为 NULL,则提供的length
参数应包含data
缓冲区大小。如果提供的
length
小于压缩流大小,则将返回错误。否则,压缩流将存储在data
缓冲区中,实际压缩缓冲区大小将存储在length
参数中。
签名
nvjpegStatus_t nvjpegEncodeRetrieveBitstreamDevice(
nvjpegHandle_t handle,
nvjpegEncoderState_t encoder_state,
unsigned char *data,
size_t *length,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
encoder_state |
|
输入/输出 |
设备 |
指向设备内存中将存储压缩流的缓冲区的指针。可以为 NULL(请参阅说明)。 |
|
输入/输出 |
主机 |
指向输入缓冲区大小的指针。返回时,NVJPEG 库会将实际压缩流大小存储在此参数中。 |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
4. JPEG 转码
本节介绍 nvJPEG 库的转码功能。
4.1. nvJPEG 转码器辅助 API 参考
本节介绍 nvJPEG 转码器辅助 API。
4.1.1. nvjpegEncoderParamsCopyMetadata()
从解析的流中复制元数据(JFIF、APP、EXT 和 COM 标记)。
签名
nvjpegStatus_t nvjpegEncoderParamsCopyMetadata(
nvjpegEncoderState_t encoder_state,
nvjpegEncoderParams_t encode_params,
nvjpegJpegStream_t jpeg_stream,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
encoder_state |
主机 |
内部结构,用于存储压缩所需的临时缓冲区。 |
|
输出 |
主机 |
将用于压缩的编码器参数。 |
|
输入 |
主机 |
stream |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
输入解析的流。
4.1.2. nvjpegEncoderParamsCopyQuantizationTables()
签名
nvjpegStatus_t nvjpegEncoderParamsCopyQuantizationTables(
nvjpegEncoderParams_t encode_params,
nvjpegJpegStream_t jpeg_stream,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
输出 |
主机 |
将用于压缩的编码器参数。 |
|
输入 |
主机 |
stream |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
从解析的流中复制量化表。
4.1.3. nvjpegEncoderParamsCopyHuffmanTables() [已弃用]
签名
nvjpegStatus_t nvjpegEncoderParamsCopyHuffmanTables(
nvjpegEncoderState_t encoder_state,
nvjpegEncoderParams_t encode_params,
nvjpegJpegStream_t jpeg_stream,
cudaStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|
encoder_state |
主机 |
内部结构,用于存储压缩所需的临时缓冲区。 |
|
输出 |
主机 |
将用于压缩的编码器参数。 |
|
输入 |
主机 |
stream |
|
输入 |
主机 |
CUDA 流,所有必需的设备操作都将放置在此流中。 |
nvjpegEncoderParamsCopyHuffmanTables() 现已弃用。由于 JPEG 编码/解码过程中的精度差异,输入的霍夫曼表可能不再对正在编码的图像有效,并可能导致比特流损坏。
4.2. JPEG 转码示例
cudaStream_t stream;
// create library handle
nvjpegHandle_t handle;
nvjpegCreateSimple(&handle);
/////////////////////////////////// nvJPEG decoding ////////////////////////////////////////
// create bitstream object
nvjpegJpegStream_t jpeg_stream;
nvjpegJpegStreamCreate(handle, &jpeg_stream);
// parse jpeg stream
nvjpegJpegStreamParse(handle,
data_ptr,
data_size,
1, // save metadata in the jpegStream structure
0,
jpeg_stream);
// create decoder and decoder state
nvjpegJpegDecoder_t decoder;
nvjpegJpegState_t decoder_state;
nvjpegDecoderCreate(handle, NVJPEG_BACKEND_DEFAULT, &decoder);
nvjpegDecoderStateCreate(handle, decoder, &decoder_state);
// create and set up decoder parameters
nvjpegDecodeParams_t decode_params;
nvjpegDecodeParamsCreate(handle, &decode_params);
nvjpegDecodeParamsSetOutputFormat(decode_params, NVJPEG_OUTPUT_RGBI);
// decode image
nvjpegImage_t output_image;
nvjpegDecodeJpeg(handle, decoder, decode_params, jpeg_stream, decoder_state, &output_image, stream);
/////////////////////////////////// nvJPEG Transcode and encode API ///////////////////////////////////
nvjpegEncoderState_t encoder_state;
nvjpegEncoderParams_t encode_params;
// get encoding from the jpeg stream and copy it to the encode parameters
nvjpegJpegEncoding_t jpeg_encoding;
nvjpegJpegStreamGetJpegEncoding(jpeg_stream, &jpeg_encoding);
nvjpegEncoderParamsSetEncoding(encode_params, jpeg_encoding);
// copies according data to the encode parameters
nvjpegEncoderParamsCopyMetadata(encode_params, jpeg_stream, stream);
nvjpegEncoderParamsCopyQuantizationTables(encode_params, jpeg_stream, stream);
nvjpegEncoderParamsCopyHuffmanTables(encode_params, jpeg_stream, stream);
// retrieve frame dimensions
unsigned width, height;
nvjpegJpegStreamGetFrameDimensions(jpeg_stream, &width, &height);
// encode using encode parameters
nvjpegEncodeImage(nvjpeg_handle, encoder_state, encode_params, &output_image,
input_format, width, height, stream);
// get compressed stream size
size_t length;
nvjpegEncodeRetrieveBitstream(nvjpeg_handle, encoder_state, NULL, &length, stream);
// get stream itself
cudaStreamSynchronize(stream);
std::vector<char> jpeg(length);
nvjpegEncodeRetrieveBitstream(nvjpeg_handle, encoder_state, jpeg.data(), &length, 0);
请参阅下面的示例代码。
5. 已删除的 API 列表
nvjpegStatus_t nvjpegDecodePhaseOne(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
const unsigned char *data,
size_t length,
nvjpegOutputFormat_t output_format,
cudaStream_t stream);
nvjpegStatus_t nvjpegDecodePhaseTwo(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
cudaStream_t stream);
nvjpegStatus_t nvjpegDecodePhaseThree(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
nvjpegImage_t *destination,
cudaStream_t stream);
nvjpegStatus_t nvjpegDecodeBatchedPhaseOne(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
const unsigned char *data,
size_t length,
int image_idx,
int thread_idx,
cudaStream_t stream);
nvjpegStatus_t nvjpegDecodeBatchedPhaseTwo(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
cudaStream_t stream);
nvjpegStatus_t nvjpegDecodeBatchedPhaseThree(
nvjpegHandle_t handle,
nvjpegJpegState_t jpeg_handle,
nvjpegImage_t *destinations,
cudaStream_t stream);
以下 API 从 CUDA 11.0 开始已删除
6. 已知问题
使用 NVJPEG_BACKEND_GPU_HYBRID
初始化时,解耦 API 可能无法正确解码具有超出范围的游程长度代码的 jpeg 比特流。
7. 声明
7.1. 声明
本文档仅供参考,不应被视为对产品的特定功能、状况或质量的保证。 NVIDIA Corporation(“NVIDIA”)对本文档中包含信息的准确性或完整性不作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。 NVIDIA 对因使用此类信息或因使用此类信息而可能导致的侵犯专利或第三方的其他权利的后果或使用不承担任何责任。 本文档不承诺开发、发布或交付任何材料(如下定义)、代码或功能。
NVIDIA 保留随时对此文档进行更正、修改、增强、改进和任何其他更改的权利,恕不另行通知。
客户在下订单前应获取最新的相关信息,并应验证此类信息是否为最新且完整。
NVIDIA 产品根据订单确认时提供的 NVIDIA 标准销售条款和条件进行销售,除非 NVIDIA 和客户的授权代表签署的个别销售协议(“销售条款”)另有约定。 NVIDIA 在此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。 本文档不直接或间接地形成任何合同义务。
NVIDIA 产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命维持设备,也不适用于 NVIDIA 产品的故障或故障可能合理预期会导致人身伤害、死亡或财产或环境损害的应用。 NVIDIA 对在上述设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此,此类包含和/或使用风险由客户自行承担。
NVIDIA 不保证或声明基于本文档的产品将适用于任何特定用途。 NVIDIA 不一定对每个产品的所有参数进行测试。 客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合并符合客户计划的应用,并为应用执行必要的测试,以避免应用或产品的默认设置。 客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的附加或不同条件和/或要求。 NVIDIA 对可能基于或归因于以下原因的任何默认设置、损坏、成本或问题不承担任何责任:(i) 以任何违反本文档的方式使用 NVIDIA 产品或 (ii) 客户产品设计。
本文档未授予 NVIDIA 专利权、版权或其他 NVIDIA 知识产权下的任何明示或暗示的许可。 NVIDIA 发布的有关第三方产品或服务的信息不构成 NVIDIA 授予使用此类产品或服务的许可,也不构成对其的保证或认可。 使用此类信息可能需要获得第三方的专利或第三方其他知识产权下的许可,或者获得 NVIDIA 的专利或 NVIDIA 其他知识产权下的许可。
只有在事先获得 NVIDIA 书面批准、未经修改地复制并完全遵守所有适用的出口法律和法规,并附带所有相关的条件、限制和声明的情况下,才允许复制本文档中的信息。
本文档和所有 NVIDIA 设计规范、参考板、文件、图纸、诊断程序、列表和其他文档(统称为“材料”)均按“原样”提供。 NVIDIA 不对材料作任何明示、暗示、法定或其他方面的保证,并明确声明不承担所有关于不侵权、适销性和特定用途适用性的暗示保证。 在法律未禁止的范围内,在任何情况下,NVIDIA 均不对任何损害负责,包括但不限于任何直接、间接、特殊、偶然、惩罚性或后果性损害,无论是如何造成的,也无论责任理论如何,因使用本文档而引起,即使 NVIDIA 已被告知可能发生此类损害。 尽管客户可能因任何原因遭受任何损害,但 NVIDIA 对本文所述产品的客户的累计总责任应根据产品的销售条款进行限制。
7.2. OpenCL
OpenCL 是 Apple Inc. 的商标,已获得 Khronos Group Inc. 的许可使用。
7.3. 商标