zoukankan      html  css  js  c++  java
  • FFmpeg 将YUV数据转RGB

    只要开始初始化一次,结束后释放就好,中间可以循环转码 

    AVFrame    *m_pFrameRGB,*m_pFrameYUV;
    uint8_t *m_rgbBuffer,*m_yuvBuffer;
    struct SwsContext *m_img_convert_ctx;
    
    void init() //分配两个Frame,两段buff,一个转换上下文
    {
     //为每帧图像分配内存
        m_pFrameYUV = av_frame_alloc();
        m_pFrameRGB = av_frame_alloc();

    // width和heigt为传入的分辨率的大小,分辨率有变化时可以以最大标准申请
    int numBytes = avpicture_get_size(AV_PIX_FMT_RGB32, nwidth,nheight); m_rgbBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t)); int yuvSize = nwidth * nheight * 3 /2; m_yuvBuffer = (uint8_t *)av_malloc(yuvSize);
    //特别注意sws_getContext内存泄露问题, //注意sws_getContext只能调用一次,在初始化时候调用即可,另外调用完后,在析构函数中使用sws_freeContext,将它的内存释放。 //设置图像转换上下文 m_img_convert_ctx = sws_getContext(nwidth, nheight, AV_PIX_FMT_YUV420P,                         nwidth, nheight, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL); } void play(char* pbuff_in,int nwidth,int nheight)
    { avpicture_fill((AVPicture *) m_pFrameRGB, m_rgbBuffer, AV_PIX_FMT_RGB32,nwidth, nheight); avpicture_fill((AVPicture *) m_pFrameYUV, (uint8_t *)pbuff_in, AV_PIX_FMT_YUV420P, nwidth, nheight); //转换图像格式,将解压出来的YUV420P的图像转换为RGB的图像 sws_scale(m_img_convert_ctx, (uint8_t const * const *) m_pFrameYUV->data, m_pFrameYUV->linesize, 0, nheight, m_pFrameRGB->data, m_pFrameRGB->linesize); //把这个RGB数据 用QImage加载 QImage tmpImg((uchar *)m_rgbBuffer,nwidth,nheight,QImage::Format_RGB32); //把图像复制一份 传递给界面显示 m_mapImage[nWindowIndex] = tmpImg.copy(); } void release() { av_frame_free(&m_pFrameYUV); av_frame_free(&m_pFrameRGB); av_free(m_rgbBuffer); av_free(m_yuvBuffer); sws_freeContext(m_img_convert_ctx); }

    另一种方法:

    bool YV12ToBGR24_FFmpeg(unsigned char* pYUV,unsigned char* pBGR24,int width,int height)
    {
        if (width < 1 || height < 1 || pYUV == NULL || pBGR24 == NULL)
            return false;
        //int srcNumBytes,dstNumBytes;
        //uint8_t *pSrc,*pDst;
        AVPicture pFrameYUV,pFrameBGR;
        
        //pFrameYUV = avpicture_alloc();
        //srcNumBytes = avpicture_get_size(PIX_FMT_YUV420P,width,height);
        //pSrc = (uint8_t *)malloc(sizeof(uint8_t) * srcNumBytes);
        avpicture_fill(&pFrameYUV,pYUV,PIX_FMT_YUV420P,width,height);
    
        //U,V互换
        uint8_t * ptmp=pFrameYUV.data[1];
        pFrameYUV.data[1]=pFrameYUV.data[2];
        pFrameYUV.data [2]=ptmp;
    
        //pFrameBGR = avcodec_alloc_frame();
        //dstNumBytes = avpicture_get_size(PIX_FMT_BGR24,width,height);
        //pDst = (uint8_t *)malloc(sizeof(uint8_t) * dstNumBytes);
        avpicture_fill(&pFrameBGR,pBGR24,PIX_FMT_BGR24,width,height);
    
        struct SwsContext* imgCtx = NULL;
        imgCtx = sws_getContext(width,height,PIX_FMT_YUV420P,width,height,PIX_FMT_BGR24,SWS_BILINEAR,0,0,0);
    
        if (imgCtx != NULL){
            sws_scale(imgCtx,pFrameYUV.data,pFrameYUV.linesize,0,height,pFrameBGR.data,pFrameBGR.linesize);
            if(imgCtx){
                sws_freeContext(imgCtx);
                imgCtx = NULL;
            }
            return true;
        }
        else{
            sws_freeContext(imgCtx);
            imgCtx = NULL;
            return false;
        }
    }
  • 相关阅读:
    python汉诺塔
    圆周率计算
    PIL: 建立一个GIF图
    Jieba库使用和好玩的词云
    Turtle库的建立——汉诺塔
    计算pi的精度+进度条显示
    Python——我所学习的turtle函数库
    Python——教你画朵太阳花
    Python常用模块re的使用
    正则表达式字符组/元字符/量词
  • 原文地址:https://www.cnblogs.com/nanqiang/p/10116279.html
Copyright © 2011-2022 走看看