I have an IP Camera that receives a char buffer containing an image over the network. I cant access it until i setup the connection to it in a program. I am trying to dissect windows source filter code and im not going very fast so i thought i’d ask if it was possible to just take a buffer like that and cast it to something that could then connect a pin to AVISplitter or such in Directshow/.net
(video buffer from IP Cam) -> (???) -> (AVI Splitter) -> (Profit)
Update
I have my program capturing video in a namespace, and i have this code from the GSSF in its own namespace. I pass a ptr with an image from the cam namespace to the GSSF namespace. This only occurs once, but the graph streams from this one image, and the camera streams from the network. is there a way to continually pass the buffer from cam to GSSF or should i combine the namespaces somehow? I tried sending the main camera pointer to the GSSF but it crashed because its accessing the pointer and its being written. maybe if i grabbed an image, passed the pointer, waited to grab a new one?
*Update*
I shrunk my code and I don’t believe im doing the namespace correctly either now that i look at it.
namespace Cam_Controller
{
static byte[] mainbyte = new byte[1280*720*2];
static IntPtr main_ptr = new IntPtr();
//(this function is threaded)
static void Trial(NPvBuffer mBuffer, NPvDisplayWnd mDisplayWnd, VideoCompression compressor)
{
Functions function = new Functions();
Defines define = new Defines();
NPvResult operationalResult = new NPvResult();
VideoCompression mcompressor = new VideoCompression();
int framecount = 0;
while (!Stopping && AcquiringImages)
{
Mutex lock_video = new Mutex();
NPvResult result = mDevice.RetrieveNextBuffer(mBuffer, operationalResult);
if(result.isOK())
{
framecount++;
wer = (int)mDisplayWnd.Display(mBuffer, wer);
main_ptr = (IntPtr)mBuffer.GetMarshalledBuffer();
Marshal.Copy(main_ptr, mainbyte, 0, 720 * 2560);
}
}
}
private void button7_Click(object sender, EventArgs e)
{
IntPtr dd = (IntPtr)mBuffer.GetMarshalledBuffer();
Marshal.Copy(dd, main_byte1, 0, 720 * 2560);
play = new VisiCam_Controller.DxPlay.DxPlay("", panel9, main_byte1);
play.Start();
}
namespace DxPlay
{
public class DxPlay
{
public DxPlay(string sPath, Control hWin, byte[] color)
{
try
{
// pick one of our image providers
//m_ImageHandler = new ImageFromFiles(sPath, 24);
m_ImageHandler = new ImageFromPixels(20, color);
//m_ImageHandler = new ImageFromMpg(@"c:\c1.mpg");
//m_ImageHandler = new ImageFromMpg(sPath);
//m_ImageHandler = new ImageFromMP3(@"c:\vss\media\track3.mp3");
// Set up the graph
SetupGraph(hWin);
}
catch
{
Dispose();
throw;
}
}
}
abstract internal class imagehandler
internal class imagefrompixels
{
private int[] mainint = new int[720 * 1280];
unsafe public 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 = V << 16 | Y << 8 | U;
int two = V << 16 | Y2 << 8 | U;
mainint[p * 2 + 0] = one;
mainint[p * 2 + 1] = two;
}
m_FPS = UNIT / FPS;
m_b = 211;
m_g = 197;
}
}
}
}
Theres also GetImage but thats relatively the same, copy the buffer into the pointer. What happens is i grab a buffer of the image and send it to the DxPlay class. it is able to process it and put it on the directshow line no problems; but it never updates nor gets updated because its just a single buffer. If i instead send DxPlay a IntPtr holding the address of the image buffer, the code crashes for accessing memory because i assume ImageFromPixels code ( which isn’t there now ( change
(x[p * 4 + #])
to
(IntPtr)((x-passed as an IntPtr).toInt64()+p*4 + #)
))
is accessing the memory of the pointer as the Cam_Controller class is editing it. I make and pass copies of the IntPtrs, and new IntPtrs but they fail halfway through the conversion.
If you want to do this in .NET, the following steps are needed:
Use the DirectShow.NET Generic Sample Source Filter (GSSF.AX) from the Misc/GSSF directory within the sample package. A source filter is always a COM module, so you need to register it too using “RegSvr32 GSSF.ax”.
Implement a bitmap provider in .NET
Setup a graph, and connect the pin from the GSSF to the implementation of the bitmap provider.
Pray.
I am using the following within a project, and made it reusable for future usage.
The code (not the best, and not finished, but a working start) (this takes a IVideoSource, which is bellow):
IVideoSource:
ImageVideoSource (mostly taken from DirectShow.NET examples):
RawVideoSource (an example of a concrete managed source generator for a DirectShow pipeline):
And the interops to the GSSF.AX COM:
Good luck, try to get it working using this. Or comment with further questions so we can iron out other issues.