FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale)

来源:互联网 发布:淘宝店主阿希哥微博 编辑:程序博客网 时间:2024/05/18 00:16

FFMPEG中的swscale提供了视频原始数据(YUV420,YUV422,YUV444,RGB24...)之间的转换,分辨率变换等操作,使用起来十分方便,在这里记录一下它的用法。

swscale主要用于在2个AVFrame之间进行转换。
下面来看一个视频解码的简单例子,这个程序完成了对"北京移动开发者大会茶歇视频2.flv"(其实就是优酷上的一个普通视频)的解码工作,并将解码后的数据保存为原始数据文件(例如YUV420,YUV422,RGB24等等)。其中略去了很多的代码。
解码H264
[cpp] view plaincopyprint?
  1. int i;  //YUV420  
  2. for(i=0;i<576;i++)    
  3. {//fwrite(buf + i * wrap, 1, xsize, f);    
  4.      memcpy(overlay->pixels[0]+i*1280, pFrame_->data[0]+i*pFrame_->linesize[0], 720);                                   
  5.  }    
  6.  for(i=0;i<288;i++)    
  7.  {    
  8.      memcpy(overlay->pixels[2]+i*640, pFrame_->data[1]+i*pFrame_->linesize[1], 360);    
  9.       memcpy(overlay->pixels[1]+i*640, pFrame_->data[2]+i*pFrame_->linesize[2], 360);   
  10.  }                                       
代码转换yuv422
[cpp] view plaincopyprint?
  1. int k=0,y,x;    //yuv420  -> yuv422    
  2.       for( y=0;y<576;y++)    
  3.       {    
  4.            for( x=0;x<720;x++)    
  5.            {    
  6.                 yuv422[k++] = pFrame_->data[0][y*pFrame_->linesize[0]+x];    
  7.                 yuv422[k++] = x%2==0?pFrame_->data[1][(y/2)*pFrame_->linesize[1]+x/2]:pFrame_->data[2][(y/2)*pFrame_->linesize[2]+x/2];    
  8.            }    
  9.       }    
  10.             
  11.         memcpy(overlay->pixels[0],yuv422, codec_->width*codec_->height*2);    
采用swscale转换
[cpp] view plaincopyprint?
  1.  int numBytes = avpicture_get_size(AV_PIX_FMT_YUYV422, codec_->width,      
  2.                                   codec_->height);      
  3.     uint8_t* yuv422 = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));      
  4.           
  5.     avpicture_fill((AVPicture *)pFrameYUV, yuv422, AV_PIX_FMT_YUYV422,      
  6.                    codec_->width, codec_->height);   
  7.   
  8.   
  9. //while  
  10.   
  11.   
  12. img_convert_ctx = sws_getContext(codec_->width, codec_->height, codec_->pix_fmt, codec_->width, codec_->height, AV_PIX_FMT_YUYV422, 2, NULL, NULL, NULL);       
  13.  sws_scale(img_convert_ctx, (const uint8_t* const*) pFrame_->data,  pFrame_->linesize, 0, codec_->height, pFrameYUV->data,pFrameYUV->linesize);      
  14.     
  15. memcpy(overlay->pixels[0],yuv422, codec_->width*codec_->height*2);   
阅读全文
0 0