本人在win7系统 vs2010下 用最新的ffmpeg库ffmpeg-3.0.2将1440*896的rgb24的格式缩放成1360*768的yuv420p,转换之后的图像左边会有条纹 源代码如下:
void Rgb24ToYuv420(int nSrcW,int nSrcH,BYTE* pRgbData,int nDstW, int nDstH,BYTE* pYuvData)
{
int nDstStride[3];
nDstStride[0] = nDstW;
nDstStride[1] = nDstW / 2;
nDstStride[2] = nDstW / 2;
int nSrcStride[3] = {3*nSrcW,0,0};
uint8_t *pSrcBuff[3] = {pRgbData,NULL,NULL};
uint8_t *pDstBuff[3] = {pYuvData, pYuvData + nDstW * nDstH, pYuvData + nDstW * nDstH * 5 / 4};
//翻转
pDstBuff[0] += nDstStride[0]*(nDstH -1);
nDstStride[0] *= -1;
pDstBuff[1] += nDstStride[1]*(nDstH/2 – 1);
nDstStride[1] *= -1;
pDstBuff[2] += nDstStride[2]*(nDstH/2 – 1);
nDstStride[2] *= -1;
SwsContext* m_pSwsContext;
m_pSwsContext = sws_getContext(nSrcW, nSrcH, AV_PIX_FMT_BGR24,
nDstW, nDstH, AV_PIX_FMT_YUV420P,
SWS_SA_BILINEAR,
NULL, NULL, NULL);
//m_pSwsContext = sws_getContext(nSrcW, nSrcH, AV_PIX_FMT_RGB24,
// nDstW, nDstH, AV_PIX_FMT_YUV420P,
// SWS_SINC,
// NULL, NULL, NULL);
if (NULL == m_pSwsContext)
{
return;
}
sws_scale(m_pSwsContext, pSrcBuff,
nSrcStride, 0, nSrcH,
pDstBuff, nDstStride);
sws_freeContext(m_pSwsContext);
}
本人也用过ffmpeg以前的库也是会有这个问题,1440*896的rgb24的格式缩放成1320*768的yuv420p也会有这个问题
void Rgb24ToYuv420(int nSrcW,int nSrcH,BYTE* pRgbData,int nDstW, int nDstH,BYTE* pYuvData)
{
int nDstStride[3];
nDstStride[0] = nDstW;
nDstStride[1] = nDstW / 2;
nDstStride[2] = nDstW / 2;
int nSrcStride[3] = {3*nSrcW,0,0};
uint8_t *pSrcBuff[3] = {pRgbData,NULL,NULL};
uint8_t *pDstBuff[3] = {pYuvData, pYuvData + nDstW * nDstH, pYuvData + nDstW * nDstH * 5 / 4};
//翻转
pDstBuff[0] += nDstStride[0]*(nDstH -1);
nDstStride[0] *= -1;
pDstBuff[1] += nDstStride[1]*(nDstH/2 – 1);
nDstStride[1] *= -1;
pDstBuff[2] += nDstStride[2]*(nDstH/2 – 1);
nDstStride[2] *= -1;
SwsContext* m_pSwsContext;
m_pSwsContext = sws_getContext(nSrcW, nSrcH, AV_PIX_FMT_BGR24,
nDstW, nDstH, AV_PIX_FMT_YUV420P,
SWS_SA_BILINEAR,
NULL, NULL, NULL);
//m_pSwsContext = sws_getContext(nSrcW, nSrcH, AV_PIX_FMT_RGB24,
// nDstW, nDstH, AV_PIX_FMT_YUV420P,
// SWS_SINC,
// NULL, NULL, NULL);
if (NULL == m_pSwsContext)
{
return;
}
sws_scale(m_pSwsContext, pSrcBuff,
nSrcStride, 0, nSrcH,
pDstBuff, nDstStride);
sws_freeContext(m_pSwsContext);
}
本人也用过ffmpeg以前的库也是会有这个问题,1440*896的rgb24的格式缩放成1320*768的yuv420p也会有这个问题
解决方案
50
拍脑袋猜想,写dst数据时有些加速操作,实际对一行操作时,写入的数据超过stride……
请题主先尝试去掉下面代码,看能否还有左边条纹问题
请题主先尝试去掉下面代码,看能否还有左边条纹问题
//翻转 pDstBuff[0] += nDstStride[0]*(nDstH -1); nDstStride[0] *= -1; pDstBuff[1] += nDstStride[1]*(nDstH/2 - 1); nDstStride[1] *= -1; pDstBuff[2] += nDstStride[2]*(nDstH/2 - 1); nDstStride[2] *= -1;
确认没问题的话,可以本人写上下翻转的代码,又或通过改变nSrcStride/pSrcBuff来实现翻转,不要动dst的东西……
50
说个题外话吧,ffmpe里很多汇编优化,它一次读取或写入的数据可能比你想象中的要多(某些对齐要求),所以ffmpeg操作的内存区域,一般都应该用av_malloc分配,这个函数通常分配的内存会比你要求的多,就是为了应付这些场景