Mercurial > mplayer.hg
annotate libmpcodecs/vf_framestep.c @ 23788:615607ca81e3
synced with r23748
author | ptt |
---|---|
date | Tue, 17 Jul 2007 16:37:26 +0000 |
parents | f8d4f8eff72b |
children | 00fff9a3b735 |
rev | line source |
---|---|
10751 | 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 | |
17012 | 54 #include "config.h" |
55 #include "mp_msg.h" | |
18004
bcd805923554
Part2 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu with LOTS of modifications by me
reynaldo
parents:
17906
diff
changeset
|
56 #include "help_mp.h" |
17012 | 57 #include "cpudetect.h" |
10751 | 58 |
59 #include "img_format.h" | |
60 #include "mp_image.h" | |
61 #include "vf.h" | |
62 | |
63 /* Uncomment if you want to print some info on the format */ | |
64 // #define DUMP_FORMAT_DATA | |
65 | |
66 /* Private data */ | |
67 struct vf_priv_s { | |
68 /* Current frame */ | |
69 int frame_cur; | |
70 /* Frame output step, 0 = all */ | |
71 int frame_step; | |
72 /* Only I-Frame (2), print on I-Frame (1) */ | |
73 int dump_iframe; | |
74 }; | |
75 | |
76 /* Filter handler */ | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17012
diff
changeset
|
77 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) |
10751 | 78 { |
79 mp_image_t *dmpi; | |
80 struct vf_priv_s *priv; | |
81 int skip; | |
82 | |
83 priv = vf->priv; | |
84 | |
85 /* Print the 'I' if is a intra frame. The \n advance the current line so you got the | |
86 * current file time (in second) and the frame number on the console ;-) | |
87 */ | |
88 if (priv->dump_iframe) { | |
89 if (mpi->pict_type == 1) { | |
18004
bcd805923554
Part2 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu with LOTS of modifications by me
reynaldo
parents:
17906
diff
changeset
|
90 mp_msg(MSGT_VFILTER, MSGL_INFO, "I!\n"); |
10751 | 91 } |
92 } | |
93 | |
94 /* decide if frame must be shown */ | |
95 if (priv->dump_iframe == 2) { | |
96 /* Only key frame */ | |
97 skip = mpi->pict_type == 1 ? 0 : 1; | |
98 } | |
99 else { | |
100 /* Only 1 every frame_step */ | |
101 skip = 0; | |
102 if ((priv->frame_step != 0) && ((priv->frame_cur % priv->frame_step) != 0)) { | |
103 skip = 1; | |
104 } | |
105 } | |
106 /* Increment current frame */ | |
107 ++priv->frame_cur; | |
108 | |
109 if (skip == 0) { | |
110 /* Get image, export type (we don't modify tghe image) */ | |
111 dmpi=vf_get_image(vf->next, mpi->imgfmt, | |
112 MP_IMGTYPE_EXPORT, 0, | |
113 mpi->w, mpi->h); | |
114 /* Copy only the pointer ( MP_IMGTYPE_EXPORT ! ) */ | |
115 dmpi->planes[0] = mpi->planes[0]; | |
116 dmpi->planes[1] = mpi->planes[1]; | |
117 dmpi->planes[2] = mpi->planes[2]; | |
118 | |
119 dmpi->stride[0] = mpi->stride[0]; | |
120 dmpi->stride[1] = mpi->stride[1]; | |
121 dmpi->stride[2] = mpi->stride[2]; | |
122 | |
123 dmpi->width = mpi->width; | |
124 dmpi->height = mpi->height; | |
125 | |
126 /* Chain to next filter / output ... */ | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17012
diff
changeset
|
127 return vf_next_put_image(vf, dmpi, pts); |
10751 | 128 } |
129 | |
130 /* Skip the frame */ | |
131 return 0; | |
132 } | |
133 | |
134 static void uninit(struct vf_instance_s* vf) | |
135 { | |
136 /* Free private data */ | |
137 free(vf->priv); | |
138 } | |
139 | |
140 /* Main entry funct for the filter */ | |
141 static int open(vf_instance_t *vf, char* args) | |
142 { | |
143 struct vf_priv_s *p; | |
144 | |
145 vf->put_image = put_image; | |
146 vf->uninit = uninit; | |
147 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
148 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
149 if (p == NULL) { | |
150 return(0); | |
151 } | |
152 | |
153 if (args != NULL) { | |
154 #ifdef DUMP_FORMAT_DATA | |
155 if (*args == 'd') { | |
156 p->dump_iframe = 3; | |
157 } | |
158 else | |
159 #endif | |
160 if (*args == 'I') { | |
161 /* Dump only KEY (ie INTRA) frame */ | |
162 p->dump_iframe = 2; | |
163 } | |
164 else { | |
165 if (*args == 'i') { | |
166 /* Print a 'I!' when a i-frame is encounter */ | |
167 p->dump_iframe = 1; | |
168 ++args; | |
169 } | |
170 | |
171 if (*args != '\0') { | |
172 p->frame_step = atoi(args); | |
173 if (p->frame_step <= 0) { | |
18004
bcd805923554
Part2 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu with LOTS of modifications by me
reynaldo
parents:
17906
diff
changeset
|
174 mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_ErrorParsingArgument); |
10751 | 175 return(0); |
176 } | |
177 } | |
178 } | |
179 } | |
180 return 1; | |
181 } | |
182 | |
183 vf_info_t vf_info_framestep = { | |
184 "Dump one every n / key frames", | |
185 "framestep", | |
186 "Daniele Forghieri", | |
187 "", | |
188 open, | |
189 NULL | |
190 }; | |
191 | |
192 |