This is version 2.0 of the driver for the Eurotech E0904 JPEG2000 frame grabber. It was developed and tested under Linux 2.6.18 (and will support newer kernels of course). The drivers supports encoding, decoding and HIPI (both encoded data and raw images come from the host).
After unpacking the source distribution you have to compile the kernel module and the user libraries:
cd linux make KERNELDIR=[path to your kernel tree] cd .. cd linux_user make
Just use the script load.sh to load the kernel module and create the devices. You will get 4 devices:
/dev/e0904-0enc /dev/e0904-0dec /dev/e0904-1enc /dev/e0904-1dec
The devices refer to the two PLX9056-ADV202 available on the board. For now only encoding is implemented, so you will use those with the enc suffix.
The module (and load.sh) accepts the following parameters:
vbuffer_pages number of pages (4096) to allocate for the video buffer.
vbuffer_images number of images that can be stored in the video buffer. Note that the following formula should hold for efficiency:
vbuffer_pages * 4096 >= vbuffer_images * max_image_size
max_image_size can be set using the quality parameter of test_encode for example (see below).
quiet suppress all warnings (for example automatic reset of the ADV202 when it gets stuck).
3.1 test_encode
In the directory linux_user there is the test_encode program. It is a good programming example of the library (see below) but also a powerful utility for testing the board. It can be easily used from HLL like Python so, for example, a simple monitoring system can be written using it.
test_encode accepts command either via command line arguments or standard input. The syntax is:
test_encode [device] [commands ...]
Keep in mind that every argument entry is a command, so you have to use the ' character (on a bourne shell) to group them. You can obtain the following list of commands with:
test_encode /dev/e0904-0enc help quit
Here is the list:
noise:/mnt/nfs/jpeg2000/linux_user# ./test_encode /dev/e0904-0enc help quit Available commands: (*) means must restart encoding to take effects -> every [arg1] [arg2] takes a shot every [arg1] frames and saves to a file with prefix [arg2] -> fw [arg1] (*) pathname of firmware to use -> help this help -> shot [arg1] takes a shot of a picture to filename [arg1] -> stat display statistics: running status, frames got, dropped, resets -> start starts encoding -> stop stops encoding -> quit exits this application -> verbose [arg1] if [arg1] is 0 be quiet, if 1 show just errors, if 2 be verbose -> wait [arg1] wait [arg1] frames before continuing -> quality [arg1] [arg2] (*) applies scheme [arg1] to quality of generated images. [arg1] = 0 no truncation [arg1] = 1 images are +/- 5% of dimensions specified by [arg2] [arg1] = 2 [arg2] is the quality factor (best = 0x100, very bad = 0x900) -> norm [arg1] (*) [arg1] can be pal, ntsc, pali, ntsci -> mon1 [arg1] monitor path full channel [arg1] -> mon4 [arg1] [arg2] [arg3] [arg4] monitor path 4 channel [arg1]-[arg4] -> mon8 [arg1] [arg2] [arg3] [arg4] [arg5] [arg6] [arg7] [arg8] monitor path 8 channel [arg1]-[arg8] -> rec1 [arg1] record path to full channel [arg1] is 0-7 -> rec4 [arg1] record path for master([arg1] = 0) or slave([arg1] = 1) to quad -> brightness [arg1] [arg2] set brightness of channel [arg1] to [arg2] -> contrast [arg1] [arg2] set contrast of channel [arg1] to [arg2] -> hue [arg1] [arg2] set hue of channel [arg1] to [arg2] -> clear clear AP5200 video memory -> osd_clear [arg1] clear OSD, [arg1] is 0 for monitor, 1 for record master, 2 for record slave -> osd_write [arg1] [arg2] [arg3] [arg4] [arg5] write OSD, [arg1] is 0 for monitor, 1 for record master, 2 for record slave [arg2],[arg3] are x,y coordinates [arg4] is the string to write *WITHOUT* spaces [arg5] is the color, 0 default, 0x100 yellow, 0x200 blue, 0x300 red -> slave_path [arg1] [arg1] = 1 sets the record path for the slave AP52000 -> init_board Initializes companion chips to the ADV202 -> noinit_board Simulates the initializaion of the board. Useful is already initialized. -> msleep [arg1] sleeps [arg1] ms -> skip [arg1] skips [arg1] frames between 2 acquired pictures in hardware. [arg1] is in the range 0-63. -> motion_enable [arg1] enables motion detection on channel [arg1] -> motion_enable_sf [arg1] [arg2] [arg3] [arg4] [arg5] [arg6] [arg7] [arg8] [arg9] [arg10] enables motion detection on channel. args: [ch] [show] [accumulate] [TH_L] [TH_H] [TH_motion] [TH_blind] [TH_win] [REF_catch] [sel_TH_motion] -> motion_enable_f [arg1] [arg2] [arg3] [arg4] [arg5] [arg6] [arg7] [arg8] [arg9] [arg10] [arg11] [arg12] [arg13] [arg14] [arg15] [arg16] [arg17] [arg18] [arg19] [arg20] [arg21] [arg22] enables motion detection on channel. args: [ch] [show] [accumulate] [TH_L] [TH_H] [TH_motion] [TH_blind] [TH_win] [REF_catch] [sel_TH_motion] [win 1-12] -> motion_disable [arg1] disables motion detection on channel [arg1] -> motion_status motion status -> motion_status_fast motion status (fast and incomplete version) OK
For example you can monitor channels 0,2,4,6 and acquire just one snapshot from channel 1 with the following command:
./test_encode /dev/plx0enc init_board 'mon4 0 2 4 6' 'rec1 1' 'msleep 2000' clear start 'msleep 1000' 'shot prova.jp2' stop quit
Please note that if you move test_encode outside the standard directory structure from the tarball you have to use the firmware command to tell the library where to find it.
The generated .jp2 file can be converted with the jasper library to some well known format:
jasper --input prova.jp2 --input-format jp2 --output prova.pnm --output-format pnm --force-srgb
Syntax:
test_decode [dev] [n sec] [jp2 images .....]
This program reads the given jp2 files and displays them in sequence for n seconds. The channel 0 of the AP5200 is put in playback mode.
Please note that on the E0904 only the slave ADV202 can be used for decoding/playback.
Syntax:
test_loop [enc dev] [dec dev] [firmware] [mode: 0=loop, 1=encode 2=decode] [pmode] [xtot] [ytot] [images ...]
This is an example of the HIPI mode, this means that both raw image and encoded data come from or go to the host. For this reason you have to specify both the encoding end the decoding device.
With the correct firmware and the mode parameter you can specify if you want to encode or decode the given images. pmode is the format of the raw data. Supported formats are:
0x14 | 4x8-bit Single Component |
0x15 | 4x8-bit Packed YCbYCr |
0x16 | 4x8-bit Packed YYCbCr |
0x17 | 4x8-bit Packed CbCrCbCr |
0x18 | 2x16-bit Packed Single Compon |
0x19 | 2x16-bit Packed YCb/YCr |
0x1A | 2x16-bit Packed YY/CbCr |
0x1B | 2x16-bit Packed CbCr |
For more information refer to the ADV202 data sheet. xtot and ytot are respectively the total number of bytes per line and the number of lines. xtot is twice the horizontal resolution for color images, otherwise it's thew same value.
libe0904.a and libe0904.h help the programmer to use the driver without knowing the details of the low level interface.
struct e0904_ch;
This structure is opaque to the user and represents a PLX9056/ADV202 couple.
struct e0904_ch* simple_e0904_encoder(char *dev);
Allocates, initializes and returns an encoder structure. dev is the device name (/dev/e0904-0enc for example).
int simple_e0904_board_init(struct e0904_ch *e, int isNtsc, char *fw, ETHJPG2K_FIRMWARE_DATA *fwdata, ETHJPG2K_FIRMWARE_PARAMS *fwparams, int slave_path);
Initializes the chips on the board (AP5200 and the SAAs) and sets the default parameters for the ADV202 (they are applied only when the encoder is started). Please note that the AP5200 is initialized only if the video norm changed. This is important to avoid interrupting the video data flow to one of the two ADV202s when the other is started. The parameters are:
e the encoder instance.
isNtsc 1 if using NTSC.
fw the file name of the firmware.
fwdata the data specific for the firmware. Please note that fields about the firmware are automatically updated by the library. The only field you should set for HIPI is Type which is used to distinguish between encoding (FW_HIPI_ENCODE) and decoding (FW_HIPI_DECODE).
typedef struct _ETHJPG2K_FIRMWARE_DATA { unsigned char bSlave; unsigned char Type; unsigned short FirmwareId; unsigned long* pFirmware; unsigned long FirmwareSizeInDwords; PETHJPG2K_FIRMWARE_PARAMS pFirmwareParameters; } ETHJPG2K_FIRMWARE_DATA, *PETHJPG2K_FIRMWARE_DATA;
fwparams defines the parameters used by the ADV202 when encoding. Please refer to the ADV202 manual for the exact meaning of the fields:
typedef struct _ETHJPG2K_VIDEO_ENCODE_FIRMWARE_PARAMS { unsigned char VFORMAT; //Video Standard; unsigned char PREC; //Precision; unsigned char XFORMLEV; //Wavelet Transform Levels; unsigned char UNI; //Component Polarity; unsigned char CBSIZE; //Codeblock Dimensions; unsigned char WKERNEL_QUANT; //Wavelet Kernel; unsigned char STALLPAR; //SkipFields; unsigned char ATTRTYPE; //Attribute Output Format; unsigned char RCTYPE; //Rate Control; unsigned char RCVAL[3]; //Target Size Or Quality; unsigned char J2KPROG; //J2K Progression; unsigned char PICFG; //Pixel If Config; unsigned char QFACT; //Quantize Factor; unsigned char COD_STYLE; //Code Output Format; unsigned short STEPSIZES[19]; //Quantize Stepsizes; unsigned char LOAD_SS; unsigned char LOAD_VW; //Visual Weight Options; unsigned short VW_Y; //Y_Visual Weight Factor; unsigned short VW_CB; //Cb_VisualWeightFactor[19]; unsigned short VW_CR; //Cr_VisualWeightFactor[19]; unsigned char RESERVED[6]; unsigned long LayersTargets[16]; //Target Size or Target Quality } ETHJPG2K_VIDEO_ENCODE_FIRMWARE_PARAMS, *PETHJPG2K__VIDEO_ENCODE_FIRMWARE_PARAMS; typedef struct _ETHJPG2K__VIDEO_DECODE_FIRMWARE_PARAMS { unsigned char VFORMAT; //Video Standard; unsigned char PREC; //Precision; unsigned char RESERVED_0; unsigned char UNI; //Component Polarity; unsigned char RESERVED_1[5]; unsigned char PICFG; //Pixel If Config; unsigned char DRES; //Decode Resolution Settings; unsigned char COD_STYLE; //Code Input Format; } ETHJPG2K_VIDEO_DECODE_FIRMWARE_PARAMS, PETHJPG2K_VIDEO_DECODE_FIRMWARE_PARAMS;
The parameters are presented in a union so you should use just those pertinent to the operation (encoding, decoding) that you are using. In HIPI mode there you have specify some more parameters, please refer to the section about the test_loop utility for an explanation of these parameters.
typedef struct _ETHJPG2K_HIPI_FIRMWARE_PARAMS { unsigned short XTOT; // number oy bytes per line unsigned short YTOT; // number of lines per frame unsigned char PMODE; // pixel format union { ETHJPG2K_VIDEO_ENCODE_FIRMWARE_PARAMS EncodeParams; ETHJPG2K_VIDEO_DECODE_FIRMWARE_PARAMS DecodeParams; } sub; } ETHJPG2K_HIPI_FIRMWARE_PARAMS, *PETHJPG2K_HIPI_FIRMWARE_PARAMS; typedef union _ETHJPG2K_FIRMWARE_PARAMS { ETHJPG2K_VIDEO_ENCODE_FIRMWARE_PARAMS EncodeParams; ETHJPG2K_VIDEO_DECODE_FIRMWARE_PARAMS DecodeParams; ETHJPG2K_HIPI_FIRMWARE_PARAMS HipiParams; } ETHJPG2K_FIRMWARE_PARAMS, *PETHJPG2K_FIRMWARE_PARAMS;
A suitable set of defaults values is provided in the test_encode.c example. Have a look at the “quality” command to see how to determine the size of the output JP2 image and it's quality (RCTYPE and RCVAL fields). Another parameter that can be easily changed is STALLPAR, which defines how many frames are skipped by ADV202 between to captured pictures. This trick considerably lowers the process load if you don't need full frame-rate. See the “skip” command in test_encode.
slave_path if set to 1 the slave AP52000 is connected to the secondary ADV202. It must be so when using this second encoder.
void simple_e0904_board_noinit(struct e0904_ch *e, int isNtsc);
This is a dummy function that sets the internal norm to that given *without* reprogramming the AP5200. This is useful to avoid interrupting primary video stream when starting the secondary.
int simple_e0904_encoder_run(struct e0904_ch* e, e0904_frame_cb cb); typedef int (*e0904_frame_cb) (struct ethjpg2k_linux_hdr *hdr, unsigned char * data, unsigned long len);
This is the signature of the callback that the user has to implement. It is called for every grabbed frame. If the function returns a value different to 0 the encoding is terminated (and the value is returned by simple_e0904encoderrun). The parameters:
hdr is a header that describes the grabbed picture (in .jp2 JPEG2000 format). The public fields are:
struct ethjpg2k_linux_hdr { unsigned long field; unsigned long index; union { unsigned long info; struct { unsigned char version; unsigned char reserved; unsigned char videoFormat; unsigned char codeFormat; } Info_s; } Info_u; unsigned long size; unsigned int overflow; };
For the first 4 (counting the union as a field) consult the ADV202 since it's the header passed by the hardware. overflow is the number of pictures dropped by the driver since there was no space in the buffer.
data a pointer to the jp2 encoded picture.
len the length (in bytes) of the jp2 encoded picture.
int simple_e0904_ioctl(struct e0904_ch* e, int code, void *arg);
With this call it's possible to modify the configuration of the ADV202 and other chips on the e0904. Please see the next section for a list and explanation on available IOCTLs and corresponding data types.
void simple_e0904_free(struct e0904_ch* e);
This function simply destroys resources of the given encoder instance.
void simple_e0904_force_stop(struct e0904_ch* e);
With this function the encoding process is forcibly terminated. It can be useful when the encoder cannot produce valid frames (for example the slave_path is not configured) so the user callback in not invoked and cannot ask the encoding engine to stop.
int simple_e0904_decoder_run(struct e0904_ch* e, e0904_len_cb cbl, e0904_frame_in_cb cbf, int add_hdr) typedef void (*e0904_frame_in_cb) (unsigned char * data, unsigned long len); typedef int (*e0904_len_cb) (void);
This function works in a similar way as the encoding one but you have to provide 2 callbacks. With *cbl* you can reserve a given space for the image you are going to decode. This is needed since the image length isn't fixed. If you return a negative value the decoding process will stop. The second callback is used for passing the image bits. You have to store them in to the area at address pointed by data and length len.
Another important parameter is add_hdr. If this is true an ADV202 header is automatically prepended to the image bits. This header is required for the ADV202 to work.
int simple_e0904_hipi(struct e0904_ch *enc, struct e0904_ch *dec, char *fw, ETHJPG2K_FIRMWARE_DATA *fwdata, ETHJPG2K_FIRMWARE_PARAMS *fwparams, int n, char **in, int *ins, char **out, int *outs) {
This function has a different way of working since HIPI mode is most suited to off-line processing. You have to create 2 struct e0904_ch objects one for the encoding device and one for the decoding.
You have to pass the function the number of images you want to encode/decode (n), the arrays of pointers to the input bits and theirs length (in and ins) and the arrays of pointers to output space and the length that will be set by the library.
It's important to keep in mind that the encoding/decoding works 1.5 frames “behind”, so when the ADV202 is fed the second bunch of data it outputs the firs one. So the last image should be considered “dummy”.
It may happen under some for circumstances (for example the video output missing for too much time) that the ADV202 stops the encoding process. In this case the encoding function exit with an error. You should retry to restart the encoding process a couple of time before giving up. Have a look at the test_decode example to see how this can be done.
If after a number of repetition (for example 5) the encoding doesn't start it's most likely that there is some problem on the video input or you have given an invalid parameter to the firmware. So it's recommended that you try to use the default ones and change them one at a time until you find the guilty value.
All the ioctls take a pointer to the data type described (when not explicitly stated otherwise).
5.1 AP5200 MODE MANAGEMENT
IOCTL_ETHJPG2K_VIDEO_SET_MODE
Is used to initialize the working mode of the 2 AP52000s. They are working together in a master-slave configuration so the monitor output can show any of the 8 available input channels. The record paths are split. The channels 0-3 are connected to the primary ADV202, the remaining (4-7) to the secondary. Please note that changing the working mode of the AP5200 interrupts the data flow to the ADV202. The driver has an auto-reset feature that recovers from this situation but it's advisable to stop the encoding before changing AP5200 mode and restart it afterwards.
typedef struct _AP5200_MODE_PARAMS { unsigned char Mode; union { struct { unsigned char Channel[4]; /*set 4 channels from left top clockwise*/ } MON_QUAD; struct { unsigned char Channel; } MON_FULL; struct { unsigned char Channel[8]; /*set 8 channels from left top clockwise*/ } MON_ALL; struct { unsigned char bSlave; } REC_QUAD; struct { unsigned char Channel; } REC_FULL; }; } AP5200_MODE_PARAMS, *PAP5200_MODE_PARAMS;
Using the *Mode* parameter you can select the mode of operation.
MODE_MON_QUAD Shows 4 channels on the monitor Path. Channel range is 0-7 and you can specify 4 of them.
MODE_MON_FULL Shows one channes on the monitor Path. Channel range is 0-7.
MODE_MON_ALL Shows 8 channels on the monitor Path. Channel range is 0-7 and you can specify 8 of them.
MODE_REC_QUAD Put the given AP5200 in 4-channel mode (bSlave is 0 for master (channels 0-3) or 1 for slave (channels 4-7)).
MODE_REC_FULL Connects just one channel to the encoder path. Channels 0-3 are connected to the primary ADV202, 3-7 to the secondary.
IOCLT_ETHJPG2K_VIDEO_CLEAR
Clears AP5200 video buffer.
5.2 AP5200 OSD
Each of the following ioctls comes in 3 flavors. Every one of them is applied to a different path: monitor, primary record and secondary record.
IOCTL_ETHJPG2K_MONITOR_ENABLE_OSD, IOCTL_ETHJPG2K_RECORD_MST_ENABLE_OSD, IOCTL_ETHJPG2K_RECORD_SLV_ENABLE_OSD.
Enable the OSD on the given path. Please note that normal initialization enable them by default so this ioctl is not very useful. The ioctl accepts an array of 3 AP5200_COLOR:
typedef struct _AP5200_COLOR { unsigned char Y; unsigned char Cb; unsigned char Cr; } AP5200_COLOR;
These are used in the OSD write ioctl (see below). At initialization the color selected are yellow, blue and red.
IOCTL_ETHJPG2K_MONITOR_DISABLE_OSD, IOCTL_ETHJPG2K_RECORD_MST_DISABLE_OSD, IOCTL_ETHJPG2K_RECORD_SLV_DISABLE_OSD.
The OSD of the path is disables.
IOCTL_ETHJPG2K_MONITOR_WRITE_OSD, IOCTL_ETHJPG2K_RECORD_MST_WRITE_OSD, IOCTL_ETHJPG2K_RECORD_SLV_WRITE_OSD.
These are used to write a OSD string on the given path. The argument is:
typedef struct _AP5200_OSD_PARAMS { unsigned char x; unsigned char y; char* String; unsigned short StrLen; unsigned short Color; } AP5200_OSD_PARAMS, *PAP5200_OSD_PARAMS;
where:
x and y are coordinates (the screen is 34x22).
String and *StrLen* are respectively the string to show and it's length.
Color selects which color to use. 0x100 for the firs defined, 0x200 for the second and 0x300 for the third. By default they are yellow, blue and red
5.3 SAA7113 VIDEO ENCODER CONTROL
IOCTL_ETHJPG2K_VIDEO_SET_BRIGHTNESS, IOCTL_ETHJPG2K_VIDEO_SET_CONTRAST, IOCTL_ETHJPG2K_VIDEO_SET_HUE
Each of these ioctls (which control brightness, contrast and hue as you might guess) accepts an array of 2 C char. The first element is the channel to act on (range 0-7), the second the value for the parameter (range 0-255).
5.4 OTHER BOARD MANAGEMENT IOCTLS
IOCTL_ETHJPG2K_SET_SLAVE_PATH
Enables the connection between the slave AP5200 and the secondary ADV202. It takes an int that can have the values 0 or 1. When capturing channels 4-7 you have to put it to 1. When doing playback (decoding a JP2 stream) to 0.
IOCLT_ETHJPG2K_VIDEO_PLAYBACK
This IOCTL enables the playback of the video stream from the secondary. You have to specify which channel is used for playback (this is useful in monitoring multiple channels), if you want to enable or disable this feature and if you are using NTSC video norm (otherwise PAL is assumed).
typedef struct _AP5200_PLAYBACK { unsigned char dest_ch; unsigned char enable; unsigned char isNtsc; } AP5200_PLAYBACK, *PAP5200_PLAYBACK;
5.5 MOTION DETECTION
IOCTL_ETHJPG2K_MOTION_ENABLE, IOCTL_ETHJPG2K_MOTION_DISABLE
Are used to enable or disable the motion detection in a given window of a given channel. The argument is a pointer to AP5200_MOTION_ENABLE_CH
typedef struct _AP5200_MOTION_ENABLE_CH { unsigned char ch; unsigned char show; unsigned char accumulate; unsigned char TH_L; unsigned char TH_H; unsigned short TH_motion; unsigned short TH_blind; unsigned char TH_win; unsigned char REF_catch; unsigned char sel_TH_motion; unsigned short Windows[12]; } AP5200_MOTION_ENABLE_CH, *PAP5200_MOTION_ENABLE_CH;
ch is the channel on which the operation applies.
Windows defines which is the sensible part. Each channel image is dived in a 16x12 grid. Each bit in every unsigned short from Windows defines which blocks in the given row are sensible to movement.
show if asserted the motion status is displayed on monitor path.
REF_catch is the interval (in number of frames) between updates of the reference image.
accumulate states if image changes during a REF_catch interval are accumulated.
TH_L, TH_H, TH_motion and sel_TH_motion are the parameter for the Alogic motion detector engine. Please see the Alogics data sheet for further information or the example program (test_encode) for a set of example parameters.
TH_win is the number of elements of the image grid that sense a movement needed to trigger a motion detection.
TH_blind is the threshold of the sigma value (see next IOCTL) under which a blind camera condition is triggered.
IOCTL_ETHJPG2K_MOTION_GET_STATUS, IOCTL_ETHJPG2K_MOTION_GET_STATUS_FAST
Returns the current status (and resets it for further readings). The argument is a pointer to AP5200_MOTION_STATUS. The non fast IOCTL fills all the fields of this structure, instead the other one just updates the fields MotionDetected and BlindDetected. On the other hand the first is slow (it takes 20ms for each active channel plus fixed 20ms due to an internal synchronization requirement of the Alogics AP5200). Please note that after the call to this function the reference image is updated.
typedef struct _AP5200_MOTION_STATUS_CH { unsigned char MotionDetected; unsigned char BlindDetected; unsigned int sigma; unsigned short Windows[12]; } AP5200_MOTION_STATUS_CH, *PAP5200_MOTION_STATUS_CH; typedef struct _AP5200_MOTION_STATUS { AP5200_MOTION_STATUS_CH ch[8]; } AP5200_MOTION_STATUS, *PAP5200_MOTION_STATUS;
Only the entries in array ch from AP5200_MOTION_STATUS which refers to enabled channels are meaningful. For each channel
Motion Detected is 1 if a motion has been detected, otherwise 0.
Blind Detected is 1 if a situation of blind camera has been detected, otherwise 0.
sigma is a value that represent the complexity of the image and is used in blind camera detection.
Windows tells which block in the grid has caused the motion detection. Refer to the description of IOCTL_ETHJPG2K_MOTION_ENABLE for an explanation on the meaning of this returned value.
5.6 GPIOs
IOCTL_ETHJPG2K_GPIO_READ, IOCTL_ETHJPG2K_GPIO_WRITE
Both of these function work with an argument of a pointer to an array of 2 unsigned chars. The first one is always the number of which GPIO bank are we referring (0/1). For write the second one is the value to set, for read instead is the returned value which represents the state of the pins.
You may want to directly access the device driver without passing through the library interface. This chapter describes how to do this. You should have a look at the library code for an example of the concepts described here.
It's important to know that for every ADV202 in the system there are 2 device inodes, one for encoding and one for decoding. For example if you have just one E0904 card in the system:
minor | function |
---|---|
0 | first ADV202 encoding |
1 | first ADV202 decoding |
2 | second ADV202 encoding |
3 | second ADV202 decoding |
The encoding one always outputs data (usually JPEG2000 encoded but in HIPI decode mode they are raw image bits), the decoding always accepts data.
6.1 MEMORY MAPPED INTERFACE
For efficiency (avoiding data copies) the data buffer is shared between kernel and user level. You have to map it via a mmap function cal. The dimension of this buffer is set by the module load parameters. The arbitration to the buffer is done via read and write system calls.
6.2 USING READ AND WRITE
When accessing an encoding device (so receiving data from the driver) an user level program has to:
read a struct ethjpg2k_linux_hdr. This call blocks until an image is available.
the struct contains the following fields: field is 0xfffffff0 or 0xfffffff1 depending if frame is even or odd in an interlaced stream. index the current frame number.
Info_u describes the attributes of the frame (see ADV202 data sheet for more information).
size is the size (in bytes) of the acquired image.
start is the location in the mmaped area of the image.
overflow is the number of image lost since last read (if we don't keep up with the pace of image acquired).
ticket is a number that has to be written to the device when finished.
You can do everything you want with the image starting at start and of length size in the mmaped area.
Write the 32-bit word to the device. The buffer is now free for the driver to be used and you should not touch it.
The procedure for reading from a decoding device is quite similar:
Read a struct ethjpg2k_linux_decode. It has just 2 fields: start the starting address of free space in the buffer and size the amount of available bytes. * Check that size is enough. If it is put your image starting at start in the mmaped buffer.
Write a struct ethjpg2k_linux_decode but now size should be the actual size of the picture you are sending to the decoding device.
6.3 AUXILIARY IOCTLS
Here are listed the IOCTLs that useful only if your directly interacting with the driver without using the helper library.
IOCTL_ETHJPG2K_LINUX_INIT
This IOCTL initializes the companion chips on the E0904. Should be called before any attempt to encode/decode a video stream.
IOCTL_ETHJPG2K_ENCDEC_START
The encoder/decoder is started.
IOCTL_ETHJPG2K_ENCDEC_STOP
The encoder/decoder is stopped.
IOCTL_ETHJPG2K_LINUX_GETBSIZE
The size (in pages) of the buffer for the acquisition of images is returned.
For any problems, bug reports and bug fixes or improvements please contact Christian Pellegrin ‹chripell@gmail.com›.