У меня есть буфер данных UYVY с камеры, и я использую фильтр GSSF Directshow.net, чтобы протолкнуть буфер через график.
График на данный момент составляет
GSSF -> YUV Transform -> AVI Splitter -> Video Renderer
График правильно вычисляет цвет и отображает его правильно, но на изображении нет полос, которых не должно быть, и я не уверен, откуда они берутся. Мне больно смотреть на изображение.
Эта функция берет буфер UYVY (основной байт) и копирует его в массив целых чисел
unsafe public void ImageFromPixels__()
{
byte[] x = mainbyte;
long fff = 720 * 1280;
mainptr = new IntPtr(fff);
for (int p = 0; p < 720 * 1280; p++)
{
U = (x[p * 4 + 0]);
Y = (x[p * 4 + 1]);
V = (x[p * 4 + 2]);
Y2 = (x[p * 4 + 3]);
// int one = V << 16 | Y << 8 | U;
// int two = V << 16 | Y2 << 8 | U;
int one = Y2 << 24 | V << 16 | Y << 8 | U;
// mainint[p * 2 + 0] = one;
// mainint[p * 2 + 1] = two;
mainint[p] = one;
}
m_FPS = UNIT / 20;
m_b = 211;
m_g = 197;
}
Эта функция берет тот же массив целых чисел и упаковывает его в указатель потока GSSF
override unsafe public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead)
{
int hr = 0;
if (iFrameNumber>-1)
{
if (iFrameNumber < MAXFRAMES)
{
ImageFromPixels_(20, mainbyte);
m_g += 3;
m_b += 7;
int* bp = (int*)ip.ToPointer();
Random k = new Random();
StreamReader s = new StreamReader("jpegFile.txt");
for (int f = 0; f < HEIGHT; f++)
{
for (int x = 0; x < (WIDTH); x += 1)
{
*(bp + (f * WIDTH) + x) = mainint[f * 1280 + x];
}
}
}
else
{
hr = 1; // End of stream
}
}
iRead = iSize;
return hr;
}
Это устанавливает сжатие растрового изображения для выходного контакта GSSF
Я думаю, что я могу делать что-то не так, но это выглядит правильно.
override public void SetMediaType(IGenericSampleConfig psc)
{
BitmapInfoHeader bmi = new BitmapInfoHeader();
// Build a BitmapInfo struct using the parms from the file
bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
bmi.Width = WIDTH;
bmi.Height = HEIGHT * -1;
bmi.Planes = 1;
bmi.BitCount = BPP;
bmi.Compression = 0x59565955; //UYVY
bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height;
bmi.XPelsPerMeter = 0;
bmi.YPelsPerMeter = 0;
bmi.ClrUsed = 0;
bmi.ClrImportant = 0;
int hr = psc.SetMediaTypeFromBitmap(bmi, m_FPS);
DsError.ThrowExceptionForHR(hr);
}
UPDATE
изменил abit
override unsafe public int GetImage(int iFrameNumber, IntPtr ip, int iSize, out int iRead)
{
int hr = 0;
if (iFrameNumber>-1)
{
if (iFrameNumber < MAXFRAMES)
{
ImageFromPixels_(20, mainbyte);
m_g += 3;
m_b += 7;
int* bp = (int*)ip.ToPointer();
Random k = new Random();
StreamReader s = new StreamReader("jpegFile.txt");
for (int f = 0; f < 720; f++)
{
for (int x = 0; x < (1280); x += 1)
{
*(bp + (f * 1280) + x) = mainint[f * 1280 + x];
}
}
}
else
{
hr = 1; // End of stream
}
}
//
переопределить public void SetMediaType (IGenericSampleConfig psc)
{
BitmapInfoHeader bmi = new BitmapInfoHeader ();
// Build a BitmapInfo struct using the parms from the file
bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
bmi.Width = WIDTH;
bmi.Height = HEIGHT * -1;
bmi.Planes = 1;
bmi.BitCount = BPP;
bmi.Compression = 0x59565955;
bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height;
bmi.XPelsPerMeter = 0;
bmi.YPelsPerMeter = 0;
bmi.ClrUsed = 0;
bmi.ClrImportant = 0;
int hr = psc.SetMediaTypeFromBitmap(bmi, m_FPS);
DsError.ThrowExceptionForHR(hr);
}
//
unsafe public void ImageFromPixels_(long FPS, byte[] x)
{
long fff = 720 * 1280 * 3;
mainptr = new IntPtr(fff);
for (int p = 0; p < 720 * 640; p++)
{
U = (x[ p * 4 + 0]);
Y = (x[p * 4 + 1]);
V = (x[p * 4 + 2]);
Y2 = (x[p * 4 + 3]);
int one = Y2 << 24 | V << 16 | Y << 8 | U;
//int one = V << 16 | Y << 8 | U;
//int two = V << 16 | Y2 << 8 | U;
//mainint[p * 2 + 0] = one;
//mainint[p * 2 + 1] = two;
mainint[p] = one;
}
m_FPS = UNIT / FPS;
m_b = 211;
m_g = 197;
}
если я изменю другие числа в GetImage, чтобы изменить высоту видео, или если я изменю его внутри ImagePixel, тогда я просто получу черные экраны: |