ОК, вот мой родной код, который развился после многих ударов головы.
Моя трудность заключалась в том, что я не понимаю, планарные форматы изображений, пока я не увидел this и это:

Вот 2 функции я в конце концов написал:
// rotate luma image plane 90*
//
// (dst direction)
// ------>
// dst -> +-------------+
// |^ |
// |^ (base dir) |
// |^ |
// base -> +-------------+ <- endp
//
//////////////////////////////////////////////////////////
void rotateLumaPlane90(const unsigned char *src, unsigned char *dst,
size_t size, size_t width, size_t height)
{
const unsigned char *endp;
const unsigned char *base;
int j;
endp = src + size;
for (base = endp - width; base < endp; base++) {
src = base;
for (j = 0; j < height; j++, src -= width)
{
*dst++ = *src;
}
}
}
//
// nv12 chroma plane is interleaved chroma values that map
// from one pair of chroma to 4 pixels:
//
// Y1 Y2 Y3 Y4
// Y5 Y6 Y7 Y8 U1,V1 -> chroma values for block Y1 Y2
// Y9 Ya Yb Yc Y5 Y6
// Yd Ye Yf Yg
// ----------- U2,V2 -> chroma values for block Y3 Y4
// U1 V1 U2 V2 Y7 Y8
// U3 V3 U4 V4
//
//////////////////////////////////////////////////////////
void rotateChromaPlane90(const unsigned char *src, unsigned char *dst,
size_t size, size_t width, size_t height)
{
// src will start at upper right, moving down to bottom
// then left 1 col and down...
//
// dest will start at end and go to 0
int row = 0;
int col = (int) width;
int src_offset = col - 1;
int dst_offset = (int) size - 2;
while (src_offset >= 0)
{
dst[dst_offset] = src[src_offset];
dst[dst_offset+1] = src[src_offset+1];
dst_offset -= 2;
src_offset += width;
row++;
if (row >= height) {
col -= 2;
src_offset = col;
row = 0;
}
}
}
И здесь является примером того, как я называю эти функции с родной от orroid:
// first rotate the Y plane
rotateLumaPlane90((unsigned char *) encode_buffer,
rotate_buffer,
yPlaneSize,
gInputWidth,
gInputHeight);
// now rotate the U and V planes
rotateChromaPlane90((unsigned char *) encode_buffer + yPlaneSize,
rotate_buffer + yPlaneSize,
yPlaneSize/2,
gInputWidth,
gInputHeight/2);
Обратите внимание, что последний параметр для rotateChromaPlane90
- высота оригинального изображения/2. Я должен, вероятно, просто изменить функцию поворота цветности, чтобы сделать это менее подверженным ошибкам.
Когда переворачивается на спину перед камерой, то я обнаружил, что мне нужно, чтобы повернуть 90 * в противоположном направлении (или 270 *), поэтому у меня есть 270 * изменение в качестве:
// rotate luma image plane 270*
//
// +-------------+
// |^ |
// |^ (base dir) |
// |^ |
// base -> +-------------+ <- endp
// ^
// <---------- |
// (dst dir) dst
//
//////////////////////////////////////////////////////////
void rotateLumaPlane270(unsigned char *src,
register unsigned char *dst,
int size, int width, int height)
{
unsigned char *endp;
register unsigned char *base;
int j;
endp = src + size;
dst = dst + size - 1;
for (base = endp - width; base < endp; base++) {
src = base;
for (j = 0; j < height; j++, src -= width)
{
*dst-- = *src;
}
}
}
//
// nv21 chroma plane is interleaved chroma values that map
// from one pair of chroma to 4 pixels:
//
// Y1 Y2 Y3 Y4
// Y5 Y6 Y7 Y8 U1,V1 -> chroma values for block Y1 Y2
// Y9 Ya Yb Yc Y5 Y6
// Yd Ye Yf Yg
// ----------- U2,V2 -> chroma values for block Y3 Y4
// U1 V1 U2 V2 Y7 Y8
// U3 V3 U4 V4
//
//////////////////////////////////////////////////////////
void rotateChromaPlane270(unsigned char *src,
register unsigned char *dst,
int size, int width, int height)
{
// src will start at upper right, moving down to bottom
// then left 1 col and down...
//
// dest will start at 0 and go til end
int row = 0;
int col = width;
int src_offset = col - 1;
int dst_offset = 0;
while (src_offset > 0)
{
dst[dst_offset++] = src[src_offset];
dst[dst_offset++] = src[src_offset+1];
src_offset += width;
row++;
if (row >= height) {
col -= 2;
src_offset = col;
row = 0;
}
}
}
Я решил это в моем android, но это в собственном коде, который я использую через JNI. Вы хотите увидеть решение на C++ или хотите только Java? – spartygw
Мне нужен собственный код, можете ли вы написать свой код здесь. благодаря – nkalra0123