Originally committed as revision 3668 to svn://svn.ffmpeg.org/ffmpeg/trunk
Michael Niedermayer authored on 2004/11/12 03:09:28... | ... |
@@ -255,6 +255,9 @@ static int nb_frames_dup = 0; |
255 | 255 |
static int nb_frames_drop = 0; |
256 | 256 |
static int input_sync; |
257 | 257 |
|
258 |
+static int pgmyuv_compatibility_hack=0; |
|
259 |
+ |
|
260 |
+ |
|
258 | 261 |
#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass" |
259 | 262 |
|
260 | 263 |
typedef struct AVOutputStream { |
... | ... |
@@ -2015,8 +2018,9 @@ static void opt_format(const char *arg) |
2015 | 2015 |
{ |
2016 | 2016 |
/* compatibility stuff for pgmyuv */ |
2017 | 2017 |
if (!strcmp(arg, "pgmyuv")) { |
2018 |
+ pgmyuv_compatibility_hack=1; |
|
2018 | 2019 |
opt_image_format(arg); |
2019 |
- arg = "image"; |
|
2020 |
+ arg = "image2"; |
|
2020 | 2021 |
} |
2021 | 2022 |
|
2022 | 2023 |
file_iformat = av_find_input_format(arg); |
... | ... |
@@ -2782,6 +2786,10 @@ static void opt_input_file(const char *filename) |
2782 | 2782 |
ap->device = grab_device; |
2783 | 2783 |
ap->channel = video_channel; |
2784 | 2784 |
ap->standard = video_standard; |
2785 |
+ ap->video_codec_id = video_codec_id; |
|
2786 |
+ ap->audio_codec_id = audio_codec_id; |
|
2787 |
+ if(pgmyuv_compatibility_hack) |
|
2788 |
+ ap->video_codec_id= CODEC_ID_PGMYUV; |
|
2785 | 2789 |
|
2786 | 2790 |
/* open the input file with generic libav function */ |
2787 | 2791 |
err = av_open_input_file(&ic, filename, file_iformat, 0, ap); |
... | ... |
@@ -3004,7 +3012,7 @@ static void opt_output_file(const char *filename) |
3004 | 3004 |
int i; |
3005 | 3005 |
AVCodec *codec; |
3006 | 3006 |
|
3007 |
- codec_id = file_oformat->video_codec; |
|
3007 |
+ codec_id = av_guess_codec(file_oformat, NULL, filename, NULL, CODEC_TYPE_VIDEO); |
|
3008 | 3008 |
if (video_codec_id != CODEC_ID_NONE) |
3009 | 3009 |
codec_id = video_codec_id; |
3010 | 3010 |
|
... | ... |
@@ -3253,7 +3261,7 @@ static void opt_output_file(const char *filename) |
3253 | 3253 |
st->stream_copy = 1; |
3254 | 3254 |
audio_enc->channels = audio_channels; |
3255 | 3255 |
} else { |
3256 |
- codec_id = file_oformat->audio_codec; |
|
3256 |
+ codec_id = av_guess_codec(file_oformat, NULL, filename, NULL, CODEC_TYPE_AUDIO); |
|
3257 | 3257 |
if (audio_codec_id != CODEC_ID_NONE) |
3258 | 3258 |
codec_id = audio_codec_id; |
3259 | 3259 |
audio_enc->codec_id = codec_id; |
... | ... |
@@ -21,7 +21,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \ |
21 | 21 |
msvideo1.o vqavideo.o idcinvideo.o adx.o rational.o faandct.o 8bps.o \ |
22 | 22 |
smc.o parser.o flicvideo.o truemotion1.o vmdav.o lcl.o qtrle.o g726.o \ |
23 | 23 |
flac.o vp3dsp.o integer.o snow.o tscc.o sonic.o ulti.o h264idct.o \ |
24 |
- qdrw.o xl.o rangecoder.o png.o |
|
24 |
+ qdrw.o xl.o rangecoder.o png.o pnm.o |
|
25 | 25 |
|
26 | 26 |
ifeq ($(AMR_NB),yes) |
27 | 27 |
ifeq ($(AMR_NB_FIXED),yes) |
... | ... |
@@ -77,6 +77,11 @@ void avcodec_register_all(void) |
77 | 77 |
#ifdef CONFIG_ZLIB |
78 | 78 |
register_avcodec(&png_encoder); |
79 | 79 |
#endif |
80 |
+ register_avcodec(&ppm_encoder); |
|
81 |
+ register_avcodec(&pgm_encoder); |
|
82 |
+ register_avcodec(&pgmyuv_encoder); |
|
83 |
+ register_avcodec(&pbm_encoder); |
|
84 |
+ register_avcodec(&pam_encoder); |
|
80 | 85 |
register_avcodec(&huffyuv_encoder); |
81 | 86 |
register_avcodec(&asv1_encoder); |
82 | 87 |
register_avcodec(&asv2_encoder); |
... | ... |
@@ -154,6 +154,11 @@ enum CodecID { |
154 | 154 |
CODEC_ID_XVID, |
155 | 155 |
|
156 | 156 |
CODEC_ID_PNG, |
157 |
+ CODEC_ID_PPM, |
|
158 |
+ CODEC_ID_PBM, |
|
159 |
+ CODEC_ID_PGM, |
|
160 |
+ CODEC_ID_PGMYUV, |
|
161 |
+ CODEC_ID_PAM, |
|
157 | 162 |
}; |
158 | 163 |
|
159 | 164 |
/* CODEC_ID_MP3LAME is absolete */ |
... | ... |
@@ -1798,6 +1803,11 @@ extern AVCodec dvvideo_encoder; |
1798 | 1798 |
extern AVCodec mjpeg_encoder; |
1799 | 1799 |
extern AVCodec ljpeg_encoder; |
1800 | 1800 |
extern AVCodec png_encoder; |
1801 |
+extern AVCodec ppm_encoder; |
|
1802 |
+extern AVCodec pgm_encoder; |
|
1803 |
+extern AVCodec pgmyuv_encoder; |
|
1804 |
+extern AVCodec pbm_encoder; |
|
1805 |
+extern AVCodec pam_encoder; |
|
1801 | 1806 |
extern AVCodec mpeg4_encoder; |
1802 | 1807 |
extern AVCodec msmpeg4v1_encoder; |
1803 | 1808 |
extern AVCodec msmpeg4v2_encoder; |
1804 | 1809 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,553 @@ |
0 |
+/* |
|
1 |
+ * PNM image format |
|
2 |
+ * Copyright (c) 2002, 2003 Fabrice Bellard. |
|
3 |
+ * |
|
4 |
+ * This library is free software; you can redistribute it and/or |
|
5 |
+ * modify it under the terms of the GNU Lesser General Public |
|
6 |
+ * License as published by the Free Software Foundation; either |
|
7 |
+ * version 2 of the License, or (at your option) any later version. |
|
8 |
+ * |
|
9 |
+ * This library is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 |
+ * Lesser General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU Lesser General Public |
|
15 |
+ * License along with this library; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 |
+ */ |
|
18 |
+#include "avcodec.h" |
|
19 |
+ |
|
20 |
+typedef struct PNMContext { |
|
21 |
+ uint8_t *bytestream; |
|
22 |
+ uint8_t *bytestream_start; |
|
23 |
+ uint8_t *bytestream_end; |
|
24 |
+ AVFrame picture; |
|
25 |
+} PNMContext; |
|
26 |
+ |
|
27 |
+static inline int pnm_space(int c) |
|
28 |
+{ |
|
29 |
+ return (c == ' ' || c == '\n' || c == '\r' || c == '\t'); |
|
30 |
+} |
|
31 |
+ |
|
32 |
+static void pnm_get(PNMContext *sc, char *str, int buf_size) |
|
33 |
+{ |
|
34 |
+ char *s; |
|
35 |
+ int c; |
|
36 |
+ |
|
37 |
+ /* skip spaces and comments */ |
|
38 |
+ for(;;) { |
|
39 |
+ c = *sc->bytestream++; |
|
40 |
+ if (c == '#') { |
|
41 |
+ do { |
|
42 |
+ c = *sc->bytestream++; |
|
43 |
+ } while (c != '\n' && sc->bytestream < sc->bytestream_end); |
|
44 |
+ } else if (!pnm_space(c)) { |
|
45 |
+ break; |
|
46 |
+ } |
|
47 |
+ } |
|
48 |
+ |
|
49 |
+ s = str; |
|
50 |
+ while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) { |
|
51 |
+ if ((s - str) < buf_size - 1) |
|
52 |
+ *s++ = c; |
|
53 |
+ c = *sc->bytestream++; |
|
54 |
+ } |
|
55 |
+ *s = '\0'; |
|
56 |
+} |
|
57 |
+ |
|
58 |
+static int common_init(AVCodecContext *avctx){ |
|
59 |
+ PNMContext *s = avctx->priv_data; |
|
60 |
+ |
|
61 |
+ avcodec_get_frame_defaults((AVFrame*)&s->picture); |
|
62 |
+ avctx->coded_frame= (AVFrame*)&s->picture; |
|
63 |
+ |
|
64 |
+ return 0; |
|
65 |
+} |
|
66 |
+ |
|
67 |
+static int pnm_decode_frame(AVCodecContext *avctx, |
|
68 |
+ void *data, int *data_size, |
|
69 |
+ uint8_t *buf, int buf_size) |
|
70 |
+{ |
|
71 |
+ PNMContext * const s = avctx->priv_data; |
|
72 |
+ AVFrame *picture = data; |
|
73 |
+ AVFrame * const p= (AVFrame*)&s->picture; |
|
74 |
+ int i, n, linesize, h; |
|
75 |
+ char buf1[32]; |
|
76 |
+ unsigned char *ptr; |
|
77 |
+ |
|
78 |
+ /* special case for last picture */ |
|
79 |
+ if (buf_size == 0) { |
|
80 |
+ return 0; |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ s->bytestream_start= |
|
84 |
+ s->bytestream= buf; |
|
85 |
+ s->bytestream_end= buf + buf_size; |
|
86 |
+ |
|
87 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
88 |
+ if (!strcmp(buf1, "P4")) { |
|
89 |
+ avctx->pix_fmt = PIX_FMT_MONOWHITE; |
|
90 |
+ } else if (!strcmp(buf1, "P5")) { |
|
91 |
+ if (avctx->codec_id == CODEC_ID_PGMYUV) |
|
92 |
+ avctx->pix_fmt = PIX_FMT_YUV420P; |
|
93 |
+ else |
|
94 |
+ avctx->pix_fmt = PIX_FMT_GRAY8; |
|
95 |
+ } else if (!strcmp(buf1, "P6")) { |
|
96 |
+ avctx->pix_fmt = PIX_FMT_RGB24; |
|
97 |
+ } else { |
|
98 |
+ return -1; |
|
99 |
+ } |
|
100 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
101 |
+ avctx->width = atoi(buf1); |
|
102 |
+ if (avctx->width <= 0) |
|
103 |
+ return -1; |
|
104 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
105 |
+ avctx->height = atoi(buf1); |
|
106 |
+ if (avctx->height <= 0) |
|
107 |
+ return -1; |
|
108 |
+ if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { |
|
109 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
110 |
+ } |
|
111 |
+ |
|
112 |
+ /* more check if YUV420 */ |
|
113 |
+ if (avctx->pix_fmt == PIX_FMT_YUV420P) { |
|
114 |
+ if ((avctx->width & 1) != 0) |
|
115 |
+ return -1; |
|
116 |
+ h = (avctx->height * 2); |
|
117 |
+ if ((h % 3) != 0) |
|
118 |
+ return -1; |
|
119 |
+ h /= 3; |
|
120 |
+ avctx->height = h; |
|
121 |
+ } |
|
122 |
+ |
|
123 |
+ if(p->data[0]) |
|
124 |
+ avctx->release_buffer(avctx, p); |
|
125 |
+ |
|
126 |
+ p->reference= 0; |
|
127 |
+ if(avctx->get_buffer(avctx, p) < 0){ |
|
128 |
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
|
129 |
+ return -1; |
|
130 |
+ } |
|
131 |
+ p->pict_type= FF_I_TYPE; |
|
132 |
+ p->key_frame= 1; |
|
133 |
+ |
|
134 |
+ switch(avctx->pix_fmt) { |
|
135 |
+ default: |
|
136 |
+ return -1; |
|
137 |
+ case PIX_FMT_RGB24: |
|
138 |
+ n = avctx->width * 3; |
|
139 |
+ goto do_read; |
|
140 |
+ case PIX_FMT_GRAY8: |
|
141 |
+ n = avctx->width; |
|
142 |
+ goto do_read; |
|
143 |
+ case PIX_FMT_MONOWHITE: |
|
144 |
+ n = (avctx->width + 7) >> 3; |
|
145 |
+ do_read: |
|
146 |
+ ptr = p->data[0]; |
|
147 |
+ linesize = p->linesize[0]; |
|
148 |
+ for(i = 0; i < avctx->height; i++) { |
|
149 |
+ memcpy(ptr, s->bytestream, n); |
|
150 |
+ s->bytestream += n; |
|
151 |
+ ptr += linesize; |
|
152 |
+ } |
|
153 |
+ break; |
|
154 |
+ case PIX_FMT_YUV420P: |
|
155 |
+ { |
|
156 |
+ unsigned char *ptr1, *ptr2; |
|
157 |
+ |
|
158 |
+ n = avctx->width; |
|
159 |
+ ptr = p->data[0]; |
|
160 |
+ linesize = p->linesize[0]; |
|
161 |
+ for(i = 0; i < avctx->height; i++) { |
|
162 |
+ memcpy(ptr, s->bytestream, n); |
|
163 |
+ s->bytestream += n; |
|
164 |
+ ptr += linesize; |
|
165 |
+ } |
|
166 |
+ ptr1 = p->data[1]; |
|
167 |
+ ptr2 = p->data[2]; |
|
168 |
+ n >>= 1; |
|
169 |
+ h = avctx->height >> 1; |
|
170 |
+ for(i = 0; i < h; i++) { |
|
171 |
+ memcpy(ptr1, s->bytestream, n); |
|
172 |
+ s->bytestream += n; |
|
173 |
+ memcpy(ptr2, s->bytestream, n); |
|
174 |
+ s->bytestream += n; |
|
175 |
+ ptr1 += p->linesize[1]; |
|
176 |
+ ptr2 += p->linesize[2]; |
|
177 |
+ } |
|
178 |
+ } |
|
179 |
+ break; |
|
180 |
+ } |
|
181 |
+ *picture= *(AVFrame*)&s->picture; |
|
182 |
+ *data_size = sizeof(AVPicture); |
|
183 |
+ |
|
184 |
+ return s->bytestream - s->bytestream_start; |
|
185 |
+} |
|
186 |
+ |
|
187 |
+static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){ |
|
188 |
+ PNMContext *s = avctx->priv_data; |
|
189 |
+ AVFrame *pict = data; |
|
190 |
+ AVFrame * const p= (AVFrame*)&s->picture; |
|
191 |
+ int i, h, h1, c, n, linesize; |
|
192 |
+ uint8_t *ptr, *ptr1, *ptr2; |
|
193 |
+ |
|
194 |
+ *p = *pict; |
|
195 |
+ p->pict_type= FF_I_TYPE; |
|
196 |
+ p->key_frame= 1; |
|
197 |
+ |
|
198 |
+ s->bytestream_start= |
|
199 |
+ s->bytestream= outbuf; |
|
200 |
+ s->bytestream_end= outbuf+buf_size; |
|
201 |
+ |
|
202 |
+ h = avctx->height; |
|
203 |
+ h1 = h; |
|
204 |
+ switch(avctx->pix_fmt) { |
|
205 |
+ case PIX_FMT_MONOWHITE: |
|
206 |
+ c = '4'; |
|
207 |
+ n = (avctx->width + 7) >> 3; |
|
208 |
+ break; |
|
209 |
+ case PIX_FMT_GRAY8: |
|
210 |
+ c = '5'; |
|
211 |
+ n = avctx->width; |
|
212 |
+ break; |
|
213 |
+ case PIX_FMT_RGB24: |
|
214 |
+ c = '6'; |
|
215 |
+ n = avctx->width * 3; |
|
216 |
+ break; |
|
217 |
+ case PIX_FMT_YUV420P: |
|
218 |
+ c = '5'; |
|
219 |
+ n = avctx->width; |
|
220 |
+ h1 = (h * 3) / 2; |
|
221 |
+ break; |
|
222 |
+ default: |
|
223 |
+ return -1; |
|
224 |
+ } |
|
225 |
+ snprintf(s->bytestream, s->bytestream_end - s->bytestream, |
|
226 |
+ "P%c\n%d %d\n", |
|
227 |
+ c, avctx->width, h1); |
|
228 |
+ s->bytestream += strlen(s->bytestream); |
|
229 |
+ if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { |
|
230 |
+ snprintf(s->bytestream, s->bytestream_end - s->bytestream, |
|
231 |
+ "%d\n", 255); |
|
232 |
+ s->bytestream += strlen(s->bytestream); |
|
233 |
+ } |
|
234 |
+ |
|
235 |
+ ptr = p->data[0]; |
|
236 |
+ linesize = p->linesize[0]; |
|
237 |
+ for(i=0;i<h;i++) { |
|
238 |
+ memcpy(s->bytestream, ptr, n); |
|
239 |
+ s->bytestream += n; |
|
240 |
+ ptr += linesize; |
|
241 |
+ } |
|
242 |
+ |
|
243 |
+ if (avctx->pix_fmt == PIX_FMT_YUV420P) { |
|
244 |
+ h >>= 1; |
|
245 |
+ n >>= 1; |
|
246 |
+ ptr1 = p->data[1]; |
|
247 |
+ ptr2 = p->data[2]; |
|
248 |
+ for(i=0;i<h;i++) { |
|
249 |
+ memcpy(s->bytestream, ptr1, n); |
|
250 |
+ s->bytestream += n; |
|
251 |
+ memcpy(s->bytestream, ptr2, n); |
|
252 |
+ s->bytestream += n; |
|
253 |
+ ptr1 += p->linesize[1]; |
|
254 |
+ ptr2 += p->linesize[2]; |
|
255 |
+ } |
|
256 |
+ } |
|
257 |
+ return s->bytestream - s->bytestream_start; |
|
258 |
+} |
|
259 |
+ |
|
260 |
+static int pam_decode_frame(AVCodecContext *avctx, |
|
261 |
+ void *data, int *data_size, |
|
262 |
+ uint8_t *buf, int buf_size) |
|
263 |
+{ |
|
264 |
+ PNMContext * const s = avctx->priv_data; |
|
265 |
+ AVFrame *picture = data; |
|
266 |
+ AVFrame * const p= (AVFrame*)&s->picture; |
|
267 |
+ int i, n, linesize, h, w, depth, maxval; |
|
268 |
+ char buf1[32], tuple_type[32]; |
|
269 |
+ unsigned char *ptr; |
|
270 |
+ |
|
271 |
+ /* special case for last picture */ |
|
272 |
+ if (buf_size == 0) { |
|
273 |
+ return 0; |
|
274 |
+ } |
|
275 |
+ |
|
276 |
+ s->bytestream_start= |
|
277 |
+ s->bytestream= buf; |
|
278 |
+ s->bytestream_end= buf + buf_size; |
|
279 |
+ |
|
280 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
281 |
+ if (strcmp(buf1, "P7") != 0) |
|
282 |
+ return -1; |
|
283 |
+ w = -1; |
|
284 |
+ h = -1; |
|
285 |
+ maxval = -1; |
|
286 |
+ depth = -1; |
|
287 |
+ tuple_type[0] = '\0'; |
|
288 |
+ for(;;) { |
|
289 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
290 |
+ if (!strcmp(buf1, "WIDTH")) { |
|
291 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
292 |
+ w = strtol(buf1, NULL, 10); |
|
293 |
+ } else if (!strcmp(buf1, "HEIGHT")) { |
|
294 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
295 |
+ h = strtol(buf1, NULL, 10); |
|
296 |
+ } else if (!strcmp(buf1, "DEPTH")) { |
|
297 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
298 |
+ depth = strtol(buf1, NULL, 10); |
|
299 |
+ } else if (!strcmp(buf1, "MAXVAL")) { |
|
300 |
+ pnm_get(s, buf1, sizeof(buf1)); |
|
301 |
+ maxval = strtol(buf1, NULL, 10); |
|
302 |
+ } else if (!strcmp(buf1, "TUPLETYPE")) { |
|
303 |
+ pnm_get(s, tuple_type, sizeof(tuple_type)); |
|
304 |
+ } else if (!strcmp(buf1, "ENDHDR")) { |
|
305 |
+ break; |
|
306 |
+ } else { |
|
307 |
+ return -1; |
|
308 |
+ } |
|
309 |
+ } |
|
310 |
+ /* check that all tags are present */ |
|
311 |
+ if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0') |
|
312 |
+ return -1; |
|
313 |
+ avctx->width = w; |
|
314 |
+ avctx->height = h; |
|
315 |
+ if (depth == 1) { |
|
316 |
+ if (maxval == 1) |
|
317 |
+ avctx->pix_fmt = PIX_FMT_MONOWHITE; |
|
318 |
+ else |
|
319 |
+ avctx->pix_fmt = PIX_FMT_GRAY8; |
|
320 |
+ } else if (depth == 3) { |
|
321 |
+ avctx->pix_fmt = PIX_FMT_RGB24; |
|
322 |
+ } else if (depth == 4) { |
|
323 |
+ avctx->pix_fmt = PIX_FMT_RGBA32; |
|
324 |
+ } else { |
|
325 |
+ return -1; |
|
326 |
+ } |
|
327 |
+ |
|
328 |
+ if(p->data[0]) |
|
329 |
+ avctx->release_buffer(avctx, p); |
|
330 |
+ |
|
331 |
+ p->reference= 0; |
|
332 |
+ if(avctx->get_buffer(avctx, p) < 0){ |
|
333 |
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
|
334 |
+ return -1; |
|
335 |
+ } |
|
336 |
+ p->pict_type= FF_I_TYPE; |
|
337 |
+ p->key_frame= 1; |
|
338 |
+ |
|
339 |
+ switch(avctx->pix_fmt) { |
|
340 |
+ default: |
|
341 |
+ return -1; |
|
342 |
+ case PIX_FMT_RGB24: |
|
343 |
+ n = avctx->width * 3; |
|
344 |
+ goto do_read; |
|
345 |
+ case PIX_FMT_GRAY8: |
|
346 |
+ n = avctx->width; |
|
347 |
+ goto do_read; |
|
348 |
+ case PIX_FMT_MONOWHITE: |
|
349 |
+ n = (avctx->width + 7) >> 3; |
|
350 |
+ do_read: |
|
351 |
+ ptr = p->data[0]; |
|
352 |
+ linesize = p->linesize[0]; |
|
353 |
+ for(i = 0; i < avctx->height; i++) { |
|
354 |
+ memcpy(ptr, s->bytestream, n); |
|
355 |
+ s->bytestream += n; |
|
356 |
+ ptr += linesize; |
|
357 |
+ } |
|
358 |
+ break; |
|
359 |
+ case PIX_FMT_RGBA32: |
|
360 |
+ ptr = p->data[0]; |
|
361 |
+ linesize = p->linesize[0]; |
|
362 |
+ for(i = 0; i < avctx->height; i++) { |
|
363 |
+ int j, r, g, b, a; |
|
364 |
+ |
|
365 |
+ for(j = 0;j < w; j++) { |
|
366 |
+ r = *s->bytestream++; |
|
367 |
+ g = *s->bytestream++; |
|
368 |
+ b = *s->bytestream++; |
|
369 |
+ a = *s->bytestream++; |
|
370 |
+ ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; |
|
371 |
+ } |
|
372 |
+ ptr += linesize; |
|
373 |
+ } |
|
374 |
+ break; |
|
375 |
+ } |
|
376 |
+ *picture= *(AVFrame*)&s->picture; |
|
377 |
+ *data_size = sizeof(AVPicture); |
|
378 |
+ |
|
379 |
+ return s->bytestream - s->bytestream_start; |
|
380 |
+} |
|
381 |
+ |
|
382 |
+static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){ |
|
383 |
+ PNMContext *s = avctx->priv_data; |
|
384 |
+ AVFrame *pict = data; |
|
385 |
+ AVFrame * const p= (AVFrame*)&s->picture; |
|
386 |
+ int i, h, w, n, linesize, depth, maxval; |
|
387 |
+ const char *tuple_type; |
|
388 |
+ uint8_t *ptr; |
|
389 |
+ |
|
390 |
+ *p = *pict; |
|
391 |
+ p->pict_type= FF_I_TYPE; |
|
392 |
+ p->key_frame= 1; |
|
393 |
+ |
|
394 |
+ s->bytestream_start= |
|
395 |
+ s->bytestream= outbuf; |
|
396 |
+ s->bytestream_end= outbuf+buf_size; |
|
397 |
+ |
|
398 |
+ h = avctx->height; |
|
399 |
+ w = avctx->width; |
|
400 |
+ switch(avctx->pix_fmt) { |
|
401 |
+ case PIX_FMT_MONOWHITE: |
|
402 |
+ n = (w + 7) >> 3; |
|
403 |
+ depth = 1; |
|
404 |
+ maxval = 1; |
|
405 |
+ tuple_type = "BLACKANDWHITE"; |
|
406 |
+ break; |
|
407 |
+ case PIX_FMT_GRAY8: |
|
408 |
+ n = w; |
|
409 |
+ depth = 1; |
|
410 |
+ maxval = 255; |
|
411 |
+ tuple_type = "GRAYSCALE"; |
|
412 |
+ break; |
|
413 |
+ case PIX_FMT_RGB24: |
|
414 |
+ n = w * 3; |
|
415 |
+ depth = 3; |
|
416 |
+ maxval = 255; |
|
417 |
+ tuple_type = "RGB"; |
|
418 |
+ break; |
|
419 |
+ case PIX_FMT_RGBA32: |
|
420 |
+ n = w * 4; |
|
421 |
+ depth = 4; |
|
422 |
+ maxval = 255; |
|
423 |
+ tuple_type = "RGB_ALPHA"; |
|
424 |
+ break; |
|
425 |
+ default: |
|
426 |
+ return -1; |
|
427 |
+ } |
|
428 |
+ snprintf(s->bytestream, s->bytestream_end - s->bytestream, |
|
429 |
+ "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n", |
|
430 |
+ w, h, depth, maxval, tuple_type); |
|
431 |
+ s->bytestream += strlen(s->bytestream); |
|
432 |
+ |
|
433 |
+ ptr = p->data[0]; |
|
434 |
+ linesize = p->linesize[0]; |
|
435 |
+ |
|
436 |
+ if (avctx->pix_fmt == PIX_FMT_RGBA32) { |
|
437 |
+ int j; |
|
438 |
+ unsigned int v; |
|
439 |
+ |
|
440 |
+ for(i=0;i<h;i++) { |
|
441 |
+ for(j=0;j<w;j++) { |
|
442 |
+ v = ((uint32_t *)ptr)[j]; |
|
443 |
+ *s->bytestream++ = v >> 16; |
|
444 |
+ *s->bytestream++ = v >> 8; |
|
445 |
+ *s->bytestream++ = v; |
|
446 |
+ *s->bytestream++ = v >> 24; |
|
447 |
+ } |
|
448 |
+ ptr += linesize; |
|
449 |
+ } |
|
450 |
+ } else { |
|
451 |
+ for(i=0;i<h;i++) { |
|
452 |
+ memcpy(s->bytestream, ptr, n); |
|
453 |
+ s->bytestream += n; |
|
454 |
+ ptr += linesize; |
|
455 |
+ } |
|
456 |
+ } |
|
457 |
+ return s->bytestream - s->bytestream_start; |
|
458 |
+} |
|
459 |
+ |
|
460 |
+#if 0 |
|
461 |
+static int pnm_probe(AVProbeData *pd) |
|
462 |
+{ |
|
463 |
+ const char *p = pd->buf; |
|
464 |
+ if (pd->buf_size >= 8 && |
|
465 |
+ p[0] == 'P' && |
|
466 |
+ p[1] >= '4' && p[1] <= '6' && |
|
467 |
+ pnm_space(p[2]) ) |
|
468 |
+ return AVPROBE_SCORE_MAX - 1; /* to permit pgmyuv probe */ |
|
469 |
+ else |
|
470 |
+ return 0; |
|
471 |
+} |
|
472 |
+ |
|
473 |
+static int pgmyuv_probe(AVProbeData *pd) |
|
474 |
+{ |
|
475 |
+ if (match_ext(pd->filename, "pgmyuv")) |
|
476 |
+ return AVPROBE_SCORE_MAX; |
|
477 |
+ else |
|
478 |
+ return 0; |
|
479 |
+} |
|
480 |
+ |
|
481 |
+static int pam_probe(AVProbeData *pd) |
|
482 |
+{ |
|
483 |
+ const char *p = pd->buf; |
|
484 |
+ if (pd->buf_size >= 8 && |
|
485 |
+ p[0] == 'P' && |
|
486 |
+ p[1] == '7' && |
|
487 |
+ p[2] == '\n') |
|
488 |
+ return AVPROBE_SCORE_MAX; |
|
489 |
+ else |
|
490 |
+ return 0; |
|
491 |
+} |
|
492 |
+#endif |
|
493 |
+ |
|
494 |
+AVCodec pgm_encoder = { |
|
495 |
+ "pgm", |
|
496 |
+ CODEC_TYPE_VIDEO, |
|
497 |
+ CODEC_ID_PGM, |
|
498 |
+ sizeof(PNMContext), |
|
499 |
+ common_init, |
|
500 |
+ pnm_encode_frame, |
|
501 |
+ NULL, //encode_end, |
|
502 |
+ pnm_decode_frame, |
|
503 |
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_GRAY8, -1}, |
|
504 |
+}; |
|
505 |
+ |
|
506 |
+AVCodec pgmyuv_encoder = { |
|
507 |
+ "pgmyuv", |
|
508 |
+ CODEC_TYPE_VIDEO, |
|
509 |
+ CODEC_ID_PGMYUV, |
|
510 |
+ sizeof(PNMContext), |
|
511 |
+ common_init, |
|
512 |
+ pnm_encode_frame, |
|
513 |
+ NULL, //encode_end, |
|
514 |
+ pnm_decode_frame, |
|
515 |
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, |
|
516 |
+}; |
|
517 |
+ |
|
518 |
+AVCodec ppm_encoder = { |
|
519 |
+ "ppm", |
|
520 |
+ CODEC_TYPE_VIDEO, |
|
521 |
+ CODEC_ID_PPM, |
|
522 |
+ sizeof(PNMContext), |
|
523 |
+ common_init, |
|
524 |
+ pnm_encode_frame, |
|
525 |
+ NULL, //encode_end, |
|
526 |
+ pnm_decode_frame, |
|
527 |
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, -1}, |
|
528 |
+}; |
|
529 |
+ |
|
530 |
+AVCodec pbm_encoder = { |
|
531 |
+ "pbm", |
|
532 |
+ CODEC_TYPE_VIDEO, |
|
533 |
+ CODEC_ID_PBM, |
|
534 |
+ sizeof(PNMContext), |
|
535 |
+ common_init, |
|
536 |
+ pnm_encode_frame, |
|
537 |
+ NULL, //encode_end, |
|
538 |
+ pnm_decode_frame, |
|
539 |
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_MONOWHITE, -1}, |
|
540 |
+}; |
|
541 |
+ |
|
542 |
+AVCodec pam_encoder = { |
|
543 |
+ "pam", |
|
544 |
+ CODEC_TYPE_VIDEO, |
|
545 |
+ CODEC_ID_PAM, |
|
546 |
+ sizeof(PNMContext), |
|
547 |
+ common_init, |
|
548 |
+ pam_encode_frame, |
|
549 |
+ NULL, //encode_end, |
|
550 |
+ pam_decode_frame, |
|
551 |
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, -1}, |
|
552 |
+}; |
... | ... |
@@ -5,7 +5,7 @@ |
5 | 5 |
extern "C" { |
6 | 6 |
#endif |
7 | 7 |
|
8 |
-#define LIBAVFORMAT_BUILD 4620 |
|
8 |
+#define LIBAVFORMAT_BUILD 4621 |
|
9 | 9 |
|
10 | 10 |
#define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT |
11 | 11 |
#define LIBAVFORMAT_VERSION FFMPEG_VERSION |
... | ... |
@@ -115,6 +115,8 @@ typedef struct AVFormatParameters { |
115 | 115 |
mpeg2ts_raw is TRUE */ |
116 | 116 |
int initial_pause:1; /* do not begin to play the stream |
117 | 117 |
immediately (RTSP only) */ |
118 |
+ enum CodecID video_codec_id; |
|
119 |
+ enum CodecID audio_codec_id; |
|
118 | 120 |
} AVFormatParameters; |
119 | 121 |
|
120 | 122 |
#define AVFMT_NOFILE 0x0001 /* no file should be opened */ |
... | ... |
@@ -358,6 +360,7 @@ typedef struct AVImageFormat { |
358 | 358 |
void av_register_image_format(AVImageFormat *img_fmt); |
359 | 359 |
AVImageFormat *av_probe_image_format(AVProbeData *pd); |
360 | 360 |
AVImageFormat *guess_image_format(const char *filename); |
361 |
+enum CodecID av_guess_image2_codec(const char *filename); |
|
361 | 362 |
int av_read_image(ByteIOContext *pb, const char *filename, |
362 | 363 |
AVImageFormat *fmt, |
363 | 364 |
int (*alloc_cb)(void *, AVImageInfo *info), void *opaque); |
... | ... |
@@ -521,6 +524,8 @@ AVOutputFormat *guess_stream_format(const char *short_name, |
521 | 521 |
const char *filename, const char *mime_type); |
522 | 522 |
AVOutputFormat *guess_format(const char *short_name, |
523 | 523 |
const char *filename, const char *mime_type); |
524 |
+enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, |
|
525 |
+ const char *filename, const char *mime_type, enum CodecType type); |
|
524 | 526 |
|
525 | 527 |
void av_hex_dump(FILE *f, uint8_t *buf, int size); |
526 | 528 |
void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); |
... | ... |
@@ -38,6 +38,11 @@ static const IdStrMap img_tags[] = { |
38 | 38 |
{ CODEC_ID_MJPEG , "jpg"}, |
39 | 39 |
{ CODEC_ID_LJPEG , "ljpg"}, |
40 | 40 |
{ CODEC_ID_PNG , "png"}, |
41 |
+ { CODEC_ID_PPM , "ppm"}, |
|
42 |
+ { CODEC_ID_PGM , "pgm"}, |
|
43 |
+ { CODEC_ID_PGMYUV , "pgmyuv"}, |
|
44 |
+ { CODEC_ID_PBM , "pbm"}, |
|
45 |
+ { CODEC_ID_PAM , "pam"}, |
|
41 | 46 |
{ CODEC_ID_MPEG1VIDEO, "mpg1-img"}, |
42 | 47 |
{ CODEC_ID_MPEG2VIDEO, "mpg2-img"}, |
43 | 48 |
{ CODEC_ID_MPEG4 , "mpg4-img"}, |
... | ... |
@@ -133,6 +138,10 @@ static int image_probe(AVProbeData *p) |
133 | 133 |
return 0; |
134 | 134 |
} |
135 | 135 |
|
136 |
+enum CodecID av_guess_image2_codec(const char *filename){ |
|
137 |
+ return av_str2id(img_tags, filename); |
|
138 |
+} |
|
139 |
+ |
|
136 | 140 |
static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) |
137 | 141 |
{ |
138 | 142 |
VideoData *s = s1->priv_data; |
... | ... |
@@ -180,8 +189,16 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) |
180 | 180 |
st->codec.frame_rate_base) / st->codec.frame_rate; |
181 | 181 |
} |
182 | 182 |
|
183 |
- st->codec.codec_type = CODEC_TYPE_VIDEO; |
|
184 |
- st->codec.codec_id = av_str2id(img_tags, s->path); |
|
183 |
+ if(ap->video_codec_id){ |
|
184 |
+ st->codec.codec_type = CODEC_TYPE_VIDEO; |
|
185 |
+ st->codec.codec_id = ap->video_codec_id; |
|
186 |
+ }else if(ap->audio_codec_id){ |
|
187 |
+ st->codec.codec_type = CODEC_TYPE_AUDIO; |
|
188 |
+ st->codec.codec_id = ap->audio_codec_id; |
|
189 |
+ }else{ |
|
190 |
+ st->codec.codec_type = CODEC_TYPE_VIDEO; |
|
191 |
+ st->codec.codec_id = av_str2id(img_tags, s->path); |
|
192 |
+ } |
|
185 | 193 |
|
186 | 194 |
return 0; |
187 | 195 |
|
... | ... |
@@ -79,6 +79,11 @@ AVOutputFormat *guess_format(const char *short_name, const char *filename, |
79 | 79 |
/* specific test for image sequences */ |
80 | 80 |
if (!short_name && filename && |
81 | 81 |
filename_number_test(filename) >= 0 && |
82 |
+ av_guess_image2_codec(filename) != CODEC_ID_NONE) { |
|
83 |
+ return guess_format("image2", NULL, NULL); |
|
84 |
+ } |
|
85 |
+ if (!short_name && filename && |
|
86 |
+ filename_number_test(filename) >= 0 && |
|
82 | 87 |
guess_image_format(filename)) { |
83 | 88 |
return guess_format("image", NULL, NULL); |
84 | 89 |
} |
... | ... |
@@ -125,6 +130,26 @@ AVOutputFormat *guess_stream_format(const char *short_name, const char *filename |
125 | 125 |
return fmt; |
126 | 126 |
} |
127 | 127 |
|
128 |
+/** |
|
129 |
+ * guesses the codec id based upon muxer and filename. |
|
130 |
+ */ |
|
131 |
+enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, |
|
132 |
+ const char *filename, const char *mime_type, enum CodecType type){ |
|
133 |
+ if(type == CODEC_TYPE_VIDEO){ |
|
134 |
+ enum CodecID codec_id= CODEC_ID_NONE; |
|
135 |
+ |
|
136 |
+ if(!strcmp(fmt->name, "image2")){ |
|
137 |
+ codec_id= av_guess_image2_codec(filename); |
|
138 |
+ } |
|
139 |
+ if(codec_id == CODEC_ID_NONE) |
|
140 |
+ codec_id= fmt->video_codec; |
|
141 |
+ return codec_id; |
|
142 |
+ }else if(type == CODEC_TYPE_AUDIO) |
|
143 |
+ return fmt->audio_codec; |
|
144 |
+ else |
|
145 |
+ return CODEC_ID_NONE; |
|
146 |
+} |
|
147 |
+ |
|
128 | 148 |
AVInputFormat *av_find_input_format(const char *short_name) |
129 | 149 |
{ |
130 | 150 |
AVInputFormat *fmt; |
... | ... |
@@ -1740,6 +1765,11 @@ int av_find_stream_info(AVFormatContext *ic) |
1740 | 1740 |
st->codec.codec_id == CODEC_ID_VORBIS || |
1741 | 1741 |
st->codec.codec_id == CODEC_ID_MJPEG || |
1742 | 1742 |
st->codec.codec_id == CODEC_ID_PNG || |
1743 |
+ st->codec.codec_id == CODEC_ID_PAM || |
|
1744 |
+ st->codec.codec_id == CODEC_ID_PGM || |
|
1745 |
+ st->codec.codec_id == CODEC_ID_PGMYUV || |
|
1746 |
+ st->codec.codec_id == CODEC_ID_PBM || |
|
1747 |
+ st->codec.codec_id == CODEC_ID_PPM || |
|
1743 | 1748 |
(st->codec.codec_id == CODEC_ID_MPEG4 && !st->need_parsing))) |
1744 | 1749 |
try_decode_frame(st, pkt->data, pkt->size); |
1745 | 1750 |
|