Пример #1
0
void *_detect_main(){
	while(init_waiting_done == FALSE)
		usleep(100);
	count_det = 0;
	connectThread = g_thread_create(_detected_ClientThread, NULL, FALSE, NULL);
	detect_motion();
}
Пример #2
0
void *recorder_thread(void *ptr) {
  struct camera *cam = (struct camera *)ptr;
  struct motion_detection md;
  AVPacket packet;
  AVFrame *frame;
  int got_frame, ret;
  unsigned int cnt = 0;
  time_t first_activity = 0;
  time_t last_activity = 0;

  if(open_camera(cam) < 0)
    return NULL;
  if(open_output(cam) < 0)
    return NULL;

  av_dump_format(cam->context, 0, cam->context->filename, 0);
  av_dump_format(cam->output_context, 0, cam->output_context->filename, 1);

  md.cam = cam;

  md.prev = cvCreateImage(cvSize(cam->codec->width, cam->codec->height), IPL_DEPTH_8U, 1);
  md.cur  = cvCreateImage(cvSize(cam->codec->width, cam->codec->height), IPL_DEPTH_8U, 1);
  md.silh = cvCreateImage(cvSize(cam->codec->width, cam->codec->height), IPL_DEPTH_8U, 1);
  cvZero(md.prev);
  cvZero(md.cur);
  cvZero(md.silh);

  md.img_convert_ctx = sws_getContext(
    cam->codec->width, cam->codec->height, cam->codec->pix_fmt,
    cam->codec->width, cam->codec->height, PIX_FMT_GRAY8,
    SWS_BICUBIC, NULL, NULL, NULL);
  md.buffer = (uint8_t*)av_malloc(3 * cam->codec->width * cam->codec->height);

  int got_key_frame = 0, first_detection = 1;
  frame = avcodec_alloc_frame();
  if(!frame) {
    av_err_msg("avcodec_alloc_frame", 0);
    return NULL;
  }

  while(1) {
    cam->last_io = time(NULL);

    if((ret = av_read_frame(cam->context, &packet)) < 0) {
      if(ret == AVERROR_EOF) break;
      else av_err_msg("av_read_frame", ret);
    }

    if(packet.stream_index == cam->video_stream_index) {
      // start on keyframe
      if(!got_key_frame && !(packet.flags & AV_PKT_FLAG_KEY)) {
        continue;
      }
      got_key_frame = 1;

      avcodec_get_frame_defaults(frame);
      got_frame = 0;

      cnt = (cnt + 1) % cam->analize_frames;
      if(cnt == 0) {
        if((ret = avcodec_decode_video2(cam->codec, frame, &got_frame, &packet)) < 0)
          av_err_msg("avcodec_decode_video2", ret);

        if(got_frame) {
          if(detect_motion(&md, frame)) {
            if(first_activity == 0) first_activity = time(NULL);
            last_activity = time(NULL);
          } else {
            if(first_activity > 0 && time(NULL) - last_activity > cam->motion_delay) {
              if(!first_detection)
                db_create_event(cam->id, first_activity, last_activity);
              else
                first_detection = 0;
              first_activity = 0;
            }
          }
        }

        if(time(NULL) - cam->last_screenshot > 60 && (packet.flags & AV_PKT_FLAG_KEY)) {
          char fname[128];
          snprintf(fname, sizeof(fname), "%s/%s/screenshot.png", store_dir, cam->name);
          cvSaveImage(fname, md.cur, 0);
          cam->last_screenshot = time(NULL);
        }
      }

      packet.stream_index = cam->output_stream->id;
      if((ret = av_write_frame(cam->output_context, &packet)) < 0)
        av_err_msg("av_write_frame", ret);

      pthread_mutex_lock(&cam->consumers_lock);
      for(l1 *p = cam->cam_consumers_list; p != NULL; p = p->next) {
        struct cam_consumer *consumer = (struct cam_consumer *)p->value;
        if(!consumer->screen->active)
          continue;

        if(consumer->screen->tmpl_size == 1) {
          packet.stream_index = 0;
          if((ret = av_write_frame(consumer->screen->rtp_context, &packet)) < 0)
            av_err_msg("av_write_frame", ret);
        } else {
          if(!got_frame) {
            if((ret = avcodec_decode_video2(cam->codec, frame, &got_frame, &packet)) < 0) {
              av_err_msg("avcodec_decode_video2", ret);
              break;
            }
          }
          if(got_frame)
            copy_frame_to_consumer(frame, cam->codec->height, consumer);
        }
      }
      pthread_mutex_unlock(&cam->consumers_lock);
    }

    av_free_packet(&packet);
    
    if(!cam->active) {
      break;
    }

    if(time(NULL) - cam->file_started_at > 60 * 60) {
      db_update_videofile(cam);
      close_output(cam);
      open_output(cam);
      got_key_frame = 0;
    }
  }

  db_update_videofile(cam);
  close_output(cam);

  if((ret = avcodec_close(cam->codec)) < 0)
    av_err_msg("avcodec_close", ret);
  avformat_close_input(&cam->context);
  av_free(frame);

  cvReleaseImage(&md.prev);
  cvReleaseImage(&md.cur);
  cvReleaseImage(&md.silh);
  av_free(md.buffer);
  sws_freeContext(md.img_convert_ctx);

  return NULL;
}