/// <summary> /// Creates a buffer to be used with Video4Linux streaming I/O. /// </summary> /// <param name="adapter">The parental Video4Linux device.</param> /// <param name="buffer">The struct holding the buffer information.</param> internal Buffer(Analog.Adapter adapter, v4l2_buffer buffer) { this.adapter = adapter; this.buffer = buffer; mapMemory(); }
/// HACK: we should read until we reached count /// HACK: offset is ignored private int readMM(byte[] buffer, int offset, int count) { if (!adapter.Capabilities.Contains(AdapterCapability.Streaming)) throw new Exception("Device does not support streaming."); v4l2_buffer buf = new v4l2_buffer(); buf.type = adapter.Buffers[0].Type; buf.memory = adapter.Buffers[0].Memory; // read one image if (adapter.IoControl.DequeueBuffer(ref buf) == 0) { Analog.Buffer dbuf = adapter.Buffers[(int)buf.index]; // max length = buffer length if ((int)dbuf.Length < count) count = (int)dbuf.Length; // copy all the data from the buffer Marshal.Copy(dbuf.Start, buffer, 0, count); // re-enqueue the buffer dbuf.Enqueue(); return count; } return 0; }
/// <summary> /// Queries the device for information about each requested buffer. /// </summary> /// <param name="req">Struct with information about the request buffers.</param> private void fetchBuffers(v4l2_requestbuffers req) { for(uint i=0; i < req.count; i++) { v4l2_buffer buffer = new v4l2_buffer(); buffer.index = i; buffer.type = req.type; buffer.memory = req.memory; if(ioControl.QueryBuffer(ref buffer) < 0) throw new Exception("VIDIOC_QUERYBUF"); buffers.Add(new Analog.Buffer(this, buffer)); } }
/// <summary> /// Calls VIDIOC_QBUF. /// </summary> public int EnqueueBuffer(ref v4l2_buffer buffer) { return ioctl(deviceHandle, v4l2_operation.EnqueueBuffer, ref buffer); }
/// <summary> /// Calls VIDIOC_QUERYBUF. /// </summary> public int QueryBuffer(ref v4l2_buffer buffer) { return ioctl(deviceHandle, v4l2_operation.QueryBuffer, ref buffer); }
ioctl(int device, v4l2_operation request, ref v4l2_buffer argp);
/// <summary> /// Tries to dequeue a buffer and fires the 'BufferFilled' event if the buffer was filled by the driver. /// </summary> private void captureFromBuffers() { v4l2_buffer buf = new v4l2_buffer(); buf.type = Buffers[0].Type; buf.memory = Buffers[0].Memory; while (ioControl.DequeueBuffer(ref buf) == 0) { Analog.Buffer dbuf = Buffers[(int)buf.index]; // invoke the event if (BufferFilled != null) BufferFilled(this, dbuf); // re-enqueue the buffer dbuf.Enqueue(); } }
private static extern int ioctl(int device, v4l2_operation request, ref v4l2_buffer argp);