FFmpeg
Loading...
Searching...
No Matches
magicyuvenc.c
Go to the documentation of this file.
1/*
2 * MagicYUV encoder
3 * Copyright (c) 2017 Paul B Mahol
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#include <stdlib.h>
23#include <string.h>
24
25#include "libavutil/cpu.h"
26#include "libavutil/mem.h"
27#include "libavutil/opt.h"
28#include "libavutil/pixdesc.h"
29#include "libavutil/qsort.h"
30
31#include "avcodec.h"
32#include "bytestream.h"
33#include "codec_internal.h"
34#include "encode.h"
35#include "put_bits.h"
37
38#define MAGICYUV_EXTRADATA_SIZE 32
39
45
46typedef struct HuffEntry {
47 uint8_t len;
48 uint32_t code;
49} HuffEntry;
50
51typedef struct PTable {
52 int value; ///< input value
53 int64_t prob; ///< number of occurrences of this value in input
54} PTable;
55
56typedef struct Slice {
57 int width;
58 int height;
60 unsigned pos;
61 unsigned size;
62 uint8_t *slice;
63 uint8_t *dst;
65} Slice;
66
67typedef struct MagicYUVContext {
68 const AVClass *class;
70 int planes;
71 uint8_t format;
72 int slice_height;
73 int nb_slices;
75 int hshift[4];
76 int vshift[4];
77 uint8_t *decorrelate_buf[2];
79 HuffEntry he[4][256];
81 void (*predict)(struct MagicYUVContext *s, const uint8_t *src, uint8_t *dst,
82 ptrdiff_t stride, int width, int height);
84
86 const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
87 int width, int height)
88{
89 uint8_t prev = 0;
90 int i, j;
91
92 for (i = 0; i < width; i++) {
93 dst[i] = src[i] - prev;
94 prev = src[i];
95 }
96 dst += width;
97 src += stride;
98 for (j = 1; j < height; j++) {
99 prev = src[-stride];
100 for (i = 0; i < width; i++) {
101 dst[i] = src[i] - prev;
102 prev = src[i];
103 }
104 dst += width;
105 src += stride;
106 }
107}
108
110 const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
111 int width, int height)
112{
113 int left = 0, top, lefttop;
114 int i, j;
115
116 for (i = 0; i < width; i++) {
117 dst[i] = src[i] - left;
118 left = src[i];
119 }
120 dst += width;
121 src += stride;
122 for (j = 1; j < height; j++) {
123 top = src[-stride];
124 left = src[0] - top;
125 dst[0] = left;
126 for (i = 1; i < width; i++) {
127 top = src[i - stride];
128 lefttop = src[i - (stride + 1)];
129 left = src[i-1];
130 dst[i] = (src[i] - top) - left + lefttop;
131 }
132 dst += width;
133 src += stride;
134 }
135}
136
138 const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
139 int width, int height)
140{
141 int left = 0, lefttop;
142 int i, j;
143
144 for (i = 0; i < width; i++) {
145 dst[i] = src[i] - left;
146 left = src[i];
147 }
148 dst += width;
149 src += stride;
150 for (j = 1; j < height; j++) {
151 left = lefttop = src[-stride];
152 s->llvidencdsp.sub_median_pred(dst, src - stride, src, width, &left, &lefttop);
153 dst += width;
154 src += stride;
155 }
156}
157
159{
160 MagicYUVContext *s = avctx->priv_data;
162
163 switch (avctx->pix_fmt) {
164 case AV_PIX_FMT_GBRP:
165 avctx->codec_tag = MKTAG('M', '8', 'R', 'G');
166 s->correlate = 1;
167 s->format = 0x65;
168 break;
169 case AV_PIX_FMT_GBRAP:
170 avctx->codec_tag = MKTAG('M', '8', 'R', 'A');
171 s->correlate = 1;
172 s->format = 0x66;
173 break;
175 avctx->codec_tag = MKTAG('M', '8', 'Y', '0');
176 s->hshift[1] =
177 s->vshift[1] =
178 s->hshift[2] =
179 s->vshift[2] = 1;
180 s->format = 0x69;
181 break;
183 avctx->codec_tag = MKTAG('M', '8', 'Y', '2');
184 s->hshift[1] =
185 s->hshift[2] = 1;
186 s->format = 0x68;
187 break;
189 avctx->codec_tag = MKTAG('M', '8', 'Y', '4');
190 s->format = 0x67;
191 break;
193 avctx->codec_tag = MKTAG('M', '8', 'Y', 'A');
194 s->format = 0x6a;
195 break;
196 case AV_PIX_FMT_GRAY8:
197 avctx->codec_tag = MKTAG('M', '8', 'G', '0');
198 s->format = 0x6b;
199 break;
200 }
201
202 ff_llvidencdsp_init(&s->llvidencdsp);
203
204 s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
205
206 s->nb_slices = avctx->slices > 0 ? avctx->slices : avctx->thread_count;
207 s->nb_slices = FFMIN(s->nb_slices, avctx->height >> s->vshift[1]);
208 s->nb_slices = FFMAX(1, s->nb_slices);
209 s->slice_height = FFALIGN((avctx->height + s->nb_slices - 1) / s->nb_slices, 1 << s->vshift[1]);
210 s->nb_slices = (avctx->height + s->slice_height - 1) / s->slice_height;
211 s->nb_slices = FFMIN(256U / s->planes, s->nb_slices);
212 s->slices = av_calloc(s->nb_slices * s->planes, sizeof(*s->slices));
213 if (!s->slices)
214 return AVERROR(ENOMEM);
215
216 if (s->correlate) {
217 size_t max_align = av_cpu_max_align();
218 size_t aligned_width = FFALIGN(avctx->width, max_align);
219 s->decorrelate_buf[0] = av_calloc(2U * (s->nb_slices * s->slice_height),
220 aligned_width);
221 if (!s->decorrelate_buf[0])
222 return AVERROR(ENOMEM);
223 s->decorrelate_buf[1] = s->decorrelate_buf[0] + (s->nb_slices * s->slice_height) * aligned_width;
224 }
225
226 for (int n = 0; n < s->nb_slices; n++) {
227 for (int i = 0; i < s->planes; i++) {
228 Slice *sl = &s->slices[n * s->planes + i];
229
230 sl->height = n == s->nb_slices - 1 ? avctx->height - n * s->slice_height : s->slice_height;
231 sl->height = AV_CEIL_RSHIFT(sl->height, s->vshift[i]);
232 sl->width = AV_CEIL_RSHIFT(avctx->width, s->hshift[i]);
233
234 sl->slice = av_malloc(avctx->width * (s->slice_height + 2) +
236 if (!sl->slice)
237 return AVERROR(ENOMEM);
238 }
239 }
240
241 switch (s->frame_pred) {
242 case LEFT: s->predict = left_predict; break;
243 case GRADIENT: s->predict = gradient_predict; break;
244 case MEDIAN: s->predict = median_predict; break;
245 }
246
248
249 avctx->extradata = av_mallocz(avctx->extradata_size +
251 if (!avctx->extradata)
252 return AVERROR(ENOMEM);
253
255 bytestream2_put_le32u(&pb, MKTAG('M', 'A', 'G', 'Y'));
256 bytestream2_put_le32u(&pb, 32);
257 bytestream2_put_byteu(&pb, 7);
258 bytestream2_put_byteu(&pb, s->format);
259 bytestream2_put_byteu(&pb, 12);
260 bytestream2_put_byteu(&pb, 0);
261
262 bytestream2_put_byteu(&pb, 0);
263 bytestream2_put_byteu(&pb, 0);
264 bytestream2_put_byteu(&pb, 32);
265 bytestream2_put_byteu(&pb, 0);
266
267 bytestream2_put_le32u(&pb, avctx->width);
268 bytestream2_put_le32u(&pb, avctx->height);
269 bytestream2_put_le32u(&pb, avctx->width);
270 bytestream2_put_le32u(&pb, avctx->height);
271
272 return 0;
273}
274
275static void calculate_codes(HuffEntry *he, uint16_t codes_count[33])
276{
277 for (unsigned i = 32, nb_codes = 0; i > 0; i--) {
278 uint16_t curr = codes_count[i]; // # of leafs of length i
279 codes_count[i] = nb_codes / 2; // # of non-leaf nodes on level i
280 nb_codes = codes_count[i] + curr; // # of nodes on level i
281 }
282
283 for (unsigned i = 0; i < 256; i++) {
284 he[i].code = codes_count[he[i].len];
285 codes_count[he[i].len]++;
286 }
287}
288
289static void count_usage(const uint8_t *src, int width,
290 int height, int64_t *counts)
291{
292 for (int j = 0; j < height; j++) {
293 for (int i = 0; i < width; i++)
294 counts[src[i]]++;
295 src += width;
296 }
297}
298
299typedef struct PackageMergerList {
300 int nitems; ///< number of items in the list and probability ex. 4
301 int item_idx[515]; ///< index range for each item in items 0, 2, 5, 9, 13
302 int probability[514]; ///< probability of each item 3, 8, 18, 46
303 int items[257 * 16]; ///< chain of all individual values that make up items A, B, A, B, C, A, B, C, D, C, D, D, E
305
306static int compare_by_prob(const void *a, const void *b)
307{
308 const PTable *a2 = a;
309 const PTable *b2 = b;
310 return a2->prob - b2->prob;
311}
312
313static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts,
314 uint16_t codes_counts[33],
315 int size, int max_length)
316{
317 PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp;
318 int times, i, j, k;
319 int nbits[257] = {0};
320 int min;
321
322 av_assert0(max_length > 0);
323
324 to->nitems = 0;
325 from->nitems = 0;
326 to->item_idx[0] = 0;
327 from->item_idx[0] = 0;
328 AV_QSORT(prob_table, size, PTable, compare_by_prob);
329
330 for (times = 0; times <= max_length; times++) {
331 to->nitems = 0;
332 to->item_idx[0] = 0;
333
334 j = 0;
335 k = 0;
336
337 if (times < max_length) {
338 i = 0;
339 }
340 while (i < size || j + 1 < from->nitems) {
341 to->nitems++;
342 to->item_idx[to->nitems] = to->item_idx[to->nitems - 1];
343 if (i < size &&
344 (j + 1 >= from->nitems ||
345 prob_table[i].prob <
346 from->probability[j] + from->probability[j + 1])) {
347 to->items[to->item_idx[to->nitems]++] = prob_table[i].value;
348 to->probability[to->nitems - 1] = prob_table[i].prob;
349 i++;
350 } else {
351 for (k = from->item_idx[j]; k < from->item_idx[j + 2]; k++) {
352 to->items[to->item_idx[to->nitems]++] = from->items[k];
353 }
354 to->probability[to->nitems - 1] =
355 from->probability[j] + from->probability[j + 1];
356 j += 2;
357 }
358 }
359 temp = to;
360 to = from;
361 from = temp;
362 }
363
364 min = (size - 1 < from->nitems) ? size - 1 : from->nitems;
365 for (i = 0; i < from->item_idx[min]; i++) {
366 nbits[from->items[i]]++;
367 }
368
369 for (i = 0; i < size; i++) {
370 distincts[i].len = nbits[i];
371 codes_counts[nbits[i]]++;
372 }
373}
374
375static int count_plane_slice(AVCodecContext *avctx, int n, int plane)
376{
377 MagicYUVContext *s = avctx->priv_data;
378 Slice *sl = &s->slices[n * s->planes + plane];
379 const uint8_t *dst = sl->slice;
380 int64_t *counts = sl->counts;
381
382 memset(counts, 0, sizeof(sl->counts));
383
384 count_usage(dst, sl->width, sl->height, counts);
385
386 return 0;
387}
388
390 HuffEntry *he, int plane)
391{
392 MagicYUVContext *s = avctx->priv_data;
393 PTable counts[256];
394 uint16_t codes_counts[33] = { 0 };
395
396 for (size_t i = 0; i < FF_ARRAY_ELEMS(counts); i++) {
397 counts[i].prob = 1;
398 counts[i].value = i;
399 }
400
401 for (int n = 0; n < s->nb_slices; n++) {
402 Slice *sl = &s->slices[n * s->planes + plane];
403 int64_t *slice_counts = sl->counts;
404
405 for (int i = 0; i < 256; i++)
406 counts[i].prob += slice_counts[i];
407 }
408
409 magy_huffman_compute_bits(counts, he, codes_counts, 256, 12);
410
411 calculate_codes(he, codes_counts);
412}
413
414static void output_codes(PutByteContext *pb, const HuffEntry he[256])
415{
416 for (int i = 0; i < 256; i++) {
417 // The seven low bits are len; the top bit means the run of
418 // codes of this length has length one.
419 bytestream2_put_byteu(pb, he[i].len);
420 }
421}
422
423static void encode_plane_slice_raw(const uint8_t *src, uint8_t *dst,
424 int width, int height, int prediction)
425{
426 unsigned count = width * height;
427
428 dst[0] = 1;
429 dst[1] = prediction;
430
431 memcpy(dst + 2, src, count);
432}
433
434static void encode_plane_slice(const uint8_t *src, uint8_t *dst, unsigned dst_size,
435 int width, int height, HuffEntry *he, int prediction)
436{
437 PutBitContext pb;
438
439 init_put_bits(&pb, dst, dst_size);
440
441 put_bits(&pb, 8, 0);
442 put_bits(&pb, 8, prediction);
443
444 for (int j = 0; j < height; j++) {
445 for (int i = 0; i < width; i++) {
446 const int idx = src[i];
447 const int len = he[idx].len;
448 put_bits(&pb, len, he[idx].code);
449 }
450
451 src += width;
452 }
453
454 flush_put_bits(&pb);
455 av_assert1(put_bytes_left(&pb, 0) <= 3);
456}
457
458static int encode_slice(AVCodecContext *avctx, void *tdata,
459 int n, int threadnr)
460{
461 MagicYUVContext *s = avctx->priv_data;
462
463 for (int i = 0; i < s->planes; i++) {
464 Slice *sl = &s->slices[n * s->planes + i];
465
466 // Zero the padding now
467 AV_WN32(sl->dst + sl->size - 4, 0);
468
469 if (sl->encode_raw)
471 sl->width, sl->height, s->frame_pred);
472 else
474 sl->dst,
475 sl->size,
476 sl->width, sl->height,
477 s->he[i], s->frame_pred);
478 }
479
480 return 0;
481}
482
483static int predict_slice(AVCodecContext *avctx, void *tdata,
484 int n, int threadnr)
485{
486 size_t max_align = av_cpu_max_align();
487 const int aligned_width = FFALIGN(avctx->width, max_align);
488 MagicYUVContext *s = avctx->priv_data;
489 const int slice_height = s->slice_height;
490 const int last_height = FFMIN(slice_height, avctx->height - n * slice_height);
491 const int height = (n < (s->nb_slices - 1)) ? slice_height : last_height;
492 const int width = avctx->width;
493 AVFrame *frame = tdata;
494
495 if (s->correlate) {
496 uint8_t *decorrelated[2] = { s->decorrelate_buf[0] + n * slice_height * aligned_width,
497 s->decorrelate_buf[1] + n * slice_height * aligned_width };
498 const int decorrelate_linesize = aligned_width;
499 const uint8_t *const data[4] = { decorrelated[0], frame->data[0] + n * slice_height * frame->linesize[0],
500 decorrelated[1], s->planes == 4 ? frame->data[3] + n * slice_height * frame->linesize[3] : NULL };
501 const uint8_t *r, *g, *b;
502 const int linesize[4] = { decorrelate_linesize, frame->linesize[0],
503 decorrelate_linesize, frame->linesize[3] };
504
505 g = frame->data[0] + n * slice_height * frame->linesize[0];
506 b = frame->data[1] + n * slice_height * frame->linesize[1];
507 r = frame->data[2] + n * slice_height * frame->linesize[2];
508
509 for (int i = 0; i < height; i++) {
510 s->llvidencdsp.diff_bytes(decorrelated[0], b, g, width);
511 s->llvidencdsp.diff_bytes(decorrelated[1], r, g, width);
512 g += frame->linesize[0];
513 b += frame->linesize[1];
514 r += frame->linesize[2];
515 decorrelated[0] += decorrelate_linesize;
516 decorrelated[1] += decorrelate_linesize;
517 }
518
519 for (int i = 0; i < s->planes; i++) {
520 Slice *sl = &s->slices[n * s->planes + i];
521
522 s->predict(s, data[i], sl->slice, linesize[i],
523 frame->width, height);
524 }
525 } else {
526 for (int i = 0; i < s->planes; i++) {
527 Slice *sl = &s->slices[n * s->planes + i];
528
529 s->predict(s, frame->data[i] + n * (slice_height >> s->vshift[i]) * frame->linesize[i],
530 sl->slice,
531 frame->linesize[i],
532 sl->width, sl->height);
533 }
534 }
535
536 for (int p = 0; p < s->planes; p++)
537 count_plane_slice(avctx, n, p);
538
539 return 0;
540}
541
543 const AVFrame *frame, int *got_packet)
544{
545 MagicYUVContext *s = avctx->priv_data;
547 int header_size = 32 + (4 + 1) * (s->planes * s->nb_slices + 1)
548 + 256 * s->planes /* Hufftables */;
549 int64_t pkt_size = header_size;
550 int ret;
551
552 avctx->execute2(avctx, predict_slice, (void *)frame, NULL, s->nb_slices);
553
554 for (int i = 0; i < s->planes; i++)
555 generate_codes(avctx, s->he[i], i);
556
557 for (int i = 0; i < s->nb_slices; ++i) {
558 for (int j = 0; j < s->planes; ++j) {
559 Slice *const sl = &s->slices[i * s->planes + j];
560 int64_t size = 0;
561
562 for (size_t k = 0; k < FF_ARRAY_ELEMS(sl->counts); ++k)
563 size += sl->counts[k] * s->he[j][k].len;
565 sl->encode_raw = size >= sl->width * sl->height;
566 if (sl->encode_raw)
567 size = sl->width * sl->height;
568 sl->size = FFALIGN(size + 2, 4);
569 sl->pos = pkt_size;
570 pkt_size += sl->size;
571 }
572 }
573
574 ret = ff_get_encode_buffer(avctx, pkt, pkt_size, 0);
575 if (ret < 0)
576 return ret;
577
578 bytestream2_init_writer(&pb, pkt->data, pkt->size);
579 bytestream2_put_le32u(&pb, MKTAG('M', 'A', 'G', 'Y'));
580 bytestream2_put_le32u(&pb, 32); // header size
581 bytestream2_put_byteu(&pb, 7); // version
582 bytestream2_put_byteu(&pb, s->format);
583 bytestream2_put_byteu(&pb, 12); // max huffman length
584 bytestream2_put_byteu(&pb, 0);
585
586 bytestream2_put_byteu(&pb, 0);
587 bytestream2_put_byteu(&pb, 0);
588 bytestream2_put_byteu(&pb, 32); // coder type
589 bytestream2_put_byteu(&pb, 0);
590
591 bytestream2_put_le32u(&pb, avctx->width);
592 bytestream2_put_le32u(&pb, avctx->height);
593 bytestream2_put_le32u(&pb, avctx->width);
594 bytestream2_put_le32u(&pb, s->slice_height);
595
596 // Slice position is relative to the current position (i.e. 32)
597 bytestream2_put_le32u(&pb, header_size - 32);
598
599 for (int i = 0; i < s->planes; ++i) {
600 for (int j = 0; j < s->nb_slices; ++j) {
601 Slice *const sl = &s->slices[j * s->planes + i];
602 bytestream2_put_le32u(&pb, sl->pos - 32);
603 sl->dst = pkt->data + sl->pos;
604 }
605 }
606
607 bytestream2_put_byteu(&pb, s->planes);
608
609 for (int i = 0; i < s->planes; i++) {
610 for (int n = 0; n < s->nb_slices; n++)
611 bytestream2_put_byteu(&pb, n * s->planes + i);
612 }
613
614 for (int i = 0; i < s->planes; ++i)
615 output_codes(&pb, s->he[i]);
616
617 avctx->execute2(avctx, encode_slice, NULL, NULL, s->nb_slices);
618
619 *got_packet = 1;
620
621 return 0;
622}
623
625{
626 MagicYUVContext *s = avctx->priv_data;
627
628 if (s->slices) {
629 for (int i = 0; i < s->planes * s->nb_slices; i++) {
630 Slice *sl = &s->slices[i];
631
632 av_freep(&sl->slice);
633 }
634 av_freep(&s->slices);
635 }
636 av_freep(&s->decorrelate_buf);
637
638 return 0;
639}
640
641#define OFFSET(x) offsetof(MagicYUVContext, x)
642#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
643static const AVOption options[] = {
644 { "pred", "Prediction method", OFFSET(frame_pred), AV_OPT_TYPE_INT, {.i64=LEFT}, LEFT, MEDIAN, VE, .unit = "pred" },
645 { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LEFT }, 0, 0, VE, .unit = "pred" },
646 { "gradient", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = GRADIENT }, 0, 0, VE, .unit = "pred" },
647 { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MEDIAN }, 0, 0, VE, .unit = "pred" },
648 { NULL},
649};
650
651static const AVClass magicyuv_class = {
652 .class_name = "magicyuv",
653 .item_name = av_default_item_name,
654 .option = options,
655 .version = LIBAVUTIL_VERSION_INT,
656};
657
659 .p.name = "magicyuv",
660 CODEC_LONG_NAME("MagicYUV video"),
661 .p.type = AVMEDIA_TYPE_VIDEO,
662 .p.id = AV_CODEC_ID_MAGICYUV,
663 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
666 .priv_data_size = sizeof(MagicYUVContext),
667 .p.priv_class = &magicyuv_class,
668 .init = magy_encode_init,
669 .close = magy_encode_close,
674 .color_ranges = AVCOL_RANGE_MPEG, /* FIXME: implement tagging */
675 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
676};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
const FFCodec ff_magicyuv_encoder
#define VE
Definition amfenc_av1.c:30
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition bytestream.h:147
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define prob(name, subs,...)
Definition cbs_vp9.c:252
#define LEFT
Definition cdgraphics.c:168
#define CODEC_PIXFMTS(...)
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define min(a, b)
static AVPacket * pkt
static AVFrame * frame
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
static int encode_slice(AVCodecContext *c, void *arg)
Definition ffv1enc.c:1736
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition codec.h:102
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition codec.h:98
@ AV_CODEC_ID_MAGICYUV
Definition codec_id.h:265
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AVERROR(e)
Definition error.h:45
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int a
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_WN32(p, v)
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
const char * from
Definition jacosubdec.c:64
const char * to
Definition webvttdec.c:36
#define av_cold
Definition attributes.h:117
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
Definition cpu.c:287
av_cold void ff_llvidencdsp_init(LLVidEncDSPContext *c)
#define FFMIN(a, b)
Definition macros.h:49
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
@ GRADIENT
Definition magicyuv.c:47
static void output_codes(PutByteContext *pb, const HuffEntry he[256])
static void encode_plane_slice_raw(const uint8_t *src, uint8_t *dst, int width, int height, int prediction)
static av_cold int magy_encode_init(AVCodecContext *avctx)
static void calculate_codes(HuffEntry *he, uint16_t codes_count[33])
static void count_usage(const uint8_t *src, int width, int height, int64_t *counts)
static const AVClass magicyuv_class
#define MAGICYUV_EXTRADATA_SIZE
Definition magicyuvenc.c:38
static void median_predict(MagicYUVContext *s, const uint8_t *src, uint8_t *dst, ptrdiff_t stride, int width, int height)
static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
static int encode_slice(AVCodecContext *avctx, void *tdata, int n, int threadnr)
static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts, uint16_t codes_counts[33], int size, int max_length)
static void gradient_predict(MagicYUVContext *s, const uint8_t *src, uint8_t *dst, ptrdiff_t stride, int width, int height)
static int compare_by_prob(const void *a, const void *b)
static void generate_codes(AVCodecContext *avctx, HuffEntry *he, int plane)
static av_cold int magy_encode_close(AVCodecContext *avctx)
static int count_plane_slice(AVCodecContext *avctx, int n, int plane)
static void left_predict(MagicYUVContext *s, const uint8_t *src, uint8_t *dst, ptrdiff_t stride, int width, int height)
Definition magicyuvenc.c:85
#define OFFSET(x)
static int predict_slice(AVCodecContext *avctx, void *tdata, int n, int threadnr)
static void encode_plane_slice(const uint8_t *src, uint8_t *dst, unsigned dst_size, int width, int height, HuffEntry *he, int prediction)
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
static int64_t prediction(int delta, ChannelContext *c)
Definition misc4.c:84
const char data[16]
Definition mxf.c:149
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition pixfmt.h:174
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition pixfmt.h:212
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition pixfmt.h:165
bitstream writer API
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static int put_bytes_left(const PutBitContext *s, int round_up)
Definition put_bits.h:145
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...
Definition qsort.h:33
#define MEDIAN(x)
#define FF_ARRAY_ELEMS(a)
const uint8_t * code
Definition spdifenc.c:433
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition avcodec.h:468
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition avcodec.h:1628
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
int slices
Number of slices.
Definition avcodec.h:1037
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
uint8_t len
Definition exr.c:96
uint32_t code
Definition exr.c:98
int hshift[4]
Definition magicyuv.c:68
int vshift[4]
Definition magicyuv.c:69
Slice * slices[4]
Definition magicyuv.c:70
void(* predict)(struct MagicYUVContext *s, const uint8_t *src, uint8_t *dst, ptrdiff_t stride, int width, int height)
Definition magicyuvenc.c:81
uint8_t * decorrelate_buf[2]
Definition magicyuvenc.c:77
HuffEntry he[1<< 14]
Definition magicyuv.c:77
LLVidEncDSPContext llvidencdsp
Definition magicyuvenc.c:80
Used to assign a occurrence count or "probability" to an input value.
Definition magicyuvenc.c:51
int64_t prob
number of occurrences of this value in input
Definition magicyuvenc.c:53
int value
input value
Definition magicyuvenc.c:52
Used to store intermediate lists in the package merge algorithm.
int probability[514]
probability of each item 3, 8, 18, 46
int items[257 *16]
chain of all individual values that make up items A, B, A, B, C, A, B, C, D, C, D,...
int item_idx[515]
index range for each item in items 0, 2, 5, 9, 13
int nitems
number of items in the list and probability ex. 4
int height
Definition magicyuvenc.c:58
uint8_t * dst
Definition magicyuvenc.c:63
int64_t counts[256]
Definition magicyuvenc.c:64
unsigned pos
Definition magicyuvenc.c:60
int width
Definition magicyuvenc.c:57
uint8_t * slice
Definition magicyuvenc.c:62
uint32_t size
Definition magicyuv.c:42
int encode_raw
Definition magicyuvenc.c:59
#define stride
#define av_mallocz(s)
#define av_freep(p)
#define src
Definition vp8dsp.c:248
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
int size
const char * g
Definition vf_curves.c:128
else temp
Definition vf_mcdeint.c:275
static double b2(void *priv, double x, double y)
Definition vf_xfade.c:2035
static double a2(void *priv, double x, double y)
Definition vf_xfade.c:2030
int len