颜色空间转换CSConvert:NV12、NV21、YV12和I420的相互转换

  1. 1、NV12转I420
  2. 2、I420转NV21
  3. 3、NV12转YV12
  4. 4、NV12转YV12
  5. 5、I420转NV12
  6. 6、I420转YV12
  7. THE END!

1、NV12转I420

NV12toI420.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int width, height;
    int frame_size;
    FILE *fin, *fou;
    char *y, *uv, *u, *v;
    int i, frame_num = 0;
    char outname[512] = { 0, };
    printf("\nUsage: NV12toI420.exe input.yuv width height\n\n");
    if (argc != 4)
    {
        return -1;
    }
    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("error:open %s fail\n", argv[1]);
        return -1;
    }
    width = atoi(argv[2]);
    height = atoi(argv[3]);
    frame_size = width*height * 3 / 2;//++YUV420
    y = (char *)malloc(frame_size);
    if (y == NULL)
    {
        printf("malloc y fail\n");
        return -1;
    }
    u = y + width*height;
    v = u + width*height / 4;

    uv = (char *)malloc(width*height >> 1);
    if (uv == NULL)
    {
        printf("malloc uv fail\n");
        return -1;
    }
    memset(outname, 0, sizeof(outname));
    sprintf_s(outname, "%s_I420.yuv", argv[1]);
    fou = fopen(outname, "wb");
    if (fou == NULL)
    {
        printf("error: open %s fail\n", outname);
        return -1;
    }

    while (!feof(fin))
    {
        int n = 0;
        n = fread(y, 1, width*height, fin);
        n += fread(uv, 1, width*height >> 1, fin);
        if (n != frame_size)
        {
            break;
        }
        for (i = 0; i < height*width >> 2; i++)
        {
            u[i] = uv[2 * i + 0];
            v[i] = uv[2 * i + 1];
        }
        fwrite(y, 1, frame_size, fou);
        printf("%dth frame ok!!\n", frame_num);
        frame_num++;
    }
    printf("NV12 to I420 successfully!!,total frames: %d\n", frame_num);

    free(y);
    y = NULL;
    free(uv);
    uv = NULL;
    fclose(fin);
    fclose(fou);

    return 0;
}

2、I420转NV21

I420toNV21.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int width, height;
    int frame_size;
    FILE *fin, *fou;
    char *y, *uv, *u, *v;
    int i, frame_num = 0;
    char outname[512] = { 0, };
    printf("\nUsage:I420toNV21.exe input.yuv width height\n\n");
    if (argc != 4)
    {
        return -1;
    }
    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("error:open %s fail\n", argv[1]);
        return -1;
    }

    width = atoi(argv[2]);
    height = atoi(argv[3]);
    frame_size = width*height * 3 / 2;//++YUV420
    y = (char *)malloc(frame_size);
    if (y == NULL)
    {
        printf("malloc y fail\n");
        return -1;
    }
    uv = y + width*height;

    u = (char *)malloc(width*height >> 2);
    v = (char *)malloc(width*height >> 2);

    if (u == NULL || v == NULL)
    {
        printf("malloc u or v fail\n");
        return -1;
    }
    memset(outname, 0, sizeof(outname));
    sprintf(outname, "%s_NV21.yuv", argv[1]);
    fou = fopen(outname, "wb");
    if (fou == NULL)
    {
        printf("error: open %s fail\n", outname);
        return -1;
    }

    while (!feof(fin))
    {
        int n = 0;
        n = fread(y, 1, width*height, fin);
        n += fread(u, 1, width*height >> 2, fin);
        n += fread(v, 1, width*height >> 2, fin);

        if (n != frame_size)
        {
            break;
        }
        for (i = 0; i < height*width >> 2; i++)
        {
            uv[2 * i + 0] = v[i]; // v
            uv[2 * i + 1] = u[i]; // u
        }
        fwrite(y, 1, height*width, fou);
        fwrite(uv, 1, height*width >> 1, fou);

        printf("%dth frame ok!!\n", frame_num);

        frame_num++;
    }
    printf("I420 to NV21 successfully!!, total frames: %d\n", frame_num);

    free(y);
    y = NULL;
    free(u);
    u = NULL;
    free(v);
    v = NULL;
    fclose(fin);
    fclose(fou);

    return 0;
}

3、NV12转YV12

NV21toYV12.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int width, height;
    int frame_size;
    FILE *fin, *fou;
    char *y, *uv, *u, *v;
    int i, frame_num = 0;
    char outname[512] = { 0, };
    printf("\nUsage: NV21toYV12.exe input.yuv width height\n\n");
    if (argc != 4)
    {
        return -1;
    }
    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("error:open %s fail\n", argv[1]);
        return -1;
    }
    width = atoi(argv[2]);
    height = atoi(argv[3]);
    frame_size = width*height * 3 / 2;//++YUV420
    y = (char *)malloc(frame_size);
    if (y == NULL)
    {
        printf("malloc y fail\n");
        return -1;
    }
    v = y + width*height;
    u = v + width*height / 4;

    uv = (char *)malloc(width*height >> 1);
    if (uv == NULL)
    {
        printf("malloc uv fail\n");
        return -1;
    }
    memset(outname, 0, sizeof(outname));
    sprintf_s(outname, "%s_YV12.yuv", argv[1]);
    fou = fopen(outname, "wb");
    if (fou == NULL)
    {
        printf("error: open %s fail\n", outname);
        return -1;
    }

    while (!feof(fin))
    {
        int n = 0;
        n = fread(y, 1, width*height, fin);
        n += fread(uv, 1, width*height >> 1, fin);
        if (n != frame_size)
        {
            break;
        }
        for (i = 0; i < height*width >> 2; i++)
        {
            v[i] = uv[2 * i + 0];// v
            u[i] = uv[2 * i + 1];// u
        }
        fwrite(y, 1, frame_size, fou);
        printf("%dth frame ok!!\n", frame_num);
        frame_num++;
    }
    printf("NV21 to YV12 successfully!!,total frames: %d\n", frame_num);

    free(y);
    y = NULL;
    free(uv);
    uv = NULL;
    fclose(fin);
    fclose(fou);

    return 0;
}

4、NV12转YV12

NV12toYV12.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int width, height;
    int frame_size;
    FILE *fin, *fou;
    char *y, *uv, *u, *v;
    int i, frame_num = 0;
    char outname[512] = { 0, };
    printf("\nUsage:NV12toYV12.exe input.yuv width height\n\n");
    if (argc != 4)
    {
        return -1;
    }
    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("error:open %s fail\n", argv[1]);
        return -1;
    }
    width = atoi(argv[2]);
    height = atoi(argv[3]);
    frame_size = width*height * 3 / 2;//++YUV420
    y = (char *)malloc(frame_size);
    if (y ==NULL)
    {
        printf("malloc y fail\n");
        return -1;
    }
    v = y + width*height;
    u = v + width*height / 4;

    uv = (char *)malloc(width*height >> 1);
    if (uv == NULL)
    {
        printf("malloc uv fail\n");
        return -1;
    }
    memset(outname, 0, sizeof(outname));
    sprintf_s(outname, "%s_YV12.yuv", argv[1]);
    fou = fopen(outname, "wb");
    if (fou == NULL)
    {
        printf("error: open %s fail\n", outname);
        return -1;
    }

    while (!feof(fin))
    {
        int n = 0;
        n = fread(y, 1, width*height, fin);
        n += fread(uv, 1, width*height >> 1, fin);
        if (n != frame_size)
        {
            break;
        }
        for (i = 0; i < height*width >> 2;i++)
        {
            u[i] = uv[2 * i + 0];
            v[i] = uv[2 * i + 1];
        }
        fwrite(y, 1, frame_size, fou);
        printf("%dth frame ok!!\n", frame_num);
        frame_num++;
    }
    printf("NV12 to YV12 successfully!!,total frames: %d\n", frame_num);

    free(y);
    y = NULL;
    free(uv);
    uv = NULL;
    fclose(fin);
    fclose(fou);

    return 0;
}

5、I420转NV12

I420toNV12.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int width, height;
    int frame_size;
    FILE *fin, *fou;
    char *y, *uv, *u, *v;
    int i, frame_num = 0;
    char outname[512] = { 0, };
    printf("\nUsage:I420toNV12.exe input.yuv width height\n\n");
    if (argc != 4)
    {
        return -1;
    }
    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("error:open %s fail\n", argv[1]);
        return -1;
    }

    width = atoi(argv[2]);
    height = atoi(argv[3]);
    frame_size = width*height * 3 / 2;//++YUV420
    y = (char *)malloc(frame_size);
    if (y == NULL)
    {
        printf("malloc y fail\n");
        return -1;
    }
    uv = y + width*height;

    u = (char *)malloc(width*height >> 2);
    v = (char *)malloc(width*height >> 2);

    if (u == NULL || v == NULL)
    {
        printf("malloc u or v fail\n");
        return -1;
    }
    memset(outname, 0, sizeof(outname));
    sprintf_s(outname, "%s_NV12.yuv", argv[1]);
    fou = fopen(outname, "wb");
    if (fou == NULL)
    {
        printf("error: open %s fail\n", outname);
        return -1;
    }

    while (!feof(fin))
    {
        int n = 0;
        n = fread(y, 1, width*height, fin);
        n += fread(u, 1, width*height >> 2, fin);
        n += fread(v, 1, width*height >> 2, fin);

        if (n != frame_size)
        {
            break;
        }
        for (i = 0; i < height*width >> 2; i++)
        {
             uv[2 * i + 0] = u[i];
             uv[2 * i + 1] = v[i];
        }
        fwrite(y, 1, height*width, fou);
        fwrite(uv, 1, height*width >> 1, fou);

        printf("%dth frame ok!!\n", frame_num);

        frame_num++;
    }
    printf("I420 to NV12 successfully!!, total frames: %d\n",frame_num);

    free(y);
    y = NULL;
    free(u);
    u = NULL;
    free(v);
    v = NULL;
    fclose(fin);
    fclose(fou);

    return 0;
}

6、I420转YV12

I420toYV12.c


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    int width, height;
    int frame_size;
    FILE *fin, *fou;
    char *y, *u, *v,*u1,*v1;
    int i, frame_num = 0;
    char outname[512] = { 0, };
    printf("\nUsage:I420toYV12.exe input.yuv width height\n\n");
    if (argc != 4)
    {
        return -1;
    }
    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("error:open %s fail\n", argv[1]);
        return -1;
    }
    width = atoi(argv[2]);
    height = atoi(argv[3]);
    frame_size = width*height * 3 / 2;
    y = (char *)malloc(frame_size);
    if (y == NULL)
    {
        printf("malloc y fail\n");
        return -1;
    }
    v = y + width*height;
    u = v + width*height/4;

    u1 = (char *)malloc(width*height >> 2);
    v1 = (char *)malloc(width*height >> 2);

    if (u1 == NULL || v1== NULL)
    {
        printf("malloc u1 or v1 fail\n");
        return -1;
    }
    memset(outname, 0, sizeof(outname));
    sprintf_s(outname, "%s_YV12.yuv", argv[1]);
    fou = fopen(outname, "wb");
    if (fou == NULL)
    {
        printf("error: open %s fail\n", outname);
        return -1;
    }

    while (!feof(fin))
    {
        int n = 0;
        n = fread(y, 1, width*height, fin);
        n += fread(u1, 1, width*height >> 2, fin);
        n += fread(v1, 1, width*height >> 2, fin);

        if (n != frame_size)
        {
            break;
        }
        for (i = 0; i < height*width >> 2; i++)
        {
            v[i] = v1[i];
            u[i] = u1[i];
        }
        fwrite(y, 1, frame_size, fou);

        printf("%dth frame ok!!\n", frame_num);
        frame_num++;
    }
    printf("I420 to YV12 successfully!!,total frames: %d\n",frame_num);

    free(y);
    y = NULL;
    free(u1);
    u1 = NULL;
    free(v1);
    v1 = NULL;
    fclose(fin);
    fclose(fou);

    return 0;
}

THE END!


本博文只能阅读,谢绝转载,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2963033731@qq.com

文章标题:颜色空间转换CSConvert:NV12、NV21、YV12和I420的相互转换

字数:1.7k

本文作者:Soaring Lee

发布时间:2019-07-13, 21:34:47

最后更新:2021-06-14, 12:13:44

原始链接:https://soaringleefighting.github.io/2019/07/13/【Codecs系列】颜色空间转换CSConvert:NV12、NV21、YV12和I420的相互转换/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏

相册