rk3588板子,mpp硬件编码示例 C++代码
时间: 2023-07-11 20:52:19 浏览: 251
以下是在 RK3588 板子上使用 MPP 硬件编码的示例 C++ 代码:
```c++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rockchip/rk_mpi.h"
#include "rockchip/mpp_buffer.h"
#include "rockchip/mpp_frame.h"
#include "rockchip/mpp_packet.h"
#include "rockchip/mpp_mem.h"
#define MAX_FILE_NAME_LENGTH 256
#define MAX_FRAME_SIZE (1920 * 1080 * 3 / 2)
int main(int argc, char **argv) {
if (argc != 4) {
printf("Usage: %s input_width input_height output_format\n", argv[0]);
return -1;
}
int width = atoi(argv[1]);
int height = atoi(argv[2]);
MppCodingType format = MPP_VIDEO_CodingAVC;
if (strcmp(argv[3], "H264") == 0) {
format = MPP_VIDEO_CodingAVC;
} else if (strcmp(argv[3], "H265") == 0) {
format = MPP_VIDEO_CodingHEVC;
} else {
printf("Invalid output format: %s\n", argv[3]);
return -1;
}
// 初始化 MPP
MPP_RET ret;
ret = mpp_init();
if (ret) {
printf("mpp_init failed: %d\n", ret);
return -1;
}
// 创建编码器
MppCtx ctx;
ret = mpp_create(&ctx, MPP_CTX_ENC);
if (ret) {
printf("mpp_create failed: %d\n", ret);
mpp_deinit();
return -1;
}
// 配置编码器参数
MppEncConfig cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.codec = format;
cfg.width = width;
cfg.height = height;
cfg.fps_in = 30;
cfg.fps_out = 30;
cfg.gop = 60;
cfg.bitrate = width * height * 2;
cfg.profile = 100;
cfg.level = 40;
ret = mpp_enc_config_set(ctx, &cfg);
if (ret) {
printf("mpp_enc_config_set failed: %d\n", ret);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
// 初始化编码器
ret = mpp_init(ctx, MPP_CTX_ENC, format);
if (ret) {
printf("mpp_init failed: %d\n", ret);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
// 创建输入 YUV 图像和输出码流缓冲区
MppFrame frame;
MppBuffer frame_buf;
MppPacket packet;
MppBuffer packet_buf;
ret = mpp_frame_init(&frame);
if (ret) {
printf("mpp_frame_init failed: %d\n", ret);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
ret = mpp_buffer_get(frame_buf, MAX_FRAME_SIZE, MPP_BUFFER_TYPE_ION);
if (ret) {
printf("mpp_buffer_get failed: %d\n", ret);
mpp_frame_deinit(&frame);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
ret = mpp_frame_set_buffer(frame, frame_buf);
if (ret) {
printf("mpp_frame_set_buffer failed: %d\n", ret);
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
ret = mpp_packet_init(&packet, packet_buf);
if (ret) {
printf("mpp_packet_init failed: %d\n", ret);
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
// 打开输入 YUV 文件和输出码流文件
char file_name[MAX_FILE_NAME_LENGTH];
sprintf(file_name, "input_%dx%d.yuv", width, height);
FILE *input_file = fopen(file_name, "rb");
if (!input_file) {
printf("Cannot open input file: %s\n", file_name);
mpp_packet_deinit(packet);
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
sprintf(file_name, "output_%dx%d.%s", width, height, argv[3]);
FILE *output_file = fopen(file_name, "wb");
if (!output_file) {
printf("Cannot open output file: %s\n", file_name);
fclose(input_file);
mpp_packet_deinit(packet);
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
mpp_destroy(ctx);
mpp_deinit();
return -1;
}
// 读取并编码每一帧 YUV 图像
int frame_idx = 0;
while (!feof(input_file)) {
// 读取 YUV 图像
size_t size = width * height * 3 / 2;
uint8_t *data = mpp_buffer_get_ptr(frame_buf);
size_t read_size = fread(data, 1, size, input_file);
if (read_size != size) {
break;
}
// 设置 YUV 图像属性
mpp_frame_set_width(frame, width);
mpp_frame_set_height(frame, height);
mpp_frame_set_format(frame, MPP_FMT_YUV420SP);
// 编码 YUV 图像
ret = mpp_enc_encode(ctx, frame, packet);
if (ret) {
printf("mpp_enc_encode failed: %d\n", ret);
break;
}
// 写入码流数据
size_t packet_size = mpp_packet_get_length(packet);
uint8_t *packet_data = mpp_packet_get_data(packet);
fwrite(packet_data, 1, packet_size, output_file);
// 输出进度
printf("Frame %d: %lu bytes\n", frame_idx, packet_size);
frame_idx++;
}
// 清理资源
fclose(input_file);
fclose(output_file);
mpp_packet_deinit(packet);
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
mpp_destroy(ctx);
mpp_deinit();
return 0;
}
```
这是一个简单的编码器程序,它读取指定分辨率的 YUV 文件,使用 MPP 硬件编码器将 YUV 图像编码为指定格式的码流文件。具体细节可以参考 Rockchip 提供的 MPP API 文档。
阅读全文