You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM与x86_64平台下C++ Python扩展RGB转CbCrA输出不一致问题

跨平台(x86_64/ARM)下Python图像转换扩展输出不一致问题

我开发了一个基于C++的Python扩展,用于将图像转换为CbCrA格式,但该函数在树莓派(ARM 32/64位)与Ubuntu 22.04(x86_64)笔记本上运行时输出结果不同。我知道ARM平台部分变量大小与x64存在差异,但无法定位具体问题点。

相关代码

static PyObject *
method_rgb_to_atem(PyObject *self, PyObject *args)
{
    Py_buffer input_buffer;
    Py_ssize_t data_length;
    unsigned int width, height, premultiply;
    PyObject *res;

    /* Parse arguments */
    if (!PyArg_ParseTuple(args, "y*IIp", &input_buffer, &width, &height, &premultiply)) {
        return NULL;
    }

    data_length = input_buffer.len;
    unsigned char *buffer;
    buffer = input_buffer.buf;

    char *outbuffer = (char *) malloc(data_length);
    if (outbuffer == NULL) {
        return PyErr_NoMemory();
    }

    char *writepointer = outbuffer;

    int pixel_size = 8;
    for (int i = 0; i < data_length; i += pixel_size) {
        // Convert RGBA 8888 to 10-bit BT.709 Y'CbCrA
        float r1 = (float)buffer[0] / 255;
        float g1 = (float)buffer[1] / 255;
        float b1 = (float)buffer[2] / 255;
        float r2 = (float)buffer[4] / 255;
        float g2 = (float)buffer[5] / 255;
        float b2 = (float)buffer[6] / 255;

        if (premultiply) {
            // PNG files have straight alpha, for BMD switchers premultipled alpha is easier
            float a1 = (float)buffer[3] / 255;
            float a2 = (float)buffer[7] / 255;
            r1 = r1 * a1;
            g1 = g1 * a1;
            b1 = b1 * a1;
            r2 = r2 * a2;
            g2 = g2 * a2;
            b2 = b2 * a2;
        }

        float y1 = (0.2126 * r1) + (0.7152 * g1) + (0.0722 * b1);
        float y2 = (0.2126 * r2) + (0.7152 * g2) + (0.0722 * b2);
        float cb = (b2 - y2) / 1.8556;
        float cr = (r2 - y2) /  1.5748;

        unsigned short a10a = ((buffer[3] << 2) * 219 / 255) + (15 << 2) + 1;
        unsigned short a10b = ((buffer[7] << 2) * 219 / 255) + (15 << 2) + 1;
        unsigned short y10a = clamp((unsigned short)(y1 * 876) + 64, 64, 940);
        unsigned short y10b = clamp((unsigned short)(y2 * 876) + 64, 64, 940);
        unsigned short cb10 = clamp((unsigned short)(cb * 896) + 512, 44, 960);
        unsigned short cr10 = clamp((unsigned short)(cr * 896) + 512, 44, 960);

        writepointer[0] = (unsigned char) (a10a >> 4);
        writepointer[1] = (unsigned char) (((a10a & 0x0f) << 4) | (cb10 >> 6));
        writepointer[2] = (unsigned char) (((cb10 & 0x3f) << 2) | (y10a >> 8));
        writepointer[3] = (unsigned char) (y10a & 0xff);
        writepointer[4] = (unsigned char) (a10b >> 4);
        writepointer[5] = (unsigned char) (((a10b & 0x0f) << 4) | (cr10 >> 6));
        writepointer[6] = (unsigned char) (((cr10 & 0x3f) << 2) | (y10b >> 8));
        writepointer[7] = (unsigned char) (y10b & 0xff);
        writepointer += pixel_size;
        buffer += pixel_size;
    }

    res = Py_BuildValue("y#", outbuffer, data_length);
    free(outbuffer);
    return res;
}

测试输入与输出

测试输入:b'\xff\x00\x00\xff\xff\x00\x00\xff'

  • Ubuntu 22.04(x86_64)输出:

    b':\x96h\xfa:\x9f\x00\xfa'
    

    十六进制:

    00000000: 3A 96 68 FA 3A 9F 00 FA                           :.h.:...
    
  • 树莓派(ARM 32/64位)输出:

    b':\x98\x00\xfa:\x9f\x00\xfa'
    

    十六进制:

    00000000: 3A 98 00 FA 3A 9F 00 FA                           :...:...
    

内容的提问来源于stack exchange,提问作者doctor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:02:57