FFmpeg
exrenc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Paul B Mahol
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 /**
22  * @file
23  * OpenEXR encoder
24  */
25 
26 #include <float.h>
27 #include <zlib.h>
28 
29 #include "libavutil/avassert.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavutil/imgutils.h"
33 #include "libavutil/pixdesc.h"
34 #include "avcodec.h"
35 #include "bytestream.h"
36 #include "codec_internal.h"
37 #include "encode.h"
38 #include "float2half.h"
39 
40 enum ExrCompr {
46 };
47 
53 };
54 
55 static const char abgr_chlist[4] = { 'A', 'B', 'G', 'R' };
56 static const char bgr_chlist[4] = { 'B', 'G', 'R', 'A' };
57 static const char y_chlist[4] = { 'Y' };
58 static const uint8_t gbra_order[4] = { 3, 1, 0, 2 };
59 static const uint8_t gbr_order[4] = { 1, 0, 2, 0 };
60 static const uint8_t y_order[4] = { 0 };
61 
62 typedef struct EXRScanlineData {
63  uint8_t *compressed_data;
64  unsigned int compressed_size;
65 
67  unsigned int uncompressed_size;
68 
69  uint8_t *tmp;
70  unsigned int tmp_size;
71 
72  int64_t actual_size;
74 
75 typedef struct EXRContext {
76  const AVClass *class;
77 
80  int planes;
83  float gamma;
84  const char *ch_names;
85  const uint8_t *ch_order;
87 
89 
90  uint16_t basetable[512];
91  uint8_t shifttable[512];
92 } EXRContext;
93 
95 {
96  EXRContext *s = avctx->priv_data;
97 
98  float2half_tables(s->basetable, s->shifttable);
99 
100  switch (avctx->pix_fmt) {
101  case AV_PIX_FMT_GBRPF32:
102  s->planes = 3;
103  s->ch_names = bgr_chlist;
104  s->ch_order = gbr_order;
105  break;
106  case AV_PIX_FMT_GBRAPF32:
107  s->planes = 4;
108  s->ch_names = abgr_chlist;
109  s->ch_order = gbra_order;
110  break;
111  case AV_PIX_FMT_GRAYF32:
112  s->planes = 1;
113  s->ch_names = y_chlist;
114  s->ch_order = y_order;
115  break;
116  default:
117  av_assert0(0);
118  }
119 
120  switch (s->compression) {
121  case EXR_RAW:
122  case EXR_RLE:
123  case EXR_ZIP1:
124  s->scanline_height = 1;
125  s->nb_scanlines = avctx->height;
126  break;
127  case EXR_ZIP16:
128  s->scanline_height = 16;
129  s->nb_scanlines = (avctx->height + s->scanline_height - 1) / s->scanline_height;
130  break;
131  default:
132  av_assert0(0);
133  }
134 
135  s->scanline = av_calloc(s->nb_scanlines, sizeof(*s->scanline));
136  if (!s->scanline)
137  return AVERROR(ENOMEM);
138 
139  return 0;
140 }
141 
143 {
144  EXRContext *s = avctx->priv_data;
145 
146  for (int y = 0; y < s->nb_scanlines && s->scanline; y++) {
147  EXRScanlineData *scanline = &s->scanline[y];
148 
149  av_freep(&scanline->tmp);
150  av_freep(&scanline->compressed_data);
151  av_freep(&scanline->uncompressed_data);
152  }
153 
154  av_freep(&s->scanline);
155 
156  return 0;
157 }
158 
159 static void reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size)
160 {
161  const ptrdiff_t half_size = (size + 1) / 2;
162  uint8_t *t1 = dst;
163  uint8_t *t2 = dst + half_size;
164 
165  for (ptrdiff_t i = 0; i < half_size; i++) {
166  t1[i] = *(src++);
167  t2[i] = *(src++);
168  }
169 }
170 
171 static void predictor(uint8_t *src, ptrdiff_t size)
172 {
173  int p = src[0];
174 
175  for (ptrdiff_t i = 1; i < size; i++) {
176  int d = src[i] - p + 384;
177 
178  p = src[i];
179  src[i] = d;
180  }
181 }
182 
183 static int64_t rle_compress(uint8_t *out, int64_t out_size,
184  const uint8_t *in, int64_t in_size)
185 {
186  int64_t i = 0, o = 0, run = 1, copy = 0;
187 
188  while (i < in_size) {
189  while (i + run < in_size && in[i] == in[i + run] && run < 128)
190  run++;
191 
192  if (run >= 3) {
193  if (o + 2 >= out_size)
194  return -1;
195  out[o++] = run - 1;
196  out[o++] = in[i];
197  i += run;
198  } else {
199  if (i + run < in_size)
200  copy += run;
201  while (i + copy < in_size && copy < 127 && in[i + copy] != in[i + copy - 1])
202  copy++;
203 
204  if (o + 1 + copy >= out_size)
205  return -1;
206  out[o++] = -copy;
207 
208  for (int x = 0; x < copy; x++)
209  out[o + x] = in[i + x];
210 
211  o += copy;
212  i += copy;
213  copy = 0;
214  }
215 
216  run = 1;
217  }
218 
219  return o;
220 }
221 
223 {
224  const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL;
225 
226  for (int y = 0; y < frame->height; y++) {
227  EXRScanlineData *scanline = &s->scanline[y];
228  int64_t tmp_size = element_size * s->planes * frame->width;
229  int64_t max_compressed_size = tmp_size * 3 / 2;
230 
231  av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size);
232  if (!scanline->uncompressed_data)
233  return AVERROR(ENOMEM);
234 
235  av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size);
236  if (!scanline->tmp)
237  return AVERROR(ENOMEM);
238 
239  av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size);
240  if (!scanline->compressed_data)
241  return AVERROR(ENOMEM);
242 
243  switch (s->pixel_type) {
244  case EXR_FLOAT:
245  for (int p = 0; p < s->planes; p++) {
246  int ch = s->ch_order[p];
247 
248  memcpy(scanline->uncompressed_data + frame->width * 4 * p,
249  frame->data[ch] + y * frame->linesize[ch], frame->width * 4);
250  }
251  break;
252  case EXR_HALF:
253  for (int p = 0; p < s->planes; p++) {
254  int ch = s->ch_order[p];
255  uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + frame->width * 2 * p);
256  uint32_t *src = (uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
257 
258  for (int x = 0; x < frame->width; x++)
259  dst[x] = float2half(src[x], s->basetable, s->shifttable);
260  }
261  break;
262  }
263 
264  reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size);
265  predictor(scanline->tmp, tmp_size);
266  scanline->actual_size = rle_compress(scanline->compressed_data,
267  max_compressed_size,
268  scanline->tmp, tmp_size);
269 
270  if (scanline->actual_size <= 0 || scanline->actual_size >= tmp_size) {
271  FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data);
272  FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size);
273  scanline->actual_size = tmp_size;
274  }
275  }
276 
277  return 0;
278 }
279 
281 {
282  const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL;
283 
284  for (int y = 0; y < s->nb_scanlines; y++) {
285  EXRScanlineData *scanline = &s->scanline[y];
286  const int scanline_height = FFMIN(s->scanline_height, frame->height - y * s->scanline_height);
287  int64_t tmp_size = element_size * s->planes * frame->width * scanline_height;
288  int64_t max_compressed_size = tmp_size * 3 / 2;
289  unsigned long actual_size, source_size;
290 
291  av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size);
292  if (!scanline->uncompressed_data)
293  return AVERROR(ENOMEM);
294 
295  av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size);
296  if (!scanline->tmp)
297  return AVERROR(ENOMEM);
298 
299  av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size);
300  if (!scanline->compressed_data)
301  return AVERROR(ENOMEM);
302 
303  switch (s->pixel_type) {
304  case EXR_FLOAT:
305  for (int l = 0; l < scanline_height; l++) {
306  const int scanline_size = frame->width * 4 * s->planes;
307 
308  for (int p = 0; p < s->planes; p++) {
309  int ch = s->ch_order[p];
310 
311  memcpy(scanline->uncompressed_data + scanline_size * l + p * frame->width * 4,
312  frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch],
313  frame->width * 4);
314  }
315  }
316  break;
317  case EXR_HALF:
318  for (int l = 0; l < scanline_height; l++) {
319  const int scanline_size = frame->width * 2 * s->planes;
320 
321  for (int p = 0; p < s->planes; p++) {
322  int ch = s->ch_order[p];
323  uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + scanline_size * l + p * frame->width * 2);
324  uint32_t *src = (uint32_t *)(frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch]);
325 
326  for (int x = 0; x < frame->width; x++)
327  dst[x] = float2half(src[x], s->basetable, s->shifttable);
328  }
329  }
330  break;
331  }
332 
333  reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size);
334  predictor(scanline->tmp, tmp_size);
335  source_size = tmp_size;
336  actual_size = max_compressed_size;
337  compress(scanline->compressed_data, &actual_size,
338  scanline->tmp, source_size);
339 
340  scanline->actual_size = actual_size;
341  if (scanline->actual_size >= tmp_size) {
342  FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data);
343  FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size);
344  scanline->actual_size = tmp_size;
345  }
346  }
347 
348  return 0;
349 }
350 
352  const AVFrame *frame, int *got_packet)
353 {
354  EXRContext *s = avctx->priv_data;
355  PutByteContext *pb = &s->pb;
356  int64_t offset;
357  int ret;
358  int64_t out_size = 2048LL + avctx->height * 16LL +
360  avctx->width,
361  avctx->height, 64) * 3LL / 2;
362 
363  if ((ret = ff_get_encode_buffer(avctx, pkt, out_size, 0)) < 0)
364  return ret;
365 
367 
368  bytestream2_put_le32(pb, 20000630);
369  bytestream2_put_byte(pb, 2);
370  bytestream2_put_le24(pb, 0);
371  bytestream2_put_buffer(pb, "channels\0chlist\0", 16);
372  bytestream2_put_le32(pb, s->planes * 18 + 1);
373 
374  for (int p = 0; p < s->planes; p++) {
375  bytestream2_put_byte(pb, s->ch_names[p]);
376  bytestream2_put_byte(pb, 0);
377  bytestream2_put_le32(pb, s->pixel_type);
378  bytestream2_put_le32(pb, 0);
379  bytestream2_put_le32(pb, 1);
380  bytestream2_put_le32(pb, 1);
381  }
382  bytestream2_put_byte(pb, 0);
383 
384  bytestream2_put_buffer(pb, "compression\0compression\0", 24);
385  bytestream2_put_le32(pb, 1);
386  bytestream2_put_byte(pb, s->compression);
387 
388  bytestream2_put_buffer(pb, "dataWindow\0box2i\0", 17);
389  bytestream2_put_le32(pb, 16);
390  bytestream2_put_le32(pb, 0);
391  bytestream2_put_le32(pb, 0);
392  bytestream2_put_le32(pb, avctx->width - 1);
393  bytestream2_put_le32(pb, avctx->height - 1);
394 
395  bytestream2_put_buffer(pb, "displayWindow\0box2i\0", 20);
396  bytestream2_put_le32(pb, 16);
397  bytestream2_put_le32(pb, 0);
398  bytestream2_put_le32(pb, 0);
399  bytestream2_put_le32(pb, avctx->width - 1);
400  bytestream2_put_le32(pb, avctx->height - 1);
401 
402  bytestream2_put_buffer(pb, "lineOrder\0lineOrder\0", 20);
403  bytestream2_put_le32(pb, 1);
404  bytestream2_put_byte(pb, 0);
405 
406  bytestream2_put_buffer(pb, "screenWindowCenter\0v2f\0", 23);
407  bytestream2_put_le32(pb, 8);
408  bytestream2_put_le64(pb, 0);
409 
410  bytestream2_put_buffer(pb, "screenWindowWidth\0float\0", 24);
411  bytestream2_put_le32(pb, 4);
412  bytestream2_put_le32(pb, av_float2int(1.f));
413 
414  if (avctx->sample_aspect_ratio.num && avctx->sample_aspect_ratio.den) {
415  bytestream2_put_buffer(pb, "pixelAspectRatio\0float\0", 23);
416  bytestream2_put_le32(pb, 4);
417  bytestream2_put_le32(pb, av_float2int(av_q2d(avctx->sample_aspect_ratio)));
418  }
419 
420  if (avctx->framerate.num && avctx->framerate.den) {
421  bytestream2_put_buffer(pb, "framesPerSecond\0rational\0", 25);
422  bytestream2_put_le32(pb, 8);
423  bytestream2_put_le32(pb, avctx->framerate.num);
424  bytestream2_put_le32(pb, avctx->framerate.den);
425  }
426 
427  bytestream2_put_buffer(pb, "gamma\0float\0", 12);
428  bytestream2_put_le32(pb, 4);
429  bytestream2_put_le32(pb, av_float2int(s->gamma));
430 
431  bytestream2_put_buffer(pb, "writer\0string\0", 14);
432  bytestream2_put_le32(pb, 4);
433  bytestream2_put_buffer(pb, "lavc", 4);
434  bytestream2_put_byte(pb, 0);
435 
436  switch (s->compression) {
437  case EXR_RAW:
438  /* nothing to do */
439  break;
440  case EXR_RLE:
442  break;
443  case EXR_ZIP16:
444  case EXR_ZIP1:
446  break;
447  default:
448  av_assert0(0);
449  }
450 
451  switch (s->compression) {
452  case EXR_RAW:
453  offset = bytestream2_tell_p(pb) + avctx->height * 8LL;
454 
455  if (s->pixel_type == EXR_FLOAT) {
456 
457  for (int y = 0; y < avctx->height; y++) {
458  bytestream2_put_le64(pb, offset);
459  offset += avctx->width * s->planes * 4 + 8;
460  }
461 
462  for (int y = 0; y < avctx->height; y++) {
463  bytestream2_put_le32(pb, y);
464  bytestream2_put_le32(pb, s->planes * avctx->width * 4);
465  for (int p = 0; p < s->planes; p++) {
466  int ch = s->ch_order[p];
467  bytestream2_put_buffer(pb, frame->data[ch] + y * frame->linesize[ch],
468  avctx->width * 4);
469  }
470  }
471  } else {
472  for (int y = 0; y < avctx->height; y++) {
473  bytestream2_put_le64(pb, offset);
474  offset += avctx->width * s->planes * 2 + 8;
475  }
476 
477  for (int y = 0; y < avctx->height; y++) {
478  bytestream2_put_le32(pb, y);
479  bytestream2_put_le32(pb, s->planes * avctx->width * 2);
480  for (int p = 0; p < s->planes; p++) {
481  int ch = s->ch_order[p];
482  uint32_t *src = (uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
483 
484  for (int x = 0; x < frame->width; x++)
485  bytestream2_put_le16(pb, float2half(src[x], s->basetable, s->shifttable));
486  }
487  }
488  }
489  break;
490  case EXR_ZIP16:
491  case EXR_ZIP1:
492  case EXR_RLE:
493  offset = bytestream2_tell_p(pb) + s->nb_scanlines * 8LL;
494 
495  for (int y = 0; y < s->nb_scanlines; y++) {
496  EXRScanlineData *scanline = &s->scanline[y];
497 
498  bytestream2_put_le64(pb, offset);
499  offset += scanline->actual_size + 8;
500  }
501 
502  for (int y = 0; y < s->nb_scanlines; y++) {
503  EXRScanlineData *scanline = &s->scanline[y];
504 
505  bytestream2_put_le32(pb, y * s->scanline_height);
506  bytestream2_put_le32(pb, scanline->actual_size);
508  scanline->actual_size);
509  }
510  break;
511  default:
512  av_assert0(0);
513  }
514 
516 
517  *got_packet = 1;
518 
519  return 0;
520 }
521 
522 #define OFFSET(x) offsetof(EXRContext, x)
523 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
524 static const AVOption options[] = {
525  { "compression", "set compression type", OFFSET(compression), AV_OPT_TYPE_INT, {.i64=0}, 0, EXR_NBCOMPR-1, VE, "compr" },
526  { "none", "none", 0, AV_OPT_TYPE_CONST, {.i64=EXR_RAW}, 0, 0, VE, "compr" },
527  { "rle" , "RLE", 0, AV_OPT_TYPE_CONST, {.i64=EXR_RLE}, 0, 0, VE, "compr" },
528  { "zip1", "ZIP1", 0, AV_OPT_TYPE_CONST, {.i64=EXR_ZIP1}, 0, 0, VE, "compr" },
529  { "zip16", "ZIP16", 0, AV_OPT_TYPE_CONST, {.i64=EXR_ZIP16}, 0, 0, VE, "compr" },
530  { "format", "set pixel type", OFFSET(pixel_type), AV_OPT_TYPE_INT, {.i64=EXR_FLOAT}, EXR_HALF, EXR_UNKNOWN-1, VE, "pixel" },
531  { "half" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=EXR_HALF}, 0, 0, VE, "pixel" },
532  { "float", NULL, 0, AV_OPT_TYPE_CONST, {.i64=EXR_FLOAT}, 0, 0, VE, "pixel" },
533  { "gamma", "set gamma", OFFSET(gamma), AV_OPT_TYPE_FLOAT, {.dbl=1.f}, 0.001, FLT_MAX, VE },
534  { NULL},
535 };
536 
537 static const AVClass exr_class = {
538  .class_name = "exr",
539  .item_name = av_default_item_name,
540  .option = options,
541  .version = LIBAVUTIL_VERSION_INT,
542 };
543 
545  .p.name = "exr",
546  .p.long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
547  .priv_data_size = sizeof(EXRContext),
548  .p.priv_class = &exr_class,
549  .p.type = AVMEDIA_TYPE_VIDEO,
550  .p.id = AV_CODEC_ID_EXR,
551  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
552  .init = encode_init,
554  .close = encode_close,
555  .p.pix_fmts = (const enum AVPixelFormat[]) {
559  AV_PIX_FMT_NONE },
560  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
561 };
EXR_NBCOMPR
@ EXR_NBCOMPR
Definition: exrenc.c:45
EXR_ZIP16
@ EXR_ZIP16
Definition: exrenc.c:44
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
EXRContext::ch_names
const char * ch_names
Definition: exrenc.c:84
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
out
FILE * out
Definition: movenc.c:54
EXR_FLOAT
@ EXR_FLOAT
Definition: exrenc.c:51
out_size
int out_size
Definition: movenc.c:55
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
ExrPixelType
ExrPixelType
Definition: exr.c:74
AVOption
AVOption.
Definition: opt.h:251
encode.h
bytestream2_tell_p
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:197
gbra_order
static const uint8_t gbra_order[4]
Definition: exrenc.c:58
FFCodec
Definition: codec_internal.h:112
EXRContext::planes
int planes
Definition: exrenc.c:80
float.h
t1
#define t1
Definition: regdef.h:29
av_float2int
static av_always_inline uint32_t av_float2int(float f)
Reinterpret a float as a 32-bit integer.
Definition: intfloat.h:50
exr_class
static const AVClass exr_class
Definition: exrenc.c:537
EXRContext::scanline_height
int scanline_height
Definition: exrenc.c:82
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1732
EXR_RAW
@ EXR_RAW
Definition: exrenc.c:41
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
EXRScanlineData::uncompressed_data
uint8_t * uncompressed_data
Definition: exrenc.c:66
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: avpacket.c:112
abgr_chlist
static const char abgr_chlist[4]
Definition: exrenc.c:55
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:263
AVRational::num
int num
Numerator.
Definition: rational.h:59
EXRScanlineData::actual_size
int64_t actual_size
Definition: exrenc.c:72
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
av_cold
#define av_cold
Definition: attributes.h:90
EXRScanlineData::tmp
uint8_t * tmp
Definition: exrenc.c:69
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
bytestream2_put_buffer
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:286
gbr_order
static const uint8_t gbr_order[4]
Definition: exrenc.c:59
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
EXRContext::scanline
EXRScanlineData * scanline
Definition: exrenc.c:88
AV_PIX_FMT_GRAYF32
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:438
EXRContext::ch_order
const uint8_t * ch_order
Definition: exrenc.c:85
OFFSET
#define OFFSET(x)
Definition: exrenc.c:522
bgr_chlist
static const char bgr_chlist[4]
Definition: exrenc.c:56
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:113
AV_CODEC_ID_EXR
@ AV_CODEC_ID_EXR
Definition: codec_id.h:230
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
rle_compress
static int64_t rle_compress(uint8_t *out, int64_t out_size, const uint8_t *in, int64_t in_size)
Definition: exrenc.c:183
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:205
EXRContext::compression
int compression
Definition: exrenc.c:78
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
float2half
static uint16_t float2half(uint32_t f, uint16_t *basetable, uint8_t *shifttable)
Definition: float2half.h:58
EXRScanlineData::tmp_size
unsigned int tmp_size
Definition: exrenc.c:70
encode_scanline_zip
static int encode_scanline_zip(EXRContext *s, const AVFrame *frame)
Definition: exrenc.c:280
PutByteContext
Definition: bytestream.h:37
f
f
Definition: af_crystalizer.c:122
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:187
codec_internal.h
AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:435
EXRContext::nb_scanlines
int nb_scanlines
Definition: exrenc.c:81
size
int size
Definition: twinvq_data.h:10344
EXRContext::gamma
float gamma
Definition: exr.c:191
EXRContext::pb
PutByteContext pb
Definition: exrenc.c:86
av_image_get_buffer_size
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:466
ff_exr_encoder
const FFCodec ff_exr_encoder
Definition: exrenc.c:544
encode_init
static av_cold int encode_init(AVCodecContext *avctx)
Definition: exrenc.c:94
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
predictor
static void predictor(uint8_t *src, ptrdiff_t size)
Definition: exrenc.c:171
y_order
static const uint8_t y_order[4]
Definition: exrenc.c:60
EXRScanlineData::compressed_data
uint8_t * compressed_data
Definition: exrenc.c:63
encode_close
static av_cold int encode_close(AVCodecContext *avctx)
Definition: exrenc.c:142
EXRScanlineData::compressed_size
unsigned int compressed_size
Definition: exrenc.c:64
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
EXR_UNKNOWN
@ EXR_UNKNOWN
Definition: exrenc.c:52
EXRScanlineData::uncompressed_size
unsigned int uncompressed_size
Definition: exrenc.c:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
av_fast_padded_malloc
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition: utils.c:48
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
EXR_UINT
@ EXR_UINT
Definition: exrenc.c:49
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: codec_internal.h:31
EXRScanlineData
Definition: exrenc.c:62
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
EXR_HALF
@ EXR_HALF
Definition: exrenc.c:50
AVCodecContext::height
int height
Definition: avcodec.h:562
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:599
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
float2half_tables
static void float2half_tables(uint16_t *basetable, uint8_t *shifttable)
Definition: float2half.h:24
avcodec.h
options
static const AVOption options[]
Definition: exrenc.c:524
encode_scanline_rle
static int encode_scanline_rle(EXRContext *s, const AVFrame *frame)
Definition: exrenc.c:222
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
EXRContext::basetable
uint16_t basetable[512]
Definition: exrenc.c:90
EXRContext::shifttable
uint8_t shifttable[512]
Definition: exrenc.c:91
reorder_pixels
static void reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size)
Definition: exrenc.c:159
AVCodecContext
main external API structure.
Definition: avcodec.h:389
EXRContext::pixel_type
int pixel_type
Definition: exrenc.c:79
t2
#define t2
Definition: regdef.h:30
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:79
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:436
EXR_RLE
@ EXR_RLE
Definition: exrenc.c:42
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
y_chlist
static const char y_chlist[4]
Definition: exrenc.c:57
ExrCompr
ExrCompr
Definition: exr.c:60
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
d
d
Definition: ffmpeg_filter.c:153
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
bytestream.h
VE
#define VE
Definition: exrenc.c:523
imgutils.h
encode_frame
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: exrenc.c:351
EXR_ZIP1
@ EXR_ZIP1
Definition: exrenc.c:43
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
float2half.h
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:759
EXRContext
Definition: exr.c:146