IPU缩放图片的实现

参考程序:https://github.com/rogeriorps/ipu-examples/tree/master/mx6
目前imx6系列是支持IPU的缩放功能的。准备好所需的库libipu.so、libipu.so.0和头文件ipu.h、mxcfb.h,在Qt下编写该程序,使用ycoto编译器交叉编译到开发板运行。

pro文件:

 LIBS += "$$PWD/libs/libipu.so" "$$PWD/libs/libipu.so.0"

调用方法:

  scale_image( "/media/sd-mmcblk2p1/ipu_main/images/img.jpg", 640, 480, "/media/sd-mmcblk2p1/ipu_main/images/img_320_24.jpg", 320, 240 );//缩小图片至320*240大小
    scale_image( "/media/sd-mmcblk2p1/ipu_main/images/img.jpg", 640, 480, "/media/sd-mmcblk2p1/ipu_main/images/img_1000_1000.jpg", 1000, 1000 );//放大图片至1000*1000大小

方法实现:

int IPUScale::scale_image( QString s_src_file, unsigned int n_src_width, unsigned int n_src_height,
                           QString s_des_file, unsigned int n_des_width, unsigned int n_des_height )
{
    struct ipu_task task;
    struct timeval begin, end;
    int sec, usec, run_time = 0;
    int fd_ipu = 0;   // IPU file descriptor
    int isize = 0, osize = 0, ret = 0;    // input size output size
    void *inbuf = NULL;
    void *outbuf = NULL;

    memset(&task, 0, sizeof(task));
    // Input image size and format
    task.input.width    = n_src_width;
    task.input.height   = n_src_height;
    task.input.format   = v4l2_fourcc('R', 'G', 'B', 'A');
    // Output image size and format
    task.output.width   = n_des_width;
    task.output.height  = n_des_height;
    task.output.format  = v4l2_fourcc('R', 'G', 'B', 'A');

    QImage src_img = QImage( n_src_width, n_src_height, QImage::Format_RGB32 );
    QImage des_img;
    bool b_save_status;
    src_img.load( s_src_file );
    int img_size = src_img.byteCount();
    unsigned char *buf = src_img.bits();
    qDebug()<<"img_size: "<<img_size<<src_img.size();
    qDebug()<<"open IPU device!";
    fd_ipu = open("/dev/mxc_ipu", O_RDWR, 0);
    if (fd_ipu < 0) {
        printf("open ipu dev fail\n");
        ret = -1;
        goto done;
    }
    qDebug()<<"according to format: "<<task.input.width<<task.input.height<<fmt_to_bpp(task.input.format);
//    isize = task.input.paddr = task.input.width * task.input.height* fmt_to_bpp(task.input.format)/8;
    isize = task.input.paddr = img_size;

    // Allocate contingous physical memory for input image
    // input.paddr contains the amount needed
    // this value will be replaced with physical address on success
    ret = ioctl(fd_ipu, IPU_ALLOC, &task.input.paddr);
    if (ret < 0) {
        printf("ioctl IPU_ALLOC fail: (errno = %d)\n", errno);
        goto done;
    }

    // Create memory map and obtain the allocated memory virtual address
    inbuf = mmap(0, isize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_ipu, task.input.paddr);
    if (!inbuf) {
        printf("mmap fail\n");
        ret = -1;
        goto done;
    }

    // Allocate memory for output image
    osize = task.output.paddr = task.output.width * task.output.height * fmt_to_bpp(task.output.format)/8;
    ret = ioctl(fd_ipu, IPU_ALLOC, &task.output.paddr);
    if (ret < 0) {
        printf("ioctl IPU_ALLOC fail\n");
        goto done;
    }

    // Create memory map for output image
    outbuf = mmap(0, osize, PROT_READ | PROT_WRITE,
    MAP_SHARED, fd_ipu, task.output.paddr);
    if (!outbuf) {
        printf("mmap fail\n");
        ret = -1;
        goto done;
    }
    memcpy( inbuf, buf, isize );

    gettimeofday(&begin, NULL);
    // Perform the rotation
    ret = ioctl(fd_ipu, IPU_QUEUE_TASK, &task);
    if (ret < 0) {
        printf("ioct IPU_QUEUE_TASK fail\n");
        goto done;
    }
    gettimeofday(&end, NULL);

    sec = end.tv_sec - begin.tv_sec;
    usec = end.tv_usec - begin.tv_usec;
    if (usec < 0) {
        sec--;
        usec = usec + 1000000;
    }
    run_time = (sec * 1000000) + usec;

    // Write resized image to output file
    des_img = QImage( (const uchar*)outbuf, n_des_width, n_des_height, QImage::Format_RGB32 );
    qDebug()<<des_img.byteCount()<<des_img.size()<<osize;
    b_save_status = des_img.save( s_des_file );
    qDebug()<<"save status: "<<b_save_status;

    printf("Resize time: %d usecs\n", run_time);
done:

    if (outbuf)
        munmap(outbuf, osize);
    if (task.output.paddr)
        ioctl(fd_ipu, IPU_FREE, &task.output.paddr);
    if (inbuf)
        munmap(inbuf, isize);
    if (task.input.paddr)
        ioctl(fd_ipu, IPU_FREE, &task.input.paddr);
    if (fd_ipu)
        close(fd_ipu);

    return ret;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱技术爱生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值