~ppsspp/ppsspp/ffmpeg-upstream

1 by Sérgio Benjamim
FFmpeg 2.7.1 source for ppsspp.
1
/*
2
 * lossless JPEG 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 FFmpeg.
12
 *
13
 * FFmpeg 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
 * FFmpeg 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 FFmpeg; 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
 * lossless JPEG encoder.
31
 */
32
33
#include "libavutil/frame.h"
34
#include "libavutil/mem.h"
35
#include "libavutil/pixdesc.h"
36
37
#include "avcodec.h"
38
#include "idctdsp.h"
39
#include "internal.h"
40
#include "jpegtables.h"
41
#include "mjpegenc_common.h"
42
#include "mpegvideo.h"
43
#include "mjpeg.h"
44
#include "mjpegenc.h"
45
46
typedef struct LJpegEncContext {
47
    IDCTDSPContext idsp;
48
    ScanTable scantable;
49
    uint16_t matrix[64];
50
51
    int vsample[3];
52
    int hsample[3];
53
54
    uint16_t huff_code_dc_luminance[12];
55
    uint16_t huff_code_dc_chrominance[12];
56
    uint8_t  huff_size_dc_luminance[12];
57
    uint8_t  huff_size_dc_chrominance[12];
58
59
    uint16_t (*scratch)[4];
60
} LJpegEncContext;
61
62
static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
63
                            const AVFrame *frame)
64
{
65
    LJpegEncContext *s    = avctx->priv_data;
66
    const int width       = frame->width;
67
    const int height      = frame->height;
68
    const int linesize    = frame->linesize[0];
69
    uint16_t (*buffer)[4] = s->scratch;
70
    const int predictor   = avctx->prediction_method+1;
71
    int left[3], top[3], topleft[3];
72
    int x, y, i;
73
74
    for (i = 0; i < 3; i++)
75
        buffer[0][i] = 1 << (9 - 1);
76
77
    for (y = 0; y < height; y++) {
78
        const int modified_predictor = y ? predictor : 1;
79
        uint8_t *ptr = frame->data[0] + (linesize * y);
80
81
        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 3 * 4) {
82
            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
83
            return -1;
84
        }
85
86
        for (i = 0; i < 3; i++)
87
            top[i]= left[i]= topleft[i]= buffer[0][i];
88
89
        for (x = 0; x < width; x++) {
90
            if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
91
                buffer[x][1] =  ptr[3 * x + 0] -     ptr[3 * x + 1] + 0x100;
92
                buffer[x][2] =  ptr[3 * x + 2] -     ptr[3 * x + 1] + 0x100;
93
                buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2;
94
            }else{
95
                buffer[x][1] =  ptr[4 * x + 0] -     ptr[4 * x + 1] + 0x100;
96
                buffer[x][2] =  ptr[4 * x + 2] -     ptr[4 * x + 1] + 0x100;
97
                buffer[x][0] = (ptr[4 * x + 0] + 2 * ptr[4 * x + 1] + ptr[4 * x + 2]) >> 2;
98
            }
99
100
            for (i = 0; i < 3; i++) {
101
                int pred, diff;
102
103
                PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
104
105
                topleft[i] = top[i];
106
                top[i]     = buffer[x+1][i];
107
108
                left[i]    = buffer[x][i];
109
110
                diff       = ((left[i] - pred + 0x100) & 0x1FF) - 0x100;
111
112
                if (i == 0)
113
                    ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
114
                else
115
                    ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
116
            }
117
        }
118
    }
119
120
    return 0;
121
}
122
123
static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb,
124
                                       const AVFrame *frame, int predictor,
125
                                       int mb_x, int mb_y)
126
{
127
    int i;
128
129
    if (mb_x == 0 || mb_y == 0) {
130
        for (i = 0; i < 3; i++) {
131
            uint8_t *ptr;
132
            int x, y, h, v, linesize;
133
            h = s->hsample[i];
134
            v = s->vsample[i];
135
            linesize = frame->linesize[i];
136
137
            for (y = 0; y < v; y++) {
138
                for (x = 0; x < h; x++) {
139
                    int pred;
140
141
                    ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
142
                    if (y == 0 && mb_y == 0) {
143
                        if (x == 0 && mb_x == 0)
144
                            pred = 128;
145
                        else
146
                            pred = ptr[-1];
147
                    } else {
148
                        if (x == 0 && mb_x == 0) {
149
                            pred = ptr[-linesize];
150
                        } else {
151
                            PREDICT(pred, ptr[-linesize - 1], ptr[-linesize],
152
                                    ptr[-1], predictor);
153
                        }
154
                    }
155
156
                    if (i == 0)
157
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
158
                    else
159
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
160
                }
161
            }
162
        }
163
    } else {
164
        for (i = 0; i < 3; i++) {
165
            uint8_t *ptr;
166
            int x, y, h, v, linesize;
167
            h = s->hsample[i];
168
            v = s->vsample[i];
169
            linesize = frame->linesize[i];
170
171
            for (y = 0; y < v; y++) {
172
                for (x = 0; x < h; x++) {
173
                    int pred;
174
175
                    ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
176
                    PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor);
177
178
                    if (i == 0)
179
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
180
                    else
181
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
182
                }
183
            }
184
        }
185
    }
186
}
187
188
static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb,
189
                            const AVFrame *frame)
190
{
191
    const int predictor = avctx->prediction_method + 1;
192
    LJpegEncContext *s  = avctx->priv_data;
193
    const int mb_width  = (avctx->width  + s->hsample[0] - 1) / s->hsample[0];
194
    const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0];
195
    int mb_x, mb_y;
196
197
    for (mb_y = 0; mb_y < mb_height; mb_y++) {
198
        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) <
199
            mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) {
200
            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
201
            return -1;
202
        }
203
204
        for (mb_x = 0; mb_x < mb_width; mb_x++)
205
            ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y);
206
    }
207
208
    return 0;
209
}
210
211
static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
212
                              const AVFrame *pict, int *got_packet)
213
{
214
    LJpegEncContext *s = avctx->priv_data;
215
    PutBitContext pb;
216
    const int width  = avctx->width;
217
    const int height = avctx->height;
218
    const int mb_width  = (width  + s->hsample[0] - 1) / s->hsample[0];
219
    const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0];
220
    int max_pkt_size = FF_MIN_BUFFER_SIZE;
221
    int ret, header_bits;
222
223
    if(    avctx->pix_fmt == AV_PIX_FMT_BGR0
224
        || avctx->pix_fmt == AV_PIX_FMT_BGRA
225
        || avctx->pix_fmt == AV_PIX_FMT_BGR24)
226
        max_pkt_size += width * height * 3 * 4;
227
    else {
228
        max_pkt_size += mb_width * mb_height * 3 * 4
229
                        * s->hsample[0] * s->vsample[0];
230
    }
231
232
    if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0)
233
        return ret;
234
235
    init_put_bits(&pb, pkt->data, pkt->size);
236
237
    ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,
238
                                   s->matrix, s->matrix);
239
240
    header_bits = put_bits_count(&pb);
241
242
    if(    avctx->pix_fmt == AV_PIX_FMT_BGR0
243
        || avctx->pix_fmt == AV_PIX_FMT_BGRA
244
        || avctx->pix_fmt == AV_PIX_FMT_BGR24)
245
        ret = ljpeg_encode_bgr(avctx, &pb, pict);
246
    else
247
        ret = ljpeg_encode_yuv(avctx, &pb, pict);
248
    if (ret < 0)
249
        return ret;
250
251
    emms_c();
252
253
    ff_mjpeg_escape_FF(&pb, header_bits >> 3);
254
    ff_mjpeg_encode_picture_trailer(&pb, header_bits);
255
256
    flush_put_bits(&pb);
257
    pkt->size   = put_bits_ptr(&pb) - pb.buf;
258
    pkt->flags |= AV_PKT_FLAG_KEY;
259
    *got_packet = 1;
260
261
    return 0;
262
}
263
264
static av_cold int ljpeg_encode_close(AVCodecContext *avctx)
265
{
266
    LJpegEncContext *s = avctx->priv_data;
267
268
    av_frame_free(&avctx->coded_frame);
269
    av_freep(&s->scratch);
270
271
    return 0;
272
}
273
274
static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
275
{
276
    LJpegEncContext *s = avctx->priv_data;
277
278
    if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
279
         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
280
         avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
281
         avctx->color_range == AVCOL_RANGE_MPEG) &&
282
        avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
283
        av_log(avctx, AV_LOG_ERROR,
284
               "Limited range YUV is non-standard, set strict_std_compliance to "
285
               "at least unofficial to use it.\n");
286
        return AVERROR(EINVAL);
287
    }
288
289
    avctx->coded_frame = av_frame_alloc();
290
    if (!avctx->coded_frame)
291
        return AVERROR(ENOMEM);
292
293
    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
294
    avctx->coded_frame->key_frame = 1;
295
296
    s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));
297
    if (!s->scratch)
298
        goto fail;
299
300
    ff_idctdsp_init(&s->idsp, avctx);
301
    ff_init_scantable(s->idsp.idct_permutation, &s->scantable,
302
                      ff_zigzag_direct);
303
304
    ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample);
305
306
    ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,
307
                                 s->huff_code_dc_luminance,
308
                                 avpriv_mjpeg_bits_dc_luminance,
309
                                 avpriv_mjpeg_val_dc);
310
    ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,
311
                                 s->huff_code_dc_chrominance,
312
                                 avpriv_mjpeg_bits_dc_chrominance,
313
                                 avpriv_mjpeg_val_dc);
314
315
    return 0;
316
fail:
317
    ljpeg_encode_close(avctx);
318
    return AVERROR(ENOMEM);
319
}
320
321
AVCodec ff_ljpeg_encoder = {
322
    .name           = "ljpeg",
323
    .long_name      = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
324
    .type           = AVMEDIA_TYPE_VIDEO,
325
    .id             = AV_CODEC_ID_LJPEG,
326
    .priv_data_size = sizeof(LJpegEncContext),
327
    .init           = ljpeg_encode_init,
328
    .encode2        = ljpeg_encode_frame,
329
    .close          = ljpeg_encode_close,
330
    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
331
    .pix_fmts       = (const enum AVPixelFormat[]){
332
        AV_PIX_FMT_BGR24   , AV_PIX_FMT_BGRA    , AV_PIX_FMT_BGR0,
333
        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
334
        AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
335
        AV_PIX_FMT_NONE},
336
};