yuv和rgb888的相互转换

YUV转rgb888

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>



static long int crv_tab[256];
static long int cbu_tab[256];
static long int cgu_tab[256];
static long int cgv_tab[256];
static long int tab_76309[256];
static unsigned char clp[1024]; //for clip in CCIR601

void init_yuv420p_table()
{
    long int crv, cbu, cgu, cgv;
    int i, ind;
    static int init = 0;

    if (init == 1)
        return;

    crv = 104597;
    cbu = 132201; /* fra matrise i global.h */
    cgu = 25675;
    cgv = 53279;

    for (i = 0; i < 256; i++)
    {
        crv_tab[i] = (i - 128) * crv;
        cbu_tab[i] = (i - 128) * cbu;
        cgu_tab[i] = (i - 128) * cgu;
        cgv_tab[i] = (i - 128) * cgv;
        tab_76309[i] = 76309 * (i - 16);
    }

    for (i = 0; i < 384; i++)
        clp[i] = 0;
    ind = 384;
    for (i = 0; i < 256; i++)
        clp[ind++] = i;
    ind = 640;
    for (i = 0; i < 384; i++)
        clp[ind++] = 255;

    init = 1;
}

void planar420_to_rgb24(uint8_t *y_buffer, uint8_t *u_buffer, uint8_t *v_buffer,uint8_t *rgbbuffer, int width, int height)
{
#if 1
    int y1, y2, u, v;
    unsigned char *py1, *py2;
    int i, j, c1, c2, c3, c4;
    unsigned char *d1, *d2;

    py1 = y_buffer; // y
    py2 = py1 + width;
    d1 = rgbbuffer;
    d2 = d1 + 3 * width;
    /* d2 = d1 + width; */

    init_yuv420p_table();

    /* struct timeval statr_time,end_time; */
    /* gettimeofday( &statr_time, NULL ); */
    for (j = 0; j < height; j += 2)
    {
        for (i = 0; i < width; i += 2)
        {

            u = *u_buffer++;
            v = *v_buffer++; // v紧跟u,在u的下一个位置

            c1 = crv_tab[v];
            c2 = cgu_tab[u];
            c3 = cgv_tab[v];
            c4 = cbu_tab[u];

            //up-left
            y1 = tab_76309[*py1++];
            *d1++ = clp[384 + ((y1 + c1) >> 16)];      //r
            *d1++ = clp[384 + ((y1 - c2 - c3) >> 16)]; //g
            *d1++ = clp[384 + ((y1 + c4) >> 16)];      //b
            /* *(d1+width*height) = clp[384+((y1 - c2 - c3)>>16)]; */
            /* *(d1+2*width*height) = clp[384+((y1 + c4)>>16)]; */

            //down-left
            y2 = tab_76309[*py2++];
            *d2++ = clp[384 + ((y2 + c1) >> 16)];      //r
            *d2++ = clp[384 + ((y2 - c2 - c3) >> 16)]; //g
            *d2++ = clp[384 + ((y2 + c4) >> 16)];      //b
            /* *(d2+width*height)= clp[384+((y2 - c2 - c3)>>16)]; */
            /* *(d2+2*width*height) = clp[384+((y2 + c4)>>16)]; */

            //up-right
            y1 = tab_76309[*py1++];
            *d1++ = clp[384 + ((y1 + c1) >> 16)];      //r
            *d1++ = clp[384 + ((y1 - c2 - c3) >> 16)]; //g
            *d1++ = clp[384 + ((y1 + c4) >> 16)];      //b
            /* *(d1+width*height) = clp[384+((y1 - c2 - c3)>>16)]; */
            /* *(d1+2*width*height) = clp[384+((y1 + c4)>>16)]; */

            //down-right
            y2 = tab_76309[*py2++];
            *d2++ = clp[384 + ((y2 + c1) >> 16)];      //r
            *d2++ = clp[384 + ((y2 - c2 - c3) >> 16)]; //g
            *d2++ = clp[384 + ((y2 + c4) >> 16)];      //b
            /* *(d2+width*height) = clp[384+((y2 - c2 - c3)>>16)]; */
            /* *(d2+2*width*height) = clp[384+((y2 + c4)>>16)]; */
        }
        d1 += 3 * width;
        d2 += 3 * width;
        /* d1 += width; */
        /* d2 += width; */
        py1 += width;
        py2 += width;
    }
    /* gettimeofday( &end_time, NULL ); */

    /* LogInfo("time = %ldms\r\n", ( end_time.tv_sec - statr_time.tv_sec )*1000 + ( end_time.tv_usec - statr_time.tv_usec )/1000 ); */
#endif
}

#define OUT_WIDTH   (1920)
#define OUT_HEIGHT  (1080)
int main()
{
    uint8_t *rgbbuffer = (uint8_t*)malloc(OUT_WIDTH*OUT_HEIGHT*3);
    uint8_t *y_buffer = (uint8_t*)malloc(OUT_WIDTH*OUT_HEIGHT);
    uint8_t *u_buffer = (uint8_t*)malloc(OUT_WIDTH*OUT_HEIGHT/4);
    uint8_t *v_buffer = (uint8_t*)malloc(OUT_WIDTH*OUT_HEIGHT/4);

    int len = 0;
    FILE *y_fp = fopen( "./y_buffer.yuv", "r+" );
    if(y_fp == NULL){
        perror("fopen:");
        return 0;
    }
    len = fread( y_buffer, 1, OUT_WIDTH*OUT_HEIGHT, y_fp );
    printf("%s@%d ====> len %d\n", __func__, __LINE__, len);
    fclose(y_fp);

    FILE *u_fp = fopen( "./u_buffer.yuv", "r+" );
    if(u_fp == NULL){
        perror("fopen:");
        return 0;
    }
    len = fread( u_buffer, 1, OUT_WIDTH*OUT_HEIGHT/4, u_fp );
    printf("%s@%d ====> len %d\n", __func__, __LINE__, len);
    fclose(u_fp);

    FILE *v_fp = fopen( "./v_buffer.yuv", "r" );
    if(v_fp == NULL){
        perror("fopen:");
        return 0;
    }
    len = fread( v_buffer, 1, OUT_WIDTH*OUT_HEIGHT/4, v_fp );
    printf("%s@%d ====> len %d\n", __func__, __LINE__, len);
    fclose(v_fp);
    int y_fd = open( "./ybuffer.yuv", O_RDONLY );
    if(y_fd < 0){
        perror("fopen:");
        return 0;
    }
    read(y_fd, y_buffer, OUT_WIDTH*OUT_HEIGHT);
    close(y_fd);

    int u_fd = open( "./ubuffer.yuv", O_RDONLY );
    if(u_fd < 0){
        perror("fopen:");
        return 0;
    }
    read(u_fd, u_buffer, OUT_WIDTH*OUT_HEIGHT/4);
    close(u_fd);

    int v_fd = open( "./vbuffer.yuv", O_RDONLY );
    if(v_fd < 0){
        perror("fopen:");
        return 0;
    }
    read(v_fd, v_buffer, OUT_WIDTH*OUT_HEIGHT/4);
    close(v_fd);

    planar420_to_rgb24( y_buffer, u_buffer, v_buffer,rgbbuffer, OUT_WIDTH, OUT_HEIGHT );


    FILE *rgb_fp = fopen( "./rgb.yuv", "wb+" );
    if(rgb_fp == NULL){
        perror("fopen:");
        return 0;
    }
    fwrite( rgbbuffer, 1, OUT_WIDTH*OUT_HEIGHT*3, rgb_fp );
    fclose(rgb_fp);


    free(rgbbuffer);
    free(y_buffer);
    free(u_buffer);
    free(v_buffer);
    return 0;
}

NV12转RGB888

#include color_convert.h
#include <imp/imp_common.h>
/*
   功能:NV12 转 RGB24
   耗时:210ms左右
   使用举例:NV12_to_rgb24(0, srcSlice[0], RGB24, tex_w, tex_h) ;
   因为没有区分 格式,因此第一个参数 随便写,
   同时定义一个转换之后的指针:
   unsigned char RGB24[1920*1080*10] = {0};
   */
static long int crv_tab[256];
static long int cbu_tab[256];
static long int cgu_tab[256];
static long int cgv_tab[256];
static long int tab_76309[256];
static unsigned char clp[1024]; //for clip in CCIR601


void init_yuv420p_table()
{
    long int crv, cbu, cgu, cgv;
    int i, ind;
    static int init = 0;


    if (init == 1)
        return;


    crv = 104597;
    cbu = 132201; /* fra matrise i global.h */
    cgu = 25675;
    cgv = 53279;


    for (i = 0; i < 256; i++)
    {
        crv_tab[i] = (i - 128) * crv;
        cbu_tab[i] = (i - 128) * cbu;
        cgu_tab[i] = (i - 128) * cgu;
        cgv_tab[i] = (i - 128) * cgv;
        tab_76309[i] = 76309 * (i - 16);
    }


    for (i = 0; i < 384; i++)
        clp[i] = 0;
    ind = 384;
    for (i = 0; i < 256; i++)
        clp[ind++] = i;
    ind = 640;
    for (i = 0; i < 384; i++)
        clp[ind++] = 255;


    init = 1;
}


#define AV_PIX_FMT_NV12 PIX_FMT_NV12
#define AV_PIX_FMT_NV21 PIX_FMT_NV21
/*
   函数功能:将NV12或者NV21格式数据 转换成RGB24
   参数说明:
   frame_type:指的是pixfmt.h中结构体 AVPixelFormat 中对应的帧格式
   */
void NV12_or_NV21_to_rgb24(int frame_type, unsigned char *yuvbuffer, unsigned char *rgbbuffer, int width, int height)
{
    int y1, y2, u, v;
    unsigned char *py1, *py2;
    int i, j, c1, c2, c3, c4;
    unsigned char *d1, *d2;
    unsigned char *src_u;
    static int init_yuv420p = 0;


    src_u = yuvbuffer + width * height; // u


    py1 = yuvbuffer; // y
    py2 = py1 + width;
    d1 = rgbbuffer;
    d2 = d1 + 3 * width;
    /* d2 = d1 + width; */


    /* init_yuv420p_table(); */


    /* struct timeval statr_time,end_time; */
    /* gettimeofday( &statr_time, NULL ); */
    for (j = 0; j < height; j += 2)
    {
        for (i = 0; i < width; i += 2)
        {


            if (frame_type == AV_PIX_FMT_NV12)
            {
                u = *src_u++;
                v = *src_u++; // v紧跟u,在u的下一个位置
            }
            if (frame_type == AV_PIX_FMT_NV21)
            {
                v = *src_u++;
                u = *src_u++; // u紧跟v,在v的下一个位置
            }


            c1 = crv_tab[v];
            c2 = cgu_tab[u];
            c3 = cgv_tab[v];
            c4 = cbu_tab[u];


            //up-left
            y1 = tab_76309[*py1++];
            *d1++ = clp[384 + ((y1 + c1) >> 16)];      //r
            *d1++ = clp[384 + ((y1 - c2 - c3) >> 16)]; //g
            *d1++ = clp[384 + ((y1 + c4) >> 16)];      //b
            /* *(d1+width*height) = clp[384+((y1 - c2 - c3)>>16)]; */
            /* *(d1+2*width*height) = clp[384+((y1 + c4)>>16)]; */


            //down-left
            y2 = tab_76309[*py2++];
            *d2++ = clp[384 + ((y2 + c1) >> 16)];      //r
            *d2++ = clp[384 + ((y2 - c2 - c3) >> 16)]; //g
            *d2++ = clp[384 + ((y2 + c4) >> 16)];      //b
            /* *(d2+width*height)= clp[384+((y2 - c2 - c3)>>16)]; */
            /* *(d2+2*width*height) = clp[384+((y2 + c4)>>16)]; */


            //up-right
            y1 = tab_76309[*py1++];
            *d1++ = clp[384 + ((y1 + c1) >> 16)];      //r
            *d1++ = clp[384 + ((y1 - c2 - c3) >> 16)]; //g
            *d1++ = clp[384 + ((y1 + c4) >> 16)];      //b
            /* *(d1+width*height) = clp[384+((y1 - c2 - c3)>>16)]; */
            /* *(d1+2*width*height) = clp[384+((y1 + c4)>>16)]; */


            //down-right
            y2 = tab_76309[*py2++];
            *d2++ = clp[384 + ((y2 + c1) >> 16)];      //r
            *d2++ = clp[384 + ((y2 - c2 - c3) >> 16)]; //g
            *d2++ = clp[384 + ((y2 + c4) >> 16)];      //b
            /* *(d2+width*height) = clp[384+((y2 - c2 - c3)>>16)]; */
            /* *(d2+2*width*height) = clp[384+((y2 + c4)>>16)]; */
        }
        d1 += 3 * width;
        d2 += 3 * width;
        /* d1 += width; */
        /* d2 += width; */
        py1 += width;
        py2 += width;
    }
    /* gettimeofday( &end_time, NULL ); */


    /* LogInfo(time = %ldms\r\n, ( end_time.tv_sec - statr_time.tv_sec )*1000 + ( end_time.tv_usec - statr_time.tv_usec )/1000 ); */
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值