void *_detect_main(){ while(init_waiting_done == FALSE) usleep(100); count_det = 0; connectThread = g_thread_create(_detected_ClientThread, NULL, FALSE, NULL); detect_motion(); }
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; }