mpp_frame_get_ptr
时间: 2023-05-03 15:07:39 浏览: 180
mpp_frame_get_ptr是一种基于多媒体处理器(MPP)的应用程序接口(API)函数,用于获得视频帧的指针。该函数可在MPP中用于处理视频数据,例如视频解码或编码。
在使用mpp_frame_get_ptr函数时,开发人员需要提供一个MPP帧作为参数。该函数将返回指向该帧内存中数据的指针,以便应用程序能够访问视频数据。由于视频帧通常非常大,使用指针访问数据可以提高数据处理速度和效率。
通过使用mpp_frame_get_ptr函数,开发人员可以利用MPP的高效处理能力,轻松地读取和处理视频数据。此外,该函数还可以与其他MPP API函数一起使用,以实现更复杂的视频处理任务。
总而言之,mpp_frame_get_ptr函数是一种非常有用的API函数,可用于处理视频数据。通过使用该函数,开发人员可以利用MPP的高效处理能力,轻松地读取和处理视频数据。
相关问题
rk3588板子,mpp硬件编码示例 C++代码
以下是在 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 文档。
LINUX qt 用mpp库编写视频采集及保存视频文件 C++代码
下面是用MPP库编写视频采集和保存视频文件的C++代码示例:
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "mpp.h"
#define MPP_ALIGN(x, a) (((x)+(a)-1) & ~((a)-1))
typedef struct {
int width;
int height;
int fps;
int bitrate;
int gop;
int bps;
int qp;
} mpp_cfg_t;
typedef struct {
int fd;
void* addr;
int size;
} mpp_mem_t;
void* mpp_malloc(int size)
{
return malloc(size);
}
void mpp_free(void* ptr)
{
free(ptr);
}
int mpp_open(const char* name, int flag)
{
return open(name, flag);
}
int mpp_close(int fd)
{
return close(fd);
}
void* mpp_mmap(void* addr, int size, int prot, int flags, int fd, int offset)
{
return mmap(addr, size, prot, flags, fd, offset);
}
int mpp_munmap(void* addr, int size)
{
return munmap(addr, size);
}
int mpp_ioctl(int fd, int cmd, void* arg)
{
return ioctl(fd, cmd, arg);
}
int mpp_config(int fd, mpp_cfg_t* cfg)
{
MppApi* mpp = NULL;
MppCtx ctx = NULL;
MppParam param = NULL;
MppCodingType type = MPP_VIDEO_CodingAVC;
MppFrameFormat fmt = MPP_FMT_YUV420SP;
int ret = MPP_OK;
mpp = new MppApi(type);
if (!mpp) {
printf("MPP create failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_OUTPUT_FORMAT, &fmt);
if (ret) {
printf("MPP set output format failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_IDR_FRAME, NULL);
if (ret) {
printf("MPP set IDR frame failed!\n");
return -1;
}
param = mpp->param_new();
if (!param) {
printf("MPP new param failed!\n");
return -1;
}
mpp->param_set_uint32(param, "coding_type", type);
mpp->param_set_uint32(param, "width", cfg->width);
mpp->param_set_uint32(param, "height", cfg->height);
mpp->param_set_uint32(param, "fps_in_num", cfg->fps);
mpp->param_set_uint32(param, "fps_in_denorm", 1);
mpp->param_set_uint32(param, "bps_target", cfg->bitrate);
mpp->param_set_uint32(param, "gop_size", cfg->gop);
mpp->param_set_uint32(param, "bitrate", cfg->bps);
mpp->param_set_uint32(param, "qp_init", cfg->qp);
mpp->param_set_uint32(param, "qp_max", cfg->qp);
mpp->param_set_uint32(param, "qp_min", cfg->qp);
ret = mpp->control(ctx, MPP_SET_OUTPUT_PARAMETER, param);
if (ret) {
printf("MPP set output parameter failed!\n");
return -1;
}
mpp->param_delete(¶m);
delete mpp;
return 0;
}
int mpp_mem_alloc(mpp_mem_t* mem, int size)
{
mem->fd = open("/dev/mem", O_RDWR|O_SYNC);
if (mem->fd < 0) {
printf("Open /dev/mem failed!\n");
return -1;
}
mem->size = MPP_ALIGN(size, 4096);
mem->addr = mmap(NULL, mem->size, PROT_READ | PROT_WRITE, MAP_SHARED, mem->fd, 0);
if (mem->addr == MAP_FAILED) {
printf("Mmap failed!\n");
return -1;
}
return 0;
}
int mpp_mem_free(mpp_mem_t* mem)
{
if (mem->addr) {
munmap(mem->addr, mem->size);
mem->addr = NULL;
}
if (mem->fd >= 0) {
close(mem->fd);
mem->fd = -1;
}
return 0;
}
int mpp_frame_encode(int fd, void* in, int in_size, void* out, int out_size)
{
MppApi* mpp = NULL;
MppCtx ctx = NULL;
MppFrame frame = NULL;
MppPacket packet = NULL;
MppBuffer buffer = NULL;
int ret = MPP_OK;
mpp = new MppApi(MPP_VIDEO_CodingAVC);
if (!mpp) {
printf("MPP create failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_INPUT_TIMEOUT, 5);
if (ret) {
printf("MPP set input timeout failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_OUTPUT_TIMEOUT, 5);
if (ret) {
printf("MPP set output timeout failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_INPUT_SIZE, &in_size);
if (ret) {
printf("MPP set input size failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_OUTPUT_SIZE, &out_size);
if (ret) {
printf("MPP set output size failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_INPUT_PTR, in);
if (ret) {
printf("MPP set input ptr failed!\n");
return -1;
}
ret = mpp->control(ctx, MPP_SET_OUTPUT_PTR, out);
if (ret) {
printf("MPP set output ptr failed!\n");
return -1;
}
frame = mpp->frame_new();
if (!frame) {
printf("MPP new frame failed!\n");
return -1;
}
mpp->frame_set_width(frame, 1920);
mpp->frame_set_height(frame, 1080);
mpp->frame_set_hor_stride(frame, 1920);
mpp->frame_set_ver_stride(frame, 1088);
mpp->frame_set_fmt(frame, MPP_FMT_YUV420SP);
mpp->frame_set_pts(frame, 0);
ret = mpp->control(ctx, MPP_ENC_GET_EXTRA_INFO, &packet);
if (ret) {
printf("MPP get extra info failed!\n");
return -1;
}
ret = mpp->encode_put_frame(ctx, frame);
if (ret) {
printf("MPP put frame failed!\n");
return -1;
}
ret = mpp->encode_get_packet(ctx, &packet);
if (ret) {
printf("MPP get packet failed!\n");
return -1;
}
ret = mpp->packet_write(packet, out, out_size);
if (ret) {
printf("MPP packet write failed!\n");
return -1;
}
mpp->packet_deinit(&packet);
mpp->frame_deinit(&frame);
delete mpp;
return 0;
}
int main(int argc, char* argv[])
{
mpp_cfg_t cfg;
mpp_mem_t input, output;
int fd = -1;
char* addr = NULL;
int size = 0;
int ret = 0;
memset(&cfg, 0, sizeof(cfg));
cfg.width = 1920;
cfg.height = 1080;
cfg.fps = 30;
cfg.bitrate = 4000000;
cfg.gop = 60;
cfg.bps = 2000000;
cfg.qp = 30;
ret = mpp_mem_alloc(&input, cfg.width * cfg.height * 3 / 2);
if (ret) {
printf("Input memory alloc failed!\n");
return -1;
}
ret = mpp_mem_alloc(&output, cfg.width * cfg.height * 3 / 2);
if (ret) {
printf("Output memory alloc failed!\n");
return -1;
}
ret = mpp_config(fd, &cfg);
if (ret) {
printf("MPP config failed!\n");
return -1;
}
fd = mpp_open("/dev/video0", O_RDWR);
if (fd < 0) {
printf("Open /dev/video0 failed!\n");
return -1;
}
while (1) {
addr = (char*)mpp_mmap(NULL, input.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
printf("Mmap input buffer failed!\n");
break;
}
ret = mpp_frame_encode(fd, addr, input.size, output.addr, output.size);
if (ret) {
printf("MPP encode failed!\n");
break;
}
mpp_munmap(addr, input.size);
}
mpp_mem_free(&input);
mpp_mem_free(&output);
mpp_close(fd);
return 0;
}
```
需要注意的是,上述代码是仅供参考的示例代码,具体实现还需要根据具体的需求进行调整和完善。
阅读全文