airockchip / librga

Apache License 2.0
243 stars 52 forks source link

关于使用imcvtcolor转换MppFrame图像的问题 #75

Closed Kevin111369 closed 1 month ago

Kevin111369 commented 3 months ago

我的目的是将mpp解码得到的yuv格式的图像转为bgr格式,但是MppFrame中存放的yuv数据并不是连续的,有hor_stride和ver_stride,这就导致一些无法被16整除的图像尺寸(例如1920x1080)的图像数据中y分量与uv分量中间有(例如1920x8)填充数据,直接将这个buf送入imcvtcolor会导致uv分量的数据无法对齐。有没有办法可以不拷贝数据,将frame的数据转为y分量和uv分量连续的数据,送入imcvtcolor进行转换。

Kevin111369 commented 3 months ago

我的目的是将mpp解码得到的yuv格式的图像转为bgr格式,但是MppFrame中存放的yuv数据并不是连续的,有hor_stride和ver_stride,这就导致一些无法被16整除的图像尺寸(例如1920x1080)的图像数据中y分量与uv分量中间有(例如1920x8)填充数据,直接将这个buf送入imcvtcolor会导致uv分量的数据无法对齐。有没有办法可以不拷贝数据,将frame的数据转为y分量和uv分量连续的数据,送入imcvtcolor进行转换。

我在使用wrapbuffer_handle封装RGA图像的时候加入了wstride和hstride参数,解决了上述问题,但是又出现了新的问题,我想利用rga_buffer中的vir_addr将图像数据写入文件中,为什么封装的rga_buffer中的vir_addr为空呢?以下是我的关键代码:

src_handle = importbuffer_fd(src_drm_fd, src_buf_size);
dst_handle = importbuffer_fd(dst_drm_fd, dst_buf_size);
if (src_handle == 0 || dst_handle == 0) {
    SAMPLE_EROOR_PRT("importbuffer failed!\n");
    goto release_buffer;
}

src_img = wrapbuffer_handle(src_handle, src_width, src_height, src_format, src_hor_stride, src_ver_stride);
dst_img = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format, dst_hor_stride, dst_ver_stride);

ret = imcheck(src_img, dst_img, {}, {});

if (IM_STATUS_NOERROR != ret) {
    SAMPLE_EROOR_PRT("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
    return -1;
}

ret = imcvtcolor(src_img, dst_img, src_format, dst_format);
if (ret != IM_STATUS_SUCCESS) {
    SAMPLE_EROOR_PRT("yuv2bgr running failed, %s\n", imStrError((IM_STATUS)ret));
    goto release_buffer;
}

int fd              = dst_img.fd;
int width           = dst_img.width;
int height          = dst_img.height;
int h_stride        = dst_img.wstride;
int v_stride        = dst_img.hstride;
int fmt             = dst_img.format;
char *buf_base      = (char *)dst_img.vir_addr;

SAMPLE_LOG_PRT("buf_base:%p,width:%d,height:%d,h_stride:%d,v_stride:%d,fmt:%d\n", buf_base, width, height, h_stride, v_stride, fmt);

打印的错误信息如下:

buf_base:(nil),width:1920,height:1080,h_stride:1920,v_stride:1080,fmt:1792
zengyao1999 commented 2 months ago

我认为wrapbuffer_handle中并没有对vir_addr赋值,所以vir_addr为空指针,可能需要对dst_img.handle进行操作。不过我直接使用wrapbuffer_virtualaddr方法是能够正常转换的,只不过按照文档的说法,这样效率比较低

TRYOKETHEPEN commented 2 months ago

dst_handle = importbuffer_fd(dst_drm_fd, dst_buf_size);

dst_handle换成importbuffer_virtualaddr()试试

dao027 commented 1 month ago
dst_drm_fd

请问你这里的dst_drm_fd是怎么定义的呢,需要怎样保存imcvtcolor转换以后的数据?我的src_fd是从mppframe拿过来的,那我转换以后也是存到mppbuffer里面吗?

Kevin111369 commented 1 month ago

请问你这里的dst_drm_fd是怎么定义的呢,需要怎样保存imcvtcolor转换以后的数据?我的src_fd是从mppframe拿过来的,那我转换以后也是存到mppbuffer里面吗?

我并没有存到mppbuffer中,而是自行维护转换后的数据

dao027 commented 1 month ago

请问你这里的dst_drm_fd是怎么定义的呢,需要怎样保存imcvtcolor转换以后的数据?我的src_fd是从mppframe拿过来的,那我转换以后也是存到mppbuffer里面吗?

我并没有存到mppbuffer中,而是自行维护转换后的数据

感谢回复,再请问下你这边有使用到sample中的这部分吗? ret = dma_buf_alloc(DMA_HEAP_DMA32_UNCACHED_PATH, dst_buf_size, &dst_dma_fd, (void **)&dst_buf); 这里的dst_dma_fd和你代码中的dst_drm_fd有区别吗?

Kevin111369 commented 1 month ago

感谢回复,再请问下你这边有使用到sample中的这部分吗? ret = dma_buf_alloc(DMA_HEAP_DMA32_UNCACHED_PATH, dst_buf_size, &dst_dma_fd, (void **)&dst_buf); 这里的dst_dma_fd和你代码中的dst_drm_fd有区别吗?

最初我使用的为drm_buf,但是后来在alloc过程中遇到了错误,所以我现在也在使用dma32_buf

dao027 commented 1 month ago

感谢回复,再请问下你这边有使用到sample中的这部分吗? ret = dma_buf_alloc(DMA_HEAP_DMA32_UNCACHED_PATH, dst_buf_size, &dst_dma_fd, (void **)&dst_buf); 这里的dst_dma_fd和你代码中的dst_drm_fd有区别吗?

最初我使用的为drm_buf,但是后来在alloc过程中遇到了错误,所以我现在也在使用dma32_buf

你好,遇到一点问题,想请教一下:

dst_buf = (char *)malloc(dst_buf_size);
memset(dst_buf, 0x80, dst_buf_size);
dst_handle = importbuffer_virtualaddr(dst_buf, dst_buf_size);

这里importbuffer_virtualaddr返回的值一直是0,然后就报importbuffer failed!这个是驱动版本的问题吗