【问题标题】:How to convert Openh264 DecodeFrameNoDelay output format to OpenCV matrix?如何将 Openh264 DecodeFrameNoDelay 输出格式转换为 OpenCV 矩阵?
【发布时间】:2019-12-04 09:08:54
【问题描述】:

我想将DecodeFrameNoDelay函数的输出格式为yuvDatabufferInfo转换为OpenCV矩阵,我可以使用imshow函数在窗口上显示框架

将 git 链接到 DecodeFrameNoDelay 详细信息:https://github.com/cisco/openh264/wiki/ISVCDecoder#decodeframenodelay

以下是我使用 Openh264 解码帧的代码

ISVCDecoder *decoder;
SBufferInfo bufferInfo;
SDecodingParam decodingParam;
uint8_t** yuvData;

void init(int width, int height) {
    WelsCreateDecoder(&decoder);
    decodingParam = {0};
    decodingParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
    decoder->Initialize(&decodingParam);
    bufferInfo = {0};
    bufferInfo.iBufferStatus = 1;

    yuvData = new uint8_t*[3];
    yuvData[0] = new uint8_t[width * height];
    yuvData[1] = new uint8_t[width * height / 4];
    yuvData[2] = new uint8_t[width * height / 4];

}

bool decode(const unsigned char* rawEncodedData, int rawEncodedDataLength, uint8_t** yuvData, char *name) {
    int err = decoder->DecodeFrameNoDelay(rawEncodedData, rawEncodedDataLength, yuvData, &bufferInfo);

    if (err != 0) {
        std::cout << "H264 decoding failed. Error code: " << err << "." << std::endl;
        parseErrorCode(err);
        return false;
    }

    printf("H264 decoding success, err: %d, name: %s, status: %d\n", err, name, bufferInfo.iBufferStatus);

    return true;
}

感谢任何帮助。

谢谢和最好的问候。

【问题讨论】:

  • 您需要通过设置图像大小的构造函数版本或使用create()函数创建Mat对象,然后将像素信息从yuvData缓冲区逐平面复制到Mat的data缓冲区.然后可以将其转换为其他编码,例如RGB,因为我不确定 OpenCV 是否可以做任何事情,除了转换 YUV 图像...

标签: c++ opencv openh264


【解决方案1】:

执行复制时应考虑stride 参数。这是将帧解码为opencv cv::Mat的代码:

inline void copyWithStride(
        void* dst, const void* src,
        size_t width, size_t height, size_t stride
) {
    for (size_t row = 0; row < height; ++row) {
        uint8_t* posFrom = (uint8_t*)src + row * stride;
        uint8_t* posTo = (uint8_t*)dst + row * width;
        memcpy(posTo, posFrom, width);
    }
}

cv::Mat decode(const unsigned char* rawEncodedData, int rawEncodedDataLength) {
    SBufferInfo sDstBufInfo;
    memset(&sDstBufInfo, 0, sizeof(SBufferInfo));

    unsigned char *pData[3] = {nullptr, nullptr, nullptr};

    int rv = decoder->DecodeFrameNoDelay(
        rawEncodedData,
        rawEncodedDataLength,
        pData,
        &sDstBufInfo
    );

    int stride0 = sDstBufInfo.UsrData.sSystemBuffer.iStride[0];
    int stride1 = sDstBufInfo.UsrData.sSystemBuffer.iStride[1];
    
    cv::Mat imageYuvCh[3];
    cv::Mat imageYuvMiniCh[3];

    copyWithStride(imageYuvCh[0].data, pData[0], width, height, stride0);
    copyWithStride(imageYuvMiniCh[1].data, pData[1], width/2, height/2, stride1);
    copyWithStride(imageYuvMiniCh[2].data, pData[2], width/2, height/2, stride1);
    
    cv::resize(imageYuvMiniCh[1], imageYuvCh[1], cv::Size(width, height));
    cv::resize(imageYuvMiniCh[2], imageYuvCh[2], cv::Size(width, height));
    
    cv::Mat resultYuv;
    cv::merge(imageYuvCh, 3, resultYuv);
    
    cv::Mat result;
    cvtColor(imgYUV, result, cv::COLOR_YUV2BGR);
    return result;
}

【讨论】:

    猜你喜欢
    • 2023-03-17
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多