使用 ffmpeg 从 jpeg 转换为 BGRA 时数据丢失
Data loss while converting from jpeg to BGRA using ffmpeg
我正在尝试使用 ffmpeg 将 JPG 帧转换为 RGBA 帧。原始图像大小为 250x250,像素格式 AV_PIX_FMT_YUV420P。源线步长数组包含 [256, 128, 128](对于 3 个平面)。我的目标帧大小是 250x250。以下是代码。
AVFrame* GetBGRAFrame(AVFrame* pFrame)
{
const int kiImageWidth = pFrame->width ;
const int kiImageHeight = pFrame->height ;
int iDestWidth = kiImageWidth;
int iDestHeight = kiImageHeight;
AVPixelFormat enPixelFormat = (AVPixelFormat)pFrame->format ;
SwsContext* pImageConvertContext =
sws_getContext(kiImageWidth, kiImageHeight, enPixelFormat,
iDestWidth, iDestHeight, PIX_FMT_BGRA, 0, NULL, NULL, NULL);
// Allocate destination frame
int iNumBytes = avpicture_get_size(AV_PIX_FMT_BGRA, iDestWidth, iDestHeight);
AVFrame* pFrame2 = av_frame_alloc();
uint8_t* pFrameBuffer = (uint8_t*)av_malloc(iNumBytes * sizeof(uint8_t));
avpicture_fill((AVPicture*)pFrame2, pFrameBuffer, AV_PIX_FMT_BGRA, iDestWidth, iDestHeight);
sws_scale(pImageConvertContext, pFrame->data, pFrame->linesize, 0, kiImageHeight, pFrame2->data, pFrame2->linesize);
sws_freeContext(pImageConvertContext);
return pFrame2;
}
转换后,我在目标框架的右侧得到了 2 个透明列。
如果我使用命令行工具,我可以获得正确的图像:
ffmpeg -i image.jpg output.png
那么,我的代码有什么问题?
目的地有对齐要求吗?如果是,我应该如何更改我的代码以获得 250x250 BGRA 帧?
谢谢
我认为您在 yuv420p 到 RGB24 的转换中遇到了 this 代码:
h_size = (c->dstW + 7) & ~7; \
if (h_size * depth > FFABS(dstStride[0])) \
h_size -= 8; \
由于 avpicture_get_size() 应该为您处理所有这些,我认为这是一个错误,您应该在 trac.ffmpeg.org 或邮件列表中报告...
[编辑]
作为一种实际的解决方法,请遵循 linked bug report 中的评论:
Call instead av_image_alloc() directly [..] with an align parameter of 32.
我正在尝试使用 ffmpeg 将 JPG 帧转换为 RGBA 帧。原始图像大小为 250x250,像素格式 AV_PIX_FMT_YUV420P。源线步长数组包含 [256, 128, 128](对于 3 个平面)。我的目标帧大小是 250x250。以下是代码。
AVFrame* GetBGRAFrame(AVFrame* pFrame)
{
const int kiImageWidth = pFrame->width ;
const int kiImageHeight = pFrame->height ;
int iDestWidth = kiImageWidth;
int iDestHeight = kiImageHeight;
AVPixelFormat enPixelFormat = (AVPixelFormat)pFrame->format ;
SwsContext* pImageConvertContext =
sws_getContext(kiImageWidth, kiImageHeight, enPixelFormat,
iDestWidth, iDestHeight, PIX_FMT_BGRA, 0, NULL, NULL, NULL);
// Allocate destination frame
int iNumBytes = avpicture_get_size(AV_PIX_FMT_BGRA, iDestWidth, iDestHeight);
AVFrame* pFrame2 = av_frame_alloc();
uint8_t* pFrameBuffer = (uint8_t*)av_malloc(iNumBytes * sizeof(uint8_t));
avpicture_fill((AVPicture*)pFrame2, pFrameBuffer, AV_PIX_FMT_BGRA, iDestWidth, iDestHeight);
sws_scale(pImageConvertContext, pFrame->data, pFrame->linesize, 0, kiImageHeight, pFrame2->data, pFrame2->linesize);
sws_freeContext(pImageConvertContext);
return pFrame2;
}
转换后,我在目标框架的右侧得到了 2 个透明列。
如果我使用命令行工具,我可以获得正确的图像: ffmpeg -i image.jpg output.png
那么,我的代码有什么问题?
目的地有对齐要求吗?如果是,我应该如何更改我的代码以获得 250x250 BGRA 帧?
谢谢
我认为您在 yuv420p 到 RGB24 的转换中遇到了 this 代码:
h_size = (c->dstW + 7) & ~7; \
if (h_size * depth > FFABS(dstStride[0])) \
h_size -= 8; \
由于 avpicture_get_size() 应该为您处理所有这些,我认为这是一个错误,您应该在 trac.ffmpeg.org 或邮件列表中报告...
[编辑] 作为一种实际的解决方法,请遵循 linked bug report 中的评论:
Call instead av_image_alloc() directly [..] with an align parameter of 32.