RK3328 解码
如何对RK3328 Ubuntu 18.04的硬件解码进行调试呢?结果怎样?
回帖(1)
2022-3-9 14:21:46
确认系统中存在 /dev/rga 设备节点,该节点是RK图形加速引擎RGA,详细介绍可以看RK的介绍。
烧录RK3328 ubuntu18.04 固件到SD卡。首先,到SD Firmware Tool 下载去下载 SD_Firmware_Tool,并解压。
- 插入 SD 卡。
- 从组合框中选择 SD 卡对应的设备。
- 勾选 “SD启动” 选项。
- 点击 “选择固件” 按钮,在文件对话框中选择RK 固件。
- 点击 “开始创建” 按钮。
- 然后会显示警告对话框,选择 “是” 来确保选择了正确的SD卡设备。
- 等待操作完成,直到提示成功对话框出现:
创建升级磁盘成功。
插入SDK,启动系统,然后更新源地址
sudo vim /etc/apt/sources.list
退出保存,终端输入: sudo apt-get update
安装rtsp依赖环境,终端输入:sh setenv.sh
编译代码,mkidr build; cmake …; make -j4
硬件解码代码:
#include
#include "mpp-dec.hpp"
MppDec::MppDec()
{
recv_count = 0;
dec_count = 0;
}
MppDec::~MppDec()
{
if(mdec != NULL)
MppDecoderDestroy(mdec);
}
int MppDec::init(DecodeType type)
{
mdec = MppDecoderCreate(type);
if(mdec == NULL) {
return -1;
}
return 0;
}
int MppDec::enqueue(unsigned char *buf, size_t len)
{
int ret;
ret = mdec->ops->enqueue(mdec, buf, len);
recv_count++;
return ret;
}
DecFrame* MppDec::dequeue(void)
{
DecFrame *frame = mdec->ops->dequeue_timeout(mdec, 300);
if(frame != NULL) {
dec_count++;
}
return frame;
}
void MppDec::freeFrame(DecFrame *frame)
{
mdec->ops->freeFrame(frame);
}
void MppDec::onStreamReceive(unsigned char *buf, size_t len)
{
while(enqueue(buf, len) != 0) {
std::cout << "enqueue err" << std::endl;
usleep(1000);
}
}
#include
#include "drm-buff.hpp"
static int DrmAllocBuffer(int drm_fd, DrmBuffer *drm_buffer, int width,
int height, int bpp)
{
struct drm_mode_create_dumb arg;
int ret;
memset(&arg, 0, sizeof(arg));
arg.bpp = bpp;
arg.width = width;
arg.height = height;
ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
if (ret) {
fprintf(stderr, "failed to create dumb buffer: %sn", strerror(errno));
return ret;
}
drm_buffer->handle = arg.handle;
drm_buffer->size = arg.size;
drm_buffer->pitch = arg.pitch;
return 0;
}
static int DrmFreeBuffer(int drm_fd, DrmBuffer *drm_buffer)
{
struct drm_mode_destroy_dumb arg;
int ret;
if (drm_buffer->handle <= 0)
return -EINVAL;
memset(&arg, 0, sizeof(arg));
arg.handle = drm_buffer->handle;
ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
if (ret){
fprintf(stderr, "failed to destroy dumb buffer: %sn", strerror(errno));
return -errno;
}
drm_buffer->handle = 0;
return 0;
}
int DrmGetAllocBuffer(DrmBuffer *drm_buffer, int width, int height, int bpp)
{
static const char* card = "/dev/dri/card0";
int ret;
int drm_fd;
int flag = O_RDWR;
#ifdef O_CLOEXEC
flag |= O_CLOEXEC;
#endif
drm_buffer->fd = -1;
drm_buffer->handle = 0;
drm_fd = open(card, flag);
if (drm_fd < 0) {
fprintf(stderr, "Fail to open %s: %mn", card);
return -errno;
}
ret = DrmAllocBuffer(drm_fd, drm_buffer, width, height, bpp);
if (ret) {
close(drm_fd);
return ret;
}
drm_buffer->fd = drm_fd;
return 0;
}
int DrmGetMmap(DrmBuffer *drm_buffer)
{
struct drm_mode_map_dumb arg;
void *map;
int ret;
memset(&arg, 0, sizeof(arg));
arg.handle = drm_buffer->handle;
ret = drmIoctl(drm_buffer->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
if (ret)
return ret;
map = mmap64(0, drm_buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_buffer->fd, arg.offset);
if (map == MAP_FAILED)
return -EINVAL;
drm_buffer->ptr = map;
return 0;
}
int DrmUnmap(DrmBuffer *drm_buffer)
{
munmap(drm_buffer->ptr, drm_buffer->size);
drm_buffer->ptr = NULL;
return 0;
}
int DrmFree(DrmBuffer *drm_buffer)
{
int ret;
if (drm_buffer->fd < 0)
return -EINVAL;
ret = DrmFreeBuffer(drm_buffer->fd, drm_buffer);
close(drm_buffer->fd);
drm_buffer->fd = -1;
return ret;
}
int DrmGetBufferFd(DrmBuffer *drm_buffer)
{
int ret = 0;
ret = drmPrimeHandleToFD(drm_buffer->fd, drm_buffer->handle, 0, &(drm_buffer->buf_fd));
return ret;
}
int DrmCloseBufferFd(DrmBuffer *drm_buffer)
{
int ret = 0;
if (drm_buffer->buf_fd < 0)
return -EINVAL;
ret = close(drm_buffer->buf_fd);
return ret;
}
实现的是解码rtsp视频,然后送到SPR5801做目标检测,支持VGG-SSD、MobileNet-SSD,支持训练自己的数据集。
确认系统中存在 /dev/rga 设备节点,该节点是RK图形加速引擎RGA,详细介绍可以看RK的介绍。
烧录RK3328 ubuntu18.04 固件到SD卡。首先,到SD Firmware Tool 下载去下载 SD_Firmware_Tool,并解压。
- 插入 SD 卡。
- 从组合框中选择 SD 卡对应的设备。
- 勾选 “SD启动” 选项。
- 点击 “选择固件” 按钮,在文件对话框中选择RK 固件。
- 点击 “开始创建” 按钮。
- 然后会显示警告对话框,选择 “是” 来确保选择了正确的SD卡设备。
- 等待操作完成,直到提示成功对话框出现:
创建升级磁盘成功。
插入SDK,启动系统,然后更新源地址
sudo vim /etc/apt/sources.list
退出保存,终端输入: sudo apt-get update
安装rtsp依赖环境,终端输入:sh setenv.sh
编译代码,mkidr build; cmake …; make -j4
硬件解码代码:
#include
#include "mpp-dec.hpp"
MppDec::MppDec()
{
recv_count = 0;
dec_count = 0;
}
MppDec::~MppDec()
{
if(mdec != NULL)
MppDecoderDestroy(mdec);
}
int MppDec::init(DecodeType type)
{
mdec = MppDecoderCreate(type);
if(mdec == NULL) {
return -1;
}
return 0;
}
int MppDec::enqueue(unsigned char *buf, size_t len)
{
int ret;
ret = mdec->ops->enqueue(mdec, buf, len);
recv_count++;
return ret;
}
DecFrame* MppDec::dequeue(void)
{
DecFrame *frame = mdec->ops->dequeue_timeout(mdec, 300);
if(frame != NULL) {
dec_count++;
}
return frame;
}
void MppDec::freeFrame(DecFrame *frame)
{
mdec->ops->freeFrame(frame);
}
void MppDec::onStreamReceive(unsigned char *buf, size_t len)
{
while(enqueue(buf, len) != 0) {
std::cout << "enqueue err" << std::endl;
usleep(1000);
}
}
#include
#include "drm-buff.hpp"
static int DrmAllocBuffer(int drm_fd, DrmBuffer *drm_buffer, int width,
int height, int bpp)
{
struct drm_mode_create_dumb arg;
int ret;
memset(&arg, 0, sizeof(arg));
arg.bpp = bpp;
arg.width = width;
arg.height = height;
ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
if (ret) {
fprintf(stderr, "failed to create dumb buffer: %sn", strerror(errno));
return ret;
}
drm_buffer->handle = arg.handle;
drm_buffer->size = arg.size;
drm_buffer->pitch = arg.pitch;
return 0;
}
static int DrmFreeBuffer(int drm_fd, DrmBuffer *drm_buffer)
{
struct drm_mode_destroy_dumb arg;
int ret;
if (drm_buffer->handle <= 0)
return -EINVAL;
memset(&arg, 0, sizeof(arg));
arg.handle = drm_buffer->handle;
ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
if (ret){
fprintf(stderr, "failed to destroy dumb buffer: %sn", strerror(errno));
return -errno;
}
drm_buffer->handle = 0;
return 0;
}
int DrmGetAllocBuffer(DrmBuffer *drm_buffer, int width, int height, int bpp)
{
static const char* card = "/dev/dri/card0";
int ret;
int drm_fd;
int flag = O_RDWR;
#ifdef O_CLOEXEC
flag |= O_CLOEXEC;
#endif
drm_buffer->fd = -1;
drm_buffer->handle = 0;
drm_fd = open(card, flag);
if (drm_fd < 0) {
fprintf(stderr, "Fail to open %s: %mn", card);
return -errno;
}
ret = DrmAllocBuffer(drm_fd, drm_buffer, width, height, bpp);
if (ret) {
close(drm_fd);
return ret;
}
drm_buffer->fd = drm_fd;
return 0;
}
int DrmGetMmap(DrmBuffer *drm_buffer)
{
struct drm_mode_map_dumb arg;
void *map;
int ret;
memset(&arg, 0, sizeof(arg));
arg.handle = drm_buffer->handle;
ret = drmIoctl(drm_buffer->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
if (ret)
return ret;
map = mmap64(0, drm_buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_buffer->fd, arg.offset);
if (map == MAP_FAILED)
return -EINVAL;
drm_buffer->ptr = map;
return 0;
}
int DrmUnmap(DrmBuffer *drm_buffer)
{
munmap(drm_buffer->ptr, drm_buffer->size);
drm_buffer->ptr = NULL;
return 0;
}
int DrmFree(DrmBuffer *drm_buffer)
{
int ret;
if (drm_buffer->fd < 0)
return -EINVAL;
ret = DrmFreeBuffer(drm_buffer->fd, drm_buffer);
close(drm_buffer->fd);
drm_buffer->fd = -1;
return ret;
}
int DrmGetBufferFd(DrmBuffer *drm_buffer)
{
int ret = 0;
ret = drmPrimeHandleToFD(drm_buffer->fd, drm_buffer->handle, 0, &(drm_buffer->buf_fd));
return ret;
}
int DrmCloseBufferFd(DrmBuffer *drm_buffer)
{
int ret = 0;
if (drm_buffer->buf_fd < 0)
return -EINVAL;
ret = close(drm_buffer->buf_fd);
return ret;
}
实现的是解码rtsp视频,然后送到SPR5801做目标检测,支持VGG-SSD、MobileNet-SSD,支持训练自己的数据集。
举报