dm365:一 dm365的resizer使用

dm365的resizer使用

在用dm365的时候,用resizer的ioctl,一直不好使,后来在ti论坛上看到一个人的讲解,原来是bootargs的错。在配置的时候,有一项dm365_imp.oper_mode=1,这个要配成1.

下面是我的配置,仅供参考

setenv bootargs mem=64M console=ttyS0,115200n8 noinitrd rw ip=192.168.0.7:192.168.0.1:255.255.255.0 nfsroot=192.168.0.8:/home/mick/davinci/nfs_filesystem/dm365_filesys davinci_enc_mngr.ch0_output=LCD video=davincifb:vid0=720x480x16,2025K@0,0:osd0=720x480x16,1350K@0,0 davinci_capture.device_type=4 dm365_imp.oper_mode=1

dm365的LCD显示

       对DM365的decode做了修改,想让他原来的从小电视输出,改成用LCD输出。在DM365上面接了一个LCD屏幕。屏幕是800*480,被设置成720*480大小。从decode出来的数据,应该是YUV420PSEMI的,而就目前我知道的,LCD输出时UYVY的422格式。声明一下,目前没太多文档读,有些地方可能不对,希望谁发现了,就回帖告诉我一声,不胜感激。
       decode是用fifo活的的一帧的数据,在一个Buffer_Handle中。声明了两个hSrcBuf, hDstBuf,分别是源和目的。

下面是两行打印信息,关于这两个Buffer_Handle的。

************hSrc below:
[15] @ 0x4378a000 (0x86ee2000 phys) numBytes 718848 (718848) useMask 2 (3) ref no
Width 720 (720) Height 480 (576) Pos 24x24 LineLength 768 (720)
************hDst below:
[0] @ 0x40c00000 (0x80a00000 phys) numBytes 691200 (691200) useMask 0 (1) ref yes
Width 720 (720) Height 480 (480) Pos 0x0 LineLength 1440 (1440)

这两个视频帧的物理空间上的值在括号里面,是虚拟出来的空间的值在括号前面。可以看到,源的linelength是768,所以拷贝的时候,后面会有一些无用的数据。没有用decode自带的那个framecopy什么的,因为我用那个图像只能被扁着显示在左边的一半地方……然后我调用了ccv里面的420到422的转化,然后手动修改了dmai里面的转化代码,目前得到了黑白的数据,也就是y值。但是u,v的值还没搞好,现在是黑白图像,不过能够全屏720*480显示了。

for(i = 0; i < srcDim.height; i++) {
for(j=0; j < srcDim.width/4; j++) { 
*dst++ = *src_u;
*dst++ = *src++;
*dst++ = *src_v;
*dst++ = *src++; 
*dst++ = *src_u;
*dst++ = *src++;
*dst++ = *src_v;
*dst++ = *src++;
src_u += 2;
src_v += 2;
}
dst = dst + (dstDim.lineLength - srcDim.width*2);
src = src + (srcDim.lineLength - srcDim.width);
src_u = src_u + (srcDim.lineLength - srcDim.width);
src_v = src_v + (srcDim.lineLength - srcDim.width);
}

        这是我幻想的,算上u跟v的转化,可是u跟v的效果不行,颜色没加上……继续努力中
       不过,看dmai的代码,好像dm365不支持硬件ccv转化,用这种软的,相当浪费arm资源,打印的arm显示,已经占用超过90%了,而且只能显示5帧左右。

之前能显示了,后来仔细查了一下内核代码,发现可以不用去掉那个check var了。之前报错的原因是,在davincifb.c的convert_osd_to_fb_var函数中,case PIXFMT_NV12中少了一个break,所以出现var的像素值一直会变成32.所以,在这里加一个break,就不用注释掉check var那段代码了。

dm365 动态切换采集编码分辨率

这个是可以用的,而且用效率最低的办法去做,也就1.5秒左右的切换时间。这种来回变换的切换数据流可以按分辨率保存成不同文件,也可以通过网络发出去。VLC使用1.2的版本就能够动态切换分辨率了。以前经常使用0.8.6的版本,觉得挺好用,但是切屏这个就不行了,必须要换高版本。

DaVinci的Buffer_Handle和BufTab Cmem函数调用

aVinci的dvsdk里面,所有的内存用的都是CMEM,而比较上层的一个封装就是BufTab和Buffer_Handle了
每个Tab可以控制好多块内存块。具体到内存块有两种,一种是创建的时候指定他的大小啊,物理地址啥的。另外一种就是仅仅创建出这个结构的一个实例,而物理地址啊啥的都留空,等到回头用的时候,用指针搞定。
        第一类,对应的配置里面有一个叫reference的变量,配成false的话,创建的时候就直接创建出来内存块了,reference这点BufTab和Buffer_Handle的创建配置是一样的。
       第二类,reference配置成true,这样的话,创建之后,指针没有指向,而需要后面重新指定。指定的时候,要用Buffer_setUserPtr,同时还要设一下大小,Buffer_setNumBytesUsed,同时用这两个,不然程序会down掉的。

我试验了,使用CMEM手动分配物理空间,用reference=TRUE的配置,声明一个Buffer_handle的结构,使用cmem函数直接申请空间,然后再配置Buffer_handle的指针。

CMEM_AllocParams cmem_params; 
Int8 *ptr_area_fifo; 
cmem_params.type = CMEM_POOL; 
cmem_params.flags = CMEM_NONCACHED; 

for(loop_num = 0; loop_num < fifo_total; loop_num++) { 
	ptr_area_fifo = (Int8 *)CMEM_alloc(bufSize, &cmem_params); 
	//hBufTab is created while its reference=TRUE. 
	hDstBuf = BufTab_getBuf(hBufTab, loop_num); 
	Buffer_setNumBytesUsed(hDstBuf, bufSize); 
	if (Buffer_setUserPtr(hDstBuf, ptr_area_fifo) < 0) { 
		printf("error while set prt into bufTab, id=%d/n", loop_num); 
	} 
}


/******************************************************************************
 * Resize_create
 ******************************************************************************/
Resize_Handle Resize_create(Resize_Attrs *attrs)
{
#ifdef CONFIG_DM365_IPIPE
    Resize_Handle hResize;
    unsigned long oper_mode;    

    assert(attrs);

    hResize = (Resize_Handle)calloc(1, sizeof(Resize_Object));

    if (hResize == NULL) {
        Dmai_err0("Failed to allocate space for Framecopy Object\n");
        return NULL;
    }

    /* Open resizer device */
    hResize->fd = open(RESIZER_DEVICE, O_RDWR);

    if (hResize->fd == -1) {
        Dmai_err1("Failed to open %s\n", RESIZER_DEVICE);
        return NULL;
    }

    oper_mode = IMP_MODE_SINGLE_SHOT;

    if (ioctl(hResize->fd,RSZ_S_OPER_MODE, &oper_mode) < 0) {
        Dmai_err0("Resizer can't set operation mode\n");        
        goto cleanup;
    }

    if (ioctl(hResize->fd,RSZ_G_OPER_MODE, &oper_mode) < 0) {
        Dmai_err0("Resizer can't get operation mode\n");        
        goto cleanup;
    }
    
    if (oper_mode != IMP_MODE_SINGLE_SHOT) {
        Dmai_err1("Resizer can't set operation mode single shot, the mode is %d\n",
            oper_mode);        
        goto cleanup;
    }

    return hResize;

cleanup:
    close(hResize->fd);
    hResize->fd = 0;
    return NULL;
#else
    Dmai_err0("not implemented\n");
    return NULL;
#endif
}

/******************************************************************************
 * Resize_config
 ******************************************************************************/
Int Resize_config(Resize_Handle hResize,
                  Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf)
{
#ifdef CONFIG_DM365_IPIPE
    BufferGfx_Dimensions srcDim, dstDim;
    UInt                 hDif;
    UInt                 vDif;    
    struct rsz_channel_config rsz_chan_config;
    struct rsz_single_shot_config rsz_ss_config;

    /* Make sure our input parameters are valid */
    if (!hResize) {
        Dmai_err0("Resize_Handle parameter must not be NULL\n");
        return Dmai_EINVAL;
    }   
    
    if (!hSrcBuf) {
        Dmai_err0("Source buffer parameter must not be NULL\n");
        return Dmai_EINVAL;
    }   

    if (!hDstBuf) {
        Dmai_err0("Destination buffer parameter must not be NULL\n");
        return Dmai_EINVAL;
    }
    
    /* Buffer needs to be graphics buffers */
    if (Buffer_getType(hSrcBuf) != Buffer_Type_GRAPHICS ||
        Buffer_getType(hDstBuf) != Buffer_Type_GRAPHICS) {

        Dmai_err0("Src and dst buffers need to be graphics buffers\n");
        return Dmai_EINVAL;
    }

    BufferGfx_getDimensions(hSrcBuf, &srcDim);
    BufferGfx_getDimensions(hDstBuf, &dstDim);

    if (dstDim.width <= 0) {
        Dmai_err0("Destination buffer width must be greater than zero\n");
        return Dmai_EINVAL;
    }

    if (dstDim.height <= 0) {
        Dmai_err0("Destination buffer height must be greater than zero\n");
        return Dmai_EINVAL;
    }

    if ((srcDim.lineLength & 0x1F) != 0) {
        Dmai_err0("Source buffer pitch must be a multiple of 32 bytes\n");
        return Dmai_EINVAL;
    }

    if ((dstDim.lineLength & 0x1F) != 0) {
        Dmai_err0("Destination buffer pitch must be a multiple of 32 bytes\n");
        return Dmai_EINVAL;
    }


    /* Check for valid buffer scaling */
    hDif = srcDim.width  * 256 / dstDim.width;
    vDif = srcDim.height * 256 / dstDim.height;

    if (hDif < 32) {
        Dmai_err0("Horizontal up-scaling must not exceed 8x\n");
        return Dmai_EINVAL;
    }

    if (hDif > 4096) {
        Dmai_err0("Horizontal down-scaling must not exceed 1/16x\n");
        return Dmai_EINVAL;
    }

    if (vDif < 32) {
        Dmai_err0("Vertical up-scaling must not exceed 8x\n");
        return Dmai_EINVAL;
    }

    if (vDif > 4096) {
        Dmai_err0("Vertical down-scaling must not exceed 1/16x\n");
        return Dmai_EINVAL;
    }

    /* Set the driver default parameters and retrieve what was set */
    Dmai_clear(rsz_ss_config);
    rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT;
    rsz_chan_config.chain = 0;
    rsz_chan_config.len = 0;
    rsz_chan_config.config = NULL; /* to set defaults in driver */
    if (ioctl(hResize->fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err0("Error in setting default configuration for single shot mode\n");
        goto cleanup;
    }

    /* default configuration setting in Resizer successfull */
    Dmai_clear(rsz_ss_config);
    rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT;
    rsz_chan_config.chain = 0;
    rsz_chan_config.len = sizeof(struct rsz_single_shot_config);
    rsz_chan_config.config = &rsz_ss_config;

    if (ioctl(hResize->fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err0("Error in getting resizer channel configuration from driver\n");
        goto cleanup;
    }

    /* input params are set at the resizer */
    rsz_ss_config.input.image_width  = srcDim.width;
    rsz_ss_config.input.image_height = srcDim.height;
    rsz_ss_config.input.ppln = rsz_ss_config.input.image_width + 8;
    rsz_ss_config.input.lpfr = rsz_ss_config.input.image_height + 10;
    rsz_ss_config.input.pix_fmt = pixFormatConversion(BufferGfx_getColorSpace(hSrcBuf));
    rsz_ss_config.output1.pix_fmt = pixFormatConversion(BufferGfx_getColorSpace(hDstBuf));
    rsz_ss_config.output1.enable = 1;
    rsz_ss_config.output1.width = dstDim.width;
    rsz_ss_config.output1.height = dstDim.height;
    rsz_ss_config.output2.enable = 0;

    rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT;
    rsz_chan_config.chain = 0;
    rsz_chan_config.len = sizeof(struct rsz_single_shot_config);
    if (ioctl(hResize->fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err0("Error in setting default configuration for single shot mode\n");
        goto cleanup;
    }
    rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT;
    rsz_chan_config.chain = 0;
    rsz_chan_config.len = sizeof(struct rsz_single_shot_config);

    /* read again and verify */
    if (ioctl(hResize->fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err0("Error in getting configuration from driver\n");
        goto cleanup;
    }

    return Dmai_EOK;
    
cleanup:
    close(hResize->fd);
    hResize->fd = 0;    
    return Dmai_EFAIL;
#else
    Dmai_err0("not implemented\n");
    return Dmai_ENOTIMPL;
#endif
}

/******************************************************************************
 * Resize_execute
 ******************************************************************************/
Int Resize_execute(Resize_Handle hResize,
                   Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf)
{
#ifdef CONFIG_DM365_IPIPE
    struct imp_convert  rsz;
    BufferGfx_Dimensions srcDim;
    BufferGfx_Dimensions dstDim;
    UInt32               srcOffset;
    UInt32               dstOffset;
    
    assert(hResize);
    assert(hSrcBuf);
    assert(hDstBuf);

    Dmai_clear(rsz);

    BufferGfx_getDimensions(hSrcBuf, &srcDim);
    BufferGfx_getDimensions(hDstBuf, &dstDim);

    srcOffset = srcDim.y * srcDim.lineLength + (srcDim.x << 1);
    dstOffset = dstDim.y * dstDim.lineLength + (dstDim.x << 1);

    rsz.in_buff.index     = -1;
    rsz.in_buff.buf_type  = IMP_BUF_IN;
    rsz.in_buff.offset    = (UInt32) Buffer_getUserPtr(hSrcBuf) + srcOffset;
    rsz.in_buff.size      = Buffer_getSize(hSrcBuf);

    rsz.out_buff1.index    = -1;
    rsz.out_buff1.buf_type = IMP_BUF_OUT1;
    rsz.out_buff1.offset   = (UInt32) Buffer_getUserPtr(hDstBuf) + dstOffset;
    rsz.out_buff1.size     = Buffer_getSize(hDstBuf);
    
    /* 
     * The IPIPE requires that the memory offsets of the input and output
     * buffers start on 32-byte boundaries.
     */
    assert((rsz.in_buff.offset  & 0x1F) == 0);
    assert((rsz.out_buff1.offset & 0x1F) == 0);

    /* Start IPIPE operation */
    if (ioctl(hResize->fd, RSZ_RESIZE, &rsz) == -1) {
        Dmai_err0("Failed RSZ_RESIZE\n");
        return Dmai_EFAIL;
    }

    Buffer_setNumBytesUsed(hDstBuf, Buffer_getNumBytesUsed(hSrcBuf));
    return Dmai_EOK;
#else
    Dmai_err0("not implemented\n");
    return Dmai_ENOTIMPL;
#endif
}

/******************************************************************************
 * Resize_delete
 ******************************************************************************/
Int Resize_delete(Resize_Handle hResize)
{
#ifdef CONFIG_DM365_IPIPE
    if (hResize) {
        close(hResize->fd);
        free(hResize);
    }
#endif
    return Dmai_EOK;
}

/******************************************************************************
 * Initialize & configure resizer in on-the-fly (continous) mode
 ******************************************************************************/
Int Resizer_continuous_config(void)
{
#ifdef CONFIG_DM365_IPIPE
    Int rsz_fd;
    unsigned int oper_mode, user_mode;
    struct rsz_channel_config rsz_chan_config;
    struct rsz_continuous_config rsz_cont_config;

    user_mode = IMP_MODE_CONTINUOUS;
    rsz_fd = open((const char *)RESIZER_DEVICE, O_RDWR);
    if(rsz_fd <= 0) {
        Dmai_err0("Cannot open resize device \n");
        return NULL;
    }
    
    if (ioctl(rsz_fd, RSZ_S_OPER_MODE, &user_mode) < 0) {
        Dmai_err1("Can't set operation mode (%s)\n", strerror(errno));
        close(rsz_fd);
        return Dmai_EFAIL;
    }

    if (ioctl(rsz_fd, RSZ_G_OPER_MODE, &oper_mode) < 0) {
        Dmai_err1("Can't get operation mode (%s)\n", strerror(errno));
        close(rsz_fd);
        return Dmai_EFAIL;
    }

    if (oper_mode == user_mode) {
        Dmai_dbg0("Successfully set mode to continuous in resizer\n");
    } else {
        Dmai_err0("Failed to set mode to continuous in resizer\n");
        close(rsz_fd);
        return Dmai_EFAIL;
    }
        
    /* set configuration to chain resizer with preview */
    rsz_chan_config.oper_mode = user_mode;
    rsz_chan_config.chain  = 1;
    rsz_chan_config.len = 0;
    rsz_chan_config.config = NULL; /* to set defaults in driver */
    if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err1("Error in setting default configuration in resizer (%s)\n", 
            strerror(errno));
        close(rsz_fd);
        return Dmai_EFAIL;
    }
    
    bzero(&rsz_cont_config, sizeof(struct rsz_continuous_config));
    rsz_chan_config.oper_mode = user_mode;
    rsz_chan_config.chain = 1;
    rsz_chan_config.len = sizeof(struct rsz_continuous_config);
    rsz_chan_config.config = &rsz_cont_config;

    if (ioctl(rsz_fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err1("Error in getting channel configuration from resizer (%s)\n",
            strerror(errno));
        close(rsz_fd);
        return Dmai_EFAIL;
    }
        
    /* we can ignore the input spec since we are chaining. So only
       set output specs */
    rsz_cont_config.output1.enable = 1;
    rsz_cont_config.output2.enable = 0;
    rsz_chan_config.len = sizeof(struct rsz_continuous_config);
    rsz_chan_config.config = &rsz_cont_config;
    if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) {
        Dmai_err1("Error in setting resizer configuration (%s)\n", 
            strerror(errno));
        close(rsz_fd);
        return Dmai_EFAIL;
    }
    Dmai_dbg0("Resizer initialized\n");
    return rsz_fd;
#else
    Dmai_err0("not implemented\n");
    return Dmai_ENOTIMPL;
#endif
}

/******************************************************************************
 * Initialize & configure previewer in on-the-fly (continous) mode
 ******************************************************************************/
Int Previewer_continuous_config(Bool setRgbColorPallet)
{
#ifdef CONFIG_DM365_IPIPE
    Int preview_fd;
    unsigned int oper_mode, user_mode;
    struct prev_channel_config prev_chan_config;
    struct prev_continuous_config prev_cont_config;
    struct prev_cap cap;
    struct prev_module_param mod_param;
    user_mode = IMP_MODE_CONTINUOUS;
    
    preview_fd = open((const char *)PREVIEWER_DEVICE, O_RDWR);
    if(preview_fd <= 0) {
        Dmai_err0("Cannot open previewer device \n");
        return NULL;
    }

    if (ioctl(preview_fd,PREV_S_OPER_MODE, &user_mode) < 0) {
        Dmai_err1("Can't set operation mode in previewer (%s)\n", strerror(errno));
        close(preview_fd);        
        return Dmai_EFAIL;
    }

    if (ioctl(preview_fd,PREV_G_OPER_MODE, &oper_mode) < 0) {
        Dmai_err1("Can't get operation mode from previewer (%s)\n", strerror(errno));
        close(preview_fd);        
        return Dmai_EFAIL;
    }

    if (oper_mode == user_mode) {
        Dmai_dbg0("Operating mode changed successfully to continuous in previewer\n");
    } else {
        Dmai_err0("failed to set mode to continuous in previewer\n");
        close(preview_fd);
        return Dmai_EFAIL;
    }

    prev_chan_config.oper_mode = oper_mode;
    prev_chan_config.len = 0;
    prev_chan_config.config = NULL; /* to set defaults in driver */

    if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) {
        Dmai_err1("Error in setting default previewer configuration (%s)\n", 
            strerror(errno));
        close(preview_fd);
        return Dmai_EFAIL;
    }

    if (setRgbColorPallet) {
        Dmai_dbg0("Setting RGB color pallet\n");
        prev_chan_config.oper_mode = oper_mode;
        prev_chan_config.len = sizeof(struct prev_continuous_config);
        prev_chan_config.config = &prev_cont_config; /* to set defaults in driver */

        if (ioctl(preview_fd, PREV_G_CONFIG, &prev_chan_config) < 0) {
            Dmai_err1("Error in setting default previewer configuration (%s)\n", 
                strerror(errno));
            close(preview_fd);
            return Dmai_EFAIL;
        }

        prev_chan_config.oper_mode = oper_mode;
        prev_chan_config.len = sizeof(struct prev_continuous_config);
        prev_chan_config.config = &prev_cont_config; /* to set defaults in driver */

        prev_cont_config.input.colp_elep= IPIPE_BLUE;
        prev_cont_config.input.colp_elop= IPIPE_GREEN_BLUE;
        prev_cont_config.input.colp_olep= IPIPE_GREEN_RED;
        prev_cont_config.input.colp_olop= IPIPE_RED;

        if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) {
            Dmai_err1("Error in setting default previewer configuration (%s)\n", 
                strerror(errno));
            close(preview_fd);
            return Dmai_EFAIL;
        }

        cap.index=0;
        while (1) {
            if (ioctl(preview_fd , PREV_ENUM_CAP, &cap) < 0) {
                break;
            }

            strcpy(mod_param.version,cap.version);
            mod_param.module_id = cap.module_id;

           // using defaults
            Dmai_dbg1("Setting default for %s\n", cap.module_name);
            mod_param.param = NULL;
            if (ioctl(preview_fd, PREV_S_PARAM, &mod_param) < 0) {
                Dmai_err1("Error in Setting %s params from driver\n", cap.module_name);
                close(preview_fd);
                return Dmai_EFAIL; 
            }
            cap.index++;
        }
    }

    Dmai_dbg0("Previewer initialized\n");
    return preview_fd;
#else
    Dmai_err0("not implemented\n");
    return Dmai_ENOTIMPL;
#endif
}

/******************************************************************************
 * Resizer_continuous_delete
 ******************************************************************************/
Int Resizer_continuous_delete(Int fd)
{
    if (fd) {
        if (close(fd) == -1) {
            Dmai_err1("Failed to close resizer device (%s)\n", strerror(errno));
            return Dmai_EIO;
        }        
    }
    return Dmai_EOK;
}

/******************************************************************************
 * Previewer_continuous_delete
 ******************************************************************************/
Int Previewer_continuous_delete(Int fd)
{
    if (fd) {
        if (close(fd) == -1) {
            Dmai_err1("Failed to close previewer device (%s)\n", strerror(errno));
            return Dmai_EIO;
        }        
    }
    return Dmai_EOK;
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值