Android 上的 libyuv::ConvertToI420 有问题?
Issue with libyuv::ConvertToI420 on Android?
我设置了 onPreviewFrame 回调。这会得到一个包含 NV21 数据的 byte[]。我已将预览大小设置为 176*144。当设备处于横向模式时,176*144 尺寸的 byte[] 是完美的,但是当设备处于纵向模式时,我仍然得到相同尺寸的 byte[]。
我想将byte[]旋转90度得到144*176尺寸的byte[]
那么问题来了,如何旋转数据,而不仅仅是预览图像? Camera.Parameters.setRotation 只影响拍照,不影响录像。 Camera.setDisplayOrientation具体说只影响显示预览,不影响帧字节:
This does not affect the order of byte array passed in
onPreviewFrame(byte[], Camera), JPEG pictures, or recorded videos.
查看各种帖子后,我发现 this 一篇声明使用 libyuv 中的 ConvertToI420。
现在我已经编译了 libyuv 并能够调用 libyuv::ConvertToI420 方法,但是我得到的结果 I420 在颜色和显示线条等方面都一团糟......但是我得到的尺寸现在是144 * 176,可以查看图像here。
我使用的代码片段如下。
//sourceWidth = 176 and sourceHeight = 144
unsigned char I420M = new unsigned char[(int)(sourceWidth*sourceHeight*1.5)];
unsigned int YSize = sourceWidth * sourceHeight;
// yuvPtr is the NV21 data passed from onPreviewCallback (from JAVA layer)
const uint8* src_frame = const_cast<const uint8*>(yuvPtr);
size_t src_size = YSize;
uint8* pDstY = I420M;
uint8* pDstU = I420M + YSize;
uint8* pDstV = I420M + (YSize/4);
libyuv::RotationMode mode;
if(landscapeLeft){
mode = libyuv::kRotate90;
}else{
mode = libyuv::kRotate270;
}
uint32 format = libyuv::FOURCC_NV21;
int retVal = libyuv::ConvertToI420(src_frame, src_size,
pDstY, sourceHeight,
pDstU, (sourceHeight/2),
pDstV, (sourceHeight/2),
0, 0,
sourceWidth, sourceHeight,
sourceWidth, sourceHeight,
mode,
format);
我不想裁剪图像,只需将其旋转 90 (clockwise/anticlockwise) 附件图像适用于 kRotate90。
任何人都可以指出我哪里出了问题,我强烈怀疑它是否对传递给 ConvertToI420 方法的参数做了什么。
感谢任何帮助。
我已经弄清楚出了什么问题。上面的代码片段运行良好,I420M 包含 144*176 尺寸的旋转 YUV。
问题出在我将 I420M 转换为 jbyte[] 并将其传回 Java 层的方式。
使用 sourceWidth 而不是 sourceHeight
int retVal = libyuv::ConvertToI420(src_frame, src_size,
pDstY, sourceWidth,
pDstU, (sourceWidth/2),
pDstV, (sourceWidth/2),
0, 0,
sourceWidth, sourceHeight,
sourceWidth, sourceHeight,
mode,
format);
我设置了 onPreviewFrame 回调。这会得到一个包含 NV21 数据的 byte[]。我已将预览大小设置为 176*144。当设备处于横向模式时,176*144 尺寸的 byte[] 是完美的,但是当设备处于纵向模式时,我仍然得到相同尺寸的 byte[]。
我想将byte[]旋转90度得到144*176尺寸的byte[]
那么问题来了,如何旋转数据,而不仅仅是预览图像? Camera.Parameters.setRotation 只影响拍照,不影响录像。 Camera.setDisplayOrientation具体说只影响显示预览,不影响帧字节:
This does not affect the order of byte array passed in
onPreviewFrame(byte[], Camera), JPEG pictures, or recorded videos.
查看各种帖子后,我发现 this 一篇声明使用 libyuv 中的 ConvertToI420。
现在我已经编译了 libyuv 并能够调用 libyuv::ConvertToI420 方法,但是我得到的结果 I420 在颜色和显示线条等方面都一团糟......但是我得到的尺寸现在是144 * 176,可以查看图像here。
我使用的代码片段如下。
//sourceWidth = 176 and sourceHeight = 144
unsigned char I420M = new unsigned char[(int)(sourceWidth*sourceHeight*1.5)];
unsigned int YSize = sourceWidth * sourceHeight;
// yuvPtr is the NV21 data passed from onPreviewCallback (from JAVA layer)
const uint8* src_frame = const_cast<const uint8*>(yuvPtr);
size_t src_size = YSize;
uint8* pDstY = I420M;
uint8* pDstU = I420M + YSize;
uint8* pDstV = I420M + (YSize/4);
libyuv::RotationMode mode;
if(landscapeLeft){
mode = libyuv::kRotate90;
}else{
mode = libyuv::kRotate270;
}
uint32 format = libyuv::FOURCC_NV21;
int retVal = libyuv::ConvertToI420(src_frame, src_size,
pDstY, sourceHeight,
pDstU, (sourceHeight/2),
pDstV, (sourceHeight/2),
0, 0,
sourceWidth, sourceHeight,
sourceWidth, sourceHeight,
mode,
format);
我不想裁剪图像,只需将其旋转 90 (clockwise/anticlockwise) 附件图像适用于 kRotate90。
任何人都可以指出我哪里出了问题,我强烈怀疑它是否对传递给 ConvertToI420 方法的参数做了什么。
感谢任何帮助。
我已经弄清楚出了什么问题。上面的代码片段运行良好,I420M 包含 144*176 尺寸的旋转 YUV。
问题出在我将 I420M 转换为 jbyte[] 并将其传回 Java 层的方式。
使用 sourceWidth 而不是 sourceHeight
int retVal = libyuv::ConvertToI420(src_frame, src_size,
pDstY, sourceWidth,
pDstU, (sourceWidth/2),
pDstV, (sourceWidth/2),
0, 0,
sourceWidth, sourceHeight,
sourceWidth, sourceHeight,
mode,
format);