5f93450368ef9979fa2509c666ae1298ecb85a13
[libav.git] / libavformat / img.c
1 /*
2 * Image format
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #include <unistd.h>
20 #include "avformat.h"
21
22 extern AVInputFormat pgm_iformat;
23 extern AVOutputFormat pgm_oformat;
24 extern AVInputFormat pgmyuv_iformat;
25 extern AVOutputFormat pgmyuv_oformat;
26 extern AVInputFormat ppm_iformat;
27 extern AVOutputFormat ppm_oformat;
28 extern AVInputFormat imgyuv_iformat;
29 extern AVOutputFormat imgyuv_oformat;
30 extern AVInputFormat pgmpipe_iformat;
31 extern AVOutputFormat pgmpipe_oformat;
32 extern AVInputFormat pgmyuvpipe_iformat;
33 extern AVOutputFormat pgmyuvpipe_oformat;
34 extern AVInputFormat ppmpipe_iformat;
35 extern AVOutputFormat ppmpipe_oformat;
36 extern AVOutputFormat yuv4mpegpipe_oformat;
37
38 #define IMGFMT_YUV 1
39 #define IMGFMT_PGMYUV 2
40 #define IMGFMT_PGM 3
41 #define IMGFMT_PPM 4
42 #define IMGFMT_YUV4MPEG 5
43
44 #define Y4M_MAGIC "YUV4MPEG2"
45 #define Y4M_FRAME_MAGIC "FRAME"
46 #define Y4M_LINE_MAX 256
47
48 typedef struct {
49 int width;
50 int height;
51 int img_number;
52 int img_size;
53 int img_fmt;
54 int is_pipe;
55 int header_written;
56 char path[1024];
57 } VideoData;
58
59 int emulate_frame_rate;
60
61 static inline int pnm_space(int c)
62 {
63 return (c==' ' || c=='\n' || c=='\r' || c=='\t');
64 }
65
66 static void pnm_get(ByteIOContext *f, char *str, int buf_size)
67 {
68 char *s;
69 int c;
70
71 do {
72 c=get_byte(f);
73 if (c=='#') {
74 do {
75 c=get_byte(f);
76 } while (c!='\n');
77 c=get_byte(f);
78 }
79 } while (pnm_space(c));
80
81 s=str;
82 do {
83 if (url_feof(f))
84 break;
85 if ((s - str) < buf_size - 1)
86 *s++=c;
87 c=get_byte(f);
88 } while (!pnm_space(c));
89 *s = '\0';
90 }
91
92 static int pgm_read(VideoData *s, ByteIOContext *f, UINT8 *buf, int size, int is_yuv)
93 {
94 int width, height, i;
95 char buf1[32];
96 UINT8 *picture[3];
97
98 width = s->width;
99 height = s->height;
100
101 pnm_get(f, buf1, sizeof(buf1));
102 if (strcmp(buf1, "P5")) {
103 return -EIO;
104 }
105 pnm_get(f, buf1, sizeof(buf1));
106 pnm_get(f, buf1, sizeof(buf1));
107 pnm_get(f, buf1, sizeof(buf1));
108
109 picture[0] = buf;
110 picture[1] = buf + width * height;
111 picture[2] = buf + width * height + (width * height / 4);
112 get_buffer(f, picture[0], width * height);
113
114 height>>=1;
115 width>>=1;
116 if (is_yuv) {
117 for(i=0;i<height;i++) {
118 get_buffer(f, picture[1] + i * width, width);
119 get_buffer(f, picture[2] + i * width, width);
120 }
121 } else {
122 for(i=0;i<height;i++) {
123 memset(picture[1] + i * width, 128, width);
124 memset(picture[2] + i * width, 128, width);
125 }
126 }
127 return 0;
128 }
129
130 static int ppm_read(VideoData *s, ByteIOContext *f, UINT8 *buf, int size)
131 {
132 int width, height;
133 char buf1[32];
134 UINT8 *picture[3];
135
136 width = s->width;
137 height = s->height;
138
139 pnm_get(f, buf1, sizeof(buf1));
140 if (strcmp(buf1, "P6")) {
141 return -EIO;
142 }
143
144 pnm_get(f, buf1, sizeof(buf1));
145 pnm_get(f, buf1, sizeof(buf1));
146 pnm_get(f, buf1, sizeof(buf1));
147
148 picture[0] = buf;
149 get_buffer(f, picture[0], width * height*3);
150
151 return 0;
152
153 }
154
155 static int yuv_read(VideoData *s, const char *filename, UINT8 *buf, int size1)
156 {
157 ByteIOContext pb1, *pb = &pb1;
158 char fname[1024], *p;
159 int size;
160
161 size = s->width * s->height;
162
163 strcpy(fname, filename);
164 p = strrchr(fname, '.');
165 if (!p || p[1] != 'Y')
166 return -EIO;
167
168 if (url_fopen(pb, fname, URL_RDONLY) < 0)
169 return -EIO;
170
171 get_buffer(pb, buf, size);
172 url_fclose(pb);
173
174 p[1] = 'U';
175 if (url_fopen(pb, fname, URL_RDONLY) < 0)
176 return -EIO;
177
178 get_buffer(pb, buf + size, size / 4);
179 url_fclose(pb);
180
181 p[1] = 'V';
182 if (url_fopen(pb, fname, URL_RDONLY) < 0)
183 return -EIO;
184
185 get_buffer(pb, buf + size + (size / 4), size / 4);
186 url_fclose(pb);
187 return 0;
188 }
189
190 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
191 {
192 VideoData *s = s1->priv_data;
193 char filename[1024];
194 int ret;
195 ByteIOContext f1, *f;
196 static INT64 first_frame;
197
198 if (emulate_frame_rate) {
199 if (!first_frame) {
200 first_frame = av_gettime();
201 } else {
202 INT64 pts;
203 INT64 nowus;
204
205 nowus = av_gettime() - first_frame;
206
207 pts = ((INT64)s->img_number * FRAME_RATE_BASE * 1000000) / (s1->streams[0]->codec.frame_rate);
208
209 if (pts > nowus)
210 usleep(pts - nowus);
211 }
212 }
213
214 /*
215 This if-statement destroys pipes - I do not see why it is necessary
216 if (get_frame_filename(filename, sizeof(filename),
217 s->path, s->img_number) < 0)
218 return -EIO;
219 */
220 get_frame_filename(filename, sizeof(filename),
221 s->path, s->img_number);
222 if (!s->is_pipe) {
223 f = &f1;
224 if (url_fopen(f, filename, URL_RDONLY) < 0)
225 return -EIO;
226 } else {
227 f = &s1->pb;
228 if (url_feof(f))
229 return -EIO;
230 }
231
232 av_new_packet(pkt, s->img_size);
233 pkt->stream_index = 0;
234
235 switch(s->img_fmt) {
236 case IMGFMT_PGMYUV:
237 ret = pgm_read(s, f, pkt->data, pkt->size, 1);
238 break;
239 case IMGFMT_PGM:
240 ret = pgm_read(s, f, pkt->data, pkt->size, 0);
241 break;
242 case IMGFMT_YUV:
243 ret = yuv_read(s, filename, pkt->data, pkt->size);
244 break;
245 case IMGFMT_PPM:
246 ret = ppm_read(s, f, pkt->data, pkt->size);
247 break;
248 default:
249 return -EIO;
250 }
251
252 if (!s->is_pipe) {
253 url_fclose(f);
254 }
255
256 if (ret < 0) {
257 av_free_packet(pkt);
258 return -EIO; /* signal EOF */
259 } else {
260 pkt->pts = ((INT64)s->img_number * s1->pts_den * FRAME_RATE_BASE) / (s1->streams[0]->codec.frame_rate * s1->pts_num);
261 s->img_number++;
262 return 0;
263 }
264 }
265
266 static int sizes[][2] = {
267 { 640, 480 },
268 { 720, 480 },
269 { 720, 576 },
270 { 352, 288 },
271 { 352, 240 },
272 { 160, 128 },
273 { 512, 384 },
274 { 640, 352 },
275 { 640, 240 },
276 };
277
278 static int infer_size(int *width_ptr, int *height_ptr, int size)
279 {
280 int i;
281
282 for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
283 if ((sizes[i][0] * sizes[i][1]) == size) {
284 *width_ptr = sizes[i][0];
285 *height_ptr = sizes[i][1];
286 return 0;
287 }
288 }
289 return -1;
290 }
291
292 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
293 {
294 VideoData *s = s1->priv_data;
295 int i, h;
296 char buf[1024];
297 char buf1[32];
298 ByteIOContext pb1, *f = &pb1;
299 AVStream *st;
300
301 st = av_new_stream(s1, 0);
302 if (!st) {
303 av_free(s);
304 return -ENOMEM;
305 }
306
307 strcpy(s->path, s1->filename);
308 s->img_number = 0;
309
310 /* find format */
311 if (s1->iformat->flags & AVFMT_NOFILE)
312 s->is_pipe = 0;
313 else
314 s->is_pipe = 1;
315
316 if (s1->iformat == &pgmyuvpipe_iformat ||
317 s1->iformat == &pgmyuv_iformat)
318 s->img_fmt = IMGFMT_PGMYUV;
319 else if (s1->iformat == &pgmpipe_iformat ||
320 s1->iformat == &pgm_iformat)
321 s->img_fmt = IMGFMT_PGM;
322 else if (s1->iformat == &imgyuv_iformat)
323 s->img_fmt = IMGFMT_YUV;
324 else if (s1->iformat == &ppmpipe_iformat ||
325 s1->iformat == &ppm_iformat)
326 s->img_fmt = IMGFMT_PPM;
327 else
328 goto fail;
329
330 if (!s->is_pipe) {
331 /* try to find the first image */
332 for(i=0;i<5;i++) {
333 if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
334 goto fail;
335 if (url_fopen(f, buf, URL_RDONLY) >= 0)
336 break;
337 s->img_number++;
338 }
339 if (i == 5)
340 goto fail;
341 } else {
342 f = &s1->pb;
343 }
344
345 /* find the image size */
346 /* XXX: use generic file format guessing, as mpeg */
347 switch(s->img_fmt) {
348 case IMGFMT_PGM:
349 case IMGFMT_PGMYUV:
350 case IMGFMT_PPM:
351 pnm_get(f, buf1, sizeof(buf1));
352 pnm_get(f, buf1, sizeof(buf1));
353 s->width = atoi(buf1);
354 pnm_get(f, buf1, sizeof(buf1));
355 h = atoi(buf1);
356 if (s->img_fmt == IMGFMT_PGMYUV)
357 h = (h * 2) / 3;
358 s->height = h;
359 if (s->width <= 0 ||
360 s->height <= 0 ||
361 (s->width % 2) != 0 ||
362 (s->height % 2) != 0) {
363 goto fail1;
364 }
365 break;
366 case IMGFMT_YUV:
367 /* infer size by using the file size. */
368 {
369 int img_size;
370 URLContext *h;
371
372 /* XXX: hack hack */
373 h = url_fileno(f);
374 img_size = url_seek(h, 0, SEEK_END);
375 if (infer_size(&s->width, &s->height, img_size) < 0) {
376 goto fail1;
377 }
378 }
379 break;
380 }
381
382
383 if (!s->is_pipe) {
384 url_fclose(f);
385 } else {
386 url_fseek(f, 0, SEEK_SET);
387 }
388
389
390 st->codec.codec_type = CODEC_TYPE_VIDEO;
391 st->codec.codec_id = CODEC_ID_RAWVIDEO;
392 st->codec.width = s->width;
393 st->codec.height = s->height;
394 if (s->img_fmt == IMGFMT_PPM) {
395 st->codec.pix_fmt = PIX_FMT_RGB24;
396 s->img_size = (s->width * s->height * 3);
397 } else {
398 st->codec.pix_fmt = PIX_FMT_YUV420P;
399 s->img_size = (s->width * s->height * 3) / 2;
400 }
401 if (!ap || !ap->frame_rate)
402 st->codec.frame_rate = 25 * FRAME_RATE_BASE;
403 else
404 st->codec.frame_rate = ap->frame_rate;
405
406 return 0;
407 fail1:
408 if (!s->is_pipe)
409 url_fclose(f);
410 fail:
411 av_free(s);
412 return -EIO;
413 }
414
415 static int img_read_close(AVFormatContext *s1)
416 {
417 return 0;
418 }
419
420 /******************************************************/
421 /* image output */
422
423 static int pgm_save(AVPicture *picture, int width, int height, ByteIOContext *pb, int is_yuv)
424 {
425 int i, h;
426 char buf[100];
427 UINT8 *ptr, *ptr1, *ptr2;
428
429 h = height;
430 if (is_yuv)
431 h = (height * 3) / 2;
432 snprintf(buf, sizeof(buf),
433 "P5\n%d %d\n%d\n",
434 width, h, 255);
435 put_buffer(pb, buf, strlen(buf));
436
437 ptr = picture->data[0];
438 for(i=0;i<height;i++) {
439 put_buffer(pb, ptr, width);
440 ptr += picture->linesize[0];
441 }
442
443 if (is_yuv) {
444 height >>= 1;
445 width >>= 1;
446 ptr1 = picture->data[1];
447 ptr2 = picture->data[2];
448 for(i=0;i<height;i++) {
449 put_buffer(pb, ptr1, width);
450 put_buffer(pb, ptr2, width);
451 ptr1 += picture->linesize[1];
452 ptr2 += picture->linesize[2];
453 }
454 }
455 put_flush_packet(pb);
456 return 0;
457 }
458
459 static int ppm_save(AVPicture *picture, int width, int height, ByteIOContext *pb)
460 {
461 int i;
462 char buf[100];
463 UINT8 *ptr;
464
465 snprintf(buf, sizeof(buf),
466 "P6\n%d %d\n%d\n",
467 width, height, 255);
468 put_buffer(pb, buf, strlen(buf));
469
470 ptr = picture->data[0];
471 for(i=0;i<height;i++) {
472 put_buffer(pb, ptr, width * 3);
473 ptr += picture->linesize[0];
474 }
475
476 put_flush_packet(pb);
477 return 0;
478 }
479
480 static int yuv_save(AVPicture *picture, int width, int height, const char *filename)
481 {
482 ByteIOContext pb1, *pb = &pb1;
483 char fname[1024], *p;
484 int i, j;
485 UINT8 *ptr;
486 static char *ext = "YUV";
487
488 strcpy(fname, filename);
489 p = strrchr(fname, '.');
490 if (!p || p[1] != 'Y')
491 return -EIO;
492
493 for(i=0;i<3;i++) {
494 if (i == 1) {
495 width >>= 1;
496 height >>= 1;
497 }
498
499 p[1] = ext[i];
500 if (url_fopen(pb, fname, URL_WRONLY) < 0)
501 return -EIO;
502
503 ptr = picture->data[i];
504 for(j=0;j<height;j++) {
505 put_buffer(pb, ptr, width);
506 ptr += picture->linesize[i];
507 }
508 put_flush_packet(pb);
509 url_fclose(pb);
510 }
511 return 0;
512 }
513
514 static int yuv4mpeg_save(AVPicture *picture, int width, int height, ByteIOContext *pb, int need_stream_header,
515 int is_yuv, int raten, int rated, int aspectn, int aspectd)
516 {
517 int i, n, m;
518 char buf[Y4M_LINE_MAX+1], buf1[20];
519 UINT8 *ptr, *ptr1, *ptr2;
520
521 /* construct stream header, if this is the first frame */
522 if(need_stream_header) {
523 n = snprintf(buf, sizeof(buf), "%s W%d H%d F%d:%d I%s A%d:%d\n",
524 Y4M_MAGIC,
525 width,
526 height,
527 raten, rated,
528 "p", /* ffmpeg seems to only output progressive video */
529 aspectn, aspectd);
530 if (n < 0) {
531 fprintf(stderr, "Error. YUV4MPEG stream header write failed.\n");
532 } else {
533 fprintf(stderr, "YUV4MPEG stream header written. FPS is %d\n", raten);
534 put_buffer(pb, buf, strlen(buf));
535 }
536 }
537
538 /* construct frame header */
539 m = snprintf(buf1, sizeof(buf1), "%s \n", Y4M_FRAME_MAGIC);
540 if (m < 0) {
541 fprintf(stderr, "Error. YUV4MPEG frame header write failed.\n");
542 } else {
543 /* fprintf(stderr, "YUV4MPEG frame header written.\n"); */
544 put_buffer(pb, buf1, strlen(buf1));
545 }
546
547 ptr = picture->data[0];
548 for(i=0;i<height;i++) {
549 put_buffer(pb, ptr, width);
550 ptr += picture->linesize[0];
551 }
552
553 if (is_yuv) {
554 height >>= 1;
555 width >>= 1;
556 ptr1 = picture->data[1];
557 ptr2 = picture->data[2];
558 for(i=0;i<height;i++) { /* Cb */
559 put_buffer(pb, ptr1, width);
560 ptr1 += picture->linesize[1];
561 }
562 for(i=0;i<height;i++) { /* Cr */
563 put_buffer(pb, ptr2, width);
564 ptr2 += picture->linesize[2];
565 }
566 }
567 put_flush_packet(pb);
568 return 0;
569 }
570
571 static int img_write_header(AVFormatContext *s)
572 {
573 VideoData *img = s->priv_data;
574
575 img->img_number = 1;
576 strcpy(img->path, s->filename);
577
578 /* find format */
579 if (s->oformat->flags & AVFMT_NOFILE)
580 img->is_pipe = 0;
581 else
582 img->is_pipe = 1;
583
584 if (s->oformat == &pgmyuvpipe_oformat ||
585 s->oformat == &pgmyuv_oformat) {
586 img->img_fmt = IMGFMT_PGMYUV;
587 } else if (s->oformat == &pgmpipe_oformat ||
588 s->oformat == &pgm_oformat) {
589 img->img_fmt = IMGFMT_PGM;
590 } else if (s->oformat == &imgyuv_oformat) {
591 img->img_fmt = IMGFMT_YUV;
592 } else if (s->oformat == &ppmpipe_oformat ||
593 s->oformat == &ppm_oformat) {
594 img->img_fmt = IMGFMT_PPM;
595 } else if (s->oformat == &yuv4mpegpipe_oformat) {
596 img->img_fmt = IMGFMT_YUV4MPEG;
597 img->header_written = 0;
598 } else {
599 goto fail;
600 }
601 return 0;
602 fail:
603 av_free(img);
604 return -EIO;
605 }
606
607 static int img_write_packet(AVFormatContext *s, int stream_index,
608 UINT8 *buf, int size, int force_pts)
609 {
610 VideoData *img = s->priv_data;
611 AVStream *st = s->streams[stream_index];
612 ByteIOContext pb1, *pb;
613 AVPicture picture;
614 int width, height, need_stream_header, ret, size1, raten, rated, aspectn, aspectd, fps, fps1;
615 char filename[1024];
616
617 width = st->codec.width;
618 height = st->codec.height;
619
620 if (img->img_number == 1) {
621 need_stream_header = 1;
622 } else {
623 need_stream_header = 0;
624 }
625
626 fps = st->codec.frame_rate;
627 fps1 = (((float)fps / FRAME_RATE_BASE) * 1000);
628
629 /* Sorry about this messy code, but mpeg2enc is very picky about
630 * the framerates it accepts. */
631 switch(fps1) {
632 case 23976:
633 raten = 24000; /* turn the framerate into a ratio */
634 rated = 1001;
635 break;
636 case 29970:
637 raten = 30000;
638 rated = 1001;
639 break;
640 case 25000:
641 raten = 25;
642 rated = 1;
643 break;
644 case 30000:
645 raten = 30;
646 rated = 1;
647 break;
648 case 24000:
649 raten = 24;
650 rated = 1;
651 break;
652 case 50000:
653 raten = 50;
654 rated = 1;
655 break;
656 case 59940:
657 raten = 60000;
658 rated = 1001;
659 break;
660 case 60000:
661 raten = 60;
662 rated = 1;
663 break;
664 default:
665 raten = fps1; /* this setting should work, but often doesn't */
666 rated = 1000;
667 break;
668 }
669
670 aspectn = 1;
671 aspectd = 1; /* ffmpeg always uses a 1:1 aspect ratio */
672
673 switch(st->codec.pix_fmt) {
674 case PIX_FMT_YUV420P:
675 size1 = (width * height * 3) / 2;
676 if (size != size1)
677 return -EIO;
678
679 picture.data[0] = buf;
680 picture.data[1] = picture.data[0] + width * height;
681 picture.data[2] = picture.data[1] + (width * height) / 4;
682 picture.linesize[0] = width;
683 picture.linesize[1] = width >> 1;
684 picture.linesize[2] = width >> 1;
685 break;
686 case PIX_FMT_RGB24:
687 size1 = (width * height * 3);
688 if (size != size1)
689 return -EIO;
690 picture.data[0] = buf;
691 picture.linesize[0] = width * 3;
692 break;
693 default:
694 return -EIO;
695 }
696
697 /*
698 This if-statement destroys pipes - I do not see why it is necessary
699 if (get_frame_filename(filename, sizeof(filename),
700 img->path, img->img_number) < 0)
701 return -EIO;
702 */
703 get_frame_filename(filename, sizeof(filename),
704 img->path, img->img_number);
705 if (!img->is_pipe) {
706 pb = &pb1;
707 if (url_fopen(pb, filename, URL_WRONLY) < 0)
708 return -EIO;
709 } else {
710 pb = &s->pb;
711 }
712 switch(img->img_fmt) {
713 case IMGFMT_PGMYUV:
714 ret = pgm_save(&picture, width, height, pb, 1);
715 break;
716 case IMGFMT_PGM:
717 ret = pgm_save(&picture, width, height, pb, 0);
718 break;
719 case IMGFMT_YUV:
720 ret = yuv_save(&picture, width, height, filename);
721 break;
722 case IMGFMT_PPM:
723 ret = ppm_save(&picture, width, height, pb);
724 break;
725 case IMGFMT_YUV4MPEG:
726 ret = yuv4mpeg_save(&picture, width, height, pb,
727 need_stream_header, 1, raten, rated, aspectn, aspectd);
728 break;
729 }
730 if (!img->is_pipe) {
731 url_fclose(pb);
732 }
733
734 img->img_number++;
735 return 0;
736 }
737
738 static int img_write_trailer(AVFormatContext *s)
739 {
740 return 0;
741 }
742
743 static AVInputFormat pgm_iformat = {
744 "pgm",
745 "pgm image format",
746 sizeof(VideoData),
747 NULL,
748 img_read_header,
749 img_read_packet,
750 img_read_close,
751 NULL,
752 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
753 .extensions = "pgm",
754 };
755
756 static AVOutputFormat pgm_oformat = {
757 "pgm",
758 "pgm image format",
759 "",
760 "pgm",
761 sizeof(VideoData),
762 CODEC_ID_NONE,
763 CODEC_ID_RAWVIDEO,
764 img_write_header,
765 img_write_packet,
766 img_write_trailer,
767 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
768 };
769
770 static AVInputFormat pgmyuv_iformat = {
771 "pgmyuv",
772 "pgm with YUV content image format",
773 sizeof(VideoData),
774 NULL, /* no probe */
775 img_read_header,
776 img_read_packet,
777 img_read_close,
778 NULL,
779 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
780 };
781
782 static AVOutputFormat pgmyuv_oformat = {
783 "pgmyuv",
784 "pgm with YUV content image format",
785 "",
786 "pgm",
787 sizeof(VideoData),
788 CODEC_ID_NONE,
789 CODEC_ID_RAWVIDEO,
790 img_write_header,
791 img_write_packet,
792 img_write_trailer,
793 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
794 };
795
796 static AVInputFormat ppm_iformat = {
797 "ppm",
798 "ppm image format",
799 sizeof(VideoData),
800 NULL,
801 img_read_header,
802 img_read_packet,
803 img_read_close,
804 NULL,
805 AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RGB24,
806 .extensions = "ppm",
807 };
808
809 static AVOutputFormat ppm_oformat = {
810 "ppm",
811 "ppm image format",
812 "",
813 "ppm",
814 sizeof(VideoData),
815 CODEC_ID_NONE,
816 CODEC_ID_RAWVIDEO,
817 img_write_header,
818 img_write_packet,
819 img_write_trailer,
820 AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RGB24,
821 };
822
823 static AVInputFormat imgyuv_iformat = {
824 ".Y.U.V",
825 ".Y.U.V format",
826 sizeof(VideoData),
827 NULL,
828 img_read_header,
829 img_read_packet,
830 img_read_close,
831 NULL,
832 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
833 .extensions = "Y",
834 };
835
836 static AVOutputFormat imgyuv_oformat = {
837 ".Y.U.V",
838 ".Y.U.V format",
839 "",
840 "Y",
841 sizeof(VideoData),
842 CODEC_ID_NONE,
843 CODEC_ID_RAWVIDEO,
844 img_write_header,
845 img_write_packet,
846 img_write_trailer,
847 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
848 };
849
850 static AVInputFormat pgmpipe_iformat = {
851 "pgmpipe",
852 "PGM pipe format",
853 sizeof(VideoData),
854 NULL, /* no probe */
855 img_read_header,
856 img_read_packet,
857 img_read_close,
858 NULL,
859 };
860
861 static AVOutputFormat pgmpipe_oformat = {
862 "pgmpipe",
863 "PGM pipe format",
864 "",
865 "pgm",
866 sizeof(VideoData),
867 CODEC_ID_NONE,
868 CODEC_ID_RAWVIDEO,
869 img_write_header,
870 img_write_packet,
871 img_write_trailer,
872 };
873
874 static AVInputFormat pgmyuvpipe_iformat = {
875 "pgmyuvpipe",
876 "PGM YUV pipe format",
877 sizeof(VideoData),
878 NULL, /* no probe */
879 img_read_header,
880 img_read_packet,
881 img_read_close,
882 NULL,
883 };
884
885 static AVOutputFormat pgmyuvpipe_oformat = {
886 "pgmyuvpipe",
887 "PGM YUV pipe format",
888 "",
889 "pgm",
890 sizeof(VideoData),
891 CODEC_ID_NONE,
892 CODEC_ID_RAWVIDEO,
893 img_write_header,
894 img_write_packet,
895 img_write_trailer,
896 };
897
898 static AVInputFormat ppmpipe_iformat = {
899 "ppmpipe",
900 "PPM pipe format",
901 sizeof(VideoData),
902 NULL, /* no probe */
903 img_read_header,
904 img_read_packet,
905 img_read_close,
906 NULL,
907 .flags = AVFMT_RGB24,
908 };
909
910 static AVOutputFormat ppmpipe_oformat = {
911 "ppmpipe",
912 "PPM pipe format",
913 "",
914 "ppm",
915 sizeof(VideoData),
916 CODEC_ID_NONE,
917 CODEC_ID_RAWVIDEO,
918 img_write_header,
919 img_write_packet,
920 img_write_trailer,
921 .flags = AVFMT_RGB24,
922 };
923
924
925 static AVOutputFormat yuv4mpegpipe_oformat = {
926 "yuv4mpegpipe",
927 "YUV4MPEG pipe format",
928 "",
929 "yuv4mpeg",
930 sizeof(VideoData),
931 CODEC_ID_NONE,
932 CODEC_ID_RAWVIDEO,
933 img_write_header,
934 img_write_packet,
935 img_write_trailer,
936 };
937
938
939 int img_init(void)
940 {
941 av_register_input_format(&pgm_iformat);
942 av_register_output_format(&pgm_oformat);
943
944 av_register_input_format(&pgmyuv_iformat);
945 av_register_output_format(&pgmyuv_oformat);
946
947 av_register_input_format(&ppm_iformat);
948 av_register_output_format(&ppm_oformat);
949
950 av_register_input_format(&imgyuv_iformat);
951 av_register_output_format(&imgyuv_oformat);
952
953 av_register_input_format(&pgmpipe_iformat);
954 av_register_output_format(&pgmpipe_oformat);
955
956 av_register_input_format(&pgmyuvpipe_iformat);
957 av_register_output_format(&pgmyuvpipe_oformat);
958
959 av_register_input_format(&ppmpipe_iformat);
960 av_register_output_format(&ppmpipe_oformat);
961
962 av_register_output_format(&yuv4mpegpipe_oformat);
963
964 return 0;
965 }