Mercurial > mplayer.hg
comparison libmpcodecs/vf_framestep.c @ 10751:81d03cb2cd64
2 new filters: tile & framestep
patch by Daniele Forghieri ( guru@digitalfantasy.it )
(little cleanup by me)
author | arpi |
---|---|
date | Sun, 31 Aug 2003 21:41:24 +0000 |
parents | |
children | 6ff3379a0862 |
comparison
equal
deleted
inserted
replaced
10750:338d91776700 | 10751:81d03cb2cd64 |
---|---|
1 /* | |
2 * vf_fstep.c - filter to ouput only 1 every n frame, or only the I (key) | |
3 * frame | |
4 * | |
5 * The parameters are: | |
6 * | |
7 * [I] | [i]num | |
8 * | |
9 * if you call the filter with I (uppercase) as the parameter | |
10 * ... -vf framestep=I ... | |
11 * then ONLY the keyframes are outputted. | |
12 * For DVD it means, generally, one every 15 frames (IBBPBBPBBPBBPBB), for avi it means | |
13 * every scene change or every keyint value (see -lavcopts). | |
14 * | |
15 * if you call the filter with the i (lowercase) | |
16 * ... -vf framestep=i ... | |
17 * then a I! followed by a cr is printed when a key frame (eg Intra frame) is | |
18 * found, leaving the current line of mplayer/mencoder, where you got the | |
19 * time, in seconds, and frame of the key. Use this information to split the | |
20 * AVI. | |
21 * | |
22 * After the i or alone you can put a positive number and only one frame every | |
23 * x (the number you set) is passed on the filter chain, limiting the output | |
24 * of the frame. | |
25 * | |
26 * Example | |
27 * ... -vf framestep=i20 ... | |
28 * Dump one every 20 frames, printing on the console when a I-Frame is encounter. | |
29 * | |
30 * ... -vf framestep=25 | |
31 * Dump one every 25 frames. | |
32 * | |
33 * If you call the filter without parameter it does nothing (except using memory | |
34 * and resource of your system,. of course). | |
35 * | |
36 * This filter doesn' t work like the option -sstep seconds. | |
37 * | |
38 * The -sstep seek to the new position, without decoding all frames but, | |
39 * expecially on avi file coded whith mpeg4 (lavc or xvid or divx), the | |
40 * seek is not always too much precise. | |
41 * | |
42 * This filter simply discard the unwanted frames, so you are very precise in | |
43 * counting the frame but sometime you use a lot of CPU for nothing. | |
44 * | |
45 * As usual it depends on what you're doing. | |
46 * | |
47 * Daniele Forghieri ( guru@digitalfantasy.it ) | |
48 */ | |
49 | |
50 #include <stdio.h> | |
51 #include <stdlib.h> | |
52 #include <string.h> | |
53 | |
54 #include "../config.h" | |
55 #include "../mp_msg.h" | |
56 #include "../cpudetect.h" | |
57 | |
58 #include "img_format.h" | |
59 #include "mp_image.h" | |
60 #include "vf.h" | |
61 | |
62 #include "../libvo/fastmemcpy.h" | |
63 | |
64 /* Uncomment if you want to print some info on the format */ | |
65 // #define DUMP_FORMAT_DATA | |
66 | |
67 /* Private data */ | |
68 struct vf_priv_s { | |
69 /* Current frame */ | |
70 int frame_cur; | |
71 /* Frame output step, 0 = all */ | |
72 int frame_step; | |
73 /* Only I-Frame (2), print on I-Frame (1) */ | |
74 int dump_iframe; | |
75 }; | |
76 | |
77 /* Filter handler */ | |
78 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) | |
79 { | |
80 mp_image_t *dmpi; | |
81 struct vf_priv_s *priv; | |
82 int skip; | |
83 | |
84 priv = vf->priv; | |
85 | |
86 /* Print the 'I' if is a intra frame. The \n advance the current line so you got the | |
87 * current file time (in second) and the frame number on the console ;-) | |
88 */ | |
89 if (priv->dump_iframe) { | |
90 if (mpi->pict_type == 1) { | |
91 printf("I!\n"); | |
92 } | |
93 } | |
94 | |
95 /* decide if frame must be shown */ | |
96 if (priv->dump_iframe == 2) { | |
97 /* Only key frame */ | |
98 skip = mpi->pict_type == 1 ? 0 : 1; | |
99 } | |
100 else { | |
101 /* Only 1 every frame_step */ | |
102 skip = 0; | |
103 if ((priv->frame_step != 0) && ((priv->frame_cur % priv->frame_step) != 0)) { | |
104 skip = 1; | |
105 } | |
106 } | |
107 /* Increment current frame */ | |
108 ++priv->frame_cur; | |
109 | |
110 if (skip == 0) { | |
111 /* Get image, export type (we don't modify tghe image) */ | |
112 dmpi=vf_get_image(vf->next, mpi->imgfmt, | |
113 MP_IMGTYPE_EXPORT, 0, | |
114 mpi->w, mpi->h); | |
115 /* Copy only the pointer ( MP_IMGTYPE_EXPORT ! ) */ | |
116 dmpi->planes[0] = mpi->planes[0]; | |
117 dmpi->planes[1] = mpi->planes[1]; | |
118 dmpi->planes[2] = mpi->planes[2]; | |
119 | |
120 dmpi->stride[0] = mpi->stride[0]; | |
121 dmpi->stride[1] = mpi->stride[1]; | |
122 dmpi->stride[2] = mpi->stride[2]; | |
123 | |
124 dmpi->width = mpi->width; | |
125 dmpi->height = mpi->height; | |
126 | |
127 /* Chain to next filter / output ... */ | |
128 return vf_next_put_image(vf, dmpi); | |
129 } | |
130 | |
131 /* Skip the frame */ | |
132 return 0; | |
133 } | |
134 | |
135 static void uninit(struct vf_instance_s* vf) | |
136 { | |
137 /* Free private data */ | |
138 free(vf->priv); | |
139 } | |
140 | |
141 /* Main entry funct for the filter */ | |
142 static int open(vf_instance_t *vf, char* args) | |
143 { | |
144 struct vf_priv_s *p; | |
145 | |
146 vf->put_image = put_image; | |
147 vf->uninit = uninit; | |
148 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
149 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
150 if (p == NULL) { | |
151 return(0); | |
152 } | |
153 | |
154 if (args != NULL) { | |
155 #ifdef DUMP_FORMAT_DATA | |
156 if (*args == 'd') { | |
157 p->dump_iframe = 3; | |
158 } | |
159 else | |
160 #endif | |
161 if (*args == 'I') { | |
162 /* Dump only KEY (ie INTRA) frame */ | |
163 p->dump_iframe = 2; | |
164 } | |
165 else { | |
166 if (*args == 'i') { | |
167 /* Print a 'I!' when a i-frame is encounter */ | |
168 p->dump_iframe = 1; | |
169 ++args; | |
170 } | |
171 | |
172 if (*args != '\0') { | |
173 p->frame_step = atoi(args); | |
174 if (p->frame_step <= 0) { | |
175 printf("Error parsing argument\n"); | |
176 return(0); | |
177 } | |
178 } | |
179 } | |
180 } | |
181 return 1; | |
182 } | |
183 | |
184 vf_info_t vf_info_framestep = { | |
185 "Dump one every n / key frames", | |
186 "framestep", | |
187 "Daniele Forghieri", | |
188 "", | |
189 open, | |
190 NULL | |
191 }; | |
192 | |
193 |