Ejemplo n.º 1
0
static int
ambitv_cycle_next_program()
{
   int ret = 0;
   
   if (!conf.ambitv_on) {
      ambitv_log(ambitv_log_info,
         LOGNAME "not cycling program, because state is paused.\n");
      
      return 0;
   }
   
   conf.cur_prog = (conf.cur_prog + 1) % ambitv_num_programs;
   
   ret = ambitv_program_run(ambitv_programs[conf.cur_prog]);
   
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to switch to program '%s', aborting...\n",
         ambitv_programs[conf.cur_prog]->name);
   } else {
      ambitv_log(ambitv_log_info, LOGNAME "switched to program '%s'.\n",
         ambitv_programs[conf.cur_prog]->name);
   }
   
   return ret;
}
Ejemplo n.º 2
0
static void ambitv_mood_light_processor_print_configuration(struct ambitv_processor_component* component)
{
	struct ambitv_mood_light_processor* mood = (struct ambitv_mood_light_processor*) component->priv;

	ambitv_log(ambitv_log_info, "\tspeed:  %.1f\n", mood->step * 1000.0);
	ambitv_log(ambitv_log_info, "\tmode:  %d\n", mood->mode);
}
Ejemplo n.º 3
0
static int
ambitv_v4l2_grab_capture_loop_iteration(struct ambitv_source_component* grabber)
{
   int ret = 0;
   fd_set fds;
   struct timeval tv;
   
   struct v4l2_grab* grab_priv = (struct v4l2_grab*)grabber->priv;
   if (NULL == grab_priv)
      return -1;
   
   FD_ZERO(&fds);
   FD_SET(grab_priv->fd, &fds);
   
   tv.tv_sec   = 2;
   tv.tv_usec  = 0;
   
   ret = select(grab_priv->fd+1, &fds, NULL, NULL, &tv);
   
   if (ret < 0) {
      if (EINTR == errno)
         ret = 0;
      
      ambitv_log(ambitv_log_error, LOGNAME "failed to select() a frame: %d (%s).\n",
         errno, strerror(errno));
   } else if (0 == ret) {
      ambitv_log(ambitv_log_error, LOGNAME "select() timed out.\n");
   }
   
   if (ret > 0) {
      ret = ambitv_v4l2_grab_read_frame(grab_priv);
   }
   
   return ret;
}
Ejemplo n.º 4
0
static int
ambitv_v4l2_grab_open_device(struct v4l2_grab* grabber)
{
   int ret = 0;
   struct stat st;
   
   ret = stat(grabber->device_name, &st);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to stat '%s' : %d (%s).\n",
         grabber->device_name, errno, strerror(errno));
      return ret;
   }
   
   if (!S_ISCHR(st.st_mode)) {
      ambitv_log(ambitv_log_error, LOGNAME "'%s' is not a device.\n",
         grabber->device_name);
      return -ENODEV;
   }
   
   grabber->fd = open(grabber->device_name, O_RDWR | O_NONBLOCK, 0);
   
   if (grabber->fd < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to open '%s': %d (%s).\n",
         grabber->device_name, errno, strerror(errno));

      ret = -errno;
   }
   
   return ret;
}
Ejemplo n.º 5
0
static int
ambitv_v4l2_grab_start_streaming(struct v4l2_grab* grabber)
{
   int i, ret;
   enum v4l2_buf_type type;
   
   for (i=0; i < grabber->num_buffers; i++) {
      struct v4l2_buffer buf;
      
      memset(&buf, 0, sizeof(buf));
      
      buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory  = V4L2_MEMORY_MMAP;
      buf.index   = i;
      
      ret = xioctl(grabber->fd, VIDIOC_QBUF, &buf);
      if (ret < 0) {
         ambitv_log(ambitv_log_error, LOGNAME "failed to enqueue a video buffer.\n");
         return -EINVAL;
      }
   }
   
   type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   
   ret = xioctl(grabber->fd, VIDIOC_STREAMON, &type);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to start video streaming: %d (%s).\n",
         errno, strerror(errno));
      return -EINVAL;
   }
      
   return 0;
}
Ejemplo n.º 6
0
static int
ambitv_edge_color_processor_configure(struct ambitv_edge_processor_priv* edge, int argc, char** argv)
{
   int c, ret = 0;

   static struct option lopts[] = {
      { "box-width", required_argument, 0, '0' },
      { "box-height", required_argument, 0, '1' },
      { NULL, 0, 0, 0 }
   };

   optind = 0;
   while (1) {      
      c = getopt_long(argc, argv, "", lopts, NULL);

      if (c < 0)
         break;

      switch (c) {
         case '0':
         case '1': {
            if (NULL != optarg) {
               char* eptr = NULL;
               long nbuf = strtol(optarg, &eptr, 10);
            
               if ('\0' == *eptr && nbuf > 0) {
                  edge->boxsize[c-'0'] = (int)nbuf;
               } else {
                  ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n",
                     argv[optind-2], optarg);
                  ret = -1;
                  goto errReturn;
               }
            }
            
            break;
         }

         default:
            break;
      }
   }

   if (optind < argc) {
      ambitv_log(ambitv_log_error, LOGNAME "extraneous argument '%s'.\n",
         argv[optind]);
      ret = -1;
   }

errReturn:
   return ret;
}
Ejemplo n.º 7
0
static int
ambitv_program_configure(struct ambitv_program* program, int argc, char** argv)
{
   int c, ret = 0;
   
   static struct option lopts[] = {
      { "activate", required_argument, 0, 'a' },
      { NULL, 0, 0, 0 }
   };
   
   optind = 0;
   while (1) {      
      c = getopt_long(argc, argv, "", lopts, NULL);
      
      if (c < 0)
         break;
         
      switch (c) {
         case 'a': {
            if ('&' != optarg[0]) {
               ambitv_log(ambitv_log_error, LOGNAME "component name is not prefixed with '&': '%s'.\n",
                  optarg);
               goto errReturn;
            }
            
            ret = ambitv_program_append_component_with_name(program, &optarg[1]);
            if (ret < 0) {
               ambitv_log(ambitv_log_error, LOGNAME "failed to find component with name '%s'.\n",
                  optarg);
               goto errReturn;
            }
            
            break;
         }
         
         default:
            break;
      }
   }
   
   if (optind < argc) {
      ambitv_log(ambitv_log_error, LOGNAME "extraneous argument '%s'.\n",
         argv[optind]);
      ret = -1;
   }

errReturn:
   return ret;
}
Ejemplo n.º 8
0
int ambitv_v4l2_grab_stop(struct ambitv_source_component* grabber)
{
   int ret = 0;
   
   struct v4l2_grab* grab_priv = (struct v4l2_grab*)grabber->priv;
   if (NULL == grab_priv)
      return -1;
   
   if (grab_priv->fd < 0) {
      ambitv_log(ambitv_log_warn, LOGNAME "grabber is not running and can't be stopped.\n");
      return -1;
   }
   
   ret = ambitv_v4l2_grab_stop_streaming(grab_priv);
   if (ret < 0)
      goto fail_return;
   
   ret = ambitv_v4l2_grab_uninit_device(grab_priv);
   if (ret < 0)
      goto fail_return;
   
   ret = ambitv_v4l2_grab_close_device(grab_priv);

fail_return:
   return ret;
}
Ejemplo n.º 9
0
static void ambitv_audio_processor_print_configuration(struct ambitv_processor_component* component)
{
	struct ambitv_audio_processor_priv* audio = (struct ambitv_audio_processor_priv*) component->priv;

	ambitv_log(ambitv_log_info, "\ttype       : %d\n"
			"\tsensitivity:  %d\n"
			"\tsmoothing  : %d\n"
			"\tlevelcolor : %02X%02X%02X\n"
			"\tlinear     : %d\n", audio->type, audio->sensitivity, audio->smoothing, audio->lcolor.r, audio->lcolor.g,
			audio->lcolor.b, audio->linear);
}
Ejemplo n.º 10
0
static void
ambitv_edge_color_processor_print_configuration(struct ambitv_processor_component* component)
{
   struct ambitv_edge_processor_priv* edge =
      (struct ambitv_edge_processor_priv*)component->priv;

   ambitv_log(ambitv_log_info,
      "\tbox-width:  %d\n"
      "\tbox-height: %d\n",
      edge->boxsize[0],
      edge->boxsize[1]
   );
}
Ejemplo n.º 11
0
static int
ambitv_v4l2_grab_init_device(struct v4l2_grab* grabber)
{
   int ret;
   struct v4l2_capability cap;
   struct v4l2_format vid_fmt;

   ret = xioctl(grabber->fd, VIDIOC_QUERYCAP, &cap);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "'%s' is no v4l2 device.\n",
         grabber->device_name);
      return ret;
   }
   
   if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
      ambitv_log(ambitv_log_error, LOGNAME "'%s' is not a video capture device.\n",
         grabber->device_name);
      return -ENODEV;
   }
   
   if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
      ambitv_log(ambitv_log_error, LOGNAME "'%s' does not support streaming i/o.\n",
         grabber->device_name);
      return -ENODEV;
   }
   
   memset(&vid_fmt, 0, sizeof(vid_fmt));
   vid_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   
   ret = xioctl(grabber->fd, VIDIOC_G_FMT, &vid_fmt);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to determine video format of '%s'.\n",
         grabber->device_name);
      return -EINVAL;
   }
   
   vid_fmt.fmt.pix.width 	= 720;
   vid_fmt.fmt.pix.height 	= 576;
   
   ret = xioctl(grabber->fd, VIDIOC_S_FMT, &vid_fmt);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to set video format of '%s'.\n",
         grabber->device_name);
      return -EINVAL;
   }
   
   grabber->width          = vid_fmt.fmt.pix.width;
   grabber->height         = vid_fmt.fmt.pix.height;
   grabber->bytesperline   = vid_fmt.fmt.pix.bytesperline;
   grabber->fmt            = v4l2_to_ambitv_video_format(vid_fmt.fmt.pix.pixelformat);
   
   ambitv_log(ambitv_log_info, LOGNAME "video format: %ux%u (%s).\n",
      vid_fmt.fmt.pix.width, vid_fmt.fmt.pix.height,
      v4l2_string_from_fourcc(vid_fmt.fmt.pix.pixelformat));
   
   return ambitv_v4l2_grab_init_mmap(grabber);
}
Ejemplo n.º 12
0
static int
ambitv_toggle_paused()
{
   int ret = 0;
   
   conf.ambitv_on = !conf.ambitv_on;
   
   if (conf.ambitv_on) {
      ret = ambitv_program_run(ambitv_programs[conf.cur_prog]);
      if (ret < 0)
         ambitv_log(ambitv_log_error, LOGNAME "failed to start program '%s'.\n",
            ambitv_programs[conf.cur_prog]->name);
   } else {
      ret = ambitv_program_stop_current();
      if (ret < 0)
         ambitv_log(ambitv_log_error, LOGNAME "failed to stop program '%s'.\n",
            ambitv_programs[conf.cur_prog]->name);
   }
   
   ambitv_log(ambitv_log_info, LOGNAME "now: %s\n",
      conf.ambitv_on ? "running" : "paused");
   
   return ret;
}
Ejemplo n.º 13
0
int
ambitv_program_enable(struct ambitv_program* program)
{
   int i;
   
   for (i=0; i<ambitv_num_programs; i++)
      if (0 == strcmp(program->name, ambitv_programs[i]->name)) {
         ambitv_log(ambitv_log_error, LOGNAME "a program with name '%s' is already registered.\n",
            program->name);
         return -1;
      }
   
   ambitv_num_programs = ambitv_util_append_ptr_to_list(
      (void***)&ambitv_programs,
      ambitv_num_programs,
      &ambitv_len_programs,
      program
   );
   
   ambitv_log(ambitv_log_info, LOGNAME "registered program '%s'.\n",
      program->name);
   
   return 0;
}
Ejemplo n.º 14
0
static int
ambitv_v4l2_grab_stop_streaming(struct v4l2_grab* grabber)
{
   int ret;
   enum v4l2_buf_type type;
   
   type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   
   ret = xioctl(grabber->fd, VIDIOC_STREAMOFF, &type);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to stop video streaming: %d (%s).\n",
         errno, strerror(errno));
      ret = -errno;
   }
   
   return ret;
}
Ejemplo n.º 15
0
static int
ambitv_v4l2_grab_uninit_device(struct v4l2_grab* grabber)
{
   unsigned int i;
   int ret;
   struct vid_buffer* buffers = (struct vid_buffer*)grabber->buffers;
   
   for (i=0; i < grabber->num_buffers; i++) {
      ret = munmap(buffers[i].start, buffers[i].length);
      if (ret < 0) {
         ambitv_log(ambitv_log_error, LOGNAME "failed to unmap buffer: %d (%s).\n",
            errno, strerror(errno));
         return -errno;
      }
   }
   
   ambitv_v4l2_grab_free_buffers(grabber);
   
   return 0;
}
Ejemplo n.º 16
0
static int
ambitv_program_append_component_with_name(struct ambitv_program* program, const char* name)
{
   int ret = -1;
   
   void* component = ambitv_component_find_by_name(name);
   
   if (NULL != component) {
      program->num_components = ambitv_util_append_ptr_to_list(
         &program->components,
         program->num_components,
         &program->len_components,
         component
      );
      
      ambitv_log(ambitv_log_info, LOGNAME "'%s': appended component '%s'.\n",
         program->name, name);
      
      ret = 0;
   }
   return ret;
}
Ejemplo n.º 17
0
static void
ambitv_v4l2_grab_print_configuration(struct ambitv_source_component* component)
{
   struct v4l2_grab* grab_priv = (struct v4l2_grab*)component->priv;
   
   ambitv_log(ambitv_log_info,
      "\tdevice name:              %s\n"
      "\tbuffers:                  %d\n"
      "\tcrop-top:                 %d\n"
      "\tcrop-right:               %d\n"
      "\tcrop-bottom:              %d\n"
      "\tcrop-left:                %d\n"
      "\tauto-crop luma threshold: %d\n",
         grab_priv->device_name,
         grab_priv->req_buffers,
         grab_priv->crop[0],
         grab_priv->crop[1],
         grab_priv->crop[2],
         grab_priv->crop[3],
         grab_priv->auto_crop_luminance
   );
}
Ejemplo n.º 18
0
int
ambitv_v4l2_grab_start(struct ambitv_source_component* grabber)
{
   int ret = 0;
   
   struct v4l2_grab* grab_priv = (struct v4l2_grab*)grabber->priv;
   if (NULL == grab_priv)
      return -1;
   
   if (grab_priv->fd > -1) {
      ambitv_log(ambitv_log_warn, LOGNAME "grabber is already running.\n");
      return -1;
   }
   
   ret = ambitv_v4l2_grab_open_device(grab_priv);
   if (ret < 0)
      goto fail_open;

   ret = ambitv_v4l2_grab_init_device(grab_priv);
   if (ret < 0)
      goto fail_init;
   
   ret = ambitv_v4l2_grab_start_streaming(grab_priv);
   if (ret < 0)
      goto fail_streaming;
   
   return ret;

fail_streaming:
   ambitv_v4l2_grab_uninit_device(grab_priv);

fail_init:
   ambitv_v4l2_grab_close_device(grab_priv);
   
fail_open:
   return ret;
}
Ejemplo n.º 19
0
static int ambitv_mood_light_processor_configure(struct ambitv_processor_component* mood, int argc, char** argv)
{
	int c, ret = 0;

	struct ambitv_mood_light_processor* mood_priv = (struct ambitv_mood_light_processor*) mood->priv;
	if (NULL == mood_priv)
		return -1;

	static struct option lopts[] =
	{
	{ "speed", required_argument, 0, 's' },
	{ "mode", required_argument, 0, 'm' },
	{ NULL, 0, 0, 0 } };

	while (1)
	{
		c = getopt_long(argc, argv, "", lopts, NULL);

		if (c < 0)
			break;

		switch (c)
		{
		case 's':
		{
			if (NULL != optarg)
			{
				char* eptr = NULL;
				double nbuf = strtod(optarg, &eptr);

				if ('\0' == *eptr && nbuf > 0)
				{
					mood_priv->step = nbuf / 1000.0;
				}
				else
				{
					ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2],
							optarg);
					return -1;
				}
			}

			break;
		}
		case 'm':
		{
			if (NULL != optarg)
			{
				char* eptr = NULL;
				long nbuf = strtol(optarg, &eptr, 10);

				if ('\0' == *eptr && nbuf >= 0)
				{
					mood_priv->mode = nbuf;
				}
				else
				{
					ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2],
							optarg);
					return -1;
				}
			}

			break;
		}

		default:
			break;
		}
	}

	if (optind < argc)
	{
		ambitv_log(ambitv_log_error, LOGNAME "extraneous configuration argument: '%s'.\n", argv[optind]);
		ret = -1;
	}

	return ret;
}
Ejemplo n.º 20
0
static int
ambitv_runloop()
{
   int ret = 0;
   unsigned char c = 0;
   fd_set fds, ex_fds;
   struct timeval tv;
   
   FD_ZERO(&fds); FD_ZERO(&ex_fds);
   FD_SET(STDIN_FILENO, &fds);
   if (conf.gpio_fd >= 0)
      FD_SET(conf.gpio_fd, &ex_fds);
   
   tv.tv_sec   = 0;
   tv.tv_usec  = 500000;
   
   ret = select(MAX(STDIN_FILENO, conf.gpio_fd)+1, &fds, NULL, &ex_fds, &tv);
      
   if (ret < 0) {
      if (EINTR != errno && EWOULDBLOCK != errno) {
         ambitv_log(ambitv_log_error, LOGNAME "error during select(): %d (%s)\n",
            errno, strerror(errno));
         ret = 0;
      }
      
      goto finishLoop;
   }
   
   if (FD_ISSET(STDIN_FILENO, &fds)) {
      ret = read(STDIN_FILENO, &c, 1);
      
      if (ret < 0) {
         if (EINTR != errno && EWOULDBLOCK != errno) {
            ambitv_log(ambitv_log_error, LOGNAME "error during read() on stdin: %d (%s)\n",
               errno, strerror(errno));
         } else
            ret = 0;
         
         goto finishLoop;
      } else if (0 == ret)
         goto finishLoop;
      
      switch (c) {
         case 0x20: { // space
            ret = ambitv_cycle_next_program();
            if (ret < 0)
               goto finishLoop;
            
            break;
         }
         
         case 't': {
            ret = ambitv_toggle_paused();
            if (ret < 0)
               goto finishLoop;
            
            break;
         }
         
         default:
            break;
      }
   }
   
   if (conf.gpio_fd >= 0 && FD_ISSET(conf.gpio_fd, &ex_fds)) {
      char buf[16];
      
      ret = read(conf.gpio_fd, buf, sizeof(*buf));
      lseek(conf.gpio_fd, 0, SEEK_SET);
      
      if (ret < 0) {
         if (EINTR != errno && EWOULDBLOCK != errno) {
            ambitv_log(ambitv_log_error, LOGNAME "failed to read from gpio %d.\n",
               conf.gpio_idx);
            ret = -1;
         } else
            ret = 0;
         
         goto finishLoop;
      } else if (0 == ret)
         goto finishLoop;
      
      if ('0' == buf[0]) {
         struct timeval now;
                         
         (void)gettimeofday(&now, NULL);
         if (0 != conf.last_button_press.tv_sec) {
            long millis = ambitv_millis_between(&now, &conf.last_button_press);
                        
            if (millis <= BUTTON_MILLIS && BUTTON_MILLIS_HYST <= millis)
               conf.button_cnt++;
         } else
            conf.button_cnt++;
                  
         memcpy(&conf.last_button_press, &now, sizeof(struct timeval));
      }
   }
   
   if (conf.button_cnt > 0) {
      struct timeval now;
      (void)gettimeofday(&now, NULL);
      if (0 != conf.last_button_press.tv_sec) {
         long millis = ambitv_millis_between(&now, &conf.last_button_press);
               
         if (millis > BUTTON_MILLIS) {
            if (conf.button_cnt > 1) {
               ret = ambitv_cycle_next_program();
            } else {
               ret = ambitv_toggle_paused();
            }
            
            conf.button_cnt = 0;
            memset(&conf.last_button_press, 0, sizeof(struct timeval));
         }
      }
   }

finishLoop:
   return ret;
}
Ejemplo n.º 21
0
static int
ambitv_v4l2_grab_configure(struct ambitv_source_component* grabber, int argc, char** argv)
{
   int c, ret = 0;
   
   struct v4l2_grab* grab_priv = (struct v4l2_grab*)grabber->priv;
   if (NULL == grab_priv)
      return -1;
   
   static struct option lopts[] = {
      { "video-device", required_argument, 0, 'd' },
      { "buffers", required_argument, 0, 'b' },
      { "crop-top", required_argument, 0, '0' },
      { "crop-right", required_argument, 0, '1' },
      { "crop-bottom", required_argument, 0, '2' },
      { "crop-left", required_argument, 0, '3' },
      { "autocrop-luminance-threshold", required_argument, 0, 'a' },
      { NULL, 0, 0, 0 }
   };
   
   while (1) {      
      c = getopt_long(argc, argv, "", lopts, NULL);
      
      if (c < 0)
         break;
         
      switch (c) {
         case 'd': {
            if (NULL != optarg) {
               if (NULL != grab_priv->device_name)
                  free(grab_priv->device_name);
                              
               grab_priv->device_name = strdup(optarg);
            }
            break;
         }
         
         case 'b': {
            if (NULL != optarg) {
               char* eptr = NULL;
               long nbuf = strtol(optarg, &eptr, 10);
               
               if ('\0' == *eptr) {
                  grab_priv->req_buffers = (int)nbuf;
               } else {
                  ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n",
                     argv[optind-2], optarg);
                  return -1;
               }
            }
            
            break;
         }
         
         case '0':
         case '1':
         case '2':
         case '3': {
            if (NULL != optarg) {
               char* eptr = NULL;
               long nbuf = strtol(optarg, &eptr, 10);
               
               if ('\0' == *eptr && nbuf >= 0) {
                  grab_priv->crop[c-'0'] = (int)nbuf;
               } else {
                  ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n",
                     argv[optind-2], optarg);
                  return -1;
               }
            }
            
            break;
         }
         
         case 'a': {
            if (NULL != optarg) {
               char* eptr = NULL;
               long nbuf = strtol(optarg, &eptr, 10);
               
               if ('\0' == *eptr) {
                  grab_priv->auto_crop_luminance = (int)nbuf;
               } else {
                  ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n",
                     argv[optind-2], optarg);
                  return -1;
               }
            }
            
            break;
         }
         
         default:
            break;
      }
   }
   
   if (optind < argc) {
      ambitv_log(ambitv_log_error, LOGNAME "extraneous configuration argument: '%s'.\n",
         argv[optind]);
      ret = -1;
   }
   
   return ret;
}
Ejemplo n.º 22
0
static int
ambitv_main_configure(int argc, char** argv)
{
   int c, ret = 0;

   static struct option lopts[] = {
      { "button-gpio", required_argument, 0, 'b' },
      { "file", required_argument, 0, 'f' },
      { "help", no_argument, 0, 'h' },
      { "program", required_argument, 0, 'p' },
      { NULL, 0, 0, 0 }
   };

   while (1) {      
      c = getopt_long(argc, argv, "b:f:hp:", lopts, NULL);

      if (c < 0)
         break;

      switch (c) {
         case 'f': {
            if (NULL != optarg) {
               conf.config_path = strdup(optarg);
            }
            
            break;
         }
         
         case 'b':
         case 'p': {
            if (NULL != optarg) {
               char* eptr = NULL;
               long nbuf = strtol(optarg, &eptr, 10);

               if ('\0' == *eptr && nbuf > 0) {
                  if ('b' == c)
                     conf.gpio_idx = (int)nbuf;
                  else if ('p' == c)
                     conf.program_idx = (int)nbuf;
               } else {
                  ambitv_log(ambitv_log_error, LOGNAME "invalid argument for '%s': '%s'.\n",
                     argv[optind-2], optarg);
                  ambitv_usage(argv[0]);
                  return -1;
               }
            }
            
            break;
         }
         
         case 'h': {
            ambitv_usage(argv[0]);
            exit(0);
         }
         
         default:
            break;
      }
   }

   if (optind < argc) {
      ambitv_log(ambitv_log_error, LOGNAME "extraneous configuration argument: '%s'.\n",
         argv[optind]);
      ambitv_usage(argv[0]);
      ret = -1;
   }

   return ret;
}
Ejemplo n.º 23
0
int
main(int argc, char** argv)
{
   int ret = 0, i;
   struct ambitv_conf_parser* parser;
   struct termios tt;
   unsigned long tt_orig;
   
   signal(SIGINT, ambitv_signal_handler);
   signal(SIGTERM, ambitv_signal_handler);
   
   printf(
      "\n"
      "*********************************************************\n"
      "*  ambi-tv: diy ambient lighting for your screen or tv  *\n"
      "*                                         (c) @gkaindl  *\n"
      "*********************************************************\n"
      "\n"
   );
   
   conf.program_idx     = 0;
   conf.gpio_idx        = -1;
   conf.config_path     = DEFAULT_CONFIG_PATH;
   conf.ambitv_on       = 1;
   conf.gpio_fd         = -1;
   conf.running         = 1;
   
   ret = ambitv_main_configure(argc, argv);
   if (ret < 0)
      return -1;
   
   parser = ambitv_conf_parser_create();
   parser->f_handle_block = ambitv_handle_config_block;
   ret = ambitv_conf_parser_read_config_file(parser, conf.config_path);
   ambitv_conf_parser_free(parser);
   
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to parse configuration file, aborting...\n");
      ambitv_usage(argv[0]);
      return -1;
   }
   
   if (ambitv_num_programs <= 0) {
      ambitv_log(ambitv_log_error, LOGNAME "no programs available, aborting...\n");
      return -1;
   }
   
   ambitv_log(ambitv_log_info, LOGNAME "configuration finished, %d programs available.\n",
      ambitv_num_programs);
   
   for (i=0; i<ambitv_num_programs; i++)
      ambitv_log(ambitv_log_info, "\t%s\n", ambitv_programs[i]->name);
   
   if (conf.gpio_idx >= 0) {
      conf.gpio_fd = ambitv_gpio_open_button_irq(conf.gpio_idx);
      if (conf.gpio_fd < 0) {
         ambitv_log(ambitv_log_error, LOGNAME "failed to prepare gpio %d, aborting...\n",
            conf.gpio_idx);
         return -1;
      } else {
         ambitv_log(ambitv_log_info, LOGNAME "using gpio %d as physical button.\n",
            conf.gpio_idx);
      }
   }
   
   tcgetattr(STDIN_FILENO, &tt);
   tt_orig = tt.c_lflag;
   tt.c_lflag &= ~(ICANON | ECHO);
   tcsetattr(STDIN_FILENO, TCSANOW, &tt);
   
   if (conf.program_idx >= ambitv_num_programs) {
      ambitv_log(ambitv_log_error, LOGNAME "program at index %d requested, but only %d programs available. aborting...\n",
         conf.program_idx, ambitv_num_programs);
      goto errReturn;
   }
   
   conf.cur_prog = conf.program_idx;
   
   ret = ambitv_program_run(ambitv_programs[conf.cur_prog]);
   
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to start initial program '%s', aborting...\n",
         ambitv_programs[conf.cur_prog]->name);
      goto errReturn;
   }
   
   ambitv_log(ambitv_log_info, LOGNAME "started initial program '%s'.\n",
      ambitv_programs[conf.cur_prog]->name);
   
   fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
   
   ambitv_log(ambitv_log_info,
      LOGNAME "************* start-up complete\n"
      "\tpress <space> to cycle between programs.\n"
      "\tpress 't' to toggle pause.\n");
   if (conf.gpio_idx >= 0) {
      ambitv_log(ambitv_log_info,
         "\tphysical (gpio) button: click to pause/resume, double-click to cycle between programs.\n");
   }
   
   while (conf.running && ambitv_runloop() >= 0);
   
   ret = ambitv_program_stop_current();
   
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to stop program '%s' before exiting.\n",
         ambitv_programs[conf.cur_prog]->name);
      goto errReturn;
   }

errReturn:   
   tt.c_lflag = tt_orig;
   tcsetattr(STDIN_FILENO, TCSANOW, &tt);
   
   if (conf.gpio_fd >= 0)
      ambitv_gpio_close_button_irq(conf.gpio_fd, conf.gpio_idx);
   
   return ret;
}
Ejemplo n.º 24
0
static int
ambitv_v4l2_grab_read_frame(struct v4l2_grab* grabber)
{
   struct v4l2_buffer buf;
   int ret, ewidth, eheight, ebpl, auto_crop[4] = {0,0,0,0};
   unsigned char* eframe;
   struct vid_buffer* buffers = (struct vid_buffer*)grabber->buffers;
   
   memset(&buf, 0, sizeof(buf));
   
   buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   buf.memory  = V4L2_MEMORY_MMAP;
   
   ret = xioctl(grabber->fd, VIDIOC_DQBUF, &buf);
   if (ret < 0) {
      switch (errno) {
         case EIO:
         case EAGAIN:
            return 0;
         
         default:
            ambitv_log(ambitv_log_error, LOGNAME "failed to dequeue a frame: %d (%s).\n",
               errno, strerror(errno));
            return -errno;
            
      }
   }
   
   if (buf.index >= grabber->num_buffers) {
      ambitv_log(ambitv_log_error, LOGNAME "buffer index is out of expected range.\n");
      return -EINVAL;
   }
   
   if (grabber->auto_crop_luminance >= 0 && ambitv_video_fmt_detect_crop_for_frame(
         &auto_crop[0],
         grabber->auto_crop_luminance,
         buffers[buf.index].start,
         grabber->width,
         grabber->height,
         grabber->bytesperline,
         grabber->fmt) < 0)
      memset(auto_crop, 0, sizeof(int) * 4);
      
   // apply crop
   switch (grabber->fmt) {
      case ambitv_video_format_yuyv: {
         int cx = (grabber->crop[3] & ~1) + auto_crop[3], cy = grabber->crop[0] + auto_crop[0];
         
         ebpl     = grabber->bytesperline ? grabber->bytesperline : 2*grabber->width;
         eframe   = buffers[buf.index].start + cy * ebpl + cx * 2;
         ewidth   = grabber->width - grabber->crop[1] - grabber->crop[3] - auto_crop[1] - auto_crop[3];
         eheight  = grabber->height - grabber->crop[0] - grabber->crop[2] - auto_crop[0] - auto_crop[2];
         break;
      }
      
      default: {
         eframe   = NULL;
         ewidth   = 0;
         eheight  = 0;
         ebpl     = 0;
         break;
      }
   }
   
   ambitv_source_component_distribute_to_active_processors(
      grabber->source_component,
      eframe,
      ewidth,
      eheight,
      ebpl,
      grabber->fmt
   );
   
   ret = xioctl(grabber->fd, VIDIOC_QBUF, &buf);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to enqueue a frame: %d (%s).\n",
         errno, strerror(errno));
   }
   
   return ret;
}
Ejemplo n.º 25
0
static int
ambitv_v4l2_grab_init_mmap(struct v4l2_grab* grabber)
{
   int ret;
   struct v4l2_requestbuffers req;

   memset(&req, 0, sizeof(req));
   
   req.count   = grabber->req_buffers;
   req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   req.memory  = V4L2_MEMORY_MMAP;
   
   ret = xioctl(grabber->fd, VIDIOC_REQBUFS, &req);
   if (ret < 0) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to set up memory mapping for '%s'.\n",
         grabber->device_name);
      return -ENODEV;
   }
   
   if (req.count < 2) {
      ambitv_log(ambitv_log_error, LOGNAME "insufficient buffer memory for '%s'.\n",
         grabber->device_name);
      return -ENOMEM;
   }
   
   grabber->buffers = calloc(req.count, sizeof(struct vid_buffer));
   if (NULL == grabber->buffers) {
      ambitv_log(ambitv_log_error, LOGNAME "failed to allocate buffer memory.\n");
      return -ENOMEM;
   }
   
   struct vid_buffer* buffers = (struct vid_buffer*)grabber->buffers;
   
   for (grabber->num_buffers = 0; grabber->num_buffers < req.count; grabber->num_buffers++) {
      struct v4l2_buffer buf;
      
      memset(&buf, 0, sizeof(buf));
      
      buf.type       = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory     = V4L2_MEMORY_MMAP;
      buf.index      = grabber->num_buffers;
      
      ret = xioctl(grabber->fd, VIDIOC_QUERYBUF, &buf);
      if (ret < 0) {
         ambitv_log(ambitv_log_error, LOGNAME "failed to query video buffer.\n");
         goto fail_buf;
      }
      
      buffers[grabber->num_buffers].length = buf.length;
      buffers[grabber->num_buffers].start = mmap(NULL,
                                        buf.length,
                                        PROT_READ | PROT_WRITE,
                                        MAP_SHARED,
                                        grabber->fd,
                                        buf.m.offset);
      
      if (MAP_FAILED == buffers[grabber->num_buffers].start) {
         ambitv_log(ambitv_log_error, LOGNAME "failed to set up mmap().\n");
         goto fail_buf;
      }
   }
      
   return 0;

fail_buf:
   ambitv_v4l2_grab_free_buffers(grabber);
   
   return -ENODEV;
}
Ejemplo n.º 26
0
int ambitv_parse_led_string(const char* str, int** out_ptr, int* out_len)
{
	int a, b, c, ilen = 0, idx = 0, skip = 0, *s = &a;
	int* list = NULL;

	a = b = 0;
	while (1)
	{
		c = *str++;

		switch (c)
		{
		case 'X':
		case 'x':
		{
			if (&b == s)
			{
				ambitv_log(ambitv_log_error, LOGNAME "unexpected '%c'.\n", c);
				goto errReturn;
			}

			skip = 1;
			break;
		}

		case '-':
		{
			if (&a == s && !skip)
			{
				s = &b;
			}
			else
			{
				ambitv_log(ambitv_log_error, LOGNAME "unexpected '%c'.\n", c);
				goto errReturn;
			}

			break;
		}

		case '\0':
		case '\n':
		case ',':
		{
			if (skip)
			{
				while (a--)
					idx = ambitv_util_append_ptr_to_list((void***) &list, idx, &ilen, (void*) -1);
			}
			else
			{
				int l = a, r = a + 1, ss = 1;

				if (&b == s)
				{
					ss = (l > b) ? -1 : 1;
					r = b + ss;
				}

				do
				{
					idx = ambitv_util_append_ptr_to_list((void***) &list, idx, &ilen, (void*) l);

					l += ss;
				} while (l != r);
			}

			skip = a = b = 0;
			s = &a;

			break;
		}

		default:
		{
			if (skip || c < '0' || c > '9')
			{
				ambitv_log(ambitv_log_error, LOGNAME "unexpected character '%c'.\n", c);
				goto errReturn;
			}

			*s = *s * 10 + (c - '0');
			break;
		}
		}

		if (c == '\0' || c == '\n')
			break;
	}

	*out_ptr = list;
	*out_len = idx;

	return 0;

	errReturn: return -1;
}
Ejemplo n.º 27
0
static int ambitv_audio_processor_configure(struct ambitv_audio_processor_priv* audio, int argc, char** argv)
{
	int c, ret = 0;

	static struct option lopts[] =
	{
	{ "atype", required_argument, 0, 't' },
	{ "sensitivity", required_argument, 0, 's' },
	{ "smoothing", required_argument, 0, 'S' },
	{ "linear", required_argument, 0, 'e' },
	{ "levelcolor", required_argument, 0, 'l' },
	{ NULL, 0, 0, 0 } };

	optind = 0;
	while (1)
	{
		c = getopt_long(argc, argv, "", lopts, NULL);

		if (c < 0)
			break;

		switch (c)
		{
		case 's':
		{
			if (NULL != optarg)
			{
				char* eptr = NULL;
				long nbuf = strtol(optarg, &eptr, 10);

				if ('\0' == *eptr && nbuf > 0)
				{
					audio->sensitivity = (int) nbuf;
				}
				else
				{
					ambitv_log(ambitv_log_error,
					LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2], optarg);
					ret = -1;
					goto errReturn;
				}
			}

			break;
		}

		case 'S':
		{
			if (NULL != optarg)
			{
				char* eptr = NULL;
				long nbuf = strtol(optarg, &eptr, 10);

				if ('\0' == *eptr && nbuf >= 0 && nbuf < 8)
				{
					audio->smoothing = (int) nbuf;
				}
				else
				{
					ambitv_log(ambitv_log_error,
					LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2], optarg);
					ret = -1;
					goto errReturn;
				}
			}

			break;
			case 't':
			{
				if (NULL != optarg)
				{
					char* eptr = NULL;
					long nbuf = strtol(optarg, &eptr, 10);

					if ('\0' == *eptr && nbuf >= 0 && nbuf < ATYPE_NUMATYPES)
					{
						audio->type = (int) nbuf;
					}
					else
					{
						ambitv_log(ambitv_log_error,
						LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2], optarg);
						ret = -1;
						goto errReturn;
					}
				}

				break;
			}
			case 'e':
			{
				if (NULL != optarg)
				{
					char* eptr = NULL;
					long nbuf = strtol(optarg, &eptr, 10);

					if ('\0' == *eptr && nbuf >= 0 && nbuf < 2)
					{
						audio->linear = (int) nbuf;
					}
					else
					{
						ambitv_log(ambitv_log_error,
						LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2], optarg);
						ret = -1;
						goto errReturn;
					}
				}

				break;
			}
			case 'l':
			{
				if (NULL != optarg)
				{
					if ((sscanf(optarg, "%2X%2X%2X", &audio->lcolor.r, &audio->lcolor.g, &audio->lcolor.b) == 3))
					{
						audio->avgcolor = !(audio->lcolor.r || audio->lcolor.g || audio->lcolor.b);
					}
					else
					{
						ambitv_log(ambitv_log_error,
						LOGNAME "invalid argument for '%s': '%s'.\n", argv[optind - 2], optarg);
						ret = -1;
						goto errReturn;
					}

				}

				break;
			}
		}

		default:
			break;
		}
	}

	if (optind < argc)
	{
		ambitv_log(ambitv_log_error, LOGNAME "extraneous argument '%s'.\n", argv[optind]);
		ret = -1;
	}

	errReturn: return ret;
}