Browse code

split ljpeg encoder out of mjpeg.c

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

Aurelien Jacobs authored on 2007/05/19 07:42:49
Showing 6 changed files
... ...
@@ -99,7 +99,7 @@ OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
99 99
 OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)  += dpcm.o
100 100
 OBJS-$(CONFIG_JPEGLS_ENCODER)          += jpeglsenc.o jpegls.o
101 101
 OBJS-$(CONFIG_KMVC_DECODER)            += kmvc.o
102
-OBJS-$(CONFIG_LJPEG_ENCODER)           += mjpegenc.o mjpeg.o mpegvideo.o
102
+OBJS-$(CONFIG_LJPEG_ENCODER)           += ljpegenc.o mjpegenc.o mjpeg.o mpegvideo.o
103 103
 OBJS-$(CONFIG_LOCO_DECODER)            += loco.o
104 104
 OBJS-$(CONFIG_MACE3_DECODER)           += mace.o
105 105
 OBJS-$(CONFIG_MACE6_DECODER)           += mace.o
106 106
new file mode 100644
... ...
@@ -0,0 +1,197 @@
0
+/*
1
+ * lossless JPEG encoder
2
+ * Copyright (c) 2000, 2001 Fabrice Bellard.
3
+ * Copyright (c) 2003 Alex Beregszaszi
4
+ * Copyright (c) 2003-2004 Michael Niedermayer
5
+ *
6
+ * This file is part of FFmpeg.
7
+ *
8
+ * FFmpeg is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Lesser General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2.1 of the License, or (at your option) any later version.
12
+ *
13
+ * FFmpeg is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Lesser General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public
19
+ * License along with FFmpeg; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ *
22
+ * Support for external huffman table, various fixes (AVID workaround),
23
+ * aspecting, new decode_frame mechanism and apple mjpeg-b support
24
+ *                                  by Alex Beregszaszi
25
+ */
26
+
27
+/**
28
+ * @file ljpegenc.c
29
+ * lossless JPEG encoder.
30
+ */
31
+
32
+#include "avcodec.h"
33
+#include "dsputil.h"
34
+#include "mpegvideo.h"
35
+#include "mjpeg.h"
36
+#include "mjpegenc.h"
37
+
38
+
39
+static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
40
+    MpegEncContext * const s = avctx->priv_data;
41
+    MJpegContext * const m = s->mjpeg_ctx;
42
+    AVFrame *pict = data;
43
+    const int width= s->width;
44
+    const int height= s->height;
45
+    AVFrame * const p= (AVFrame*)&s->current_picture;
46
+    const int predictor= avctx->prediction_method+1;
47
+
48
+    init_put_bits(&s->pb, buf, buf_size);
49
+
50
+    *p = *pict;
51
+    p->pict_type= FF_I_TYPE;
52
+    p->key_frame= 1;
53
+
54
+    mjpeg_picture_header(s);
55
+
56
+    s->header_bits= put_bits_count(&s->pb);
57
+
58
+    if(avctx->pix_fmt == PIX_FMT_RGB32){
59
+        int x, y, i;
60
+        const int linesize= p->linesize[0];
61
+        uint16_t (*buffer)[4]= (void *) s->rd_scratchpad;
62
+        int left[3], top[3], topleft[3];
63
+
64
+        for(i=0; i<3; i++){
65
+            buffer[0][i]= 1 << (9 - 1);
66
+        }
67
+
68
+        for(y = 0; y < height; y++) {
69
+            const int modified_predictor= y ? predictor : 1;
70
+            uint8_t *ptr = p->data[0] + (linesize * y);
71
+
72
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){
73
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
74
+                return -1;
75
+            }
76
+
77
+            for(i=0; i<3; i++){
78
+                top[i]= left[i]= topleft[i]= buffer[0][i];
79
+            }
80
+            for(x = 0; x < width; x++) {
81
+                buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100;
82
+                buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100;
83
+                buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2;
84
+
85
+                for(i=0;i<3;i++) {
86
+                    int pred, diff;
87
+
88
+                    PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
89
+
90
+                    topleft[i]= top[i];
91
+                    top[i]= buffer[x+1][i];
92
+
93
+                    left[i]= buffer[x][i];
94
+
95
+                    diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100;
96
+
97
+                    if(i==0)
98
+                        mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
99
+                    else
100
+                        mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
101
+                }
102
+            }
103
+        }
104
+    }else{
105
+        int mb_x, mb_y, i;
106
+        const int mb_width  = (width  + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0];
107
+        const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0];
108
+
109
+        for(mb_y = 0; mb_y < mb_height; mb_y++) {
110
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){
111
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
112
+                return -1;
113
+            }
114
+            for(mb_x = 0; mb_x < mb_width; mb_x++) {
115
+                if(mb_x==0 || mb_y==0){
116
+                    for(i=0;i<3;i++) {
117
+                        uint8_t *ptr;
118
+                        int x, y, h, v, linesize;
119
+                        h = s->mjpeg_hsample[i];
120
+                        v = s->mjpeg_vsample[i];
121
+                        linesize= p->linesize[i];
122
+
123
+                        for(y=0; y<v; y++){
124
+                            for(x=0; x<h; x++){
125
+                                int pred;
126
+
127
+                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
128
+                                if(y==0 && mb_y==0){
129
+                                    if(x==0 && mb_x==0){
130
+                                        pred= 128;
131
+                                    }else{
132
+                                        pred= ptr[-1];
133
+                                    }
134
+                                }else{
135
+                                    if(x==0 && mb_x==0){
136
+                                        pred= ptr[-linesize];
137
+                                    }else{
138
+                                        PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
139
+                                    }
140
+                                }
141
+
142
+                                if(i==0)
143
+                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
144
+                                else
145
+                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
146
+                            }
147
+                        }
148
+                    }
149
+                }else{
150
+                    for(i=0;i<3;i++) {
151
+                        uint8_t *ptr;
152
+                        int x, y, h, v, linesize;
153
+                        h = s->mjpeg_hsample[i];
154
+                        v = s->mjpeg_vsample[i];
155
+                        linesize= p->linesize[i];
156
+
157
+                        for(y=0; y<v; y++){
158
+                            for(x=0; x<h; x++){
159
+                                int pred;
160
+
161
+                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
162
+//printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr);
163
+                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
164
+
165
+                                if(i==0)
166
+                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
167
+                                else
168
+                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
169
+                            }
170
+                        }
171
+                    }
172
+                }
173
+            }
174
+        }
175
+    }
176
+
177
+    emms_c();
178
+
179
+    mjpeg_picture_trailer(s);
180
+    s->picture_number++;
181
+
182
+    flush_put_bits(&s->pb);
183
+    return pbBufPtr(&s->pb) - s->pb.buf;
184
+//    return (put_bits_count(&f->pb)+7)/8;
185
+}
186
+
187
+
188
+AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them
189
+    "ljpeg",
190
+    CODEC_TYPE_VIDEO,
191
+    CODEC_ID_LJPEG,
192
+    sizeof(MpegEncContext),
193
+    MPV_encode_init,
194
+    encode_picture_lossless,
195
+    MPV_encode_end,
196
+};
... ...
@@ -37,23 +37,12 @@
37 37
 #include "dsputil.h"
38 38
 #include "mpegvideo.h"
39 39
 #include "mjpeg.h"
40
+#include "mjpegenc.h"
40 41
 
41 42
 /* use two quantizer tables (one for luminance and one for chrominance) */
42 43
 /* not yet working */
43 44
 #undef TWOMATRIXES
44 45
 
45
-typedef struct MJpegContext {
46
-    uint8_t huff_size_dc_luminance[12]; //FIXME use array [3] instead of lumi / chrom, for easier addressing
47
-    uint16_t huff_code_dc_luminance[12];
48
-    uint8_t huff_size_dc_chrominance[12];
49
-    uint16_t huff_code_dc_chrominance[12];
50
-
51
-    uint8_t huff_size_ac_luminance[256];
52
-    uint16_t huff_code_ac_luminance[256];
53
-    uint8_t huff_size_ac_chrominance[256];
54
-    uint16_t huff_code_ac_chrominance[256];
55
-} MJpegContext;
56
-
57 46
 
58 47
 int mjpeg_init(MpegEncContext *s)
59 48
 {
... ...
@@ -365,7 +354,7 @@ void mjpeg_picture_trailer(MpegEncContext *s)
365 365
     put_marker(&s->pb, EOI);
366 366
 }
367 367
 
368
-static inline void mjpeg_encode_dc(MpegEncContext *s, int val,
368
+void mjpeg_encode_dc(MpegEncContext *s, int val,
369 369
                                    uint8_t *huff_size, uint16_t *huff_code)
370 370
 {
371 371
     int mant, nbits;
... ...
@@ -460,162 +449,3 @@ void mjpeg_encode_mb(MpegEncContext *s,
460 460
         encode_block(s, block[7], 7);
461 461
     }
462 462
 }
463
-
464
-static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
465
-    MpegEncContext * const s = avctx->priv_data;
466
-    MJpegContext * const m = s->mjpeg_ctx;
467
-    AVFrame *pict = data;
468
-    const int width= s->width;
469
-    const int height= s->height;
470
-    AVFrame * const p= (AVFrame*)&s->current_picture;
471
-    const int predictor= avctx->prediction_method+1;
472
-
473
-    init_put_bits(&s->pb, buf, buf_size);
474
-
475
-    *p = *pict;
476
-    p->pict_type= FF_I_TYPE;
477
-    p->key_frame= 1;
478
-
479
-    mjpeg_picture_header(s);
480
-
481
-    s->header_bits= put_bits_count(&s->pb);
482
-
483
-    if(avctx->pix_fmt == PIX_FMT_RGB32){
484
-        int x, y, i;
485
-        const int linesize= p->linesize[0];
486
-        uint16_t (*buffer)[4]= (void *) s->rd_scratchpad;
487
-        int left[3], top[3], topleft[3];
488
-
489
-        for(i=0; i<3; i++){
490
-            buffer[0][i]= 1 << (9 - 1);
491
-        }
492
-
493
-        for(y = 0; y < height; y++) {
494
-            const int modified_predictor= y ? predictor : 1;
495
-            uint8_t *ptr = p->data[0] + (linesize * y);
496
-
497
-            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){
498
-                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
499
-                return -1;
500
-            }
501
-
502
-            for(i=0; i<3; i++){
503
-                top[i]= left[i]= topleft[i]= buffer[0][i];
504
-            }
505
-            for(x = 0; x < width; x++) {
506
-                buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100;
507
-                buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100;
508
-                buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2;
509
-
510
-                for(i=0;i<3;i++) {
511
-                    int pred, diff;
512
-
513
-                    PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
514
-
515
-                    topleft[i]= top[i];
516
-                    top[i]= buffer[x+1][i];
517
-
518
-                    left[i]= buffer[x][i];
519
-
520
-                    diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100;
521
-
522
-                    if(i==0)
523
-                        mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
524
-                    else
525
-                        mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
526
-                }
527
-            }
528
-        }
529
-    }else{
530
-        int mb_x, mb_y, i;
531
-        const int mb_width  = (width  + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0];
532
-        const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0];
533
-
534
-        for(mb_y = 0; mb_y < mb_height; mb_y++) {
535
-            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){
536
-                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
537
-                return -1;
538
-            }
539
-            for(mb_x = 0; mb_x < mb_width; mb_x++) {
540
-                if(mb_x==0 || mb_y==0){
541
-                    for(i=0;i<3;i++) {
542
-                        uint8_t *ptr;
543
-                        int x, y, h, v, linesize;
544
-                        h = s->mjpeg_hsample[i];
545
-                        v = s->mjpeg_vsample[i];
546
-                        linesize= p->linesize[i];
547
-
548
-                        for(y=0; y<v; y++){
549
-                            for(x=0; x<h; x++){
550
-                                int pred;
551
-
552
-                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
553
-                                if(y==0 && mb_y==0){
554
-                                    if(x==0 && mb_x==0){
555
-                                        pred= 128;
556
-                                    }else{
557
-                                        pred= ptr[-1];
558
-                                    }
559
-                                }else{
560
-                                    if(x==0 && mb_x==0){
561
-                                        pred= ptr[-linesize];
562
-                                    }else{
563
-                                        PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
564
-                                    }
565
-                                }
566
-
567
-                                if(i==0)
568
-                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
569
-                                else
570
-                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
571
-                            }
572
-                        }
573
-                    }
574
-                }else{
575
-                    for(i=0;i<3;i++) {
576
-                        uint8_t *ptr;
577
-                        int x, y, h, v, linesize;
578
-                        h = s->mjpeg_hsample[i];
579
-                        v = s->mjpeg_vsample[i];
580
-                        linesize= p->linesize[i];
581
-
582
-                        for(y=0; y<v; y++){
583
-                            for(x=0; x<h; x++){
584
-                                int pred;
585
-
586
-                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
587
-//printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr);
588
-                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
589
-
590
-                                if(i==0)
591
-                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
592
-                                else
593
-                                    mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
594
-                            }
595
-                        }
596
-                    }
597
-                }
598
-            }
599
-        }
600
-    }
601
-
602
-    emms_c();
603
-
604
-    mjpeg_picture_trailer(s);
605
-    s->picture_number++;
606
-
607
-    flush_put_bits(&s->pb);
608
-    return pbBufPtr(&s->pb) - s->pb.buf;
609
-//    return (put_bits_count(&f->pb)+7)/8;
610
-}
611
-
612
-
613
-AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them
614
-    "ljpeg",
615
-    CODEC_TYPE_VIDEO,
616
-    CODEC_ID_LJPEG,
617
-    sizeof(MpegEncContext),
618
-    MPV_encode_init,
619
-    encode_picture_lossless,
620
-    MPV_encode_end,
621
-};
622 463
new file mode 100644
... ...
@@ -0,0 +1,60 @@
0
+/*
1
+ * MJPEG encoder
2
+ * Copyright (c) 2000, 2001 Fabrice Bellard.
3
+ * Copyright (c) 2003 Alex Beregszaszi
4
+ * Copyright (c) 2003-2004 Michael Niedermayer
5
+ *
6
+ * This file is part of FFmpeg.
7
+ *
8
+ * FFmpeg is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Lesser General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2.1 of the License, or (at your option) any later version.
12
+ *
13
+ * FFmpeg is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Lesser General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public
19
+ * License along with FFmpeg; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ *
22
+ * Support for external huffman table, various fixes (AVID workaround),
23
+ * aspecting, new decode_frame mechanism and apple mjpeg-b support
24
+ *                                  by Alex Beregszaszi
25
+ */
26
+
27
+/**
28
+ * @file mjpegenc.h
29
+ * MJPEG encoder.
30
+ */
31
+
32
+#ifndef MJPEGENC_H
33
+#define MJPEGENC_H
34
+
35
+#include "dsputil.h"
36
+#include "mpegvideo.h"
37
+
38
+typedef struct MJpegContext {
39
+    uint8_t huff_size_dc_luminance[12]; //FIXME use array [3] instead of lumi / chrom, for easier addressing
40
+    uint16_t huff_code_dc_luminance[12];
41
+    uint8_t huff_size_dc_chrominance[12];
42
+    uint16_t huff_code_dc_chrominance[12];
43
+
44
+    uint8_t huff_size_ac_luminance[256];
45
+    uint16_t huff_code_ac_luminance[256];
46
+    uint8_t huff_size_ac_chrominance[256];
47
+    uint16_t huff_code_ac_chrominance[256];
48
+} MJpegContext;
49
+
50
+int mjpeg_init(MpegEncContext *s);
51
+void mjpeg_close(MpegEncContext *s);
52
+void mjpeg_picture_header(MpegEncContext *s);
53
+void mjpeg_picture_trailer(MpegEncContext *s);
54
+void ff_mjpeg_stuffing(PutBitContext *pbc);
55
+void mjpeg_encode_dc(MpegEncContext *s, int val,
56
+                     uint8_t *huff_size, uint16_t *huff_code);
57
+void mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]);
58
+
59
+#endif /* MJPEGENC_H */
... ...
@@ -30,6 +30,7 @@
30 30
 #include "avcodec.h"
31 31
 #include "dsputil.h"
32 32
 #include "mpegvideo.h"
33
+#include "mjpegenc.h"
33 34
 #include "msmpeg4.h"
34 35
 #include "faandct.h"
35 36
 #include <limits.h>
... ...
@@ -905,14 +905,5 @@ void ff_wmv2_encode_mb(MpegEncContext * s,
905 905
                        DCTELEM block[6][64],
906 906
                        int motion_x, int motion_y);
907 907
 
908
-/* mjpeg.c */
909
-int mjpeg_init(MpegEncContext *s);
910
-void mjpeg_close(MpegEncContext *s);
911
-void mjpeg_encode_mb(MpegEncContext *s,
912
-                     DCTELEM block[6][64]);
913
-void mjpeg_picture_header(MpegEncContext *s);
914
-void mjpeg_picture_trailer(MpegEncContext *s);
915
-void ff_mjpeg_stuffing(PutBitContext * pbc);
916
-
917 908
 #endif /* AVCODEC_MPEGVIDEO_H */
918 909