55 #define HAS_IFRAME_IMAGE 0x02
56 #define HAS_PALLET_INFO 0x01
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
114 #ifndef FLASHSV2_DUMB
145 memset(blocks, 0,
s->cols *
s->rows *
sizeof(*blocks));
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) ?
151 s->image_width - col *
s->block_width;
153 b->height = (row < s->rows - 1) ?
155 s->image_height - row *
s->block_height;
161 encbuf +=
b->width *
b->height * 3;
162 databuf = databuf ? databuf +
b->width *
b->height * 6 :
NULL;
169 #ifndef FLASHSV2_DUMB
170 s->diff_blocks = 0.1;
174 s->raw_size =
s->comp_size =
s->uncomp_size = 10;
180 s->block_width = block_width;
181 s->block_height = block_height;
182 s->rows = (
s->image_height +
s->block_height - 1) /
s->block_height;
183 s->cols = (
s->image_width +
s->block_width - 1) /
s->block_width;
184 if (
s->rows *
s->cols >
s->blocks_size /
sizeof(
Block)) {
187 if (!
s->frame_blocks || !
s->key_blocks) {
191 s->blocks_size =
s->rows *
s->cols *
sizeof(
Block);
196 av_fast_malloc(&
s->blockbuffer, &
s->blockbuffer_size, block_width * block_height * 6);
197 if (!
s->blockbuffer) {
215 if (
s->comp < 0 ||
s->comp > 9) {
217 "Compression level should be 0-9, not %d\n",
s->comp);
222 if ((avctx->
width > 4095) || (avctx->
height > 4095)) {
224 "Input dimensions too large, input must be max 4095x4095 !\n");
229 "Input dimensions too small, input must be at least 16x16 !\n");
237 s->last_key_frame = 0;
239 s->image_width = avctx->
width;
240 s->image_height = avctx->
height;
242 s->frame_size =
s->image_width *
s->image_height * 3;
249 if (!
s->encbuffer || !
s->keybuffer || !
s->databuffer
250 || !
s->current_frame || !
s->key_frame) {
256 #ifndef FLASHSV2_DUMB
260 s->use_custom_palette = 0;
261 s->palette_type = -1;
269 memcpy(
s->key_blocks,
s->frame_blocks,
s->blocks_size);
270 memcpy(
s->key_frame,
s->current_frame,
s->frame_size);
272 for (
i = 0;
i <
s->rows *
s->cols;
i++) {
273 s->key_blocks[
i].enc += (
s->keybuffer -
s->encbuffer);
274 s->key_blocks[
i].sl_begin = 0;
275 s->key_blocks[
i].sl_end = 0;
276 s->key_blocks[
i].data = 0;
278 memcpy(
s->keybuffer,
s->encbuffer,
s->frame_size);
299 put_bits(&pb, 4, (
s->block_width >> 4) - 1);
301 put_bits(&pb, 4, (
s->block_height >> 4) - 1);
307 buf[buf_pos++] =
s->flags;
322 unsigned block_size =
b->data_size;
330 if (buf_size < block_size + 2)
333 buf[buf_pos++] = block_size >> 8;
334 buf[buf_pos++] = block_size;
339 buf[buf_pos++] =
b->flags;
342 buf[buf_pos++] = (
b->start);
343 buf[buf_pos++] = (
b->len);
348 buf[buf_pos++] = (
b->col);
349 buf[buf_pos++] = (
b->row);
352 memcpy(buf + buf_pos,
b->data,
b->data_size);
354 buf_pos +=
b->data_size;
361 int res = compress2(buf, buf_size,
b->sl_begin,
b->sl_end -
b->sl_begin,
comp);
362 return res == Z_OK ? 0 : -1;
366 int *buf_size,
int comp)
373 res = deflateInit(&
s,
comp);
377 s.next_in = prime->
enc;
379 while (
s.avail_in > 0) {
381 s.avail_out = *buf_size;
387 s.next_in =
b->sl_begin;
388 s.avail_in =
b->sl_end -
b->sl_begin;
390 s.avail_out = *buf_size;
393 *buf_size -=
s.avail_out;
394 if (res != Z_STREAM_END)
403 for (
i = 0;
i <
b->start;
i++)
404 memcpy(ptr +
i *
b->width * 3,
src +
i *
stride,
b->width * 3);
405 b->sl_begin = ptr +
i *
b->width * 3;
406 for (;
i <
b->start +
b->len;
i++)
407 memcpy(ptr +
i *
b->width * 3,
src +
i *
stride,
b->width * 3);
408 b->sl_end = ptr +
i *
b->width * 3;
409 for (;
i <
b->height;
i++)
410 memcpy(ptr +
i *
b->width * 3,
src +
i *
stride,
b->width * 3);
411 b->enc_size = ptr +
i *
b->width * 3 -
b->enc;
417 return (
src[0] >> 3) | ((
src[1] & 0xf8) << 2) | ((
src[2] & 0xf8) << 7);
422 #define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
424 unsigned int t1 = (
c1 & 0x000000ff) + ((
c1 & 0x0000ff00) >> 8) + ((
c1 & 0x00ff0000) >> 16);
425 unsigned int t2 = (
c2 & 0x000000ff) + ((
c2 & 0x0000ff00) >> 8) + ((
c2 & 0x00ff0000) >> 16);
428 ABSDIFF((
c1 & 0x0000ff00) >> 8 , (
c2 & 0x0000ff00) >> 8) +
429 ABSDIFF((
c1 & 0x00ff0000) >> 16, (
c2 & 0x00ff0000) >> 16);
434 return palette->
index[c15];
439 int i,
min = 0x7fffffff;
441 for (
i = 0;
i < 128;
i++) {
454 return (
src[0]) | (
src[1] << 8) | (
src[2] << 16);
465 if (dist + d15 >= d7) {
469 dest[0] = 0x80 | (c15 >> 8);
470 dest[1] = c15 & 0xff;
478 unsigned int bgr, c15,
index;
479 for (
r = 4;
r < 256;
r += 8) {
480 for (
g = 4;
g < 256;
g += 8) {
481 for (
b = 4;
b < 256;
b += 8) {
482 bgr =
b | (
g << 8) | (
r << 16);
483 c15 = (
b >> 3) | ((
g & 0xf8) << 2) | ((
r & 0xf8) << 7);
494 0x00000000, 0x00333333, 0x00666666, 0x00999999, 0x00CCCCCC, 0x00FFFFFF,
495 0x00330000, 0x00660000, 0x00990000, 0x00CC0000, 0x00FF0000, 0x00003300,
496 0x00006600, 0x00009900, 0x0000CC00, 0x0000FF00, 0x00000033, 0x00000066,
497 0x00000099, 0x000000CC, 0x000000FF, 0x00333300, 0x00666600, 0x00999900,
498 0x00CCCC00, 0x00FFFF00, 0x00003333, 0x00006666, 0x00009999, 0x0000CCCC,
499 0x0000FFFF, 0x00330033, 0x00660066, 0x00990099, 0x00CC00CC, 0x00FF00FF,
500 0x00FFFF33, 0x00FFFF66, 0x00FFFF99, 0x00FFFFCC, 0x00FF33FF, 0x00FF66FF,
501 0x00FF99FF, 0x00FFCCFF, 0x0033FFFF, 0x0066FFFF, 0x0099FFFF, 0x00CCFFFF,
502 0x00CCCC33, 0x00CCCC66, 0x00CCCC99, 0x00CCCCFF, 0x00CC33CC, 0x00CC66CC,
503 0x00CC99CC, 0x00CCFFCC, 0x0033CCCC, 0x0066CCCC, 0x0099CCCC, 0x00FFCCCC,
504 0x00999933, 0x00999966, 0x009999CC, 0x009999FF, 0x00993399, 0x00996699,
505 0x0099CC99, 0x0099FF99, 0x00339999, 0x00669999, 0x00CC9999, 0x00FF9999,
506 0x00666633, 0x00666699, 0x006666CC, 0x006666FF, 0x00663366, 0x00669966,
507 0x0066CC66, 0x0066FF66, 0x00336666, 0x00996666, 0x00CC6666, 0x00FF6666,
508 0x00333366, 0x00333399, 0x003333CC, 0x003333FF, 0x00336633, 0x00339933,
509 0x0033CC33, 0x0033FF33, 0x00663333, 0x00993333, 0x00CC3333, 0x00FF3333,
510 0x00003366, 0x00336600, 0x00660033, 0x00006633, 0x00330066, 0x00663300,
511 0x00336699, 0x00669933, 0x00993366, 0x00339966, 0x00663399, 0x00996633,
512 0x006699CC, 0x0099CC66, 0x00CC6699, 0x0066CC99, 0x009966CC, 0x00CC9966,
513 0x0099CCFF, 0x00CCFF99, 0x00FF99CC, 0x0099FFCC, 0x00CC99FF, 0x00FFCC99,
514 0x00111111, 0x00222222, 0x00444444, 0x00555555, 0x00AAAAAA, 0x00BBBBBB,
515 0x00DDDDDD, 0x00EEEEEE
537 for (x = 0; x <
width; x++) {
548 for (
i = 0;
i <
b->start;
i++)
551 for (;
i <
b->start +
b->len;
i++)
554 for (;
i <
b->height;
i++)
556 b->enc_size = ptr -
b->enc;
562 int dist,
int keyframe)
564 unsigned buf_size =
b->width *
b->height * 6;
575 b->data_size = buf_size;
585 if (buf_size < b->data_size) {
586 b->data_size = buf_size;
587 memcpy(
b->data, buf, buf_size);
600 if (memcmp(
src,
frame,
b->width * 3) != 0) {
603 #ifndef FLASHSV2_DUMB
607 if (memcmp(
src,
key,
b->width * 3) != 0) {
610 b->len = y + 1 -
b->start;
618 int sl, rsl, col,
pos, possl;
620 for (sl =
s->image_height - 1; sl >= 0; sl--) {
621 for (col = 0; col <
s->cols; col++) {
622 rsl =
s->image_height - sl - 1;
623 b =
s->frame_blocks + col + rsl /
s->block_height *
s->cols;
624 possl =
stride * sl + col *
s->block_width * 3;
625 pos =
s->image_width * rsl * 3 + col *
s->block_width * 3;
627 s->key_frame +
pos, rsl %
s->block_height, keyframe);
630 #ifndef FLASHSV2_DUMB
631 s->tot_lines +=
s->image_height *
s->cols;
641 for (row = 0; row <
s->rows; row++) {
642 for (col = 0; col <
s->cols; col++) {
643 b =
s->frame_blocks + (row *
s->cols + col);
644 prev =
s->key_blocks + (row *
s->cols + col);
649 }
else if (!
b->dirty) {
654 }
else if (
b->start != 0 ||
b->len !=
b->height) {
657 data =
s->current_frame +
s->image_width * 3 *
s->block_height * row +
s->block_width * col * 3;
659 #ifndef FLASHSV2_DUMB
662 s->comp_size +=
b->data_size;
663 s->uncomp_size +=
b->enc_size;
669 #ifndef FLASHSV2_DUMB
670 s->raw_size +=
s->image_width *
s->image_height * 3;
671 s->tot_blocks +=
s->rows *
s->cols;
679 int row, col, buf_pos = 0,
len;
681 for (row = 0; row <
s->rows; row++) {
682 for (col = 0; col <
s->cols; col++) {
683 b =
s->frame_blocks + row *
s->cols + col;
685 b->start =
b->len =
b->dirty = 0;
695 uint8_t * buf,
int buf_size,
int keyframe)
716 #ifndef FLASHSV2_DUMB
717 s->total_bits += ((double) buf_pos) * 8.0;
725 #ifndef FLASHSV2_DUMB
726 double block_ratio, line_ratio, enc_ratio, comp_ratio, data_ratio;
727 if (
s->avctx->gop_size > 0) {
728 block_ratio =
s->diff_blocks /
s->tot_blocks;
729 line_ratio =
s->diff_lines /
s->tot_lines;
730 enc_ratio =
s->uncomp_size /
s->raw_size;
731 comp_ratio =
s->comp_size /
s->uncomp_size;
732 data_ratio =
s->comp_size /
s->raw_size;
734 if ((block_ratio >= 0.5 && line_ratio / block_ratio <= 0.5) || line_ratio >= 0.95) {
744 #ifndef FLASHSV2_DUMB
745 static const double block_size_fraction = 1.0 / 300;
746 static const double use15_7_threshold = 8192;
747 static const double color15_7_factor = 100;
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 width = block_size_fraction * sqrt(0.5 * save *
s->rows *
s->cols) *
s->image_width;
755 return FFCLIP(pwidth & ~15, 256, 16);
763 #ifndef FLASHSV2_DUMB
764 double save = (1-pow(
s->diff_lines/
s->diff_blocks/
s->block_height, 0.5)) *
s->comp_size/
s->tot_blocks;
765 double height = block_size_fraction * sqrt(0.5 * save *
s->rows *
s->cols) *
s->image_height;
767 return FFCLIP(pheight & ~15, 256, 16);
775 #ifndef FLASHSV2_DUMB
776 double ideal = ((double)(
s->avctx->bit_rate *
s->avctx->time_base.den *
s->avctx->ticks_per_frame)) /
777 ((
double)
s->avctx->time_base.num) *
s->avctx->frame_number;
778 if (ideal + use15_7_threshold < s->total_bits) {
784 return s->avctx->global_quality == 0;
790 #ifndef FLASHSV2_DUMB
792 s->avctx->bit_rate *
s->avctx->time_base.den *
793 s->avctx->ticks_per_frame;
794 int dist = pow((
s->total_bits / ideal) * color15_7_factor, 3);
806 int update_palette = 0;
811 if (block_width !=
s->block_width || block_height !=
s->block_height) {
819 if ((
s->use_custom_palette &&
s->palette_type != 1) || update_palette) {
825 }
else if (!
s->use_custom_palette &&
s->palette_type != 0) {
841 const AVFrame *p,
int *got_packet)