]> git.sesse.net Git - ffmpeg/blob - libavcodec/magicyuvenc.c
Merge commit 'dc40e64adb1712b1209c018914a44f809bc32664'
[ffmpeg] / libavcodec / magicyuvenc.c
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/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavutil/qsort.h"
28
29 #include "avcodec.h"
30 #include "bytestream.h"
31 #include "put_bits.h"
32 #include "internal.h"
33 #include "thread.h"
34 #include "lossless_videoencdsp.h"
35
36 typedef enum Prediction {
37     LEFT = 1,
38     GRADIENT,
39     MEDIAN,
40 } Prediction;
41
42 typedef struct HuffEntry {
43     uint8_t  sym;
44     uint8_t  len;
45     uint32_t code;
46 } HuffEntry;
47
48 typedef struct PTable {
49     int     value;  ///< input value
50     int64_t prob;   ///< number of occurences of this value in input
51 } PTable;
52
53 typedef struct MagicYUVContext {
54     const AVClass       *class;
55     int                  frame_pred;
56     PutBitContext        pb;
57     int                  planes;
58     uint8_t              format;
59     AVFrame             *p;
60     int                  max;
61     int                  slice_height;
62     int                  nb_slices;
63     int                  correlate;
64     int                  hshift[4];
65     int                  vshift[4];
66     uint8_t             *slices[4];
67     unsigned             slice_pos[4];
68     unsigned             tables_size;
69     HuffEntry            he[4][256];
70     LLVidEncDSPContext   llvidencdsp;
71     void (*predict)(struct MagicYUVContext *s, uint8_t *src, uint8_t *dst,
72                     ptrdiff_t stride, int width, int height);
73 } MagicYUVContext;
74
75 static void left_predict(MagicYUVContext *s,
76                          uint8_t *src, uint8_t *dst, ptrdiff_t stride,
77                          int width, int height)
78 {
79     uint8_t prev = 0;
80     int i, j;
81
82     for (i = 0; i < width; i++) {
83         dst[i] = src[i] - prev;
84         prev   = src[i];
85     }
86     dst += width;
87     src += stride;
88     for (j = 1; j < height; j++) {
89         prev = src[-stride];
90         for (i = 0; i < width; i++) {
91             dst[i] = src[i] - prev;
92             prev   = src[i];
93         }
94         dst += width;
95         src += stride;
96     }
97 }
98
99 static void gradient_predict(MagicYUVContext *s,
100                              uint8_t *src, uint8_t *dst, ptrdiff_t stride,
101                              int width, int height)
102 {
103     int left = 0, top, lefttop;
104     int i, j;
105
106     for (i = 0; i < width; i++) {
107         dst[i] = src[i] - left;
108         left   = src[i];
109     }
110     dst += width;
111     src += stride;
112     for (j = 1; j < height; j++) {
113         top = src[-stride];
114         left = src[0] - top;
115         dst[0] = left;
116         for (i = 1; i < width; i++) {
117             top = src[i - stride];
118             lefttop = src[i - (stride + 1)];
119             left = src[i-1];
120             dst[i] = (src[i] - top) - left + lefttop;
121         }
122         dst += width;
123         src += stride;
124     }
125 }
126
127 static void median_predict(MagicYUVContext *s,
128                            uint8_t *src, uint8_t *dst, ptrdiff_t stride,
129                            int width, int height)
130 {
131     int left = 0, lefttop;
132     int i, j;
133
134     for (i = 0; i < width; i++) {
135         dst[i] = src[i] - left;
136         left   = src[i];
137     }
138     dst += width;
139     src += stride;
140     for (j = 1; j < height; j++) {
141         left = lefttop = src[-stride];
142         s->llvidencdsp.sub_median_pred(dst, src - stride, src, width, &left, &lefttop);
143         dst += width;
144         src += stride;
145     }
146 }
147
148 static av_cold int magy_encode_init(AVCodecContext *avctx)
149 {
150     MagicYUVContext *s = avctx->priv_data;
151     int i;
152
153     switch (avctx->pix_fmt) {
154     case AV_PIX_FMT_GBRP:
155         avctx->codec_tag = MKTAG('M', '8', 'R', 'G');
156         s->correlate = 1;
157         s->format = 0x65;
158         break;
159     case AV_PIX_FMT_GBRAP:
160         avctx->codec_tag = MKTAG('M', '8', 'R', 'A');
161         s->correlate = 1;
162         s->format = 0x66;
163         break;
164     case AV_PIX_FMT_YUV420P:
165         avctx->codec_tag = MKTAG('M', '8', 'Y', '0');
166         s->hshift[1] =
167         s->vshift[1] =
168         s->hshift[2] =
169         s->vshift[2] = 1;
170         s->format = 0x69;
171         break;
172     case AV_PIX_FMT_YUV422P:
173         avctx->codec_tag = MKTAG('M', '8', 'Y', '2');
174         s->hshift[1] =
175         s->hshift[2] = 1;
176         s->format = 0x68;
177         break;
178     case AV_PIX_FMT_YUV444P:
179         avctx->codec_tag = MKTAG('M', '8', 'Y', '4');
180         s->format = 0x67;
181         break;
182     case AV_PIX_FMT_YUVA444P:
183         avctx->codec_tag = MKTAG('M', '8', 'Y', 'A');
184         s->format = 0x6a;
185         break;
186     case AV_PIX_FMT_GRAY8:
187         avctx->codec_tag = MKTAG('M', '8', 'G', '0');
188         s->format = 0x6b;
189         break;
190     default:
191         av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format: %d\n",
192                avctx->pix_fmt);
193         return AVERROR_INVALIDDATA;
194     }
195
196     ff_llvidencdsp_init(&s->llvidencdsp);
197
198     s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
199
200     s->nb_slices = 1;
201
202     for (i = 0; i < s->planes; i++) {
203         s->slices[i] = av_malloc(avctx->width * (avctx->height + 2) +
204                                  AV_INPUT_BUFFER_PADDING_SIZE);
205         if (!s->slices[i]) {
206             av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer.\n");
207             return AVERROR(ENOMEM);
208         }
209     }
210
211     switch (s->frame_pred) {
212     case LEFT:     s->predict = left_predict;     break;
213     case GRADIENT: s->predict = gradient_predict; break;
214     case MEDIAN:   s->predict = median_predict;   break;
215     }
216
217     return 0;
218 }
219
220 static int magy_huff_cmp_len(const void *a, const void *b)
221 {
222     const HuffEntry *aa = a, *bb = b;
223     return (aa->len - bb->len) * 256 + aa->sym - bb->sym;
224 }
225
226 static int huff_cmp_sym(const void *a, const void *b)
227 {
228     const HuffEntry *aa = a, *bb = b;
229     return bb->sym - aa->sym;
230 }
231
232 static void calculate_codes(HuffEntry *he)
233 {
234     uint32_t code;
235     int i;
236
237     AV_QSORT(he, 256, HuffEntry, magy_huff_cmp_len);
238
239     code = 1;
240     for (i = 255; i >= 0; i--) {
241         he[i].code  = code >> (32 - he[i].len);
242         code       += 0x80000000u >> (he[i].len - 1);
243     }
244
245     AV_QSORT(he, 256, HuffEntry, huff_cmp_sym);
246 }
247
248 static void count_usage(uint8_t *src, int width,
249                         int height, PTable *counts)
250 {
251     int i, j;
252
253     for (j = 0; j < height; j++) {
254         for (i = 0; i < width; i++) {
255             counts[src[i]].prob++;
256         }
257         src += width;
258     }
259 }
260
261 typedef struct PackageMergerList {
262     int nitems;             ///< number of items in the list and probability      ex. 4
263     int item_idx[515];      ///< index range for each item in items                   0, 2, 5, 9, 13
264     int probability[514];   ///< probability of each item                             3, 8, 18, 46
265     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
266 } PackageMergerList;
267
268 static int compare_by_prob(const void *a, const void *b)
269 {
270     PTable a_val = *(PTable *)a;
271     PTable b_val = *(PTable *)b;
272     return a_val.prob - b_val.prob;
273 }
274
275 static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts,
276                                       int size, int max_length)
277 {
278     PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp;
279     int times, i, j, k;
280     int nbits[257] = {0};
281     int min;
282
283     av_assert0(max_length > 0);
284
285     to->nitems = 0;
286     from->nitems = 0;
287     to->item_idx[0] = 0;
288     from->item_idx[0] = 0;
289     AV_QSORT(prob_table, size, PTable, compare_by_prob);
290
291     for (times = 0; times <= max_length; times++) {
292         to->nitems = 0;
293         to->item_idx[0] = 0;
294
295         j = 0;
296         k = 0;
297
298         if (times < max_length) {
299             i = 0;
300         }
301         while (i < size || j + 1 < from->nitems) {
302             to->nitems++;
303             to->item_idx[to->nitems] = to->item_idx[to->nitems - 1];
304             if (i < size &&
305                 (j + 1 >= from->nitems ||
306                  prob_table[i].prob <
307                      from->probability[j] + from->probability[j + 1])) {
308                 to->items[to->item_idx[to->nitems]++] = prob_table[i].value;
309                 to->probability[to->nitems - 1] = prob_table[i].prob;
310                 i++;
311             } else {
312                 for (k = from->item_idx[j]; k < from->item_idx[j + 2]; k++) {
313                     to->items[to->item_idx[to->nitems]++] = from->items[k];
314                 }
315                 to->probability[to->nitems - 1] =
316                     from->probability[j] + from->probability[j + 1];
317                 j += 2;
318             }
319         }
320         temp = to;
321         to = from;
322         from = temp;
323     }
324
325     min = (size - 1 < from->nitems) ? size - 1 : from->nitems;
326     for (i = 0; i < from->item_idx[min]; i++) {
327         nbits[from->items[i]]++;
328     }
329
330     for (i = 0; i < size; i++) {
331         distincts[i].sym = i;
332         distincts[i].len = nbits[i];
333     }
334 }
335
336 static int encode_table(AVCodecContext *avctx, uint8_t *dst,
337                         int width, int height,
338                         PutBitContext *pb, HuffEntry *he)
339 {
340     PTable counts[256] = { {0} };
341     int i;
342
343     count_usage(dst, width, height, counts);
344
345     for (i = 0; i < 256; i++) {
346         counts[i].prob++;
347         counts[i].value = 255 - i;
348     }
349
350     magy_huffman_compute_bits(counts, he, 256, 16);
351
352     calculate_codes(he);
353
354     for (i = 0; i < 256; i++) {
355         put_bits(pb, 1, 0);
356         put_bits(pb, 7, he[i].len);
357     }
358
359     return 0;
360 }
361
362 static int encode_slice(uint8_t *src, uint8_t *dst, int dst_size,
363                         int width, int height, HuffEntry *he, int prediction)
364 {
365     PutBitContext pb;
366     int i, j;
367     int count;
368
369     init_put_bits(&pb, dst, dst_size);
370
371     put_bits(&pb, 8, 0);
372     put_bits(&pb, 8, prediction);
373
374     for (j = 0; j < height; j++) {
375         for (i = 0; i < width; i++) {
376             const int idx = src[i];
377             put_bits(&pb, he[idx].len, he[idx].code);
378         }
379
380         src += width;
381     }
382
383     count = put_bits_count(&pb) & 0x1F;
384
385     if (count)
386         put_bits(&pb, 32 - count, 0);
387
388     count = put_bits_count(&pb);
389
390     flush_put_bits(&pb);
391
392     return count >> 3;
393 }
394
395 static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
396                              const AVFrame *frame, int *got_packet)
397 {
398     MagicYUVContext *s = avctx->priv_data;
399     PutByteContext pb;
400     const int width = avctx->width, height = avctx->height;
401     int pos, slice, i, j, ret = 0;
402
403     ret = ff_alloc_packet2(avctx, pkt, (256 + 4 * s->nb_slices + width * height) *
404                            s->planes + 256, 0);
405     if (ret < 0)
406         return ret;
407
408     bytestream2_init_writer(&pb, pkt->data, pkt->size);
409     bytestream2_put_le32(&pb, MKTAG('M', 'A', 'G', 'Y'));
410     bytestream2_put_le32(&pb, 32);
411     bytestream2_put_byte(&pb, 7);
412     bytestream2_put_byte(&pb, s->format);
413     bytestream2_put_byte(&pb, 0);
414     bytestream2_put_byte(&pb, 0);
415     bytestream2_put_le32(&pb, 0);
416
417     bytestream2_put_le32(&pb, avctx->width);
418     bytestream2_put_le32(&pb, avctx->height);
419     bytestream2_put_le32(&pb, avctx->width);
420     bytestream2_put_le32(&pb, avctx->height);
421     bytestream2_put_le32(&pb, 0);
422
423     for (i = 0; i < s->planes; i++) {
424         bytestream2_put_le32(&pb, 0);
425         for (j = 1; j < s->nb_slices; j++) {
426             bytestream2_put_le32(&pb, 0);
427         }
428     }
429
430     bytestream2_put_byte(&pb, s->planes);
431
432     for (i = 0; i < s->planes; i++) {
433         for (slice = 0; slice < s->nb_slices; slice++) {
434             bytestream2_put_byte(&pb, i);
435         }
436     }
437
438     if (s->correlate) {
439         uint8_t *r, *g, *b;
440         AVFrame *p = av_frame_clone(frame);
441
442         g = p->data[0];
443         b = p->data[1];
444         r = p->data[2];
445
446         for (i = 0; i < height; i++) {
447             s->llvidencdsp.diff_bytes(b, b, g, width);
448             s->llvidencdsp.diff_bytes(r, r, g, width);
449             g += p->linesize[0];
450             b += p->linesize[1];
451             r += p->linesize[2];
452         }
453
454         FFSWAP(uint8_t*, p->data[0], p->data[1]);
455         FFSWAP(int, p->linesize[0], p->linesize[1]);
456
457         for (i = 0; i < s->planes; i++) {
458             for (slice = 0; slice < s->nb_slices; slice++) {
459                 s->predict(s, p->data[i], s->slices[i], p->linesize[i],
460                                p->width, p->height);
461             }
462         }
463
464         av_frame_free(&p);
465     } else {
466         for (i = 0; i < s->planes; i++) {
467             for (slice = 0; slice < s->nb_slices; slice++) {
468                 s->predict(s, frame->data[i], s->slices[i], frame->linesize[i],
469                            AV_CEIL_RSHIFT(frame->width, s->hshift[i]),
470                            AV_CEIL_RSHIFT(frame->height, s->vshift[i]));
471             }
472         }
473     }
474
475     init_put_bits(&s->pb, pkt->data + bytestream2_tell_p(&pb), bytestream2_get_bytes_left_p(&pb));
476
477     for (i = 0; i < s->planes; i++) {
478         encode_table(avctx, s->slices[i],
479                      AV_CEIL_RSHIFT(frame->width,  s->hshift[i]),
480                      AV_CEIL_RSHIFT(frame->height, s->vshift[i]),
481                      &s->pb, s->he[i]);
482     }
483     s->tables_size = (put_bits_count(&s->pb) + 7) >> 3;
484     bytestream2_skip_p(&pb, s->tables_size);
485
486     for (i = 0; i < s->planes; i++) {
487         unsigned slice_size;
488
489         s->slice_pos[i] = bytestream2_tell_p(&pb);
490         slice_size = encode_slice(s->slices[i], pkt->data + bytestream2_tell_p(&pb),
491                                   bytestream2_get_bytes_left_p(&pb),
492                                   AV_CEIL_RSHIFT(frame->width,  s->hshift[i]),
493                                   AV_CEIL_RSHIFT(frame->height, s->vshift[i]),
494                                   s->he[i], s->frame_pred);
495         bytestream2_skip_p(&pb, slice_size);
496     }
497
498     pos = bytestream2_tell_p(&pb);
499     bytestream2_seek_p(&pb, 32, SEEK_SET);
500     bytestream2_put_le32(&pb, s->slice_pos[0] - 32);
501     for (i = 0; i < s->planes; i++) {
502         bytestream2_put_le32(&pb, s->slice_pos[i] - 32);
503     }
504     bytestream2_seek_p(&pb, pos, SEEK_SET);
505
506     pkt->size   = bytestream2_tell_p(&pb);
507     pkt->flags |= AV_PKT_FLAG_KEY;
508
509     *got_packet = 1;
510
511     return 0;
512 }
513
514 static av_cold int magy_encode_close(AVCodecContext *avctx)
515 {
516     MagicYUVContext *s = avctx->priv_data;
517     int i;
518
519     for (i = 0; i < s->planes; i++)
520         av_freep(&s->slices[i]);
521
522     return 0;
523 }
524
525 #define OFFSET(x) offsetof(MagicYUVContext, x)
526 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
527 static const AVOption options[] = {
528     { "pred", "Prediction method", OFFSET(frame_pred), AV_OPT_TYPE_INT, {.i64=LEFT}, LEFT, MEDIAN, VE, "pred" },
529     { "left",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LEFT },     0, 0, VE, "pred" },
530     { "gradient", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = GRADIENT }, 0, 0, VE, "pred" },
531     { "median",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MEDIAN },   0, 0, VE, "pred" },
532     { NULL},
533 };
534
535 static const AVClass magicyuv_class = {
536     .class_name = "magicyuv",
537     .item_name  = av_default_item_name,
538     .option     = options,
539     .version    = LIBAVUTIL_VERSION_INT,
540 };
541
542 AVCodec ff_magicyuv_encoder = {
543     .name             = "magicyuv",
544     .long_name        = NULL_IF_CONFIG_SMALL("MagicYUV video"),
545     .type             = AVMEDIA_TYPE_VIDEO,
546     .id               = AV_CODEC_ID_MAGICYUV,
547     .priv_data_size   = sizeof(MagicYUVContext),
548     .priv_class       = &magicyuv_class,
549     .init             = magy_encode_init,
550     .close            = magy_encode_close,
551     .encode2          = magy_encode_frame,
552     .capabilities     = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
553     .pix_fmts         = (const enum AVPixelFormat[]) {
554                           AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_YUV422P,
555                           AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GRAY8,
556                           AV_PIX_FMT_NONE
557                       },
558 };