Makes it easier to work with, despite the heavy ifdeffery.
Showing the changes to libavcodec/vulkan (6 of 7 files). Show all
Unified · Split
| @@ -6,10 +6,8 @@ clean:: · 5 unmodified lines | ||
| 6 | 6 | OBJS-$(CONFIG_FFV1_VULKAN_ENCODER) += vulkan/common.o \ |
| 7 | 7 | vulkan/rangecoder.o vulkan/ffv1_vlc.o \ |
| 8 | 8 | vulkan/ffv1_common.o vulkan/ffv1_reset.o \ |
| 9 | − vulkan/ffv1_enc_common.o \ | |
| 10 | 9 | vulkan/ffv1_enc_rct.o vulkan/ffv1_enc_setup.o \ |
| 11 | − vulkan/ffv1_enc_vlc.o vulkan/ffv1_enc_ac.o \ | |
| 12 | − vulkan/ffv1_enc.o vulkan/ffv1_enc_rgb.o | |
| 10 | + vulkan/ffv1_enc.o | |
| 13 | 11 | |
| 14 | 12 | OBJS-$(CONFIG_FFV1_VULKAN_HWACCEL) += vulkan/common.o \ |
| 15 | 13 | vulkan/rangecoder.o vulkan/ffv1_vlc.o \ |
| @@ -20,12 +20,186 @@ · 19 unmodified lines | ||
| 20 | 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 21 | 21 | */ |
| 22 | 22 | |
| 23 | +ivec2 get_diff(ivec2 pos, ivec2 off, int p, int comp, int sw, int bits) | |
| 24 | +{ | |
| 25 | + const ivec2 yoff_border1 = off.x == 0 ? ivec2(1, -1) : ivec2(0, 0); | |
| 26 | + const ivec2 yoff_border2 = off.x == 1 ? ivec2(1, -1) : ivec2(0, 0); | |
| 27 | + | |
| 28 | + TYPE top2 = TYPE(0); | |
| 29 | + if (off.y > 1) | |
| 30 | + top2 = TYPE(imageLoad(src[p], pos + ivec2(0, -2))[comp]); | |
| 31 | + | |
| 32 | + VTYPE3 top = VTYPE3(TYPE(0), | |
| 33 | + TYPE(0), | |
| 34 | + TYPE(0)); | |
| 35 | + if (off.y > 0 && off != ivec2(0, 1)) | |
| 36 | + top[0] = TYPE(imageLoad(src[p], pos + ivec2(-1, -1) + yoff_border1)[comp]); | |
| 37 | + if (off.y > 0) { | |
| 38 | + top[1] = TYPE(imageLoad(src[p], pos + ivec2(0, -1))[comp]); | |
| 39 | + top[2] = TYPE(imageLoad(src[p], pos + ivec2(min(1, sw - off.x - 1), -1))[comp]); | |
| 40 | + } | |
| 41 | + | |
| 42 | + VTYPE3 cur = VTYPE3(TYPE(0), | |
| 43 | + TYPE(0), | |
| 44 | + imageLoad(src[p], pos)[comp]); | |
| 45 | + if (off.x > 0 && off != ivec2(1, 0)) | |
| 46 | + cur[0] = TYPE(imageLoad(src[p], pos + ivec2(-2, 0) + yoff_border2)[comp]); | |
| 47 | + if (off != ivec2(0, 0)) | |
| 48 | + cur[1] = TYPE(imageLoad(src[p], pos + ivec2(-1, 0) + yoff_border1)[comp]); | |
| 49 | + | |
| 50 | + /* context, diff */ | |
| 51 | + ivec2 d = ivec2(get_context(VTYPE2(cur), top, top2, context_model), | |
| 52 | + cur[2] - predict(cur[1], VTYPE2(top))); | |
| 53 | + | |
| 54 | + if (d[0] < 0) | |
| 55 | + d = -d; | |
| 56 | + | |
| 57 | + d[1] = fold(d[1], bits); | |
| 58 | + | |
| 59 | + return d; | |
| 60 | +} | |
| 61 | + | |
| 62 | +#ifndef GOLOMB | |
| 63 | +void put_rac(inout RangeCoder c, uint64_t state, bool bit) | |
| 64 | +{ | |
| 65 | + put_rac_norenorm(c, state, bit); | |
| 66 | + if (c.range < 0x100) | |
| 67 | + renorm_encoder(c); | |
| 68 | +} | |
| 69 | + | |
| 70 | +/* Note - only handles signed values */ | |
| 71 | +void put_symbol(inout RangeCoder c, uint64_t state, int v) | |
| 72 | +{ | |
| 73 | + bool is_nil = (v == 0); | |
| 74 | + put_rac(c, state, is_nil); | |
| 75 | + if (is_nil) | |
| 76 | + return; | |
| 77 | + | |
| 78 | + const int a = abs(v); | |
| 79 | + const int e = findMSB(a); | |
| 80 | + | |
| 81 | + state += 1; | |
| 82 | + for (int i = 0; i < e; i++) | |
| 83 | + put_rac(c, state + min(i, 9), true); | |
| 84 | + put_rac(c, state + min(e, 9), false); | |
| 85 | + | |
| 86 | + state += 21; | |
| 87 | + for (int i = e - 1; i >= 0; i--) | |
| 88 | + put_rac(c, state + min(i, 9), bool(bitfieldExtract(a, i, 1))); | |
| 89 | + | |
| 90 | + put_rac(c, state - 11 + min(e, 10), v < 0); | |
| 91 | +} | |
| 92 | + | |
| 93 | +void encode_line_pcm(inout SliceContext sc, int y, int p, int comp, | |
| 94 | + int bits) | |
| 95 | +{ | |
| 96 | + ivec2 sp = sc.slice_pos; | |
| 97 | + int w = sc.slice_dim.x; | |
| 98 | + if (p > 0 && p < 3) { | |
| 99 | + w >>= chroma_shift.x; | |
| 100 | + sp >>= chroma_shift; | |
| 101 | + } | |
| 102 | + | |
| 103 | + for (int x = 0; x < w; x++) { | |
| 104 | + uint v = imageLoad(src[p], (sp + ivec2(x, y)))[comp]; | |
| 105 | + for (int i = (bits - 1); i >= 0; i--) | |
| 106 | + put_rac_equi(sc.c, bool(bitfieldExtract(v, i, 1))); | |
| 107 | + } | |
| 108 | +} | |
| 109 | + | |
| 110 | +void encode_line(inout SliceContext sc, uint64_t state, | |
| 111 | + int y, int p, int comp, int bits, const int run_index) | |
| 112 | +{ | |
| 113 | + ivec2 sp = sc.slice_pos; | |
| 114 | + | |
| 115 | + int w = sc.slice_dim.x; | |
| 116 | + if (p > 0 && p < 3) { | |
| 117 | + w >>= chroma_shift.x; | |
| 118 | + sp >>= chroma_shift; | |
| 119 | + } | |
| 120 | + | |
| 121 | + for (int x = 0; x < w; x++) { | |
| 122 | + const ivec2 d = get_diff(sp + ivec2(x, y), ivec2(x, y), p, comp, w, bits); | |
| 123 | + put_symbol(sc.c, state + CONTEXT_SIZE*d[0], d[1]); | |
| 124 | + } | |
| 125 | +} | |
| 126 | + | |
| 127 | +#else /* GOLOMB */ | |
| 128 | + | |
| 129 | +void encode_line(inout SliceContext sc, uint64_t state, | |
| 130 | + int y, int p, int comp, int bits, inout int run_index) | |
| 131 | +{ | |
| 132 | + ivec2 sp = sc.slice_pos; | |
| 133 | + | |
| 134 | + int w = sc.slice_dim.x; | |
| 135 | + if (p > 0 && p < 3) { | |
| 136 | + w >>= chroma_shift.x; | |
| 137 | + sp >>= chroma_shift; | |
| 138 | + } | |
| 139 | + | |
| 140 | + int run_count = 0; | |
| 141 | + bool run_mode = false; | |
| 142 | + | |
| 143 | + for (int x = 0; x < w; x++) { | |
| 144 | + ivec2 d = get_diff(sp + ivec2(x, y), ivec2(x, y), p, comp, w, bits); | |
| 145 | + | |
| 146 | + if (d[0] == 0) | |
| 147 | + run_mode = true; | |
| 148 | + | |
| 149 | + if (run_mode) { | |
| 150 | + if (d[1] != 0) { | |
| 151 | + /* A very unlikely loop */ | |
| 152 | + while (run_count >= 1 << log2_run[run_index]) { | |
| 153 | + run_count -= 1 << log2_run[run_index]; | |
| 154 | + run_index++; | |
| 155 | + put_bits(sc.pb, 1, 1); | |
| 156 | + } | |
| 157 | + | |
| 158 | + put_bits(sc.pb, 1 + log2_run[run_index], run_count); | |
| 159 | + if (run_index != 0) | |
| 160 | + run_index--; | |
| 161 | + run_count = 0; | |
| 162 | + run_mode = false; | |
| 163 | + if (d[1] > 0) | |
| 164 | + d[1]--; | |
| 165 | + } else { | |
| 166 | + run_count++; | |
| 167 | + } | |
| 168 | + } | |
| 169 | + | |
| 170 | + if (!run_mode) { | |
| 171 | + VlcState sb = VlcState(state + VLC_STATE_SIZE*d[0]); | |
| 172 | + Symbol sym = get_vlc_symbol(sb, d[1], bits); | |
| 173 | + put_bits(sc.pb, sym.bits, sym.val); | |
| 174 | + } | |
| 175 | + } | |
| 176 | + | |
| 177 | + if (run_mode) { | |
| 178 | + while (run_count >= (1 << log2_run[run_index])) { | |
| 179 | + run_count -= 1 << log2_run[run_index]; | |
| 180 | + run_index++; | |
| 181 | + put_bits(sc.pb, 1, 1); | |
| 182 | + } | |
| 183 | + | |
| 184 | + if (run_count > 0) | |
| 185 | + put_bits(sc.pb, 1, 1); | |
| 186 | + } | |
| 187 | +} | |
| 188 | +#endif | |
| 189 | + | |
| 23 | 190 | void encode_slice(inout SliceContext sc, const uint slice_idx) |
| 24 | 191 | { |
| 192 | +#ifndef RGB | |
| 25 | 193 | int bits = bits_per_raw_sample; |
| 194 | +#else | |
| 195 | + int bits = 9; | |
| 196 | + if (bits != 8 || sc.slice_coding_mode != 0) | |
| 197 | + bits = bits_per_raw_sample + int(sc.slice_coding_mode != 1); | |
| 198 | +#endif | |
| 26 | 199 | |
| 27 | 200 | #ifndef GOLOMB |
| 28 | 201 | if (sc.slice_coding_mode == 1) { |
| 202 | +#ifndef RGB | |
| 29 | 203 | for (int c = 0; c < components; c++) { |
| 30 | 204 | |
| 31 | 205 | int h = sc.slice_dim.y; |
| @@ -39,12 +213,22 @@ void encode_slice(inout SliceContext sc, const uint slice_idx) · 7 unmodified lines | ||
| 39 | 213 | for (int y = 0; y < h; y++) |
| 40 | 214 | encode_line_pcm(sc, y, p, comp, bits); |
| 41 | 215 | } |
| 216 | +#else | |
| 217 | + for (int y = 0; y < sc.slice_dim.y; y++) { | |
| 218 | + encode_line_pcm(sc, y, 0, 1, bits); | |
| 219 | + encode_line_pcm(sc, y, 0, 2, bits); | |
| 220 | + encode_line_pcm(sc, y, 0, 0, bits); | |
| 221 | + if (transparency == 1) | |
| 222 | + encode_line_pcm(sc, y, 0, 3, bits); | |
| 223 | + } | |
| 224 | +#endif | |
| 42 | 225 | } else |
| 43 | 226 | #endif |
| 44 | 227 | { |
| 45 | 228 | uint64_t slice_state_off = uint64_t(slice_state) + |
| 46 | 229 | slice_idx*plane_state_size*codec_planes; |
| 47 | 230 | |
| 231 | +#ifndef RGB | |
| 48 | 232 | for (int c = 0; c < components; c++) { |
| 49 | 233 | int run_index = 0; |
| 50 | 234 | |
| @@ -62,13 +246,67 @@ void encode_slice(inout SliceContext sc, const uint slice_idx) · 11 unmodified lines | ||
| 62 | 246 | if (c != 1) |
| 63 | 247 | slice_state_off += plane_state_size; |
| 64 | 248 | } |
| 249 | +#else | |
| 250 | + int run_index = 0; | |
| 251 | + for (int y = 0; y < sc.slice_dim.y; y++) { | |
| 252 | + encode_line(sc, slice_state_off + plane_state_size*0, | |
| 253 | + y, 0, 1, bits, run_index); | |
| 254 | + encode_line(sc, slice_state_off + plane_state_size*1, | |
| 255 | + y, 0, 2, bits, run_index); | |
| 256 | + encode_line(sc, slice_state_off + plane_state_size*1, | |
| 257 | + y, 0, 0, bits, run_index); | |
| 258 | + if (transparency == 1) | |
| 259 | + encode_line(sc, slice_state_off + plane_state_size*2, | |
| 260 | + y, 0, 3, bits, run_index); | |
| 261 | + } | |
| 262 | +#endif | |
| 263 | + } | |
| 264 | +} | |
| 265 | + | |
| 266 | +void finalize_slice(inout SliceContext sc, const uint slice_idx) | |
| 267 | +{ | |
| 268 | +#ifdef GOLOMB | |
| 269 | + uint32_t enc_len = sc.hdr_len + flush_put_bits(sc.pb); | |
| 270 | +#else | |
| 271 | + uint32_t enc_len = rac_terminate(sc.c); | |
| 272 | +#endif | |
| 273 | + | |
| 274 | + u8buf bs = u8buf(sc.c.bytestream_start); | |
| 275 | + | |
| 276 | + /* Append slice length */ | |
| 277 | + u8vec4 enc_len_p = unpack8(enc_len); | |
| 278 | + bs[enc_len + 0].v = enc_len_p.z; | |
| 279 | + bs[enc_len + 1].v = enc_len_p.y; | |
| 280 | + bs[enc_len + 2].v = enc_len_p.x; | |
| 281 | + enc_len += 3; | |
| 282 | + | |
| 283 | + /* Calculate and write CRC */ | |
| 284 | + if (ec != 0) { | |
| 285 | + bs[enc_len].v = uint8_t(0); | |
| 286 | + enc_len++; | |
| 287 | + | |
| 288 | + uint32_t crc = crcref; | |
| 289 | + for (int i = 0; i < enc_len; i++) | |
| 290 | + crc = crc_ieee[(crc & 0xFF) ^ uint32_t(bs[i].v)] ^ (crc >> 8); | |
| 291 | + | |
| 292 | + if (crcref != 0x00000000) | |
| 293 | + crc ^= 0x8CD88196; | |
| 294 | + | |
| 295 | + u8vec4 crc_p = unpack8(crc); | |
| 296 | + bs[enc_len + 0].v = crc_p.x; | |
| 297 | + bs[enc_len + 1].v = crc_p.y; | |
| 298 | + bs[enc_len + 2].v = crc_p.z; | |
| 299 | + bs[enc_len + 3].v = crc_p.w; | |
| 300 | + enc_len += 4; | |
| 65 | 301 | } |
| 66 | 302 | |
| 67 | − finalize_slice(sc, slice_idx); | |
| 303 | + slice_results[slice_idx*2 + 0] = enc_len; | |
| 304 | + slice_results[slice_idx*2 + 1] = uint64_t(bs) - uint64_t(out_data); | |
| 68 | 305 | } |
| 69 | 306 | |
| 70 | 307 | void main(void) |
| 71 | 308 | { |
| 72 | 309 | const uint slice_idx = gl_WorkGroupID.y*gl_NumWorkGroups.x + gl_WorkGroupID.x; |
| 73 | 310 | encode_slice(slice_ctx[slice_idx], slice_idx); |
| 311 | + finalize_slice(slice_ctx[slice_idx], slice_idx); | |
| 74 | 312 | } |
| @@ -1,83 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2024 Lynne <dev@lynne.ee> | |
| 3 | − * | |
| 4 | − * This file is part of FFmpeg. | |
| 5 | − * | |
| 6 | − * FFmpeg is free software; you can redistribute it and/or | |
| 7 | − * modify it under the terms of the GNU Lesser General Public | |
| 8 | − * License as published by the Free Software Foundation; either | |
| 9 | − * version 2.1 of the License, or (at your option) any later version. | |
| 10 | − * | |
| 11 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 12 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | − * Lesser General Public License for more details. | |
| 15 | − * | |
| 16 | − * You should have received a copy of the GNU Lesser General Public | |
| 17 | − * License along with FFmpeg; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 19 | − */ | |
| 20 | − | |
| 21 | −void put_rac(inout RangeCoder c, uint64_t state, bool bit) | |
| 22 | −{ | |
| 23 | − put_rac_norenorm(c, state, bit); | |
| 24 | − if (c.range < 0x100) | |
| 25 | − renorm_encoder(c); | |
| 26 | −} | |
| 27 | − | |
| 28 | −/* Note - only handles signed values */ | |
| 29 | −void put_symbol(inout RangeCoder c, uint64_t state, int v) | |
| 30 | −{ | |
| 31 | − bool is_nil = (v == 0); | |
| 32 | − put_rac(c, state, is_nil); | |
| 33 | − if (is_nil) | |
| 34 | − return; | |
| 35 | − | |
| 36 | − const int a = abs(v); | |
| 37 | − const int e = findMSB(a); | |
| 38 | − | |
| 39 | − state += 1; | |
| 40 | − for (int i = 0; i < e; i++) | |
| 41 | − put_rac(c, state + min(i, 9), true); | |
| 42 | − put_rac(c, state + min(e, 9), false); | |
| 43 | − | |
| 44 | − state += 21; | |
| 45 | − for (int i = e - 1; i >= 0; i--) | |
| 46 | − put_rac(c, state + min(i, 9), bool(bitfieldExtract(a, i, 1))); | |
| 47 | − | |
| 48 | − put_rac(c, state - 11 + min(e, 10), v < 0); | |
| 49 | −} | |
| 50 | − | |
| 51 | −void encode_line_pcm(inout SliceContext sc, int y, int p, int comp, | |
| 52 | − int bits) | |
| 53 | −{ | |
| 54 | − ivec2 sp = sc.slice_pos; | |
| 55 | − int w = sc.slice_dim.x; | |
| 56 | − if (p > 0 && p < 3) { | |
| 57 | − w >>= chroma_shift.x; | |
| 58 | − sp >>= chroma_shift; | |
| 59 | − } | |
| 60 | − | |
| 61 | − for (int x = 0; x < w; x++) { | |
| 62 | − uint v = imageLoad(src[p], (sp + ivec2(x, y)))[comp]; | |
| 63 | − for (int i = (bits - 1); i >= 0; i--) | |
| 64 | − put_rac_equi(sc.c, bool(bitfieldExtract(v, i, 1))); | |
| 65 | − } | |
| 66 | −} | |
| 67 | − | |
| 68 | −void encode_line(inout SliceContext sc, uint64_t state, | |
| 69 | − int y, int p, int comp, int bits, const int run_index) | |
| 70 | −{ | |
| 71 | − ivec2 sp = sc.slice_pos; | |
| 72 | − | |
| 73 | − int w = sc.slice_dim.x; | |
| 74 | − if (p > 0 && p < 3) { | |
| 75 | − w >>= chroma_shift.x; | |
| 76 | − sp >>= chroma_shift; | |
| 77 | − } | |
| 78 | − | |
| 79 | − for (int x = 0; x < w; x++) { | |
| 80 | − const ivec2 d = get_diff(sp + ivec2(x, y), ivec2(x, y), p, comp, w, bits); | |
| 81 | − put_symbol(sc.c, state + CONTEXT_SIZE*d[0], d[1]); | |
| 82 | − } | |
| 83 | −} | |
| @@ -1,101 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * FFv1 codec | |
| 3 | − * | |
| 4 | − * Copyright (c) 2024 Lynne <dev@lynne.ee> | |
| 5 | − * | |
| 6 | − * This file is part of FFmpeg. | |
| 7 | − * | |
| 8 | − * FFmpeg is free software; you can redistribute it and/or | |
| 9 | − * modify it under the terms of the GNU Lesser General Public | |
| 10 | − * License as published by the Free Software Foundation; either | |
| 11 | − * version 2.1 of the License, or (at your option) any later version. | |
| 12 | − * | |
| 13 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 14 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 16 | − * Lesser General Public License for more details. | |
| 17 | − * | |
| 18 | − * You should have received a copy of the GNU Lesser General Public | |
| 19 | − * License along with FFmpeg; if not, write to the Free Software | |
| 20 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 21 | − */ | |
| 22 | − | |
| 23 | −ivec2 get_diff(ivec2 pos, ivec2 off, int p, int comp, int sw, int bits) | |
| 24 | −{ | |
| 25 | − const ivec2 yoff_border1 = off.x == 0 ? ivec2(1, -1) : ivec2(0, 0); | |
| 26 | − const ivec2 yoff_border2 = off.x == 1 ? ivec2(1, -1) : ivec2(0, 0); | |
| 27 | − | |
| 28 | − TYPE top2 = TYPE(0); | |
| 29 | − if (off.y > 1) | |
| 30 | − top2 = TYPE(imageLoad(src[p], pos + ivec2(0, -2))[comp]); | |
| 31 | − | |
| 32 | − VTYPE3 top = VTYPE3(TYPE(0), | |
| 33 | − TYPE(0), | |
| 34 | − TYPE(0)); | |
| 35 | − if (off.y > 0 && off != ivec2(0, 1)) | |
| 36 | − top[0] = TYPE(imageLoad(src[p], pos + ivec2(-1, -1) + yoff_border1)[comp]); | |
| 37 | − if (off.y > 0) { | |
| 38 | − top[1] = TYPE(imageLoad(src[p], pos + ivec2(0, -1))[comp]); | |
| 39 | − top[2] = TYPE(imageLoad(src[p], pos + ivec2(min(1, sw - off.x - 1), -1))[comp]); | |
| 40 | − } | |
| 41 | − | |
| 42 | − VTYPE3 cur = VTYPE3(TYPE(0), | |
| 43 | − TYPE(0), | |
| 44 | − imageLoad(src[p], pos)[comp]); | |
| 45 | − if (off.x > 0 && off != ivec2(1, 0)) | |
| 46 | − cur[0] = TYPE(imageLoad(src[p], pos + ivec2(-2, 0) + yoff_border2)[comp]); | |
| 47 | − if (off != ivec2(0, 0)) | |
| 48 | − cur[1] = TYPE(imageLoad(src[p], pos + ivec2(-1, 0) + yoff_border1)[comp]); | |
| 49 | − | |
| 50 | − /* context, diff */ | |
| 51 | − ivec2 d = ivec2(get_context(VTYPE2(cur), top, top2, context_model), | |
| 52 | − cur[2] - predict(cur[1], VTYPE2(top))); | |
| 53 | − | |
| 54 | − if (d[0] < 0) | |
| 55 | − d = -d; | |
| 56 | − | |
| 57 | − d[1] = fold(d[1], bits); | |
| 58 | − | |
| 59 | − return d; | |
| 60 | −} | |
| 61 | − | |
| 62 | −void finalize_slice(inout SliceContext sc, const uint slice_idx) | |
| 63 | −{ | |
| 64 | −#ifdef GOLOMB | |
| 65 | − uint32_t enc_len = sc.hdr_len + flush_put_bits(sc.pb); | |
| 66 | −#else | |
| 67 | − uint32_t enc_len = rac_terminate(sc.c); | |
| 68 | −#endif | |
| 69 | − | |
| 70 | − u8buf bs = u8buf(sc.c.bytestream_start); | |
| 71 | − | |
| 72 | − /* Append slice length */ | |
| 73 | − u8vec4 enc_len_p = unpack8(enc_len); | |
| 74 | − bs[enc_len + 0].v = enc_len_p.z; | |
| 75 | − bs[enc_len + 1].v = enc_len_p.y; | |
| 76 | − bs[enc_len + 2].v = enc_len_p.x; | |
| 77 | − enc_len += 3; | |
| 78 | − | |
| 79 | − /* Calculate and write CRC */ | |
| 80 | − if (ec != 0) { | |
| 81 | − bs[enc_len].v = uint8_t(0); | |
| 82 | − enc_len++; | |
| 83 | − | |
| 84 | − uint32_t crc = crcref; | |
| 85 | − for (int i = 0; i < enc_len; i++) | |
| 86 | − crc = crc_ieee[(crc & 0xFF) ^ uint32_t(bs[i].v)] ^ (crc >> 8); | |
| 87 | − | |
| 88 | − if (crcref != 0x00000000) | |
| 89 | − crc ^= 0x8CD88196; | |
| 90 | − | |
| 91 | − u8vec4 crc_p = unpack8(crc); | |
| 92 | − bs[enc_len + 0].v = crc_p.x; | |
| 93 | − bs[enc_len + 1].v = crc_p.y; | |
| 94 | − bs[enc_len + 2].v = crc_p.z; | |
| 95 | − bs[enc_len + 3].v = crc_p.w; | |
| 96 | − enc_len += 4; | |
| 97 | − } | |
| 98 | − | |
| 99 | − slice_results[slice_idx*2 + 0] = enc_len; | |
| 100 | − slice_results[slice_idx*2 + 1] = uint64_t(bs) - uint64_t(out_data); | |
| 101 | −} | |
| @@ -1,83 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * FFv1 codec | |
| 3 | − * | |
| 4 | − * Copyright (c) 2024 Lynne <dev@lynne.ee> | |
| 5 | − * | |
| 6 | − * This file is part of FFmpeg. | |
| 7 | − * | |
| 8 | − * FFmpeg is free software; you can redistribute it and/or | |
| 9 | − * modify it under the terms of the GNU Lesser General Public | |
| 10 | − * License as published by the Free Software Foundation; either | |
| 11 | − * version 2.1 of the License, or (at your option) any later version. | |
| 12 | − * | |
| 13 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 14 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 16 | − * Lesser General Public License for more details. | |
| 17 | − * | |
| 18 | − * You should have received a copy of the GNU Lesser General Public | |
| 19 | − * License along with FFmpeg; if not, write to the Free Software | |
| 20 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 21 | − */ | |
| 22 | − | |
| 23 | −void encode_slice_rgb(inout SliceContext sc, const uint slice_idx) | |
| 24 | −{ | |
| 25 | − int bits = 9; | |
| 26 | − if (bits != 8 || sc.slice_coding_mode != 0) | |
| 27 | − bits = bits_per_raw_sample + int(sc.slice_coding_mode != 1); | |
| 28 | − | |
| 29 | − int run_index = 0; | |
| 30 | − | |
| 31 | −#ifndef GOLOMB | |
| 32 | − if (sc.slice_coding_mode == 1) { | |
| 33 | − if (transparency == 1) { | |
| 34 | − for (int y = 0; y < sc.slice_dim.y; y++) { | |
| 35 | − encode_line_pcm(sc, y, 0, 1, bits); | |
| 36 | − encode_line_pcm(sc, y, 0, 2, bits); | |
| 37 | − encode_line_pcm(sc, y, 0, 0, bits); | |
| 38 | − encode_line_pcm(sc, y, 0, 3, bits); | |
| 39 | − } | |
| 40 | − } else { | |
| 41 | − for (int y = 0; y < sc.slice_dim.y; y++) { | |
| 42 | − encode_line_pcm(sc, y, 0, 1, bits); | |
| 43 | − encode_line_pcm(sc, y, 0, 2, bits); | |
| 44 | − encode_line_pcm(sc, y, 0, 0, bits); | |
| 45 | − } | |
| 46 | − } | |
| 47 | − } else | |
| 48 | −#endif | |
| 49 | − { | |
| 50 | − uint64_t slice_state_off = uint64_t(slice_state) + | |
| 51 | − slice_idx*plane_state_size*codec_planes; | |
| 52 | − | |
| 53 | − if (transparency == 1) { | |
| 54 | − for (int y = 0; y < sc.slice_dim.y; y++) { | |
| 55 | − encode_line(sc, slice_state_off + plane_state_size*0, | |
| 56 | − y, 0, 1, bits, run_index); | |
| 57 | − encode_line(sc, slice_state_off + plane_state_size*1, | |
| 58 | − y, 0, 2, bits, run_index); | |
| 59 | − encode_line(sc, slice_state_off + plane_state_size*1, | |
| 60 | − y, 0, 0, bits, run_index); | |
| 61 | − encode_line(sc, slice_state_off + plane_state_size*2, | |
| 62 | − y, 0, 3, bits, run_index); | |
| 63 | − } | |
| 64 | − } else { | |
| 65 | − for (int y = 0; y < sc.slice_dim.y; y++) { | |
| 66 | − encode_line(sc, slice_state_off + plane_state_size*0, | |
| 67 | − y, 0, 1, bits, run_index); | |
| 68 | − encode_line(sc, slice_state_off + plane_state_size*1, | |
| 69 | − y, 0, 2, bits, run_index); | |
| 70 | − encode_line(sc, slice_state_off + plane_state_size*1, | |
| 71 | − y, 0, 0, bits, run_index); | |
| 72 | − } | |
| 73 | − } | |
| 74 | − } | |
| 75 | − | |
| 76 | − finalize_slice(sc, slice_idx); | |
| 77 | −} | |
| 78 | − | |
| 79 | −void main(void) | |
| 80 | −{ | |
| 81 | − const uint slice_idx = gl_WorkGroupID.y*gl_NumWorkGroups.x + gl_WorkGroupID.x; | |
| 82 | − encode_slice_rgb(slice_ctx[slice_idx], slice_idx); | |
| 83 | −} | |
| @@ -1,112 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * FFv1 codec | |
| 3 | − * | |
| 4 | − * Copyright (c) 2024 Lynne <dev@lynne.ee> | |
| 5 | − * | |
| 6 | − * This file is part of FFmpeg. | |
| 7 | − * | |
| 8 | − * FFmpeg is free software; you can redistribute it and/or | |
| 9 | − * modify it under the terms of the GNU Lesser General Public | |
| 10 | − * License as published by the Free Software Foundation; either | |
| 11 | − * version 2.1 of the License, or (at your option) any later version. | |
| 12 | − * | |
| 13 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 14 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 16 | − * Lesser General Public License for more details. | |
| 17 | − * | |
| 18 | − * You should have received a copy of the GNU Lesser General Public | |
| 19 | − * License along with FFmpeg; if not, write to the Free Software | |
| 20 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 21 | − */ | |
| 22 | − | |
| 23 | −struct RLEState { | |
| 24 | − int count; | |
| 25 | − int diff; | |
| 26 | − int index; | |
| 27 | − bool mode; | |
| 28 | −}; | |
| 29 | − | |
| 30 | −void calc_new_state(inout RLEState state, int context) | |
| 31 | −{ | |
| 32 | − if (context == 0) | |
| 33 | − state.mode = false; | |
| 34 | − | |
| 35 | − if (!state.mode) | |
| 36 | − return; | |
| 37 | − | |
| 38 | − if (state.diff > 0) { | |
| 39 | − while (state.count >= (1 << log2_run[state.index])) { | |
| 40 | − state.count -= 1 << log2_run[state.index]; | |
| 41 | − state.index++; | |
| 42 | − } | |
| 43 | − if (state.index > 0) | |
| 44 | − state.index--; | |
| 45 | − state.count = 0; | |
| 46 | − state.mode = false; | |
| 47 | − if (state.diff > 0) | |
| 48 | − state.diff--; | |
| 49 | − } else { | |
| 50 | − state.count++; | |
| 51 | − } | |
| 52 | −} | |
| 53 | − | |
| 54 | −void encode_line(inout SliceContext sc, uint64_t state, | |
| 55 | − int y, int p, int comp, int bits, inout int run_index) | |
| 56 | −{ | |
| 57 | − ivec2 sp = sc.slice_pos; | |
| 58 | − | |
| 59 | − int w = sc.slice_dim.x; | |
| 60 | − if (p > 0 && p < 3) { | |
| 61 | − w >>= chroma_shift.x; | |
| 62 | − sp >>= chroma_shift; | |
| 63 | − } | |
| 64 | − | |
| 65 | − int run_count = 0; | |
| 66 | − bool run_mode = false; | |
| 67 | − | |
| 68 | − for (int x = 0; x < w; x++) { | |
| 69 | − ivec2 d = get_diff(sp + ivec2(x, y), ivec2(x, y), p, comp, w, bits); | |
| 70 | − | |
| 71 | − if (d[0] == 0) | |
| 72 | − run_mode = true; | |
| 73 | − | |
| 74 | − if (run_mode) { | |
| 75 | − if (d[1] != 0) { | |
| 76 | − /* A very unlikely loop */ | |
| 77 | − while (run_count >= 1 << log2_run[run_index]) { | |
| 78 | − run_count -= 1 << log2_run[run_index]; | |
| 79 | − run_index++; | |
| 80 | − put_bits(sc.pb, 1, 1); | |
| 81 | − } | |
| 82 | − | |
| 83 | − put_bits(sc.pb, 1 + log2_run[run_index], run_count); | |
| 84 | − if (run_index != 0) | |
| 85 | − run_index--; | |
| 86 | − run_count = 0; | |
| 87 | − run_mode = false; | |
| 88 | − if (d[1] > 0) | |
| 89 | − d[1]--; | |
| 90 | − } else { | |
| 91 | − run_count++; | |
| 92 | − } | |
| 93 | − } | |
| 94 | − | |
| 95 | − if (!run_mode) { | |
| 96 | − VlcState sb = VlcState(state + VLC_STATE_SIZE*d[0]); | |
| 97 | − Symbol sym = get_vlc_symbol(sb, d[1], bits); | |
| 98 | − put_bits(sc.pb, sym.bits, sym.val); | |
| 99 | − } | |
| 100 | − } | |
| 101 | − | |
| 102 | − if (run_mode) { | |
| 103 | − while (run_count >= (1 << log2_run[run_index])) { | |
| 104 | − run_count -= 1 << log2_run[run_index]; | |
| 105 | − run_index++; | |
| 106 | − put_bits(sc.pb, 1, 1); | |
| 107 | − } | |
| 108 | − | |
| 109 | − if (run_count > 0) | |
| 110 | − put_bits(sc.pb, 1, 1); | |
| 111 | − } | |
| 112 | −} | |