【问题标题】:How can I use ffmpeg's swscale to convert from NV12 to RGB32?如何使用 ffmpeg 的 swscale 将 NV12 转换为 RGB32?
【发布时间】:2017-08-29 01:31:43
【问题描述】:

假设我在内存中有一个 NV12 帧作为字节数组。我知道:

  • 它的宽度和高度
  • 它的步幅(包括填充在内的线的总宽度),根据 NV12 规范,对于 Y 和 UV 分量是相同的
  • 我知道 Y 从哪里开始,U 从 Y +(步幅 * 高度)开始,V 从 U + 1 开始(与 U 交错)。

这就是我目前所拥有的:

SwsContext* context = sws_getContext(frameWidth, frameHeight, AV_PIX_FMT_NV12, frameWidth, frameHeight, AV_PIX_FMT_RGB32, 0, nullptr, nullptr, nullptr);
sws_scale(context, 

所以我不知道sws_scale的参数应该是什么:

  • srcSlice:指向字节数组的指针?它显然应该是一个 指向指针的指针,但我所拥有的只是一维 字节数组。
  • srcStride :显然需要一组步幅,但我对整个文件只有一个步幅。我应该只传递一个数组吗 一个元素?
  • srcSliceY:我猜是第一个字节的偏移量?那么应该是 0。
  • srcSliceH : 我猜的帧高度
  • dst :再一次指向一个指针,但我的目标输出实际上只是另一个字节数组...
  • dstStride : Width * 4 我猜?

任何帮助表示赞赏。

【问题讨论】:

    标签: c++ video ffmpeg


    【解决方案1】:
    /// uint8_t * Y;
    /// uint8_t * out;
    
    // 2 planes for NV12: Y and interleaved UV
    uint8_t * data[2] = {Y, Y + Stride * Height}; 
    
    // Strides for Y and UV
    // U and V have Stride/2 bytes per line; 
    // Thus, we have 2 * Stride/2 bytes per line in UV plane
    int linesize[2] = {Stride, Stride}; 
    
    uint8_t * outData[1] = {out}; // RGB have one plane 
    int outLinesize[1] = {frameWidth*4}; // RGB32 Stride
    
    sws_scale(context, data, linesize, 0, Height, outData, outLinesize);
    

    【讨论】:

    • 这是有道理的,但它因 AccessViolationException 而失败...我的输出缓冲区的长度为 (Height * Stride * 4),所以我不明白。
    • 哦,我找到了:“outLineSize”应该是frameWidth * 4,而不是stride * 4。如果有padding,stride可以大于宽度。这就是导致越界内存访问的原因。
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多