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
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.
67
74
80
85
94
97
102
104
106
108
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
127
129 {
136
139 }
140
143 {
144 int row, col;
146 for (col = 0; col < s->
cols; col++) {
147 for (row = 0; row < s->
rows; row++) {
148 b = blocks + (col + row * s->
cols);
152
153 b->
height = (row < s->rows - 1) ?
156
162 databuf += !databuf ? 0 : b->
width * b->
height * 6;
163 }
164 }
165 }
166
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
179 {
181
183
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)) {
196 "Input dimensions too large, input must be max 4096x4096 !\n");
197 return -1;
198 }
201 "Input dimensions too small, input must be at least 16x16 !\n");
202 return -1;
203 }
204
206 return -1;
207
208
210
213
216
221
224
227
235
238
242 #ifndef FLASHSV2_DUMB
243 s->total_bits = 1;
244 #endif
245
247 s->
palette_type = -1;
// so that the palette will be generated in reconfigure_at_keyframe
248
254 return -1;
255 }
256
257 return 0;
258 }
259
261 {
262 int i;
265
266 for (i = 0; i < s->
rows * s->
cols; i++) {
271 }
273
274 return 0;
275 }
276
278 {
279 //this isn't implemented yet! Default palette only!
280 return -1;
281 }
282
284 {
287
288 if (buf_size < 5)
289 return -1;
290
292
297
299 buf_pos = 4;
300
301 buf[buf_pos++] = s->
flags;
302
305 if (len < 0)
306 return -1;
308 }
309
310 return buf_pos;
311 }
312
314 {
315 int buf_pos = 0;
317
319 block_size += 2;
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
336 buf[buf_pos++] = (b->
start);
337 buf[buf_pos++] = (b->
len);
338 }
339
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
347
349
350 return buf_pos;
351 }
352
354 {
356 return res == Z_OK ? 0 : -1;
357 }
358
360 int *buf_size,
int comp)
361 {
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;
373 while (s.avail_in > 0) {
375 s.avail_out = *buf_size;
376 res = deflate(&s, Z_SYNC_FLUSH);
377 if (res < 0)
378 return -1;
379 }
380
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
394 {
395 int i;
397 for (i = 0; i < b->
start; i++)
398 memcpy(ptr + i * b->
width * 3, src + i * stride, b->
width * 3);
401 memcpy(ptr + i * b->
width * 3, src + i * stride, b->
width * 3);
403 for (; i < b->
height; i++)
404 memcpy(ptr + i * b->
width * 3, src + i * stride, b->
width * 3);
407 }
408
410 {
411 return (src[0] >> 3) | ((src[1] & 0xf8) << 2) | ((src[2] & 0xf8) << 7);
412 }
413
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
425 {
426 return palette->
index[c15];
427 }
428
430 {
431 int i,
min = 0x7fffffff;
432 int minc = -1;
433 for (i = 0; i < 128; i++) {
436 if (diff < min) {
438 minc = i;
439 }
440 }
441 return minc;
442 }
443
445 {
446 return (src[0]) | (src[1] << 8) | (src[2] << 16);
447 }
448
450 int dist)
451 {
457 if (dist + d15 >= d7) {
459 return 1;
460 } else {
461 dest[0] = 0x80 | (c15 >> 8);
462 dest[1] = c15 & 0xff;
463 return 2;
464 }
465 }
466
468 {
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);
477
479 }
480 }
481 }
482 return 0;
483 }
484
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
511 {
514
516 }
517
520 {
521 //this isn't implemented yet! Default palette only!
522 return -1;
523 }
524
527 {
529 for (x = 0; x <
width; x++) {
531 }
533 }
534
537 {
538 int i;
540 for (i = 0; i < b->
start; i++)
546 for (; i < b->
height; i++)
550 }
551
554 int dist, int keyframe)
555 {
559
562 } else {
564 }
565
569 if (res)
571
572 if (!keyframe) {
574 if (res)
576
577 if (buf_size < b->data_size) {
579 memcpy(b->
data, buf, buf_size);
581 }
582 }
583 } else {
585 }
586 return 0;
587 }
588
591 {
592 if (memcmp(src, frame, b->
width * 3) != 0) {
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) {
603 }
604 return 0;
605 }
606
608 int keyframe)
609 {
610 int sl, rsl, col, pos, possl;
613 for (col = 0; col < s->
cols; col++) {
620 }
621 }
622 #ifndef FLASHSV2_DUMB
624 #endif
625 return 0;
626 }
627
629 {
633 for (row = 0; row < s->
rows; row++) {
634 for (col = 0; col < s->
cols; col++) {
638 if (keyframe) {
641 }
else if (!b->
dirty) {
645 continue;
648 }
651 #ifndef FLASHSV2_DUMB
653 s->diff_blocks++;
656 #endif
657 if (res)
659 }
660 }
661 #ifndef FLASHSV2_DUMB
664 #endif
665 return 0;
666 }
667
669 int buf_size)
670 {
671 int row, col, buf_pos = 0,
len;
673 for (row = 0; row < s->
rows; row++) {
674 for (col = 0; col < s->
cols; col++) {
681 }
682 }
683 return buf_pos;
684 }
685
688 {
690
692 if (res)
695 if (res)
697
699 if (res < 0) {
701 } else {
703 }
705 if (res < 0)
708 #ifndef FLASHSV2_DUMB
709 s->total_bits += ((double) buf_pos) * 8.0;
710 #endif
711
712 return buf_pos;
713 }
714
716 {
717 #ifndef FLASHSV2_DUMB
718 double block_ratio, line_ratio, enc_ratio, comp_ratio, data_ratio;
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
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;
742 int pwidth = ((int)
width);
743 return FFCLIP(pwidth & ~15, 256, 16);
744 #else
745 return 64;
746 #endif
747 }
748
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;
754 int pheight = ((int)
height);
755 return FFCLIP(pheight & ~15, 256, 16);
756 #else
757 return 64;
758 #endif
759 }
760
762
764 {
765 #ifndef FLASHSV2_DUMB
768 if (ideal + use15_7_threshold < s->total_bits) {
769 return 1;
770 } else {
771 return 0;
772 }
773 #else
775 #endif
776 }
777
779
781 {
782 #ifndef FLASHSV2_DUMB
783 double ideal =
788 return dist;
789 #else
790 return 15;
791 #endif
792 }
793
794
797 {
798 int update_palette = 0;
802
805
814 return -1;
815 }
817 }
820
825 }
826 }
827
832 if (res)
838 if (res)
842 }
843 }
844
845
847
848 return 0;
849 }
850
852 const AVFrame *pict,
int *got_packet)
853 {
857 int keyframe = 0;
858
859 *p = *pict;
860
863
864 /* First frame needs to be a keyframe */
866 keyframe = 1;
867
868 /* Check the placement of keyframes */
871 keyframe = 1;
872 }
873
874 if (!keyframe
877 if (keyframe)
879 }
880
881 if (keyframe) {
883 if (res)
885 }
886
889
891
892 if (keyframe) {
899 } else {
902 }
903
905
907 *got_packet = 1;
908
909 return 0;
910 }
911
913 {
915
917
918 return 0;
919 }
920
931 };