nvJPEG
一个基于GPU加速的JPEG编解码库。
1. 简介
1.1. nvJPEG解码器
nvJPEG库为深度学习和超大规模多媒体应用中常用的图像格式提供了高性能的GPU加速JPEG解码功能。该库提供单张和批量JPEG解码能力,能高效利用可用GPU资源以获得最佳性能;同时为用户提供了管理解码所需内存分配的灵活性。
nvJPEG库支持以下功能:使用JPEG图像数据流作为输入;从数据流中获取图像的宽度和高度,并利用这些检索到的信息来管理GPU内存分配和解码过程。该库还提供了专用API,用于从原始JPEG图像数据流中提取图像信息。
注意
在本文档中,"CPU"和"主机"是同义词。同样地,"GPU"和"设备"也是同义词。
nvJPEG库支持以下功能:
JPEG选项:
基准和渐进式JPEG解码/编码
每像素8位
霍夫曼比特流解码
最多支持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库的编码功能执行用户图像数据到JPEG比特流的GPU加速压缩。用户可以以多种格式和色彩空间提供输入数据,并通过参数控制编码过程。编码功能将使用用户提供的内存分配器分配临时缓冲区。
在调用编码函数之前,用户应使用nvJPEG编码器辅助API参考中描述的辅助函数执行几个先决步骤。
1.3. 线程安全
并非所有nvJPEG类型都是线程安全的。
在多线程环境下使用解码器API时,以下解码器类型应为每个线程单独实例化:nvJPEG Bitstream Handle、nvJPEG Opaque JPEG Decoding State Handle、nvJPEG Decode Device Buffer Handle、nvJPEG Decode Pinned Buffer Handle
在多线程中使用编码器API时,每个线程应单独实例化nvjpegEncoderState_t。
对于用户提供的分配器(nvjpegCreateEx()的输入),用户需要确保线程安全。
1.4. 多GPU支持
nvJPEG的状态和句柄绑定在创建时设置的当前设备上。将这些状态和句柄与其他设置为当前的设备一起使用是未定义行为。用户需自行跟踪当前设备。
1.5. 硬件加速
硬件加速的JPEG解码可在以下GPU架构上使用 -
安培架构 (A100, A30)
Hopper
Ada
布莱克威尔
支持硬件加速JPEG解码的平台:
Windows
Linux (x86_64、PowerPC、ARM64)
2. JPEG解码
2.1. 使用JPEG解码
nvJPEG库提供了单张图像解码和批量多张图像解码的功能。
2.1.1. 单张图像解码
对于单张图像解码,您需要提供数据大小和文件数据的指针,解码后的图像将被放入输出缓冲区。
要使用nvJPEG库,首先调用辅助函数进行初始化。
使用辅助函数
nvjpegCreateSimple() 或 nvjpegCreateEx()之一创建nvJPEG库句柄。-
使用辅助函数
nvjpegJpegStateCreate()创建JPEG状态。参见nvJPEG Type Declarations和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 Helper API Reference。
-
使用
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 Chroma Subsampling。-
使用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 |
仅填充输出的第一个通道 |
No |
Yes |
No |
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
width[c] for c = 0, 1, 2
destination.pitch[c]*height[c] for c = 0, 1, 2
NVJPEG_OUTPUT_RGB和NVJPEG_OUTPUT_BGR
width[0] for c = 0, 1, 2
destination.pitch[0]*height[0] for c = 0, 1, 2
NVJPEG_OUTPUT_RGBI和NVJPEG_OUTPUT_BGRI
width[0]*3
destination.pitch[0]*height[0]
NVJPEG_OUTPUT_UNCHANGED
width[c] for c = [ 0, nComponents - 1 ]
destination.pitch[c]*height[c] for c = [ 0, nComponents - 1]
NVJPEG_OUTPUT_UNCHANGEDI_U16
width[c]* nComponents* sizeof(unsigned short)
destination.pitch[c]*height[c] for c = [ 0, nComponents - 1]
-
确保nvJPEG图像结构体(或在批量解码情况下的多个结构体)已填充分配缓冲区的指针和间距。
nvjpegImage_t结构体用于保存输出指针,其定义如下:typedef struct { unsigned char * channel[NVJPEG_MAX_COMPONENT]; size_t pitch[NVJPEG_MAX_COMPONENT]; } nvjpegImage_t;
NVJPEG_MAX_COMPONENT是当前版本中nvJPEG库支持的最大颜色分量数。对于通用图像,这是该库能够解压缩的最大编码通道数。
最后,当您使用上述参数调用
nvjpegDecode()函数时,该函数会将解码后的数据填充到输出缓冲区中。
2.1.2. 使用解耦阶段进行解码
nvJPEG库允许进一步分离解码过程的主机阶段和设备阶段。解码的主机阶段将不需要访问设备资源。
可以在Decode API—Decoupled Decoding下找到一些解耦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()
-
-
按照以下顺序调用decode 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解码,或使用CPU进行霍夫曼解码。
成员 |
描述 |
NVJPEG_BACKEND_DEFAULT |
后端由内部自动选择。 |
NVJPEG_BACKEND_HYBRID |
使用CPU进行霍夫曼解码。 |
NVJPEG_BACKEND_GPU_HYBRID |
使用GPU进行霍夫曼解码。当批量大小超过50时, |
NVJPEG_BACKEND_HARDWARE |
使用硬件加速进行解码。支持单次扫描的基线JPEG图像(1或3通道)。不支持410和411色度二次采样。 |
NVJPEG_BACKEND_GPU_HYBRID_DEVICE |
支持设备内存上的输入比特流。仅适用于无重启间隔的基线JPEG图像的批量解码API。 |
NVJPEG_BACKEND_HARDWARE_DEVICE |
支持设备内存中的输入比特流。仅能与批量解码API一起使用。使用硬件加速进行解码。支持基线JPEG图像(单次扫描,1或3通道)。不支持410和411色度二次采样。 |
NVJPEG_BACKEND_LOSSLESS_JPEG |
支持JPEG 92标准定义的无损JPEG比特流。支持最多2个通道和预测模式1的比特流。 |
2.2.2. nvJPEG 比特流句柄
struct nvjpegJpegStream;
typedef struct nvjpegJpegStream* nvjpegJpegStream_t;
该句柄在主机上存储比特流参数。这有助于使用nvJPEG Stream 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初始化的。它用作Decode API—Decoupled Decoding的输入。
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,否则返回非零值。需要向nvjpegCreate()函数提供一个指向nvjpegDevAllocator_t结构的指针,且该结构的字段需正确填充。如果传入NULL,则将使用默认的内存分配函数cudaMalloc()和cudaFree()。
当nvjpegCreate()或nvjpegCreateEx()函数中的nvjpegDevAllocator_t *allocator参数被设置为指向上述nvjpegDevAllocator_t结构的指针时,该结构将用于分配和释放设备内存。内存分配和内存释放函数的原型与cudaMalloc()和cudaFree()函数类似。成功时应返回0,否则返回非零值。
然而,如果在nvjpegCreate()或nvjpegCreateEx()函数中将nvjpegDevAllocator_t *allocator参数设置为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
nvJPEG标志位在使用nvjpegCreateEx()或nvjpegCreateExV2()初始化库时提供额外的控制选项。由于这些标志位是位字段,因此可以进行组合使用。
成员 |
描述 |
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 Return Codes。
2.3.1.2. nvjpegGetCudartProperty()
获取用于构建nvJPEG库的CUDA工具包的主版本号、次版本号或补丁级别的数值。如需获取nvJPEG库本身的相同信息,请参阅nvjpegGetProperty()。
签名:
nvjpegStatus_t nvjpegGetCudartProperty(
libraryPropertyType type,
int *value);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
支持的 |
|
输出 |
主机 |
与请求的特定 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
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 Flags。 |
|
输入/输出 |
主机 |
库句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Flags。 |
|
输入/输出 |
主机 |
库句柄。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.7. nvjpegDestroy()
释放库句柄。
签名:
nvjpegStatus_t nvjpegDestroy(nvjpegHandle_t handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
要释放的库句柄。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.8. nvjpegSetDeviceMemoryPadding()
为所有使用指定库句柄的设备内存分配提供填充。较大的数值有助于分摊需要时设备内存重新分配的消耗。
签名:
nvjpegStatus_t nvjpegSetDeviceMemoryPadding(
size_t padding,
nvjpegHandle_t handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
用于所有后续设备内存分配的设备内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.9. nvjpegGetDeviceMemoryPadding()
获取当前用于指定库句柄的设备内存填充量。
签名:
nvjpegStatus_t nvjpegGetDeviceMemoryPadding(
size_t *padding,
nvjpegHandle_t handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输出 |
主机 |
当前用于设备内存分配的设备内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.10. nvjpegSetPinnedMemoryPadding()
为所有使用指定库句柄的固定主机内存分配提供填充。较大的数值有助于在需要时分摊固定主机内存重新分配的需求。
签名:
nvjpegStatus_t nvjpegSetPinnedMemoryPadding(
size_t padding,
nvjpegHandle_t handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
为所有后续固定主机内存分配使用的固定主机内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.11. nvjpegGetPinnedMemoryPadding()
获取当前用于指定库句柄的固定主机内存填充量。
签名:
nvjpegStatus_t nvjpegGetPinnedMemoryPadding(
size_t *padding,
nvjpegHandle_t handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输出 |
主机 |
当前用于固定主机内存分配的固定主机内存填充。 |
|
输入/输出 |
主机 |
库句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
2.3.1.13. nvjpegJpegStateCreate()
分配并初始化JPEG处理所需的内部结构。
签名:
nvjpegStatus_t nvjpegJpegStateCreate(
nvjpegHandle_t handle,
nvjpegJpegState_t *jpeg_handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
图像状态句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.14. nvjpegJpegStateDestroy()
释放图像内部结构。
签名:
nvjpegStatus_t nvjpegJpegStateDestroy(nvjpegJpegState handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
图像状态句柄。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.15. nvjpegDecoderCreate()
创建一个解码器句柄。
签名:
nvjpegStatus_t nvjpegDecoderCreate(
nvjpegHandle_t nvjpeg_handle,
nvjpegBackend_t implementation,
nvjpegJpegDecoder_t* decoder_handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
解码器句柄的后端参数。该后端适用于通过此句柄调用的解耦API下的所有函数。 |
|
输入/输出 |
主机 |
解码器状态句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.16. nvjpegDecoderDestroy()
销毁解码器句柄。
签名:
nvjpegStatus_t nvjpegDecoderDestroy(
nvjpegJpegDecoder_t decoder_handle);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
解码器句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
2.3.1.18. nvjpegDecoderStateCreate()
创建decoder_state内部结构。decoder_state与用于创建decoder_handle的nvJPEG Backend实现相关联。
签名:
nvjpegStatus_t nvjpegDecoderStateCreate(
nvjpegHandle_t nvjpeg_handle,
nvjpegJpegDecoder_t decoder_handle,
nvjpegJpegState_t* decoder_state);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
解码器句柄。 |
|
输入/输出 |
主机 |
nvJPEG 图像状态句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.19. nvjpegJpegStreamCreate()
创建用于解析JPEG比特流并存储比特流参数的jpeg_stream。
签名:
nvjpegStatus_t nvjpegJpegStreamCreate(
nvjpegHandle_t handle,
nvjpegJpegStream_t *jpeg_stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄 |
|
输入 |
主机 |
比特流句柄 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.20. nvjpegJpegStreamDestroy()
销毁jpeg_stream结构体。
签名:
nvjpegStatus_t nvjpegJpegStreamDestroy(
nvjpegJpegStream_t *jpeg_stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.21. nvjpegBufferPinnedCreate()
创建一个固定的缓冲区句柄。
签名:
nvjpegStatus_t nvjpegBufferPinnedCreate(
nvjpegHandle_t handle,
nvjpegPinnedAllocator_t* pinned_allocator,
nvjpegBufferPinned_t* buffer);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
固定主机内存分配器。请参阅 |
|
输入/输出 |
主机 |
nvJPEG 固定缓冲区对象。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Extended Host Pinned Memory Allocator Interface结构描述。 |
nvjpegBufferPinned_t* buffer |
输入/输出 |
主机 |
nvJPEG固定缓冲区对象。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.23. nvjpegBufferPinnedDestroy()
销毁一个固定的缓冲区句柄。
签名:
nvjpegStatus_t nvjpegBufferPinnedDestroy(
nvjpegBufferPinned_t buffer);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 固定缓冲区对象。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
2.3.1.25. nvjpegBufferPinnedRetrieve()
从nvJPEG固定缓冲区句柄中获取固定内存指针和大小。允许应用程序在解码完成后重新使用该内存。
签名:
nvjpegStatus_t nvjpegBufferPinnedRetrieve(
nvjpegBufferPinned_t buffer,
size_t* size, void** ptr);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 固定缓冲区容器。 |
|
输入/输出 |
主机 |
固定缓冲区的大小(以字节为单位)。 |
|
输入/输出 |
主机 |
指向固定缓冲区的指针。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.26. nvjpegBufferPinnedResize()
将固定缓冲区的大小调整为指定的字节数。此API可用于预先分配固定缓冲区到较大值,从而避免在解码过程中调用分配器。
签名:
nvjpegStatus_t nvjpegBufferPinnedResize(nvjpegBufferPinned_t buffer,
size_t size,
cudaStream_t stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG 固定缓冲区容器。 |
|
输入 |
主机 |
固定缓冲区的大小(以字节为单位)。 |
|
输入 |
主机 |
当使用流序分配器初始化 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.27. nvjpegBufferDeviceCreate()
创建设备缓冲区句柄。
签名:
nvjpegStatus_t nvjpegBufferDeviceCreate(
nvjpegHandle_t handle,
nvjpegDevAllocator_t* device_allocator,
nvjpegBufferDevice_t* buffer);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
设备内存分配器。请参阅nvJPEG设备内存分配器接口结构描述。 |
|
输入/输出 |
主机 |
nvJPEG设备缓冲区容器。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.28. nvjpegBufferDeviceCreateV2()
使用扩展分配器创建设备缓冲区句柄。
签名:
nvjpegStatus_t nvjpegBufferDeviceCreateV2(
nvjpegHandle_t handle,
nvjpegDevAllocatorV2_t* device_allocator,
nvjpegBufferDevice_t* buffer);
参数:
参数 |
输入/输出 |
内存 |
描述 |
nvjpegHandle_t handle |
输入 |
主机端 |
库句柄。 |
nvjpegDevAllocatorV2_t* 设备分配器 |
输入 |
主机 |
扩展设备内存分配器。请参阅 |
nvjpegBufferDevice_t* buffer |
输入/输出 |
主机 |
nvJPEG设备缓冲区容器。 |
返回:
nvjpegStatus_t - 错误代码,定义参见nvJPEG API Return Codes。
2.3.1.29. nvjpegBufferDeviceDestroy()
销毁设备缓冲区句柄。
签名:
nvjpegStatus_t nvjpegBufferDeviceDestroy(
nvjpegBufferDevice_t buffer);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机/设备 |
nvJPEG设备缓冲区容器。设备指针存储在主机结构中。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
2.3.1.31. nvjpegBufferDeviceRetrieve()
从nvJPEG设备缓冲区句柄中检索设备内存指针和大小。允许应用程序在解码完成后重新使用该内存。
签名:
nvjpegStatus_t nvjpegBufferDeviceRetrieve(
nvjpegBufferDevice_t buffer,
size_t* size,
void** ptr);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG设备缓冲区容器。 |
|
输入/输出 |
主机 |
设备缓冲区大小(以字节为单位)。 |
|
输入/输出 |
主机 |
指向设备缓冲区的指针。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.32. nvjpegBufferDeviceResize()
将设备缓冲区的大小调整为指定的字节数。此API可用于预先分配较大的设备缓冲区,避免在解码过程中调用分配器。
签名:
nvjpegStatus_t nvjpegBufferDeviceResize(nvjpegBufferDevice_t buffer,
size_t size,
cudaStream_t stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
nvJPEG设备缓冲区容器。 |
|
输入 |
主机 |
设备缓冲区的大小(以字节为单位)。 |
|
输入 |
主机 |
当使用流序分配器初始化 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.33. nvjpegDecodeParamsCreate()
创建一个参数句柄。可编程的参数包括:输出格式、ROI解码、CMYK到RGB转换。
签名:
nvjpegStatus_t nvjpegDecodeParamsCreate(
nvjpegHandle_t handle,
nvjpegDecodeParams_t *decode_params);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
解码输出参数。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.1.34. nvjpegDecodeParamsDestroy()
销毁decode_params句柄。
签名:
nvjpegStatus_t nvjpegDecodeParamsDestroy(
nvjpegDecodeParams_t *decode_params);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
解码输出参数。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
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流元数据(头部信息、应用标记等)将被保存在内部 |
|
输入 |
主机 |
如果不为0,则整个jpeg流将被复制到内部JpegStream结构中,且在此调用后将不再需要指向JPEG文件数据的指针。
如果为0,则 |
|
输入/输出 |
主机/设备 |
存储已解析比特流信息的nvJPEG比特流句柄。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
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 Return Codes。
2.3.2.2.4. nvjpegJpegStreamGetFrameDimensions()
从比特流中提取JPEG帧的尺寸。
签名:
nvjpegStatus_t nvjpegJpegStreamGetFrameDimensions(
nvjpegJpegStream_t jpeg_stream,
unsigned int* width,
unsigned int* height);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
框架高度。 |
|
输出 |
主机 |
框架宽度。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.2.2.5. nvjpegJpegStreamGetComponentsNum()
从比特流中提取JPEG帧的尺寸。
签名:
nvjpegStatus_t nvjpegJpegStreamGetComponentsNum(
nvjpegJpegStream_t jpeg_stream,
unsigned int* components_num);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
输入中的编码通道数量。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
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 Return Codes。
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 Return Codes。
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 Return Codes。
2.3.2.2.10. nvjpegJpegStreamGetSamplePrecision()
从比特流中提取样本精度(位深度)。
签名:
nvjpegStatus_t NVJPEGAPI nvjpegJpegStreamGetSamplePrecision(
nvjpegJpegStream_t jpeg_stream,
unsigned int *precision);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
比特流句柄。 |
|
输出 |
主机 |
样本精度值。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
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 Return Codes。
2.3.3.3. nvjpegDecodeBatched()
解码批量图像,并将它们以提供给nvjpegDecodeBatchedInitialize()函数的格式写入destination参数描述的缓冲区中。此函数相对于主机是异步的。该函数的所有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 Return Codes。
2.3.3.4. nvjpegDecodeBatchedEx()
该API帮助解码带ROI的批量图像,并将它们以提供给nvjpegDecodeBatchedInitialize()函数的格式写入destination参数描述的缓冲区中。此函数相对于主机是异步的。该函数的所有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 Return Codes。
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 Return Codes。
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 Return Codes。
2.3.3.7. nvjpegDecodeBatchedPreAllocate()
这是一个实验性API,可与nvjpegDecodeBatched()配合使用。当解码具有不同尺寸和色度二次采样的图像时,性能会受到库重复调用cuda来释放/分配设备内存的限制。该API试图通过在实际解码前预分配设备内存来避免此问题。用户可以选择在调用nvjpegDecodeBatched()时使用不太可能被超过的值来调用此API。
注意
注意:
此功能仅在nvjpegHandle_t使用NVJPEG_BACKEND_HARDWARE实例化时可用。对于其他后端目前是空操作。
此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 Return Codes。
2.3.3.8. nvjpegDecodeBatchedParseJpegTables()
当从TIFF文件解码JPEG比特流时,需与批量解码API配合使用。此函数解析JPEG表比特流以提取JPEG表。外部霍夫曼表和量化表将应用于批次中的所有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 Return Codes。
2.3.4. 解码API—解耦解码
这组解码API与比特流句柄、解码参数句柄、固定和设备缓冲区句柄配合使用作为输入,从而将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解码器句柄实例之间共享固定缓冲区和设备缓冲区。
#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()
这是解耦解码过程的第一阶段。该阶段完全在主机上完成,因此相对于主机是同步的。
如果解码器状态附加了一个固定缓冲区,那么将使用该固定缓冲区对象来分配主机解码阶段所需的固定内存。如果固定缓冲区对象已经处理了所需的固定内存量,则不会进行分配。
如果未附加固定的缓冲区对象,则状态将使用堆主机内存来分配主机处理所需的内存。
在此阶段,设备尚未参与。因此设备选择、设备初始化和设备内存初始化可以在解码过程的后续阶段完成。
此函数作用于已解析的流。在调用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 Return Codes。
2.3.4.2. nvjpegDecodeJpegTransferToDevice()
此阶段包含主机和设备操作。因此,对于主机而言,它是同步和异步操作的混合体。所有设备操作将被提交到提供的流中。
此阶段仅应在具有相同解码器句柄、解码器状态句柄和已解析jpeg流句柄的主机阶段之后调用。在调用此API之前,应初始化设备并使用nvjpegStateAttachDeviceBuffer()将设备缓冲区附加到decoder_state句柄。如果需要,此设备缓冲区对象将被调整为所需的内存大小。对于主机内存缓冲区,此阶段将使用主机阶段所用的内容:无论是附加的固定缓冲区还是状态的主机内存缓冲区。
签名:
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 Return Codes。
2.3.4.3. nvjpegDecodeJpegDevice()
此阶段主要由设备端执行的解码操作组成(主机端没有显著计算)。因此,该阶段相对于主机是异步的。对于给定的decoder_state句柄和解码器句柄,应在调用nvjpegDecodeJpegTransferToDevice()后进入此阶段。
在此函数调用中,未使用主机内存缓冲区,因此如果固定缓冲区已附加到状态,则可以在其他地方重复使用。请注意,此时不再需要Jpeg流句柄,因为设备解码所需的部分已在上一阶段复制到设备内存中。
签名:
nvjpegStatus_t nvjpegDecodeJpegDevice(
nvjpegHandle_t handle,
nvjpegJpegDecoder_t decoder,
nvjpegJpegState_t decoder_state,
nvjpegImage_t *destination,
cudaStream_t stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入 |
主机 |
nvJPEG解码器句柄。 |
|
输入 |
主机 |
nvJPEG解码器状态句柄。 |
|
输入/输出 |
主机/设备 |
指向描述输出目标的结构体的指针。该结构体应位于主机内存中,但结构体中的指针应指向设备内存。详情请参阅nvJPEG Image。 |
|
输入 |
主机 |
所有GPU任务将被提交到的CUDA流。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
2.3.4.4. nvjpegDecodeJpeg()
这是一个单阶段API,在创建nvjpegJpegDecoder_t对象时可以选择nvJPEG后端。用户可以选择调用此API,而不是分别调用nvjpegDecodeJpegHost()、nvjpegDecodeJpegTransferToDevice()和nvjpegDecodeJpegDevice()这三个独立接口。
在调用此API之前,需要将设备缓冲区附加到解码器状态。固定缓冲区是可选的。如果未附加固定缓冲区,则将使用堆内存进行主机处理。
此函数作用于已解析的流。在调用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 Return Codes。
2.3.5. nvJPEG 解码参数
此类别API用于设置解码参数。这些API应与解码API—解耦解码中定义的相关解码API配合使用。
2.3.5.1. nvjpegDecodeParamsSetOutputFormat()
此函数用于设置解码输出格式。请参阅单张图像解码步骤6中描述的nvjpegOutputFormat_t。如果未通过此API设置,nvjpegOutputFormat_t的输出参数默认为NVJPEG_OUTPUT_UNCHANGED。
签名:
nvjpegStatus_t nvjpegDecodeParamsSetOutputFormat(
nvjpegDecodeParams_t decode_params,
nvjpegOutputFormat_t output_format);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
参见单图像解码的第6步。 |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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窗口不能超出图像边界。也就是说:
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 Return Codes。
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 Return Codes。
2.3.5.4. nvjpegDecodeParamsSetScaleFactor()
允许用户缩放解码输出。
注意
此功能目前仅在通过NVJPEG_BACKEND_HARDWARE创建nvJPEG解码器句柄时受支持。
签名:
nvjpegStatus_t nvjpegDecodeParamsSetScaleFactor(
nvjpegDecodeParams_t decode_params,
nvjpegScaleFactor_t scale_factor);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
解码输出参数句柄。 |
|
输入 |
主机 |
设置解码输出的缩放因子。 |
默认情况下,缩放因子设置为NVJPEG_SCALE_NONE。支持的取值列表请参见nvJPEG Scale Factor。
设置缩放因子值时,目标参数的推荐分配方式如下:
使用 nvjpegGetImageInfo() 或 nvjpegJpegStreamGetFrameDimensions() 提取每个通道的尺寸。
设height[NVJPEG_MAX_COMPONENT]和width[NVJPEG_MAX_COMPONENT]为两个数组,分别存储高度和宽度。这些数组的索引对应通道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
|
对于输出格式: NVJPEG_OUTPUT_Y |
destination.pitch[0] 至少应为: width[0] |
destination.channel[0] 的最小尺寸应为: destination.pitch[0]*height[0] |
对于输出格式 |
destination.pitch[c] 至少应为: |
destination.channel[c] 的最小尺寸应为: |
NVJPEG_OUTPUT_YUV |
宽度[c](c = 0, 1, 2) |
目标.pitch[c]*高度[c](c = 0, 1, 2) |
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] 其中 c = [ 0, nComponents - 1 ] |
目标.pitch[c]*高度[c] 其中 c = [ 0, nComponents - 1] |
返回:
nvjpegStatus_t — 错误代码,具体定义参见nvJPEG API Return Codes。
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 Return Codes。
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数据流。 |
|
用户提供的分配器函数,无论是用于内存分配还是释放内存,返回了一个非零代码。 |
|
设备任务执行期间发生错误。 |
|
The device capabilities are not enough for the set of input parameters provided (input parameters such as backend, encoded stream parameters, output format). |
|
设备任务执行期间发生错误。 |
|
不支持。 |
|
比特流输入数据不完整 |
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 Encoder Helper API Reference。
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
大小为31 x 161的Cb和Cr平面
3.1.3.2. nvjpegEncodeImage
请参阅nvjpegEncodeImage()。该函数的输入数据(即如何在source参数中提供数据)由input_format参数决定。对于交错格式(以I结尾的格式),仅使用第一个通道。对于非交错格式,将使用输入格式中的所有通道。
例如,如果用户有一个交错存储的RGB图像,尺寸为W x H,连续存储,且指向它的指针是pImage,那么source应该是:
source.channel[0] = pImagesource.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编码器进行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);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
编码类型选择(Baseline/Progressive)。默认为Baseline。 |
|
输入 |
主机 |
放置所有所需设备操作的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);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
内部结构,用于保存压缩所需的临时缓冲区,并存储最终的压缩JPEG流。 |
|
输入 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
指向 |
|
输入 |
主机 |
输入数据的色度二次采样。 |
|
输入 |
主机 |
输入图像的宽度。 |
|
输入 |
主机 |
输入图像高度。 |
|
输入 |
主机 |
放置所有所需设备操作的CUDA流。 |
3.4.3. nvjpegEncodeImage()
使用提供的参数将图像按指定格式压缩为JPEG流,并将其存储在状态结构中。
签名:
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);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
内部结构,用于保存压缩所需的临时缓冲区,并存储最终的压缩JPEG流。 |
|
输入 |
主机 |
编码器参数结构句柄。 |
|
输入 |
主机 |
指向 |
|
输入 |
主机 |
|
|
输入 |
主机 |
输入图像的宽度。 |
|
输入 |
主机 |
输入图像高度。 |
|
输入 |
主机 |
放置所有所需设备操作的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);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
之前在某个编码器函数中使用过的 |
|
输入/输出 |
主机 |
指向主机内存中存储压缩流的缓冲区指针。可以为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);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入 |
主机 |
库句柄。 |
|
输入/输出 |
主机 |
之前在某个编码器函数中使用过的 |
|
输入/输出 |
设备 |
指向设备内存中存储压缩流的缓冲区指针。可以为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);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
用于存储压缩所需的临时缓冲区的内部结构。 |
|
输出 |
主机 |
将用于压缩的编码器参数。 |
|
在 |
主机 |
输入解析后的数据流。 |
|
在 |
主机 |
放置所有所需设备操作的CUDA流。 |
4.1.2. nvjpegEncoderParamsCopyQuantizationTables()
从解析的流中复制量化表。
签名:
nvjpegStatus_t nvjpegEncoderParamsCopyQuantizationTables(
nvjpegEncoderParams_t encode_params,
nvjpegJpegStream_t jpeg_stream,
cudaStream_t stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输出 |
主机 |
将用于压缩的编码器参数。 |
|
在 |
主机 |
输入解析后的数据流。 |
|
在 |
主机 |
放置所有所需设备操作的CUDA流。 |
4.1.3. nvjpegEncoderParamsCopyHuffmanTables() [已弃用]
nvjpegEncoderParamsCopyHuffmanTables() 现已弃用。由于JPEG编码/解码过程中的精度差异,输入的霍夫曼表可能不再适用于正在编码的图像,并可能导致比特流损坏。
签名:
nvjpegStatus_t nvjpegEncoderParamsCopyHuffmanTables(
nvjpegEncoderState_t encoder_state,
nvjpegEncoderParams_t encode_params,
nvjpegJpegStream_t jpeg_stream,
cudaStream_t stream);
参数:
参数 |
输入/输出 |
内存 |
描述 |
|
输入/输出 |
主机 |
用于存储压缩所需的临时缓冲区的内部结构。 |
|
输出 |
主机 |
将用于压缩的编码器参数。 |
|
在 |
主机 |
输入已解析的流。 |
|
在 |
主机 |
放置所有所需设备操作的CUDA流。 |
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列表
以下API从CUDA 11.0开始被弃用:
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);
6. 已知问题
解耦的API在初始化时使用NVJPEG_BACKEND_GPU_HYBRID,可能无法正确解码含有越界游程编码的JPEG比特流。
7. 通知
7.1. 注意事项
本文档仅供信息参考之用,不应视为对产品功能、状态或质量的保证。NVIDIA公司(“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对客户就本文所述产品的全部及累计责任应受产品销售条款的限制。
7.2. OpenCL
OpenCL是苹果公司的商标,经Khronos Group Inc.授权使用。
7.3. 商标
NVIDIA和NVIDIA标识是美国及其他国家NVIDIA公司的商标或注册商标。其他公司及产品名称可能是其各自关联公司的商标。