美文网首页video
sws_scale的图像色彩空间转换

sws_scale的图像色彩空间转换

作者: 技术笔记 | 来源:发表于2019-12-17 14:15 被阅读0次

    阅读ffmpegthumbnailer的代码,其中MovieDecoder::getScaledVideoFrame,将解码出来的avFrame送给filter,其中有rgb24这个format filter,经过这个转换,然后copy到VideoFrame的frameData中:

        videoFrame.frameData.resize(videoFrame.lineSize * videoFrame.height);
        memcpy((videoFrame.frameData.data()), res->data[0], videoFrame.frameData.size());
    

    单从代码来看,这个地方直接拷贝的res->data[0]给videoFrame.frameData.data(),没有处理res->data[1],res->data[2],所以直观判断,这里已经是全部的数据了。

    所以根据这一点,实现了下面的函数,通过sw_scale进行格式转换,不用再走过多的filter。还有一种思路,就是实现一个yuv到rgb的转换函数,把m_pFrame中的数据直接写到VideoFrame的frameData中,这个效率应该是最高的。

        videoFrame.width = m_pFrame->width;
        videoFrame.height = m_pFrame->height;
    
        int linesize[4];
        uint8_t* data[4];
        struct SwsContext *swsContext = NULL;
        swsContext = sws_getContext(m_pFrame->width, m_pFrame->height, AVPixelFormat(m_pFrame->format),
                                 videoFrame.width, videoFrame.height, AV_PIX_FMT_RGB24,
                                 SWS_BILINEAR, NULL, NULL, NULL);
        av_image_alloc(data, linesize, videoFrame.width, videoFrame.height, AV_PIX_FMT_RGB24, 1);
        sws_scale(swsContext, m_pFrame->data, m_pFrame->linesize, 0, m_pFrame->height, data, linesize);
    
        videoFrame.lineSize = linesize[0];
        videoFrame.frameData.resize(videoFrame.lineSize * videoFrame.height);
        memcpy(videoFrame.frameData.data(), data[0], videoFrame.frameData.size());
    
        sws_freeContext(swsContext);
        avpicture_free((AVPicture *)data);
    

    代码分析:

    1. 首先获取SwsContext
    2. av_image_alloc根据width, height, pix_fmt初始化linesize[4], data[4]
    3. sws_scale色彩转换,完成yuv到rgb的转换
    4. 将data[0]的数据全部copy到framedata.data()

    相关文章

      网友评论

        本文标题:sws_scale的图像色彩空间转换

        本文链接:https://www.haomeiwen.com/subject/oxmsnctx.html