2

我需要将 YUV 转换为 RGB。我还需要 RGB 值在有限范围内(16-235)。我尝试使用 sws_scale 函数来完成这项任务。

我的代码你可以在下面看到。但转换后我得到的黑色像素是 (0, 0, 0) 而不是 (16, 16, 16)。

也许有一些选项可以告诉 sws_scale 函数计算有限范围。

AVFrame* frameRGB = avFrameConvertPixelFormat(_decodedBuffer[i].pAVFrame, AV_PIX_FMT_RGB24);
AVFrame* Decoder::avFrameConvertPixelFormat(const AVFrame* src, AVPixelFormat dstFormat) {
    int width = src->width;
    int height = src->height;

    AVFrame* dst = allocPicture(dstFormat, width, height);

    SwsContext* conversion = sws_getContext(width,
                                            height,
                                            (AVPixelFormat)src->format,
                                            width,
                                            height,
                                            dstFormat,
                                            SWS_FAST_BILINEAR,
                                            NULL,
                                            NULL,
                                            NULL);
    sws_scale(conversion, src->data, src->linesize, 0, height, dst->data, dst->linesize);
    sws_freeContext(conversion);

    dst->format = dstFormat;
    dst->width = src->width;
    dst->height = src->height;

    return dst;
}

我也尝试使用公式手动将 YUV 像素转换为 RGB 像素,我得到了正确的结果。从 YUV (16, 128, 128) 我得到 (16, 16, 16) 的 RGB。

cmpR = y + 1.402 * (v - 128);
cmpG = y - 0.3441 * (u - 128) - 0.7141 * (v - 128);
cmpB = y + 1.772 * (u - 128);
4

1 回答 1

1

您可以将源格式设置为“全尺寸” YUVJ

据我所知, sws_scale 没有选择Studio RGB作为输出格式的选项。
更改输入格式是我能想到的最佳解决方案。

“JPEG:YUV -> RGB”的颜色转换公式与您帖子中的公式相同。

设置源格式的示例:

  • 如果src->formatPIX_FMT_YUV420P,请将格式设置为PIX_FMT_YUVJ420P.
  • 如果src->formatPIX_FMT_YUV422P,请将格式设置为PIX_FMT_YUVJ422P.
  • 如果src->formatPIX_FMT_YUV444P,请将格式设置为PIX_FMT_YUVJ444P.
  • 如果PIX_FMT_YUV440P,使用PIX_FMT_YUVJ440P.

我知道该解决方案并未涵盖所有可能性,并且可能有一些输出像素超出 [16, 235] 的范围,因此这不是最通用的解决方案...

于 2021-02-26T21:51:34.247 回答