38 #define COLORS_PER_TABLE 256
56 #define ADVANCE_BLOCK(pixel_ptr, row_ptr, nb_blocks) \
58 for (int block = 0; block < nb_blocks && pixel_ptr && row_ptr; block++) { \
60 if (pixel_ptr - row_ptr >= width) \
62 row_ptr += stride * 4; \
63 pixel_ptr = row_ptr; \
70 const uint8_t *aa =
a, *bb =
b;
76 uint8_t *distinct_values,
81 distinct_values[0] = block_values[0];
82 for (
int i = 1;
i <
size;
i++) {
83 if (block_values[
i] != block_values[
i-1]) {
84 distinct_values[n] = block_values[
i];
92 #define CACHE_PAIR(x) \
93 (s->color_pairs[i][0] == distinct_values[x] || \
94 s->color_pairs[i][1] == distinct_values[x])
96 #define CACHE_QUAD(x) \
97 (s->color_quads[i][0] == distinct_values[x] || \
98 s->color_quads[i][1] == distinct_values[x] || \
99 s->color_quads[i][2] == distinct_values[x] || \
100 s->color_quads[i][3] == distinct_values[x])
102 #define CACHE_OCTET(x) \
103 (s->color_octets[i][0] == distinct_values[x] || \
104 s->color_octets[i][1] == distinct_values[x] || \
105 s->color_octets[i][2] == distinct_values[x] || \
106 s->color_octets[i][3] == distinct_values[x] || \
107 s->color_octets[i][4] == distinct_values[x] || \
108 s->color_octets[i][5] == distinct_values[x] || \
109 s->color_octets[i][6] == distinct_values[x] || \
110 s->color_octets[i][7] == distinct_values[x])
115 const uint8_t *src_pixels = (
const uint8_t *)
frame->data[0];
117 const uint8_t *prev_pixels = (
const uint8_t *)
s->prev_frame->data[0];
118 uint8_t *distinct_values =
s->distinct_values;
119 const uint8_t *pixel_ptr, *row_ptr;
121 uint8_t block_values[16];
122 int block_counter = 0;
123 int color_pair_index = 0;
124 int color_quad_index = 0;
125 int color_octet_index = 0;
126 int color_table_index;
129 memset(
s->color_pairs, 0,
sizeof(
s->color_pairs));
130 memset(
s->color_quads, 0,
sizeof(
s->color_quads));
131 memset(
s->color_octets, 0,
sizeof(
s->color_octets));
134 total_blocks = ((
frame->width + 3) / 4) * ((
frame->height + 3) / 4);
136 pixel_ptr = row_ptr = src_pixels;
138 while (block_counter < total_blocks) {
139 const uint8_t *xpixel_ptr = pixel_ptr;
140 const uint8_t *xrow_ptr = row_ptr;
141 int intra_skip_blocks = 0;
142 int inter_skip_blocks = 0;
143 int coded_distinct = 0;
144 int coded_blocks = 0;
149 while (prev_pixels &&
s->key_frame == 0 && block_counter + inter_skip_blocks < total_blocks) {
152 for (
int y = 0; y < 4; y++) {
153 const ptrdiff_t
offset = pixel_ptr - src_pixels;
154 const uint8_t *prev_pixel_ptr = prev_pixels +
offset;
164 if (inter_skip_blocks >= 256)
171 pixel_ptr = xpixel_ptr;
174 while (block_counter > 0 && block_counter + intra_skip_blocks < total_blocks) {
175 const ptrdiff_t
offset = pixel_ptr - src_pixels;
178 const int ny = sx < 4 ? sy - 4 : sy;
179 const int nx = sx < 4 ?
width - 4 : sx - 4;
180 const uint8_t *old_pixel_ptr = src_pixels + nx + ny *
stride;
183 for (
int y = 0; y < 4; y++) {
192 if (intra_skip_blocks >= 256)
198 pixel_ptr = xpixel_ptr;
201 while (block_counter + coded_blocks < total_blocks && coded_blocks < 256) {
202 for (
int y = 0; y < 4; y++)
203 memcpy(block_values + y * 4, pixel_ptr + y *
stride, 4);
207 if (coded_blocks == 0) {
208 memcpy(distinct_values,
s->next_distinct_values,
sizeof(
s->distinct_values));
209 s->nb_distinct =
s->next_nb_distinct;
211 if (
s->next_nb_distinct !=
s->nb_distinct ||
212 memcmp(distinct_values,
s->next_distinct_values,
s->nb_distinct)) {
216 s->mono_value = block_values[0];
218 coded_distinct =
s->nb_distinct;
221 if (coded_distinct > 1 && coded_blocks >= 16)
225 pixel_ptr = xpixel_ptr;
228 blocks = coded_blocks;
229 distinct = coded_distinct;
231 if (intra_skip_blocks > 0 && intra_skip_blocks >= inter_skip_blocks &&
232 intra_skip_blocks > 0) {
234 blocks = intra_skip_blocks;
237 if (intra_skip_blocks > 16 && intra_skip_blocks >= inter_skip_blocks &&
238 intra_skip_blocks > 0) {
240 blocks = intra_skip_blocks;
243 if (inter_skip_blocks > 0 && inter_skip_blocks > intra_skip_blocks &&
244 inter_skip_blocks > 0) {
246 blocks = inter_skip_blocks;
249 if (inter_skip_blocks > 16 && inter_skip_blocks > intra_skip_blocks &&
250 inter_skip_blocks > 0) {
252 blocks = inter_skip_blocks;
258 bytestream2_put_byte(pb, 0x60 | (blocks - 1));
260 bytestream2_put_byte(pb, 0x70);
261 bytestream2_put_byte(pb, blocks - 1);
263 bytestream2_put_byte(pb,
s->mono_value);
276 if (cache_index >= 0) {
277 bytestream2_put_byte(pb, 0x90 | (blocks - 1));
278 bytestream2_put_byte(pb, cache_index);
279 color_table_index = cache_index;
281 bytestream2_put_byte(pb, 0x80 | (blocks - 1));
283 color_table_index = color_pair_index;
285 s->color_pairs[color_table_index][
i] = distinct_values[
i];
286 bytestream2_put_byte(pb, distinct_values[
i]);
291 color_pair_index = 0;
294 for (
int i = 0;
i < blocks;
i++) {
295 uint8_t
value =
s->color_pairs[color_table_index][1];
299 for (
int y = 0; y < 4; y++) {
300 for (
int x = 0; x < 4; x++) {
306 bytestream2_put_be16(pb,
flags);
324 if (cache_index >= 0) {
325 bytestream2_put_byte(pb, 0xB0 | (blocks - 1));
326 bytestream2_put_byte(pb, cache_index);
327 color_table_index = cache_index;
329 bytestream2_put_byte(pb, 0xA0 | (blocks - 1));
331 color_table_index = color_quad_index;
333 s->color_quads[color_table_index][
i] = distinct_values[
i];
334 bytestream2_put_byte(pb, distinct_values[
i]);
339 color_quad_index = 0;
342 for (
int i = 0;
i < blocks;
i++) {
347 for (
int k = 0; k < 4; k++)
348 quad[k] =
s->color_quads[color_table_index][k];
350 for (
int y = 0; y < 4; y++) {
351 for (
int x = 0; x < 4; x++) {
367 bytestream2_put_be32(pb,
flags);
391 if (cache_index >= 0) {
392 bytestream2_put_byte(pb, 0xD0 | (blocks - 1));
393 bytestream2_put_byte(pb, cache_index);
394 color_table_index = cache_index;
396 bytestream2_put_byte(pb, 0xC0 | (blocks - 1));
398 color_table_index = color_octet_index;
400 s->color_octets[color_table_index][
i] = distinct_values[
i];
401 bytestream2_put_byte(pb, distinct_values[
i]);
406 color_octet_index = 0;
409 for (
int i = 0;
i < blocks;
i++) {
414 for (
int k = 0; k < 8; k++)
415 octet[k] =
s->color_octets[color_table_index][k];
417 for (
int y = 0; y < 4; y++) {
418 for (
int x = 0; x < 4; x++) {
434 bytestream2_put_be16(pb, ((
flags >> 32) & 0xFFF0) | ((
flags >> 8) & 0xF));
435 bytestream2_put_be16(pb, ((
flags >> 20) & 0xFFF0) | ((
flags >> 4) & 0xF));
436 bytestream2_put_be16(pb, ((
flags >> 8) & 0xFFF0) | ((
flags >> 0) & 0xF));
442 bytestream2_put_byte(pb, 0xE0 | (blocks - 1));
443 for (
int i = 0;
i < blocks;
i++) {
444 for (
int y = 0; y < 4; y++) {
445 for (
int x = 0; x < 4; x++)
446 bytestream2_put_byte(pb, pixel_ptr[x + y *
stride]);
453 bytestream2_put_byte(pb, 0x20 | (blocks - 1));
457 bytestream2_put_byte(pb, 0x30);
458 bytestream2_put_byte(pb, blocks - 1);
462 bytestream2_put_byte(pb, 0x00 | (blocks - 1));
466 bytestream2_put_byte(pb, 0x10);
467 bytestream2_put_byte(pb, blocks - 1);
472 block_counter += blocks;
502 if (avctx->
gop_size == 0 || !
s->prev_frame->data[0] ||
511 bytestream2_put_be32(&pb, 0x00);