ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【音视频开发(四)】---RGB转YUV 颜色空间转换

2022-02-20 17:05:24  阅读:176  来源: 互联网

标签:-------- mMaxBufferNumber int void YUV --- input 音视频 Rgb2YuvCv


Android的MediaCodec编码,默认要求输入是原始视频图像格式,一般为YUV420,例如NV12, NV21。但算法库输出默认的颜色为RGB或者BGR,需要进行转化。而如果使用循环单纯用CPU转换是比较慢的,这里使用OpenCV来进行转换,OpenCV虽然也是用了CPU,但是他内部做了并行计算的优化是比较快的,例如NEON/SSE等。
 

头文件:


#include "Flow.h"
#include <thread>
#include "DmSyncQueue.h"
#include "InputData.h"

#include <atomic>

using namespace  std;

class Rgb2YuvCv : public Flow {

public:
    Rgb2YuvCv();
    ~Rgb2YuvCv();
    void Init(int width, int height, int buffNumber=10);
    void PushData(const unsigned char *data, int size, int copy, int flag=0);
    void ReleaseOuputData(); //当外部使用完缓冲工区时释放
    void UnInit();
private:
    void Loop();

    int imageW;
    int imageH;

    int mMaxBufferNumber;
    int mBufferHead;
    int mBufferTail;
    atomic<int> mBufferSize;
    unsigned char **mOutputBuffer;
};

初始化:


void Rgb2YuvCv::Init(int width, int height, int buffNumber)
{

    run = true;
    imageW = width;
    imageH = height;
    mMaxBufferNumber = buffNumber;

    mInputDataList = new DmSyncQueue<InputData_t>(mMaxBufferNumber);
    mOutputDataList = new DmSyncQueue<InputData_t>(mMaxBufferNumber);

   
    mOutputBuffer =  new unsigned char* [mMaxBufferNumber+1];
    for (int i = 0; i < mMaxBufferNumber+1; i++) {
        mOutputBuffer[i] = new unsigned char [imageW * imageH * 3];
    }

    mBufferHead = 0;
    mBufferTail = 0;
    mBufferSize.store(mMaxBufferNumber);
    mLoopThread = new std::thread(&Rgb2YuvCv::Loop, this);
}
void Rgb2YuvCv::UnInit()
{
    run = false;
    if(mLoopThread) mLoopThread->join();

    for (int i = 0; i < mMaxBufferNumber+1; i++) {
        delete [] mOutputBuffer[i] ;
    }
    delete [] mOutputBuffer ;

    SAFE_DELETE(mInputDataList);
    SAFE_DELETE(mOutputDataList);
}

数据的输入或者释放:

void Rgb2YuvCv::PushData(const unsigned char *data, int size, int copy, int flag)
{
    InputData_t input;
    if (size <= 0 ) return;
    if (copy) {
        unsigned char *newdata = new unsigned char[size];
        memcpy(newdata, data, size);
        data = newdata;
    }
    input.dataPtr = data;
    input.size = size;
    input.needRealeaseMemory = copy;
    input.flag = flag;
    mInputDataList->Put(input);
}

void Rgb2YuvCv::ReleaseOuputData()
{
    mBufferTail = (mBufferTail + 1) % mMaxBufferNumber;
    mBufferSize++;
}

图像数据转换工作线程:


void Rgb2YuvCv::Loop()
{
    unsigned char *buffer ;
    while(run) {
        if(mBufferSize.load() == 0) {
            usleep(1000);
            continue;
        }
        InputData_t input;
        if(mInputStreamDataList == NULL) {
            if(!mInputDataList->Take(input)) continue;
        } else {
            if(!mInputStreamDataList->Take(input)) continue;
        }
        buffer = mOutputBuffer[mBufferHead];
        //DM_NATIVE_ERR_PRINT("-------- Rgb2YuvCv %dx%d size= %p %d %p--------\n",imageW,imageH, input.dataPtr, input.size, buffer);

        //转码
        cv::Mat yuvImg(imageH*1.5, imageW,CV_8UC1, (void *)buffer);
        // rgbImg.data = buffer;
        cv::Mat rgbImg(imageH, imageW, CV_8UC3,  (void *)input.dataPtr);
        // yuvImg.data = yuvImg.data;

        mBufferHead = (mBufferHead + 1) % mMaxBufferNumber;
        mBufferSize--;

        //memcpy(yuvImg.data, *iter, decoder.mYUVSize);
        //DM_NATIVE_ERR_PRINT("-------- cvtColor start--------\n");
        cv::cvtColor(rgbImg, yuvImg , CV_RGB2YUV_I420);
        //DM_NATIVE_ERR_PRINT("-------- cvtColor done--------\n");
        InputData_t output;
        output.dataPtr = buffer;
        output.size = imageH * imageW * 1.5;
        output.flag = input.flag;
        output.needRealeaseMemory = false;
        DM_NATIVE_DEBUG_PRINT("-------- Rgb2YuvCv %dx%d size= %p %d %p flag=%d--------\n",imageW,imageH, input.dataPtr, input.size, buffer, output.flag);
        mOutputDataList->Put(output);
        CALLBACK_InputDataFinished(input);
        if (input.needRealeaseMemory) {
            SAFE_DELETE_ARRAY(input.dataPtr);
        }
    }
}

标签:--------,mMaxBufferNumber,int,void,YUV,---,input,音视频,Rgb2YuvCv
来源: https://blog.csdn.net/sdewenking/article/details/123032722

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有