Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * Flash Screen Video Version 2 encoder
3
 * Copyright (C) 2009 Joshua Warner
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
 
22
/**
23
 * @file
24
 * Flash Screen Video Version 2 encoder
25
 * @author Joshua Warner
26
 */
27
 
28
/* Differences from version 1 stream:
29
 * NOTE: Currently, the only player that supports version 2 streams is Adobe Flash Player itself.
30
 * * Supports sending only a range of scanlines in a block,
31
 *   indicating a difference from the corresponding block in the last keyframe.
32
 * * Supports initializing the zlib dictionary with data from the corresponding
33
 *   block in the last keyframe, to improve compression.
34
 * * Supports a hybrid 15-bit rgb / 7-bit palette color space.
35
 */
36
 
37
/* TODO:
38
 * Don't keep Block structures for both current frame and keyframe.
39
 * Make better heuristics for deciding stream parameters (optimum_* functions).  Currently these return constants.
40
 * Figure out how to encode palette information in the stream, choose an optimum palette at each keyframe.
41
 * Figure out how the zlibPrimeCompressCurrent flag works, implement support.
42
 * Find other sample files (that weren't generated here), develop a decoder.
43
 */
44
 
45
#include 
46
#include 
47
#include 
48
 
49
#include "libavutil/imgutils.h"
50
#include "avcodec.h"
51
#include "internal.h"
52
#include "put_bits.h"
53
#include "bytestream.h"
54
 
55
#define HAS_IFRAME_IMAGE 0x02
56
#define HAS_PALLET_INFO 0x01
57
 
58
#define COLORSPACE_BGR 0x00
59
#define COLORSPACE_15_7 0x10
60
#define HAS_DIFF_BLOCKS 0x04
61
#define ZLIB_PRIME_COMPRESS_CURRENT 0x02
62
#define ZLIB_PRIME_COMPRESS_PREVIOUS 0x01
63
 
64
// Disables experimental "smart" parameter-choosing code, as well as the statistics that it depends on.
65
// At the moment, the "smart" code is a great example of how the parameters *shouldn't* be chosen.
66
#define FLASHSV2_DUMB
67
 
68
typedef struct Block {
69
    uint8_t *enc;
70
    uint8_t *sl_begin, *sl_end;
71
    int enc_size;
72
    uint8_t *data;
73
    unsigned long data_size;
74
 
75
    uint8_t start, len;
76
    uint8_t dirty;
77
    uint8_t col, row, width, height;
78
    uint8_t flags;
79
} Block;
80
 
81
typedef struct Palette {
82
    unsigned colors[128];
83
    uint8_t index[1 << 15];
84
} Palette;
85
 
86
typedef struct FlashSV2Context {
87
    AVCodecContext *avctx;
88
    uint8_t *current_frame;
89
    uint8_t *key_frame;
90
    AVFrame frame;
91
    uint8_t *encbuffer;
92
    uint8_t *keybuffer;
93
    uint8_t *databuffer;
94
 
95
    uint8_t *blockbuffer;
96
    int blockbuffer_size;
97
 
98
    Block *frame_blocks;
99
    Block *key_blocks;
100
    int frame_size;
101
    int blocks_size;
102
 
103
    int use15_7, dist, comp;
104
 
105
    int rows, cols;
106
 
107
    int last_key_frame;
108
 
109
    int image_width, image_height;
110
    int block_width, block_height;
111
    uint8_t flags;
112
    uint8_t use_custom_palette;
113
    uint8_t palette_type;       ///< 0=>default, 1=>custom - changed when palette regenerated.
114
    Palette palette;
115
#ifndef FLASHSV2_DUMB
116
    double tot_blocks;          ///< blocks encoded since last keyframe
117
    double diff_blocks;         ///< blocks that were different since last keyframe
118
    double tot_lines;           ///< total scanlines in image since last keyframe
119
    double diff_lines;          ///< scanlines that were different since last keyframe
120
    double raw_size;            ///< size of raw frames since last keyframe
121
    double comp_size;           ///< size of compressed data since last keyframe
122
    double uncomp_size;         ///< size of uncompressed data since last keyframe
123
 
124
    double total_bits;          ///< total bits written to stream so far
125
#endif
126
} FlashSV2Context;
127
 
128
static av_cold void cleanup(FlashSV2Context * s)
129
{
130
    av_freep(&s->encbuffer);
131
    av_freep(&s->keybuffer);
132
    av_freep(&s->databuffer);
133
    av_freep(&s->blockbuffer);
134
    av_freep(&s->current_frame);
135
    av_freep(&s->key_frame);
136
 
137
    av_freep(&s->frame_blocks);
138
    av_freep(&s->key_blocks);
139
}
140
 
141
static void init_blocks(FlashSV2Context * s, Block * blocks,
142
                        uint8_t * encbuf, uint8_t * databuf)
143
{
144
    int row, col;
145
    Block *b;
146
    for (col = 0; col < s->cols; col++) {
147
        for (row = 0; row < s->rows; row++) {
148
            b = blocks + (col + row * s->cols);
149
            b->width = (col < s->cols - 1) ?
150
                s->block_width :
151
                s->image_width - col * s->block_width;
152
 
153
            b->height = (row < s->rows - 1) ?
154
                s->block_height :
155
                s->image_height - row * s->block_height;
156
 
157
            b->row   = row;
158
            b->col   = col;
159
            b->enc   = encbuf;
160
            b->data  = databuf;
161
            encbuf  += b->width * b->height * 3;
162
            databuf += !databuf ? 0 : b->width * b->height * 6;
163
        }
164
    }
165
}
166
 
167
static void reset_stats(FlashSV2Context * s)
168
{
169
#ifndef FLASHSV2_DUMB
170
    s->diff_blocks = 0.1;
171
    s->tot_blocks = 1;
172
    s->diff_lines = 0.1;
173
    s->tot_lines = 1;
174
    s->raw_size = s->comp_size = s->uncomp_size = 10;
175
#endif
176
}
177
 
178
static av_cold int flashsv2_encode_init(AVCodecContext * avctx)
179
{
180
    FlashSV2Context *s = avctx->priv_data;
181
 
182
    s->avctx = avctx;
183
 
184
    s->comp = avctx->compression_level;
185
    if (s->comp == -1)
186
        s->comp = 9;
187
    if (s->comp < 0 || s->comp > 9) {
188
        av_log(avctx, AV_LOG_ERROR,
189
               "Compression level should be 0-9, not %d\n", s->comp);
190
        return -1;
191
    }
192
 
193
 
194
    if ((avctx->width > 4095) || (avctx->height > 4095)) {
195
        av_log(avctx, AV_LOG_ERROR,
196
               "Input dimensions too large, input must be max 4096x4096 !\n");
197
        return -1;
198
    }
199
    if ((avctx->width < 16) || (avctx->height < 16)) {
200
        av_log(avctx, AV_LOG_ERROR,
201
               "Input dimensions too small, input must be at least 16x16 !\n");
202
        return -1;
203
    }
204
 
205
    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)
206
        return -1;
207
 
208
 
209
    s->last_key_frame = 0;
210
 
211
    s->image_width  = avctx->width;
212
    s->image_height = avctx->height;
213
 
214
    s->block_width  = (s->image_width /  12) & ~15;
215
    s->block_height = (s->image_height / 12) & ~15;
216
 
217
    if(!s->block_width)
218
        s->block_width = 1;
219
    if(!s->block_height)
220
        s->block_height = 1;
221
 
222
    s->rows = (s->image_height + s->block_height - 1) / s->block_height;
223
    s->cols = (s->image_width +  s->block_width -  1) / s->block_width;
224
 
225
    s->frame_size  = s->image_width * s->image_height * 3;
226
    s->blocks_size = s->rows * s->cols * sizeof(Block);
227
 
228
    s->encbuffer     = av_mallocz(s->frame_size);
229
    s->keybuffer     = av_mallocz(s->frame_size);
230
    s->databuffer    = av_mallocz(s->frame_size * 6);
231
    s->current_frame = av_mallocz(s->frame_size);
232
    s->key_frame     = av_mallocz(s->frame_size);
233
    s->frame_blocks  = av_mallocz(s->blocks_size);
234
    s->key_blocks    = av_mallocz(s->blocks_size);
235
 
236
    s->blockbuffer      = NULL;
237
    s->blockbuffer_size = 0;
238
 
239
    init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
240
    init_blocks(s, s->key_blocks,   s->keybuffer, 0);
241
    reset_stats(s);
242
#ifndef FLASHSV2_DUMB
243
    s->total_bits = 1;
244
#endif
245
 
246
    s->use_custom_palette =  0;
247
    s->palette_type       = -1;        // so that the palette will be generated in reconfigure_at_keyframe
248
 
249
    if (!s->encbuffer || !s->keybuffer || !s->databuffer
250
        || !s->current_frame || !s->key_frame || !s->key_blocks
251
        || !s->frame_blocks) {
252
        av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
253
        cleanup(s);
254
        return -1;
255
    }
256
 
257
    return 0;
258
}
259
 
260
static int new_key_frame(FlashSV2Context * s)
261
{
262
    int i;
263
    memcpy(s->key_blocks, s->frame_blocks, s->blocks_size);
264
    memcpy(s->key_frame, s->current_frame, s->frame_size);
265
 
266
    for (i = 0; i < s->rows * s->cols; i++) {
267
        s->key_blocks[i].enc += (s->keybuffer - s->encbuffer);
268
        s->key_blocks[i].sl_begin = 0;
269
        s->key_blocks[i].sl_end   = 0;
270
        s->key_blocks[i].data     = 0;
271
    }
272
    memcpy(s->keybuffer, s->encbuffer, s->frame_size);
273
 
274
    return 0;
275
}
276
 
277
static int write_palette(FlashSV2Context * s, uint8_t * buf, int buf_size)
278
{
279
    //this isn't implemented yet!  Default palette only!
280
    return -1;
281
}
282
 
283
static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size)
284
{
285
    PutBitContext pb;
286
    int buf_pos, len;
287
 
288
    if (buf_size < 5)
289
        return -1;
290
 
291
    init_put_bits(&pb, buf, buf_size * 8);
292
 
293
    put_bits(&pb, 4, (s->block_width  >> 4) - 1);
294
    put_bits(&pb, 12, s->image_width);
295
    put_bits(&pb, 4, (s->block_height >> 4) - 1);
296
    put_bits(&pb, 12, s->image_height);
297
 
298
    flush_put_bits(&pb);
299
    buf_pos = 4;
300
 
301
    buf[buf_pos++] = s->flags;
302
 
303
    if (s->flags & HAS_PALLET_INFO) {
304
        len = write_palette(s, buf + buf_pos, buf_size - buf_pos);
305
        if (len < 0)
306
            return -1;
307
        buf_pos += len;
308
    }
309
 
310
    return buf_pos;
311
}
312
 
313
static int write_block(Block * b, uint8_t * buf, int buf_size)
314
{
315
    int buf_pos = 0;
316
    unsigned block_size = b->data_size;
317
 
318
    if (b->flags & HAS_DIFF_BLOCKS)
319
        block_size += 2;
320
    if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT)
321
        block_size += 2;
322
    if (block_size > 0)
323
        block_size += 1;
324
    if (buf_size < block_size + 2)
325
        return -1;
326
 
327
    buf[buf_pos++] = block_size >> 8;
328
    buf[buf_pos++] = block_size;
329
 
330
    if (block_size == 0)
331
        return buf_pos;
332
 
333
    buf[buf_pos++] = b->flags;
334
 
335
    if (b->flags & HAS_DIFF_BLOCKS) {
336
        buf[buf_pos++] = (b->start);
337
        buf[buf_pos++] = (b->len);
338
    }
339
 
340
    if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT) {
341
        //This feature of the format is poorly understood, and as of now, unused.
342
        buf[buf_pos++] = (b->col);
343
        buf[buf_pos++] = (b->row);
344
    }
345
 
346
    memcpy(buf + buf_pos, b->data, b->data_size);
347
 
348
    buf_pos += b->data_size;
349
 
350
    return buf_pos;
351
}
352
 
353
static int encode_zlib(Block * b, uint8_t * buf, unsigned long *buf_size, int comp)
354
{
355
    int res = compress2(buf, buf_size, b->sl_begin, b->sl_end - b->sl_begin, comp);
356
    return res == Z_OK ? 0 : -1;
357
}
358
 
359
static int encode_zlibprime(Block * b, Block * prime, uint8_t * buf,
360
                            int *buf_size, int comp)
361
{
362
    z_stream s;
363
    int res;
364
    s.zalloc = NULL;
365
    s.zfree  = NULL;
366
    s.opaque = NULL;
367
    res = deflateInit(&s, comp);
368
    if (res < 0)
369
        return -1;
370
 
371
    s.next_in  = prime->enc;
372
    s.avail_in = prime->enc_size;
373
    while (s.avail_in > 0) {
374
        s.next_out  = buf;
375
        s.avail_out = *buf_size;
376
        res = deflate(&s, Z_SYNC_FLUSH);
377
        if (res < 0)
378
            return -1;
379
    }
380
 
381
    s.next_in   = b->sl_begin;
382
    s.avail_in  = b->sl_end - b->sl_begin;
383
    s.next_out  = buf;
384
    s.avail_out = *buf_size;
385
    res = deflate(&s, Z_FINISH);
386
    deflateEnd(&s);
387
    *buf_size -= s.avail_out;
388
    if (res != Z_STREAM_END)
389
        return -1;
390
    return 0;
391
}
392
 
393
static int encode_bgr(Block * b, const uint8_t * src, int stride)
394
{
395
    int i;
396
    uint8_t *ptr = b->enc;
397
    for (i = 0; i < b->start; i++)
398
        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
399
    b->sl_begin = ptr + i * b->width * 3;
400
    for (; i < b->start + b->len; i++)
401
        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
402
    b->sl_end = ptr + i * b->width * 3;
403
    for (; i < b->height; i++)
404
        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
405
    b->enc_size = ptr + i * b->width * 3 - b->enc;
406
    return b->enc_size;
407
}
408
 
409
static inline unsigned pixel_color15(const uint8_t * src)
410
{
411
    return (src[0] >> 3) | ((src[1] & 0xf8) << 2) | ((src[2] & 0xf8) << 7);
412
}
413
 
414
static inline unsigned int chroma_diff(unsigned int c1, unsigned int c2)
415
{
416
    unsigned int t1 = (c1 & 0x000000ff) + ((c1 & 0x0000ff00) >> 8) + ((c1 & 0x00ff0000) >> 16);
417
    unsigned int t2 = (c2 & 0x000000ff) + ((c2 & 0x0000ff00) >> 8) + ((c2 & 0x00ff0000) >> 16);
418
 
419
    return abs(t1 - t2) + abs((c1 & 0x000000ff) - (c2 & 0x000000ff)) +
420
        abs(((c1 & 0x0000ff00) >> 8) - ((c2 & 0x0000ff00) >> 8)) +
421
        abs(((c1 & 0x00ff0000) >> 16) - ((c2 & 0x00ff0000) >> 16));
422
}
423
 
424
static inline int pixel_color7_fast(Palette * palette, unsigned c15)
425
{
426
    return palette->index[c15];
427
}
428
 
429
static int pixel_color7_slow(Palette * palette, unsigned color)
430
{
431
    int i, min = 0x7fffffff;
432
    int minc = -1;
433
    for (i = 0; i < 128; i++) {
434
        int c1 = palette->colors[i];
435
        int diff = chroma_diff(c1, color);
436
        if (diff < min) {
437
            min = diff;
438
            minc = i;
439
        }
440
    }
441
    return minc;
442
}
443
 
444
static inline unsigned pixel_bgr(const uint8_t * src)
445
{
446
    return (src[0]) | (src[1] << 8) | (src[2] << 16);
447
}
448
 
449
static int write_pixel_15_7(Palette * palette, uint8_t * dest, const uint8_t * src,
450
                            int dist)
451
{
452
    unsigned c15 = pixel_color15(src);
453
    unsigned color = pixel_bgr(src);
454
    int d15 = chroma_diff(color, color & 0x00f8f8f8);
455
    int c7 = pixel_color7_fast(palette, c15);
456
    int d7 = chroma_diff(color, palette->colors[c7]);
457
    if (dist + d15 >= d7) {
458
        dest[0] = c7;
459
        return 1;
460
    } else {
461
        dest[0] = 0x80 | (c15 >> 8);
462
        dest[1] = c15 & 0xff;
463
        return 2;
464
    }
465
}
466
 
467
static int update_palette_index(Palette * palette)
468
{
469
    int r, g, b;
470
    unsigned int bgr, c15, index;
471
    for (r = 4; r < 256; r += 8) {
472
        for (g = 4; g < 256; g += 8) {
473
            for (b = 4; b < 256; b += 8) {
474
                bgr = b | (g << 8) | (r << 16);
475
                c15 = (b >> 3) | ((g & 0xf8) << 2) | ((r & 0xf8) << 7);
476
                index = pixel_color7_slow(palette, bgr);
477
 
478
                palette->index[c15] = index;
479
            }
480
        }
481
    }
482
    return 0;
483
}
484
 
485
static const unsigned int default_screen_video_v2_palette[128] = {
486
    0x00000000, 0x00333333, 0x00666666, 0x00999999, 0x00CCCCCC, 0x00FFFFFF,
487
    0x00330000, 0x00660000, 0x00990000, 0x00CC0000, 0x00FF0000, 0x00003300,
488
    0x00006600, 0x00009900, 0x0000CC00, 0x0000FF00, 0x00000033, 0x00000066,
489
    0x00000099, 0x000000CC, 0x000000FF, 0x00333300, 0x00666600, 0x00999900,
490
    0x00CCCC00, 0x00FFFF00, 0x00003333, 0x00006666, 0x00009999, 0x0000CCCC,
491
    0x0000FFFF, 0x00330033, 0x00660066, 0x00990099, 0x00CC00CC, 0x00FF00FF,
492
    0x00FFFF33, 0x00FFFF66, 0x00FFFF99, 0x00FFFFCC, 0x00FF33FF, 0x00FF66FF,
493
    0x00FF99FF, 0x00FFCCFF, 0x0033FFFF, 0x0066FFFF, 0x0099FFFF, 0x00CCFFFF,
494
    0x00CCCC33, 0x00CCCC66, 0x00CCCC99, 0x00CCCCFF, 0x00CC33CC, 0x00CC66CC,
495
    0x00CC99CC, 0x00CCFFCC, 0x0033CCCC, 0x0066CCCC, 0x0099CCCC, 0x00FFCCCC,
496
    0x00999933, 0x00999966, 0x009999CC, 0x009999FF, 0x00993399, 0x00996699,
497
    0x0099CC99, 0x0099FF99, 0x00339999, 0x00669999, 0x00CC9999, 0x00FF9999,
498
    0x00666633, 0x00666699, 0x006666CC, 0x006666FF, 0x00663366, 0x00669966,
499
    0x0066CC66, 0x0066FF66, 0x00336666, 0x00996666, 0x00CC6666, 0x00FF6666,
500
    0x00333366, 0x00333399, 0x003333CC, 0x003333FF, 0x00336633, 0x00339933,
501
    0x0033CC33, 0x0033FF33, 0x00663333, 0x00993333, 0x00CC3333, 0x00FF3333,
502
    0x00003366, 0x00336600, 0x00660033, 0x00006633, 0x00330066, 0x00663300,
503
    0x00336699, 0x00669933, 0x00993366, 0x00339966, 0x00663399, 0x00996633,
504
    0x006699CC, 0x0099CC66, 0x00CC6699, 0x0066CC99, 0x009966CC, 0x00CC9966,
505
    0x0099CCFF, 0x00CCFF99, 0x00FF99CC, 0x0099FFCC, 0x00CC99FF, 0x00FFCC99,
506
    0x00111111, 0x00222222, 0x00444444, 0x00555555, 0x00AAAAAA, 0x00BBBBBB,
507
    0x00DDDDDD, 0x00EEEEEE
508
};
509
 
510
static int generate_default_palette(Palette * palette)
511
{
512
    memcpy(palette->colors, default_screen_video_v2_palette,
513
           sizeof(default_screen_video_v2_palette));
514
 
515
    return update_palette_index(palette);
516
}
517
 
518
static int generate_optimum_palette(Palette * palette, const uint8_t * image,
519
                                   int width, int height, int stride)
520
{
521
    //this isn't implemented yet!  Default palette only!
522
    return -1;
523
}
524
 
525
static inline int encode_15_7_sl(Palette * palette, uint8_t * dest,
526
                                 const uint8_t * src, int width, int dist)
527
{
528
    int len = 0, x;
529
    for (x = 0; x < width; x++) {
530
        len += write_pixel_15_7(palette, dest + len, src + 3 * x, dist);
531
    }
532
    return len;
533
}
534
 
535
static int encode_15_7(Palette * palette, Block * b, const uint8_t * src,
536
                       int stride, int dist)
537
{
538
    int i;
539
    uint8_t *ptr = b->enc;
540
    for (i = 0; i < b->start; i++)
541
        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
542
    b->sl_begin = ptr;
543
    for (; i < b->start + b->len; i++)
544
        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
545
    b->sl_end = ptr;
546
    for (; i < b->height; i++)
547
        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
548
    b->enc_size = ptr - b->enc;
549
    return b->enc_size;
550
}
551
 
552
static int encode_block(FlashSV2Context *s, Palette * palette, Block * b,
553
                        Block * prev, const uint8_t * src, int stride, int comp,
554
                        int dist, int keyframe)
555
{
556
    unsigned buf_size = b->width * b->height * 6;
557
    uint8_t *buf = s->blockbuffer;
558
    int res;
559
 
560
    if (b->flags & COLORSPACE_15_7) {
561
        encode_15_7(palette, b, src, stride, dist);
562
    } else {
563
        encode_bgr(b, src, stride);
564
    }
565
 
566
    if (b->len > 0) {
567
        b->data_size = buf_size;
568
        res = encode_zlib(b, b->data, &b->data_size, comp);
569
        if (res)
570
            return res;
571
 
572
        if (!keyframe) {
573
            res = encode_zlibprime(b, prev, buf, &buf_size, comp);
574
            if (res)
575
                return res;
576
 
577
            if (buf_size < b->data_size) {
578
                b->data_size = buf_size;
579
                memcpy(b->data, buf, buf_size);
580
                b->flags |= ZLIB_PRIME_COMPRESS_PREVIOUS;
581
            }
582
        }
583
    } else {
584
        b->data_size = 0;
585
    }
586
    return 0;
587
}
588
 
589
static int compare_sl(FlashSV2Context * s, Block * b, const uint8_t * src,
590
                      uint8_t * frame, uint8_t * key, int y, int keyframe)
591
{
592
    if (memcmp(src, frame, b->width * 3) != 0) {
593
        b->dirty = 1;
594
        memcpy(frame, src, b->width * 3);
595
#ifndef FLASHSV2_DUMB
596
        s->diff_lines++;
597
#endif
598
    }
599
    if (memcmp(src, key, b->width * 3) != 0) {
600
        if (b->len == 0)
601
            b->start = y;
602
        b->len = y + 1 - b->start;
603
    }
604
    return 0;
605
}
606
 
607
static int mark_all_blocks(FlashSV2Context * s, const uint8_t * src, int stride,
608
                           int keyframe)
609
{
610
    int sl, rsl, col, pos, possl;
611
    Block *b;
612
    for (sl = s->image_height - 1; sl >= 0; sl--) {
613
        for (col = 0; col < s->cols; col++) {
614
            rsl = s->image_height - sl - 1;
615
            b = s->frame_blocks + col + rsl / s->block_height * s->cols;
616
            possl = stride * sl + col * s->block_width * 3;
617
            pos = s->image_width * rsl * 3 + col * s->block_width * 3;
618
            compare_sl(s, b, src + possl, s->current_frame + pos,
619
                       s->key_frame + pos, rsl % s->block_height, keyframe);
620
        }
621
    }
622
#ifndef FLASHSV2_DUMB
623
    s->tot_lines += s->image_height * s->cols;
624
#endif
625
    return 0;
626
}
627
 
628
static int encode_all_blocks(FlashSV2Context * s, int keyframe)
629
{
630
    int row, col, res;
631
    uint8_t *data;
632
    Block *b, *prev;
633
    for (row = 0; row < s->rows; row++) {
634
        for (col = 0; col < s->cols; col++) {
635
            b = s->frame_blocks + (row * s->cols + col);
636
            prev = s->key_blocks + (row * s->cols + col);
637
            b->flags = s->use15_7 ? COLORSPACE_15_7 : 0;
638
            if (keyframe) {
639
                b->start = 0;
640
                b->len = b->height;
641
            } else if (!b->dirty) {
642
                b->start = 0;
643
                b->len = 0;
644
                b->data_size = 0;
645
                continue;
646
            } else if (b->start != 0 || b->len != b->height) {
647
                b->flags |= HAS_DIFF_BLOCKS;
648
            }
649
            data = s->current_frame + s->image_width * 3 * s->block_height * row + s->block_width * col * 3;
650
            res = encode_block(s, &s->palette, b, prev, data, s->image_width * 3, s->comp, s->dist, keyframe);
651
#ifndef FLASHSV2_DUMB
652
            if (b->dirty)
653
                s->diff_blocks++;
654
            s->comp_size += b->data_size;
655
            s->uncomp_size += b->enc_size;
656
#endif
657
            if (res)
658
                return res;
659
        }
660
    }
661
#ifndef FLASHSV2_DUMB
662
    s->raw_size += s->image_width * s->image_height * 3;
663
    s->tot_blocks += s->rows * s->cols;
664
#endif
665
    return 0;
666
}
667
 
668
static int write_all_blocks(FlashSV2Context * s, uint8_t * buf,
669
                            int buf_size)
670
{
671
    int row, col, buf_pos = 0, len;
672
    Block *b;
673
    for (row = 0; row < s->rows; row++) {
674
        for (col = 0; col < s->cols; col++) {
675
            b = s->frame_blocks + row * s->cols + col;
676
            len = write_block(b, buf + buf_pos, buf_size - buf_pos);
677
            b->start = b->len = b->dirty = 0;
678
            if (len < 0)
679
                return len;
680
            buf_pos += len;
681
        }
682
    }
683
    return buf_pos;
684
}
685
 
686
static int write_bitstream(FlashSV2Context * s, const uint8_t * src, int stride,
687
                           uint8_t * buf, int buf_size, int keyframe)
688
{
689
    int buf_pos, res;
690
 
691
    res = mark_all_blocks(s, src, stride, keyframe);
692
    if (res)
693
        return res;
694
    res = encode_all_blocks(s, keyframe);
695
    if (res)
696
        return res;
697
 
698
    res = write_header(s, buf, buf_size);
699
    if (res < 0) {
700
        return res;
701
    } else {
702
        buf_pos = res;
703
    }
704
    res = write_all_blocks(s, buf + buf_pos, buf_size - buf_pos);
705
    if (res < 0)
706
        return res;
707
    buf_pos += res;
708
#ifndef FLASHSV2_DUMB
709
    s->total_bits += ((double) buf_pos) * 8.0;
710
#endif
711
 
712
    return buf_pos;
713
}
714
 
715
static void recommend_keyframe(FlashSV2Context * s, int *keyframe)
716
{
717
#ifndef FLASHSV2_DUMB
718
    double block_ratio, line_ratio, enc_ratio, comp_ratio, data_ratio;
719
    if (s->avctx->gop_size > 0) {
720
        block_ratio = s->diff_blocks / s->tot_blocks;
721
        line_ratio = s->diff_lines / s->tot_lines;
722
        enc_ratio = s->uncomp_size / s->raw_size;
723
        comp_ratio = s->comp_size / s->uncomp_size;
724
        data_ratio = s->comp_size / s->raw_size;
725
 
726
        if ((block_ratio >= 0.5 && line_ratio / block_ratio <= 0.5) || line_ratio >= 0.95) {
727
            *keyframe = 1;
728
            return;
729
        }
730
    }
731
#else
732
    return;
733
#endif
734
}
735
 
736
static const double block_size_fraction = 1.0 / 300;
737
static int optimum_block_width(FlashSV2Context * s)
738
{
739
#ifndef FLASHSV2_DUMB
740
    double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
741
    double width = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_width;
742
    int pwidth = ((int) width);
743
    return FFCLIP(pwidth & ~15, 256, 16);
744
#else
745
    return 64;
746
#endif
747
}
748
 
749
static int optimum_block_height(FlashSV2Context * s)
750
{
751
#ifndef FLASHSV2_DUMB
752
    double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
753
    double height = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_height;
754
    int pheight = ((int) height);
755
    return FFCLIP(pheight & ~15, 256, 16);
756
#else
757
    return 64;
758
#endif
759
}
760
 
761
static const double use15_7_threshold = 8192;
762
 
763
static int optimum_use15_7(FlashSV2Context * s)
764
{
765
#ifndef FLASHSV2_DUMB
766
    double ideal = ((double)(s->avctx->bit_rate * s->avctx->time_base.den * s->avctx->ticks_per_frame)) /
767
        ((double) s->avctx->time_base.num) * s->avctx->frame_number;
768
    if (ideal + use15_7_threshold < s->total_bits) {
769
        return 1;
770
    } else {
771
        return 0;
772
    }
773
#else
774
    return s->avctx->global_quality == 0;
775
#endif
776
}
777
 
778
static const double color15_7_factor = 100;
779
 
780
static int optimum_dist(FlashSV2Context * s)
781
{
782
#ifndef FLASHSV2_DUMB
783
    double ideal =
784
        s->avctx->bit_rate * s->avctx->time_base.den *
785
        s->avctx->ticks_per_frame;
786
    int dist = pow((s->total_bits / ideal) * color15_7_factor, 3);
787
    av_log(s->avctx, AV_LOG_DEBUG, "dist: %d\n", dist);
788
    return dist;
789
#else
790
    return 15;
791
#endif
792
}
793
 
794
 
795
static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image,
796
                                   int stride)
797
{
798
    int update_palette = 0;
799
    int res;
800
    int block_width  = optimum_block_width (s);
801
    int block_height = optimum_block_height(s);
802
 
803
    s->rows = (s->image_height + block_height - 1) / block_height;
804
    s->cols = (s->image_width  + block_width  - 1) / block_width;
805
 
806
    if (block_width != s->block_width || block_height != s->block_height) {
807
        s->block_width  = block_width;
808
        s->block_height = block_height;
809
        if (s->rows * s->cols > s->blocks_size / sizeof(Block)) {
810
            s->frame_blocks = av_realloc(s->frame_blocks, s->rows * s->cols * sizeof(Block));
811
            s->key_blocks = av_realloc(s->key_blocks, s->cols * s->rows * sizeof(Block));
812
            if (!s->frame_blocks || !s->key_blocks) {
813
                av_log(s->avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
814
                return -1;
815
            }
816
            s->blocks_size = s->rows * s->cols * sizeof(Block);
817
        }
818
        init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
819
        init_blocks(s, s->key_blocks, s->keybuffer, 0);
820
 
821
        av_fast_malloc(&s->blockbuffer, &s->blockbuffer_size, block_width * block_height * 6);
822
        if (!s->blockbuffer) {
823
            av_log(s->avctx, AV_LOG_ERROR, "Could not allocate block buffer.\n");
824
            return AVERROR(ENOMEM);
825
        }
826
    }
827
 
828
    s->use15_7 = optimum_use15_7(s);
829
    if (s->use15_7) {
830
        if ((s->use_custom_palette && s->palette_type != 1) || update_palette) {
831
            res = generate_optimum_palette(&s->palette, image, s->image_width, s->image_height, stride);
832
            if (res)
833
                return res;
834
            s->palette_type = 1;
835
            av_log(s->avctx, AV_LOG_DEBUG, "Generated optimum palette\n");
836
        } else if (!s->use_custom_palette && s->palette_type != 0) {
837
            res = generate_default_palette(&s->palette);
838
            if (res)
839
                return res;
840
            s->palette_type = 0;
841
            av_log(s->avctx, AV_LOG_DEBUG, "Generated default palette\n");
842
        }
843
    }
844
 
845
 
846
    reset_stats(s);
847
 
848
    return 0;
849
}
850
 
851
static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
852
                                 const AVFrame *pict, int *got_packet)
853
{
854
    FlashSV2Context *const s = avctx->priv_data;
855
    AVFrame *const p = &s->frame;
856
    int res;
857
    int keyframe = 0;
858
 
859
    *p = *pict;
860
 
861
    if ((res = ff_alloc_packet2(avctx, pkt, s->frame_size + FF_MIN_BUFFER_SIZE)) < 0)
862
        return res;
863
 
864
    /* First frame needs to be a keyframe */
865
    if (avctx->frame_number == 0)
866
        keyframe = 1;
867
 
868
    /* Check the placement of keyframes */
869
    if (avctx->gop_size > 0) {
870
        if (avctx->frame_number >= s->last_key_frame + avctx->gop_size)
871
            keyframe = 1;
872
    }
873
 
874
    if (!keyframe
875
        && avctx->frame_number > s->last_key_frame + avctx->keyint_min) {
876
        recommend_keyframe(s, &keyframe);
877
        if (keyframe)
878
            av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %d\n", avctx->frame_number);
879
    }
880
 
881
    if (keyframe) {
882
        res = reconfigure_at_keyframe(s, p->data[0], p->linesize[0]);
883
        if (res)
884
            return res;
885
    }
886
 
887
    if (s->use15_7)
888
        s->dist = optimum_dist(s);
889
 
890
    res = write_bitstream(s, p->data[0], p->linesize[0], pkt->data, pkt->size, keyframe);
891
 
892
    if (keyframe) {
893
        new_key_frame(s);
894
        p->pict_type = AV_PICTURE_TYPE_I;
895
        p->key_frame = 1;
896
        s->last_key_frame = avctx->frame_number;
897
        pkt->flags |= AV_PKT_FLAG_KEY;
898
        av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number);
899
    } else {
900
        p->pict_type = AV_PICTURE_TYPE_P;
901
        p->key_frame = 0;
902
    }
903
 
904
    avctx->coded_frame = p;
905
 
906
    pkt->size = res;
907
    *got_packet = 1;
908
 
909
    return 0;
910
}
911
 
912
static av_cold int flashsv2_encode_end(AVCodecContext * avctx)
913
{
914
    FlashSV2Context *s = avctx->priv_data;
915
 
916
    cleanup(s);
917
 
918
    return 0;
919
}
920
 
921
AVCodec ff_flashsv2_encoder = {
922
    .name           = "flashsv2",
923
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"),
924
    .type           = AVMEDIA_TYPE_VIDEO,
925
    .id             = AV_CODEC_ID_FLASHSV2,
926
    .priv_data_size = sizeof(FlashSV2Context),
927
    .init           = flashsv2_encode_init,
928
    .encode2        = flashsv2_encode_frame,
929
    .close          = flashsv2_encode_end,
930
    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
931
};