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