1. 程式人生 > >FFmpeg 將YUV資料轉RGB

FFmpeg 將YUV資料轉RGB

只要開始初始化一次,結束後釋放就好,中間可以迴圈轉碼 

AVFrame    *m_pFrameRGB,*m_pFrameYUV;
uint8_t *m_rgbBuffer,*m_yuvBuffer;
struct SwsContext *m_img_convert_ctx;

void init() //分配兩個Frame,兩段buff,一個轉換上下文
{
 //為每幀影象分配記憶體
    // width和heigt為傳入的解析度的大小,解析度有變化時可以以最大標準申請
    m_pFrameYUV = av_frame_alloc();
    m_pFrameRGB = av_frame_alloc();
    
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); }