视频/图像 倒置解决办法
本次推视频流从摄像头拿到的数据是RGB32的,在编码推流后,播放器播放出来是倒置的画面。
需要对原始数据进行数据倒转处理。如下
1 struct Rgb32Byte 2 { 3 uint8_t r; 4 uint8_t g; 5 uint8_t b; 6 uint8_t a; 7 }; 8 9 void VideoReadThread::RGB32ToYUV420P(unsigned char *src, unsigned char *dst, int Width, int height) 10 { 11 //解决图像倒置问题 12 Rgb32Byte *reb32Buf = (Rgb32Byte *)src; 13 std::reverse(reb32Buf, reb32Buf + Width*height); 14 15 unsigned char * dst_y_even; 16 unsigned char * dst_y_odd; 17 unsigned char * dst_u; 18 unsigned char * dst_v; 19 const unsigned char *src_even; 20 const unsigned char *src_odd; 21 22 int i, j; 23 src_even = (const unsigned char *)reb32Buf; 24 src_odd = src_even + Width * 4; 25 // it's planar 26 27 dst_y_even = (unsigned char *)dst; 28 dst_y_odd = dst_y_even + Width; 29 dst_u = dst_y_even + Width * height; 30 dst_v = dst_u + ((Width * height) >> 2); 31 // NB this doesn't work perfectly for u and v values of theedges of the video if your video size is not divisible by 2.FWIW. 32 33 for (i = 0; i < height / 2; ++i) { 34 for (j = 0; j < Width / 2; ++j) { 35 short r, g, b; 36 b = *src_even++; 37 g = *src_even++; 38 r = *src_even++; 39 ++src_even; 40 *dst_y_even++ = ((r * 66 + g * 129 + b * 25 + 128) >> 8) + 16; 41 42 short sum_r = r, sum_g = g, sum_b = b; 43 b = *src_even++; 44 g = *src_even++; 45 r = *src_even++; 46 ++src_even; 47 *dst_y_even++ = ((r * 66 + g * 129 + b * 25 + 128) >> 8) + 16; 48 49 sum_r += r; 50 sum_g += g; 51 sum_b += b; 52 53 b = *src_odd++; 54 g = *src_odd++; 55 r = *src_odd++; 56 ++src_odd; 57 *dst_y_odd++ = ((r * 66 + g * 129 + b * 25 + 128) >> 8) + 16; 58 59 sum_r += r; 60 sum_g += g; 61 sum_b += b; 62 b = *src_odd++; 63 g = *src_odd++; 64 r = *src_odd++; 65 ++src_odd; 66 *dst_y_odd++ = ((r * 66 + g * 129 + b * 25 + 128) >> 8) + 16; 67 sum_r += r; 68 sum_g += g; 69 sum_b += b; 70 71 // compute ave's of this 2x2 bloc for its u and v values 72 // could use Catmull-Rom interpolation possibly? 73 //http://msdn.microsoft.com/en-us/library/Aa904813#yuvformats_420formats_16bitsperpixel 74 // rounding by one? don't care enough... 39 ms - 36.8 75 //sum_r += 2; 76 //sum_g += 2; 77 //sum_b += 2; 78 // divide by 4 to average 79 sum_r /= 4; 80 sum_g /= 4; 81 sum_b /= 4; 82 *dst_u++ = ((sum_r * -38 - sum_g * 74 + sum_b * 112 + 128) >> 8) + 128; // only one 83 *dst_v++ = ((sum_r * 112 - sum_g * 94 - sum_b * 18 + 128) >> 8) + 128; // only one 84 } 85 dst_y_even += Width; 86 dst_y_odd += Width; 87 src_even += Width * 4; 88 src_odd += Width * 4; 89 } 90 }