3. JPEG编码
3.1. 使用编码器
在调用mcJPEG编码函数之前,用户应执行以下先决步骤。
3.1.1. 编码参数配置
用户应使用 mcjpegEncoderParamsCreate() 函数创建编码参数结构体。
该函数将使用默认参数进行初始化。用户可以使用 mcjpegEncoderParamsSet*() 函数来设置特定参数。
可以使用 mcjpegEncoderParamsSetQuality() 函数将编码质量参数设置为1到100之间的整数,该编码质量参数作为生成JPEG量化表的依据。
应将参数结构体传递给压缩函数。
3.1.2. 创建编码状态结构
用户应使用 mcjpegEncoderStateCreate() 函数创建编码状态结构体。此函数将为编码过程保留中间缓冲区。应将此状态传递给压缩函数。
3.1.3. 对图像进行编码
mcJPEG库提供了几个接口,用于以不同的格式和色彩空间压缩图像。
3.1.3.1. mcjpegEncodeYUV
此函数的输入为YUV色彩空间的图像。应将相应的YUV平面数据填充到 source 参数中。
chroma_subsampling 参数表示输入数据的色度子采样。
如果编码参数中的色度子采样与输入色度子采样相同,用户的输入数据将直接用于JPEG压缩。否则,将对色度进行重采样,以匹配编码参数的色度子采样。
应根据采样因子提供输入数据。也就是说,色度图像平面的大小应与相应的采样对齐。例如:
图像尺寸:123 x 321
输入色度子采样:MCJPEG_CSS_410
色度采样因子:4 x 2
鉴于上述情况,编码器库要求用户提供:
Y平面大小: 123 x 321
Cb和Cr平面大小:31 x 161
3.1.3.2. mcjpegEncodeImage
此函数的输入(即如何在 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 值应根据数据布局进行相应设置。
3.1.4. 获取压缩流
对于任何输入数据和参数,通常无法准确预测最终JPEG流的最终压缩数据大小。 编码时,mcJPEG库计算最终数据流的大小,在编码器状态下分配临时缓冲区,并将压缩数据保存在编码状态的缓冲区中。为了获得最终的压缩JPEG流,用户应提供足够大的内存缓冲区来存储此压缩数据。执行此操作有两个选择:
使用给定参数和图像尺寸下压缩JPEG流大小的上限:
使用
mcjpegEncodeGetBufferSize()函数获取压缩后的JPEG流最大可能的大小。分配对应大小的内存缓冲区。
使用一个编码函数对图像进行编码。
使用
mcjpegEncodeRetrieveBitstream()和分配的缓冲区,在成功编码后从编码器状态中获取压缩的JPEG流。
等待编码完成,获取所需缓冲区的确切大小,如下所示:
使用一个编码函数对图像进行编码。
使用
mcjpegEncodeRetrieveBitstream()函数获取压缩JPEG流的大小,以字节为单位。分配内存缓冲区,最少为获取到的大小。
使用
mcjpegEncodeRetrieveBitstream()函数用压缩的JPEG流填充缓冲区。
3.1.5. mcJPEG编码示例
mcjpegHandle_t handle;
mcjpegEncoderState_t enc_state;
mcjpegEncoderParams_t enc_params;
mcStream_t stream;
//初始化mcjpeg结构体
mcjpegCreateSimple(&handle);
mcjpegEncoderStateCreate(handle, &enc_state, stream);
mcjpegEncoderParamsCreate(handle, &enc_params, stream);
mcjpegImage_t image;
//用图像数据填充图像,比如,640x480的RGB图像
//压缩图像
mcjpegEncodeImage(handle, enc_state, enc_params,
&image, MCJPEG_INPUT_RGB, 640, 480, stream);
//获取压缩的流大小
size_t length;
mcjpegEncodeRetrieveBitstream(handle, enc_state, NULL, &length, stream);
//获取流本身
mcStreamSynchronize(stream);
std::vector<char> jpeg(length);
mcjpegEncodeRetrieveBitstream(handle, enc_state, jpeg.data(), &length, 0);
//将流写入文件
mcStreamSynchronize(stream);
std::ofstream output_file("test.jpg", std::ios::out | std::ios::binary);
output_file.write(jpeg.data(), length);
output_file.close();
3.2. mcJPEG编码类型声明
3.2.1. mcjpegInputFormat_t
typedef enum {
MCJPEG_INPUT_RGB = 3,
MCJPEG_INPUT_BGR = 4,
MCJPEG_INPUT_RGBI = 5,
MCJPEG_INPUT_BGRI = 6
} mcjpegInputFormat_t;
mcjpegInputFormat_t 枚举用于选择输入图像的像素格式。
成员 |
描述 |
|---|---|
MCJPEG_INPUT_RGB |
输入图像为RGB色彩模型,像素格式为RGB |
MCJPEG_INPUT_BGR |
输入图像为RGB色彩模型,像素格式为BGR |
MCJPEG_INPUT_RGBI |
输入图像为RGB色彩模型,像素格式为交错RGB |
MCJPEG_INPUT_BGRI |
输入图像为RGB色彩模型,像素格式为交错BGR |
3.2.2. mcjpegEncoderState_t
mcjpegEncoderState_t 结构体存储用于压缩的中间缓冲区和变量。
3.2.3. mcjpegEncoderParams_t
mcjpegEncoderParams_t 结构体存储JPEG编码参数。
3.3. mcJPEG编码API
3.3.1. mcjpegEncoderStateCreate()
创建编码状态,用于存储压缩中使用的中间缓冲区。
签名
mcjpegStatus_t mcjpegEncoderStateCreate(
mcjpegHandle_t handle,
mcjpegEncoderState_t *encoder_state,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_state |
输出 |
主机 |
此指针指向编码状态结构体 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.2. mcjpegEncoderStateDestroy()
销毁编码状态。
签名
mcjpegStatus_t mcjpegEncoderStateDestroy( mcjpegEncoderState_t encoder_state);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
encoder_state |
输入/输出 |
主机 |
要被销毁的编码状态结构体 |
3.3.3. mcjpegEncoderParamsCreate()
创建包含压缩参数的结构体。
签名
mcjpegStatus_t mcjpegEncoderParamsCreate(
mcjpegHandle_t handle,
mcjpegEncoderParams_t *encoder_params,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_params |
输出 |
主机 |
此指针指向创建的压缩参数结构体 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.4. mcjpegEncoderParamsDestroy()
销毁编码参数结构体。
签名
mcjpegEncoderParamsDestroy( mcjpegEncoderParams_t encoder_params);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
encoder_params |
输入/输出 |
主机 |
要被销毁的编码器参数结构体 |
3.3.5. mcjpegEncoderParamsSetEncoding()
在编码参数结构体中设置编码类型参数。
签名
mcjpegStatus_t mcjpegEncoderParamsSetEncoding(
mcjpegEncoderParams_t encoder_params,
mcjpegJpegEncoding_t etype,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
encoder_params |
输入/输出 |
主机 |
编码参数结构体句柄 |
etype |
输入 |
主机 |
编码类型选择。 默认为baseline,当前仅支持baseline |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.6. mcjpegEncoderParamsSetQuality()
在编码参数结构体中设置编码质量参数。
签名
mcjpegStatus_t mcjpegEncoderParamsSetQuality(
mcjpegEncoderParams_t encoder_params,
const int quality,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
encoder_params |
输入/输出 |
主机 |
编码参数结构体句柄 |
quality |
输入 |
主机 |
介于1到100之间、表示质量的整数值,100表示最高质量。默认值为70 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.7. mcjpegEncoderParamsSetSamplingFactors()
设置用于JPEG压缩的色度子采样。
签名
mcjpegStatus_t mcjpegEncoderParamsSetSamplingFactors(
mcjpegEncoderParams_t encoder_params,
const mcjpegChromaSubsampling_t chroma_subsampling,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
encoder_params |
输入/输出 |
主机 |
编码参数结构体句柄 |
chroma_subsampling |
输入 |
主机 |
用于JPEG压缩的色度子采样。如果输入是YUV色彩模型,且 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.8. mcjpegEncodeGetBufferSize()
为给定的输入参数返回存储压缩JPEG流所需的最大可能缓冲区大小。
签名
mcjpegStatus_t mcjpegEncodeGetBufferSize(
mcjpegHandle_t handle,
const mcjpegEncoderParams_t encoder_params,
int image_width,
int image_height,
size_t *max_stream_length);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_params |
输入/输出 |
主机 |
编码参数结构体句柄 |
image_width |
输入 |
主机 |
输入图像宽度 |
image_height |
输入 |
主机 |
输入图像高度 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.9. mcjpegEncodeYUV()
使用提供的参数将YUV图像压缩到JPEG流,并将其存储在状态结构体中。
签名
mcjpegStatus_t mcjpegEncodeYUV(
mcjpegHandle_t handle,
mcjpegEncoderState_t encoder_state,
const mcjpegEncoderParams_t encoder_params,
const mcjpegImage_t *source,
mcjpegChromaSubsampling_t chroma_subsampling,
int image_width,
int image_height,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_state |
输入/输出 |
主机 |
内部结构体,用于保存压缩所需的临时缓冲区,并存储最终压缩的JPEG流 |
encoder_params |
输入 |
主机 |
编码参数结构体句柄 |
source |
输入 |
主机 |
此指针指向 |
chroma_subsampling |
输入 |
主机 |
输入数据的色度子采样 |
image_width |
输入 |
主机 |
输入图像宽度 |
image_height |
输入 |
主机 |
输入图像高度 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.10. mcjpegEncodeImage()
使用提供的参数将RGB图像压缩到JPEG流,并将其存储在状态结构体中。
签名
mcjpegStatus_t mcjpegEncodeImage(
mcjpegHandle_t handle,
mcjpegEncoderState_t encoder_state,
const mcjpegEncoderParams_t encoder_params,
const mcjpegImage_t *source,
mcjpegInputFormat_t input_format,
int image_width,
int image_height,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_state |
输入/输出 |
主机 |
内部结构体,用于保存压缩所需的临时缓冲区,以及存储最终压缩的JPEG流 |
encoder_params |
输入 |
主机 |
编码参数结构体句柄 |
source |
输入 |
主机 |
此指针指向 |
input_format |
输入 |
主机 |
描述输入数据的 |
image_width |
输入 |
主机 |
输入图像宽度 |
image_height |
输入 |
主机 |
输入图像高度 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.11. mcjpegEncodeRetrieveBitstream()
从先前在一个编码函数中使用过的编码状态中获取压缩流。
如果
data参数为NULL,则在length参数中返回压缩流的大小。如果
data不为空,则提供的length参数应包含data缓冲区大小。如果提供的
length小于压缩流的大小,则返回错误。否则,压缩流将存储在data缓冲区中,且实际的压缩缓冲区大小将存储在length参数中。
签名
mcjpegStatus_t mcjpegEncodeRetrieveBitstream(
mcjpegHandle_t handle,
mcjpegEncoderState_t encoder_state,
unsigned char *data,
size_t *length,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_state |
输入/输出 |
主机 |
先前在一个编码函数中使用过的 |
data |
输入/输出 |
主机 |
此指针指向主机内存中用于存储压缩流的缓冲区。可以为NULL |
length |
输入/输出 |
主机 |
此指针指向输入缓冲区大小。返回时,mcJPEG库将在此参数中存储实际的压缩流大小 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |
3.3.12. mcjpegEncodeRetrieveBitstreamDevice()
从先前在一个编码函数中使用过的编码状态中获取压缩流。
data参数应指向设备内存。如果
data参数为NULL,则将在length参数中返回压缩流的大小。如果
data不为空,则提供的length参数应包含data缓冲区大小。如果提供的
length小于压缩流的大小,则返回错误。否则,压缩的流将存储在data缓冲区中,而实际的压缩缓冲区大小将存储在length参数中。
签名
mcjpegStatus_t mcjpegEncodeRetrieveBitstreamDevice(
mcjpegHandle_t handle,
mcjpegEncoderState_t encoder_state,
unsigned char *data,
size_t *length,
mcStream_t stream);
参数
参数 |
输入/输出 |
内存 |
描述 |
|---|---|---|---|
handle |
输入 |
主机 |
库句柄 |
encoder_state |
输入/输出 |
主机 |
先前在一个编码函数中使用过的 |
data |
输入/输出 |
设备 |
此指针指向设备内存中用于存储压缩流的缓冲区。可以为NULL |
length |
输入/输出 |
主机 |
此指针指向输入缓冲区大小。返回时,mcJPEG库将在此参数中存储实际的压缩流大小 |
stream |
输入 |
主机 |
MXMACA流,包含所有必需的设备操作 |