通过 directshow 创建了一个 UYVY 图像,它已损坏,我不知道为什么
我有一个来自相机的 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);
}
更新 稍微改变一下
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 内部,然后我就得到黑屏:|
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 :|
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
指针数学很糟糕。将我的代码从 更改
为
并将 BPP 从 32 更改为 16,现在它可以顺利运行。
<_<
Pointer math sucks. Changed my code from
to
and changed BPP from 32 to 16 and it now works without a hitch.
<_<
为什么你的循环达到(720 * 1280),这是图片中每个像素的一次迭代,但在循环内你正在做Y和Y2。看起来不对。
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.