summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/post/planar/Makefile.am2
-rw-r--r--src/post/planar/fill.c165
-rw-r--r--src/post/planar/planar.c6
3 files changed, 171 insertions, 2 deletions
diff --git a/src/post/planar/Makefile.am b/src/post/planar/Makefile.am
index 4bdf8c80f..5eeae5a58 100644
--- a/src/post/planar/Makefile.am
+++ b/src/post/planar/Makefile.am
@@ -7,7 +7,7 @@ libdir = $(XINE_PLUGINDIR)/post
lib_LTLIBRARIES = xineplug_post_planar.la
-xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c boxblur.c \
+xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c boxblur.c \
denoise3d.c eq.c eq2.c unsharp.c pp.c
xineplug_post_planar_la_DEPENDENCIES = $(POSTPROC_LIB)
xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(POSTPROC_LIB) -lm
diff --git a/src/post/planar/fill.c b/src/post/planar/fill.c
new file mode 100644
index 000000000..1fdc2ad8b
--- /dev/null
+++ b/src/post/planar/fill.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2005 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: fill.c,v 1.1 2005/07/18 18:02:51 jstembridge Exp $
+ *
+ * fill video filter by James Stembridge (jstembridge@gmail.com)
+ *
+ * based on invert.c
+ *
+ */
+
+#include "xine_internal.h"
+#include "post.h"
+
+/* plugin class initialization function */
+void *fill_init_plugin(xine_t *xine, void *);
+
+/* plugin class functions */
+static post_plugin_t *fill_open_plugin(post_class_t *class_gen, int inputs,
+ xine_audio_port_t **audio_target,
+ xine_video_port_t **video_target);
+static char *fill_get_identifier(post_class_t *class_gen);
+static char *fill_get_description(post_class_t *class_gen);
+static void fill_class_dispose(post_class_t *class_gen);
+
+/* plugin instance functions */
+static void fill_dispose(post_plugin_t *this_gen);
+
+/* replaced video port functions */
+static vo_frame_t *fill_get_frame(xine_video_port_t *port_gen, uint32_t width,
+ uint32_t height, double ratio,
+ int format, int flags);
+static int fill_draw(vo_frame_t *frame, xine_stream_t *stream);
+
+
+void *fill_init_plugin(xine_t *xine, void *data)
+{
+ post_class_t *class = (post_class_t *)malloc(sizeof(post_class_t));
+
+ if (!class)
+ return NULL;
+
+ class->open_plugin = fill_open_plugin;
+ class->get_identifier = fill_get_identifier;
+ class->get_description = fill_get_description;
+ class->dispose = fill_class_dispose;
+
+ return class;
+}
+
+
+static post_plugin_t *fill_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 *)xine_xmalloc(sizeof(post_plugin_t));
+ post_in_t *input;
+ post_out_t *output;
+ post_video_port_t *port;
+
+ if (!this || !video_target || !video_target[0]) {
+ free(this);
+ return NULL;
+ }
+
+ _x_post_init(this, 0, 1);
+
+ port = _x_post_intercept_video_port(this, video_target[0], &input, &output);
+ port->new_port.get_frame = fill_get_frame;
+ port->new_frame->draw = fill_draw;
+
+ input->xine_in.name = "video";
+ output->xine_out.name = "cropped video";
+
+ this->xine_post.video_input[0] = &port->new_port;
+
+ this->dispose = fill_dispose;
+
+ return this;
+}
+
+static char *fill_get_identifier(post_class_t *class_gen)
+{
+ return "fill";
+}
+
+static char *fill_get_description(post_class_t *class_gen)
+{
+ return "crops left and right of video to fill 4:3 aspect ratio";
+}
+
+static void fill_class_dispose(post_class_t *class_gen)
+{
+ free(class_gen);
+}
+
+static void fill_dispose(post_plugin_t *this)
+{
+ if (_x_post_dispose(this))
+ free(this);
+}
+
+
+static vo_frame_t *fill_get_frame(xine_video_port_t *port_gen, uint32_t width,
+ uint32_t height, double ratio,
+ int format, int flags)
+{
+ post_video_port_t *port = (post_video_port_t *)port_gen;
+ post_plugin_t *this = port->post;
+ vo_frame_t *frame;
+
+ _x_post_rewire(this);
+
+ if (ratio <= 0.0) ratio = (double)width / (double)height;
+
+ if ((ratio > 4.0/3.0) &&
+ (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) {
+ frame = port->original_port->get_frame(port->original_port,
+ width, height, 4.0/3.0, format, flags);
+
+ _x_post_inc_usage(port);
+ frame = _x_post_intercept_video_frame(frame, port);
+
+ frame->ratio = ratio;
+ } else {
+ frame = port->original_port->get_frame(port->original_port,
+ width, height, ratio, format, flags);
+ /* no need to intercept this one, we are not going to do anything with it */
+ }
+
+ return frame;
+}
+
+
+static int fill_draw(vo_frame_t *frame, xine_stream_t *stream)
+{
+ int skip, new_width;
+
+ new_width = (4.0*frame->width) / (3.0*frame->ratio);
+
+ frame->crop_left += (frame->width - new_width) / 2;
+ frame->crop_right += (frame->width + 1 - new_width) / 2;
+ frame->ratio = 4.0/3.0;
+
+ _x_post_frame_copy_down(frame, frame->next);
+ skip = frame->next->draw(frame->next, stream);
+ _x_post_frame_copy_up(frame, frame->next);
+ return skip;
+}
diff --git a/src/post/planar/planar.c b/src/post/planar/planar.c
index 07db7a4e5..2d2c76767 100644
--- a/src/post/planar/planar.c
+++ b/src/post/planar/planar.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: planar.c,v 1.8 2004/04/17 19:54:32 mroi Exp $
+ * $Id: planar.c,v 1.9 2005/07/18 18:02:51 jstembridge Exp $
*
* catalog for planar post plugins
*/
@@ -32,6 +32,9 @@ post_info_t invert_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
extern void *expand_init_plugin(xine_t *xine, void *);
post_info_t expand_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
+extern void *fill_init_plugin(xine_t *xine, void*);
+post_info_t fill_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
+
extern void *eq_init_plugin(xine_t *xine, void *);
post_info_t eq_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
@@ -53,6 +56,7 @@ post_info_t pp_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
{ PLUGIN_POST, 9, "expand", XINE_VERSION_CODE, &expand_special_info, &expand_init_plugin },
+ { PLUGIN_POST, 9, "fill", XINE_VERSION_CODE, &fill_special_info, &fill_init_plugin },
{ PLUGIN_POST, 9, "invert", XINE_VERSION_CODE, &invert_special_info, &invert_init_plugin },
{ PLUGIN_POST, 9, "eq", XINE_VERSION_CODE, &eq_special_info, &eq_init_plugin },
{ PLUGIN_POST, 9, "denoise3d", XINE_VERSION_CODE, &denoise3d_special_info, &denoise3d_init_plugin },