Mercurial > mplayer.hg
annotate libmpcodecs/vf_framestep.c @ 30086:f72ea7a67421
Introduce a sh_common struct that contains the parts in common by the audio, video
and sub "stream headers".
One reason for this is to help avoid/make more obvious things like members with
the same function but different name (extradata vs. codecdata etc.), or members
with the same name but different semantics (pts for audio vs. pts for video).
author | reimar |
---|---|
date | Sun, 27 Dec 2009 14:40:56 +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 |