]> git.sesse.net Git - ffmpeg/blob - libavcodec/mjpegenc.c
lavc: mark the old audio/video encoding API as deprecated
[ffmpeg] / libavcodec / mjpegenc.c
1 /*
2  * MJPEG encoder
3  * Copyright (c) 2000, 2001 Fabrice Bellard
4  * Copyright (c) 2003 Alex Beregszaszi
5  * Copyright (c) 2003-2004 Michael Niedermayer
6  *
7  * Support for external huffman table, various fixes (AVID workaround),
8  * aspecting, new decode_frame mechanism and apple mjpeg-b support
9  *                                  by Alex Beregszaszi
10  *
11  * This file is part of Libav.
12  *
13  * Libav is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * Libav is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with Libav; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26  */
27
28 /**
29  * @file
30  * MJPEG encoder.
31  */
32
33 #include "libavutil/pixdesc.h"
34
35 #include "avcodec.h"
36 #include "jpegtables.h"
37 #include "mjpegenc_common.h"
38 #include "mpegvideo.h"
39 #include "mjpeg.h"
40 #include "mjpegenc.h"
41
42 av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
43 {
44     MJpegContext *m;
45
46     m = av_malloc(sizeof(MJpegContext));
47     if (!m)
48         return AVERROR(ENOMEM);
49
50     s->min_qcoeff=-1023;
51     s->max_qcoeff= 1023;
52
53     /* build all the huffman tables */
54     ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance,
55                                  m->huff_code_dc_luminance,
56                                  avpriv_mjpeg_bits_dc_luminance,
57                                  avpriv_mjpeg_val_dc);
58     ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance,
59                                  m->huff_code_dc_chrominance,
60                                  avpriv_mjpeg_bits_dc_chrominance,
61                                  avpriv_mjpeg_val_dc);
62     ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance,
63                                  m->huff_code_ac_luminance,
64                                  avpriv_mjpeg_bits_ac_luminance,
65                                  avpriv_mjpeg_val_ac_luminance);
66     ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance,
67                                  m->huff_code_ac_chrominance,
68                                  avpriv_mjpeg_bits_ac_chrominance,
69                                  avpriv_mjpeg_val_ac_chrominance);
70
71     s->mjpeg_ctx = m;
72     return 0;
73 }
74
75 void ff_mjpeg_encode_close(MpegEncContext *s)
76 {
77     av_free(s->mjpeg_ctx);
78 }
79
80 static void encode_block(MpegEncContext *s, int16_t *block, int n)
81 {
82     int mant, nbits, code, i, j;
83     int component, dc, run, last_index, val;
84     MJpegContext *m = s->mjpeg_ctx;
85     uint8_t *huff_size_ac;
86     uint16_t *huff_code_ac;
87
88     /* DC coef */
89     component = (n <= 3 ? 0 : (n&1) + 1);
90     dc = block[0]; /* overflow is impossible */
91     val = dc - s->last_dc[component];
92     if (n < 4) {
93         ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
94         huff_size_ac = m->huff_size_ac_luminance;
95         huff_code_ac = m->huff_code_ac_luminance;
96     } else {
97         ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
98         huff_size_ac = m->huff_size_ac_chrominance;
99         huff_code_ac = m->huff_code_ac_chrominance;
100     }
101     s->last_dc[component] = dc;
102
103     /* AC coefs */
104
105     run = 0;
106     last_index = s->block_last_index[n];
107     for(i=1;i<=last_index;i++) {
108         j = s->intra_scantable.permutated[i];
109         val = block[j];
110         if (val == 0) {
111             run++;
112         } else {
113             while (run >= 16) {
114                 put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]);
115                 run -= 16;
116             }
117             mant = val;
118             if (val < 0) {
119                 val = -val;
120                 mant--;
121             }
122
123             nbits= av_log2(val) + 1;
124             code = (run << 4) | nbits;
125
126             put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]);
127
128             put_sbits(&s->pb, nbits, mant);
129             run = 0;
130         }
131     }
132
133     /* output EOB only if not already 64 values */
134     if (last_index < 63 || run != 0)
135         put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
136 }
137
138 void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[8][64])
139 {
140     int i;
141     for(i=0;i<5;i++) {
142         encode_block(s, block[i], i);
143     }
144     if (s->chroma_format == CHROMA_420) {
145         encode_block(s, block[5], 5);
146     } else {
147         encode_block(s, block[6], 6);
148         encode_block(s, block[5], 5);
149         encode_block(s, block[7], 7);
150     }
151
152     s->i_tex_bits += get_bits_diff(s);
153 }
154
155 #define OFFSET(x) offsetof(MpegEncContext, x)
156 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
157 static const AVOption options[] = {
158 { "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 3, VE, "pred" },
159     { "left",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" },
160     { "plane",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" },
161     { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "pred" },
162
163     { NULL},
164 };
165
166 static const AVClass mjpeg_class = {
167     .class_name = "mjpeg",
168     .item_name  = av_default_item_name,
169     .option     = options,
170     .version    = LIBAVUTIL_VERSION_INT,
171 };
172
173 AVCodec ff_mjpeg_encoder = {
174     .name           = "mjpeg",
175     .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
176     .type           = AVMEDIA_TYPE_VIDEO,
177     .id             = AV_CODEC_ID_MJPEG,
178     .priv_data_size = sizeof(MpegEncContext),
179     .priv_class     = &mjpeg_class,
180     .init           = ff_mpv_encode_init,
181     .encode2        = ff_mpv_encode_picture,
182     .close          = ff_mpv_encode_end,
183     .pix_fmts       = (const enum AVPixelFormat[]){
184         AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_NONE
185     },
186 };