Browse code

rawvideo patch by (Fred Rothganger <rothgang at uiuc dot edu>)

Originally committed as revision 1687 to svn://svn.ffmpeg.org/ffmpeg/trunk

Fred Rothganger authored on 2003/03/17 06:03:20
Showing 7 changed files
... ...
@@ -386,102 +386,6 @@ static void do_audio_out(AVFormatContext *s,
386 386
     }
387 387
 }
388 388
 
389
-/* write a picture to a raw mux */
390
-static void write_picture(AVFormatContext *s, int index, AVPicture *picture, 
391
-                          int pix_fmt, int w, int h)
392
-{
393
-    uint8_t *buf, *src, *dest;
394
-    int size, j, i;
395
-
396
-    /* XXX: not efficient, should add test if we can take
397
-       directly the AVPicture */
398
-    switch(pix_fmt) {
399
-    case PIX_FMT_YUV420P:
400
-        size = avpicture_get_size(pix_fmt, w, h);
401
-        buf = av_malloc(size);
402
-        if (!buf)
403
-            return;
404
-        dest = buf;
405
-        for(i=0;i<3;i++) {
406
-            if (i == 1) {
407
-                w >>= 1;
408
-                h >>= 1;
409
-            }
410
-            src = picture->data[i];
411
-            for(j=0;j<h;j++) {
412
-                memcpy(dest, src, w);
413
-                dest += w;
414
-                src += picture->linesize[i];
415
-            }
416
-        }
417
-        break;
418
-    case PIX_FMT_YUV422P:
419
-        size = (w * h) * 2; 
420
-        buf = av_malloc(size);
421
-        if (!buf)
422
-            return;
423
-        dest = buf;
424
-        for(i=0;i<3;i++) {
425
-            if (i == 1) {
426
-                w >>= 1;
427
-            }
428
-            src = picture->data[i];
429
-            for(j=0;j<h;j++) {
430
-                memcpy(dest, src, w);
431
-                dest += w;
432
-                src += picture->linesize[i];
433
-            }
434
-        }
435
-        break;
436
-    case PIX_FMT_YUV444P:
437
-        size = (w * h) * 3; 
438
-        buf = av_malloc(size);
439
-        if (!buf)
440
-            return;
441
-        dest = buf;
442
-        for(i=0;i<3;i++) {
443
-            src = picture->data[i];
444
-            for(j=0;j<h;j++) {
445
-                memcpy(dest, src, w);
446
-                dest += w;
447
-                src += picture->linesize[i];
448
-            }
449
-        }
450
-        break;
451
-    case PIX_FMT_YUV422:
452
-        size = (w * h) * 2; 
453
-        buf = av_malloc(size);
454
-        if (!buf)
455
-            return;
456
-        dest = buf;
457
-        src = picture->data[0];
458
-        for(j=0;j<h;j++) {
459
-            memcpy(dest, src, w * 2);
460
-            dest += w * 2;
461
-            src += picture->linesize[0];
462
-        }
463
-        break;
464
-    case PIX_FMT_RGB24:
465
-    case PIX_FMT_BGR24:
466
-        size = (w * h) * 3; 
467
-        buf = av_malloc(size);
468
-        if (!buf)
469
-            return;
470
-        dest = buf;
471
-        src = picture->data[0];
472
-        for(j=0;j<h;j++) {
473
-            memcpy(dest, src, w * 3);
474
-            dest += w * 3;
475
-            src += picture->linesize[0];
476
-        }
477
-        break;
478
-    default:
479
-        return;
480
-    }
481
-    av_write_frame(s, index, buf, size);
482
-    av_free(buf);
483
-}
484
-
485 389
 static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void **bufp)
486 390
 {
487 391
     AVCodecContext *dec;
... ...
@@ -657,7 +561,13 @@ static void do_video_out(AVFormatContext *s,
657 657
     /* duplicates frame if needed */
658 658
     /* XXX: pb because no interleaving */
659 659
     for(i=0;i<nb_frames;i++) {
660
-        if (enc->codec_id != CODEC_ID_RAWVIDEO) {
660
+        if (s->oformat->flags & AVFMT_RAWPICTURE) {
661
+            /* raw pictures are written as AVPicture structure to
662
+               avoid any copies. We support temorarily the older
663
+               method. */
664
+            av_write_frame(s, ost->index, 
665
+                           (uint8_t *)final_picture, sizeof(AVPicture));
666
+        } else {
661 667
             AVFrame big_picture;
662 668
             
663 669
             memset(&big_picture, 0, sizeof(AVFrame));
... ...
@@ -683,17 +593,6 @@ static void do_video_out(AVFormatContext *s,
683 683
             if (ost->logfile && enc->stats_out) {
684 684
                 fprintf(ost->logfile, "%s", enc->stats_out);
685 685
             }
686
-        } else {
687
-            if (s->oformat->flags & AVFMT_RAWPICTURE) {
688
-                /* raw pictures are written as AVPicture structure to
689
-                   avoid any copies. We support temorarily the older
690
-                   method. */
691
-                av_write_frame(s, ost->index, 
692
-                               (uint8_t *)final_picture, sizeof(AVPicture));
693
-            } else {
694
-                write_picture(s, ost->index, final_picture, enc->pix_fmt, 
695
-                              enc->width, enc->height);
696
-            }
697 686
         }
698 687
         ost->frame_number++;
699 688
     }
... ...
@@ -1311,16 +1210,7 @@ static int av_encode(AVFormatContext **output_files,
1311 1311
                     data_buf = (uint8_t *)samples;
1312 1312
                     break;
1313 1313
                 case CODEC_TYPE_VIDEO:
1314
-                    if (ist->st->codec.codec_id == CODEC_ID_RAWVIDEO) {
1315
-                        int size;
1316
-
1317
-                        size = (ist->st->codec.width * ist->st->codec.height);
1318
-                        avpicture_fill(&picture, ptr, 
1319
-                                     ist->st->codec.pix_fmt,
1320
-                                     ist->st->codec.width,
1321
-                                     ist->st->codec.height);
1322
-                        ret = len;
1323
-                    } else {
1314
+                    {
1324 1315
                         AVFrame big_picture;
1325 1316
 
1326 1317
                         data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2;
... ...
@@ -16,7 +16,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \
16 16
       motion_est.o imgconvert.o imgresample.o \
17 17
       mpeg12.o mpegaudiodec.o pcm.o simple_idct.o \
18 18
       ratecontrol.o adpcm.o eval.o dv.o error_resilience.o \
19
-      fft.o mdct.o mace.o huffyuv.o cyuv.o opts.o
19
+      fft.o mdct.o mace.o huffyuv.o cyuv.o opts.o raw.o
20 20
 ASM_OBJS=
21 21
 
22 22
 # codecs which are patented in some non free countries like the us
... ...
@@ -907,6 +907,10 @@ static inline int ff_get_fourcc(const char *s){
907 907
     return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24);
908 908
 }
909 909
 
910
+#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
911
+#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
912
+
913
+
910 914
 void ff_float2fraction(int *nom_arg, int *denom_arg, double f, int max);
911 915
 
912 916
 
913 917
new file mode 100644
... ...
@@ -0,0 +1,204 @@
0
+/*
1
+ * Raw Video Codec
2
+ * Copyright (c) 2001 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
+ 
19
+/**
20
+ * @file raw.c
21
+ * Raw Video Codec
22
+ */
23
+ 
24
+#include "avcodec.h"
25
+
26
+
27
+typedef struct PixleFormatTag {
28
+    int pix_fmt;
29
+    unsigned int fourcc;
30
+} PixelFormatTag;
31
+
32
+const PixelFormatTag pixelFormatTags[] = {
33
+    { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') },
34
+    { -1, 0 },
35
+};
36
+
37
+static int findPixelFormat(unsigned int fourcc)
38
+{
39
+    const PixelFormatTag * tags = pixelFormatTags;
40
+    while (tags->pix_fmt >= 0) {
41
+        if (tags->fourcc == fourcc)
42
+            return tags->pix_fmt;
43
+        tags++;
44
+    }
45
+    return PIX_FMT_YUV420P;
46
+}
47
+
48
+
49
+typedef struct RawVideoContext {
50
+    unsigned char * buffer;  /* block of memory for holding one frame */
51
+    unsigned char * p;       /* current position in buffer */
52
+    int             length;  /* number of bytes in buffer */
53
+} RawVideoContext;
54
+
55
+
56
+static int raw_init(AVCodecContext *avctx)
57
+{
58
+    RawVideoContext *context = avctx->priv_data;
59
+
60
+    if (avctx->codec_tag) {
61
+	    avctx->pix_fmt = findPixelFormat(avctx->codec_tag);
62
+    }
63
+
64
+	context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
65
+	context->buffer = av_malloc(context->length);
66
+	context->p      = context->buffer;
67
+
68
+    if (! context->buffer) {
69
+        return -1;
70
+    }
71
+
72
+    return 0;
73
+}
74
+
75
+static int raw_decode(AVCodecContext *avctx,
76
+			    void *data, int *data_size,
77
+			    uint8_t *buf, int buf_size)
78
+{
79
+    RawVideoContext *context = avctx->priv_data;
80
+
81
+    AVPicture * picture = (AVPicture *) data;
82
+
83
+    /* Early out without copy if packet size == frame size */
84
+    if (buf_size == context->length  &&  context->p == context->buffer) {
85
+        avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
86
+        *data_size = sizeof(AVPicture);
87
+        return buf_size;
88
+    }
89
+
90
+    int bytesNeeded = context->length - (context->p - context->buffer);
91
+    if (buf_size < bytesNeeded) {
92
+        memcpy(context->p, buf, buf_size);
93
+        context->p += buf_size;
94
+        *data_size = 0;
95
+        return buf_size;
96
+    }
97
+
98
+    memcpy(context->p, buf, bytesNeeded);
99
+    context->p = context->buffer;
100
+    avpicture_fill(picture, context->buffer, avctx->pix_fmt, avctx->width, avctx->height);
101
+    *data_size = sizeof(AVPicture);
102
+    return bytesNeeded;
103
+}
104
+
105
+static int raw_close(AVCodecContext *avctx)
106
+{
107
+    RawVideoContext *context = avctx->priv_data;
108
+
109
+    av_freep(& context->buffer);
110
+
111
+    return 0;
112
+}
113
+
114
+static int raw_encode(AVCodecContext *avctx,
115
+			    unsigned char *frame, int buf_size, void *data)
116
+{
117
+	AVPicture * picture = data;
118
+
119
+    unsigned char *src;
120
+	unsigned char *dest = frame;
121
+    int i, j;
122
+
123
+	int w = avctx->width;
124
+	int h = avctx->height;
125
+	int size = avpicture_get_size(avctx->pix_fmt, w, h);
126
+
127
+    if (size > buf_size) {
128
+        return -1;
129
+    }
130
+
131
+    switch(avctx->pix_fmt) {
132
+    case PIX_FMT_YUV420P:
133
+        for(i=0;i<3;i++) {
134
+            if (i == 1) {
135
+                w >>= 1;
136
+                h >>= 1;
137
+            }
138
+            src = picture->data[i];
139
+            for(j=0;j<h;j++) {
140
+                memcpy(dest, src, w);
141
+                dest += w;
142
+                src += picture->linesize[i];
143
+            }
144
+        }
145
+        break;
146
+    case PIX_FMT_YUV422P:
147
+        for(i=0;i<3;i++) {
148
+            if (i == 1) {
149
+                w >>= 1;
150
+            }
151
+            src = picture->data[i];
152
+            for(j=0;j<h;j++) {
153
+                memcpy(dest, src, w);
154
+                dest += w;
155
+                src += picture->linesize[i];
156
+            }
157
+        }
158
+        break;
159
+    case PIX_FMT_YUV444P:
160
+        for(i=0;i<3;i++) {
161
+            src = picture->data[i];
162
+            for(j=0;j<h;j++) {
163
+                memcpy(dest, src, w);
164
+                dest += w;
165
+                src += picture->linesize[i];
166
+            }
167
+        }
168
+        break;
169
+    case PIX_FMT_YUV422:
170
+        src = picture->data[0];
171
+        for(j=0;j<h;j++) {
172
+            memcpy(dest, src, w * 2);
173
+            dest += w * 2;
174
+            src += picture->linesize[0];
175
+        }
176
+        break;
177
+    case PIX_FMT_RGB24:
178
+    case PIX_FMT_BGR24:
179
+        src = picture->data[0];
180
+        for(j=0;j<h;j++) {
181
+            memcpy(dest, src, w * 3);
182
+            dest += w * 3;
183
+            src += picture->linesize[0];
184
+        }
185
+        break;
186
+    default:
187
+        return -1;
188
+    }
189
+
190
+    return size;
191
+}
192
+
193
+
194
+AVCodec rawvideo_codec = {
195
+    "rawvideo",
196
+    CODEC_TYPE_VIDEO,
197
+    CODEC_ID_RAWVIDEO,
198
+    sizeof(RawVideoContext),
199
+    raw_init,
200
+    raw_encode,
201
+    raw_close,
202
+    raw_decode,
203
+};
... ...
@@ -647,32 +647,3 @@ int64_t av_rescale(int64_t a, int b, int c){
647 647
 
648 648
     return ((h/c)<<32) + l/c;
649 649
 }
650
-
651
-static int raw_encode_init(AVCodecContext *s)
652
-{
653
-    return 0;
654
-}
655
-
656
-static int raw_decode_frame(AVCodecContext *avctx,
657
-			    void *data, int *data_size,
658
-			    uint8_t *buf, int buf_size)
659
-{
660
-    return -1;
661
-}
662
-
663
-static int raw_encode_frame(AVCodecContext *avctx,
664
-			    unsigned char *frame, int buf_size, void *data)
665
-{
666
-    return -1;
667
-}
668
-
669
-AVCodec rawvideo_codec = {
670
-    "rawvideo",
671
-    CODEC_TYPE_VIDEO,
672
-    CODEC_ID_RAWVIDEO,
673
-    0,
674
-    raw_encode_init,
675
-    raw_encode_frame,
676
-    NULL,
677
-    raw_decode_frame,
678
-};
... ...
@@ -331,9 +331,6 @@ int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f);
331 331
 extern AVOutputFormat yuv4mpegpipe_oformat;
332 332
 
333 333
 /* utils.c */
334
-#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
335
-#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
336
-
337 334
 void av_register_input_format(AVInputFormat *format);
338 335
 void av_register_output_format(AVOutputFormat *format);
339 336
 AVOutputFormat *guess_stream_format(const char *short_name, 
... ...
@@ -89,6 +89,7 @@ const CodecTag codec_bmp_tags[] = {
89 89
     { CODEC_ID_HUFFYUV, MKTAG('h', 'f', 'y', 'u') },
90 90
     { CODEC_ID_CYUV, MKTAG('C', 'Y', 'U', 'V') },
91 91
     { CODEC_ID_CYUV, MKTAG('c', 'y', 'u', 'v') },
92
+    { CODEC_ID_RAWVIDEO, MKTAG('Y', '4', '2', '2') },
92 93
     { 0, 0 },
93 94
 };
94 95
 
... ...
@@ -249,12 +250,17 @@ static int avi_write_header(AVFormatContext *s)
249 249
     
250 250
         stream = &s->streams[i]->codec;
251 251
 
252
+        /* FourCC should really be set by the codec itself */
253
+        if (! stream->codec_tag) {
254
+            stream->codec_tag = codec_get_bmp_tag(stream->codec_id);
255
+        }
256
+
252 257
         /* stream generic header */
253 258
         strh = start_tag(pb, "strh");
254 259
         switch(stream->codec_type) {
255 260
         case CODEC_TYPE_VIDEO:
256 261
             put_tag(pb, "vids");
257
-            put_le32(pb, codec_get_bmp_tag(stream->codec_id));
262
+            put_le32(pb, stream->codec_tag);
258 263
             put_le32(pb, 0); /* flags */
259 264
             put_le16(pb, 0); /* priority */
260 265
             put_le16(pb, 0); /* language */