Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

camerav4l2.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  */
00018 //
00019 // Desc: Video for Linux 2 capture driver
00020 // Author: Marcin Rudowski
00021 // Email: mar_rud@poczta.onet.pl
00022 // Date: 19 Jun 2006
00023 //
00025 
00267 #include <player.h>
00268 
00269 #include <errno.h>
00270 #include <string.h>
00271 #include <math.h>
00272 //#include <stdlib.h>       // for atoi(3)
00273 #include <netinet/in.h>   // for htons(3)
00274 #include <unistd.h>
00275 
00276 #include <player/driver.h>
00277 #include <player/devicetable.h>
00278 #include <player/drivertable.h>
00279 #include <player/playertime.h>
00280 #include <player/error.h>
00281 
00282 #include "v4l2capture.h"  // help for capturing and accessind device
00283 
00284 // Time for timestamps
00285 extern PlayerTime *GlobalTime;
00286 
00287 
00289 class CameraV4L2 : public Driver
00290 {
00292     public: CameraV4L2( ConfigFile* cf, int section);
00293 
00295     public: virtual int Setup();
00297     public: virtual int Shutdown();
00298 
00300     private: virtual void Main();
00301 
00303     private: int HandleRequests();
00304 
00306     private: void WriteData();
00307 
00309     private: const char *device;
00310 
00312     private: const char *sourceCh;
00313     private: int source;
00314 
00316     private: v4l2_std_id norm;
00317 
00319     private: int depth;
00320 
00322     private: int width, height;
00323 
00325     enum v4l2_field fieldType;
00326 
00327     unsigned int v4l2_type_id;
00328 
00329     int flip_rb;
00330 
00331     int showFPS;
00332 
00334     private: FRAMEGRABBER2* fg;
00335 
00337     private: uint32_t tsec, tusec;
00338 
00340     private: player_camera_data_t data;
00341 
00342 
00343     private:
00345         int selectNorm(const char *snorm);
00346         int selectFormat(const char *sformat);
00347         int selectField(const char *sfield);
00348 
00349         int numOfCtls;
00350         const char **ctlNames;
00351         double *ctlVals;
00352 
00353         int tryPixelSettings(FRAMEGRABBER2* fg, int w, int h, unsigned int fmt, enum v4l2_field fld);
00354 
00356         int handleCommand(char *cmd, int len);
00357         int handleCommand(char *cmd, int len, char *reply, int rlen);
00358 
00360         int back_source;
00361         v4l2_std_id back_norm;
00362         int back_depth;
00363         int back_width;
00364         int back_height;
00365         enum v4l2_field back_fieldType;
00366         unsigned int back_v4l2_type_id;
00367 };
00368 
00369 
00371 Driver* CameraV4L2_Init( ConfigFile* cf, int section)
00372 {
00373     return ((Driver*) (new CameraV4L2( cf, section)));
00374 }
00375 
00376 
00378 void CameraV4L2_Register(DriverTable* table)
00379 {
00380     table->AddDriver("camerav4l2", CameraV4L2_Init);
00381 }
00382 
00383 
00385 // Extra stuff for building a shared object.
00386 
00387 /* need the extern to avoid C++ name-mangling  */
00388 extern "C" {
00389     int player_driver_init(DriverTable* table)
00390     {
00391         puts("Camerav4l2: Registering driver");
00392         CameraV4L2_Register(table);
00393         puts("Camerav4l2 driver registered");
00394         return(0);
00395     }
00396 }
00397 
00398 
00399 
00403 struct NormsList {
00404     const char *name;
00405     v4l2_std_id id;
00406     int width;
00407     int height;
00408 } normy[] = {
00409     { // first is default
00410         "PAL",
00411         V4L2_STD_PAL,
00412         768,
00413         575,
00414     },{
00415         "NTSC",
00416         V4L2_STD_NTSC,
00417         640,
00418         480,
00419     },{
00420         "SECAM",
00421         V4L2_STD_SECAM,
00422         640,//??
00423         480,
00424     },{
00425         0, 0, 0, 0// do not delete this
00426     }
00427 };
00428 
00432 struct FormatsList {
00433     const char *name;
00434     unsigned int player_type_id;
00435     unsigned int v4l2_type_id;
00436     unsigned int bits;
00437 } formaty[] = {
00438     { /* 24  RGB-8-8-8     */
00439         // first and default value
00440         "RGB24",                        //ffname
00441         PLAYER_CAMERA_FORMAT_RGB888,    //player_type_id
00442         V4L2_PIX_FMT_RGB24,             //v4l2_type_id
00443         24,                             //bits
00444     },{/* 32  RGB-8-8-8-8   */
00445         "RGB32",                         //ffname
00446         PLAYER_CAMERA_FORMAT_RGB888,     //player_type_id
00447         V4L2_PIX_FMT_RGB32,              //v4l2_type_id
00448         32,                              //bits
00449     },{/* 24  BGR-8-8-8     */
00450         "BGR24",                        //ffname
00451         PLAYER_CAMERA_FORMAT_RGB888,    //player_type_id
00452         V4L2_PIX_FMT_BGR24,             //v4l2_type_id
00453         24,                             //bits
00454     },{/* 32  BGR-8-8-8-8   */
00455         "BGR32",                         //ffname
00456         PLAYER_CAMERA_FORMAT_RGB888,     //player_type_id
00457         V4L2_PIX_FMT_BGR32,              //v4l2_type_id
00458         32,                              //bits
00459     },{/*  8  Greyscale     */
00460         "GREY",                         //ffname
00461         PLAYER_CAMERA_FORMAT_MONO8,     //player_type_id
00462         V4L2_PIX_FMT_GREY,              //v4l2_type_id
00463         8,                              //bits
00464     },{/* 16  RGB-5-6-5     */
00465         "RGB565",                        //ffname
00466         PLAYER_CAMERA_FORMAT_RGB565,     //player_type_id
00467         V4L2_PIX_FMT_RGB565,             //v4l2_type_id
00468         16,                              //bits
00469     },{/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
00470         "SBGGR8",                        //ffname
00471         PLAYER_CAMERA_FORMAT_MONO8,     //player_type_id
00472         V4L2_PIX_FMT_SBGGR8,             //v4l2_type_id
00473         8,                              //bits
00474     },{/*  8  RGB-3-3-2     */
00475         "RGB332",                        //ffname
00476         PLAYER_CAMERA_FORMAT_MONO8,     //player_type_id
00477         V4L2_PIX_FMT_RGB332,             //v4l2_type_id
00478         8,                              //bits
00479     },{/* 16  RGB-5-5-5     */
00480         "RGB555",                        //ffname
00481         PLAYER_CAMERA_FORMAT_RGB565,     //player_type_id
00482         V4L2_PIX_FMT_RGB555,             //v4l2_type_id
00483         16,                              //bits
00484     },{/* 16  RGB-5-5-5 BE  */
00485         "RGB555X",                        //ffname
00486         PLAYER_CAMERA_FORMAT_RGB565,     //player_type_id
00487         V4L2_PIX_FMT_RGB555X,             //v4l2_type_id
00488         16,                              //bits
00489     },{/* 16  RGB-5-6-5 BE  */
00490         "RGB565X",                        //ffname
00491         PLAYER_CAMERA_FORMAT_RGB565,     //player_type_id
00492         V4L2_PIX_FMT_RGB565X,             //v4l2_type_id
00493         16,                              //bits
00494     },{/*  9  YVU 4:1:0     */
00495         "YVU410",                        //ffname
00496         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00497         V4L2_PIX_FMT_YVU410,             //v4l2_type_id
00498         16,                              //bits
00499     },{/* 12  YVU 4:2:0     */
00500         "YVU420",                        //ffname
00501         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00502         V4L2_PIX_FMT_YVU420,             //v4l2_type_id
00503         16,                              //bits
00504     },{/* 16  YUV 4:2:2     */
00505         "YUYV",                        //ffname
00506         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00507         V4L2_PIX_FMT_YUYV,             //v4l2_type_id
00508         16,                              //bits
00509     },{/* 16  YUV 4:2:2     */
00510         "UYVY",                        //ffname
00511         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00512         V4L2_PIX_FMT_UYVY,             //v4l2_type_id
00513         16,                              //bits
00514     },{/* 16  YVU422 planar */
00515         "YUV422P",                        //ffname
00516         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00517         V4L2_PIX_FMT_YUV422P,             //v4l2_type_id
00518         16,                              //bits
00519     },{/* 16  YVU411 planar */
00520         "YUV411P",                        //ffname
00521         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00522         V4L2_PIX_FMT_YUV411P,             //v4l2_type_id
00523         16,                              //bits
00524     },{/* 12  YUV 4:1:1     */
00525         "Y41P",                        //ffname
00526         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00527         V4L2_PIX_FMT_Y41P,             //v4l2_type_id
00528         16,                              //bits
00529     },{/* 12  Y/CbCr 4:2:0  */
00530         "NV12",                        //ffname
00531         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00532         V4L2_PIX_FMT_NV12,             //v4l2_type_id
00533         16,                              //bits
00534     },{/* 12  Y/CrCb 4:2:0  */
00535         "NV21",                        //ffname
00536         PLAYER_CAMERA_FORMAT_MONO16,     //player_type_id
00537         V4L2_PIX_FMT_NV21,             //v4l2_type_id
00538         16,                              //bits
00539     },{
00540 //        "",                        //ffname
00541 //        PLAYER_CAMERA_FORMAT_???,     //player_type_id
00542 //        V4L2_PIX_FMT_???,             //v4l2_type_id
00543 //        ???,                              //bits
00544 //    },{
00545         0,0,0,0// do not delete this
00546     }
00547 //           from player.h
00548 // /** Image format : 8-bit monochrome. */
00549 // #define PLAYER_CAMERA_FORMAT_MONO8  1
00550 // /** Image format : 16-bit monochrome (network byte order). */
00551 // #define PLAYER_CAMERA_FORMAT_MONO16 2
00552 // /** Image format : 16-bit color (5 bits R, 6 bits G, 5 bits B). */
00553 // #define PLAYER_CAMERA_FORMAT_RGB565 4
00554 // /** Image format : 24-bit color (8 bits R, 8 bits G, 8 bits B). */
00555 // #define PLAYER_CAMERA_FORMAT_RGB888 5
00556 
00557 
00558 //           from videodev2.h
00559 // #define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R','G','B','1')
00560 // #define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R','G','B','O')
00561 // #define V4L2_PIX_FMT_RGB565  v4l2_fourcc('R','G','B','P')
00562 // #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q')
00563 // #define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R')
00564 // #define V4L2_PIX_FMT_BGR24   v4l2_fourcc('B','G','R','3')
00565 // #define V4L2_PIX_FMT_RGB24   v4l2_fourcc('R','G','B','3')
00566 // #define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B','G','R','4')
00567 // #define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R','G','B','4')
00568 // #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G','R','E','Y')
00569 // #define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y','V','U','9')
00570 // #define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y','V','1','2')
00571 // #define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y','U','Y','V')
00572 // #define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U','Y','V','Y')
00573 // #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P')
00574 // #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P')
00575 // #define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y','4','1','P')
00576 //
00577 // /* two planes -- one Y, one Cr + Cb interleaved  */
00578 // #define V4L2_PIX_FMT_NV12    v4l2_fourcc('N','V','1','2')
00579 // #define V4L2_PIX_FMT_NV21    v4l2_fourcc('N','V','2','1')
00580 //
00581 // /*  The following formats are not defined in the V4L2 specification */
00582 // #define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y','U','V','9') /*  9  YUV 4:1:0     */
00583 // #define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y','U','1','2') /* 12  YUV 4:2:0     */
00584 // #define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
00585 // #define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
00586 };
00587 
00590 struct FieldsList {
00591     const char *name;
00592     enum v4l2_field fieldType;
00593 } fieldy[] = {
00594     { // first is default
00595         "ANY",
00596         V4L2_FIELD_ANY,
00597     },{
00598         "NONE",
00599         V4L2_FIELD_NONE,
00600     },{
00601         "TOP",
00602         V4L2_FIELD_TOP,
00603     },{
00604         "BOTTOM",
00605         V4L2_FIELD_BOTTOM,
00606     },{
00607         "INTERLEACED",
00608         V4L2_FIELD_INTERLACED,
00609     },{
00610         "SEQ_TB",
00611         V4L2_FIELD_SEQ_TB,
00612     },{
00613         "SEQ_BT",
00614         V4L2_FIELD_SEQ_BT,
00615     },{
00616         "ALTERNATE",
00617         V4L2_FIELD_ALTERNATE,
00618     },{
00619         0,V4L2_FIELD_NONE// do not delete this
00620     }
00621 };
00622 
00623 
00630 int CameraV4L2::selectNorm(const char *snorm){
00631     int i=0;
00632     for(i=0; normy[i].name; i++)
00633         if (strcasecmp(snorm, normy[i].name) == 0)
00634             break;
00635 
00636     if (normy[i].name){
00637         this->norm = normy[i].id;
00638         this->width = normy[i].width;
00639         this->height = normy[i].height;
00640     } else {
00641         PLAYER_ERROR2("norm: %s is not supported (add it yourself to normy struct in %s)",
00642                       snorm, __FILE__);
00643         return -1;
00644     }
00645     return 0;
00646 }
00647 
00654 int CameraV4L2::selectFormat(const char *sformat){
00655     int i;
00656     for(i=0; formaty[i].name; i++)
00657         if (strcasecmp(sformat, formaty[i].name) == 0)
00658             break;
00659 
00660     if (formaty[i].name){
00661         this->data.format = formaty[i].player_type_id;
00662         this->depth = formaty[i].bits;
00663         this->v4l2_type_id = formaty[i].v4l2_type_id;
00664     } else {
00665         PLAYER_ERROR2("image pallete %s is not supported (add it yourself to formaty struct in %s)",
00666                       sformat, __FILE__);
00667         return -1;
00668     }
00669     return 0;
00670 }
00671 
00678 int CameraV4L2::selectField(const char *sfield){
00679     int i;
00680     for(i=0; fieldy[i].name; i++)
00681         if (strcasecmp(sfield, fieldy[i].name) == 0)
00682             break;
00683     if (fieldy[i].name){
00684         this->fieldType = fieldy[i].fieldType;
00685     } else {
00686         PLAYER_ERROR2("Field type %s is not supported",
00687                       sfield, __FILE__);
00688         return -1;
00689     }
00690     return 0;
00691 }
00692 
00694 // Constructor
00695 CameraV4L2::CameraV4L2( ConfigFile* cf, int section)
00696     : Driver(cf, section, PLAYER_CAMERA_CODE, PLAYER_ALL_MODE,
00697              sizeof(player_camera_data_t), 128, 10, 10)
00698 {
00699     showFPS = 0;
00700     sourceCh = 0;
00701     const char *schary;
00702 
00703   // Camera defaults to /dev/video0 and NTSC
00704     this->device = cf->ReadString(section, "dev_file", "/dev/video0");
00705 
00706   // Input source
00707     this->sourceCh = NULL;
00708     schary = cf->ReadString(section, "input", NULL);
00709     if (schary!=NULL && schary[0]>='0' && schary[0]<='9')
00710         this->source = cf->ReadInt(section, "input", 0);
00711     else {
00712         this->source = -1;
00713         this->sourceCh = schary;
00714     }
00715 
00716   // NTSC or PAL
00717     schary = cf->ReadString(section, "norm", "pal");
00718     if (selectNorm(schary)!=0)
00719         selectNorm(normy[0].name);
00720 
00721   // Size
00722     this->width = cf->ReadTupleInt(section, "size", 0, this->width);
00723     this->height = cf->ReadTupleInt(section, "size", 1, this->height);
00724 
00725   // Palette type
00726     schary = cf->ReadString(section, "mode", "RGB24");
00727     if (selectFormat(schary)!=0)
00728         selectFormat(formaty[0].name);
00729 
00730     schary = cf->ReadString(section, "field", "ANY");
00731     if (selectField(schary)!=0)
00732         selectField(fieldy[0].name);
00733 
00734     flip_rb = cf->ReadInt(section, "swap_rb", 0);
00735 
00736     showFPS = cf->ReadInt(section, "show_fps", -1);
00737     if (showFPS>9)
00738         showFPS = 9;
00739 
00740     //printf("#controls: %d", cf->GetTupleCount(section, "controls") );
00741     numOfCtls = cf->GetTupleCount(section, "controls")/2;
00742     if (numOfCtls>0){
00743         int i;
00744         double k=0;
00745         ctlNames = new const char*[numOfCtls];
00746         ctlVals = new double[numOfCtls];
00747         for(i=0; i<numOfCtls; i++){
00748             ctlNames[i] = cf->ReadTupleString(section, "controls", i*2+1, "null");
00749             k = cf->ReadTupleFloat(section, "controls", i*2, 200.0);
00750             if (k>1.0){
00751                 numOfCtls = i;
00752                 PLAYER_WARN1("Wrong value format for control %s, need val <= 1.0", ctlNames[i]);
00753             } else {
00754                 ctlVals[i]=(double)k;//??
00755             }
00756         }
00757     }
00758 
00759     back_source = source;
00760     back_norm = norm;
00761     back_depth = depth;
00762     back_width = width;
00763     back_height = height;
00764     back_fieldType = fieldType;
00765     back_v4l2_type_id = v4l2_type_id;
00766 
00767     puts("Camerav4l2: Driver object created");
00768 
00769     return;
00770 }
00771 
00772 
00774 // Set up the device (called by server thread).
00775 int CameraV4L2::Setup()
00776 {
00777     int err=0;
00778     int i;
00779 
00780     source = back_source;
00781     norm = back_norm;
00782     depth = back_depth;
00783     width = back_width;
00784     height = back_height;
00785     fieldType = back_fieldType;
00786     v4l2_type_id = back_v4l2_type_id;
00787 
00788     PLAYER_MSG1(0,"Camerav4l2: Setting up device %s", this->device);
00789     this->fg = fg2_createFrameGrabber();
00790     // set initial settings
00791     if (fg2_open(this->fg, this->device)!=0)
00792     {
00793         PLAYER_ERROR1("unable to open %s", this->device);
00794         fg2_delete(&fg);
00795         return -1;
00796     }
00797 
00798     PLAYER_MSG0(1,"Camerav4l2: device opened, aplying settings");
00799 
00800     err |= fg2_set_source(this->fg, this->source, this->sourceCh);
00801     err |= fg2_set_source_norm(this->fg, this->norm);
00802     if (err!=0){
00803         PLAYER_ERROR("Camerav4l2: failed source or norm");
00804         fg2_delete(&fg);
00805         return -1;
00806     }
00807     for(i=0; i<numOfCtls; i++){
00808         fg2_setControlValue(fg, ctlNames[i], ctlVals[i]);
00809     }
00810 
00811     if (fg2_setPixelSettings(fg, this->width, this->height, this->v4l2_type_id, this->fieldType, this->depth)==0) {
00812     } else {
00813         PLAYER_ERROR("Camerav4l2: nie udalo sie ustawic podanych parametrow");
00814         //fg2_delete(&fg);
00815         //return -1;
00816     }
00817 
00818     // finally start streaming with new settings
00819     if (fg2_startCapture(fg)!=0){
00820         fg2_delete(&fg);
00821         return -1;
00822     }
00823 
00824   // Start the driver thread.
00825     this->StartThread();
00826 
00827     return 0;
00828 }
00829 
00830 
00832 // Shutdown the device (called by server thread).
00833 int CameraV4L2::Shutdown()
00834 {
00835     //printf("CameraV4L2::Shutdown()");
00836   // Stop the driver thread.
00837     StopThread();
00838 
00839     fg2_delete(&fg);
00840     return 0;
00841 }
00842 
00843 
00845 // Main function for device thread
00846 void CameraV4L2::Main()
00847 {
00848 
00849     struct timeval time;
00850     long sumTime=0;
00851     int fpsFrames = 0;
00852     struct timeval timePrev;
00853 
00854     GlobalTime->GetTime(&timePrev);
00855 
00856 
00857     int frameno;
00858 
00859     frameno = 0;
00860 
00861     while (true)
00862     {
00863     // Go to sleep for a while (this is a polling loop).
00864         //usleep(50000);
00865 
00866     // Test if we are supposed to cancel this thread.
00867         pthread_testcancel();
00868 
00869     // Process any pending requests.
00870         HandleRequests();
00871 
00872     // Get the time
00873         GlobalTime->GetTime(&time);
00874 
00875         sumTime += (time.tv_sec-timePrev.tv_sec)*1000000 + (time.tv_usec-timePrev.tv_usec);
00876         timePrev = time;
00877         fpsFrames++;
00878         if (sumTime > 2000000){
00879             if (showFPS>=0)
00880                 PLAYER_MSG2(showFPS, "Fps: %f (%d)", 1000000.0*fpsFrames/sumTime, fpsFrames);
00881             sumTime = 0;
00882             fpsFrames = 0;
00883         }
00884         if (sumTime<0){
00885             sumTime = 0;
00886             fpsFrames = 0;
00887         }
00888 
00889         this->tsec = time.tv_sec;
00890         this->tusec = time.tv_usec;
00891 
00892 
00893 
00894         //printf("Time between
00895 
00896     // Write data to server
00897         this->WriteData();
00898 
00899         frameno++;
00900     }
00901 }
00902 
00912 int CameraV4L2::tryPixelSettings(FRAMEGRABBER2* fg, int w, int h, unsigned int fmt, enum v4l2_field fld)
00913 {
00914     int ret=0;
00915     if (fg2_setPixelSettings(fg, w, h,fmt, fld, this->depth)!=0){
00916         fg2_setPixelSettings(fg, this->width, this->height,
00917                              this->v4l2_type_id, fieldType, this->depth);
00918         ret = -1;
00919     } else {
00920         this->width = w;
00921         this->height = h;
00922         this->v4l2_type_id = fmt;
00923         fieldType = fld;
00924     }
00925 
00926     return ret;
00927 }
00928 
00929 
00932 int CameraV4L2::HandleRequests()
00933 {
00934     void *client;
00935     char request[PLAYER_MAX_REQREP_SIZE];
00936     char outBuf[PLAYER_MAX_REQREP_SIZE];
00937     int len;
00938 
00939 
00940     while ((len = GetConfig(&client, &request, sizeof(request),NULL)) > 0)
00941     {
00942         int ret = -1;
00943         PLAYER_MSG2(2,"Got Reguest %c (size: %d)", request[0], len);
00944         if (len>1 && (request[0]=='g' || request[0]=='G')){
00945             // pobranie jakiejs wartosci
00946             PLAYER_MSG0(2,"Get type request");
00947             ret = handleCommand(request, len, outBuf, PLAYER_MAX_REQREP_SIZE-1);
00948 
00949             if (ret==0) {
00950                 outBuf[PLAYER_MAX_REQREP_SIZE-1] = '\0';
00951                 PLAYER_MSG1(2,"Sending Ack: %s", outBuf);
00952                 if (PutReply(client, PLAYER_MSGTYPE_RESP_ACK, outBuf, strlen(outBuf)+1,NULL) != 0)
00953                     PLAYER_ERROR("PutReply() failed");
00954             } else {
00955                 PLAYER_MSG0(2,"Sendinf NACK");
00956                 if (PutReply(client, PLAYER_MSGTYPE_RESP_NACK,NULL) != 0)
00957                     PLAYER_ERROR("PutReply() failed");
00958             }
00959 
00960         } else {
00961             if (len>0) {
00962                 ret = handleCommand(request, len);
00963             }
00964 
00965             if (ret == 0){
00966                 PLAYER_MSG0(2,"Sending Ack");
00967                 if (PutReply(client, PLAYER_MSGTYPE_RESP_ACK,NULL) != 0)
00968                     PLAYER_ERROR("PutReply() failed");
00969             } else {
00970                 PLAYER_MSG0(2,"Sending Nack");
00971                 if (PutReply(client, PLAYER_MSGTYPE_RESP_NACK,NULL) != 0)
00972                     PLAYER_ERROR("PutReply() failed");
00973             }
00974         }
00975         // if framegrabber is slow(1-10s), it is worth handling all commands at once
00976         //usleep(30000);
00977     }
00978     return 0;
00979 }
00980 
00987 int CameraV4L2::handleCommand(char *cmd, int len){
00988     int w;
00989     int h;
00990     enum v4l2_field fld;
00991     int ret=-1;
00992     unsigned int a,b,c; // backup
00993     double dblVal;
00994 
00995     ret = -1; // error on default
00996     PLAYER_MSG1(2,"Got command %s", cmd);
00997     switch(cmd[0]){
00998         case 's':
00999         case 'S':
01000             if (sscanf(cmd+1," %d %d", &w, &h)!=2)
01001                 break;
01002             fg2_stopCapture(fg);
01003             ret = tryPixelSettings(fg, w, h, this->v4l2_type_id, fieldType);
01004             fg2_startCapture(fg);
01005             break;
01006         case 'i':
01007         case 'I':
01008                 // todo: rollback if needed
01009             if (cmd[2]>='0' && cmd[2]<='9')
01010                 sscanf(cmd+2,"%d", &(this->source));
01011             else {
01012                 this->source = -1;
01013             }
01014 
01015             fg2_stopCapture(fg);
01016             ret = fg2_set_source(this->fg, this->source, cmd+2);
01017             fg2_startCapture(fg);
01018             break;
01019         case 'n':
01020         case 'N':
01021             a = this->norm;
01022             b = this->width;
01023             c = this->height;
01024 
01025             if (cmd[1]!=' ' || selectFormat(cmd+2)!=0)
01026                 break;
01027             fg2_stopCapture(fg);
01028             ret = fg2_set_source_norm(this->fg, this->norm);
01029             ret |= tryPixelSettings(fg, this->width, this->height, this->v4l2_type_id, fieldType);
01030             if (ret!=0) {
01031                 this->norm = a;
01032                 this->width = b;
01033                 this->height = c;
01034                     // known working?
01035                 fg2_set_source_norm(this->fg, this->norm);
01036                 tryPixelSettings(fg, this->width, this->height, this->v4l2_type_id, fieldType);
01037             }
01038             fg2_startCapture(fg);
01039             break;
01040         case 'm':
01041         case 'M':
01042             a = this->data.format;
01043             b = this->depth;
01044             c = this->v4l2_type_id;
01045 
01046             if (cmd[1]!=' ' || selectFormat(cmd+2)!=0)
01047                 break;
01048             fg2_stopCapture(fg);
01049             ret = tryPixelSettings(fg, this->width, this->height, this->v4l2_type_id, fieldType);
01050             if (ret!=0) {
01051                 this->data.format = a;
01052                 this->depth = b;
01053                 this->v4l2_type_id = c;
01054                 ret = tryPixelSettings(fg, this->width, this->height, this->v4l2_type_id, fieldType);
01055             }
01056             fg2_startCapture(fg);
01057             break;
01058         case 'w':
01059         case 'W':
01060                 // todo: rollback if needed
01061             if (cmd[2]>='0' && cmd[2]<='9'){
01062                 sscanf(cmd+2,"%d", &(this->flip_rb));
01063                 ret = 0;
01064             }
01065             break;
01066         case 'f':
01067         case 'F':
01068             fld = fieldType;
01069 
01070             if (cmd[1]!=' ' || selectField(cmd+2)!=0)
01071                 break;
01072             fg2_stopCapture(fg);
01073             ret = tryPixelSettings(fg, this->width, this->height, this->v4l2_type_id, fieldType);
01074             fg2_startCapture(fg);
01075             if (ret!=0) {
01076                 fieldType = fld;
01077             }
01078             break;
01079         case 'c':
01080         case 'C':
01081             if (cmd[1] == 'i' || cmd[1] == 'I') {
01082                 if (sscanf(cmd+2, "%lf %u", &dblVal, &a)!=2)
01083                     break;
01084                 ret = fg2_setControlValueI(fg, a, dblVal);
01085                 break;
01086             }
01087             for(w=2; w<len-1; w++)
01088                 if (cmd[w]==' ' || cmd[w+1]=='\0')
01089                     break;
01090             if (sscanf(cmd+2,"%lf",&dblVal) != 1)
01091                 break;
01092             ret = fg2_setControlValue(fg, cmd+w+1, dblVal);
01093             break;
01094         default:
01095             PLAYER_WARN1("Unknown command %s",cmd);
01096             break;
01097     }
01098     return ret;
01099 }
01100 
01101 
01102 
01111 int CameraV4L2::handleCommand(char *cmd, int len, char *reply, int rlen){
01112     //enum v4l2_field fld;
01113     int ret=-1;
01114     unsigned int a; // backup
01115     double dblVal;
01116 
01117     ret = -1; // error on default
01118     PLAYER_MSG1(2,"Got command get type %s", cmd);
01119     switch(cmd[1]){
01120         case 'c': // controls
01121         case 'C':
01122             if (len<3)
01123                 break;
01124             if (cmd[2] == '\0'){
01125                 // count controls
01126                 PLAYER_MSG0(2,"counting controls");
01127                 a = fg2_countControls(fg);
01128                 ret = 0;
01129                 snprintf(reply, rlen, "%d", a);
01130                 break;
01131             }
01132             if (len<4)
01133                 break;
01134             if (cmd[2] == 'i' || cmd[2] == 'I') {
01135                 if (sscanf(cmd+3, "%u", &a)!=1)
01136                     break;
01137                 dblVal = fg2_getControlValueI(fg, a);
01138                 ret = 0;
01139                 snprintf(reply, rlen, "%f", dblVal);
01140                 break;
01141             }
01142             if (cmd[2] == 'n' || cmd[2] == 'N' && cmd[3]==' '){
01143                 if (sscanf(cmd+3, "%u", &a)!=1)
01144                     break;
01145                 // get name
01146                 const char *name = fg2_getControlName(fg, a);
01147                 if (name==0)
01148                     break;
01149                 ret = 0;
01150                 snprintf(reply, rlen, "%s", name);
01151                 break;
01152             }
01153             if (cmd[2] != ' ')
01154                 break;
01155 
01156             dblVal = fg2_getControlValue(fg, cmd + 3);
01157             ret = 0;
01158             snprintf(reply, rlen, "%f", dblVal);
01159             break;
01160         case 'f': // fields
01161         case 'F':
01162         {
01163             int i=0;
01164             for(i=0; fieldy[i].name; i++)
01165                 if (fieldy[i].fieldType == this->fieldType)
01166                     break;
01167             if (fieldy[i].name) {
01168                 snprintf(reply, rlen, "%s", fieldy[i].name);
01169                 ret = 0;
01170             } else {
01171                 PLAYER_WARN1("Unknown field type: %d", this->fieldType);
01172             }
01173             break;
01174         }
01175         case 'm': // modes
01176         case 'M':
01177         {
01178             int i=0;
01179             for(i=0; formaty[i].name; i++)
01180                 if (formaty[i].v4l2_type_id == this->v4l2_type_id)
01181                     break;
01182             if (formaty[i].name) {
01183                 snprintf(reply, rlen, "%s", formaty[i].name);
01184                 ret = 0;
01185             } else {
01186                 PLAYER_WARN1("Unknown pixel format type: %d", this->v4l2_type_id);
01187             }
01188             break;
01189         }
01190         case 'n': // norms
01191         case 'N':
01192         {
01193             int i=0;
01194             for(i=0; normy[i].name; i++)
01195                 if (normy[i].id == this->norm)
01196                     break;
01197             if (formaty[i].name) {
01198                 snprintf(reply, rlen, "%s", normy[i].name);
01199                 ret = 0;
01200             } else {
01201                 PLAYER_WARN1("Unknown pixel format type: %d", this->norm);
01202             }
01203             break;
01204         }
01205         case 'i': // source name
01206         case 'I':
01207         {
01208             ret = 0;
01209             snprintf(reply, rlen, "%s", fg2_get_source_name(fg));
01210             break;
01211         }
01212         case '\0': // driver name
01213         {
01214             ret = 0;
01215             snprintf(reply, rlen, "%s", fg2_get_device_name(fg));
01216             break;
01217         }
01218         default:
01219             PLAYER_ERROR1("Unknown command2 %s",cmd);
01220             break;
01221     }
01222     return ret;
01223 }
01224 
01225 
01227 
01230 void CameraV4L2::WriteData()
01231 {
01232     size_t image_size, size;
01233     unsigned char * ptr1, * ptr2;
01234 
01235     struct my_buffer *v4lBuffer = getFrameBuffer(fg);
01236     if (v4lBuffer==NULL)
01237         exit(1);
01238     ptr1 = (unsigned char *)v4lBuffer->start;
01239     ptr2 = this->data.image;
01240 
01241   // Compute size of image
01242     image_size = this->width * this->height * this->depth / 8;
01243 
01244   // Set the image properties
01245     this->data.width = htons(this->width);
01246     this->data.height = htons(this->height);
01247     this->data.bpp = this->depth;
01248     this->data.compression = PLAYER_CAMERA_COMPRESS_RAW;
01249     this->data.image_size = htonl(image_size);
01250 
01251     if (image_size > sizeof(this->data.image)){
01252         PLAYER_ERROR2("image_size <= sizeof(this->data.image) failed: %d > %d",
01253                image_size, sizeof(this->data.image));
01254     }
01255     assert(image_size <= sizeof(this->data.image));
01256     if (image_size > (size_t) v4lBuffer->length){
01257         PLAYER_WARN("Frame size is smaller then expected");
01258         image_size = (size_t) v4lBuffer->length;
01259     }
01260     //assert(image_size <= (size_t) v4lBuffer->length);
01261 
01262 
01263     if (!flip_rb) {
01264         memcpy(ptr2, ptr1, image_size);
01265     } else {
01266         int imgSize = ((this->width) * (this->height));
01267         int i;
01268         switch (v4l2_type_id)
01269         {
01270             case V4L2_PIX_FMT_RGB24:
01271             case V4L2_PIX_FMT_BGR24:
01272                 for (i = 0; i < imgSize; i++)
01273                 {
01274                     ptr2[0] = ptr1[2];
01275                     ptr2[1] = ptr1[1];
01276                     ptr2[2] = ptr1[0];
01277                     ptr1 += 3;
01278                     ptr2 += 3;
01279                 }
01280                 break;
01281             case V4L2_PIX_FMT_RGB32:
01282             case V4L2_PIX_FMT_BGR32:
01283                 for (i = 0; i < imgSize; i++)
01284                 {
01285                     ptr2[0] = ptr1[2];
01286                     ptr2[1] = ptr1[1];
01287                     ptr2[2] = ptr1[0];
01288                     ptr2[3] = ptr1[3];
01289                     ptr1 += 4;
01290                     ptr2 += 4;
01291                 }
01292                 break;
01293             default:
01294                 memcpy(ptr2, ptr1, image_size);
01295         }
01296     }
01297 
01298   // Copy data to server
01299     size = sizeof(this->data) - sizeof(this->data.image) + image_size;
01300 
01301     struct timeval timestamp;
01302     timestamp.tv_sec = this->tsec;
01303     timestamp.tv_usec = this->tusec;
01304     PutData((void*) &this->data, size, &timestamp);
01305 
01306     giveBackFrameBuffer(fg, v4lBuffer);
01307 
01308     return;
01309 }
01310 
01311 

Generated on Thu Jun 29 22:04:42 2006 for Camerav4l2 by  doxygen 1.4.4