Mercurial > mplayer.hg
annotate libmpcodecs/vf_framestep.c @ 20213:cc316541564f
during stream detection always parse ts_probesize bytes (even with -nosound set),
otherwise the demuxer may not have a chance to correctly identify the stream type
(e.g. H264 was misidentified as MPEG2 with -nosound set)
author | nicodvb |
---|---|
date | Sun, 15 Oct 2006 09:29:02 +0000 |
parents | d3b0e55b0c90 |
children | f8d4f8eff72b |
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 | |
17012 | 63 #include "libvo/fastmemcpy.h" |
10751 | 64 |
65 /* Uncomment if you want to print some info on the format */ | |
66 // #define DUMP_FORMAT_DATA | |
67 | |
68 /* Private data */ | |
69 struct vf_priv_s { | |
70 /* Current frame */ | |
71 int frame_cur; | |
72 /* Frame output step, 0 = all */ | |
73 int frame_step; | |
74 /* Only I-Frame (2), print on I-Frame (1) */ | |
75 int dump_iframe; | |
76 }; | |
77 | |
78 /* 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
|
79 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) |
10751 | 80 { |
81 mp_image_t *dmpi; | |
82 struct vf_priv_s *priv; | |
83 int skip; | |
84 | |
85 priv = vf->priv; | |
86 | |
87 /* Print the 'I' if is a intra frame. The \n advance the current line so you got the | |
88 * current file time (in second) and the frame number on the console ;-) | |
89 */ | |
90 if (priv->dump_iframe) { | |
91 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
|
92 mp_msg(MSGT_VFILTER, MSGL_INFO, "I!\n"); |
10751 | 93 } |
94 } | |
95 | |
96 /* decide if frame must be shown */ | |
97 if (priv->dump_iframe == 2) { | |
98 /* Only key frame */ | |
99 skip = mpi->pict_type == 1 ? 0 : 1; | |
100 } | |
101 else { | |
102 /* Only 1 every frame_step */ | |
103 skip = 0; | |
104 if ((priv->frame_step != 0) && ((priv->frame_cur % priv->frame_step) != 0)) { | |
105 skip = 1; | |
106 } | |
107 } | |
108 /* Increment current frame */ | |
109 ++priv->frame_cur; | |
110 | |
111 if (skip == 0) { | |
112 /* Get image, export type (we don't modify tghe image) */ | |
113 dmpi=vf_get_image(vf->next, mpi->imgfmt, | |
114 MP_IMGTYPE_EXPORT, 0, | |
115 mpi->w, mpi->h); | |
116 /* Copy only the pointer ( MP_IMGTYPE_EXPORT ! ) */ | |
117 dmpi->planes[0] = mpi->planes[0]; | |
118 dmpi->planes[1] = mpi->planes[1]; | |
119 dmpi->planes[2] = mpi->planes[2]; | |
120 | |
121 dmpi->stride[0] = mpi->stride[0]; | |
122 dmpi->stride[1] = mpi->stride[1]; | |
123 dmpi->stride[2] = mpi->stride[2]; | |
124 | |
125 dmpi->width = mpi->width; | |
126 dmpi->height = mpi->height; | |
127 | |
128 /* 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
|
129 return vf_next_put_image(vf, dmpi, pts); |
10751 | 130 } |
131 | |
132 /* Skip the frame */ | |
133 return 0; | |
134 } | |
135 | |
136 static void uninit(struct vf_instance_s* vf) | |
137 { | |
138 /* Free private data */ | |
139 free(vf->priv); | |
140 } | |
141 | |
142 /* Main entry funct for the filter */ | |
143 static int open(vf_instance_t *vf, char* args) | |
144 { | |
145 struct vf_priv_s *p; | |
146 | |
147 vf->put_image = put_image; | |
148 vf->uninit = uninit; | |
149 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
150 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
151 if (p == NULL) { | |
152 return(0); | |
153 } | |
154 | |
155 if (args != NULL) { | |
156 #ifdef DUMP_FORMAT_DATA | |
157 if (*args == 'd') { | |
158 p->dump_iframe = 3; | |
159 } | |
160 else | |
161 #endif | |
162 if (*args == 'I') { | |
163 /* Dump only KEY (ie INTRA) frame */ | |
164 p->dump_iframe = 2; | |
165 } | |
166 else { | |
167 if (*args == 'i') { | |
168 /* Print a 'I!' when a i-frame is encounter */ | |
169 p->dump_iframe = 1; | |
170 ++args; | |
171 } | |
172 | |
173 if (*args != '\0') { | |
174 p->frame_step = atoi(args); | |
175 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
|
176 mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_ErrorParsingArgument); |
10751 | 177 return(0); |
178 } | |
179 } | |
180 } | |
181 } | |
182 return 1; | |
183 } | |
184 | |
185 vf_info_t vf_info_framestep = { | |
186 "Dump one every n / key frames", | |
187 "framestep", | |
188 "Daniele Forghieri", | |
189 "", | |
190 open, | |
191 NULL | |
192 }; | |
193 | |
194 |