libyuv嵌入式平台使用说明

1.aarch64平台移植是需要根据不同指令集调整编译,dotprod指令支持需要armv8.2以上指令集,CortexA53架构的SOC编译失败。

2.MakeLists.txt里面有多个功能模块需要用的armv9指令集,如果SOC不支持需要编译前注释掉这些模块生产。

3.项目中用到的接口封装如下:

static int DispYV12Scale(char *src_img, int src_w, int src_h, char *dst_img, int dst_w, int dst_h)
{
    char *src_y_addr = src_img;
    char *src_v_addr = src_img + (src_w * src_h);
    char *src_u_addr = src_img + (src_w * src_h * 5 / 4);
    char *dst_y_addr = dst_img;
    char *dst_v_addr = dst_img + (dst_w * dst_h);
    char *dst_u_addr = dst_img + (dst_w * dst_h * 5 / 4);

    return I420Scale(src_y_addr, src_w, src_u_addr, src_w>>1, src_v_addr, src_w>>1, src_w, src_h, 
        dst_y_addr, dst_w, dst_u_addr, dst_w>>1, dst_v_addr, dst_w>>1, dst_w, dst_h, kFilterLinear);//kFilterNone
}

static int DispYV12ToARGB(char *yuv_img, char *rgb_img, int img_w, int img_h)
{
    char *src_y_addr = yuv_img;
    char *src_v_addr = yuv_img + (img_w * img_h);
    char *src_u_addr = yuv_img + (img_w * img_h * 5 / 4);

    return I420ToARGB(src_y_addr, img_w, src_u_addr, img_w>>1, src_v_addr, img_w>>1,
        rgb_img, img_w*4, img_w, img_h);
}

static int DispNV21Scale(char *src_img, int src_w, int src_h, char *dst_img, int dst_w, int dst_h)
{
    int ret = 0;
    char *src_y_addr = src_img;
    char *src_vu_addr = src_img + (src_w * src_h);
    char *dst_y_addr = dst_img;
    char *dst_vu_addr = dst_img + (dst_w * dst_h);

    return NV12Scale(src_y_addr, src_w, src_vu_addr, src_w, src_w, src_h, 
        dst_y_addr, dst_w, dst_vu_addr, dst_w, dst_w, dst_h, kFilterLinear);//kFilterNone
}

static int DispNV21ToARGB(char *yuv_img, char *rgb_img, int img_w, int img_h)
{
    char *src_y_addr = yuv_img;
    char *src_vu_addr = yuv_img + (img_w * img_h);

    return NV21ToARGB(src_y_addr, img_w, src_vu_addr, img_w, rgb_img, img_w*4, img_w, img_h);
}

static void DispYV12ToNV21(char *src_img, char *dst_img, int img_w, int img_h)
{
    char *dst_y_addr = dst_img;
    char *dst_vu_addr = dst_img + (img_w * img_h);
    char *src_y_addr = src_img;
    char *src_v_addr = src_img + (img_w * img_h);
    char *src_u_addr = src_img + (img_w * img_h * 5 / 4);

    CopyPlane(src_y_addr, img_w, dst_y_addr, img_w, img_w, img_h);
    MergeUVPlane(src_v_addr, img_w/2, src_u_addr, img_w/2, dst_vu_addr, img_w, img_w/2, img_h/2);
    SINK_LOG_DEBUG("YV12 to NV21 img_w=%d, img_h=%d", img_w, img_h);
}

static int DispDrawNV21(void *hdl, char *img)
{
    dispOutPort *vout_hd = (dispOutPort *)hdl;
    disp_layer_t* layer = vout_hd->layer;

    char * dst_addr;
    char * src_addr;
    int dst_width = layer->config.info.fb.size[0].width;
    int dst_height = layer->config.info.fb.size[0].height;
    int src_width = ALIGN_32B(vout_hd->window.width);
    int src_height = vout_hd->window.height;
    int dst_y_offset = vout_hd->window.x + vout_hd->window.y * dst_width;
    int dst_vu_offset = vout_hd->window.x + vout_hd->window.y * dst_width/2;
    char *dst_y_addr = (char *)layer->disp_buff.vir_addr + dst_y_offset;
    char *dst_vu_addr = (char *)layer->disp_buff.vir_addr + dst_width * dst_height + dst_vu_offset;
    char *src_y_addr = img;
    char *src_vu_addr = img + src_width * src_height;

    pthread_mutex_lock(g_layer_mutex);
    for (int i=0; i<src_height; i++) {
        dst_addr = dst_y_addr + i * (dst_width);
        src_addr = src_y_addr + i * (src_width);
        //SINK_LOG_DEBUG("dst_y_vir=%p, src_y_vir=%p",dst_vir_addr, src_vir_addr,i, mem_width);
        memcpy(dst_addr, src_addr, vout_hd->window.width);
    }
    for (int i=0; i<src_height/2; i++) {
        dst_addr = dst_vu_addr + i * (dst_width);
        src_addr = src_vu_addr + i * (src_width);
        //SINK_LOG_DEBUG("dst_y_vir=%p, src_y_vir=%p",dst_vir_addr, src_vir_addr,i, mem_width);
        memcpy(dst_addr, src_addr, vout_hd->window.width);
    }
    pthread_mutex_unlock(g_layer_mutex);

    return 0;
}

static int DispDrawYV12(void *hdl)
{
    dispOutPort *vout_hd = (dispOutPort *)hdl;
    disp_layer_t* layer = vout_hd->layer;

    char * dst_addr;
    char * src_addr;
    int dst_width = layer->config.info.fb.size[0].width;
    int dst_height = layer->config.info.fb.size[0].height;
    int src_width = ALIGN_32B(vout_hd->window.width);
    int src_height = vout_hd->window.height;
    int dst_y_offset = vout_hd->window.x + vout_hd->window.y * dst_width;
    int dst_uv_offset = (vout_hd->window.x*2 + vout_hd->window.y * dst_width)/4;
    char *dst_y_addr = (char *)layer->disp_buff.vir_addr + dst_y_offset;
    char *dst_u_addr = (char *)layer->disp_buff.vir_addr + dst_width * dst_height + dst_uv_offset;
    char *dst_v_addr = (char *)layer->disp_buff.vir_addr + dst_width * dst_height * 5/4 + dst_uv_offset;
    char *src_y_addr = vout_hd->yuv_img;
    char *src_u_addr = vout_hd->yuv_img + src_width * src_height;
    char *src_v_addr = vout_hd->yuv_img + src_width * src_height * 5 /4;

    pthread_mutex_lock(g_layer_mutex);
    for (int i=0; i<src_height; i++) {
        dst_addr = dst_y_addr + i * (dst_width);
        src_addr = src_y_addr + i * (src_width);
        //SINK_LOG_DEBUG("dst_y_vir=%p, src_y_vir=%p",dst_vir_addr, src_vir_addr,i, mem_width);
        memcpy(dst_addr, src_addr, vout_hd->window.width);
    }
    for (int i=0; i<src_height/2; i++) {
        dst_addr = dst_u_addr + i * (dst_width/2);
        src_addr = src_u_addr + i * (src_width/2);
        memcpy(dst_addr, src_addr, vout_hd->window.width/2);
        dst_addr = dst_v_addr + i * (dst_width/2);
        src_addr = src_v_addr + i * (src_width/2);
        memcpy(dst_addr, src_addr, vout_hd->window.width/2);
    }
    pthread_mutex_unlock(g_layer_mutex);

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值