1 /*
2 * QuickTime Graphics (SMC) Video Encoder
3 * Copyright (c) 2021 The FFmpeg project
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 smcenc.c
24 * QT SMC Video Encoder by Paul B. Mahol
25 */
26
28
33
37
38 #define COLORS_PER_TABLE 256
39
42
48
52
55
56 #define ADVANCE_BLOCK(pixel_ptr, row_ptr, nb_blocks) \
57 { \
58 for (int block = 0; block < nb_blocks && pixel_ptr && row_ptr; block++) { \
59 pixel_ptr += 4; \
60 cur_x += 4; \
61 if (pixel_ptr - row_ptr >= width) \
62 { \
63 row_ptr += stride * 4; \
64 pixel_ptr = row_ptr; \
65 cur_y += 4; \
66 cur_x = 0; \
67 } \
68 } \
69 }
70
72 {
73 const uint8_t *aa =
a, *bb =
b;
74
76 }
77
79 uint8_t *distinct_values,
81 {
82 int n = 1;
83
84 distinct_values[0] = block_values[0];
85 for (
int i = 1;
i <
size;
i++) {
86 if (block_values[
i] != block_values[
i-1]) {
87 distinct_values[n] = block_values[
i];
88 n++;
89 }
90 }
91
92 return n;
93 }
94
95 #define CACHE_PAIR(x) \
96 (s->color_pairs[i][0] == distinct_values[x] || \
97 s->color_pairs[i][1] == distinct_values[x])
98
99 #define CACHE_QUAD(x) \
100 (s->color_quads[i][0] == distinct_values[x] || \
101 s->color_quads[i][1] == distinct_values[x] || \
102 s->color_quads[i][2] == distinct_values[x] || \
103 s->color_quads[i][3] == distinct_values[x])
104
105 #define CACHE_OCTET(x) \
106 (s->color_octets[i][0] == distinct_values[x] || \
107 s->color_octets[i][1] == distinct_values[x] || \
108 s->color_octets[i][2] == distinct_values[x] || \
109 s->color_octets[i][3] == distinct_values[x] || \
110 s->color_octets[i][4] == distinct_values[x] || \
111 s->color_octets[i][5] == distinct_values[x] || \
112 s->color_octets[i][6] == distinct_values[x] || \
113 s->color_octets[i][7] == distinct_values[x])
114
117 {
118 const uint8_t *src_pixels = (
const uint8_t *)
frame->data[0];
120 const uint8_t *prev_pixels = (
const uint8_t *)
s->prev_frame->data[0];
121 const ptrdiff_t prev_stride =
s->prev_frame->linesize[0];
122 uint8_t *distinct_values =
s->distinct_values;
123 const uint8_t *pixel_ptr, *row_ptr;
126 int block_counter = 0;
127 int color_pair_index = 0;
128 int color_quad_index = 0;
129 int color_octet_index = 0;
130 int color_table_index; /* indexes to color pair, quad, or octet tables */
131 int total_blocks;
132 int cur_y = 0;
133 int cur_x = 0;
134
135 /* Number of 4x4 blocks in frame. */
136 total_blocks = ((
width + 3) / 4) * ((
height + 3) / 4);
137
138 pixel_ptr = row_ptr = src_pixels;
139
140 while (block_counter < total_blocks) {
141 const uint8_t *xpixel_ptr = pixel_ptr;
142 const uint8_t *xrow_ptr = row_ptr;
143 int intra_skip_blocks = 0;
144 int inter_skip_blocks = 0;
145 int coded_distinct = 0;
146 int coded_blocks = 0;
147 int cache_index;
148 int distinct = 0;
149 int blocks = 0;
150 int frame_y = cur_y;
151 int frame_x = cur_x;
152
153 while (prev_pixels &&
s->key_frame == 0 && block_counter + inter_skip_blocks < total_blocks) {
157
158 for (int y = 0; y < y_size; y++) {
159 const uint8_t *prev_pixel_ptr = prev_pixels + (y + cur_y) * prev_stride + cur_x;
160
161 compare |= !!memcmp(prev_pixel_ptr, pixel_ptr + y *
stride, x_size);
163 break;
164 }
165
167 break;
168
169 inter_skip_blocks++;
170 if (inter_skip_blocks >= 256)
171 break;
172
174 }
175
176 pixel_ptr = xpixel_ptr;
177 row_ptr = xrow_ptr;
178 cur_y = frame_y;
179 cur_x = frame_x;
180
181 while (block_counter > 0 && block_counter + intra_skip_blocks < total_blocks) {
184 const ptrdiff_t
offset = xpixel_ptr - src_pixels;
187 const int ny = sx < 4 ?
FFMAX(sy - 4, 0) : sy;
189 const uint8_t *old_pixel_ptr = src_pixels + nx + ny *
stride;
191
192 for (int y = 0; y < y_size; y++) {
195 break;
196 }
197
199 break;
200
201 intra_skip_blocks++;
202 if (intra_skip_blocks >= 256)
203 break;
204
206 }
207
208 pixel_ptr = xpixel_ptr;
209 row_ptr = xrow_ptr;
210 cur_y = frame_y;
211 cur_x = frame_x;
212
213 while (block_counter + coded_blocks < total_blocks && coded_blocks < 256) {
216 const int nb_elements = x_size * y_size;
217 uint8_t block_values[16] = { 0 };
218 for (int y = 0; y < y_size; y++)
219 memcpy(block_values + y * x_size, pixel_ptr + y *
stride, x_size);
220
221 qsort(block_values, nb_elements,
sizeof(block_values[0]),
smc_cmp_values);
223 if (coded_blocks == 0) {
224 memcpy(distinct_values,
s->next_distinct_values,
sizeof(
s->distinct_values));
225 s->nb_distinct =
s->next_nb_distinct;
226 } else {
227 if (
s->next_nb_distinct !=
s->nb_distinct ||
228 memcmp(distinct_values,
s->next_distinct_values,
s->nb_distinct)) {
229 break;
230 }
231 }
232 s->mono_value = block_values[0];
233
234 coded_distinct =
s->nb_distinct;
235 coded_blocks++;
236 if (coded_distinct > 1 && coded_blocks >= 16)
237 break;
238
240 }
241
242 pixel_ptr = xpixel_ptr;
243 row_ptr = xrow_ptr;
244 cur_y = frame_y;
245 cur_x = frame_x;
246
247 blocks = coded_distinct <= 8 ? coded_blocks : 0;
248 distinct = coded_distinct;
249
250 if (intra_skip_blocks >= blocks && intra_skip_blocks >= inter_skip_blocks) {
251 distinct = 17;
252 blocks = intra_skip_blocks;
253 }
254
255 if (intra_skip_blocks > 16 && intra_skip_blocks >= inter_skip_blocks &&
256 intra_skip_blocks >= blocks) {
257 distinct = 18;
258 blocks = intra_skip_blocks;
259 }
260
261 if (inter_skip_blocks >= blocks && inter_skip_blocks > intra_skip_blocks) {
262 distinct = 19;
263 blocks = inter_skip_blocks;
264 }
265
266 if (inter_skip_blocks > 16 && inter_skip_blocks > intra_skip_blocks &&
267 inter_skip_blocks >= blocks) {
268 distinct = 20;
269 blocks = inter_skip_blocks;
270 }
271
272 if (blocks == 0) {
273 blocks = coded_blocks;
274 distinct = coded_distinct;
275 }
276
277 switch (distinct) {
278 case 1:
279 if (blocks <= 16) {
280 bytestream2_put_byte(pb, 0x60 | (blocks - 1));
281 } else {
282 bytestream2_put_byte(pb, 0x70);
283 bytestream2_put_byte(pb, blocks - 1);
284 }
285 bytestream2_put_byte(pb,
s->mono_value);
287 break;
288 case 2:
289 cache_index = -1;
294 break;
295 }
296 }
297
298 if (cache_index >= 0) {
299 bytestream2_put_byte(pb, 0x90 | (blocks - 1));
300 bytestream2_put_byte(pb, cache_index);
301 color_table_index = cache_index;
302 } else {
303 bytestream2_put_byte(pb, 0x80 | (blocks - 1));
304
305 color_table_index = color_pair_index;
307 s->color_pairs[color_table_index][
i] = distinct_values[
i];
308 bytestream2_put_byte(pb, distinct_values[
i]);
309 }
310
311 color_pair_index++;
313 color_pair_index = 0;
314 }
315
316 for (
int i = 0;
i < blocks;
i++) {
319 uint8_t
value =
s->color_pairs[color_table_index][1];
322
323 for (int y = 0; y < y_size; y++) {
324 for (int x = 0; x < x_size; x++) {
327 }
329 }
330
331 bytestream2_put_be16(pb,
flags);
332
334 }
335 break;
336 case 3:
337 case 4:
338 cache_index = -1;
345 break;
346 }
347 }
348
349 if (cache_index >= 0) {
350 bytestream2_put_byte(pb, 0xB0 | (blocks - 1));
351 bytestream2_put_byte(pb, cache_index);
352 color_table_index = cache_index;
353 } else {
354 bytestream2_put_byte(pb, 0xA0 | (blocks - 1));
355
356 color_table_index = color_quad_index;
358 s->color_quads[color_table_index][
i] = distinct_values[
i];
359 bytestream2_put_byte(pb, distinct_values[
i]);
360 }
361
362 color_quad_index++;
364 color_quad_index = 0;
365 }
366
367 for (
int i = 0;
i < blocks;
i++) {
371 uint8_t quad[4];
373
374 for (int k = 0; k < 4; k++)
375 quad[k] =
s->color_quads[color_table_index][k];
376
377 for (
int y = 0; y < y_size; y++) {
378 for (int x = 0; x < x_size; x++) {
380 uint32_t idx = 0;
381
385 break;
386 }
387 }
388
391 }
392
393 shift -= 2 * (4 - x_size);
394 }
395
396 bytestream2_put_be32(pb,
flags);
397
399 }
400 break;
401 case 5:
402 case 6:
403 case 7:
404 case 8:
405 cache_index = -1;
416 break;
417 }
418 }
419
420 if (cache_index >= 0) {
421 bytestream2_put_byte(pb, 0xD0 | (blocks - 1));
422 bytestream2_put_byte(pb, cache_index);
423 color_table_index = cache_index;
424 } else {
425 bytestream2_put_byte(pb, 0xC0 | (blocks - 1));
426
427 color_table_index = color_octet_index;
429 s->color_octets[color_table_index][
i] = distinct_values[
i];
430 bytestream2_put_byte(pb, distinct_values[
i]);
431 }
432
433 color_octet_index++;
435 color_octet_index = 0;
436 }
437
438 for (
int i = 0;
i < blocks;
i++) {
442 uint8_t octet[8];
444
445 for (int k = 0; k < 8; k++)
446 octet[k] =
s->color_octets[color_table_index][k];
447
448 for (
int y = 0; y < y_size; y++) {
449 for (int x = 0; x < x_size; x++) {
451 uint64_t idx = 0;
452
456 break;
457 }
458 }
459
462 }
463
464 shift -= 3 * (4 - x_size);
465 }
466
467 bytestream2_put_be16(pb, ((
flags >> 32) & 0xFFF0) | ((
flags >> 8) & 0xF));
468 bytestream2_put_be16(pb, ((
flags >> 20) & 0xFFF0) | ((
flags >> 4) & 0xF));
469 bytestream2_put_be16(pb, ((
flags >> 8) & 0xFFF0) | ((
flags >> 0) & 0xF));
470
472 }
473 break;
474 default:
475 bytestream2_put_byte(pb, 0xE0 | (blocks - 1));
476 for (
int i = 0;
i < blocks;
i++) {
479 for (int y = 0; y < y_size; y++) {
480 for (int x = 0; x < x_size; x++)
481 bytestream2_put_byte(pb, pixel_ptr[x + y *
stride]);
482 for (int x = x_size; x < 4; x++)
483 bytestream2_put_byte(pb, 0);
484 }
485
486 for (int y = y_size; y < 4; y++) {
487 for (int x = 0; x < 4; x++)
488 bytestream2_put_byte(pb, 0);
489 }
490
492 }
493 break;
494 case 17:
495 bytestream2_put_byte(pb, 0x20 | (blocks - 1));
497 break;
498 case 18:
499 bytestream2_put_byte(pb, 0x30);
500 bytestream2_put_byte(pb, blocks - 1);
502 break;
503 case 19:
504 bytestream2_put_byte(pb, 0x00 | (blocks - 1));
506 break;
507 case 20:
508 bytestream2_put_byte(pb, 0x10);
509 bytestream2_put_byte(pb, blocks - 1);
511 break;
512 }
513
514 block_counter += blocks;
515 }
516 }
517
519 {
521
523
527
528 return 0;
529 }
530
533 {
537 uint8_t *pal;
539
543
544 if (avctx->
gop_size == 0 || !
s->prev_frame->data[0] ||
547 } else {
549 }
550
552
553 bytestream2_put_be32(&pb, 0x00);
554
556 if (!pal)
559
561
563
565
566 // write chunk length
568
573 }
574
577
578 *got_packet = 1;
579
580 return 0;
581 }
582
584 {
586
588
589 return 0;
590 }
591
603 };