这是常见问题的变体,但我没有看到这种情况,所以我会把它扔出去。
我有一个onPreviewFrame回调设置。这会得到一个包含NV21数据的byte []。我们对它进行h.264编码并将其作为视频流发送出去。另一方面,我们看到视频偏向90度或270度,具体取决于手机。
所以问题是,如何旋转数据,而不仅仅是预览图像? Camera.Parameters.setRotation仅影响拍照,而不影响视频。 Camera.setDisplayOrientation明确表示它只影响显示预览,而不影响帧字节:
这不会影响onPreviewFrame(byte [],Camera),JPEG图片或录制视频中传递的字节数组的顺序。
那么在任何API级别都有一种方法可以改变字节数组的方向吗?如果不这样做,你甚至可以旋转这种格式的NV21(YVU)格式,还是首先需要RGB格式呢?
答案 0 :(得分:1)
原来你需要在发送之前自己旋转每一帧。我们最终使用了libyuv,它具有非常方便的功能,可以旋转并转换它 - libyuv :: ConvertToI420
答案 1 :(得分:0)
我认为您需要自己旋转图片。我使用NDK和leptonica库做了一次。看看我的代码应该让你入门。在三星Galaxy S2上表现还不错(我觉得我大约有15帧左右)。由于我将结果推入openGL纹理,我不得不调整周围的颜色字节.. 您可以通过直接在循环中旋转图像来加速它,该循环解码yuv数据。
之前已经分配了mPix32和mPix8来保存转换后的数据。当然,您需要替换自己的图像数据结构。jint Java_de_renard_ImageFilter_nativeProcessImage(JNIEnv *env, jobject javathis, jbyteArray frame) {
....
jbyte *data_buffer = env->GetByteArrayElements(frame, NULL);
l_uint8 *byte_buffer = (l_uint8 *) data_buffer;
yuvToPixFast(byte_buffer, mPix32, mPix8);
env->ReleaseByteArrayElements(frame, data_buffer, JNI_ABORT);
....
}
static inline void yuvToPixFast(unsigned char* pY, Pix* pix32, Pix* pix8) {
int i, j;
int nR, nG, nB;
int nY, nU, nV;
l_uint32* data = pixGetData(pix32);
l_uint32* data8 = pixGetData(pix8);
l_int32 height = pixGetHeight(pix32);
l_int32 width = pixGetWidth(pix32);
l_int32 wpl = pixGetWpl(pix32);
l_int32 wpl8 = pixGetWpl(pix8);
l_uint8 **lineptrs = pixSetupByteProcessing(pix8, NULL, NULL);
l_uint8* line8;
//memcpy(data8,pY,height*width);
unsigned char* pUV = pY + width * height;
for (i = 0; i < height; i++) {
nU = 0;
nV = 0;
unsigned char* uvp = pUV + (i >> 1) * width;
line8 = lineptrs[i];
memcpy(line8, pY, wpl8 * 4);
for (j = 0; j < width; j++) {
if ((j & 1) == 0) {
nV = (0xff & *uvp++) - 128;
nU = (0xff & *uvp++) - 128;
}
// Yuv Convert
nY = *(pY++);
//*line8++ = (l_uint8) nY;
nY -= -16;
if (nY < 0) {
nY = 0;
}
int y1192 = nY * 1192;
/*double saturation to increase cartoon effect*/
//nU<<=1;
//nV<<=1;
nB = y1192 + 2066 * nU;
nG = y1192 - 833 * nV - 400 * nU;
nR = y1192 + 1634 * nV;
if (nR < 0) {
nR = 0;
} else if (nR > 262143) {
nR = 262143;
}
if (nG < 0) {
nG = 0;
} else if (nG > 262143) {
nG = 262143;
}
if (nB < 0) {
nB = 0;
} else if (nB > 262143) {
nB = 262143;
}
//RGBA
//ABGR
*data++ = ((nR << 14) & 0xff000000) | ((nG << 6) & 0xff0000) | ((nB >> 2) & 0xff00) | (0xff);
//*data++ = (0x00 << 24) | (0xff<<16) | (0x00<<8) | ( 0xff) ;
//*data++ = (0xff << 24) | ((nB << 6) & 0xff0000) | ((nG >> 2) & 0xff00) | ((nR >> 10) & 0xff);
}
}
pixCleanupByteProcessing(pix8, lineptrs);
}