diff --git a/Makefile.in b/Makefile.in index 925603369..3cf50d050 100644 --- a/Makefile.in +++ b/Makefile.in @@ -655,10 +655,6 @@ rtsp_server: @RTSP_SERVER_LIB_TARGET@ mkdir -p lib/ultragrid $(LINKER) $(LDFLAGS) -shared -Wl,-soname,video_rxtx_h264.so.@video_rxtx_abi_version@ $^ @RTSP_SERVER_LIB@ -o $@ -@VCAPTURE_FILTER_RESIZE_LIB_TARGET@: @RESIZE_OBJ@ - mkdir -p lib/ultragrid - $(LINKER) $(LDFLAGS) -shared -Wl,-soname,vidcap_resize.so.@vcapture_filter_abi_version@ $^ @RESIZE_LIB@ -o $@ - install: all $(INSTALL) -d -m 755 $(DESTDIR)/$(bindir) $(INSTALL) -m 755 bin/uv $(DESTDIR)/$(bindir) diff --git a/configure.ac b/configure.ac index 66dfea1b9..ffc47fb3c 100644 --- a/configure.ac +++ b/configure.ac @@ -1343,9 +1343,8 @@ case $host in OPENCV_INC= RESIZE_LIB="${OPENCV_LIBS}" RESIZE_OBJ="src/capture_filter/resize.o src/capture_filter/resize_utils.o" - AC_SUBST(VCAPTURE_FILTER_RESIZE_LIB_TARGET, "lib/ultragrid/vcapfilter_resize.so.$vcapture_filter_abi_version") - LIB_TARGETS="$LIB_TARGETS $VCAPTURE_FILTER_RESIZE_LIB_TARGET" + LIB_TARGETS="$LIB_TARGETS" LIB_OBJS="$LIB_OBJS $RESIZE_OBJ" opencv=yes diff --git a/src/capture_filter.cpp b/src/capture_filter.cpp index d4b859f19..e876ce27e 100644 --- a/src/capture_filter.cpp +++ b/src/capture_filter.cpp @@ -55,6 +55,9 @@ #include "capture_filter/logo.h" #include "capture_filter/none.h" #include "capture_filter/scale.h" +#ifdef HAVE_OPENCV +#include "capture_filter/resize.h" +#endif #include @@ -76,6 +79,9 @@ struct init_capture_filters { &capture_filter_logo, &capture_filter_none, &capture_filter_scale, +#ifdef HAVE_OPENCV + &capture_filter_resize, +#endif }; } } diff --git a/src/capture_filter/resize.cpp b/src/capture_filter/resize.cpp index 3a5725933..dca03e990 100644 --- a/src/capture_filter/resize.cpp +++ b/src/capture_filter/resize.cpp @@ -91,7 +91,7 @@ static int init(struct module *parent, const char *cfg, void **state) UNUSED(parent); int n; - int denom = 1;; + int denom = 1; if(cfg) { if(strcasecmp(cfg, "help") == 0) { usage(); @@ -107,15 +107,20 @@ static int init(struct module *parent, const char *cfg, void **state) } if(n <= 0 || denom <= 0){ - printf("\n[RESIZE ERROR] numerator and denominator resize factors must be greater than zero!\n"); + printf("\n[RESIZE ERROR] resize factors must be greater than zero!\n"); usage(); return -1; } if(n/denom > 1.0){ - printf("\n[RESIZE ERROR] numerator and denominator resize factors must be lower than 1 (only downscaling is supported)\n"); + printf("\n[RESIZE ERROR] resize factors must be lower than 1 (only downscaling is supported)\n"); usage(); return -1; } + if(n == denom){ + printf("\n[RESIZE ERROR] resize factors must be lower than 1 (only downscaling is supported)\n"); + usage(); + return -1; + } struct state_resize *s = (state_resize*) calloc(1, sizeof(struct state_resize)); s->reinit = 1; @@ -150,7 +155,7 @@ static struct video_frame *filter(void *state, struct video_frame *in) for(i=0; iframe->tile_count;i++){ if(s->reinit==1){ - //TODO: all tiles could have different sizes and other color specs different than UYVY and RGB + //TODO: all tiles could have different sizes and other color specs different than UYVY, YUYV and RGB s->orig_width = s->frame->tiles[i].width; s->orig_height = s->frame->tiles[i].height; s->frame->tiles[i].width *= s->num; @@ -175,23 +180,18 @@ static struct video_frame *filter(void *state, struct video_frame *in) } } + VIDEO_FRAME_DISPOSE(in); + return s->frame; } -static struct capture_filter_info capture_filter_resize = { +struct capture_filter_info capture_filter_resize = { "resize", init, done, filter, }; -static void init(void) __attribute__((constructor)); - -static void init(void) -{ - register_video_capture_filter(&capture_filter_resize); -} - #ifdef __cplusplus } #endif diff --git a/src/capture_filter/resize.h b/src/capture_filter/resize.h new file mode 100644 index 000000000..cbad20e54 --- /dev/null +++ b/src/capture_filter/resize.h @@ -0,0 +1,51 @@ +/* + * FILE: capture_filter/resize.h + * AUTHORS: Gerard Castillo + * Marc Palau + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the Fundació i2CAT, + * Internet I Innovació Digital a Catalunya. This product also includes + * software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef CAPTURE_FILTER_RESIZE_H_ +#define CAPTURE_FILTER_RESIZE_H_ + +struct capture_filter_info; +extern struct capture_filter_info capture_filter_resize; + +#endif // CAPTURE_FILTER_RESIZE_H_ diff --git a/src/capture_filter/resize_utils.cpp b/src/capture_filter/resize_utils.cpp index a35885891..dfd720fd1 100644 --- a/src/capture_filter/resize_utils.cpp +++ b/src/capture_filter/resize_utils.cpp @@ -47,7 +47,7 @@ using namespace cv; int resize_frame(char *indata, codec_t in_color, char *outdata, unsigned int *data_len, unsigned int width, unsigned int height, double scale_factor){ - assert(in_color == UYVY || in_color == RGB); + assert(in_color == UYVY || in_color == YUYV || in_color == RGB); int res = 0; Mat out, in, rgb; @@ -63,6 +63,12 @@ int resize_frame(char *indata, codec_t in_color, char *outdata, unsigned int *da cvtColor(in, rgb, CV_YUV2RGB_UYVY); resize(rgb, out, Size(0,0), scale_factor, scale_factor, INTER_LINEAR); break; + case YUYV: + in.create(height, width, CV_8UC2); + in.data = (uchar*)indata; + cvtColor(in, rgb, CV_YUV2RGB_YUYV); + resize(rgb, out, Size(0,0), scale_factor, scale_factor, INTER_LINEAR); + break; case RGB: in.create(height, width, CV_8UC3); in.data = (uchar*)indata; diff --git a/src/control_socket.cpp b/src/control_socket.cpp index b22070d05..50d8e5e9a 100644 --- a/src/control_socket.cpp +++ b/src/control_socket.cpp @@ -161,7 +161,7 @@ static fd_t create_internal_port(int *port) } -int control_init(int port, struct control_state **state, struct module *root_module) +int control_init(int port, int connection_type, struct control_state **state, struct module *root_module) { control_state *s = new control_state; @@ -174,8 +174,8 @@ int control_init(int port, struct control_state **state, struct module *root_mod s->mod.cls = MODULE_CLASS_CONTROL; s->mod.priv_data = s; - if(port == -1) { - s->network_port = DEFAULT_CONTROL_PORT; + if(connection_type == 0) { + s->network_port = port; s->connection_type = SERVER; } else { s->network_port = port; diff --git a/src/control_socket.h b/src/control_socket.h index 1284e326a..c22969b83 100644 --- a/src/control_socket.h +++ b/src/control_socket.h @@ -53,12 +53,12 @@ struct control_state; struct module; struct stats; -#define CONTROL_DEFAULT_PORT -1 +#define CONTROL_DEFAULT_PORT 5054 /** * @retval 0 if success */ -int control_init(int port, struct control_state **state, struct module *root_module); +int control_init(int port, int connection_type, struct control_state **state, struct module *root_module); void control_start(struct control_state *state); void control_done(struct control_state *s); void control_add_stats(struct control_state *state, struct stats *stats); diff --git a/src/hd-rum-translator/hd-rum-translator.c b/src/hd-rum-translator/hd-rum-translator.c index 44a02a6fc..a01c927d9 100644 --- a/src/hd-rum-translator/hd-rum-translator.c +++ b/src/hd-rum-translator/hd-rum-translator.c @@ -547,7 +547,7 @@ int main(int argc, char **argv) module_register(&state.replicas[i].mod, &state.mod); } - if(control_init(control_port, &control_state, &state.mod) != 0) { + if(control_init(control_port, 0, &control_state, &state.mod) != 0) { fprintf(stderr, "Warning: Unable to create remote control.\n"); if(control_port != CONTROL_DEFAULT_PORT) { return EXIT_FAILURE; diff --git a/src/main.cpp b/src/main.cpp index ed111a83f..de686947b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -201,6 +201,9 @@ static void usage(void) printf(" address(es)\n\n"); printf("\t--verbose \tprint verbose messages\n"); printf("\n"); + printf("\t--control-port [:0|1] \tset control port (default port: 5054)\n"); + printf("\t \tconnection types: 0- Server (default), 1- Client\n"); + printf("\n"); printf ("\t-d \tselect display device, use '-d help'\n"); printf("\t \tto get list of supported devices\n"); @@ -448,6 +451,7 @@ int main(int argc, char *argv[]) char *sage_opts = NULL; int control_port = CONTROL_DEFAULT_PORT; + int connection_type = 0; struct control_state *control = NULL; const char *audio_host = NULL; @@ -779,7 +783,22 @@ int main(int argc, char *argv[]) requested_encryption = optarg; break; case OPT_CONTROL_PORT: - control_port = atoi(optarg); + if (strchr(optarg, ':')) { + char *save_ptr = NULL; + char *tok; + control_port = atoi(strtok_r(optarg, ":", &save_ptr)); + connection_type = atoi(strtok_r(NULL, ":", &save_ptr)); + if(connection_type < 0 || connection_type > 1){ + usage(); + return EXIT_FAIL_USAGE; + } + if ((tok = strtok_r(NULL, ":", &save_ptr))) { + usage(); + return EXIT_FAIL_USAGE; + } + } else { + control_port = atoi(optarg); + } break; case OPT_VERBOSE: verbose = true; @@ -863,7 +882,7 @@ int main(int argc, char *argv[]) } #endif - if(control_init(control_port, &control, &root_mod) != 0) { + if(control_init(control_port, connection_type, &control, &root_mod) != 0) { fprintf(stderr, "%s Unable to initialize remote control!\n", control_port != CONTROL_DEFAULT_PORT ? "Warning:" : "Error:"); if(control_port != CONTROL_DEFAULT_PORT) { diff --git a/src/video_frame.c b/src/video_frame.c index fe823d08a..6443c1212 100644 --- a/src/video_frame.c +++ b/src/video_frame.c @@ -133,6 +133,7 @@ void vf_data_deleter(struct video_frame *buf) return; for(unsigned int i = 0u; i < buf->tile_count; ++i) { + if(!buf->tiles[i].data) free(buf->tiles[i].data); } }