From 298a8fdd0137cb97df44c4730f848f5b881cb4ab Mon Sep 17 00:00:00 2001 From: Luca Ognibene Date: Fri, 14 Mar 2003 16:14:23 +0000 Subject: * fixes in mosaico pp * a new post plugin You can init switch post plugin with >1 inputs and switch between them at any time CVS patchset: 4410 CVS date: 2003/03/14 16:14:23 --- src/post/mosaico/Makefile.am | 6 +- src/post/mosaico/mosaico.c | 59 +------ src/post/mosaico/switch.c | 381 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+), 57 deletions(-) create mode 100644 src/post/mosaico/switch.c diff --git a/src/post/mosaico/Makefile.am b/src/post/mosaico/Makefile.am index fbfa85604..3b2c26c01 100644 --- a/src/post/mosaico/Makefile.am +++ b/src/post/mosaico/Makefile.am @@ -9,12 +9,16 @@ LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic libdir = $(XINE_PLUGINDIR)/post -lib_LTLIBRARIES = xineplug_post_mosaico.la +lib_LTLIBRARIES = xineplug_post_mosaico.la xineplug_post_switch.la xineplug_post_mosaico_la_SOURCES = mosaico.c xineplug_post_mosaico_la_LIBADD = $(XINE_LIB) xineplug_post_mosaico_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ +xineplug_post_switch_la_SOURCES = switch.c +xineplug_post_switch_la_LIBADD = $(XINE_LIB) +xineplug_post_switch_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ + debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" diff --git a/src/post/mosaico/mosaico.c b/src/post/mosaico/mosaico.c index 7a21d6d07..935647368 100644 --- a/src/post/mosaico/mosaico.c +++ b/src/post/mosaico/mosaico.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: mosaico.c,v 1.9 2003/03/14 12:07:14 skaboy Exp $ + * $Id: mosaico.c,v 1.10 2003/03/14 16:14:24 skaboy Exp $ */ /* @@ -35,9 +35,9 @@ #define DEFAULT_H (150) #define MAXPIP (5) - +/* #define LOG - +*/ /* plugin class initialization function */ static void *mosaico_init_plugin(xine_t *xine, void *); @@ -594,10 +594,6 @@ static int mosaico_draw_2(vo_frame_t *frame, xine_stream_t *stream) xine_video_port_t *pt; xine_post_in_t *in; int i = 0; -#if 0 - int skip; - vo_frame_t *newframe; -#endif in = xine_list_first_content(port->post->input); @@ -617,56 +613,7 @@ static int mosaico_draw_2(vo_frame_t *frame, xine_stream_t *stream) _mosaico_draw_2(frame, output, i-1); -#if 0 - - pthread_mutex_lock(&output->mut1); - pthread_mutex_lock(&output->mut2); - - if(output->saved_frame != NULL) { - - /*printf("get\n");*/ - newframe = output->vo_port->get_frame(output->vo_port, output->saved_frame->width, output->saved_frame->height, - output->saved_frame->ratio, output->saved_frame->format, - VO_BOTH_FIELDS); - /*printf("got\n");*/ - newframe->extra_info->invalid = 1; - newframe->pts = frame->pts; - newframe->duration = output->saved_frame->duration; - newframe->bad_frame = output->saved_frame->bad_frame; - /*newframe->vpts = frame->vpts;*/ - /*vpts = 0; - frame->duration = 90000 * this->samples_per_frame / this->sample_rate; - this->sample_counter -= this->samples_per_frame; - */ - frame_copy_content(newframe, output->saved_frame); - - /*memset(frame->base[0], this->current_yuv_byte, FOO_WIDTH * FOO_HEIGHT * 2); - this->current_yuv_byte += 3; - - frame->draw(frame, stream);*/ - - /*printf("dis\n");*/ - if(newframe->draw) - skip = newframe->draw(newframe, output->saved_frame->stream); - else { - skip = 0; - printf("salta..\n"); - } - newframe->free(newframe); - /*printf("draw2 %d\n", skip);*/ - /*frame->vpts = output->saved_frame->vpts;*/ - post_restore_video_frame(frame, port); - - pthread_mutex_unlock(&output->mut1); - pthread_mutex_unlock(&output->mut2); - - return skip; - } - /*pthread_mutex_unlock(&output->mut1); - pthread_mutex_unlock(&output->mut2);*/ -#else post_restore_video_frame(frame, port); -#endif return 0; } diff --git a/src/post/mosaico/switch.c b/src/post/mosaico/switch.c new file mode 100644 index 000000000..f981d4a86 --- /dev/null +++ b/src/post/mosaico/switch.c @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2000-2002 the xine project + * + * This file is part of xine, a free video player. + * + * xine 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; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 + * + * $Id: switch.c,v 1.1 2003/03/14 16:14:23 skaboy Exp $ + */ + +/* + * simple switch video post plugin + */ + +#include "xine_internal.h" +#include "post.h" + +#define SWVERSION (5) + +/* +#define LOG +*/ + +/* plugin class initialization function */ +static void *switch_init_plugin(xine_t *xine, void *); + +/* plugin catalog information */ +post_info_t switch_special_info = { XINE_POST_TYPE_VIDEO_COMPOSE }; + +plugin_info_t xine_plugin_info[] = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_POST, 2, "switch", SWVERSION, &switch_special_info, &switch_init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + +/* plugin structure */ +typedef struct post_switch_out_s post_switch_out_t; +struct post_switch_out_s { + xine_post_out_t xine_out; + /* keep the stream for open/close when rewiring */ + xine_stream_t *stream; + pthread_mutex_t mut1; + unsigned int pip; + unsigned int selected_source; +}; + +typedef struct post_class_switch_s post_class_switch_t; +struct post_class_switch_s { + post_class_t class; + xine_t *xine; + post_switch_out_t *ip; +}; + +/* plugin class functions */ +static post_plugin_t *switch_open_plugin(post_class_t *class_gen, int inputs, + xine_audio_port_t **audio_target, + xine_video_port_t **video_target); +static char *switch_get_identifier(post_class_t *class_gen); +static char *switch_get_description(post_class_t *class_gen); +static void switch_class_dispose(post_class_t *class_gen); + +/* plugin instance functions */ +static void switch_dispose(post_plugin_t *this_gen); + +/* rewire function */ +static int switch_rewire(xine_post_out_t *output, void *data); + +/* replaced video_port functions */ +static void switch_open(xine_video_port_t *port_gen, xine_stream_t *stream); +static vo_frame_t *switch_get_frame(xine_video_port_t *port_gen, uint32_t width, + uint32_t height, int ratio_code, + int format, int flags); +static void switch_close(xine_video_port_t *port_gen, xine_stream_t *stream); + +/* replaced vo_frame functions */ +static int switch_draw(vo_frame_t *frame, xine_stream_t *stream); + +static void source_changed_cb(void *data, xine_cfg_entry_t *cfg) { + post_class_switch_t *class = (post_class_switch_t *)data; + + if(class->ip) { + post_switch_out_t *this = class->ip; + pthread_mutex_lock(&this->mut1); + + this->selected_source = cfg->num_value; + pthread_mutex_unlock(&this->mut1); + } +} + +static void *switch_init_plugin(xine_t *xine, void *data) +{ + post_class_switch_t *this = (post_class_switch_t *)malloc(sizeof(post_class_switch_t)); + config_values_t *cfg; + char string[255]; + + if (!this) + return NULL; + + this->class.open_plugin = switch_open_plugin; + this->class.get_identifier = switch_get_identifier; + this->class.get_description = switch_get_description; + this->class.dispose = switch_class_dispose; + this->xine = xine; + this->ip = NULL; + cfg = xine->config; + + sprintf(string, "post.switch_active"); + cfg->register_num (cfg, string, 0, _("Default active stream"), NULL, 10, source_changed_cb, this); + + return &this->class; +} + +static post_plugin_t *switch_open_plugin(post_class_t *class_gen, int inputs, + xine_audio_port_t **audio_target, + xine_video_port_t **video_target) +{ + post_plugin_t *this = (post_plugin_t *)malloc(sizeof(post_plugin_t)); + xine_post_in_t *input1 = (xine_post_in_t *)malloc(sizeof(xine_post_in_t)); + xine_post_in_t *input2; + post_switch_out_t *output = (post_switch_out_t *)malloc(sizeof(post_switch_out_t)); + post_class_switch_t *class = (post_class_switch_t *) class_gen; + post_video_port_t *port = NULL, *port2; + int i; + char string[255]; + xine_cfg_entry_t entry; + + + if(inputs < 2) return NULL; + +#ifdef LOG + printf("switch open\n"); +#endif + + if (!this || !input1 || !output || !video_target || !video_target[0]) { + free(this); + free(input1); + free(output); + return NULL; + } + + class->ip = output; + + this->input = xine_list_new(); + this->output = xine_list_new(); + + this->xine_post.audio_input = (xine_audio_port_t **)malloc(sizeof(xine_audio_port_t *)); + this->xine_post.audio_input[0] = NULL; + this->xine_post.video_input = (xine_video_port_t **)malloc(sizeof(xine_video_port_t *) * (inputs+1)); + + for(i=0; iport.open = switch_open; + port2->port.get_frame = switch_get_frame; + port2->port.close = switch_close; + + sprintf(string, "video in %d", i); + input2->name = strdup(string); + input2->type = XINE_POST_DATA_VIDEO; + input2->data = (xine_video_port_t *)&port2->port; + + this->xine_post.video_input[i] = &port2->port; + xine_list_append_content(this->input, input2); + } + + output->xine_out.name = "video out"; + output->xine_out.type = XINE_POST_DATA_VIDEO; + output->xine_out.data = (xine_video_port_t **)&port->original_port; + output->xine_out.rewire = switch_rewire; + output->stream = NULL; + xine_list_append_content(this->output, output); + + pthread_mutex_init(&output->mut1, NULL); + + if(xine_config_lookup_entry(class->xine, "post.switch_active", &entry)) + source_changed_cb(class, &entry); + + this->xine_post.video_input[i+1] = NULL; + this->dispose = switch_dispose; + + return this; +} + +static char *switch_get_identifier(post_class_t *class_gen) +{ + return "switch"; +} + +static char *switch_get_description(post_class_t *class_gen) +{ + return "Switch is a post plugin able to switch at any time from different streams"; +} + +static void switch_class_dispose(post_class_t *class_gen) +{ + free(class_gen); +} + + +static void switch_dispose(post_plugin_t *this) +{ + post_switch_out_t *output = (post_switch_out_t *)xine_list_first_content(this->output); + xine_video_port_t *port = *(xine_video_port_t **)output->xine_out.data; + + if (output->stream) + port->close(port, output->stream); + + free(this->xine_post.audio_input); + free(this->xine_post.video_input); + free(xine_list_first_content(this->input)); + free(xine_list_first_content(this->output)); + xine_list_free(this->input); + xine_list_free(this->output); + free(this); +} + + +static int switch_rewire(xine_post_out_t *output_gen, void *data) +{ + post_switch_out_t *output = (post_switch_out_t *)output_gen; + xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; + /*xine_post_in_t *input = (xine_post_in_t *) data;*/ + xine_video_port_t *new_port = (xine_video_port_t *)data; + + if (!data) + return 0; + if (output->stream) { + /* register our stream at the new output port */ + old_port->close(old_port, output->stream); + new_port->open(new_port, output->stream); + } + /* reconnect ourselves */ + *(xine_video_port_t **)output_gen->data = new_port; + return 1; +} + +static void switch_open(xine_video_port_t *port_gen, xine_stream_t *stream) +{ + post_video_port_t *port = (post_video_port_t *)port_gen; + post_switch_out_t *output = (post_switch_out_t *)xine_list_first_content(port->post->output); + + output->stream = stream; + port->original_port->open(port->original_port, stream); + +} + +static vo_frame_t *switch_get_frame(xine_video_port_t *port_gen, uint32_t width, + uint32_t height, int ratio_code, + int format, int flags) +{ + post_video_port_t *port = (post_video_port_t *)port_gen; + vo_frame_t *frame; + + frame = port->original_port->get_frame(port->original_port, + width, height, ratio_code, format, flags); + post_intercept_video_frame(frame, port); + /* replace with our own draw function */ + frame->draw = switch_draw; + /* decoders should not copy the frames, since they won't be displayed */ + frame->copy = NULL; + return frame; +} + +static void switch_close(xine_video_port_t *port_gen, xine_stream_t *stream) +{ + post_video_port_t *port = (post_video_port_t *)port_gen; + post_switch_out_t *output = (post_switch_out_t *)xine_list_first_content(port->post->output); + output->stream = NULL; + port->original_port->close(port->original_port, stream); +} + +static void frame_copy_content(vo_frame_t *to, vo_frame_t *from) { + int size; + + if((to == NULL)||(from == NULL)) { +#ifdef LOG + printf("Something wrong in frame_copy_content\n"); +#endif + return; + } + + if(to->format != from->format) { +#ifdef LOG + printf("frame_copy_content : buffers have different format\n"); +#endif + return; + } + + switch (from->format) { + case XINE_IMGFMT_YUY2: + size = to->pitches[0] * to->height; + xine_fast_memcpy(to->base[0], from->base[0], size); + break; + + case XINE_IMGFMT_YV12: + /* Y */ + size = to->pitches[0] * to->height; + xine_fast_memcpy(to->base[0], from->base[0], size); + + /* U */ + size = to->pitches[1] * ((to->height + 1) / 2); + xine_fast_memcpy(to->base[1], from->base[1], size); + + /* V */ + size = to->pitches[2] * ((to->height + 1) / 2); + xine_fast_memcpy(to->base[2], from->base[2], size); + + } +} + +static int switch_draw(vo_frame_t *frame, xine_stream_t *stream) +{ + int skip; + post_video_port_t *port = (post_video_port_t *)frame->port; + post_switch_out_t *output = (post_switch_out_t *)xine_list_first_content(port->post->output); + xine_video_port_t *pt; + xine_post_in_t *in; + int i = 0; + vo_frame_t *res_frame; + + pthread_mutex_lock(&output->mut1); + + in = xine_list_first_content(port->post->input); + + while(in != NULL) { + pt = in->data; + if(pt == frame->port) { + + /* printf("trovato %d\n", i); */ + + break; + } + in = xine_list_next_content(port->post->input); + i++; + } + + /* printf("%d %d\n", i, output->selected_source); */ + if(i != output->selected_source) { + post_restore_video_frame(frame, port); + pthread_mutex_unlock(&output->mut1); + return 0; + } + + res_frame = port->original_port->get_frame(port->original_port, + frame->width, frame->height, frame->ratio, frame->format, VO_BOTH_FIELDS); + res_frame->pts = frame->pts; + res_frame->duration = frame->duration; + res_frame->bad_frame = frame->bad_frame; + extra_info_merge(res_frame->extra_info, frame->extra_info); + + + frame_copy_content(res_frame, frame); + + skip = res_frame->draw(res_frame, stream); + + res_frame->free(res_frame); + frame->vpts = res_frame->vpts; + + post_restore_video_frame(frame, port); + + pthread_mutex_unlock(&output->mut1); + + return skip; +} -- cgit v1.2.3