summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-08-31 21:41:24 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-08-31 21:41:24 +0000
commit280fa83b42a8f5b605944e5462ace3d91af05c48 (patch)
treec26542ed03dff08ff14e0f694bd65a30fd1d299f /libmpcodecs
parent9bae6276a6aaa34e1c41bf2b8c8e367fc562d824 (diff)
downloadmpv-280fa83b42a8f5b605944e5462ace3d91af05c48.tar.bz2
mpv-280fa83b42a8f5b605944e5462ace3d91af05c48.tar.xz
2 new filters: tile & framestep
patch by Daniele Forghieri ( guru@digitalfantasy.it ) (little cleanup by me) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10752 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/Makefile2
-rw-r--r--libmpcodecs/vf.c4
-rw-r--r--libmpcodecs/vf_framestep.c193
-rw-r--r--libmpcodecs/vf_tile.c314
4 files changed, 512 insertions, 1 deletions
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile
index 76aefea58a..0bf65dcc6f 100644
--- a/libmpcodecs/Makefile
+++ b/libmpcodecs/Makefile
@@ -14,7 +14,7 @@ VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_qtrpza.c vd_raw.c vd_hmblck.c vd_msvidc
VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_xanim.c vd_xvid.c vd_libdv.c vd_qtvideo.c vd_theora.c
VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT)
-VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_pp.c vf_scale.c vf_format.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c
+VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_pp.c vf_scale.c vf_format.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c
ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_rawrgb.c ve_libdv.c ve_xvid.c ve_qtvideo.c ve_nuv.c
NATIVE_SRCS=native/RTjpegN.c native/cinepak.c native/fli.c native/minilzo.c native/msvidc.c native/nuppelvideo.c native/qtrle.c native/qtrpza.c native/qtsmc.c native/roqav.c native/xa_gsm.c native/decode144.c native/decode288.c
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index c3bea5629f..4447595820 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -72,6 +72,8 @@ extern vf_info_t vf_info_dsize;
extern vf_info_t vf_info_decimate;
extern vf_info_t vf_info_softpulldown;
extern vf_info_t vf_info_pullup;
+extern vf_info_t vf_info_framestep;
+extern vf_info_t vf_info_tile;
// list of available filters:
static vf_info_t* filter_list[]={
@@ -133,6 +135,8 @@ static vf_info_t* filter_list[]={
&vf_info_decimate,
&vf_info_softpulldown,
&vf_info_pullup,
+ &vf_info_framestep,
+ &vf_info_tile,
NULL
};
diff --git a/libmpcodecs/vf_framestep.c b/libmpcodecs/vf_framestep.c
new file mode 100644
index 0000000000..3586a99103
--- /dev/null
+++ b/libmpcodecs/vf_framestep.c
@@ -0,0 +1,193 @@
+/*
+ * vf_fstep.c - filter to ouput only 1 every n frame, or only the I (key)
+ * frame
+ *
+ * The parameters are:
+ *
+ * [I] | [i]num
+ *
+ * if you call the filter with I (uppercase) as the parameter
+ * ... -vf framestep=I ...
+ * then ONLY the keyframes are outputted.
+ * For DVD it means, generally, one every 15 frames (IBBPBBPBBPBBPBB), for avi it means
+ * every scene change or every keyint value (see -lavcopts).
+ *
+ * if you call the filter with the i (lowercase)
+ * ... -vf framestep=i ...
+ * then a I! followed by a cr is printed when a key frame (eg Intra frame) is
+ * found, leaving the current line of mplayer/mencoder, where you got the
+ * time, in seconds, and frame of the key. Use this information to split the
+ * AVI.
+ *
+ * After the i or alone you can put a positive number and only one frame every
+ * x (the number you set) is passed on the filter chain, limiting the output
+ * of the frame.
+ *
+ * Example
+ * ... -vf framestep=i20 ...
+ * Dump one every 20 frames, printing on the console when a I-Frame is encounter.
+ *
+ * ... -vf framestep=25
+ * Dump one every 25 frames.
+ *
+ * If you call the filter without parameter it does nothing (except using memory
+ * and resource of your system,. of course).
+ *
+ * This filter doesn' t work like the option -sstep seconds.
+ *
+ * The -sstep seek to the new position, without decoding all frames but,
+ * expecially on avi file coded whith mpeg4 (lavc or xvid or divx), the
+ * seek is not always too much precise.
+ *
+ * This filter simply discard the unwanted frames, so you are very precise in
+ * counting the frame but sometime you use a lot of CPU for nothing.
+ *
+ * As usual it depends on what you're doing.
+ *
+ * Daniele Forghieri ( guru@digitalfantasy.it )
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../config.h"
+#include "../mp_msg.h"
+#include "../cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "../libvo/fastmemcpy.h"
+
+/* Uncomment if you want to print some info on the format */
+// #define DUMP_FORMAT_DATA
+
+/* Private data */
+struct vf_priv_s {
+ /* Current frame */
+ int frame_cur;
+ /* Frame output step, 0 = all */
+ int frame_step;
+ /* Only I-Frame (2), print on I-Frame (1) */
+ int dump_iframe;
+};
+
+/* Filter handler */
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi)
+{
+ mp_image_t *dmpi;
+ struct vf_priv_s *priv;
+ int skip;
+
+ priv = vf->priv;
+
+ /* Print the 'I' if is a intra frame. The \n advance the current line so you got the
+ * current file time (in second) and the frame number on the console ;-)
+ */
+ if (priv->dump_iframe) {
+ if (mpi->pict_type == 1) {
+ printf("I!\n");
+ }
+ }
+
+ /* decide if frame must be shown */
+ if (priv->dump_iframe == 2) {
+ /* Only key frame */
+ skip = mpi->pict_type == 1 ? 0 : 1;
+ }
+ else {
+ /* Only 1 every frame_step */
+ skip = 0;
+ if ((priv->frame_step != 0) && ((priv->frame_cur % priv->frame_step) != 0)) {
+ skip = 1;
+ }
+ }
+ /* Increment current frame */
+ ++priv->frame_cur;
+
+ if (skip == 0) {
+ /* Get image, export type (we don't modify tghe image) */
+ dmpi=vf_get_image(vf->next, mpi->imgfmt,
+ MP_IMGTYPE_EXPORT, 0,
+ mpi->w, mpi->h);
+ /* Copy only the pointer ( MP_IMGTYPE_EXPORT ! ) */
+ dmpi->planes[0] = mpi->planes[0];
+ dmpi->planes[1] = mpi->planes[1];
+ dmpi->planes[2] = mpi->planes[2];
+
+ dmpi->stride[0] = mpi->stride[0];
+ dmpi->stride[1] = mpi->stride[1];
+ dmpi->stride[2] = mpi->stride[2];
+
+ dmpi->width = mpi->width;
+ dmpi->height = mpi->height;
+
+ /* Chain to next filter / output ... */
+ return vf_next_put_image(vf, dmpi);
+ }
+
+ /* Skip the frame */
+ return 0;
+}
+
+static void uninit(struct vf_instance_s* vf)
+{
+ /* Free private data */
+ free(vf->priv);
+}
+
+/* Main entry funct for the filter */
+static int open(vf_instance_t *vf, char* args)
+{
+ struct vf_priv_s *p;
+
+ vf->put_image = put_image;
+ vf->uninit = uninit;
+ vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+ vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+ if (p == NULL) {
+ return(0);
+ }
+
+ if (args != NULL) {
+#ifdef DUMP_FORMAT_DATA
+ if (*args == 'd') {
+ p->dump_iframe = 3;
+ }
+ else
+#endif
+ if (*args == 'I') {
+ /* Dump only KEY (ie INTRA) frame */
+ p->dump_iframe = 2;
+ }
+ else {
+ if (*args == 'i') {
+ /* Print a 'I!' when a i-frame is encounter */
+ p->dump_iframe = 1;
+ ++args;
+ }
+
+ if (*args != '\0') {
+ p->frame_step = atoi(args);
+ if (p->frame_step <= 0) {
+ printf("Error parsing argument\n");
+ return(0);
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+vf_info_t vf_info_framestep = {
+ "Dump one every n / key frames",
+ "framestep",
+ "Daniele Forghieri",
+ "",
+ open,
+ NULL
+};
+
+
diff --git a/libmpcodecs/vf_tile.c b/libmpcodecs/vf_tile.c
new file mode 100644
index 0000000000..ef9c2fcda1
--- /dev/null
+++ b/libmpcodecs/vf_tile.c
@@ -0,0 +1,314 @@
+/*
+ * vf_tile.c - filter to tile a serie of image in a single, bigger, image
+ *
+ * The parameters are:
+ *
+ * xtile: number of tile on the x axis (5)
+ * ytile: number of tile on the y axis (5)
+ * xytile: when write the image, it can be different then xtile * ytile
+ * (for example you can write 8 * 7 tile, writing the file every
+ * 50 frame, to have one image every 2 seconds @ 25 fps ).
+ * start: pixel at the start (x/y), default 2
+ * delta: pixel between 2 tile, (x/y), default 4
+ *
+ * For example a valid command line is:
+ * ... -vf tile=10:5:-1:4:8 ...
+ * that make images of 10 * 5 tiles, with 4 pixel at the beginning and
+ * 8 pixel between tiles.
+ *
+ * The default command is:
+ * ... -vf tile=5:5:25:2:4
+ *
+ * If you omit a parameter or put a value less then 0, the default is used.
+ * ... -vf tile=10:5::-1:10
+ *
+ * You can also stop when you're ok
+ * ... -vf tile=10:5
+ * (and this is probably the option you will use more often ...)
+ *
+ * Probably is good to put the scale filter before the tile :-)
+ *
+ * Daniele Forghieri ( guru@digitalfantasy.it )
+ */
+
+// strtoi memcpy_pic
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../config.h"
+#include "../mp_msg.h"
+#include "../cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "../libvo/fastmemcpy.h"
+
+/* external */
+extern int verbose;
+
+/* private data */
+struct vf_priv_s {
+ /* configuration data */
+ /* Number on hor/ver tiles */
+ int xtile;
+ int ytile;
+ /* When write the whole frame (default = xtile * ytile) */
+ int xytile;
+ /* pixel at start / end (default = 4) */
+ int start;
+ /* pixel between image (default = 2) */
+ int delta;
+// /* Background color, in destination format */
+// int bkgSet;
+
+ /* Work data */
+ int frame_cur;
+};
+
+
+static int config(struct vf_instance_s* vf,
+ int width, int height, int d_width, int d_height,
+ unsigned int flags, unsigned int outfmt){
+
+ struct vf_priv_s *priv;
+ int xw;
+ int yh;
+
+ /* Calculate new destination size */
+ priv = vf->priv;
+ xw = priv->start * 2 +
+ priv->xtile * width +
+ (priv->xtile - 1) * priv->delta;
+ yh = priv->start * 2 +
+ priv->ytile * height +
+ (priv->ytile - 1) * priv->delta;
+
+ mp_msg(MSGT_VFILTER,MSGL_V,"vf_tile:config size set to %d * %d\n", xw, yh);
+
+ return vf_next_config(vf, xw, yh, xw, yh, flags, outfmt);
+}
+
+/* Filter handler */
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi)
+{
+ mp_image_t *dmpi;
+ struct vf_priv_s *priv;
+ int t;
+ int xw;
+ int yh;
+ int xi;
+ int yi;
+ int by;
+ int dw;
+
+ /* Calculate new size */
+ priv = vf->priv;
+ xw = priv->start * 2 +
+ priv->xtile * mpi->w +
+ (priv->xtile - 1) * priv->delta;
+ yh = priv->start * 2 +
+ priv->ytile * mpi->h+
+ (priv->ytile - 1) * priv->delta;
+
+ /* Get the big image! */
+ dmpi=vf_get_image(vf->next, mpi->imgfmt,
+ MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE,
+ xw, yh);
+
+ /* bytes x pixel & bytes x line */
+ if (mpi->flags & MP_IMGFLAG_PLANAR) {
+ by = 1;
+ dw = mpi->w;
+ }
+ else {
+ by = (mpi->bpp + 7) / 8;
+ dw = mpi->w * by;
+ }
+ /* Index position */
+ t = priv->frame_cur % priv->xytile;
+// if ((t == 0) && (bkg != 0)) {
+// /* First frame, delete the background */
+//
+// }
+
+ /* Position of image */
+ xi = priv->start + (mpi->w + priv->delta) * (t % priv->xtile);
+ yi = priv->start + (mpi->h + priv->delta) * (t / priv->xtile);
+
+ /* Copy first (or only) plane */
+ memcpy_pic( dmpi->planes[0] + xi * by + yi * dmpi->stride[0],
+ mpi->planes[0],
+ dw,
+ mpi->h,
+ dmpi->stride[0],
+ mpi->stride[0]);
+
+ if (mpi->flags & MP_IMGFLAG_PLANAR) {
+ /* Copy the other 2 planes */
+ memcpy_pic( dmpi->planes[1] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[1],
+ mpi->planes[1],
+ mpi->chroma_width,
+ mpi->chroma_height,
+ dmpi->stride[1],
+ mpi->stride[1]);
+ memcpy_pic( dmpi->planes[2] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[2],
+ mpi->planes[2],
+ mpi->chroma_width,
+ mpi->chroma_height,
+ dmpi->stride[2],
+ mpi->stride[2]);
+ }
+
+ /* Increment current frame */
+ ++priv->frame_cur;
+
+ if (t == priv->xytile - 1) {
+ /* Display the composition */
+ dmpi->width = xw;
+ dmpi->height = yh;
+ return vf_next_put_image(vf, dmpi);
+ }
+ else {
+ /* Skip the frame */
+ return(0);
+ }
+}
+
+static void uninit(struct vf_instance_s* vf)
+{
+ /* free local data */
+ free(vf->priv);
+}
+
+/* rgb/bgr 15->32 supported & some Yxxx */
+static int query_format(struct vf_instance_s* vf, unsigned int fmt)
+{
+ switch (fmt) {
+ /* rgb 15 -> 32 bit */
+ case IMGFMT_RGB15:
+ case IMGFMT_RGB16:
+ case IMGFMT_RGB24:
+ case IMGFMT_RGB32:
+ /* bgr 15 -> 32 bit */
+ case IMGFMT_BGR15:
+ case IMGFMT_BGR16:
+ case IMGFMT_BGR24:
+ case IMGFMT_BGR32:
+ /* Various Yxxx Formats */
+ case IMGFMT_444P:
+ case IMGFMT_422P:
+ case IMGFMT_411P:
+ case IMGFMT_YUY2:
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_YVU9:
+ case IMGFMT_IF09:
+ case IMGFMT_IYUV:
+ return vf_next_query_format(vf, fmt);
+ }
+ return 0;
+}
+
+/* Get an integer from the string pointed by s, adjusting s.
+ * If the value is less then 0 def_val is used.
+ * Return 0 for ok
+ *
+ * Look below ( in open(...) ) for a use ...
+ */
+static int parse_int(char **s, int *rt, int def_val)
+{
+
+ int t = 0;
+
+ if (**s) {
+ /* Get value (dec, hex or octal) */
+ t = strtol( *s, s, 0 );
+
+ /* Use default */
+ if (t < 0) {
+ t = def_val;
+ }
+
+ if (**s == ':') {
+ /* Point to next character (problably a digit) */
+ ++(*s);
+ }
+ else if (**s != '\0') {
+ /* Error, we got some wrong char */
+ return(1);
+ }
+ }
+ else {
+ t = def_val;
+ }
+
+ *rt = t;
+ return(0);
+
+}
+
+/* Main entry funct for the filter */
+static int open(vf_instance_t *vf, char* args)
+{
+ struct vf_priv_s *p;
+ int er;
+
+ vf->put_image = put_image;
+ vf->query_format = query_format;
+ vf->config = config;
+ vf->uninit = uninit;
+ vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+ /* Private data */
+ vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+ if (p == NULL) {
+ return(0);
+ }
+
+ if (args == NULL) {
+ /* Use the default */
+ args = "";
+ }
+ /* Parse all the arguments */
+ er = parse_int( &args, &p->xtile, 5 );
+ er |= parse_int( &args, &p->ytile, 5 );
+ er |= parse_int( &args, &p->xytile, 0 );
+ er |= parse_int( &args, &p->start, 2 );
+ er |= parse_int( &args, &p->delta, 4 );
+// er |= parse_int( &args, &p->bkgSet, 0 );
+
+ if (er) {
+ printf("Error parsing argument\n");
+ return(0);
+ }
+ /* Load some default */
+ if ((p->xytile <= 0) || (p->xytile > p->xtile * p->ytile)) {
+ p->xytile = p->xtile * p->ytile;
+ }
+
+ /* Say what happen: use mp_msg(...)? */
+ if (verbose) {
+ printf("vf_tile: tiling %d * %d, output every %d frames\n",
+ p->xtile,
+ p->ytile,
+ p->xytile);
+ printf("vf_tile: start pixel %d, delta pixel %d\n",
+ p->start,
+ p->delta);
+// printf("vf_tile: background 0x%x\n",
+// p->bkgSet);
+ }
+ return 1;
+}
+
+vf_info_t vf_info_tile = {
+ "Make a single image tiling x/y images",
+ "tile",
+ "Daniele Forghieri",
+ "",
+ open,
+ NULL
+};