FFmpeg对颠倒的RGB图像翻转显示

转载:https://blog.csdn.net/zhoubotong2012/article/details/103304698

很多使用FFmpeg做解码的用户都可能遇到过一个问题,他们对解码出来的图像转为RGB格式之后显示图像是颠倒的。

有些用户对其原因不大明白,其实原因跟RGB图像的存储方式有关。

RGB图像即RGB位图有两种存储方式:一种是从上往下扫描,另一种是从下往上扫描。

从上扫描的图像第一行的首地址即为图像Buffer的起始地址,而从下往上扫描的图像第一行的首地址为:buffer_data + linesize*(height-1),

其中buffer_data为图像Buffer的起始地址,linesize为图像的行字节宽度,

对于RGB24图像,linesize = (width * 3 + 3)/4×4,

对于YUV420图像,linesize = (width + 3)/4 *4。

对于颠倒显示的RGB图像我们可以用FFmpeg的函数把它翻转过来显示,处理方法很简单,下面是实现步骤和代码:

第一步:先定义几个用于FFmpeg解码和转换图像的变量。

	AVCodec *codec; 
	AVCodecContext *codecCtx;
	AVFrame *m_picture; 
	AVFrame *m_pFrameRGB;
	SwsContext *m_pImgCtx;
	uint8_t *m_PicBuf;
	int m_PicBytes;

第二步:初始化变量。

 m_pImgCtx = NULL;
 m_PicBuf  = NULL;
 m_PicBytes = 0;

第三步:解码图像,并转换图像为RGB格式

	int ret, got_picture;
	ret = avcodec_decode_video2(codecCtx, m_picture, &got_picture, &packet);
	if (ret > 0 )
	{
		if(got_picture)
		{
			if(m_PicBuf == NULL)
			{
				m_PicBytes = avpicture_get_size(PIX_FMT_BGR24, codecCtx->width, codecCtx->height);  
				m_PicBuf = new uint8_t[m_PicBytes];  
				avpicture_fill((AVPicture *)m_pFrameRGB, m_PicBuf, PIX_FMT_BGR24, codecCtx->width, codecCtx->height);  
			}
			if(m_pImgCtx == NULL)
			{  
				m_pImgCtx = sws_getContext(codecCtx->width, codecCtx->height, codecCtx->pix_fmt, codecCtx->width, codecCtx->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);  
			}  
			m_picture->data[0] += m_picture->linesize[0]*(codecCtx->height-1);  
			m_picture->linesize[0] *= -1;                        
			m_picture->data[1] += m_picture->linesize[1]*(codecCtx->height/2-1);  
			m_picture->linesize[1] *= -1;  
			m_picture->data[2] += m_picture->linesize[2]*(codecCtx->height/2-1);  
			m_picture->linesize[2] *= -1;  
			sws_scale(m_pImgCtx, (const uint8_t* const*)m_picture->data, m_picture->linesize, 0, codecCtx->height, m_pFrameRGB->data, m_pFrameRGB->linesize);   
 
			display_pic(m_pFrameRGB->data[0], codecCtx->width, codecCtx->height);  //显示视频
 
 
		}
	}

上面的sws_scale函数除了将YUV420的图像转为BGR24,并且同时将颠倒的BGR24图像翻转过来。

最后,记得释放临时的图像内存:

sws_freeContext(m_pImgCtx);//转换函数也要释放
delete[] m_PicBuf; //释放内存

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值