ffmpeg图片格式转换缩放的问题sws_scale

bestxp 2016-05-28 05:06:49
我在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也会有这个问题

...全文
697 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
bestxp 2016-05-30
  • 打赏
  • 举报
回复
问题已解决,改变nSrcStride/pSrcBuff实现翻转 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}; int nSrcStride[3] = {-3*nSrcW,0,0}; uint8_t *pSrcBuff[3] = {pRgbData+3*nSrcW*( nSrcH - 1),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); }
bestxp 2016-05-30
  • 打赏
  • 举报
回复
引用 2 楼 lqbk1 的回复:
拍脑袋猜想,写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的东西......
删除翻转代码 是没有条纹出现的 //翻转 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来实现翻转,感谢
lqbk1 2016-05-28
  • 打赏
  • 举报
回复
说个题外话吧,ffmpe里很多汇编优化,它一次读取或写入的数据可能比你想象中的要多(某些对齐要求),所以ffmpeg操作的内存区域,一般都应该用av_malloc分配,这个函数通常分配的内存会比你要求的多,就是为了应付这些场景
lqbk1 2016-05-28
  • 打赏
  • 举报
回复
拍脑袋猜想,写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的东西......
打开链接下载源码: https://pan.quark.cn/s/8ec3d104bde6 华为MA5671是一款针对宽带接入需求而研发的智能型光猫设备,其核心应用场景为家庭用户及小型企业环境。该设备运用了千兆以太网技术,能够提供卓越的网络连接性能,从而使用户可以体验到稳定流畅的互联网服务。其完整名称为SmartAX MA5671,其中"SmartAX"是华为对其智能接入产品系列的特定命名,意指该设备具备智能化管理功能与自动化配置特性。固件,即Firmware,是指存储于硬件设备内部的一套程序代码,负责控制设备的各项功能运作并合理调配硬件资源。在华为MA5671设备中,固件发挥着核心作用,它直接影响着设备的操作系统运行机制、网络协议兼容性、安全防护机制以及性能表现等多个维度。"MA5671V8R313C00SPC100"作为该固件的标识编号,通过此代码可以解析出以下几个关键层面的信息: 1. **V8**:这通常象征固件的主版本号,或许表明这是第8代产品形态或第8次主要升级迭代。 2. **R313**:这可能代表固件的次级版本或修订层级,暗示着相较于V8版本,该版本经历了313次的迭代优化。 3. **C00**:这部分或许与设备的特定型号设定或地域适配性相关,不同的C00编码可能对应不同的功能模块配置或区域适应性调整。 4. **SPC100**:最后的这一段编码可能标识着特殊版本或性能增强配置,SPC(Special Performance Configuration)可能是华为针对特定性能优化版本设定的代号,而100可能代表这种优化措施的等级或序列编号。 在实际部署过程中,将固件保持为最新版本是非常重要的,这样做能够有效修正已知的安全隐患,优化设备运作效能,...

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧