基于FFMpeg的BGR缓冲图像到YUV的快速转换
Fast transformation of BGR BufferedImage to YUV using FFMpeg
我想通过JNI使用FFMpeg的sws_scale函数将Java中的TYPE_3BYTE_BGR BufferedImage转换为yuv。我首先从BufferedImage中提取我的图像数据作为
byte[] imgData = ((DataBufferByte) myImage.getRaster().getDataBuffer()).getData();
byte[] output = processImage(toSend,0);
然后我将它传递给processImage函数,它是一个本机函数。C++方面看起来是这样的:
JNIEXPORT jbyteArray JNICALL Java_jni_JniExample_processData
(JNIEnv *env, jobject obj, jbyteArray data, jint index)
{
jboolean isCopy;
uint8_t *test = (uint8_t *)env->GetPrimitiveArrayCritical(data, &isCopy);
uint8_t *inData[1]; // RGB24 have one plane
inData[0] = test;
SwsContext * ctx = sws_getContext(width,height,AV_PIX_FMT_BGR24, (int)width, (int)width,
AV_PIX_FMT_YUV420P, 0, 0, 0, 0);
int lumaPlaneSize = width *height;
uint8_t *yuv[3];
yuv[0] = new uint8_t[lumaPlaneSize];
yuv[1] = new uint8_t[lumaPlaneSize/4];
yuv[2] = new uint8_t[lumaPlaneSize/4];
int inLinesize[1] = { 3*nvEncoder->width }; // RGB stride
int outLinesize[3] = { 3*width ,3*width ,3*width }; // YUV stride
sws_scale(ctx, inData, inLinesize, 0, height , yuv, outLinesize);
然而,在运行完代码后,我得到了警告:[swscaler @ 0x7fb598659480] Warning: data is not aligned! This can lead to a speedloss, everything crashes.
,所有东西都在最后一行崩溃。在将正确的参数传递给sws_scale方面,我做得是否正确?(特别是步伐)。
更新:这里有一个单独的错误:SwsContext * ctx = sws_getContext(width,height,AV_PIX_FMT_BGR24, (int)width, (int)width,0,NULL,NULL,NULL)
,应该更改为:SwsContext * ctx = sws_getContext(width,height,AV_PIX_FMT_BGR24, (int)height, (int)width,0,NULL,NULL,NULL)
我看到的第一个问题-输出图像的步幅错误:
yuv[0] = new uint8_t[lumaPlaneSize];
yuv[1] = new uint8_t[lumaPlaneSize/4];
yuv[2] = new uint8_t[lumaPlaneSize/4];
int inLinesize[1] = { 3*nvEncoder->width }; // RGB stride
int outLinesize[3] = { 3*width ,3*width ,3*width }; // YUV stride
// ^^^^^^^ ^^^^^^^ ^^^^^^^
分配的飞机不够大,无法通过跨步。YUV420为每个通道使用一个字节,因此3
是冗余的,并导致绑定冲突。由于重新缩放程序在转到下一行时会跳过大量空间。接下来,实际的色度宽度是亮度宽度的一半,所以如果你想要紧凑的亮度和色度平面,在行末端没有间隙,请使用下一个:
int outLinesize[3] = { width , width / 2 , width / 2 }; // YUV stride
分配大小保持不变。
查看源代码,特别是第321行附近,如果您的系统支持AVX2指令,并且各种指针和大小不是16的倍数,则会收到警告消息。崩溃的发生可能是因为传入的数组inData
、inLineSize
和outLinesize
的大小不合适。指针数组需要至少有3个元素,步长数组需要4个元素。在sws_scale
中的某个位置,它正在访问超出数组边界的inData[1]
,导致指针错误。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- 如何在Qt中将带有YUV数据的"QVideoFrame"转换为具有RGBA32数据的"QVideoframe"?
- 在 opencv 中使用 Color_YUV2BGR 从 YUV 到 BGR 的错误转换
- 从RGB到YUV(YCoCg)的颜色转换
- RGB到FFMPEG中YUV转换的错误
- YUV -> RGB 转换可以硬件加速吗?
- x265编码器,将YUV转换为x265_picture
- Blackmagic框架:将yuv转换为RGB以在openCV中使用
- 如何将 YUV 帧转换为视频
- 如何优化 YUV 到 RGB 颜色转换代码
- 要转换为 RGB 的 YUV 缓冲区的内存分配
- 移动设备上的 YUV (NV21) 到 BGR 转换(本机代码)
- 如何转换 RGB -> YUV -> RGB(双向)
- 如何将直播视频流从YUV(HDYC)转换为RGB
- 如何在YUV到RGB转换期间垂直翻转缓冲区
- 将数据缓冲器(YUV)转换为QImage(RGBA)
- 基于FFMpeg的BGR缓冲图像到YUV的快速转换