ae32b40d8364bb0132131c85b9f02a0dffd70b08
[ffmpeg.git] / libavfilter / libmpcodecs / vf_fixpts.c
1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <inttypes.h>
23
24 #include "config.h"
25 #include "mp_msg.h"
26 #include "help_mp.h"
27
28 #include "img_format.h"
29 #include "mp_image.h"
30 #include "vf.h"
31
32 struct vf_priv_s {
33     double current;
34     double step;
35     int autostart;
36     int autostep;
37     unsigned have_step:1;
38     unsigned print:1;
39 };
40
41 static int put_image(vf_instance_t *vf, mp_image_t *src, double pts)
42 {
43     struct vf_priv_s *p = vf->priv;
44
45     if (p->print) {
46         if (pts == MP_NOPTS_VALUE)
47             mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: undef\n");
48         else
49             mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: %f\n", pts);
50     }
51     if (pts != MP_NOPTS_VALUE && p->autostart != 0) {
52         p->current = pts;
53         if (p->autostart > 0)
54             p->autostart--;
55     } else if (pts != MP_NOPTS_VALUE && p->autostep > 0) {
56         p->step = pts - p->current;
57         p->current = pts;
58         p->autostep--;
59         p->have_step = 1;
60     } else if (p->have_step) {
61         p->current += p->step;
62         pts = p->current;
63     } else {
64         pts = MP_NOPTS_VALUE;
65     }
66     return vf_next_put_image(vf, src, pts);
67 }
68
69 static void uninit(vf_instance_t *vf)
70 {
71     free(vf->priv);
72 }
73
74 static int parse_args(struct vf_priv_s *p, const char *args)
75 {
76     int pos;
77     double num, denom = 1;
78     int iarg;
79
80     while (*args != 0) {
81         pos = 0;
82         if (sscanf(args, "print%n", &pos) == 0 && pos > 0) {
83             p->print = 1;
84         } else if (sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >=
85                    1 && pos > 0) {
86             p->step = denom / num;
87             p->have_step = 1;
88         } else if (sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) {
89             p->current = num;
90         } else if (sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) {
91             p->autostart = iarg;
92         } else if (sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) {
93             p->autostep = iarg;
94         } else {
95             mp_msg(MSGT_VFILTER, MSGL_FATAL,
96                    "fixpts: unknown suboption: %s\n", args);
97             return 0;
98         }
99         args += pos;
100         if (*args == ':')
101             args++;
102     }
103     return 1;
104 }
105
106 static int open(vf_instance_t *vf, char *args)
107 {
108     struct vf_priv_s *p;
109     struct vf_priv_s ptmp = {
110         .current = 0,
111         .step = 0,
112         .autostart = 0,
113         .autostep = 0,
114         .have_step = 0,
115         .print = 0,
116     };
117
118     if (!parse_args(&ptmp, args == NULL ? "" : args))
119         return 0;
120
121     vf->put_image = put_image;
122     vf->uninit = uninit;
123     vf->priv = p = malloc(sizeof(struct vf_priv_s));
124     *p = ptmp;
125     p->current = -p->step;
126
127     return 1;
128 }
129
130 const vf_info_t vf_info_fixpts = {
131     "Fix presentation timestamps",
132     "fixpts",
133     "Nicolas George",
134     "",
135     &open,
136     NULL
137 };