| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 | |||
| 27 | #include "libavutil/common.h" | ||
| 28 | |||
| 29 | #include "avcodec.h" | ||
| 30 | #include "codec_internal.h" | ||
| 31 | #include "encode.h" | ||
| 32 | #include "bytestream.h" | ||
| 33 | |||
| 34 | #define CPAIR 2 | ||
| 35 | #define CQUAD 4 | ||
| 36 | #define COCTET 8 | ||
| 37 | |||
| 38 | #define COLORS_PER_TABLE 256 | ||
| 39 | |||
| 40 | typedef struct SMCContext { | ||
| 41 | AVFrame *prev_frame; // buffer for previous source frame | ||
| 42 | |||
| 43 | uint8_t mono_value; | ||
| 44 | int nb_distinct; | ||
| 45 | int next_nb_distinct; | ||
| 46 | uint8_t distinct_values[16]; | ||
| 47 | uint8_t next_distinct_values[16]; | ||
| 48 | |||
| 49 | uint8_t color_pairs[COLORS_PER_TABLE][CPAIR]; | ||
| 50 | uint8_t color_quads[COLORS_PER_TABLE][CQUAD]; | ||
| 51 | uint8_t color_octets[COLORS_PER_TABLE][COCTET]; | ||
| 52 | |||
| 53 | int key_frame; | ||
| 54 | } SMCContext; | ||
| 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 | |||
| 71 | 81354609 | static int smc_cmp_values(const void *a, const void *b) | |
| 72 | { | ||
| 73 | 81354609 | const uint8_t *aa = a, *bb = b; | |
| 74 | |||
| 75 | 81354609 | return FFDIFFSIGN(aa[0], bb[0]); | |
| 76 | } | ||
| 77 | |||
| 78 | 1841851 | static int count_distinct_items(const uint8_t *block_values, | |
| 79 | uint8_t *distinct_values, | ||
| 80 | int size) | ||
| 81 | { | ||
| 82 | 1841851 | int n = 1; | |
| 83 | |||
| 84 | 1841851 | distinct_values[0] = block_values[0]; | |
| 85 |
2/2✓ Branch 0 taken 27613773 times.
✓ Branch 1 taken 1841851 times.
|
29455624 | for (int i = 1; i < size; i++) { |
| 86 |
2/2✓ Branch 0 taken 10525322 times.
✓ Branch 1 taken 17088451 times.
|
27613773 | if (block_values[i] != block_values[i-1]) { |
| 87 | 10525322 | distinct_values[n] = block_values[i]; | |
| 88 | 10525322 | n++; | |
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | 1841851 | 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 | |||
| 115 | 200 | static void smc_encode_stream(SMCContext *s, const AVFrame *frame, | |
| 116 | PutByteContext *pb) | ||
| 117 | { | ||
| 118 | 200 | const uint8_t *src_pixels = (const uint8_t *)frame->data[0]; | |
| 119 | 200 | const ptrdiff_t stride = frame->linesize[0]; | |
| 120 | 200 | const uint8_t *prev_pixels = (const uint8_t *)s->prev_frame->data[0]; | |
| 121 | 200 | const ptrdiff_t prev_stride = s->prev_frame->linesize[0]; | |
| 122 | 200 | uint8_t *distinct_values = s->distinct_values; | |
| 123 | const uint8_t *pixel_ptr, *row_ptr; | ||
| 124 | 200 | const int height = frame->height; | |
| 125 | 200 | const int width = frame->width; | |
| 126 | 200 | int block_counter = 0; | |
| 127 | 200 | int color_pair_index = 0; | |
| 128 | 200 | int color_quad_index = 0; | |
| 129 | 200 | int color_octet_index = 0; | |
| 130 | int color_table_index; /* indexes to color pair, quad, or octet tables */ | ||
| 131 | int total_blocks; | ||
| 132 | 200 | int cur_y = 0; | |
| 133 | 200 | int cur_x = 0; | |
| 134 | |||
| 135 | /* Number of 4x4 blocks in frame. */ | ||
| 136 | 200 | total_blocks = ((width + 3) / 4) * ((height + 3) / 4); | |
| 137 | |||
| 138 | 200 | pixel_ptr = row_ptr = src_pixels; | |
| 139 | |||
| 140 |
2/2✓ Branch 0 taken 889064 times.
✓ Branch 1 taken 200 times.
|
889264 | while (block_counter < total_blocks) { |
| 141 | 889064 | const uint8_t *xpixel_ptr = pixel_ptr; | |
| 142 | 889064 | const uint8_t *xrow_ptr = row_ptr; | |
| 143 | 889064 | int intra_skip_blocks = 0; | |
| 144 | 889064 | int inter_skip_blocks = 0; | |
| 145 | 889064 | int coded_distinct = 0; | |
| 146 | 889064 | int coded_blocks = 0; | |
| 147 | int cache_index; | ||
| 148 | 889064 | int distinct = 0; | |
| 149 | 889064 | int blocks = 0; | |
| 150 | 889064 | int frame_y = cur_y; | |
| 151 | 889064 | int frame_x = cur_x; | |
| 152 | |||
| 153 |
5/6✓ Branch 0 taken 886487 times.
✓ Branch 1 taken 17353 times.
✓ Branch 2 taken 814927 times.
✓ Branch 3 taken 71560 times.
✓ Branch 4 taken 814927 times.
✗ Branch 5 not taken.
|
903840 | while (prev_pixels && s->key_frame == 0 && block_counter + inter_skip_blocks < total_blocks) { |
| 154 | 814927 | const int y_size = FFMIN(4, height - cur_y); | |
| 155 | 814927 | const int x_size = FFMIN(4, width - cur_x); | |
| 156 | 814927 | int compare = 0; | |
| 157 | |||
| 158 |
2/2✓ Branch 0 taken 997456 times.
✓ Branch 1 taken 14776 times.
|
1012232 | for (int y = 0; y < y_size; y++) { |
| 159 | 997456 | const uint8_t *prev_pixel_ptr = prev_pixels + (y + cur_y) * prev_stride + cur_x; | |
| 160 | |||
| 161 | 997456 | compare |= !!memcmp(prev_pixel_ptr, pixel_ptr + y * stride, x_size); | |
| 162 |
2/2✓ Branch 0 taken 800151 times.
✓ Branch 1 taken 197305 times.
|
997456 | if (compare) |
| 163 | 800151 | break; | |
| 164 | } | ||
| 165 | |||
| 166 |
2/2✓ Branch 0 taken 800151 times.
✓ Branch 1 taken 14776 times.
|
814927 | if (compare) |
| 167 | 800151 | break; | |
| 168 | |||
| 169 | 14776 | inter_skip_blocks++; | |
| 170 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14776 times.
|
14776 | if (inter_skip_blocks >= 256) |
| 171 | ✗ | break; | |
| 172 | |||
| 173 |
6/8✓ Branch 0 taken 27 times.
✓ Branch 1 taken 14749 times.
✓ Branch 2 taken 14776 times.
✓ Branch 3 taken 14776 times.
✓ Branch 4 taken 14776 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14776 times.
✗ Branch 7 not taken.
|
29552 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 174 | } | ||
| 175 | |||
| 176 | 889064 | pixel_ptr = xpixel_ptr; | |
| 177 | 889064 | row_ptr = xrow_ptr; | |
| 178 | 889064 | cur_y = frame_y; | |
| 179 | 889064 | cur_x = frame_x; | |
| 180 | |||
| 181 |
3/4✓ Branch 0 taken 888936 times.
✓ Branch 1 taken 200 times.
✓ Branch 2 taken 888936 times.
✗ Branch 3 not taken.
|
889136 | while (block_counter > 0 && block_counter + intra_skip_blocks < total_blocks) { |
| 182 | 888936 | const int y_size = FFMIN(4, height - cur_y); | |
| 183 | 888936 | const int x_size = FFMIN(4, width - cur_x); | |
| 184 | 888936 | const ptrdiff_t offset = xpixel_ptr - src_pixels; | |
| 185 | 888936 | const int sy = offset / stride; | |
| 186 | 888936 | const int sx = offset % stride; | |
| 187 |
2/2✓ Branch 0 taken 11034 times.
✓ Branch 1 taken 877902 times.
|
888936 | const int ny = sx < 4 ? FFMAX(sy - 4, 0) : sy; |
| 188 |
2/2✓ Branch 0 taken 11034 times.
✓ Branch 1 taken 877902 times.
|
888936 | const int nx = sx < 4 ? FFMAX(width - 4 + (width & 3), 0) : sx - 4; |
| 189 | 888936 | const uint8_t *old_pixel_ptr = src_pixels + nx + ny * stride; | |
| 190 | 888936 | int compare = 0; | |
| 191 | |||
| 192 |
2/2✓ Branch 0 taken 951899 times.
✓ Branch 1 taken 72 times.
|
951971 | for (int y = 0; y < y_size; y++) { |
| 193 | 951899 | compare |= !!memcmp(old_pixel_ptr + y * stride, pixel_ptr + y * stride, x_size); | |
| 194 |
2/2✓ Branch 0 taken 888864 times.
✓ Branch 1 taken 63035 times.
|
951899 | if (compare) |
| 195 | 888864 | break; | |
| 196 | } | ||
| 197 | |||
| 198 |
2/2✓ Branch 0 taken 888864 times.
✓ Branch 1 taken 72 times.
|
888936 | if (compare) |
| 199 | 888864 | break; | |
| 200 | |||
| 201 | 72 | intra_skip_blocks++; | |
| 202 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
|
72 | if (intra_skip_blocks >= 256) |
| 203 | ✗ | break; | |
| 204 | |||
| 205 |
6/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 72 times.
✗ Branch 7 not taken.
|
144 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 206 | } | ||
| 207 | |||
| 208 | 889064 | pixel_ptr = xpixel_ptr; | |
| 209 | 889064 | row_ptr = xrow_ptr; | |
| 210 | 889064 | cur_y = frame_y; | |
| 211 | 889064 | cur_x = frame_x; | |
| 212 | |||
| 213 |
3/4✓ Branch 0 taken 1841851 times.
✓ Branch 1 taken 200 times.
✓ Branch 2 taken 1841851 times.
✗ Branch 3 not taken.
|
1842051 | while (block_counter + coded_blocks < total_blocks && coded_blocks < 256) { |
| 214 | 1841851 | const int y_size = FFMIN(4, height - cur_y); | |
| 215 | 1841851 | const int x_size = FFMIN(4, width - cur_x); | |
| 216 | 1841851 | const int nb_elements = x_size * y_size; | |
| 217 | 1841851 | uint8_t block_values[16] = { 0 }; | |
| 218 |
2/2✓ Branch 0 taken 7365604 times.
✓ Branch 1 taken 1841851 times.
|
9207455 | for (int y = 0; y < y_size; y++) |
| 219 | 7365604 | memcpy(block_values + y * x_size, pixel_ptr + y * stride, x_size); | |
| 220 | |||
| 221 | 1841851 | qsort(block_values, nb_elements, sizeof(block_values[0]), smc_cmp_values); | |
| 222 | 1841851 | s->next_nb_distinct = count_distinct_items(block_values, s->next_distinct_values, nb_elements); | |
| 223 |
2/2✓ Branch 0 taken 889064 times.
✓ Branch 1 taken 952787 times.
|
1841851 | if (coded_blocks == 0) { |
| 224 | 889064 | memcpy(distinct_values, s->next_distinct_values, sizeof(s->distinct_values)); | |
| 225 | 889064 | s->nb_distinct = s->next_nb_distinct; | |
| 226 | } else { | ||
| 227 |
2/2✓ Branch 0 taken 215197 times.
✓ Branch 1 taken 737590 times.
|
952787 | if (s->next_nb_distinct != s->nb_distinct || |
| 228 |
2/2✓ Branch 0 taken 63942 times.
✓ Branch 1 taken 151255 times.
|
215197 | memcmp(distinct_values, s->next_distinct_values, s->nb_distinct)) { |
| 229 | break; | ||
| 230 | } | ||
| 231 | } | ||
| 232 | 953006 | s->mono_value = block_values[0]; | |
| 233 | |||
| 234 | 953006 | coded_distinct = s->nb_distinct; | |
| 235 | 953006 | coded_blocks++; | |
| 236 |
4/4✓ Branch 0 taken 950474 times.
✓ Branch 1 taken 2532 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 950455 times.
|
953006 | if (coded_distinct > 1 && coded_blocks >= 16) |
| 237 | 19 | break; | |
| 238 | |||
| 239 |
6/8✓ Branch 0 taken 11246 times.
✓ Branch 1 taken 941741 times.
✓ Branch 2 taken 952987 times.
✓ Branch 3 taken 952987 times.
✓ Branch 4 taken 952987 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 952987 times.
✗ Branch 7 not taken.
|
1905974 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 240 | } | ||
| 241 | |||
| 242 | 889064 | pixel_ptr = xpixel_ptr; | |
| 243 | 889064 | row_ptr = xrow_ptr; | |
| 244 | 889064 | cur_y = frame_y; | |
| 245 | 889064 | cur_x = frame_x; | |
| 246 | |||
| 247 |
2/2✓ Branch 0 taken 682023 times.
✓ Branch 1 taken 207041 times.
|
889064 | blocks = coded_distinct <= 8 ? coded_blocks : 0; |
| 248 | 889064 | distinct = coded_distinct; | |
| 249 | |||
| 250 |
4/4✓ Branch 0 taken 207083 times.
✓ Branch 1 taken 681981 times.
✓ Branch 2 taken 207015 times.
✓ Branch 3 taken 68 times.
|
889064 | if (intra_skip_blocks >= blocks && intra_skip_blocks >= inter_skip_blocks) { |
| 251 | 207015 | distinct = 17; | |
| 252 | 207015 | blocks = intra_skip_blocks; | |
| 253 | } | ||
| 254 | |||
| 255 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 889064 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
889064 | 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 |
4/4✓ Branch 0 taken 215350 times.
✓ Branch 1 taken 673714 times.
✓ Branch 2 taken 8377 times.
✓ Branch 3 taken 206973 times.
|
889064 | if (inter_skip_blocks >= blocks && inter_skip_blocks > intra_skip_blocks) { |
| 262 | 8377 | distinct = 19; | |
| 263 | 8377 | blocks = inter_skip_blocks; | |
| 264 | } | ||
| 265 | |||
| 266 |
5/6✓ Branch 0 taken 4 times.
✓ Branch 1 taken 889060 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
889064 | if (inter_skip_blocks > 16 && inter_skip_blocks > intra_skip_blocks && |
| 267 | inter_skip_blocks >= blocks) { | ||
| 268 | 2 | distinct = 20; | |
| 269 | 2 | blocks = inter_skip_blocks; | |
| 270 | } | ||
| 271 | |||
| 272 |
2/2✓ Branch 0 taken 206973 times.
✓ Branch 1 taken 682091 times.
|
889064 | if (blocks == 0) { |
| 273 | 206973 | blocks = coded_blocks; | |
| 274 | 206973 | distinct = coded_distinct; | |
| 275 | } | ||
| 276 | |||
| 277 |
8/9✓ Branch 0 taken 511 times.
✓ Branch 1 taken 9960 times.
✓ Branch 2 taken 150047 times.
✓ Branch 3 taken 513154 times.
✓ Branch 4 taken 206973 times.
✓ Branch 5 taken 42 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8375 times.
✓ Branch 8 taken 2 times.
|
889064 | switch (distinct) { |
| 278 | 511 | case 1: | |
| 279 |
2/2✓ Branch 0 taken 500 times.
✓ Branch 1 taken 11 times.
|
511 | if (blocks <= 16) { |
| 280 | 500 | bytestream2_put_byte(pb, 0x60 | (blocks - 1)); | |
| 281 | } else { | ||
| 282 | 11 | bytestream2_put_byte(pb, 0x70); | |
| 283 | 11 | bytestream2_put_byte(pb, blocks - 1); | |
| 284 | } | ||
| 285 | 511 | bytestream2_put_byte(pb, s->mono_value); | |
| 286 |
6/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1363 times.
✓ Branch 2 taken 1364 times.
✓ Branch 3 taken 511 times.
✓ Branch 4 taken 1364 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1364 times.
✗ Branch 7 not taken.
|
1875 | ADVANCE_BLOCK(pixel_ptr, row_ptr, blocks) |
| 287 | 511 | break; | |
| 288 | 9960 | case 2: | |
| 289 | 9960 | cache_index = -1; | |
| 290 |
2/2✓ Branch 0 taken 345512 times.
✓ Branch 1 taken 839 times.
|
346351 | for (int i = 0; i < COLORS_PER_TABLE; i++) { |
| 291 |
4/4✓ Branch 0 taken 298176 times.
✓ Branch 1 taken 47336 times.
✓ Branch 2 taken 2329 times.
✓ Branch 3 taken 295847 times.
|
345512 | if (CACHE_PAIR(0) && |
| 292 |
3/4✓ Branch 0 taken 49665 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9121 times.
✓ Branch 3 taken 40544 times.
|
49665 | CACHE_PAIR(1)) { |
| 293 | 9121 | cache_index = i; | |
| 294 | 9121 | break; | |
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 |
2/2✓ Branch 0 taken 9121 times.
✓ Branch 1 taken 839 times.
|
9960 | if (cache_index >= 0) { |
| 299 | 9121 | bytestream2_put_byte(pb, 0x90 | (blocks - 1)); | |
| 300 | 9121 | bytestream2_put_byte(pb, cache_index); | |
| 301 | 9121 | color_table_index = cache_index; | |
| 302 | } else { | ||
| 303 | 839 | bytestream2_put_byte(pb, 0x80 | (blocks - 1)); | |
| 304 | |||
| 305 | 839 | color_table_index = color_pair_index; | |
| 306 |
2/2✓ Branch 0 taken 1678 times.
✓ Branch 1 taken 839 times.
|
2517 | for (int i = 0; i < CPAIR; i++) { |
| 307 | 1678 | s->color_pairs[color_table_index][i] = distinct_values[i]; | |
| 308 | 1678 | bytestream2_put_byte(pb, distinct_values[i]); | |
| 309 | } | ||
| 310 | |||
| 311 | 839 | color_pair_index++; | |
| 312 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 839 times.
|
839 | if (color_pair_index == COLORS_PER_TABLE) |
| 313 | ✗ | color_pair_index = 0; | |
| 314 | } | ||
| 315 | |||
| 316 |
2/2✓ Branch 0 taken 16882 times.
✓ Branch 1 taken 9960 times.
|
26842 | for (int i = 0; i < blocks; i++) { |
| 317 | 16882 | const int y_size = FFMIN(4, height - cur_y); | |
| 318 | 16882 | const int x_size = FFMIN(4, width - cur_x); | |
| 319 | 16882 | uint8_t value = s->color_pairs[color_table_index][1]; | |
| 320 | 16882 | uint16_t flags = 0; | |
| 321 | 16882 | int shift = 15; | |
| 322 | |||
| 323 |
2/2✓ Branch 0 taken 67526 times.
✓ Branch 1 taken 16882 times.
|
84408 | for (int y = 0; y < y_size; y++) { |
| 324 |
2/2✓ Branch 0 taken 270060 times.
✓ Branch 1 taken 67526 times.
|
337586 | for (int x = 0; x < x_size; x++) { |
| 325 | 270060 | flags |= (value == pixel_ptr[x + y * stride]) << shift; | |
| 326 | 270060 | shift--; | |
| 327 | } | ||
| 328 | 67526 | shift -= 4 - x_size; | |
| 329 | } | ||
| 330 | |||
| 331 | 16882 | bytestream2_put_be16(pb, flags); | |
| 332 | |||
| 333 |
6/8✓ Branch 0 taken 135 times.
✓ Branch 1 taken 16747 times.
✓ Branch 2 taken 16882 times.
✓ Branch 3 taken 16882 times.
✓ Branch 4 taken 16882 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16882 times.
✗ Branch 7 not taken.
|
33764 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 334 | } | ||
| 335 | 9960 | break; | |
| 336 | 150047 | case 3: | |
| 337 | case 4: | ||
| 338 | 150047 | cache_index = -1; | |
| 339 |
2/2✓ Branch 0 taken 18552849 times.
✓ Branch 1 taken 27203 times.
|
18580052 | for (int i = 0; i < COLORS_PER_TABLE; i++) { |
| 340 |
8/8✓ Branch 0 taken 17629383 times.
✓ Branch 1 taken 923466 times.
✓ Branch 2 taken 16977560 times.
✓ Branch 3 taken 651823 times.
✓ Branch 4 taken 16495647 times.
✓ Branch 5 taken 481913 times.
✓ Branch 6 taken 355550 times.
✓ Branch 7 taken 16140097 times.
|
18552849 | if (CACHE_QUAD(0) && |
| 341 |
8/8✓ Branch 0 taken 2405754 times.
✓ Branch 1 taken 6998 times.
✓ Branch 2 taken 2033720 times.
✓ Branch 3 taken 372034 times.
✓ Branch 4 taken 1716388 times.
✓ Branch 5 taken 317332 times.
✓ Branch 6 taken 161448 times.
✓ Branch 7 taken 1554940 times.
|
2412752 | CACHE_QUAD(1) && |
| 342 |
7/8✓ Branch 0 taken 857812 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 853861 times.
✓ Branch 3 taken 3951 times.
✓ Branch 4 taken 623855 times.
✓ Branch 5 taken 230006 times.
✓ Branch 6 taken 133747 times.
✓ Branch 7 taken 490108 times.
|
857812 | CACHE_QUAD(2) && |
| 343 |
8/8✓ Branch 0 taken 364623 times.
✓ Branch 1 taken 3081 times.
✓ Branch 2 taken 359819 times.
✓ Branch 3 taken 4804 times.
✓ Branch 4 taken 343034 times.
✓ Branch 5 taken 16785 times.
✓ Branch 6 taken 98174 times.
✓ Branch 7 taken 244860 times.
|
367704 | CACHE_QUAD(3)) { |
| 344 | 122844 | cache_index = i; | |
| 345 | 122844 | break; | |
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 |
2/2✓ Branch 0 taken 122844 times.
✓ Branch 1 taken 27203 times.
|
150047 | if (cache_index >= 0) { |
| 350 | 122844 | bytestream2_put_byte(pb, 0xB0 | (blocks - 1)); | |
| 351 | 122844 | bytestream2_put_byte(pb, cache_index); | |
| 352 | 122844 | color_table_index = cache_index; | |
| 353 | } else { | ||
| 354 | 27203 | bytestream2_put_byte(pb, 0xA0 | (blocks - 1)); | |
| 355 | |||
| 356 | 27203 | color_table_index = color_quad_index; | |
| 357 |
2/2✓ Branch 0 taken 108812 times.
✓ Branch 1 taken 27203 times.
|
136015 | for (int i = 0; i < CQUAD; i++) { |
| 358 | 108812 | s->color_quads[color_table_index][i] = distinct_values[i]; | |
| 359 | 108812 | bytestream2_put_byte(pb, distinct_values[i]); | |
| 360 | } | ||
| 361 | |||
| 362 | 27203 | color_quad_index++; | |
| 363 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 27154 times.
|
27203 | if (color_quad_index == COLORS_PER_TABLE) |
| 364 | 49 | color_quad_index = 0; | |
| 365 | } | ||
| 366 | |||
| 367 |
2/2✓ Branch 0 taken 191380 times.
✓ Branch 1 taken 150047 times.
|
341427 | for (int i = 0; i < blocks; i++) { |
| 368 | 191380 | const int y_size = FFMIN(4, height - cur_y); | |
| 369 | 191380 | const int x_size = FFMIN(4, width - cur_x); | |
| 370 | 191380 | uint32_t flags = 0; | |
| 371 | uint8_t quad[4]; | ||
| 372 | 191380 | int shift = 30; | |
| 373 | |||
| 374 |
2/2✓ Branch 0 taken 765520 times.
✓ Branch 1 taken 191380 times.
|
956900 | for (int k = 0; k < 4; k++) |
| 375 | 765520 | quad[k] = s->color_quads[color_table_index][k]; | |
| 376 | |||
| 377 |
2/2✓ Branch 0 taken 765370 times.
✓ Branch 1 taken 191380 times.
|
956750 | for (int y = 0; y < y_size; y++) { |
| 378 |
2/2✓ Branch 0 taken 3060500 times.
✓ Branch 1 taken 765370 times.
|
3825870 | for (int x = 0; x < x_size; x++) { |
| 379 | 3060500 | int pixel = pixel_ptr[x + y * stride]; | |
| 380 | 3060500 | uint32_t idx = 0; | |
| 381 | |||
| 382 |
1/2✓ Branch 0 taken 7561475 times.
✗ Branch 1 not taken.
|
7561475 | for (int w = 0; w < CQUAD; w++) { |
| 383 |
2/2✓ Branch 0 taken 3060500 times.
✓ Branch 1 taken 4500975 times.
|
7561475 | if (quad[w] == pixel) { |
| 384 | 3060500 | idx = w; | |
| 385 | 3060500 | break; | |
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | 3060500 | flags |= idx << shift; | |
| 390 | 3060500 | shift -= 2; | |
| 391 | } | ||
| 392 | |||
| 393 | 765370 | shift -= 2 * (4 - x_size); | |
| 394 | } | ||
| 395 | |||
| 396 | 191380 | bytestream2_put_be32(pb, flags); | |
| 397 | |||
| 398 |
6/8✓ Branch 0 taken 2277 times.
✓ Branch 1 taken 189103 times.
✓ Branch 2 taken 191380 times.
✓ Branch 3 taken 191380 times.
✓ Branch 4 taken 191380 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 191380 times.
✗ Branch 7 not taken.
|
382760 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 399 | } | ||
| 400 | 150047 | break; | |
| 401 | 513154 | case 5: | |
| 402 | case 6: | ||
| 403 | case 7: | ||
| 404 | case 8: | ||
| 405 | 513154 | cache_index = -1; | |
| 406 |
2/2✓ Branch 0 taken 112804394 times.
✓ Branch 1 taken 389757 times.
|
113194151 | for (int i = 0; i < COLORS_PER_TABLE; i++) { |
| 407 |
16/16✓ Branch 0 taken 107527819 times.
✓ Branch 1 taken 5276575 times.
✓ Branch 2 taken 104592429 times.
✓ Branch 3 taken 2935390 times.
✓ Branch 4 taken 102287481 times.
✓ Branch 5 taken 2304948 times.
✓ Branch 6 taken 100573539 times.
✓ Branch 7 taken 1713942 times.
✓ Branch 8 taken 99180757 times.
✓ Branch 9 taken 1392782 times.
✓ Branch 10 taken 98049379 times.
✓ Branch 11 taken 1131378 times.
✓ Branch 12 taken 97094574 times.
✓ Branch 13 taken 954805 times.
✓ Branch 14 taken 807117 times.
✓ Branch 15 taken 96287457 times.
|
112804394 | if (CACHE_OCTET(0) && |
| 408 |
16/16✓ Branch 0 taken 16459827 times.
✓ Branch 1 taken 57110 times.
✓ Branch 2 taken 14398018 times.
✓ Branch 3 taken 2061809 times.
✓ Branch 4 taken 12646681 times.
✓ Branch 5 taken 1751337 times.
✓ Branch 6 taken 11302896 times.
✓ Branch 7 taken 1343785 times.
✓ Branch 8 taken 10333897 times.
✓ Branch 9 taken 968999 times.
✓ Branch 10 taken 9703535 times.
✓ Branch 11 taken 630362 times.
✓ Branch 12 taken 9281954 times.
✓ Branch 13 taken 421581 times.
✓ Branch 14 taken 305956 times.
✓ Branch 15 taken 8975998 times.
|
16516937 | CACHE_OCTET(1) && |
| 409 |
16/16✓ Branch 0 taken 7531465 times.
✓ Branch 1 taken 9474 times.
✓ Branch 2 taken 7485772 times.
✓ Branch 3 taken 45693 times.
✓ Branch 4 taken 6207739 times.
✓ Branch 5 taken 1278033 times.
✓ Branch 6 taken 5021646 times.
✓ Branch 7 taken 1186093 times.
✓ Branch 8 taken 4185187 times.
✓ Branch 9 taken 836459 times.
✓ Branch 10 taken 3687627 times.
✓ Branch 11 taken 497560 times.
✓ Branch 12 taken 3403032 times.
✓ Branch 13 taken 284595 times.
✓ Branch 14 taken 159510 times.
✓ Branch 15 taken 3243522 times.
|
7540939 | CACHE_OCTET(2) && |
| 410 |
16/16✓ Branch 0 taken 4296784 times.
✓ Branch 1 taken 633 times.
✓ Branch 2 taken 4291176 times.
✓ Branch 3 taken 5608 times.
✓ Branch 4 taken 4262159 times.
✓ Branch 5 taken 29017 times.
✓ Branch 6 taken 3505056 times.
✓ Branch 7 taken 757103 times.
✓ Branch 8 taken 2749491 times.
✓ Branch 9 taken 755565 times.
✓ Branch 10 taken 2297158 times.
✓ Branch 11 taken 452333 times.
✓ Branch 12 taken 2067134 times.
✓ Branch 13 taken 230024 times.
✓ Branch 14 taken 110566 times.
✓ Branch 15 taken 1956568 times.
|
4297417 | CACHE_OCTET(3) && |
| 411 |
15/16✓ Branch 0 taken 2340849 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2340594 times.
✓ Branch 3 taken 255 times.
✓ Branch 4 taken 2337809 times.
✓ Branch 5 taken 2785 times.
✓ Branch 6 taken 2319162 times.
✓ Branch 7 taken 18647 times.
✓ Branch 8 taken 1858328 times.
✓ Branch 9 taken 460834 times.
✓ Branch 10 taken 1411831 times.
✓ Branch 11 taken 446497 times.
✓ Branch 12 taken 1179148 times.
✓ Branch 13 taken 232683 times.
✓ Branch 14 taken 101691 times.
✓ Branch 15 taken 1077457 times.
|
2340849 | CACHE_OCTET(4) && |
| 412 |
16/16✓ Branch 0 taken 1257025 times.
✓ Branch 1 taken 6367 times.
✓ Branch 2 taken 1247939 times.
✓ Branch 3 taken 9086 times.
✓ Branch 4 taken 1233843 times.
✓ Branch 5 taken 14096 times.
✓ Branch 6 taken 1207748 times.
✓ Branch 7 taken 26095 times.
✓ Branch 8 taken 1143495 times.
✓ Branch 9 taken 64253 times.
✓ Branch 10 taken 884890 times.
✓ Branch 11 taken 258605 times.
✓ Branch 12 taken 719691 times.
✓ Branch 13 taken 165199 times.
✓ Branch 14 taken 81444 times.
✓ Branch 15 taken 638247 times.
|
1263392 | CACHE_OCTET(5) && |
| 413 |
16/16✓ Branch 0 taken 619937 times.
✓ Branch 1 taken 5208 times.
✓ Branch 2 taken 611734 times.
✓ Branch 3 taken 8203 times.
✓ Branch 4 taken 600389 times.
✓ Branch 5 taken 11345 times.
✓ Branch 6 taken 585605 times.
✓ Branch 7 taken 14784 times.
✓ Branch 8 taken 562783 times.
✓ Branch 9 taken 22822 times.
✓ Branch 10 taken 525813 times.
✓ Branch 11 taken 36970 times.
✓ Branch 12 taken 409789 times.
✓ Branch 13 taken 116024 times.
✓ Branch 14 taken 51499 times.
✓ Branch 15 taken 358290 times.
|
625145 | CACHE_OCTET(6) && |
| 414 |
16/16✓ Branch 0 taken 264361 times.
✓ Branch 1 taken 2494 times.
✓ Branch 2 taken 260110 times.
✓ Branch 3 taken 4251 times.
✓ Branch 4 taken 253931 times.
✓ Branch 5 taken 6179 times.
✓ Branch 6 taken 245661 times.
✓ Branch 7 taken 8270 times.
✓ Branch 8 taken 235957 times.
✓ Branch 9 taken 9704 times.
✓ Branch 10 taken 224144 times.
✓ Branch 11 taken 11813 times.
✓ Branch 12 taken 209304 times.
✓ Branch 13 taken 14840 times.
✓ Branch 14 taken 65846 times.
✓ Branch 15 taken 143458 times.
|
266855 | CACHE_OCTET(7)) { |
| 415 | 123397 | cache_index = i; | |
| 416 | 123397 | break; | |
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 420 |
2/2✓ Branch 0 taken 123397 times.
✓ Branch 1 taken 389757 times.
|
513154 | if (cache_index >= 0) { |
| 421 | 123397 | bytestream2_put_byte(pb, 0xD0 | (blocks - 1)); | |
| 422 | 123397 | bytestream2_put_byte(pb, cache_index); | |
| 423 | 123397 | color_table_index = cache_index; | |
| 424 | } else { | ||
| 425 | 389757 | bytestream2_put_byte(pb, 0xC0 | (blocks - 1)); | |
| 426 | |||
| 427 | 389757 | color_table_index = color_octet_index; | |
| 428 |
2/2✓ Branch 0 taken 3118056 times.
✓ Branch 1 taken 389757 times.
|
3507813 | for (int i = 0; i < COCTET; i++) { |
| 429 | 3118056 | s->color_octets[color_table_index][i] = distinct_values[i]; | |
| 430 | 3118056 | bytestream2_put_byte(pb, distinct_values[i]); | |
| 431 | } | ||
| 432 | |||
| 433 | 389757 | color_octet_index++; | |
| 434 |
2/2✓ Branch 0 taken 1434 times.
✓ Branch 1 taken 388323 times.
|
389757 | if (color_octet_index == COLORS_PER_TABLE) |
| 435 | 1434 | color_octet_index = 0; | |
| 436 | } | ||
| 437 | |||
| 438 |
2/2✓ Branch 0 taken 526571 times.
✓ Branch 1 taken 513154 times.
|
1039725 | for (int i = 0; i < blocks; i++) { |
| 439 | 526571 | const int y_size = FFMIN(4, height - cur_y); | |
| 440 | 526571 | const int x_size = FFMIN(4, width - cur_x); | |
| 441 | 526571 | uint64_t flags = 0; | |
| 442 | uint8_t octet[8]; | ||
| 443 | 526571 | int shift = 45; | |
| 444 | |||
| 445 |
2/2✓ Branch 0 taken 4212568 times.
✓ Branch 1 taken 526571 times.
|
4739139 | for (int k = 0; k < 8; k++) |
| 446 | 4212568 | octet[k] = s->color_octets[color_table_index][k]; | |
| 447 | |||
| 448 |
2/2✓ Branch 0 taken 2105536 times.
✓ Branch 1 taken 526571 times.
|
2632107 | for (int y = 0; y < y_size; y++) { |
| 449 |
2/2✓ Branch 0 taken 8419768 times.
✓ Branch 1 taken 2105536 times.
|
10525304 | for (int x = 0; x < x_size; x++) { |
| 450 | 8419768 | int pixel = pixel_ptr[x + y * stride]; | |
| 451 | 8419768 | uint64_t idx = 0; | |
| 452 | |||
| 453 |
1/2✓ Branch 0 taken 32084590 times.
✗ Branch 1 not taken.
|
32084590 | for (int w = 0; w < COCTET; w++) { |
| 454 |
2/2✓ Branch 0 taken 8419768 times.
✓ Branch 1 taken 23664822 times.
|
32084590 | if (octet[w] == pixel) { |
| 455 | 8419768 | idx = w; | |
| 456 | 8419768 | break; | |
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 460 | 8419768 | flags |= idx << shift; | |
| 461 | 8419768 | shift -= 3; | |
| 462 | } | ||
| 463 | |||
| 464 | 2105536 | shift -= 3 * (4 - x_size); | |
| 465 | } | ||
| 466 | |||
| 467 | 526571 | bytestream2_put_be16(pb, ((flags >> 32) & 0xFFF0) | ((flags >> 8) & 0xF)); | |
| 468 | 526571 | bytestream2_put_be16(pb, ((flags >> 20) & 0xFFF0) | ((flags >> 4) & 0xF)); | |
| 469 | 526571 | bytestream2_put_be16(pb, ((flags >> 8) & 0xFFF0) | ((flags >> 0) & 0xF)); | |
| 470 | |||
| 471 |
6/8✓ Branch 0 taken 6434 times.
✓ Branch 1 taken 520137 times.
✓ Branch 2 taken 526571 times.
✓ Branch 3 taken 526571 times.
✓ Branch 4 taken 526571 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 526571 times.
✗ Branch 7 not taken.
|
1053142 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 472 | } | ||
| 473 | 513154 | break; | |
| 474 | 206973 | default: | |
| 475 | 206973 | bytestream2_put_byte(pb, 0xE0 | (blocks - 1)); | |
| 476 |
2/2✓ Branch 0 taken 206986 times.
✓ Branch 1 taken 206973 times.
|
413959 | for (int i = 0; i < blocks; i++) { |
| 477 | 206986 | const int y_size = FFMIN(4, height - cur_y); | |
| 478 | 206986 | const int x_size = FFMIN(4, width - cur_x); | |
| 479 |
2/2✓ Branch 0 taken 827944 times.
✓ Branch 1 taken 206986 times.
|
1034930 | for (int y = 0; y < y_size; y++) { |
| 480 |
2/2✓ Branch 0 taken 3311776 times.
✓ Branch 1 taken 827944 times.
|
4139720 | for (int x = 0; x < x_size; x++) |
| 481 | 3311776 | bytestream2_put_byte(pb, pixel_ptr[x + y * stride]); | |
| 482 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 827944 times.
|
827944 | for (int x = x_size; x < 4; x++) |
| 483 | ✗ | bytestream2_put_byte(pb, 0); | |
| 484 | } | ||
| 485 | |||
| 486 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 206986 times.
|
206986 | for (int y = y_size; y < 4; y++) { |
| 487 | ✗ | for (int x = 0; x < 4; x++) | |
| 488 | ✗ | bytestream2_put_byte(pb, 0); | |
| 489 | } | ||
| 490 | |||
| 491 |
6/8✓ Branch 0 taken 2375 times.
✓ Branch 1 taken 204611 times.
✓ Branch 2 taken 206986 times.
✓ Branch 3 taken 206986 times.
✓ Branch 4 taken 206986 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 206986 times.
✗ Branch 7 not taken.
|
413972 | ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) |
| 492 | } | ||
| 493 | 206973 | break; | |
| 494 | 42 | case 17: | |
| 495 | 42 | bytestream2_put_byte(pb, 0x20 | (blocks - 1)); | |
| 496 |
6/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 42 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
|
91 | ADVANCE_BLOCK(pixel_ptr, row_ptr, blocks) |
| 497 | 42 | break; | |
| 498 | ✗ | case 18: | |
| 499 | ✗ | bytestream2_put_byte(pb, 0x30); | |
| 500 | ✗ | bytestream2_put_byte(pb, blocks - 1); | |
| 501 | ✗ | ADVANCE_BLOCK(pixel_ptr, row_ptr, blocks) | |
| 502 | ✗ | break; | |
| 503 | 8375 | case 19: | |
| 504 | 8375 | bytestream2_put_byte(pb, 0x00 | (blocks - 1)); | |
| 505 |
6/8✓ Branch 0 taken 27 times.
✓ Branch 1 taken 11155 times.
✓ Branch 2 taken 11182 times.
✓ Branch 3 taken 8375 times.
✓ Branch 4 taken 11182 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11182 times.
✗ Branch 7 not taken.
|
19557 | ADVANCE_BLOCK(pixel_ptr, row_ptr, blocks) |
| 506 | 8375 | break; | |
| 507 | 2 | case 20: | |
| 508 | 2 | bytestream2_put_byte(pb, 0x10); | |
| 509 | 2 | bytestream2_put_byte(pb, blocks - 1); | |
| 510 |
5/8✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
|
38 | ADVANCE_BLOCK(pixel_ptr, row_ptr, blocks) |
| 511 | 2 | break; | |
| 512 | } | ||
| 513 | |||
| 514 | 889064 | block_counter += blocks; | |
| 515 | } | ||
| 516 | 200 | } | |
| 517 | |||
| 518 | 4 | static av_cold int smc_encode_init(AVCodecContext *avctx) | |
| 519 | { | ||
| 520 | 4 | SMCContext *s = avctx->priv_data; | |
| 521 | |||
| 522 | 4 | avctx->bits_per_coded_sample = 8; | |
| 523 | |||
| 524 | 4 | s->prev_frame = av_frame_alloc(); | |
| 525 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!s->prev_frame) |
| 526 | ✗ | return AVERROR(ENOMEM); | |
| 527 | |||
| 528 | 4 | return 0; | |
| 529 | } | ||
| 530 | |||
| 531 | 200 | static int smc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |
| 532 | const AVFrame *frame, int *got_packet) | ||
| 533 | { | ||
| 534 | 200 | SMCContext *s = avctx->priv_data; | |
| 535 | 200 | const AVFrame *pict = frame; | |
| 536 | PutByteContext pb; | ||
| 537 | uint8_t *pal; | ||
| 538 | int ret; | ||
| 539 | |||
| 540 | 200 | ret = ff_alloc_packet(avctx, pkt, 8LL * avctx->height * avctx->width); | |
| 541 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
|
200 | if (ret < 0) |
| 542 | ✗ | return ret; | |
| 543 | |||
| 544 |
3/4✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 196 times.
✓ Branch 3 taken 4 times.
|
200 | if (avctx->gop_size == 0 || !s->prev_frame->data[0] || |
| 545 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 180 times.
|
196 | (avctx->frame_num % avctx->gop_size) == 0) { |
| 546 | 20 | s->key_frame = 1; | |
| 547 | } else { | ||
| 548 | 180 | s->key_frame = 0; | |
| 549 | } | ||
| 550 | |||
| 551 | 200 | bytestream2_init_writer(&pb, pkt->data, pkt->size); | |
| 552 | |||
| 553 | 200 | bytestream2_put_be32(&pb, 0x00); | |
| 554 | |||
| 555 | 200 | pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); | |
| 556 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
|
200 | if (!pal) |
| 557 | ✗ | return AVERROR(ENOMEM); | |
| 558 | 200 | memcpy(pal, frame->data[1], AVPALETTE_SIZE); | |
| 559 | |||
| 560 | 200 | smc_encode_stream(s, pict, &pb); | |
| 561 | |||
| 562 | 200 | av_shrink_packet(pkt, bytestream2_tell_p(&pb)); | |
| 563 | |||
| 564 | 200 | pkt->data[0] = 0x0; | |
| 565 | |||
| 566 | // write chunk length | ||
| 567 | 200 | AV_WB24(pkt->data + 1, pkt->size); | |
| 568 | |||
| 569 | 200 | ret = av_frame_replace(s->prev_frame, frame); | |
| 570 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
|
200 | if (ret < 0) { |
| 571 | ✗ | av_log(avctx, AV_LOG_ERROR, "cannot add reference\n"); | |
| 572 | ✗ | return ret; | |
| 573 | } | ||
| 574 | |||
| 575 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 180 times.
|
200 | if (s->key_frame) |
| 576 | 20 | pkt->flags |= AV_PKT_FLAG_KEY; | |
| 577 | |||
| 578 | 200 | *got_packet = 1; | |
| 579 | |||
| 580 | 200 | return 0; | |
| 581 | } | ||
| 582 | |||
| 583 | 4 | static av_cold int smc_encode_end(AVCodecContext *avctx) | |
| 584 | { | ||
| 585 | 4 | SMCContext *s = avctx->priv_data; | |
| 586 | |||
| 587 | 4 | av_frame_free(&s->prev_frame); | |
| 588 | |||
| 589 | 4 | return 0; | |
| 590 | } | ||
| 591 | |||
| 592 | const FFCodec ff_smc_encoder = { | ||
| 593 | .p.name = "smc", | ||
| 594 | CODEC_LONG_NAME("QuickTime Graphics (SMC)"), | ||
| 595 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 596 | .p.id = AV_CODEC_ID_SMC, | ||
| 597 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
| 598 | .priv_data_size = sizeof(SMCContext), | ||
| 599 | .init = smc_encode_init, | ||
| 600 | FF_CODEC_ENCODE_CB(smc_encode_frame), | ||
| 601 | .close = smc_encode_end, | ||
| 602 | CODEC_PIXFMTS(AV_PIX_FMT_PAL8), | ||
| 603 | }; | ||
| 604 |