~ubuntu-dev/mplayer/upstream-ubuntu

« back to all changes in this revision

Viewing changes to libmpcodecs/vf_zrmjpeg.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2005 Rik Snel <rsnel@cube.dyndns.org>, license GPL v2
 
3
 * - based on vd_lavc.c by A'rpi (C) 2002-2003 
 
4
 * - parts from ffmpeg Copyright (c) 2000-2003 Fabrice Bellard
 
5
 *
 
6
 * This files includes a straightforward (to be) optimized JPEG encoder for
 
7
 * the YUV422 format, based on mjpeg code from ffmpeg.
 
8
 *
 
9
 * For an excellent introduction to the JPEG format, see:
 
10
 * http://www.ece.purdue.edu/~bouman/grad-labs/lab8/pdf/lab.pdf
 
11
 */
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <string.h>
 
15
#include <inttypes.h>
 
16
 
 
17
#include "config.h"
 
18
#include "mp_msg.h"
 
19
 
 
20
#include "img_format.h"
 
21
#include "mp_image.h"
 
22
#include "vf.h"
 
23
 
 
24
#ifdef USE_FASTMEMCPY
 
25
#include "libvo/fastmemcpy.h"
 
26
#endif
 
27
 
 
28
/* We need this #define because we need ../libavcodec/common.h to #define 
 
29
 * be2me_32, otherwise the linker will complain that it doesn't exist */
 
30
#define HAVE_AV_CONFIG_H
 
31
#include "libavcodec/avcodec.h"
 
32
#include "libavcodec/dsputil.h"
 
33
#include "libavcodec/mpegvideo.h"
 
34
 
 
35
#undef malloc
 
36
#undef free
 
37
#undef realloc
 
38
 
 
39
 
 
40
/* some convenient #define's, is this portable enough? */
 
41
#define VERBOSE(...) mp_msg(MSGT_DECVIDEO, MSGL_V, "vf_zrmjpeg: " __VA_ARGS__)
 
42
#define ERROR(...) mp_msg(MSGT_DECVIDEO, MSGL_ERR, "vf_zrmjpeg: " __VA_ARGS__)
 
43
#define WARNING(...) mp_msg(MSGT_DECVIDEO, MSGL_WARN, \
 
44
                "vf_zrmjpeg: " __VA_ARGS__)
 
45
 
 
46
 
 
47
extern int avcodec_inited;
 
48
 
 
49
/* zrmjpeg_encode_mb needs access to these tables for the black & white 
 
50
 * option */
 
51
typedef struct MJpegContext {
 
52
        uint8_t huff_size_dc_luminance[12];
 
53
        uint16_t huff_code_dc_luminance[12];
 
54
        uint8_t huff_size_dc_chrominance[12];
 
55
        uint16_t huff_code_dc_chrominance[12];
 
56
 
 
57
        uint8_t huff_size_ac_luminance[256];
 
58
        uint16_t huff_code_ac_luminance[256];
 
59
        uint8_t huff_size_ac_chrominance[256];
 
60
        uint16_t huff_code_ac_chrominance[256];
 
61
} MJpegContext;
 
62
 
 
63
/* Begin excessive code duplication ************************************/
 
64
/* Code coming from mpegvideo.c and mjpeg.c in ../libavcodec ***********/
 
65
 
 
66
static const unsigned short aanscales[64] = {
 
67
        /* precomputed values scaled up by 14 bits */
 
68
        16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 
69
        22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
 
70
        21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
 
71
        19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
 
72
        16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 
73
        12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
 
74
        8867,  12299, 11585, 10426,  8867,  6967,  4799,  2446,
 
75
        4520,   6270,  5906,  5315,  4520,  3552,  2446,  1247
 
76
};
 
77
 
 
78
static void convert_matrix(MpegEncContext *s, int (*qmat)[64], 
 
79
                uint16_t (*qmat16)[2][64], const uint16_t *quant_matrix,
 
80
                int bias, int qmin, int qmax) {
 
81
        int qscale; 
 
82
 
 
83
        for(qscale = qmin; qscale <= qmax; qscale++) {
 
84
                int i;
 
85
                if (s->dsp.fdct == ff_jpeg_fdct_islow) {
 
86
                        for (i = 0; i < 64; i++) {
 
87
                                const int j = s->dsp.idct_permutation[i];
 
88
/* 16 <= qscale * quant_matrix[i] <= 7905 
 
89
 * 19952         <= aanscales[i] * qscale * quant_matrix[i]      <= 249205026 
 
90
 * (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) 
 
91
 *                                                       >= (1<<36)/249205026
 
92
 * 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i])  >= 275 */
 
93
                                qmat[qscale][i] = (int)((UINT64_C(1) << 
 
94
                                        (QMAT_SHIFT-3))/
 
95
                                        (qscale*quant_matrix[j]));
 
96
                        }
 
97
                } else if (s->dsp.fdct == fdct_ifast) {
 
98
                        for (i = 0; i < 64; i++) {
 
99
                                const int j = s->dsp.idct_permutation[i];
 
100
/* 16 <= qscale * quant_matrix[i] <= 7905 
 
101
 * 19952         <= aanscales[i] * qscale * quant_matrix[i]      <= 249205026 
 
102
 * (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) 
 
103
 *                                                       >= (1<<36)/249205026
 
104
 * 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i])  >= 275 */
 
105
                                qmat[qscale][i] = (int)((UINT64_C(1) << 
 
106
                                        (QMAT_SHIFT + 11))/(aanscales[i]
 
107
                                        *qscale * quant_matrix[j]));
 
108
                        }
 
109
                } else {
 
110
                        for (i = 0; i < 64; i++) {
 
111
                                const int j = s->dsp.idct_permutation[i];
 
112
/* We can safely assume that 16 <= quant_matrix[i] <= 255
 
113
 * So 16           <= qscale * quant_matrix[i]             <= 7905
 
114
 * so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905
 
115
 * so 32768        >= (1<<19) / (qscale * quant_matrix[i]) >= 67 */
 
116
                                qmat[qscale][i] = (int)((uint64_t_C(1) << 
 
117
                                                QMAT_SHIFT_MMX) / (qscale 
 
118
                                                        *quant_matrix[j]));
 
119
                                qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX)
 
120
                                                /(qscale * quant_matrix[j]);
 
121
 
 
122
                                if (qmat16[qscale][0][i] == 0 || 
 
123
                                                qmat16[qscale][0][i] == 128*256)
 
124
                                        qmat16[qscale][0][i]=128*256-1;
 
125
                                qmat16[qscale][1][i]=ROUNDED_DIV(bias
 
126
                                                <<(16-QUANT_BIAS_SHIFT), 
 
127
                                                qmat16[qscale][0][i]);
 
128
                        }
 
129
                }
 
130
        }
 
131
}
 
132
 
 
133
static inline void encode_dc(MpegEncContext *s, int val, 
 
134
                uint8_t *huff_size, uint16_t *huff_code) {
 
135
        int mant, nbits;
 
136
 
 
137
        if (val == 0) {
 
138
                put_bits(&s->pb, huff_size[0], huff_code[0]);
 
139
        } else {
 
140
                mant = val;
 
141
                if (val < 0) {
 
142
                        val = -val;
 
143
                        mant--;
 
144
                }
 
145
        
 
146
                /* compute the log (XXX: optimize) */
 
147
                nbits = 0;
 
148
                while (val != 0) {
 
149
                        val = val >> 1;
 
150
                        nbits++;
 
151
                }
 
152
            
 
153
                put_bits(&s->pb, huff_size[nbits], huff_code[nbits]);
 
154
                put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
 
155
        }
 
156
}
 
157
 
 
158
static void encode_block(MpegEncContext *s, DCTELEM *block, int n) {
 
159
        int mant, nbits, code, i, j;
 
160
        int component, dc, run, last_index, val;
 
161
        MJpegContext *m = s->mjpeg_ctx;
 
162
        uint8_t *huff_size_ac;
 
163
        uint16_t *huff_code_ac;
 
164
    
 
165
        /* DC coef */
 
166
        component = (n <= 3 ? 0 : n - 4 + 1);
 
167
        dc = block[0]; /* overflow is impossible */
 
168
        val = dc - s->last_dc[component];
 
169
        if (n < 4) {
 
170
                encode_dc(s, val, m->huff_size_dc_luminance, 
 
171
                                m->huff_code_dc_luminance);
 
172
                huff_size_ac = m->huff_size_ac_luminance;
 
173
                huff_code_ac = m->huff_code_ac_luminance;
 
174
        } else {
 
175
                encode_dc(s, val, m->huff_size_dc_chrominance, 
 
176
                                m->huff_code_dc_chrominance);
 
177
                huff_size_ac = m->huff_size_ac_chrominance;
 
178
                huff_code_ac = m->huff_code_ac_chrominance;
 
179
        }
 
180
        s->last_dc[component] = dc;
 
181
    
 
182
        /* AC coefs */
 
183
    
 
184
        run = 0;
 
185
        last_index = s->block_last_index[n];
 
186
        for (i = 1; i <= last_index; i++) {
 
187
                j = s->intra_scantable.permutated[i];
 
188
                val = block[j];
 
189
                if (val == 0) run++;
 
190
                else {
 
191
                        while (run >= 16) {
 
192
                                put_bits(&s->pb, huff_size_ac[0xf0], 
 
193
                                                huff_code_ac[0xf0]);
 
194
                                run -= 16;
 
195
                        }
 
196
                        mant = val;
 
197
                        if (val < 0) {
 
198
                                val = -val;
 
199
                                mant--;
 
200
                        }
 
201
            
 
202
                        /* compute the log (XXX: optimize) */
 
203
                        nbits = 0;
 
204
                        while (val != 0) {
 
205
                                val = val >> 1;
 
206
                                nbits++; 
 
207
                        }
 
208
                        code = (run << 4) | nbits;
 
209
 
 
210
                        put_bits(&s->pb, huff_size_ac[code], 
 
211
                                        huff_code_ac[code]);
 
212
                        put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
 
213
                        run = 0;
 
214
                }
 
215
        }
 
216
 
 
217
        /* output EOB only if not already 64 values */ 
 
218
        if (last_index < 63 || run != 0)
 
219
                put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
 
220
}
 
221
 
 
222
static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, 
 
223
                int last_index) {
 
224
        int i;
 
225
        const int maxlevel= s->max_qcoeff;
 
226
        const int minlevel= s->min_qcoeff;
 
227
 
 
228
        for (i = 0; i <= last_index; i++) {
 
229
                const int j = s->intra_scantable.permutated[i];
 
230
                int level = block[j];
 
231
       
 
232
                if (level > maxlevel) level=maxlevel;
 
233
                else if(level < minlevel) level=minlevel;
 
234
                block[j]= level;
 
235
        }
 
236
}
 
237
 
 
238
/* End excessive code duplication **************************************/
 
239
 
 
240
typedef struct {
 
241
        struct MpegEncContext *s;
 
242
        int cheap_upsample;
 
243
        int bw;
 
244
        int y_ps;
 
245
        int u_ps;
 
246
        int v_ps;
 
247
        int y_rs;
 
248
        int u_rs;
 
249
        int v_rs;
 
250
} jpeg_enc_t;
 
251
 
 
252
/* this function is a reproduction of the one in mjpeg, it includes two
 
253
 * changes, it allows for black&white encoding (it skips the U and V
 
254
 * macroblocks and it outputs the huffman code for 'no change' (dc) and
 
255
 * 'all zero' (ac)) and it takes 4 macroblocks (422) instead of 6 (420) */
 
256
static void zr_mjpeg_encode_mb(jpeg_enc_t *j) {
 
257
 
 
258
        MJpegContext *m = j->s->mjpeg_ctx;
 
259
 
 
260
        encode_block(j->s, j->s->block[0], 0);
 
261
        encode_block(j->s, j->s->block[1], 1);
 
262
        if (j->bw) {
 
263
                /* U */
 
264
                put_bits(&j->s->pb, m->huff_size_dc_chrominance[0],
 
265
                                m->huff_code_dc_chrominance[0]);
 
266
                put_bits(&j->s->pb, m->huff_size_ac_chrominance[0],
 
267
                                m->huff_code_ac_chrominance[0]);
 
268
                /* V */
 
269
                put_bits(&j->s->pb, m->huff_size_dc_chrominance[0],
 
270
                                m->huff_code_dc_chrominance[0]);
 
271
                put_bits(&j->s->pb, m->huff_size_ac_chrominance[0],
 
272
                                m->huff_code_ac_chrominance[0]);
 
273
        } else {
 
274
                /* we trick encode_block here so that it uses
 
275
                 * chrominance huffman tables instead of luminance ones 
 
276
                 * (see the effect of second argument of encode_block) */
 
277
                encode_block(j->s, j->s->block[2], 4); 
 
278
                encode_block(j->s, j->s->block[3], 5);
 
279
        }
 
280
}
 
281
 
 
282
/* this function can take all kinds of YUV colorspaces
 
283
 * YV12, YVYU, UYVY. The necesary parameters must be set up by the caller
 
284
 * y_ps means "y pixel size", y_rs means "y row size".
 
285
 * For YUYV, for example, is u_buf = y_buf + 1, v_buf = y_buf + 3, 
 
286
 * y_ps = 2, u_ps = 4, v_ps = 4, y_rs = u_rs = v_rs.
 
287
 *
 
288
 *  The actual buffers must be passed with mjpeg_encode_frame, this is
 
289
 *  to make it possible to call encode on the buffer provided by the
 
290
 *  codec in draw_frame.
 
291
 *  
 
292
 * The data is straightened out at the moment it is put in DCT
 
293
 * blocks, there are therefore no spurious memcopies involved */
 
294
/* Notice that w must be a multiple of 16 and h must be a multiple of 8 */
 
295
/* We produce YUV422 jpegs, the colors must be subsampled horizontally,
 
296
 * if the colors are also subsampled vertically, then this function
 
297
 * performs cheap upsampling (better solution will be: a DCT that is
 
298
 * optimized in the case that every two rows are the same) */
 
299
/* cu = 0 means 'No cheap upsampling'
 
300
 * cu = 1 means 'perform cheap upsampling' */
 
301
/* The encoder doesn't know anything about interlacing, the halve height
 
302
 * needs to be passed and the double rowstride. Which field gets encoded
 
303
 * is decided by what buffers are passed to mjpeg_encode_frame */
 
304
static jpeg_enc_t *jpeg_enc_init(int w, int h, int y_psize, int y_rsize, 
 
305
                int u_psize, int u_rsize, int v_psize, int v_rsize,
 
306
                int cu, int q, int b) {
 
307
        jpeg_enc_t *j;
 
308
        int i = 0;
 
309
        VERBOSE("JPEG encoder init: %dx%d %d %d %d %d %d %d\n",
 
310
                        w, h, y_psize, y_rsize, u_psize, 
 
311
                        u_rsize, v_psize, v_rsize);
 
312
 
 
313
        j = malloc(sizeof(jpeg_enc_t));
 
314
        if (j == NULL) return NULL;
 
315
 
 
316
        j->s = malloc(sizeof(MpegEncContext));
 
317
        memset(j->s,0x00,sizeof(MpegEncContext));
 
318
        if (j->s == NULL) {
 
319
                free(j);
 
320
                return NULL;
 
321
        }
 
322
 
 
323
        /* info on how to access the pixels */
 
324
        j->y_ps = y_psize; 
 
325
        j->u_ps = u_psize; 
 
326
        j->v_ps = v_psize;
 
327
        j->y_rs = y_rsize; 
 
328
        j->u_rs = u_rsize; 
 
329
        j->v_rs = v_rsize;
 
330
 
 
331
        j->s->width = w;
 
332
        j->s->height = h;
 
333
        j->s->qscale = q;
 
334
 
 
335
        j->s->mjpeg_data_only_frames = 0;
 
336
        j->s->out_format = FMT_MJPEG;
 
337
        j->s->intra_only = 1;
 
338
        j->s->encoding = 1;
 
339
        j->s->pict_type = I_TYPE;
 
340
        j->s->y_dc_scale = 8;
 
341
        j->s->c_dc_scale = 8;
 
342
 
 
343
        j->s->mjpeg_write_tables = 1;
 
344
        j->s->mjpeg_vsample[0] = 1;
 
345
        j->s->mjpeg_vsample[1] = 1;
 
346
        j->s->mjpeg_vsample[2] = 1;
 
347
        j->s->mjpeg_hsample[0] = 2;
 
348
        j->s->mjpeg_hsample[1] = 1;
 
349
        j->s->mjpeg_hsample[2] = 1;
 
350
 
 
351
        j->cheap_upsample = cu;
 
352
        j->bw = b;
 
353
 
 
354
        if (mjpeg_init(j->s) < 0) {
 
355
                free(j->s);
 
356
                free(j);
 
357
                return NULL;
 
358
        }
 
359
 
 
360
        /* alloc bogus avctx to keep MPV_common_init from segfaulting */
 
361
        j->s->avctx = calloc(sizeof(*j->s->avctx), 1);
 
362
 
 
363
        /* make MPV_common_init allocate important buffers, like s->block */
 
364
        j->s->avctx->thread_count = 1;
 
365
 
 
366
        if (MPV_common_init(j->s) < 0) {
 
367
                free(j->s);
 
368
                free(j);
 
369
                return NULL;
 
370
        }
 
371
 
 
372
        /* correct the value for sc->mb_height */
 
373
        j->s->mb_height = j->s->height/8;
 
374
        j->s->mb_intra = 1;
 
375
 
 
376
        j->s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];
 
377
        for (i = 1; i < 64; i++) 
 
378
                j->s->intra_matrix[i] = clip_uint8(
 
379
                        (ff_mpeg1_default_intra_matrix[i]*j->s->qscale) >> 3);
 
380
        convert_matrix(j->s, j->s->q_intra_matrix, j->s->q_intra_matrix16, 
 
381
                        j->s->intra_matrix, j->s->intra_quant_bias, 8, 8);
 
382
        return j;
 
383
}       
 
384
 
 
385
static int jpeg_enc_frame(jpeg_enc_t *j, unsigned char *y_data, 
 
386
                unsigned char *u_data, unsigned char *v_data, char *bufr) {
 
387
        int i, k, mb_x, mb_y, overflow;
 
388
        short int *dest;
 
389
        unsigned char *source;
 
390
        /* initialize the buffer */
 
391
 
 
392
        init_put_bits(&j->s->pb, bufr, 1024*256);
 
393
 
 
394
        mjpeg_picture_header(j->s);
 
395
 
 
396
        j->s->header_bits = put_bits_count(&j->s->pb);
 
397
 
 
398
        j->s->last_dc[0] = 128; 
 
399
        j->s->last_dc[1] = 128; 
 
400
        j->s->last_dc[2] = 128;
 
401
 
 
402
        for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) {
 
403
                for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) {
 
404
                        /* conversion 8 to 16 bit and filling of blocks
 
405
                         * must be mmx optimized */
 
406
                        /* fill 2 Y macroblocks and one U and one V */
 
407
                        source = mb_y * 8 * j->y_rs + 
 
408
                                16 * j->y_ps * mb_x + y_data;
 
409
                        dest = j->s->block[0];
 
410
                        for (i = 0; i < 8; i++) {
 
411
                                for (k = 0; k < 8; k++) {
 
412
                                        dest[k] = source[k*j->y_ps];
 
413
                                }
 
414
                                dest += 8;
 
415
                                source += j->y_rs;
 
416
                        }
 
417
                        source = mb_y * 8 * j->y_rs + 
 
418
                                (16*mb_x + 8)*j->y_ps + y_data;
 
419
                        dest = j->s->block[1];
 
420
                        for (i = 0; i < 8; i++) {
 
421
                                for (k = 0; k < 8; k++) {
 
422
                                        dest[k] = source[k*j->y_ps];
 
423
                                }
 
424
                                dest += 8;
 
425
                                source += j->y_rs;
 
426
                        }
 
427
                        if (!j->bw && j->cheap_upsample) {
 
428
                                source = mb_y*4*j->u_rs + 
 
429
                                        8*mb_x*j->u_ps + u_data;
 
430
                                dest = j->s->block[2];
 
431
                                for (i = 0; i < 4; i++) {
 
432
                                        for (k = 0; k < 8; k++) {
 
433
                                                dest[k] = source[k*j->u_ps];
 
434
                                                dest[k+8] = source[k*j->u_ps];
 
435
                                        }
 
436
                                        dest += 16;
 
437
                                        source += j->u_rs;
 
438
                                }
 
439
                                source = mb_y*4*j->v_rs + 
 
440
                                        8*mb_x*j->v_ps + v_data;
 
441
                                dest = j->s->block[3];
 
442
                                for (i = 0; i < 4; i++) {
 
443
                                        for (k = 0; k < 8; k++) {
 
444
                                                dest[k] = source[k*j->v_ps];
 
445
                                                dest[k+8] = source[k*j->v_ps];
 
446
                                        }
 
447
                                        dest += 16;
 
448
                                        source += j->u_rs;
 
449
                                }
 
450
                        } else if (!j->bw && !j->cheap_upsample) {
 
451
                                source = mb_y*8*j->u_rs + 
 
452
                                        8*mb_x*j->u_ps + u_data;
 
453
                                dest = j->s->block[2];
 
454
                                for (i = 0; i < 8; i++) {
 
455
                                        for (k = 0; k < 8; k++) 
 
456
                                                dest[k] = source[k*j->u_ps];
 
457
                                        dest += 8;
 
458
                                        source += j->u_rs;
 
459
                                }
 
460
                                source = mb_y*8*j->v_rs + 
 
461
                                        8*mb_x*j->v_ps + v_data;
 
462
                                dest = j->s->block[3];
 
463
                                for (i = 0; i < 8; i++) {
 
464
                                        for (k = 0; k < 8; k++) 
 
465
                                                dest[k] = source[k*j->v_ps];
 
466
                                        dest += 8;
 
467
                                        source += j->u_rs;
 
468
                                }
 
469
                        }
 
470
                        emms_c(); /* is this really needed? */
 
471
 
 
472
                        j->s->block_last_index[0] = 
 
473
                                j->s->dct_quantize(j->s, j->s->block[0], 
 
474
                                                0, 8, &overflow);
 
475
                        if (overflow) clip_coeffs(j->s, j->s->block[0], 
 
476
                                        j->s->block_last_index[0]);
 
477
                        j->s->block_last_index[1] = 
 
478
                                j->s->dct_quantize(j->s, j->s->block[1], 
 
479
                                                1, 8, &overflow);
 
480
                        if (overflow) clip_coeffs(j->s, j->s->block[1], 
 
481
                                        j->s->block_last_index[1]);
 
482
 
 
483
                        if (!j->bw) {
 
484
                                j->s->block_last_index[4] =
 
485
                                        j->s->dct_quantize(j->s, j->s->block[2],
 
486
                                                        4, 8, &overflow);
 
487
                                if (overflow) clip_coeffs(j->s, j->s->block[2], 
 
488
                                                j->s->block_last_index[2]);
 
489
                                j->s->block_last_index[5] =
 
490
                                        j->s->dct_quantize(j->s, j->s->block[3],
 
491
                                                        5, 8, &overflow);
 
492
                                if (overflow) clip_coeffs(j->s, j->s->block[3], 
 
493
                                                j->s->block_last_index[3]);
 
494
                        }
 
495
                        zr_mjpeg_encode_mb(j);
 
496
                }
 
497
        }
 
498
        emms_c();
 
499
        mjpeg_picture_trailer(j->s);
 
500
        flush_put_bits(&j->s->pb);      
 
501
 
 
502
        if (j->s->mjpeg_write_tables == 1)
 
503
                j->s->mjpeg_write_tables = 0;
 
504
        
 
505
        return pbBufPtr(&(j->s->pb)) - j->s->pb.buf;
 
506
}
 
507
 
 
508
static void jpeg_enc_uninit(jpeg_enc_t *j) {
 
509
        mjpeg_close(j->s);
 
510
        free(j->s);
 
511
        free(j);
 
512
}
 
513
 
 
514
struct vf_priv_s {
 
515
        jpeg_enc_t *j;
 
516
        unsigned char buf[256*1024];
 
517
        int bw, fd, hdec, vdec;
 
518
        int fields;
 
519
        int y_stride;
 
520
        int c_stride;
 
521
        int quality;
 
522
        int maxwidth;
 
523
        int maxheight;
 
524
};
 
525
 
 
526
static int config(struct vf_instance_s* vf, int width, int height, int d_width,
 
527
                int d_height, unsigned int flags, unsigned int outfmt){
 
528
        struct vf_priv_s *priv = vf->priv;
 
529
        float aspect_decision;
 
530
        int stretchx, stretchy, err = 0, maxstretchx = 4;
 
531
        priv->fields = 1;
 
532
 
 
533
        VERBOSE("config() called\n");
 
534
 
 
535
        if (priv->j) {
 
536
                VERBOSE("re-configuring, resetting JPEG encoder\n");
 
537
                jpeg_enc_uninit(priv->j);
 
538
                priv->j = NULL;
 
539
        }
 
540
        
 
541
        aspect_decision = ((float)d_width/(float)d_height)/
 
542
                ((float)width/(float)height);
 
543
        
 
544
        if (aspect_decision > 1.8 && aspect_decision < 2.2) {
 
545
                VERBOSE("should correct aspect by stretching x times 2, %d %d\n", 2*width, priv->maxwidth);
 
546
                if (2*width <= priv->maxwidth) {
 
547
                        d_width = 2*width;
 
548
                        d_height = height;
 
549
                        maxstretchx = 2;
 
550
                } else {
 
551
                        WARNING("unable to correct aspect by stretching, because resulting X will be too large, aspect correction by decimating y not yet implemented\n");
 
552
                        d_width = width;
 
553
                        d_height = height;
 
554
                }
 
555
                /* prestretch movie */
 
556
        } else {
 
557
                /* uncorrecting output for now */
 
558
                d_width = width;
 
559
                d_height = height;
 
560
        }
 
561
        /* make the scaling decision
 
562
         * we are capable of stretching the image in the horizontal
 
563
         * direction by factors 1, 2 and 4
 
564
         * we can stretch the image in the vertical direction by a 
 
565
         * factor of 1 and 2 AND we must decide about interlacing */
 
566
        if (d_width > priv->maxwidth/2 || height > priv->maxheight/2 
 
567
                        || maxstretchx == 1) {
 
568
                stretchx = 1;
 
569
                stretchy = 1;
 
570
                priv->fields = 2;
 
571
                if (priv->vdec == 2) {
 
572
                        priv->fields = 1;
 
573
                } else if (priv->vdec == 4) {
 
574
                        priv->fields = 1;
 
575
                        stretchy = 2;
 
576
                }
 
577
                if (priv->hdec > maxstretchx) {
 
578
                        if (priv->fd) {
 
579
                                WARNING("horizontal decimation too high, changing to %d (use fd to keep hdec=%d)\n", maxstretchx, priv->hdec);
 
580
                                priv->hdec = maxstretchx;
 
581
                        }
 
582
                }
 
583
                stretchx = priv->hdec;
 
584
        } else if (d_width > priv->maxwidth/4 ||
 
585
                        height > priv->maxheight/4 ||
 
586
                        maxstretchx == 2) {
 
587
                stretchx = 2;
 
588
                stretchy = 1;
 
589
                priv->fields = 1;
 
590
                if (priv->vdec == 2) {
 
591
                        stretchy = 2;
 
592
                } else if (priv->vdec == 4) {
 
593
                        if (!priv->fd) {
 
594
                                WARNING("vertical decimation too high, changing to 2 (use fd to keep vdec=4)\n");
 
595
                                priv->vdec = 2;
 
596
                        }
 
597
                        stretchy = 2;
 
598
                }
 
599
                if (priv->hdec == 2) {
 
600
                        stretchx = 4;
 
601
                } else if (priv->hdec == 4) {
 
602
                        if (priv->fd) {
 
603
                                WARNING("horizontal decimation too high, changing to 2 (use fd to keep hdec=4)\n");
 
604
                                priv->hdec = 2;
 
605
                        }
 
606
                        stretchx = 4;
 
607
                }
 
608
        } else {
 
609
                /* output image is maximally stretched */
 
610
                stretchx = 4;
 
611
                stretchy = 2;
 
612
                priv->fields = 1;
 
613
                if (priv->vdec != 1 && !priv->fd) {
 
614
                        WARNING("vertical decimation too high, changing to 1 (use fd to keep vdec=%d)\n", priv->vdec);
 
615
                        priv->vdec = 1;
 
616
                }
 
617
                if (priv->hdec != 1 && !priv->fd) {
 
618
                        WARNING("horizontal decimation too high, changing to 1 (use fd to keep hdec=%d)\n", priv->hdec);
 
619
                        priv->hdec = 1;
 
620
                }
 
621
        }
 
622
        
 
623
        VERBOSE("generated JPEG's %dx%s%d%s, stretched to %dx%d\n", 
 
624
                        width/priv->hdec, (priv->fields == 2) ? "(" : "", 
 
625
                        height/(priv->vdec*priv->fields),
 
626
                        (priv->fields == 2) ? "x2)" : "",
 
627
                        (width/priv->hdec)*stretchx,
 
628
                        (height/(priv->vdec*priv->fields))*
 
629
                        stretchy*priv->fields);
 
630
 
 
631
 
 
632
        if ((width/priv->hdec)*stretchx > priv->maxwidth || 
 
633
                        (height/(priv->vdec*priv->fields))*
 
634
                         stretchy*priv->fields  > priv->maxheight) {
 
635
                ERROR("output dimensions too large (%dx%d), max (%dx%d) insert crop to fix\n", (width/priv->hdec)*stretchx, (height/(priv->vdec*priv->fields))*stretchy*priv->fields, priv->maxwidth, priv->maxheight);
 
636
                err = 1;
 
637
        }
 
638
 
 
639
        if (width%(16*priv->hdec) != 0) {
 
640
                ERROR("width must be a multiple of 16*hdec (%d), use expand\n", 
 
641
                                priv->hdec*16);
 
642
                err = 1;
 
643
        }
 
644
 
 
645
        if (height%(8*priv->fields*priv->vdec) != 0) {
 
646
                ERROR("height must be a multiple of 8*fields*vdec (%d),"
 
647
                                " use expand\n", priv->vdec*priv->fields*8);
 
648
                err = 1;
 
649
        }
 
650
 
 
651
        if (err) return 0;
 
652
 
 
653
        priv->y_stride = width;
 
654
        priv->c_stride = width/2;
 
655
        priv->j = jpeg_enc_init(width, height/priv->fields, 1, 
 
656
                        priv->fields*priv->y_stride, 1, 
 
657
                        priv->fields*priv->c_stride, 1, 
 
658
                        priv->fields*priv->c_stride, 1, 
 
659
                        priv->quality, priv->bw);
 
660
 
 
661
        if (!priv->j) return 0;
 
662
        return vf_next_config(vf, width, height, d_width, d_height, flags, 
 
663
                (priv->fields == 2) ? IMGFMT_ZRMJPEGIT : IMGFMT_ZRMJPEGNI); 
 
664
}
 
665
 
 
666
static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
 
667
        struct vf_priv_s *priv = vf->priv;
 
668
        int size = 0;
 
669
        int i;
 
670
        mp_image_t* dmpi; 
 
671
        for (i = 0; i < priv->fields; i++) 
 
672
                size += jpeg_enc_frame(priv->j, 
 
673
                                mpi->planes[0] + i*priv->y_stride,
 
674
                                mpi->planes[1] + i*priv->c_stride, 
 
675
                                mpi->planes[2] + i*priv->c_stride, 
 
676
                                priv->buf + size);
 
677
 
 
678
        dmpi = vf_get_image(vf->next, IMGFMT_ZRMJPEGNI,
 
679
                        MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h);
 
680
        dmpi->planes[0] = (uint8_t*)priv->buf;
 
681
        dmpi->planes[1] = (uint8_t*)size;
 
682
        return vf_next_put_image(vf,dmpi); 
 
683
}
 
684
 
 
685
static int query_format(struct vf_instance_s* vf, unsigned int fmt){
 
686
        VERBOSE("query_format() called\n");
 
687
 
 
688
        switch (fmt) { 
 
689
                case IMGFMT_YV12:
 
690
                case IMGFMT_YUY2:
 
691
                        /* strictly speaking the output format of
 
692
                         * this filter will be known after config(),
 
693
                         * but everything that supports IMGFMT_ZRMJPEGNI
 
694
                         * should also support all other IMGFMT_ZRMJPEG* */
 
695
                        return vf_next_query_format(vf, IMGFMT_ZRMJPEGNI);
 
696
        }
 
697
 
 
698
        return 0;
 
699
}
 
700
 
 
701
static void uninit(vf_instance_t *vf) {
 
702
        struct vf_priv_s *priv = vf->priv;
 
703
        VERBOSE("uninit() called\n");
 
704
        if (priv->j) jpeg_enc_uninit(priv->j);
 
705
        free(priv);
 
706
}
 
707
 
 
708
static int open(vf_instance_t *vf, char* args){
 
709
        struct vf_priv_s *priv;
 
710
        VERBOSE("open() called: args=\"%s\"\n", args);
 
711
 
 
712
        vf->config = config;
 
713
        vf->put_image = put_image;
 
714
        vf->query_format = query_format;
 
715
        vf->uninit = uninit;
 
716
 
 
717
        priv = vf->priv = calloc(sizeof(*priv), 1);
 
718
        if (!vf->priv) {
 
719
                ERROR("out of memory error\n");
 
720
                return 0;
 
721
        }
 
722
 
 
723
        /* maximum displayable size by zoran card, these defaults 
 
724
         * are for my own zoran card in PAL mode, these can be changed
 
725
         * by filter options. But... in an ideal world these values would
 
726
         * be queried from the vo device itself... */
 
727
        priv->maxwidth = 768;
 
728
        priv->maxheight = 576;
 
729
 
 
730
        priv->quality = 2;
 
731
        priv->hdec = 1;
 
732
        priv->vdec = 1;
 
733
 
 
734
        /* if libavcodec is already initialized, we must not initialize it 
 
735
         * again, but if it is not initialized then we mustinitialize it now. */
 
736
        if (!avcodec_inited) {
 
737
                /* we need to initialize libavcodec */
 
738
                avcodec_init();
 
739
                avcodec_register_all();
 
740
                avcodec_inited=1;
 
741
        }
 
742
        
 
743
        if (args) {
 
744
                char *arg, *tmp, *ptr, junk;
 
745
                int last = 0, input;
 
746
 
 
747
                /* save arguments, to be able to safely modify them */
 
748
                arg = strdup(args);
 
749
                if (!arg) {
 
750
                        ERROR("out of memory, this is bad\n");
 
751
                        return 0;
 
752
                }
 
753
 
 
754
                tmp = ptr = arg;
 
755
                do {
 
756
                        while (*tmp != ':' && *tmp) tmp++;
 
757
                        if (*tmp == ':') *tmp++ = '\0';
 
758
                        else last = 1;
 
759
                        VERBOSE("processing filter option \"%s\"\n", ptr);
 
760
                        /* These options deal with the maximum output
 
761
                         * resolution of the zoran card. These should
 
762
                         * be queried from the vo device, but it is currently
 
763
                         * too difficult, so the user should tell the filter */
 
764
                        if (!strncmp("maxheight=", ptr, 10)) {
 
765
                                if (sscanf(ptr+10, "%d%c", &input, &junk) != 1) 
 
766
                                                ERROR(
 
767
                "error parsing parameter to \"maxheight=\", \"%s\", ignoring\n"
 
768
                                                                , ptr + 10);
 
769
                                else {
 
770
                                        priv->maxheight = input;
 
771
                                        VERBOSE("setting maxheight to %d\n",
 
772
                                                        priv->maxheight);
 
773
                                }
 
774
                        } else if (!strncmp("quality=", ptr, 8)) {
 
775
                                if (sscanf(ptr+8, "%d%c", &input, &junk) != 1)
 
776
                                        ERROR(
 
777
                "error parsing parameter to \"quality=\", \"%s\", ignoring\n"
 
778
                                                                , ptr + 8);
 
779
                                else if (input < 1 || input > 20)
 
780
                                        ERROR(
 
781
                "parameter to \"quality=\" out of range (1..20), %d\n", input);
 
782
                                else {
 
783
                                        priv->quality = input;
 
784
                                        VERBOSE("setting JPEG quality to %d\n",
 
785
                                                        priv->quality);
 
786
                                }
 
787
                        } else if (!strncmp("maxwidth=", ptr, 9)) {
 
788
                                if (sscanf(ptr+9, "%d%c", &input, &junk) != 1) 
 
789
                                        ERROR(
 
790
                "error parsing parameter to \"maxwidth=\", \"%s\", ignoring\n"
 
791
                                                                , ptr + 9);
 
792
                                else {
 
793
                                        priv->maxwidth = input;
 
794
                                        VERBOSE("setting maxwidth to %d\n",
 
795
                                                        priv->maxwidth);
 
796
                                }
 
797
                        } else if (!strncmp("hdec=", ptr, 5)) {
 
798
                                if (sscanf(ptr+5, "%d%c", &input, &junk) != 1) 
 
799
                                        ERROR(
 
800
                "error parsing parameter to \"hdec=\", \"%s\", ignoring\n"
 
801
                                                                , ptr + 9);
 
802
                                else if (input != 1 && input != 2 && input != 4)
 
803
                                        ERROR(
 
804
                "illegal parameter to \"hdec=\", %d, should be 1, 2 or 4", 
 
805
                                                                input);
 
806
                                else {
 
807
                                        priv->hdec = input;
 
808
                                        VERBOSE(
 
809
                "setting horizontal decimation to %d\n", priv->maxwidth);
 
810
                                }
 
811
                        } else if (!strncmp("vdec=", ptr, 5)) {
 
812
                                if (sscanf(ptr+5, "%d%c", &input, &junk) != 1) 
 
813
                                        ERROR(
 
814
                "error parsing parameter to \"vdec=\", \"%s\", ignoring\n"
 
815
                                                                , ptr + 9);
 
816
                                else if (input != 1 && input != 2 && input != 4)
 
817
                                        ERROR(
 
818
                "illegal parameter to \"vdec=\", %d, should be 1, 2 or 4", 
 
819
                                                                input);
 
820
                                else {
 
821
                                        priv->vdec = input;
 
822
                                        VERBOSE(
 
823
                        "setting vertical decimation to %d\n", priv->maxwidth);
 
824
                                }
 
825
                        } else if (!strcasecmp("dc10+-PAL", ptr) ||
 
826
                                        !strcasecmp("dc10-PAL", ptr)) {
 
827
                                priv->maxwidth = 768;
 
828
                                priv->maxheight = 576;
 
829
                                VERBOSE("setting DC10(+) PAL profile\n");
 
830
                        } else if (!strcasecmp("fd", ptr)) {
 
831
                                priv->fd = 1;
 
832
                                VERBOSE("forcing decimation\n");
 
833
                        } else if (!strcasecmp("nofd", ptr)) {
 
834
                                priv->fd = 0;
 
835
                                VERBOSE("decimate only if beautiful\n");
 
836
                        } else if (!strcasecmp("bw", ptr)) {
 
837
                                priv->bw = 1;
 
838
                                VERBOSE("setting black and white encoding\n");
 
839
                        } else if (!strcasecmp("color", ptr)) {
 
840
                                priv->bw = 0;
 
841
                                VERBOSE("setting color encoding\n");
 
842
                        } else if (!strcasecmp("dc10+-NTSC", ptr) ||
 
843
                                        !strcasecmp("dc10-NTSC", ptr)) {
 
844
                                priv->maxwidth = 640;
 
845
                                priv->maxheight = 480;
 
846
                                VERBOSE("setting DC10(+) NTSC profile\n");
 
847
                        } else if (!strcasecmp("buz-PAL", ptr) ||
 
848
                                        !strcasecmp("lml33-PAL", ptr)) {
 
849
                                priv->maxwidth = 720;
 
850
                                priv->maxheight = 576;
 
851
                                VERBOSE("setting buz/lml33 PAL profile\n");
 
852
                        } else if (!strcasecmp("buz-NTSC", ptr) ||
 
853
                                        !strcasecmp("lml33-NTSC", ptr)) {
 
854
                                priv->maxwidth = 720;
 
855
                                priv->maxheight = 480;
 
856
                                VERBOSE("setting buz/lml33 NTSC profile\n");
 
857
                        } else {
 
858
                                WARNING("ignoring unknown filter option " 
 
859
                                                "\"%s\", or missing argument\n",
 
860
                                                ptr);
 
861
                        }
 
862
                        ptr = tmp;
 
863
                } while (!last);
 
864
 
 
865
                free(arg);
 
866
        }
 
867
 
 
868
 
 
869
        return 1;
 
870
}
 
871
 
 
872
vf_info_t vf_info_zrmjpeg = {
 
873
    "realtime zoran MJPEG encoding",
 
874
    "zrmjpeg",
 
875
    "Rik Snel",
 
876
    "",
 
877
    open,
 
878
    NULL
 
879
};
 
880