mjpg-streamer/plugins/input_http/input_http.c

182 lines
5.9 KiB
C

/*******************************************************************************
# #
# MJPG-streamer allows to stream JPG frames from an input-plugin #
# to several output plugins #
# #
# Copyright (C) 2007 Tom Stöveken #
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
# #
# Modified by Eugene Katsevman, 2011 #
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pthread.h>
#include <syslog.h>
#include "../../mjpg_streamer.h"
#include "../../utils.h"
#include "mjpg-proxy.h"
/* private functions and variables to this plugin */
static pthread_t worker;
static globals *pglobal;
static pthread_mutex_t controls_mutex;
static int plugin_number;
void *worker_thread(void *);
void worker_cleanup(void *);
#define INPUT_PLUGIN_NAME "HTTP Input plugin"
struct extractor_state proxy;
/*** plugin interface functions ***/
/******************************************************************************
Description.: parse input parameters
Input Value.: param contains the command line string and a pointer to globals
Return Value: 0 if everything is ok
******************************************************************************/
int input_init(input_parameter *param, int plugin_no)
{
int i;
if(pthread_mutex_init(&controls_mutex, NULL) != 0) {
IPRINT("could not initialize mutex variable\n");
exit(EXIT_FAILURE);
}
param->argv[0] = INPUT_PLUGIN_NAME;
/* show all parameters for DBG purposes */
for(i = 0; i < param->argc; i++) {
DBG("argv[%d]=%s\n", i, param->argv[i]);
}
init_mjpg_proxy( &proxy );
reset_getopt();
if (parse_cmd_line(&proxy, param->argc, param->argv))
return 1;
pglobal = param->global;
IPRINT("host.............: %s\n", proxy.hostname);
IPRINT("port.............: %s\n", proxy.port);
return 0;
}
/******************************************************************************
Description.: stops the execution of the worker thread
Input Value.: -
Return Value: 0
******************************************************************************/
int input_stop(int id)
{
DBG("will cancel input thread\n");
pthread_cancel(worker);
return 0;
}
/******************************************************************************
Description.: starts the worker thread and allocates memory
Input Value.: -
Return Value: 0
******************************************************************************/
int input_run(int id)
{
pglobal->in[id].buf = malloc(256 * 1024);
if(pglobal->in[id].buf == NULL) {
fprintf(stderr, "could not allocate memory\n");
exit(EXIT_FAILURE);
}
if(pthread_create(&worker, 0, worker_thread, NULL) != 0) {
free(pglobal->in[id].buf);
fprintf(stderr, "could not start worker thread\n");
exit(EXIT_FAILURE);
}
pthread_detach(worker);
return 0;
}
void on_image_received(char * data, int length){
/* copy JPG picture to global buffer */
pthread_mutex_lock(&pglobal->in[plugin_number].db);
pglobal->in[plugin_number].size = length;
memcpy(pglobal->in[plugin_number].buf, data, pglobal->in[plugin_number].size);
/* signal fresh_frame */
pthread_cond_broadcast(&pglobal->in[plugin_number].db_update);
pthread_mutex_unlock(&pglobal->in[plugin_number].db);
}
void *worker_thread(void *arg)
{
/* set cleanup handler to cleanup allocated resources */
pthread_cleanup_push(worker_cleanup, NULL);
proxy.on_image_received = on_image_received;
proxy.should_stop = & pglobal->stop;
connect_and_stream(&proxy);
IPRINT("leaving input thread, calling cleanup function now\n");
pthread_cleanup_pop(1);
return NULL;
}
/******************************************************************************
Description.: this functions cleans up allocated resources
Input Value.: arg is unused
Return Value: -
******************************************************************************/
void worker_cleanup(void *arg)
{
static unsigned char first_run = 1;
if(!first_run) {
DBG("already cleaned up resources\n");
return;
}
first_run = 0;
DBG("cleaning up resources allocated by input thread\n");
close_mjpg_proxy(&proxy);
if(pglobal->in[plugin_number].buf != NULL) free(pglobal->in[plugin_number].buf);
}