У меня есть код, который будет передавать видео с камеры на 720p и 24fps. Я пытаюсь захватить этот поток в коде и в конечном итоге создать его видео, объединяя сжатые файлы jpeg в mjpeg и т.п. Проблема, с которой я столкнулся, заключается в том, что этот общий код недостаточно быстр, чтобы создать что-то со скоростью 24 кадра в секунду или 0,04 секунды на изображение.
используя
Stopwatch();
Я обнаружил, что внутренний цикл for занимает 0,00000000000022 секунды на цикл.
Внешний цикл for занимает 0,0000077 секунды на цикл.
и я обнаружил, что вся функция с самого начала для сохранения изображения выполняется 0,21 секунды на запуск.
вычисления из внутреннего цикла для завершения изображения:
.000000000022 x 640 = .000000001408 seconds
.000000001408 x 360 = .00000050688 seconds
вычисления из внешнего цикла для завершения изображения:
.0000077 x 360 = .002772 seconds
Если бы я мог создать изображение, относящееся к тем временам, я был бы установлен, но код, выполняющий весь код, занимает 0,21 секунды для завершения всего кода
temp_byte1 = main_byte1;
temp_byte2 = main_byte2;
timer1.Reset();
timer1.Start();
Bitmap mybmp = new Bitmap(1280, 720);
BitmapData BPD = mybmp.LockBits(new Rectangle(0, 0, 1280, 720), ImageLockMode.WriteOnly, mybmp.PixelFormat);
IntPtr xptr = BPD.Scan0;
IntPtr yptr = BPD.Scan0;
yptr = new IntPtr( yptr.ToInt64() + (1280 * 720 * 2));
int bytes = Math.Abs(BPD.Stride);
byte[][] rgb = new byte[720][];
int Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8;
int U1, U2, V1, V2, U3, U4, V3, V4;
for (int one = 0; one < 360; one++)
{
timer2.Reset();
timer2.Start();
rgb[one] = new byte[bytes];
rgb[360 + one] = new byte[bytes];
for (int two = 0; two < 640; two++)
{
timer3.Reset();
timer3.Start();
U1 = temp_byte1[one * 2560 + 4 * two + 0];
Y1 = temp_byte1[one * 2560 + 4 * two + 1];
V1 = temp_byte1[one * 2560 + 4 * two + 2];
Y2 = temp_byte1[one * 2560 + 4 * two + 3];
U2 = temp_byte2[one * 2560 + 4 * two + 0];
Y3 = temp_byte2[one * 2560 + 4 * two + 1];
V2 = temp_byte2[one * 2560 + 4 * two + 2];
Y4 = temp_byte2[one * 2560 + 4 * two + 3];
RGB_Conversion(Y1, U1, V1, two * 8 + 0, rgb[one]);
RGB_Conversion(Y2, U1, V1, two * 8 + 4, rgb[one]);
RGB_Conversion(Y3, U2, V2, two * 8 + 0, rgb[(360 + one)]);
RGB_Conversion(Y4, U2, V2, two * 8 + 4, rgb[(360 + one)]);
timer3.Stop();
timer3_[two] = timer3.Elapsed;
}
Marshal.Copy(rgb[one], 0, xptr, 5120);
xptr = new IntPtr(xptr.ToInt64() + 5120);
Marshal.Copy(rgb[(360 + one)], 0, yptr, 5120);
yptr = new IntPtr(yptr.ToInt64() + 5120);
timer2.Stop();
timer2_[one] = timer2.Elapsed;
}
mybmp.UnlockBits(BPD);
mybmp.Save(GetDateTimeString("IP Pictures") + ".jpg", ImageFormat.Jpeg);
код работает и преобразует входящий массив байтов yuv422 в полноразмерный jpeg, но не может понять, почему существует такое несоответствие между скоростью циклов for и всего кода
Я переместил
byte[][]rgb = new byte[720];
rgb[x] = new byte[bytes];
в глобал, который получает init при запуске программы вместо каждого вызова / запуска функции без заметного увеличения скорости.
UPDATE
Преобразование RGB: принимает в YUV, преобразует его в RGB и помещает в глобальный массив, содержащий значения
public void RGB_Conversion(int Y, int U, int V, int MULT, byte[] rgb)
{
int C,D,E;
int R,G,B;
// create the params for rgb conversion
C = Y - 16;
D = U - 128;
E = V - 128;
//R = clamp((298 x C + 409 x E + 128)>>8)
//G = clamp((298 x C - 100 x D - 208 x E + 128)>>8)
//B = clamp((298 x C + 516 x D + 128)>>8)
R = (298 * C + 409 * E + 128)/256;
G = (298 * C - 100 * D - 208 * E + 128)/256;
B = (298 * C + 516 * D + 128)/256;
if (R > 255)
R = 255;
if (R < 0)
R = 0;
if (G > 255)
G = 255;
if (G < 0)
G = 0;
if (B > 255)
B = 255;
if (B < 0)
B = 0;
rgb[MULT + 3] = 255;
rgb[MULT + 0] = (byte)B;
rgb[MULT + 1] = (byte)G;
rgb[MULT + 2] = (byte)R;
}