1 /*
2  *  filter_slowmo.c
3  *
4  *  Copyright (C) Thomas Oestreich - August 2002
5  *
6  *  This file is part of transcode, a video stream processing tool
7  *
8  *  transcode is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2, or (at your option)
11  *  any later version.
12  *
13  *  transcode is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with GNU Make; see the file COPYING.  If not, write to
20  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */
23 
24 #define MOD_NAME    "filter_slowmo.so"
25 #define MOD_VERSION "v0.3.1 (2006-09-10)"
26 #define MOD_CAP     "very cheap slow-motion effect"
27 #define MOD_AUTHOR  "Tilmann Bitterberg"
28 
29 #include "transcode.h"
30 #include "filter.h"
31 #include "libtc/libtc.h"
32 #include "libtc/optstr.h"
33 
34 /*-------------------------------------------------
35  *
36  * single function interface
37  *
38  *-------------------------------------------------*/
39 
help_optstr(void)40 static void help_optstr(void)
41 {
42     tc_log_info(MOD_NAME, "(%s) help", MOD_CAP);
43     tc_log_info(MOD_NAME,
44 "\n* Overview\n"
45 "   This filter produces a simple slow-motion effect by\n"
46 "   duplicating certain frames. I have seen this effect\n"
47 "   on TV and despite its the simple algorithm it works\n"
48 "   quite well. The filter has no options.\n");
49 }
50 
do_clone(int id)51 static int do_clone(int id)
52 {
53     static int last = 0;
54 
55     if ((id) % 3 == 0) {
56         last = 0;
57         return 1;
58     }
59     if (last > 0) {
60         last--;
61         return 0;
62     }
63     if (last == 0) {
64         last = -1;
65         return 1;
66     }
67     return 0;
68 }
69 
slowmo_init(const char * options)70 static inline int slowmo_init(const char *options)
71 {
72     if (verbose) {
73         tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP);
74     }
75     if (options != NULL) {
76         if (verbose) {
77             tc_log_info(MOD_NAME, "options=%s", options);
78         }
79         if (optstr_lookup(options, "help") != NULL) {
80             help_optstr();
81         }
82     }
83     return 0;
84 }
85 
slowmo_exec(vframe_list_t * ptr)86 static inline int slowmo_exec(vframe_list_t *ptr)
87 {
88     /*
89      * tag variable indicates, if we are called before
90      * transcodes internal video/audo frame processing routines
91      * or after and determines video/audio context
92      *
93      *  1 <-
94      *  2 <-
95      *  3 = 2
96      *  4 <-
97      *  5 = 4
98      *  6 <-
99      *  7 <-
100      *  8 = 7
101      *  9 <-
102      * 10 = 9
103      * 11 <-
104      * 12 <-
105      * 13 = 12
106      * 14 <-
107      * 15 = 14
108      */
109 
110     if (ptr->tag & TC_PRE_S_PROCESS && ptr->tag & TC_VIDEO) {
111         if (!(ptr->tag & TC_FRAME_WAS_CLONED) && do_clone(ptr->id))  {
112 	        ptr->attributes |= TC_FRAME_IS_CLONED;
113         }
114     }
115     return 0;
116 }
117 
tc_filter(frame_list_t * ptr_,char * options)118 int tc_filter(frame_list_t *ptr_, char *options)
119 {
120     vframe_list_t *ptr = (vframe_list_t*)ptr_;
121 
122     if (ptr->tag & TC_FILTER_INIT) {
123         return slowmo_init(options);
124     }
125 
126     if (ptr->tag & TC_FILTER_CLOSE) {
127         return 0;
128     }
129 
130     if (ptr->tag & TC_FILTER_GET_CONFIG) {
131         optstr_filter_desc(options, MOD_NAME, MOD_CAP,
132                            MOD_VERSION, MOD_AUTHOR, "VRYE", "1");
133         return 0;
134     }
135 
136     return slowmo_exec(ptr);
137 }
138 
139