38#define MAGICYUV_EXTRADATA_SIZE 32
98 for (j = 1; j <
height; j++) {
113 int left = 0, top, lefttop;
122 for (j = 1; j <
height; j++) {
141 int left = 0, lefttop;
150 for (j = 1; j <
height; j++) {
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));
218 size_t aligned_width =
FFALIGN(avctx->
width, max_align);
219 s->decorrelate_buf[0] =
av_calloc(2U * (
s->nb_slices *
s->slice_height),
221 if (!
s->decorrelate_buf[0])
223 s->decorrelate_buf[1] =
s->decorrelate_buf[0] + (
s->nb_slices *
s->slice_height) * aligned_width;
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];
230 sl->
height = n ==
s->nb_slices - 1 ? avctx->
height - n *
s->slice_height :
s->slice_height;
241 switch (
s->frame_pred) {
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);
262 bytestream2_put_byteu(&pb, 0);
263 bytestream2_put_byteu(&pb, 0);
264 bytestream2_put_byteu(&pb, 32);
265 bytestream2_put_byteu(&pb, 0);
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);
277 for (
unsigned i = 32, nb_codes = 0;
i > 0;
i--) {
278 uint16_t curr = codes_count[
i];
279 codes_count[
i] = nb_codes / 2;
280 nb_codes = codes_count[
i] + curr;
283 for (
unsigned i = 0;
i < 256;
i++) {
292 for (
int j = 0; j <
height; j++) {
310 return a2->prob -
b2->prob;
314 uint16_t codes_counts[33],
315 int size,
int max_length)
319 int nbits[257] = {0};
327 from->item_idx[0] = 0;
330 for (times = 0; times <= max_length; times++) {
337 if (times < max_length) {
340 while (
i <
size || j + 1 <
from->nitems) {
342 to->item_idx[
to->nitems] =
to->item_idx[
to->nitems - 1];
344 (j + 1 >=
from->nitems ||
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;
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];
354 to->probability[
to->nitems - 1] =
355 from->probability[j] +
from->probability[j + 1];
366 nbits[
from->items[
i]]++;
370 distincts[
i].
len = nbits[
i];
371 codes_counts[nbits[
i]]++;
378 Slice *sl = &
s->slices[n *
s->planes + plane];
382 memset(counts, 0,
sizeof(sl->
counts));
394 uint16_t codes_counts[33] = { 0 };
401 for (
int n = 0; n <
s->nb_slices; n++) {
402 Slice *sl = &
s->slices[n *
s->planes + plane];
405 for (
int i = 0;
i < 256;
i++)
406 counts[
i].
prob += slice_counts[
i];
416 for (
int i = 0;
i < 256;
i++) {
419 bytestream2_put_byteu(pb, he[
i].
len);
431 memcpy(
dst + 2,
src, count);
444 for (
int j = 0; j <
height; j++) {
446 const int idx =
src[
i];
447 const int len = he[idx].
len;
463 for (
int i = 0;
i <
s->planes;
i++) {
464 Slice *sl = &
s->slices[n *
s->planes +
i];
477 s->he[
i],
s->frame_pred);
487 const int aligned_width =
FFALIGN(avctx->
width, max_align);
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;
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] };
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];
510 s->llvidencdsp.diff_bytes(decorrelated[0],
b,
g,
width);
511 s->llvidencdsp.diff_bytes(decorrelated[1],
r,
g,
width);
515 decorrelated[0] += decorrelate_linesize;
516 decorrelated[1] += decorrelate_linesize;
519 for (
int i = 0;
i <
s->planes;
i++) {
520 Slice *sl = &
s->slices[n *
s->planes +
i];
526 for (
int i = 0;
i <
s->planes;
i++) {
527 Slice *sl = &
s->slices[n *
s->planes +
i];
529 s->predict(
s,
frame->data[
i] + n * (slice_height >>
s->vshift[
i]) *
frame->linesize[
i],
536 for (
int p = 0; p <
s->planes; p++)
547 int header_size = 32 + (4 + 1) * (
s->planes *
s->nb_slices + 1)
549 int64_t pkt_size = header_size;
554 for (
int i = 0;
i <
s->planes;
i++)
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];
570 pkt_size += sl->
size;
579 bytestream2_put_le32u(&pb,
MKTAG(
'M',
'A',
'G',
'Y'));
580 bytestream2_put_le32u(&pb, 32);
581 bytestream2_put_byteu(&pb, 7);
582 bytestream2_put_byteu(&pb,
s->format);
583 bytestream2_put_byteu(&pb, 12);
584 bytestream2_put_byteu(&pb, 0);
586 bytestream2_put_byteu(&pb, 0);
587 bytestream2_put_byteu(&pb, 0);
588 bytestream2_put_byteu(&pb, 32);
589 bytestream2_put_byteu(&pb, 0);
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);
597 bytestream2_put_le32u(&pb, header_size - 32);
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);
607 bytestream2_put_byteu(&pb,
s->planes);
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);
614 for (
int i = 0;
i <
s->planes; ++
i)
629 for (
int i = 0;
i <
s->planes *
s->nb_slices;
i++) {
641#define OFFSET(x) offsetof(MagicYUVContext, x)
642#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
652 .class_name =
"magicyuv",
659 .p.name =
"magicyuv",
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
const FFCodec ff_magicyuv_encoder
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
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)
#define i(width, name, range_min, range_max)
#define prob(name, subs,...)
#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)
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
static int encode_slice(AVCodecContext *c, void *arg)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
const char * av_default_item_name(void *ptr)
Return the context name.
#define LIBAVUTIL_VERSION_INT
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
av_cold void ff_llvidencdsp_init(LLVidEncDSPContext *c)
#define MKTAG(a, b, c, d)
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
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)
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)
Memory handling functions.
static int64_t prediction(int delta, ChannelContext *c)
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
static int put_bytes_left(const PutBitContext *s, int round_up)
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
#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...
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
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.
int slices
Number of slices.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
void(* predict)(struct MagicYUVContext *s, const uint8_t *src, uint8_t *dst, ptrdiff_t stride, int width, int height)
uint8_t * decorrelate_buf[2]
LLVidEncDSPContext llvidencdsp
Used to assign a occurrence count or "probability" to an input value.
int64_t prob
number of occurrences of this value in input
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
static double b2(void *priv, double x, double y)
static double a2(void *priv, double x, double y)