wiki

Pages imported from Elphel wiki

Licensing

The content below is downloaded from wiki.elphel.com/index.php?title=GNU_GPL_FAQ, copyright(s) of the source apply.


GNU GPL FAQ

From ElphelWiki

If your question is not covered here please post it in: Questions and Answers


The first topic to be covered is application of GNU GPL to Elphel products

Contents

Questions related to the licensing of Elphel products

On your web site you write that your products come with GNU GPL license. What does it mean for me as an end user? OEM?

GNU General Public License is designed to protect your freedom to modify and distribute covered programs and imposes restrictions to ensure that the recipients of your modifications will have the same rights as you do. That means that before you start to develop derivative products you have to carefully read the text of the license and make sure it is compatible with your plans.

Of course, if you do not have plans to distribute your modifications and intend to use Elphel products only internally, you may skip the reading of the legal stuff and are free to do whatever you like, modify any part of our products and keep all your secrets with you.

As far as I know GNU GPL is a software license. How is it applicable to your hardware?

Yes, text of the GNU GPL uses the term 'Program' as the covered object and is based on the copyright law that is not directly applicable to the hardware systems. But as more and more parts of the hardware are acquiring software features, more parts can be covered by the software licenses. Absolute majority of the hardware use some kind of a microprocessor that runs firmware and so do Elphel products. We use Axis ETRAX processors optimized for and running GNU/Linux operating system - most parts of it are also covered by GNU GPL. All of the specific software code designed for operating Elphel cameras is also released with the same license.

The high processing speed of Elphel cameras needed for video processing comes from the reconfigurable Xilinx FPGA devices. These devices can typically run 100 times faster than the general purpose processors, their reconfigurability makes it possible to change their code similar to microprocessor firmware. Usually FPGA code is developed using one of the hardware description languages such as Verilog or VHDL (Elphel products use Verilog) and so the code of these designs can be (and in our case is) protected by the GNU GPL.

Can I resell your products bundled with our proprietary software running on the connected computers without providing the source code?

Yes, you can. License that comes with Elphel cameras does not restrict your ability to use them with any types of software running outside of the camera. Of course you may still be bound by the GNU GPL if you base your software on the software provided on our Live DVD or any third party software that you receive with GNU GPL.

Can I install our proprietary software inside the camera and resell it as our product without providing the source code for our additions?

Usually yes, but that depends. As with any software running on GNU/Linux system you may install (and distribute) proprietary software without disclosing the source code if it is not compiled with or statically linked to the software cover by the GNU GPL.

Basically these are the same rules as with the computer running software covered with this license. What is legal on the computer is legal in the camera, what is not - is not.

All the Elphel software installed in the camera including drivers that provide processor interaction with the FPGA and the image sensors is covered by GNU GPL.

What about FPGA code? Can we add our own processing to it without disclosing our secrets?

No, it is not possible. You can use proprietary FPGA code in Elphel products only if you completely rewrite all the FPGA code from scratch, including host interface, interaction with the sensor, dedicated SDRAM memory and the system memory - not just the video compressor. No part of the Elphel FPGA code may be included with the proprietary closed-source replacement.

It is so because the current development software for the FPGA used in Elphel projects does not allow to combine separately compiled modules - all the code is synthesized from the source together, the placement is also inter-dependent. This prohibits to mix Elphel code covered by GNU GPL with closed one in the same chip.

So yes, it is possible but we would recommend to stay with GNU GPL - for those who develop such software that runs in or with Elphel cameras we exclude software development cost from the price of our cameras and provide our customers with a discount that can be combined with other discounts available for the cameras.

Can I resell your products with modified FPGA code?

I know some companies work with dual licensing. Can I buy a proprietary license to be able to resell you products as part of ours without providing of any source code to our customers?

GNU GPL is the only license that Elphel provides for our products and we do not sell licenses that allow licensee to close the source code. Our business model does not involve that source of compensation.

Do I have to pay Elphel any royalties if I will build my cameras using documentation provided by Elphel, Inc?

No, you do not have to pay any royalties to Elphel if you decide to clone Elphel camera or manufacture an improved derivative product. But in that case you will still be bound by the GNU GPL license for all parts of the firmware and/or hardware code that you plan to reuse and subject to all license compatibility issues described above.

What do I need to be able to resell your products (or our based on yours) in compliance with the license?

First of all you have to read the full text of the GNU GPL and take it seriously. Covered materials are not in the public domain and are protected by the copyright law of most countries. GPL itself describes what is required for compliance, you may also find this vendor FAQ and this source code FAQ useful. Below are specifics for Elphel products.

Even modified software in the cameras will have to run with GNU/Linux as it is the only software provided for the Axis CPU by the manufacturer. Of course, it is theoretically possible to port some non-free operating system to run in the camera or even write your own, but it is too time consuming to be practical. It would be much easier to modify the hardware to use some other CPU for which it is possible to purchase non-free operating system.

And as your device will run GNU/Linux you will need to provide the source code of at least that part of the software on the terms described in the license. Same applies to all of the software that you preserved in the cameras "as is" or modified from the Elphel firmware or any third party software that you obtained with the GNU GPL license.

You will also have to provide the source code of the FPGA - original developed by Elphel or possibly your amended version if you used any part of the original one. Forgive us for being suspicious if you claim that you completely rewrote the code and haven't used a single line of the one you received with the camera from Elphel - FPGA code of our products make a significant part of the value of the cameras and while it is easier to replace it than the GNU/Linux part of the firmware - we believe it is still far from an easy task.

We are proud of our designs and care that all users of our hardware receive the freedoms guaranteed by the GNU GPL and would like to help you to ensure license compliance and help to fix the problems if they would come out.

All of the Elphel products come with /* source inside */ (tm) logo and have the source code of all the firmware and the FPGA code sufficient to rebuild all the code and run it in the cameras. The only exception - sources of the Linux kernel and original Axis software (freely available on the Internet) that are too big to fit in the camera flash memory. We may help you to modify the script that will include your additions/modifications so you could provide the source code in the way we do ourselves.

How do you make money with the open designs?

You really want to know our secrets?

OK. First of all our products fill the virtual void on the market of the open hardware. Demand is still much higher than offer and people are willing to pay money for the systems they will be able to modify to their needs - it saves them a lot of resources when they can not find an exact fit on the market and the only other option would be a complete custom design. In recent years when the advance of GNU/Linux and free software became obvious for many, most companies are already using or planning to use it, they expect (and are actively looking for) similar solutions for the hardware.

Significant activity of the hobbyists who modify and improve the off-the-shelf devices, such as OpenWrt project indicates that many developers are eager to work in this area in spite of the difficulties of the usually not-so-good support from the hardware manufacturers.

Next - this business model helps startups as it helped Elphel when it was a one-man company. Open designs make it less risky for the customers to use the products and services for big projects, because even if the company goes under it will not take the project to it's grave. It may somewhat slow down new development but you always may continue it on your own or hire specialists who can take over the project.

Are we afraid of somebody cloning our products? Not really. There might be two types of cloning - illegal one if the clone will be distributed in violation of the GNU GPL and the fair one if the clone will be built and distributed in compliance with the license.

In the first case it will soon come out - now it is virtually impossible to keep your product (and the fact that it is a clone) secret from the Internet community. And even if that would be possible - the product will lack significant part of the features that originals have - features that depend on flexibility ensured by the openness.

Fair cloning or manufacturing of modified versions would not hurt us either. Software and FPGA code developed for compatible products would increase the value of our products too. And there will be code even if the cloning company would not develop code - better availability of the products would drive up number of independent developers. And sure we are constantly working on the new designs and periodically release the new better products.


10344

The content below is downloaded from wiki.elphel.com/index.php?title=10344, copyright(s) of the source apply.


10344

From ElphelWiki

10344

10344 CCD Interface Board is a part of Elplhel Model 353/363 Camera. It is designed to work together with the CCD Control Board (10347), both controlled by the 10353 processor board. This board is built around 16 Megapixel interline Kodak KAI-16000 CCD image sensor. This board include:

  • pin sockets for the KAI-16000 CCD image sensor (to facilitate sensor replacement)
  • a pair of pre-amplifiers of the CCD output signals
  • high-current amplifiers for CCD vertical phase drivers. These signals are multi-level, they are generated by a DAC on the 10347 board and then amplified on this board.
  • fast high-current drivers for horizontal phase signals - the AC component is generated by the switches with regulated input voltage, DC shift is added to it (for some signals - to the high level, for others - to the lower level) by the programmable bias voltage generator
  • bias voltage generator is used to provide DC bias for horizontal phase signals and the levels for DC signals required fro CCD operation. It uses multi-channel serial DAC (programmed by the signals generated by the FPGA on the 10347 board and operational amplifiers to provide required output voltage range for each signal.
  • substrate (erase) pulse generator provides a high voltage (>40V) pulse to erase pixels before the exposure

Connectors:

  • 10344 board has a single 40-pin connector (J5) in the middle of the board that links it to the 10347 board

10342

The content below is downloaded from wiki.elphel.com/index.php?title=10342, copyright(s) of the source apply.


10342

From ElphelWiki

10342

10342 CCD Interface Board is a part of Elplhel Model 353/363 Camera. It is designed to work together with the CCD Control Board (10347), both controlled by the 10353 processor board. This board is built around 11 Megapixel interline Kodak KAI-11002 CCD image sensor. This board include:

  • pin sockets for the KAI-11002 CCD image sensor (to facilitate sensor replacement)
  • a pair of pre-amplifiers of the CCD output signals
  • high-current amplifiers for CCD vertical phase drivers. These signals are multi-level, they are generated by a DAC on the 10347 board and then amplified on this board.
  • fast high-current drivers for horizontal phase signals - the AC component is generated by the switches with regulated input voltage, DC shift is added to it (for some signals - to the high level, for others - to the lower level) by the programmable bias voltage generator
  • bias voltage generator is used to provide DC bias for horizontal phase signals and the levels for DC signals required fro CCD operation. It uses multi-channel serial DAC (programmed by the signals generated by the FPGA on the 10347 board and operational amplifiers to provide required output voltage range for each signal.
  • substrate (erase) pulse generator provides a high voltage (>40V) pulse to erase pixels before the exposure

Connectors:

  • 10342 board has a single 40-pin connector (J5) in the middle of the board that links it to the 10347 board

10359

The content below is downloaded from wiki.elphel.com/index.php?title=10359, copyright(s) of the source apply.


10359

From ElphelWiki

Contents

10359

10359 is an optional multi-function board for Elplhel Model 353/363 Cameras. It can be connected between the 10353 Processor board and a sensor one (up to three sensor boards can be connected) This board has the same FPGA-DDR SDRAM pair as on the 10353 (Processor) board. It uses just one extra conductor in the flex cable to configure the on-board FPGA, rest of the JTAG programming interface pins share connections with the data signals. This board can fit in the standard camera enclosure (when only one sensor board is used) and does not interfere with the boards that use inter-board connectors (i.e. 10357) - the 10359 is mounted on the other side of the 10353 board.

10359 board can be used in the following applications (as well as other ones):

  • Additional custom image processing in the FPGA without the requirement to recompile the main FPGA on the 10353 board and solve possible conflicts with existent functionality.
  • multiplex several sensor boards (i.e. "day" - color and "night" - monochrome) to one 10353 camera board.
  • simultaneously acquire images from up to 3 sensors, compress them and send out one after another
  • extract 3-d information from multiple sensors in real time in FPGA
  • use additional sensor(s) to run correlation code (like in optical mice) to track camera orientation to compensate for the effect of Electronic_Rolling_Shutter
  • connect earlier sensor boards (with 3.3V interface) to the 10353 board. Interface voltage for the sensor boards can be switched from 2.5V to 3.3V (all 3 simultaneously)

Connectors:

  • 30-pin flex cable connector (J1) for data to/from the 10353 Processor board. It also receives 3.3V power through this connector
  • 3 of 30-pin flex cable connectors (J2, J3, J4) for the flex cables to the sensor boards (i.e. 10338, 10347)

Spartan3E:

Currently is available

1. Switching between 3 direct(w/o buffering in 10359 DDR) data streams from sensors.

2. Getting 2 frames from 2 sensors with programmed delay, one frame is being stored in DDR while the other is going directly through the fpga.

Tests

Projects with 10359


10357

The content below is downloaded from wiki.elphel.com/index.php?title=10357, copyright(s) of the source apply.


10357

From ElphelWiki

10357

10357 board is designed to provide a solid-state storage medium for 353/363-series cameras. It multiplexes the IDE bus (available from the 10353 board) between 4 master/slave pairs of CF cards configured to operate in IDE mode. With 8 of 16GB CF cards installed the 10357 board can provide 128GB of storage

On-board FPGA can be later configured to write data to several CF cards in parallel increasing the overall data rate.

In addition to the main function of CF storage 10357 can be also used for prototyping purposes. It has FPGA that is connected to auxiliary 30-pin connector and can be programmed by and can communicate with the software running on the main board. It has 4 groups of pairs of 50-pin headers, most pins are connected to individual FPGA pads and so can be programmed for a variety of I/O functions.


Elphel wiki:10338

The content below is downloaded from wiki.elphel.com/index.php?title=10338, copyright(s) of the source apply.


10338

From ElphelWiki

10338

10338 is designed to interface Aptina (before Micron) MT9P031/MT9P001 5MPix (2592x1944) sensor to Elplhel Model 353/363 Cameras. It is a first Elphel sensor board designed specifically to be compatible with 2.5V LVTTL interface in the 353 cameras. Earlier sensor boards need a redesign to limit output voltage swing to 2.5V required by the 10353 board.

Connectors:

  • 30-pin flex cable connector (J1) for data and power.

Imgsrv - Image server in Elphel cameras

The content below is downloaded from wiki.elphel.com/index.php?title=Imgsrv, copyright(s) of the source apply.


Imgsrv

From ElphelWiki

Contents

imgsrv - Simple and fast HTTP server to provide still images and metadata acquired by the camera

Overview

This server was developed to increase the transfer rate of individual images acquired by the Elphel 353 series cameras as the CGI (and even fastCGI applications) connected through the universal web servers (Boa, included with Axis SDK, currently on the default port 80 in camera and lighttpd - now used in Elphel cameras together with php in fast CGI mode, port 81) failed to reach the top speed of the 100mbps network. Specialized imgsrv is connected through a different port (currently listens to 8081) and writes GET responses directly to the socket (reading image data from the circbuf using zero-copy memory mapping mmap), reaching 9-10MB/sec - virtually the full bandwidth of the network. This server does not provide any control over the sensor or FPGA compressor operation, its only purpose is to get data acquired to the (currently 19 MB) circular buffer in the system RAM. It is intended to have the functionality similar to the camera video streamers that also deal with the data already being acquired to the system buffer to be used when individual images are needed rather than the continuous video stream .

The imgsrv makes use of the new functionality of the /dev/circbuf driver providing it with a convenient web front end. It serves JPEG images (with Exif data attached) as well as metadata and circbuf status formatting output as the xml files.

imgsrv usage

imgsrv listens to the camera http port (currently 8081) and parses the rest of the url string as a series of commands, i.e.:

http://<camera_ip>:8081/towp/save 
http://<camera_ip>:8081/torp/wait/img/next/save  

The above command will be interpreted as the following sequences:

First command (needed once):

  1. set the current image pointer after the last image acquired;
  2. save the pointer to the "global" (shared by all applications that use it) image pointer

Second command (to be repeated for each image to be transfered):

  1. set the current image pointer to the global read pointer stored in the driver;
  2. wait for the image at that pointer to become available (it is possible that no waiting will actually take place if the image acquisition is ahead of the reading images out process. As far as the image readout process does not fall behind too far (by the size of the circbuf) it is OK.
  3. transfer compressed image to the client
  4. advance frame pointer to the next one
  5. and finally - save the new pointer to the global read pointer, so that the same url can be used over and over each time providing the next acquired image

If issued with empty arguments (just http://<camera_ip>:8081/ ) imgsrv outputs a text file with the list of the valid commands.

Commands are separated from the server url and from each other by the slashes ("/"), "?" and "&" also work. Each command is interpreted sequentially, from the left to the right. The /dev/circbuf file stays open for all the command sequence, so local image pointer stays valid from one command to the other.

First group of the commands generates response data sent to the client, they are mutually exclusive and can appear only once in the command line (url). Each subsequent instances of such commands will be ignored. If none of the response-generating commands appear in the URL (but the url is not empty) the server will generate a minimalistic response - 1x1 pixel image. The commands of that group are the following:

  • img - send image at the current pointer (if it is the first command - use last acquired image - implied last command), if no image is available and the current pointer server will not wait for the image to be acquired (see wait below) but rather immediately return 1x1 GIF image to the client;
  • bimg -same as above, but the whole image is stored in the camera outside of the circbuf before being sent to the client. It makes it safe from being overwritten by the new frames acquired by the camera. This option is useful when the camera is accessed from outside of the fast LAN over the slow network, it is safer and is recommended if the full frame rate is not required;
  • meta - send XML-formated metadata of the current frame instead of the image;
  • pointers - send XML-formatted data about the circbuf frame pointers.

Next commands are designed on top of circbuf control commands:

  • torp - set frame pointer to the global read pointer, maintained by the camera driver. If frame at that pointer is invalid (i.e. overran by the next images), the scnd command (see below) is used instead;
  • towp - set frame pointer to hardware write pointer - position where next frame will be acquired;
  • prev - move to previous frame in buffer, nop if none are available;
  • next - move to the next frame in the buffer. Pointer will not go beyond write pointer that defines where the next frame will be acquired;
  • last - move to the most recently acquired frame, or to write pointer if there are none already acquiured. This command is automatically executed each time the imgsrv is called with a new line;
  • first - move to the oldest frame still available in the buffer. It is not safe to rely on it if more frames are expected - data might be overwritten at any moment and the output image/meta data will be corrupted;
  • second - move to the second oldest frame in the buffer - somewhat safer than the 'first' - there will be time for the "next" command at least before frame data (and pointer structures) will be overwritten;
  • save - save the current frame pointer as a global read pointer that holds it values between the server requests. This pointer is shared between all the clients and applications that use it;
  • wait - Delay execution until there will be a frame at the current pointer ready.

imgsrv and Exif data

imgsrv supports Exif format and includes frame metadata in the image header. The Exif headers are generated in several steps.

  • First, the Exif template (/var/state/exif.template) file is generated by the Exif_init.php script (during the system start up). The template generated is a binary file that is a valid Exif header itself. This script provides the "static" data (data that does not change between the frames), it also includes specific data that the script collects from various parts of the camera and camera software (like current firmware file name). Finally it provides a place holders for dynamic frame data to be replaced by the actual values by the imgsrv server;
  • Next step happens during initialization of the imgsrv. At that time the /var/state/exif.template is read in, parsed and the pointers to the Exif data that imgsrv is aware of are stored in as internal list together with the maximal string lengths that imgsrv may use.
  • Last step - imgsrv reads current frames meta data and uses it to fill the Exif fields at the pointers.

You may find documentation about Exif tags in Exif tags or download an official Exif2-2.PDF The fields that are currently updated by imgsrv are the following (all the other fields are preserved as they are generated by the Exif_init.php):

Tag IFD Key Type Description
0x0132IFD0 DateTimeASCIIDate/time of the image last modified. This field is likely to be modified later by image-processing software
0x9003IFD1 DateTimeOriginalASCIIDate/time of the image acquisition. Here - start of the frame readout (or start of the exposure where applicable)
0x9291IFD1 SubSecTimeOriginalASCIIFractional seconds (digits after the decimal point) to be added to DateTimeOriginal field, 6 digits
0x829aIFD1 ExposureTimeRATIONAL This field consists of 2 unsigned shorts that make exposure time (in seconds) as a rational number (the nominator divided by the denominator). With the current software denominator is a constant of 10000, imgsrv only updates the nominato
0x927cIFD1 MakerNoteBYTE This custom field is defined in the camera as 36 bytes, they are filled with raw frame metadata - structure frame_params_t defined in include/asm-cris/elphel/c313a.h. Bytes go in CPU order, so the data is little-endian (the rest is big-endian)

Circbuf - circular video buffer in Elphel cameras

The content below is downloaded from wiki.elphel.com/index.php?title=Circbuf, copyright(s) of the source apply.


Circbuf

From ElphelWiki

Contents

Circular buffer for the image/video data in Elphel 353 cameras: Description and access

Overview

Elphel cameras use FPGA to compress images and video, the compressed frames are transferred from the FPGA to the system memory through pseudo-DMA channel implemented in the CPU (Axis Etrax FS). It is "pseudo" as physically the data still goes (over the system bus) from the FPGA to the CPU chip, buffered there in small chunks and then sent to the system memory. Overall on average it takes 5 bus cycles (100MHz clock) to transfer one 32-bit word (4 bytes) of data from the FPGA to the system memory - 80MB/sec. There are hardware provisions in the model 353 to support new feature of ETRAX FS (not available in earlier ETRAX 100LX used in Elphel earlier models 303,313,323 and 333 cameras) - allowing external device (FPGA in our case) to become the bus master. That can allow to increase the data rate to virtually full 400MB/sec (in large bursts), but no FPGA code is yet developed to support this mode.

Circular buffer in Elphel 353 camera

The compressed frames are stored in the large circular buffer, it is done similar in the previous cameras and with other compressor (Ogg Theora) but the following description applies to the current state of the firmware (7.1.0.1) of the model 353 camera with JPEG compressor (Theora branch is not ported yet as of September 2007). Currently buffer size - CCAM_DMA_SIZE is ~19MB as defined in include/asm-cris/elphel/c313a.h).

All DMA transfers are 32-bytes aligned (32 bytes is a size of the internal DMA buffer in Etrax), and the data received from the FPGA contains JPEG-encode bit stream -- everything between SOF and EOF tags, no header, all 0xff data bytes escaped by appropriate 0x00 codes as required by the standard, so no 2 0xff bytes can appear together - this fact is used to find out if the data in the circular buffer was overwritten by the newer image frames.

When FPGA outputs the whole frame (it does not know the frame size in advance, only after compression is over) it adds 12 more bytes (3 long words), aligning them to the end of the 32-byte chunk, adding zeros before the data if needed. The last 4 bytes contain a 24-bit byte length of the JPEG data with the high byte set to 0xff. 8 bytes before (2 long words) have timestamp of the frame exposure start - seconds from epoch and microseconds.

The following listing has a sample of the buffer data (generated by the /usr/local/bin/test_mmap):

4b7ff8:  000000a4  06000800  016c0120  0a3946c1  01ab010a  40404040  ffff0000  000378fe
000000: {d30b03cc} 8af1dc34  a5875e77  9d4cf334  204db683  b1533cc7  c59f949e  36b1af45
000008:  90e20102  5e9ad7f1  f68cd273  130a1dc5  7e50641c  41bd14ef  140720c5  73c0e02e
...
00de38:  20a50766  4e433fc9  7614f51c  087bd2e4  988ee64e  cdf41ca0  6af40e1c  0000003b
00de40:  00000000  00000000  00000000  00000000  00000000  46ff4a82  000303bd <ff0378fe>
00de48:  f6285e9f  aeacb0a5  00000000  00000000  00000000  46ff4a81  000a1930  ff037929
00de50: [00000000] 00000000  00000000  00000000  00000000  00000000  00000000  00000000

The buffer is circular, so before 0 there is 0x4b7fff - last long word in the buffer). In this example FPGA compressed frame starting from the very beginning of the circbuf, bit stream is 0x378fe bytes long (as written in the 0x00de47 - OR-ed with 0xff000000) and it ends in the long word 0xde3f : "cc 03 0b d3 ... 1c 0e f4 6a 3b 00"

Timestamp - seconds=0x46ff4a82 and microseconds=000303bd are stored in the 0xde45 and 0xde46 - right before the bitstream length. Internal Etrax DMA ponter (circbuf write pointer) is now equal 0xde50 so the next frame will be acquired starting from that word. Data in the range 0xde48..0xde4f is garbage (you can see remnants from the other frame acquired starting from the same address 0x0 - "46ff4a81 000a1930 ff037929"). Actually FPGA already had sent 32 bytes (8 long words) of zeros - they are now in the ETRAX DMA buffer and will be written to 0xde48..0xde4f as soon as FPGA will start sending the next frame from address 0xde50. So the 32-byte spare area after (address-wise) the frame (it is used to make sure that all the current frame data, including timestamp+length is actually written to the system memory when the frame is finished without explicit flushing of the DMA buffer) can not be used, but it is possible to use it preceding the frame, and this is what is now implemented in the firmware of the 353 camera.

Frame metadata stored in the circbuf (added by the software)

The interrupt service routine arch/cris/arch-v32/drivers/elphel/cc353.c::camSeq_interrupt is responsible for

  • updating software pointer (JPEG_wp) after each new frame is compressed to match the location where next frame bitstream will be output,
  • copying the bitstream length before the frame itself (no simplify traversing frames) - it is now at 0x4b7fff (copied from 0xde4f lower 24 bits)
  • writing 2 of the 0xff bytes just before the length as a marker of valid frame header (incoming compressed bitstream data will never have two of 0xff bytes together, and the microsecond high byte, that might be written at that location is always 0)
  • filling in the 26 byte remaining area right before the last frame acquired - it is now safe until the whole buffer will be filled with image data. In the example above it starts at 0x4b7ff8.

The 26 (actually 28, as 0xffff marker is also included in the memcpy) bytes are copied from the data structure frame_params_t defined in include/asm-cris/elphel/c313a.h

struct frame_params_t {
/*00-03*/ unsigned long  exposure;       //! currently - exposure time measured in 100usec. Really need to change it to smaller increments?
/*04-05*/ unsigned short width;          //! frame width, pixels
/*06-07*/ unsigned short height;         //! frame height, pixels
/*08-11*/ unsigned long  colorsat;       //! matches FPGA format , for 1.0 it is DEFAULT_COLOR_SATURATION_RED<<16 + DEFAULT_COLOR_SATURATION_BLUE
/*12   */ unsigned char  color;          //! 0 - mono, 1 - color, 2 - jp4 + (0x40 - flipX) + (0x80 - flipY)
/*13   */ unsigned char  quality;        //! compression quality (%)
/*14   */ unsigned char  gamma;          //! (%), 255 - non-gamma curve, 0 - raw (16-bit data) - not yet implemented
/*15   */ unsigned char  black;          //! black level shift (255 - full scale)
/*16-17*/ unsigned short rscale;         //! 8.8 - red  relative to green - "gamma" table, not sensor gain
/*18-19*/ unsigned short bscale;         //! 8.8 - blue relative to green - "gamma" table, not sensor gain
/*20   */ unsigned char  gain_r;         //! color gain Red   (sensor specific), is set
/*21   */ unsigned char  gain_g;         //! color gain Green (sensor specific)
/*22   */ unsigned char  gain_b;         //! color gain Blue  (sensor specific)
/*23   */ unsigned char  gain_gb;        //! color gain Green in Blue line (sensor specific)
/*24   */ unsigned char  bindec_hor;     //! ((bh-1) << 4) | (dh-1) & 0xf (binning/decimation horizontal, 1..16 for each)
/*25   */ unsigned char  bindec_vert;    //! ((bv-1) << 4) | (dv-1) & 0xf (binning/decimation vertical  , 1..16 for each)
/*26-27*/ unsigned short signffff;       //! should be 0xffff - it will be a signature that JPEG data was not overwritten,
                                         //! JPEG bitstream can not have two 0xff after each other
/*28-31*/ unsigned long  timestamp_sec ; //! number of seconds since 1970 till the start of the frame exposure
/*32-35*/ unsigned long  timestamp_usec; //! number of microseconds to add
};

the last 8 bytes (imestamp_sec,imestamp_usec) are not copied - this information is provided by the FPGA following the bitstream (see above), these members of the structure can be used in a local copy in the application to store the time stamp data. By applying this data structure to the circbuf in the example above (this is just one line)

4b7ff8:  000000a4  06000800  016c0120  0a3946c1  01ab010a  40404040  ffff0000  000378fe

you may decode that

  • exposure was [0x4b7ff8] 0xa4*100usec= 0.0164 s,
  • frame width - 0x800 (2048)
  • frame height - 0x600 (1536)
  • saturation red is 016c (actually it is raw FPGA data proportional to actual saturation that was 2.0 in that case)
  • saturation blue is 0x120 (same note as above, also 2.0 - the scale for blue is different)
  • color/mirror mode was 0xc1 (normal color, flipX, flip Y)
  • JPEG quality - 0x46 (70%)
  • gamma - 0x39 - 0.57 (57%)
  • black level shift (subtracted from the pixels before gamma on 0..256 scale) - 0x0a (10)
  • rscale - 0x010a 0x01+(0x0a/0x100) - relative red-to-green scale used to build per-color component gamma tables
  • bscale - 0x01ab 0x01+(0xab/0x100) - relative blue-to-green scale used to build per-color component gamma tables
  • gain_r - 0x40 - analog gain setting of the sensor red pixels (hardware dependent, here 4.0x)
  • gain_g - 0x40 - same for green
  • gain_b - 0x40 - same for blue
  • gain_gb - 0x40 - same for green pixels in blue lines
  • bindec_hor - 0 - binning and decimation horizontal is 1/1 (no binning, no decimation)
  • bindec_vert - 0 - binning and decimation vertical is 1/1 (no binning, no decimation)

Circbuf data access - /dev/circbuf

User access to the circular buffer is provided by the /dev/circbuf device driver. It is now in arch/cris/arch-v32/drivers/elphel/circbuf.c. That device supports read, write, poll methods, but the most important are mmap and (overloaded) lseek. mmap provides direct access to the circbuf data, lseek is overloaded to include additional functions that are normally implemented in ioctl. It is a hack, of course, but gives easy access to the buffer data (and meta data) from the PHP scripts.

Normally lseek (also fseek, ftell) are designed to move file pointer and find out current pointer position. For example these functions can be used to determine the file size - move the file pointer to the end of file at read it value back. The last argument of lseek (fseek) function (called whence for some historical reasons) can take one of the 3 values:

  • SEEK_SET - passed offset value (2-nd argument) used directly as the new pointer position (i.e. fseek(file,0,SEEK_SET) would place the pointer at the very beginning of the file)
  • SEEK_CUR - relative movement of the file pointer. lseek(fp,0,SEEK_CUR) will return current position without modifying it (like ftell(file))
  • SEEK_END - move file pointer relative to the end of file, so any positive value of offset moves file pointer beyond the end of file. It is not considered to be an error - normal files can be written to beyond the current file length. This is not applicable to current implementation of the circbuf (it has a fixed size), so the SEEK_END with positive (>0) values of offset are used to perform several specific actions with the pointers to circbuf data and to wait for the next image to be acquired. Using SEEK_END with offset==0 (or negative) will have no difference to normal implementations, fseek(file, 0, SEEK_END) will move the file pointer just after the last byte in the circbuf. All the accesses with SEEK_CUR, SEEK_SET will use the fact that the buffer is circular - the file pointer will just roll over, so fseek (file, -2, SEEK_SET) will position the pointer just in front of the 2 last bytes of the circbuf.

The values for symbolic constants described below are defined in the include/asm-cris/elphel/c313a.h header file.

"Current pointer" or "selected frame" in the description below references to the file pointer of an opened file. As soon as the /dev/circbuf file is closed (usually happens between individual accesses through the web server), the value of such pointer is lost.

  • CIRCLSEEK_TORP - set file pointer to global (shared) read pointer. This pointer is maintained by the camera driver and preserves the value even when particular file access to circbuf is closed, it is valid for individual accesses to the camera through embedded web servers. But this pointer is the shared one, so it will have predictable values only if there is a single client to manipulate it.
  • CIRCLSEEK_TOWP - set file pointer to FPGA write pointer. This is the "hardware" pointer in the circbuf (next frame to be acquired). There is no frame available at that position in the circbuf, but it is a good place to wait for the next frame to come.
  • CIRCLSEEK_PREV - move frame pointer to the previous one (acquired just before the currently selected), the call will return an negative number -- error (-EOVERFLOW) if there are none frames in the buffer older than the currently pointed one. That can be the case if there are not enough frames acquired since last circbuf buffer reset or if the newer frames had overwritten the ones before the current.
  • CIRCLSEEK_NEXT - advance frame pointer to the next frame acquired, return -EOVERFLOW if was already at the last one (if the current pointer equals to the FPGA write pointer)
  • CIRCLSEEK_LAST - move pointer to the last acquired frame (default after open). It is similar to a combination of CIRCLSEEK_PREV after CIRCLSEEK_TOWP, but no error will be generated if there are no frames in the buffer - pointer will stay at FPGA write pointer.
  • CIRCLSEEK_FIRST - move pointer to the oldest acquired frame that still is available in the buffer. It is OK to browse through the frames in the buffer including that one when the image acquisition is stopped, but it is not safe to rely on this pointer if more frames are expected - next incoming frame can overwrite this one.
  • CIRCLSEEK_SCND - move pointer to the second oldest acquired frame. A slightly safer to use instead of CIRCLSEEK_FIRST when constant acquisition is on and sensor provides new frames - this frame will likely survive longer and give you a chance for the CIRCLSEEK_NEXT at least to buy some more time.
  • CIRCLSEEK_SETP - save current pointer to the global read pointer. This will allow to continue from the same frame next time the circbuf will be accessed as the global read pointer survives closing the circbuf file. But it is a global variable, so if several clients use this pointer they might interfere with each other.
  • CIRCLSEEK_VALID - verify that the frame at the current location is valid (not overrun in the buffer) Returns file pointer if valid, else - an error.
  • CIRCLSEEK_READY - verify the frame at current location is available (valid and acquired) Returns file pointer if ready, else - an error. If the file pointer was set to FPGA write pointer it will pass validation with CIRCLSEEK_VALID ( the pointer is still valid and not overrun by the later data), but will fail CIRCLSEEK_READY (frame is not ready), for all other pointers CIRCLSEEK_VALID and CIRCLSEEK_READY will give the identical result.
  • CIRCLSEEK_WAIT - this call will put the process to sleep until the image will be available at the current pointer. The actual sleep will take place only if the current pointer is equal to FPGA write pointer, in all other cases it will return immediately. If the pointer was invalid (i.e. overrun) the call will return with an error as there is no sense to wait for a frame here. If the pointer is valid but is not equal to write pointer - frame is already available and the call will return with current pointer immediately.
  • CIRCLSEEK_FREE - returnes remaining memory in circbuf from the current file pointer, or -EINVAL if the pointer is invalid. As this command uses the buffer write pointer that is updated only when the complete frame is in the buffer, the actual free memory may be less by a whole frame if compressor is running. Has a side effect of moving file pointer - should be saved/restored
  • CIRCLSEEK_USED - returnes memory used in the in circbuf from the current file pointer, or -EINVAL if the pointer is invalid. Has a side effect of moving file pointer - should be saved/restored

Reading JPEG headers

Circbuf buffer contains only the compressed bitstream and some metadata, JPEG headers that are needed for complete JPEG images are generated separately by the driver and can be read through the /dev/jpeghead device driver. This file supports read and lseek method among others, and SEEK_END is again overloaded with additional function - regenerating of the header (quantization tables and image size parameters) according to the metadata stored in the circbuf for the particular frame. This driver accepts frame pointer in the circbuf (that can be obtained with lseek/ftell calls to /dev/circbuf described in [Circbuf data access] section. Frames are always aligned to the 32-byte boundaries and lseek /dev/jpeghead with SEEK_END and positive offsets always zero out lower 5 bits so it is safer to provide offset=frame_pointer+1 to avoid offset of zero that will yield the file size when combined with SEEK_END, not the header recalculation.

This call will return an error if no valid frame exist at the current location (rounded down to the nearest 32 bytes).


Import Wiki

link=importwiki?title=Image:10369_bd.jpeg

Elphel wiki: 2008.RMLL.info_recording

The content below is downloaded from wiki.elphel.com/index.php?title=2008.RMLL.info_recording, copyright(s) of the source apply.


2008.RMLL.info recording

From ElphelWiki

Contents

Prefix

We had some contacts with organizers of http://2008.rmll.info/?lang=en and decided to participate recording all conferences with Elphel NC353L network cameras.

Goals

The goal is:

  • record all the conferences in high resolution. (from 640x480 to 1920x1080p)
  • restream few conferences in real time
  • upload ALL conferences on RMLL site and google video and as many support as possible.
  • keep high quality 1920x1080p MJPEG sources for all conferences what will be post processed.
  • have at least 1 camera per conference room and 2-4 camera for a very important conferences what will be post processed.
  • do all that with exclusively FreeSoftware

Hardware

This section will describe used hardware.

Cameras

We will bring 14 cameras with lenses and POE injectors.

POE injectors

We will bring POE injectors with us.

Lenses

We will use Computar H2Z0414C-MP Varifocal Lens, 4-8mm F1.4 Manual Iris Vari-Focal C-Mount, 3MPix. We will have 10-12 of such lense + 2 5MPix fisheyes. Maybe we will have some other good quality lenses.

PC

Requirement

If we do not want to stream or transcode in live a X40 IBM thinkpad or equivalent is OK.

If we do want to mux, transcode and stream in realtime a core2duo or quadro 2.4 Ghz and with 2GB RAM minimum is more welcome.

Microphones

Tripods

Network

Software

FreeSoftware

List of freesoftware needed to record video/audio, mux and stream.


Of course standard GNU/Linux

mencoder to record video

gstreamer-0.10 to record audio

ogmmerge from ogmtools to mux ogg vorbis sound produce by gstreamer and mjpeg video from mencoder

ffmpeg2theora to encode on theora ( minimum version is 0.19 )

oggfwd to send video and icecast server

icecast2 for streaming the ogg/theora file


On standard ubuntu 7.10 i've got all this software with apt-get.

Ubuntu Desktop

Special scripts for recording

Pure-Data patch


Here there is a simple patch for pure data to record, mux sound and stream on icecast server. You can download this patch here :

http://community.elphel.com/files/elencode.pd

Change the path of your need and launch this with pd name_you_choose.pd

Recording audio

To record audio there is new elphel cam with USB where you can plug USB microphone ( recommended SAMSON USB MIC ) BUT she is not avaivable for this events :( so we need to find solution to record audio.

The solution is a computer ... :(


For this we need standard computer with soundcard alsa compatible and gstreamer-0.10 software. To record audio i use this scripts made by luxigo.

#!/bin/sh

 # audio settings
 AUDIO_DEVICE="hw:0,0"
 AUDIO_BITRATE=48000

 # output file name
 OUTFILE="out.ogg"

 DEBUG="-v -m"

 gst-launch-0.10 $DEBUG \
 \
	oggmux name=mux \
	! filesink location="$OUTFILE" \
 \
	fdsrc fd=0 \
	! queue \
	! oggparse \
	! oggdemux \
	! ogmvideoparse \
	! mux. \
 \
	alsasrc \
		device="$AUDIO_DEVICE" \
	! queue \
	! audioconvert \
	! vorbisenc bitrate=$AUDIO_BITRATE \
	! mux.

 # Description of the gst-launch command above:

 # - the muxed stream (the output from the oggmux element) will be
 #   stored in a file (filesink)

 # - The video comes from ElphelOgm through stdin (fdsrc fd=0).
 # - The ogg stream is parsed for security (optional?) and demuxed.
 # - The ogmvideo stream is also parsed for security (optional?).
 # - The resulting mjpeg stream is sent to the ogg muxer through the
 #    "mux." element (defined with "oggmux name=mux"). 
 #   (This syntax could also be used for oggdemux but here there's only
 #   a single stream in the incoming ogg container so we dont need to
 #   complicate things here) 

 # - The sound comes from an alsa device through alsasrc,
 # - The sound is converted in a suitable format then encoded in vorbis,
 #   before being muxed with the video stream

Recording video

We've got different way to record video from elphel camera. The newest way to record is camogm/cam2ogm but we need nfs server or hard drive directly connected to the camera but we don't have camera with harddrive and nfs server is not what i prefer.. We can also use ElphelOgm but we are some artefact with this so i choose to use classic mencoder way to record video like this :

mencoder rtsp://ipcamera:554 -ovc copy -fps 24.99 -frames 250000 -o outputv.avi 

the option frames 250000 produce approximatively 2 hours of video on 1920x1088 format.

Muxing audio with video

To mux of audio and video we use ogmmerge from ogmtools like this :


ogmmerge -o sync.ogg out.ogg outputv.avi

There is an option -sync if you need an audio track synchronized.

 $ ogmmerge -o goodsync.ogm -A source.avi -s 200 outofsync.ogg

       This would add 200ms of silence at the beginning of  the  audio  tracks
       taken  from outofsync.ogg. And -s always applies to all audio tracks in
       a source file. If you want to apply -s only to a  specific  track  then
       take the same source file more than once and add -a and -s accordingly.

from man ogmmerge

Transcoding to Theora/Vorbis


For the the transcoding we use ffmpeg2theora ( minimum version 0.19 ) to encode the mjpeg and oggvorbis on the ogg/theora file.

cat sync.ogg | ffmpeg2theora -p preview -o final.ogg - 

Streaming


Finally to stream for the world we use icecast2 server.

Send the ogg/theora files with oggfwd like this.


cat final.ogg | oggfwd ip_of_icecast_server port password /stream.ogg 

Of course you need to configure icecast2 server before.


Syndicate content