summaryrefslogtreecommitdiffstats
path: root/TOOLS/vf_dlopen/telecine.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-06-18 13:53:44 +0200
committerwm4 <wm4@nowhere>2017-06-18 13:55:40 +0200
commitc680cfd18a09f9a023926db0b3a90f69e8651b37 (patch)
tree12968bbb2fd2443cb6cf1df6403a13bfbeb031b4 /TOOLS/vf_dlopen/telecine.c
parent937dcc25adc20872f7b0751ddfecb89acebd05a2 (diff)
downloadmpv-c680cfd18a09f9a023926db0b3a90f69e8651b37.tar.bz2
mpv-c680cfd18a09f9a023926db0b3a90f69e8651b37.tar.xz
vf_dlopen: remove this filter
It was an attempt to move some MPlayer filters (which were removed from mpv) to external, loadable filters. That worked well, but then the MPlayer filters were ported to libavfilter (independently), so they're available again. Also there is a more widely supported and more advanced loadable filter system supported by mpv: vapoursynth. In conclusion, vf_dlopen is not useful anymore, confusing, and requires quite a bit of code (and probably wouldn't survive the rewrite of the mpv video filter chain, which has to come at some point). It has some implicit dependencies on internal conventions, like possibly the format names dropped in the previous commit. We also deprecated it last release. Drop it.
Diffstat (limited to 'TOOLS/vf_dlopen/telecine.c')
-rw-r--r--TOOLS/vf_dlopen/telecine.c269
1 files changed, 0 insertions, 269 deletions
diff --git a/TOOLS/vf_dlopen/telecine.c b/TOOLS/vf_dlopen/telecine.c
deleted file mode 100644
index 6c5eb4adc0..0000000000
--- a/TOOLS/vf_dlopen/telecine.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (c) 2012 Rudolf Polzer <divVerent@xonotic.org>
- *
- * This file is part of mpv's vf_dlopen examples.
- *
- * mpv's vf_dlopen examples are free software; you can redistribute them and/or
- * modify them under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * mpv's vf_dlopen examples are distributed in the hope that they will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv's vf_dlopen examples; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vf_dlopen.h"
-#include "filterutils.h"
-
-#define MIN(a,b) ((a)<(b)?(a):(b))
-
-/*
- * telecine filter
- *
- * usage: --vf=dlopen=/path/to/telecine.so:t:23
- *
- * Parameter: first parameter is "t" for top field first, "b" for bottom field first
- * then digits (0-9) for how many fields a frame is to be displayed
- *
- * Typical patterns (see http://en.wikipedia.org/wiki/Telecine):
- *
- * NTSC output (30i):
- * 27.5p: 32222
- * 24p: 23 (classic)
- * 24p: 2332 (preferred)
- * 20p: 33
- * 18p: 334
- * 16p: 3444
- *
- * PAL output (25i):
- * 27.5p: 12222
- * 24p: 222222222223 ("Euro pulldown")
- * 16.67p: 33
- * 16p: 33333334
- */
-
-typedef struct {
- int firstfield;
- const char *pattern;
- unsigned int pattern_pos;
- unsigned char *buffer_plane[4];
- size_t buffer_size[4];
- int pts_num;
- int pts_denom;
- int occupied;
- double lastpts_in;
- double lastpts_out;
- int first_frame_of_group;
-} tc_data_t;
-
-static int tc_config(struct vf_dlopen_context *ctx)
-{
- // we may return more than one pic!
- tc_data_t *tc = ctx->priv;
- const char *p;
- int max = 0;
- tc->pts_num = 0;
- tc->pts_denom = 0;
- for (p = tc->pattern; *p; ++p) {
- if (*p - '0' > max)
- max = *p - '0';
- tc->pts_num += 2;
- tc->pts_denom += *p - '0';
- }
- ctx->out_cnt = (max + 1) / 2;
- printf(
- "Telecine pattern %s yields up to %d frames per frame, pts advance factor: %d/%d\n",
- tc->pattern, ctx->out_cnt, tc->pts_num, tc->pts_denom);
- return 1;
-}
-
-static int tc_put_image(struct vf_dlopen_context *ctx)
-{
- tc_data_t *tc = ctx->priv;
-
- unsigned p;
- unsigned np = ctx->outpic[0].planes;
- assert(ctx->inpic.planes == ctx->outpic[0].planes);
-
- int need_reinit = 0;
-
- // fix buffers
- for (p = 0; p < np; ++p) {
- size_t sz = ctx->inpic.planestride[p] * ctx->inpic.planeheight[p];
- if (sz != tc->buffer_size[p]) {
- if (p == 0 && tc->buffer_plane[p])
- printf("WARNING: reinitializing telecine buffers.\n");
- tc->buffer_plane[p] = realloc(tc->buffer_plane[p], sz);
- tc->buffer_size[p] = sz;
- need_reinit = 1;
- }
- }
-
- // too big pts change? reinit
- if (ctx->inpic.pts < tc->lastpts_in || ctx->inpic.pts > tc->lastpts_in + 0.5)
- need_reinit = 1;
-
- if (need_reinit) {
- // initialize telecine
- tc->pattern_pos = 0;
- tc->occupied = 0;
- tc->lastpts_in = ctx->inpic.pts;
- tc->lastpts_out = ctx->inpic.pts;
- }
-
- int len = tc->pattern[tc->pattern_pos] - '0';
- unsigned nout;
- double delta = ctx->inpic.pts - tc->lastpts_in;
- tc->lastpts_in = ctx->inpic.pts;
-
- for (nout = 0; nout < ctx->out_cnt; ++nout) {
- for (p = 0; p < np; ++p) {
- assert(ctx->inpic.planewidth[p] == ctx->outpic[nout].planewidth[p]);
- assert(ctx->inpic.planeheight[p] == ctx->outpic[nout].planeheight[p]);
- }
- }
- nout = 0;
-
- if (tc->pattern_pos == 0 && !tc->occupied) {
- // at the start of the pattern, reset pts
- // printf("pts reset: %f -> %f (delta: %f)\n", tc->lastpts_out, ctx->inpic.pts, ctx->inpic.pts - tc->lastpts_out);
- tc->lastpts_out = ctx->inpic.pts;
- tc->first_frame_of_group = 1;
- }
- ++tc->pattern_pos;
- if (!tc->pattern[tc->pattern_pos])
- tc->pattern_pos = 0;
-
- if (len == 0) {
- // do not output any field from this frame
- return 0;
- }
-
- if (tc->occupied) {
- for (p = 0; p < np; ++p) {
- // fill in the EARLIER field from the buffered pic
- copy_plane(
- &ctx->outpic[nout].plane[p][ctx->outpic[nout].planestride[p] * tc->firstfield],
- ctx->outpic[nout].planestride[p] * 2,
- &tc->buffer_plane[p][ctx->inpic.planestride[p] * tc->firstfield],
- ctx->inpic.planestride[p] * 2,
- MIN(ctx->inpic.planestride[p], ctx->outpic[nout].planestride[p]),
- (ctx->inpic.planeheight[p] - tc->firstfield + 1) / 2
- );
- // fill in the LATER field from the new pic
- copy_plane(
- &ctx->outpic[nout].plane[p][ctx->outpic[nout].planestride[p] * !tc->firstfield],
- ctx->outpic[nout].planestride[p] * 2,
- &ctx->inpic.plane[p][ctx->inpic.planestride[p] * !tc->firstfield],
- ctx->inpic.planestride[p] * 2,
- MIN(ctx->inpic.planestride[p], ctx->outpic[nout].planestride[p]),
- (ctx->inpic.planeheight[p] - !tc->firstfield + 1) / 2
- );
- }
- if (tc->first_frame_of_group)
- tc->first_frame_of_group = 0;
- else
- tc->lastpts_out += (delta * tc->pts_num) / tc->pts_denom;
- ctx->outpic[nout].pts = tc->lastpts_out;
- // printf("pts written: %f\n", ctx->outpic[nout].pts);
- ++nout;
- --len;
- tc->occupied = 0;
- }
-
- while (len >= 2) {
- // output THIS image as-is
- for (p = 0; p < np; ++p)
- copy_plane(
- ctx->outpic[nout].plane[p], ctx->outpic[nout].planestride[p],
- ctx->inpic.plane[p], ctx->inpic.planestride[p],
- MIN(ctx->inpic.planestride[p], ctx->outpic[nout].planestride[p]),
- ctx->inpic.planeheight[p]
- );
- if (tc->first_frame_of_group)
- tc->first_frame_of_group = 0;
- else
- tc->lastpts_out += (delta * tc->pts_num) / tc->pts_denom;
- ctx->outpic[nout].pts = tc->lastpts_out;
- // printf("pts written: %f\n", ctx->outpic[nout].pts);
- ++nout;
- len -= 2;
- }
-
- if (len >= 1) {
- // copy THIS image to the buffer, we need it later
- for (p = 0; p < np; ++p)
- copy_plane(
- &tc->buffer_plane[p][0], ctx->inpic.planestride[p],
- &ctx->inpic.plane[p][0], ctx->inpic.planestride[p],
- ctx->inpic.planestride[p],
- ctx->inpic.planeheight[p]
- );
- tc->occupied = 1;
- }
-
- return nout;
-}
-
-void tc_uninit(struct vf_dlopen_context *ctx)
-{
- tc_data_t *tc = ctx->priv;
- free(tc->buffer_plane[3]);
- free(tc->buffer_plane[2]);
- free(tc->buffer_plane[1]);
- free(tc->buffer_plane[0]);
- free(tc);
-}
-
-int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **argv)
-{
- VF_DLOPEN_CHECK_VERSION(ctx);
-
- const char *a0 = (argc < 1) ? "t" : argv[0];
- const char *a1 = (argc < 2) ? "23" : argv[1];
-
- if (!a0[0] || a0[1] || !a1[0] || argc > 2)
- return -1;
-
- tc_data_t *tc = calloc(1,sizeof(tc_data_t));
-
- if (a0[0] == 't')
- tc->firstfield = 0;
- else if (a0[0] == 'b')
- tc->firstfield = 1;
- else {
- printf("telecine: invalid first field\n");
- free(tc);
- return -1;
- }
-
- tc->pattern = a1;
-
- const char *p;
- for (p = tc->pattern; *p; ++p)
- if (*p < '0' || *p > '9') {
- printf("telecine: invalid pattern\n");
- free(tc);
- return -1;
- }
-
- ctx->priv = tc;
- ctx->format_mapping = NULL; // anything goes
- ctx->config = tc_config;
- ctx->put_image = tc_put_image;
- ctx->uninit = tc_uninit;
-
- return 1;
-}