I have a buffer of UYVY data from a camera and i am using the GSSF Directshow.net filter to push the buffer through a graph.
The Graph at the moment is
GSSF -> YUV Transform -> AVI Splitter -> Video Renderer
The graph correctly calculates the color and is displaying it correctly but theres bars in the image that shouldn't be there and i am not sure where they are coming from. It hurts my eyes to stare at the image.
This function takes the UYVY buffer (mainbyte) and copies it to an array of integers
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;
}
This function takes that same array of integers and packs it into the GSSF stream pointer
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;
}
This sets up the bitmap compression for the output pin of the GSSF I think i may be doing something wrong here but it looks correct.
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 changed it 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
}
}
// 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;
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;
}
if i change the other numbers within GetImage to alter the height of the video, or if i chnge it inside of ImagePixel then i just get black screens :|
Pointer math sucks. Changed my code from
for (int f = 0; f < 720; f++)
{
for (int x = 0; x < (1280); x += 1)
{
*(bp + (f * 1280) + x) = mainbyte[f * 1280 + x];
}
}
to
Marshal.Copy(mainbyte, 0, ip, 1280*720);
and changed BPP from 32 to 16 and it now works without a hitch.
<_<
How comes your loop is up to (720 * 1280), that is one iteration for every pixel in the picture, but within the loop you're doing Y and Y2. It does not look right.
精彩评论