gpt4 book ai didi

c - FFMpeg、libav、sws_scale 和 yuv 到 rgb 转换的问题 - 颜色不正确

转载 作者:行者123 更新时间:2023-12-04 23:12:29 24 4
gpt4 key购买 nike

我一直在尝试在 Delphi 中创建自己的视频播放器,并且 ffmpeg 效果很好,直到我遇到了色彩空间或颜色转换的障碍。
这几天一直在尝试一切,但无法弄清楚。
我正在使用 AV_PIX_FMT_RGB48LE 作为输出...
旧上下文创建:

      videoConvContext := sws_getContext(AVStreamInit.codec.width, AVStreamInit.codec.height, AVStreamInit.codec.pix_fmt, AVStreamInit.codec.width, AVStreamInit.codec.height, AV_PIX_FMT_RGB48LE, SWS_POINT, nil, nil, nil);
新的上下文创建:
    dstRange := 1;
srcRange := 1;
if AVStreamInit.codec.color_range = AVCOL_RANGE_MPEG then
srcRange := 0;

videoConvContext := sws_alloc_context();

av_opt_set_int(videoConvContext, 'sws_flags', SWS_POINT or SWS_PRINT_INFO, 0);

av_opt_set_int(videoConvContext, 'srcw', AVStreamInit.codec.width, 0);
av_opt_set_int(videoConvContext, 'srch', AVStreamInit.codec.height, 0);
av_opt_set_int(videoConvContext, 'src_format', Integer(AVStreamInit.codec.pix_fmt), 0);

av_opt_set_int(videoConvContext, 'dstw', AVStreamInit.codec.width, 0);
av_opt_set_int(videoConvContext, 'dsth', AVStreamInit.codec.height, 0);
av_opt_set_int(videoConvContext, 'dst_format', Integer(AV_PIX_FMT_RGB48LE), 0);

i1 := sws_getCoefficients2(Integer(AVStreamInit.codec.colorspace));
i2 := sws_getCoefficients2(SWS_CS_ITU709);

ret := sws_setColorspaceDetails2(videoConvContext, i1, srcRange, i2, dstRange, 0, 1 shl 16, 1 shl 16);

sws_init_context(videoConvContext, nil, nil);
结果完全一样......
sws_scale 的输出没有正确的颜色,这里是 2 个屏幕截图
好的 - 来自 mpc-hc
ok
不行 - 从我的播放器通过 sws_scale (直接原始提取,所以没有完成颜色处理)
not ok
该视频有 pix_fmt AV_PIX_FMT_YUV420P10LE ,但它发生在其他 YUV 输入上,但不是那么明显。同样在其他 RGB 输出(8 位等)...
这里的 Netflix 标志是纯红色的,但 sws_scale 输出是橙色的……
Sws_scale 代码仅供引用:
sws_scale(videoConvContext, @AVPacketBuffer.AVFrameCopy.Data, @AVPacketBuffer.AVFrameCopy.linesize, 0, AVStream.codec.height, @BitmapXBuffer.data, @linesize);
BitmapXBuffer.data 是一个大小正确的单一缓冲区...
AVFrameCopy - 是原始帧的副本,完成:
  if Assigned(AVPacketBuffer.AVFrameCopy) then
av_frame_free(@AVPacketBuffer.AVFrameCopy);

AVPacketBuffer.AVFrameCopy := av_frame_alloc();
AVPacketBuffer.AVFrameCopy.format := AVPacketBuffer.AVFrame.format;
AVPacketBuffer.AVFrameCopy.width := AVPacketBuffer.AVFrame.width;
AVPacketBuffer.AVFrameCopy.height := AVPacketBuffer.AVFrame.height;
AVPacketBuffer.AVFrameCopy.channels := AVPacketBuffer.AVFrame.channels;
AVPacketBuffer.AVFrameCopy.channel_layout := AVPacketBuffer.AVFrame.channel_layout;
AVPacketBuffer.AVFrameCopy.nb_samples := AVPacketBuffer.AVFrame.nb_samples;
av_frame_get_buffer(AVPacketBuffer.AVFrameCopy, 32);
av_frame_copy(AVPacketBuffer.AVFrameCopy, AVPacketBuffer.AVFrame);
av_frame_copy_props(AVPacketBuffer.AVFrameCopy, AVPacketBuffer.AVFrame);
谢谢!

最佳答案

回答我自己的问题 - 上面的代码是正确的,
让我感到困惑的是 dst_table,但只有当目标颜色空间是 YUV 时它才有意义。
Netflix 的标志也是橙色的,但不是正确的橙色。从 sRGB 转换为线性 RGB 为我解决了这个问题,但这仅适用于我的情况。
所以,以上面的代码为例:D

关于c - FFMpeg、libav、sws_scale 和 yuv 到 rgb 转换的问题 - 颜色不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62985672/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com