root/ossiedev/branches/deepanns/components/WebCamCapture/WebCamCapture.cpp @ 8886

Revision 8886, 14.7 KB (checked in by deepanns, 4 years ago)

updated query and configure for components

Line 
1/****************************************************************************
2
3Copyright 2006 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE WebCamCapture.
6
7OSSIE WebCamCapture is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12OSSIE WebCamCapture is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OSSIE WebCamCapture; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23
24#include <string>
25#include <iostream>
26#include "WebCamCapture.h"
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <unistd.h>
31
32
33
34
35/*from main in spcaview.c*/
36const char *videodevice = NULL;
37/* default mmap */
38
39       
40        int format = VIDEO_PALETTE_JPEG; //VIDEO_PALETTE_YUV420P;
41        /******** output screen pointer ***/
42       
43        unsigned int image_width = IMAGE_WIDTH;
44        unsigned int image_height = IMAGE_HEIGHT;
45        int owidth = 0;
46        int oheight = 0;
47        /*********************************/
48        /*          Starting Flags       */
49//      int i;
50        int videoOn = 1;
51        int decodeOn =1 ;
52        int statOn = 0;
53        int audioout = 0;
54        int videocomp = 0;
55        int channel = 0;
56        int norme = 0;
57        int autobright = 0;
58               
59        /*********************************/
60        SPCASTATE funct;
61       
62 
63        int bpp = 3;
64
65/*from grab method in spcaview.c*/
66  int fd;
67        /* default mmap */
68        //int i, j, k, nframes = 2000, f, status;
69        struct video_mmap vmmap;
70        struct video_capability videocap;
71        int mmapsize;
72        struct video_mbuf videombuf;
73        struct video_picture videopict;
74        struct video_window videowin;
75        struct video_channel videochan;
76        struct video_param videoparam;
77
78       
79        /******** output screen pointer ***/
80        SDL_Surface *pscreen;
81        SDL_Event sdlevent;
82        /**********************************/
83        /*        avi parametres          */
84        unsigned char *pFramebuffer;
85        int ff;
86        int framecount = 0;
87        /*********************************/
88        /*          Starting Flags       */
89        int run = 1;
90        int quit = 1;   
91        int initAudio = 0; //flag start audio
92        int method = 1;
93        int streamid ;
94        int isVideoChannel = 1;
95        int frame_size = 0;
96        int len = 0;
97       
98       
99        /*********************************/
100        /* data for SDL_audioin && SDL_audio */
101        //SDL_AudioSpec spec, result;
102  //SDL_AudioSpec expect;
103//  struct Rbuffer RingBuffer;
104  int retry = 100;
105  int ptread ;
106        int ptwrite ;
107  int err = 0; 
108        int bytes_per_read =0;
109        int testbpp=16;
110        /*********************************/
111//      RingBuffer.ptread =0;
112//  RingBuffer.ptwrite =0;
113
114/**************************/
115
116
117WebCamCapture_i::WebCamCapture_i(const char *uuid, omni_condition *condition)
118  : Resource_impl(uuid), component_running(condition)
119{
120    dataOut_0 = new standardInterfaces_i::realChar_u("JPEG_DataOut");
121
122
123    //Create the thread for the writer's processing function
124    processing_thread = new omni_thread(run, (void *) this);
125
126    //Start the thread containing the writer's processing function
127    processing_thread->start();
128
129}
130
131// Destructor
132WebCamCapture_i::~WebCamCapture_i(void)
133{   
134    delete dataOut_0;
135}
136
137// static function for omni thread
138void WebCamCapture_i::run( void * data )
139{
140    ((WebCamCapture_i*)data)->run_loop();
141}
142
143CORBA::Object_ptr WebCamCapture_i::getPort( const char* portName ) throw (CORBA::SystemException, CF::PortSupplier::UnknownPort)
144{
145    DEBUG(3, WebCamCapture, "getPort invoked with port name: " << portName)
146   
147    CORBA::Object_var p;
148
149    p = dataOut_0->getPort(portName);
150
151    if (!CORBA::is_nil(p))
152        return p._retn();
153
154    /*exception*/
155    throw CF::PortSupplier::UnknownPort();
156}
157
158void WebCamCapture_i::start() throw (CORBA::SystemException, CF::Resource::StartError)
159{
160    DEBUG(3, WebCamCapture, "start invoked")
161
162               
163    isRunning = true;
164
165}
166
167void WebCamCapture_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
168
169    DEBUG(3, WebCamCapture, "stop invoked")
170    //Uint32 frame_color = NULL;
171    //Uint8 r, g, b;
172 
173    isRunning = false;
174   
175    //r = g = b = 0xFF;
176
177    /*
178    frame_color = SDL_MapRGB(pscreen->format, r, g, b);
179    if(SDL_FillRect(pscreen, NULL, frame_color) < 0)
180    {
181      std::cout << "Error: Could not set frame to NULL" << std::endl;
182    }
183    SDL_UpdateRect (pscreen, 0, 0, 0, 0);       //update the entire screen
184    */
185}
186
187void WebCamCapture_i::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError)
188{
189    DEBUG(3, WebCamCapture, "releaseObject invoked")
190   
191    if (audioout)
192    {
193                  //SDL_CloseAudioIn(); //stop record
194                        printf ("free sound buffer\n");
195                }
196                printf ("Quiting SDL.\n");
197    //printf ("Decoded frames:%d Average decode time: %f\n",framecount, average_decode_time);
198                printf ("unmapping\n");
199                munmap (pFramebuffer, mmapsize);
200       
201                printf ("closing\n");
202                close (fd);
203                printf ("closed\n");
204
205        printf ("Quiting....\n");
206                SDL_Quit (); 
207    printf("Done Shutting Down, WebCam\n");
208    component_running->signal();
209}
210
211void WebCamCapture_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemException)
212{
213  DEBUG(3, WebCamCapture, "initialize invoked")
214
215  int f = 0;
216  int bpp = 3;
217
218  //isRunning = false;
219  std::cout << "initialize called on WebCam" << std::endl;
220
221  printf ("Initializing SDL.\n");
222       
223        /* Initialize defaults, Video and Audio */
224        if ((SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1))
225  {
226                printf ("Could not initialize SDL: %s.\n", SDL_GetError ());
227                exit (-1);
228        }
229       
230        /* Clean up on exit */
231        atexit (SDL_Quit);
232        if(!owidth || !oheight)
233  {
234                owidth  = image_width;
235                oheight = image_height;
236        }       
237        printf ("SDL initialized.\n"); 
238        /* validate parameters */
239//      printf ("bpp %d format %d\n", bpp, format);
240
241        if (videodevice == NULL || *videodevice == 0)
242  {
243                        videodevice = "/dev/video0";
244        }
245        printf ("Using video device %s.\n", videodevice);
246        printf ("Initializing v4l.\n");
247               
248        //v4l init
249        if ((fd = open (videodevice, O_RDWR)) == -1)
250  {
251                        perror ("ERROR opening V4L interface \n");
252                        exit (1);
253        }
254        printf("**************** PROBING CAMERA *********************\n");
255        /*Get Video Device Capabilities*/
256  if (ioctl (fd, VIDIOCGCAP, &videocap) == -1)
257  {
258          printf ("wrong device\n");
259                exit (1);
260        }
261               
262        printf("Camera found: %s \n",videocap.name);
263        printf("Camera Type: %d \n", videocap.type);
264
265 /*Get Video Device Video Channel*/
266        if (ioctl (fd, VIDIOCGCHAN, &videochan) == -1)
267  {
268          printf ("Hmm did not support Video_channel\n");
269                isVideoChannel = 0;
270        }
271        if (isVideoChannel)
272  {
273          videochan.norm = norme;
274                videochan.channel = channel;
275    /*Set Video Channel and Norm by channel*/
276                if (ioctl (fd, VIDIOCSCHAN, &videochan) == -1)
277    {
278                  printf ("ERROR setting channel and norme \n");
279                        exit (1);
280                }
281          /************ just to be sure *************/
282    /*Not sure if this is doing what he thinks...should check to see if the Channel and Norm got set correctly. */
283          if (ioctl (fd, VIDIOCGCHAN, &videochan) == -1)
284    {
285            printf ("wrong device\n");
286                  exit (1);
287          }
288          printf("Bridge found: %s \n",videochan.name);
289          streamid = getStreamId (videochan.name); //find out what type of camera
290       
291    /*Logitech QuickCam Communicate STX is a JPEG camera*/ 
292          if (streamid >= 0)
293    {
294            printf("StreamId: %s Camera\n",Plist[streamid].name);
295                  /* look a spca5xx webcam try to set the video param struct */
296                  spcaPrintParam (fd,&videoparam);
297          }
298    else
299    {
300            printf("StreamId: %d Unknow Camera\n",streamid);
301          }
302          /* test jpeg capability if not and jpeg ask without raw data
303                        set default format to YUVP */
304          if ((format == VIDEO_PALETTE_RAW_JPEG || format == VIDEO_PALETTE_JPEG )&& streamid != JPEG && videoOn)
305    {
306            printf ("Camera unable to stream in JPEG mode switch to YUV420P\n");
307                  format = VIDEO_PALETTE_YUV420P;
308          }
309          if(probeSize(videochan.name,&image_width,&image_height) < 0)
310                  printf("unable to probe size !!\n");
311        }
312        printf("*****************************************************\n");
313        /* Init grab method mmap */
314               
315        printf(" grabbing method default MMAP asked \n");
316        // MMAP VIDEO acquisition
317        memset (&videombuf, 0, sizeof (videombuf));
318        if (ioctl (fd, VIDIOCGMBUF, &videombuf) < 0) {
319          perror (" init VIDIOCGMBUF FAILED\n");
320        }
321        printf ("VIDIOCGMBUF size %d  frames %d  offets[0]=%d offsets[1]=%d\n", videombuf.size, videombuf.frames, videombuf.offsets[0], videombuf.offsets[1]);
322                       
323                        pFramebuffer = (unsigned char *) mmap (0, videombuf.size,       PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
324                        mmapsize = videombuf.size;
325                        vmmap.height = image_height;
326                        vmmap.width = image_width;
327                        vmmap.format = format;
328                        for (f = 0; f < videombuf.frames; f++)
329      {
330                                vmmap.frame = f;
331                                if (ioctl (fd, VIDIOCMCAPTURE, &vmmap))
332        {
333                                        perror ("cmcapture");
334                                }
335                        }
336                       
337      vmmap.frame = 0;
338                       
339                                 
340                        frame_size = image_width * image_height;
341               
342                /* struct video_picture VIDIOCGPICT VIDIOCSPICT */
343                if (ioctl (fd, VIDIOCGPICT, &videopict) < 0) {
344                        perror ("Couldnt get videopict params with VIDIOCGPICT\n");
345                }
346                       
347                videopict.palette = format;
348                videopict.depth = bpp * 8;
349                //videopict.brightness = INIT_BRIGHT;
350                sleep (1);
351    /*Set Video Picture Param.*/
352                setVideoPict (&videopict, fd);
353   
354    /*
355           * Initialize the display
356    */
357    if ( decodeOn && videoOn )
358                {       /* Display data */
359      printf("Creating Video Frame...\n");
360                  pscreen =     SDL_SetVideoMode (owidth, oheight, testbpp, SDL_SWSURFACE);
361                  if (pscreen == NULL)
362      {
363                          printf ("Couldn't set %d*%dx%d video mode: %s\n",     owidth, oheight,3 * 8, SDL_GetError ());
364                          exit (1);
365                  }
366      SDL_WM_SetCaption ("OSSIE Web Cam Monitor - Live", NULL); //videocap.name
367      printf("Done Creating Video Frame\n");
368    }
369
370}
371
372void
373WebCamCapture_i::query (CF::Properties & configProperties)
374throw (CORBA::SystemException, CF::UnknownProperties)
375{
376    // for queries of zero length, return all id/value pairs in propertySet
377    if (configProperties.length () == 0)
378    {
379        configProperties.length (propertySet.length ());
380        for (unsigned int i = 0; i < propertySet.length (); i++)
381        {
382            configProperties[i].id = CORBA::string_dup (propertySet[i].id);
383            configProperties[i].value = propertySet[i].value;
384        }
385
386        return ;
387    }
388    else {
389        for (unsigned int i = 0; i < configProperties.length(); i++) {
390            for (unsigned int j=0; j < propertySet.length(); j++) {
391                if ( strcmp(configProperties[i].id, propertySet[i].id) == 0 ){
392                    configProperties[i].value = propertySet[i].value;
393               }
394            }
395        }
396    }
397}
398
399
400
401void WebCamCapture_i::configure(const CF::Properties& props) throw (CORBA::SystemException, CF::PropertySet::InvalidConfiguration, CF::PropertySet::PartialConfiguration)
402{
403        static int init = 0;
404    DEBUG(3, WebCamCapture, "configure invoked")
405   
406    std::cout << "props length : " << props.length() << std::endl;
407
408    std::cout << "Component - WEBCAM CAPTURE" << std::endl;
409    if (init == 0){
410        std::cout << " WebcamCapture - initial configure call .." << std::endl;
411        propertySet.length(props.length());
412        for (unsigned int i=0; i < props.length(); i++) {
413            std::cout << "Property Id : " << props[i].id << std::endl;
414            propertySet[i].id = CORBA::string_dup(props[i].id);
415            propertySet[i].value = props[i].value;
416        }
417        init = 1;
418        return;
419    }
420    else {
421
422
423                for (unsigned int i = 0; i <props.length(); i++)
424                {
425                    std::cout << "Property id : " << props[i].id << std::endl;
426
427                    if (strcmp(props[i].id, "DCE:3dd2928a-c369-11db-8bd5-000129227a88") == 0)
428                    {
429                        CORBA::Short n;
430                        props[i].value >>= n;
431                        quality = n;
432                        std::cout << "WebCam: Quality (1 - 5): " << quality << std::endl;
433                        spcaSetQuality(fd, &videoparam, (unsigned char)quality);
434                               
435                               
436                std::cout << "Property id : " << props[i].id << std::endl;
437                // Update value of this property in propertySet also
438                for (unsigned int j=0; j < propertySet.length(); j++ ) {
439                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
440                        propertySet[i].value = props[i].value;
441                        break;
442                    }
443                }
444
445                    }
446
447                }
448        }
449}
450
451void WebCamCapture_i::run_loop()
452{
453    DEBUG(3, WebCamCapture, "run loop invoked")
454
455    PortTypes::CharSequence I_out;
456    short N;
457   
458    tmp = NULL;
459    int i = 0;
460    int status;
461
462
463    while( true )
464    {
465      N = frame_size;
466      I_out.length(N);
467      if(isRunning)
468      {
469        tmp = (unsigned char*)malloc (frame_size);
470        //std::cout << "Running...Frame Size: " << frame_size << std::endl;
471        memset(tmp,0x00,frame_size);
472        //intime = SDL_GetTicks ();
473                          //pictime = intime - delaytime;
474                          //delaytime = intime;
475                          /* Try to synchronize sound with frame rate */
476                        if (initAudio && i > 9)
477        {
478                                  initAudio = 0;
479                                  //    SDL_PauseAudioIn(0); // start record
480                          }
481                          /* compute bytes sound */
482                          //if (pictime < 100)
483        //{
484                          // bytes_per_read =((AUDIO_SAMPLERATE / 1000) * 2 * pictime);
485                          //}
486                          //i++;
487        ff = vmmap.frame;
488        if (ioctl (fd, VIDIOCSYNC, &ff) < 0)
489        {
490          perror ("cvsync err\n");
491        }
492        vmmap.frame = ff;
493        memcpy (tmp, pFramebuffer +     videombuf.offsets[vmmap.frame], frame_size);
494                          if ((status = ioctl (fd, VIDIOCMCAPTURE, &vmmap)) < 0)
495        {
496          //std::cout << "VIDEOCMCAPTURE" << std::endl;
497                                  perror ("cmcapture");
498                                  printf (">>cmcapture err %d\n", status);
499                          }
500        vmmap.frame =   (vmmap.frame + 1) % videombuf.frames;
501                                 
502                    //  synctime = SDL_GetTicks ();
503                          /*here the frame is in tmp ready to used */
504
505        //Send WebCam->tmp (unsigned char*) out to packetizer
506
507        /*This just updates the OSSIE WebCam Monitor - Live*/
508        //if ( decodeOn && videoOn && (i > 10))
509                         // {   
510          //std::cout << "Update OSSIE WebCam Monitor - Live" << std::endl;
511          refresh_screen(tmp,(unsigned char*)(pscreen->pixels),format,image_width,image_height,owidth,oheight,image_width*image_height*bpp,autobright);
512                            if (autobright)
513          {
514                              // printf("AutoBright\n");
515            adjust_bright(&videopict, fd);
516          }
517          //decodetime = SDL_GetTicks ();
518          SDL_UpdateRect (pscreen, 0, 0, 0, 0); //update the entire screen             
519       // } 
520        //else
521       // {
522                            //decodetime = SDL_GetTicks ();
523                         // }
524      int y = 0;
525      for(y = 0; y < N; y++)
526      {
527        I_out[y] = tmp[y];
528      }
529      //std::cout << "Data Transmitted length: " << N << std::endl;
530
531      dataOut_0->pushPacket(I_out);
532      free(tmp);
533      //usleep(400000);
534      }
535      else
536      {
537             
538      }
539    }
540}
541
542   
Note: See TracBrowser for help on using the browser.