推送mpp已经编码后的H265 MppPacket包,c或者c++代码
时间: 2024-03-16 19:45:31 浏览: 206
3588j-mpp库的简单应用
以下是推送mpp编码好的H265 MppPacket包的C++代码示例:
```
#include <iostream>
#include <memory.h>
#include <mpp/mpp.h>
#define MAX_FILE_NAME_LENGTH 256
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <input_file>\n";
return -1;
}
char input_file[MAX_FILE_NAME_LENGTH];
strncpy(input_file, argv[1], MAX_FILE_NAME_LENGTH);
mpp_env_init();
MppCtx mpp_ctx;
MppApi *mpp_api;
MppBuffer packet_buf;
MppPacket packet;
MppTask task;
MPP_RET ret = MPP_OK;
MppCodingType codec_type = MPP_VIDEO_CodingHEVC;
MppFrameFormat frame_fmt = MPP_FMT_YUV420SP;
MppPacketType packet_type = MPP_PACKET_NORMAL;
RK_U32 packet_size = 0;
RK_U8 *packet_data = NULL;
ret = mpp_create(&mpp_ctx, &mpp_api);
if (ret != MPP_OK) {
std::cerr << "Failed to create mpp context\n";
return -1;
}
MppParam param = {
.coding = codec_type,
.width = 1920,
.height = 1080,
.hor_stride = 1920,
.ver_stride = 1088,
.format = frame_fmt,
.frame_rate = 30,
.bps = 2000000,
.gop = 30,
.qp_init = 26,
.qp_step = 4,
.qp_min = 4,
.qp_max = 48,
.rc_mode = MPP_ENC_RC_MODE_CBR
};
ret = mpp_init(mpp_ctx, MPP_CTX_ENC, param);
if (ret != MPP_OK) {
std::cerr << "Failed to init mpp context\n";
mpp_destroy(mpp_ctx);
return -1;
}
FILE *fp = fopen(input_file, "rb");
if (!fp) {
std::cerr << "Failed to open input file " << input_file << "\n";
mpp_destroy(mpp_ctx);
return -1;
}
while (1) {
MppFrame frame;
MppBuffer frame_buf;
ret = mpp_frame_init(&frame);
if (ret != MPP_OK) {
std::cerr << "Failed to init frame\n";
break;
}
ret = mpp_buffer_get(mpp_ctx, &frame_buf, MPP_BUFFER_TYPE_ION);
if (ret != MPP_OK) {
std::cerr << "Failed to get buffer for frame\n";
mpp_frame_deinit(&frame);
break;
}
fread(mpp_buffer_get_ptr(frame_buf), 1, mpp_buffer_get_size(frame_buf), fp);
mpp_frame_set_width(frame, param.width);
mpp_frame_set_height(frame, param.height);
mpp_frame_set_hor_stride(frame, param.hor_stride);
mpp_frame_set_ver_stride(frame, param.ver_stride);
mpp_frame_set_fmt(frame, frame_fmt);
mpp_frame_set_buffer(frame, frame_buf);
ret = mpp_encode_put_frame(mpp_ctx, frame);
if (ret != MPP_OK) {
std::cerr << "Failed to put frame to encoder\n";
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
break;
}
ret = mpp_encode_get_packet(mpp_ctx, &packet);
if (ret != MPP_OK) {
std::cerr << "Failed to get packet from encoder\n";
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
break;
}
if (packet) {
packet_data = mpp_packet_get_data(packet);
packet_size = mpp_packet_get_length(packet);
// 这里将 packet_data 和 packet_size 发送出去
// ...
mpp_packet_deinit(&packet);
}
mpp_buffer_put(frame_buf);
mpp_frame_deinit(&frame);
}
fclose(fp);
mpp_destroy(mpp_ctx);
mpp_env_deinit();
return 0;
}
```
在这个示例中,我们先使用 `mpp_create` 创建 MPP 上下文和 API,然后使用 `mpp_init` 初始化编码器。在读取文件时,我们使用 `mpp_frame_init` 初始化 MPP 帧,使用 `mpp_buffer_get` 获取 MPP 缓冲区,然后使用 `fread` 读取输入文件并将其写入缓冲区。接下来,我们使用 `mpp_frame_set_*` 将帧的信息设置为正确的值,并使用 `mpp_frame_set_buffer` 将缓冲区与帧相关联。最后,我们将帧传递给编码器,使用 `mpp_encode_put_frame` 将其放入编码器的输入队列中。然后,我们使用 `mpp_encode_get_packet` 从编码器的输出队列中获取数据包。如果数据包存在,我们可以使用 `mpp_packet_get_data` 获取数据包的实际数据和 `mpp_packet_get_length` 获取数据包的长度。最后,我们使用 `mpp_packet_deinit` 释放数据包的内存,并使用 `mpp_buffer_put` 和 `mpp_frame_deinit` 释放帧和缓冲区的内存。
阅读全文