输入数据是yuv,输出是flipyuv, uv分量是交替存储,uvsize刚好是height/2 * width, 下面的实现没有考虑stride的情况。
void CvtNV21FlipH(Mat& mYUV, Mat& mflipYUV) {
int width = mYUV.cols;
int height = mYUV.rows;
// flip Y data
for (int j = 0; j < height; j++) {
uint8_t* ydata = mYUV.data + (j+1)*width;
uint8_t* flipYdata = mflipYUV.data + j*width;
for (int i = 0; i < width; i++) {
int idx = width - 1 - i;
flipYdata[i] = ydata[idx];
}
}
//flip VU data
int yLen = width * height;
for (int j = 0; j < height/2; j++) {
uint8_t* vu = mYUV.data + yLen + (j+1)*width;
uint8_t* flipVU = mflipYUV.data + yLen + j*width;
for (int i = 0; i < width; i+=2) {
int idx = width - 2 - i;
flipVU[i] = vu[idx];
flipVU[i+1] = vu[idx+1];
}
}
}
下面的实现加上stride参数
因为是nv21, yvu420sp格式,vstride实际上是vu数据一行的宽度(width + stride), ystride就是Y分量一行的宽度(width + stride)
ystride = width + stride
vstride = width + stride;
输入参数h,w是输入图像的实际宽和高,矩阵的rows = h+h/2, cols = ystride,ystride大于等于w.
void CvtNV21FlipH(Mat& mYUV, int h, int w, int ystride, int ustride, int vstride, Mat& mflipYUV) {
int width = mYUV.cols;
int height = mYUV.rows;
// flip Y data
for (int j = 0; j < h; j++) {
uint8_t* ydata = mYUV.data + (j+1)*ystride;
uint8_t* flipYdata = mflipYUV.data + j*ystride;
for (int i = 0; i < w; i++) {
int idx = w - 1 - i;
flipYdata[i] = ydata[idx];
}
}
//flip VU data
int yLen = ystride * h;
for (int j = 0; j < h/2; j++) {
uint8_t* vu = mYUV.data + yLen + (j+1)*vstride;
uint8_t* flipvu = mflipYUV.data + yLen + j*vstride;
for (int i = 0; i < w; i+=2) {
int idx = w - 2 - i;
flipvu[i] = vu[idx];
flipvu[i+1] = vu[idx+1];
}
}
}