由于RAW10和NV12的像素排列方式不同,因此需要进行像素格式转换。一般的转换方法是将RAW10转换成RAW16,然后再将RAW16转换成NV12。以下是用C语言实现RAW10转换成NV12的示例代码:

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

// 像素格式转换函数:将RAW10转换成RAW16
void raw10_to_raw16(unsigned char *raw10, unsigned short *raw16, int width, int height) {
    int i, j;
    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j += 4) {
            unsigned char *p = raw10 + i * width + j;
            unsigned short *q = raw16 + i * width + j / 4 * 3;
            q[0] = (p[0] << 2) | (p[1] >> 6);
            q[1] = ((p[1] & 0x3f) << 8) | p[2];
            q[2] = (p[3] << 2) | (p[4] >> 6);
            q[3] = ((p[4] & 0x3f) << 8) | p[5];
            q[4] = (p[6] << 2) | (p[7] >> 6);
            q[5] = ((p[7] & 0x3f) << 8) | p[8];
            q[6] = (p[9] << 2) | (p[10] >> 6);
            q[7] = ((p[10] & 0x3f) << 8) | p[11];
        }
    }
}

// 像素格式转换函数:将RAW16转换成NV12
void raw16_to_nv12(unsigned short *raw16, unsigned char *nv12, int width, int height) {
    int i, j;
    int y_size = width * height;
    int uv_size = y_size / 2;
    unsigned char *y = nv12;
    unsigned char *uv = nv12 + y_size;
    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {
            unsigned short *p = raw16 + i * width + j;
            unsigned char *q;
            if (i % 2 == 0 && j % 2 == 0) {
                q = uv + (i / 2) * width + (j / 2) * 2;
                q[0] = (p[0] & 0xff);
                q[1] = ((p[0] >> 8) & 0xff);
            }
            q = y + i * width + j;
            q[0] = (p[0] >> 2);
        }
    }
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("Usage: %s raw10_file width height\n", argv[0]);
        return 1;
    }
    char *raw10_file = argv[1];
    int width = atoi(argv[2]);
    int height = atoi(argv[3]);
    int raw10_size = width * height * 5 / 4;
    int raw16_size = width * height * 3 / 2;
    int nv12_size = width * height * 3 / 2;
    unsigned char *raw10_buffer = (unsigned char*)malloc(raw10_size);
    unsigned short *raw16_buffer = (unsigned short*)malloc(raw16_size);
    unsigned char *nv12_buffer = (unsigned char*)malloc(nv12_size);
    FILE *fp = fopen(raw10_file, "rb");
    if (!fp) {
        printf("Failed to open %s\n", raw10_file);
        return 1;
    }
    fread(raw10_buffer, 1, raw10_size, fp);
    fclose(fp);
    raw10_to_raw16(raw10_buffer, raw16_buffer, width, height);
    raw16_to_nv12(raw16_buffer, nv12_buffer, width, height);
    fp = fopen("output.nv12", "wb");
    if (!fp) {
        printf("Failed to create output.nv12\n");
        return 1;
    }
    fwrite(nv12_buffer, 1, nv12_size, fp);
    fclose(fp);
    free(raw10_buffer);
    free(raw16_buffer);
    free(nv12_buffer);
    return 0;
}

这个示例代码中,首先从命令行参数中获取输入文件名、图像宽度和图像高度。然后分别申请RAW10、RAW16和NV12缓冲区,并打开输入文件读取RAW10数据。接着调用raw10_to_raw16函数将RAW10转换成RAW16,然后调用raw16_to_nv12函数将RAW16转换成NV12。最后将NV12数据写入输出文件。注意,在实际应用中需要根据图像的实际格式和分辨率进行适当的修改。

用c语言实现RAW10转换成NV12

原文地址: https://www.cveoy.top/t/topic/ut5 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录