]> git.sesse.net Git - ffmpeg/blob - libavcodec/flashsv2enc.c
avformat/hlsenc: reindent the code
[ffmpeg] / libavcodec / flashsv2enc.c
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 <stdio.h>
46 #include <stdlib.h>
47 #include <zlib.h>
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     uint8_t *encbuffer;
91     uint8_t *keybuffer;
92     uint8_t *databuffer;
93
94     uint8_t *blockbuffer;
95     int blockbuffer_size;
96
97     Block *frame_blocks;
98     Block *key_blocks;
99     int frame_size;
100     int blocks_size;
101
102     int use15_7, dist, comp;
103
104     int rows, cols;
105
106     int last_key_frame;
107
108     int image_width, image_height;
109     int block_width, block_height;
110     uint8_t flags;
111     uint8_t use_custom_palette;
112     uint8_t palette_type;       ///< 0=>default, 1=>custom - changed when palette regenerated.
113     Palette palette;
114 #ifndef FLASHSV2_DUMB
115     double tot_blocks;          ///< blocks encoded since last keyframe
116     double diff_blocks;         ///< blocks that were different since last keyframe
117     double tot_lines;           ///< total scanlines in image since last keyframe
118     double diff_lines;          ///< scanlines that were different since last keyframe
119     double raw_size;            ///< size of raw frames since last keyframe
120     double comp_size;           ///< size of compressed data since last keyframe
121     double uncomp_size;         ///< size of uncompressed data since last keyframe
122
123     double total_bits;          ///< total bits written to stream so far
124 #endif
125 } FlashSV2Context;
126
127 static av_cold void cleanup(FlashSV2Context * s)
128 {
129     av_freep(&s->encbuffer);
130     av_freep(&s->keybuffer);
131     av_freep(&s->databuffer);
132     av_freep(&s->blockbuffer);
133     av_freep(&s->current_frame);
134     av_freep(&s->key_frame);
135
136     av_freep(&s->frame_blocks);
137     av_freep(&s->key_blocks);
138 }
139
140 static void init_blocks(FlashSV2Context * s, Block * blocks,
141                         uint8_t * encbuf, uint8_t * databuf)
142 {
143     int row, col;
144     Block *b;
145     for (col = 0; col < s->cols; col++) {
146         for (row = 0; row < s->rows; row++) {
147             b = blocks + (col + row * s->cols);
148             b->width = (col < s->cols - 1) ?
149                 s->block_width :
150                 s->image_width - col * s->block_width;
151
152             b->height = (row < s->rows - 1) ?
153                 s->block_height :
154                 s->image_height - row * s->block_height;
155
156             b->row   = row;
157             b->col   = col;
158             b->enc   = encbuf;
159             b->data  = databuf;
160             encbuf  += b->width * b->height * 3;
161             databuf += !databuf ? 0 : b->width * b->height * 6;
162         }
163     }
164 }
165
166 static void reset_stats(FlashSV2Context * s)
167 {
168 #ifndef FLASHSV2_DUMB
169     s->diff_blocks = 0.1;
170     s->tot_blocks = 1;
171     s->diff_lines = 0.1;
172     s->tot_lines = 1;
173     s->raw_size = s->comp_size = s->uncomp_size = 10;
174 #endif
175 }
176
177 static av_cold int flashsv2_encode_init(AVCodecContext * avctx)
178 {
179     FlashSV2Context *s = avctx->priv_data;
180     int ret;
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 AVERROR(EINVAL);
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 4095x4095 !\n");
197         return AVERROR(EINVAL);
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 AVERROR(EINVAL);
203     }
204
205     if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
206         return ret;
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     if (!s->encbuffer || !s->keybuffer || !s->databuffer
236         || !s->current_frame || !s->key_frame || !s->key_blocks
237         || !s->frame_blocks) {
238         av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
239         return AVERROR(ENOMEM);
240     }
241
242     s->blockbuffer      = NULL;
243     s->blockbuffer_size = 0;
244
245     init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
246     init_blocks(s, s->key_blocks,   s->keybuffer, 0);
247     reset_stats(s);
248 #ifndef FLASHSV2_DUMB
249     s->total_bits = 1;
250 #endif
251
252     s->use_custom_palette =  0;
253     s->palette_type       = -1;        // so that the palette will be generated in reconfigure_at_keyframe
254
255     return 0;
256 }
257
258 static int new_key_frame(FlashSV2Context * s)
259 {
260     int i;
261     memcpy(s->key_blocks, s->frame_blocks, s->blocks_size);
262     memcpy(s->key_frame, s->current_frame, s->frame_size);
263
264     for (i = 0; i < s->rows * s->cols; i++) {
265         s->key_blocks[i].enc += (s->keybuffer - s->encbuffer);
266         s->key_blocks[i].sl_begin = 0;
267         s->key_blocks[i].sl_end   = 0;
268         s->key_blocks[i].data     = 0;
269     }
270     memcpy(s->keybuffer, s->encbuffer, s->frame_size);
271
272     return 0;
273 }
274
275 static int write_palette(FlashSV2Context * s, uint8_t * buf, int buf_size)
276 {
277     //this isn't implemented yet!  Default palette only!
278     return -1;
279 }
280
281 static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size)
282 {
283     PutBitContext pb;
284     int buf_pos, len;
285
286     if (buf_size < 5)
287         return -1;
288
289     init_put_bits(&pb, buf, buf_size);
290
291     put_bits(&pb, 4, (s->block_width  >> 4) - 1);
292     put_bits(&pb, 12, s->image_width);
293     put_bits(&pb, 4, (s->block_height >> 4) - 1);
294     put_bits(&pb, 12, s->image_height);
295
296     flush_put_bits(&pb);
297     buf_pos = 4;
298
299     buf[buf_pos++] = s->flags;
300
301     if (s->flags & HAS_PALLET_INFO) {
302         len = write_palette(s, buf + buf_pos, buf_size - buf_pos);
303         if (len < 0)
304             return -1;
305         buf_pos += len;
306     }
307
308     return buf_pos;
309 }
310
311 static int write_block(Block * b, uint8_t * buf, int buf_size)
312 {
313     int buf_pos = 0;
314     unsigned block_size = b->data_size;
315
316     if (b->flags & HAS_DIFF_BLOCKS)
317         block_size += 2;
318     if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT)
319         block_size += 2;
320     if (block_size > 0)
321         block_size += 1;
322     if (buf_size < block_size + 2)
323         return -1;
324
325     buf[buf_pos++] = block_size >> 8;
326     buf[buf_pos++] = block_size;
327
328     if (block_size == 0)
329         return buf_pos;
330
331     buf[buf_pos++] = b->flags;
332
333     if (b->flags & HAS_DIFF_BLOCKS) {
334         buf[buf_pos++] = (b->start);
335         buf[buf_pos++] = (b->len);
336     }
337
338     if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT) {
339         //This feature of the format is poorly understood, and as of now, unused.
340         buf[buf_pos++] = (b->col);
341         buf[buf_pos++] = (b->row);
342     }
343
344     memcpy(buf + buf_pos, b->data, b->data_size);
345
346     buf_pos += b->data_size;
347
348     return buf_pos;
349 }
350
351 static int encode_zlib(Block * b, uint8_t * buf, unsigned long *buf_size, int comp)
352 {
353     int res = compress2(buf, buf_size, b->sl_begin, b->sl_end - b->sl_begin, comp);
354     return res == Z_OK ? 0 : -1;
355 }
356
357 static int encode_zlibprime(Block * b, Block * prime, uint8_t * buf,
358                             int *buf_size, int comp)
359 {
360     z_stream s;
361     int res;
362     s.zalloc = NULL;
363     s.zfree  = NULL;
364     s.opaque = NULL;
365     res = deflateInit(&s, comp);
366     if (res < 0)
367         return -1;
368
369     s.next_in  = prime->enc;
370     s.avail_in = prime->enc_size;
371     while (s.avail_in > 0) {
372         s.next_out  = buf;
373         s.avail_out = *buf_size;
374         res = deflate(&s, Z_SYNC_FLUSH);
375         if (res < 0)
376             return -1;
377     }
378
379     s.next_in   = b->sl_begin;
380     s.avail_in  = b->sl_end - b->sl_begin;
381     s.next_out  = buf;
382     s.avail_out = *buf_size;
383     res = deflate(&s, Z_FINISH);
384     deflateEnd(&s);
385     *buf_size -= s.avail_out;
386     if (res != Z_STREAM_END)
387         return -1;
388     return 0;
389 }
390
391 static int encode_bgr(Block * b, const uint8_t * src, int stride)
392 {
393     int i;
394     uint8_t *ptr = b->enc;
395     for (i = 0; i < b->start; i++)
396         memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
397     b->sl_begin = ptr + i * b->width * 3;
398     for (; i < b->start + b->len; i++)
399         memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
400     b->sl_end = ptr + i * b->width * 3;
401     for (; i < b->height; i++)
402         memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
403     b->enc_size = ptr + i * b->width * 3 - b->enc;
404     return b->enc_size;
405 }
406
407 static inline unsigned pixel_color15(const uint8_t * src)
408 {
409     return (src[0] >> 3) | ((src[1] & 0xf8) << 2) | ((src[2] & 0xf8) << 7);
410 }
411
412 static inline unsigned int chroma_diff(unsigned int c1, unsigned int c2)
413 {
414 #define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
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 ABSDIFF(t1, t2) + ABSDIFF(c1 & 0x000000ff, c2 & 0x000000ff) +
420         ABSDIFF((c1 & 0x0000ff00) >> 8 , (c2 & 0x0000ff00) >> 8) +
421         ABSDIFF((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 #ifndef FLASHSV2_DUMB
737 static const double block_size_fraction = 1.0 / 300;
738 static const double use15_7_threshold = 8192;
739 static const double color15_7_factor = 100;
740 #endif
741 static int optimum_block_width(FlashSV2Context * s)
742 {
743 #ifndef FLASHSV2_DUMB
744     double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
745     double width = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_width;
746     int pwidth = ((int) width);
747     return FFCLIP(pwidth & ~15, 256, 16);
748 #else
749     return 64;
750 #endif
751 }
752
753 static int optimum_block_height(FlashSV2Context * s)
754 {
755 #ifndef FLASHSV2_DUMB
756     double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
757     double height = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_height;
758     int pheight = ((int) height);
759     return FFCLIP(pheight & ~15, 256, 16);
760 #else
761     return 64;
762 #endif
763 }
764
765 static int optimum_use15_7(FlashSV2Context * s)
766 {
767 #ifndef FLASHSV2_DUMB
768     double ideal = ((double)(s->avctx->bit_rate * s->avctx->time_base.den * s->avctx->ticks_per_frame)) /
769         ((double) s->avctx->time_base.num) * s->avctx->frame_number;
770     if (ideal + use15_7_threshold < s->total_bits) {
771         return 1;
772     } else {
773         return 0;
774     }
775 #else
776     return s->avctx->global_quality == 0;
777 #endif
778 }
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_array(s->frame_blocks, s->rows, s->cols * sizeof(Block));
811             s->key_blocks = av_realloc_array(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 *p, int *got_packet)
853 {
854     FlashSV2Context *const s = avctx->priv_data;
855     int res;
856     int keyframe = 0;
857
858     if ((res = ff_alloc_packet2(avctx, pkt, s->frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
859         return res;
860
861     /* First frame needs to be a keyframe */
862     if (avctx->frame_number == 0)
863         keyframe = 1;
864
865     /* Check the placement of keyframes */
866     if (avctx->gop_size > 0) {
867         if (avctx->frame_number >= s->last_key_frame + avctx->gop_size)
868             keyframe = 1;
869     }
870
871     if (!keyframe
872         && avctx->frame_number > s->last_key_frame + avctx->keyint_min) {
873         recommend_keyframe(s, &keyframe);
874         if (keyframe)
875             av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %d\n", avctx->frame_number);
876     }
877
878     if (keyframe) {
879         res = reconfigure_at_keyframe(s, p->data[0], p->linesize[0]);
880         if (res)
881             return res;
882     }
883
884     if (s->use15_7)
885         s->dist = optimum_dist(s);
886
887     res = write_bitstream(s, p->data[0], p->linesize[0], pkt->data, pkt->size, keyframe);
888
889     if (keyframe) {
890         new_key_frame(s);
891         s->last_key_frame = avctx->frame_number;
892         pkt->flags |= AV_PKT_FLAG_KEY;
893         av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number);
894     }
895
896     pkt->size = res;
897     *got_packet = 1;
898
899     return 0;
900 }
901
902 static av_cold int flashsv2_encode_end(AVCodecContext * avctx)
903 {
904     FlashSV2Context *s = avctx->priv_data;
905
906     cleanup(s);
907
908     return 0;
909 }
910
911 AVCodec ff_flashsv2_encoder = {
912     .name           = "flashsv2",
913     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"),
914     .type           = AVMEDIA_TYPE_VIDEO,
915     .id             = AV_CODEC_ID_FLASHSV2,
916     .priv_data_size = sizeof(FlashSV2Context),
917     .init           = flashsv2_encode_init,
918     .encode2        = flashsv2_encode_frame,
919     .close          = flashsv2_encode_end,
920     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
921     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
922 };