sws_scale, преобразование YUV в RGB

Мне нужно преобразовать 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);

person Валентин Никин    schedule 26.02.2021    source источник


Ответы (1)


Вы можете отформатировать исходный файл до полного масштаба YUVJ.

Насколько мне известно, в sws_scale нет возможности выбрать Studio RGB. в качестве выходного формата.
Изменение входного формата — лучшее решение, которое я могу придумать.

Преобразование цвета формула JPEG: YUV -> RGB такое же, как формула в вашем посте.

Примеры установки исходного формата:

  • Если src->format равно PIX_FMT_YUV420P, установите формат PIX_FMT_YUVJ420P.
  • Если src->format равно PIX_FMT_YUV422P, установите формат PIX_FMT_YUVJ422P.
  • Если src->format равно PIX_FMT_YUV444P, установите формат PIX_FMT_YUVJ444P.
  • Если PIX_FMT_YUV440P, используйте PIX_FMT_YUVJ440P.

Я знаю, что решение не охватывает всех возможностей, и некоторые выходные пиксели могут превышать диапазон [16, 235], так что это не самое общее решение...

person Rotem    schedule 26.02.2021
comment
Привет @Rotem, спасибо! Это решение, кажется, работает для меня. Не могли бы вы объяснить мне, почему это решение работает? На каком принципе он основан? И кажется, что AV_PIX_FMT_YUVJ420P устарел, плоский YUV 4: 2: 0, 12bpp, полная шкала (JPEG), устарел в пользу AV_PIX_FMT_YUV420P и настройки color_range - person Валентин Никин; 01.03.2021
comment
Как я уже упоминал в своем посте, я основывал решение на вашей формуле преобразования в вашем вопросе. Формула идентична преобразованию JPEG YUV (описано в Википедии). Буква J в YUVJ применяется к преобразованию JPEG (JPEG использует полный диапазон YUV, а не общую формулу преобразования видео, где Y ограничено значением [16, 235]). - person Rotem; 01.03.2021