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 "libavutil/float2half.h"
35 #include "avcodec.h"
36 #include "bytestream.h"
37 #include "codec_internal.h"
38 #include "encode.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 
91 } EXRContext;
92 
94 {
95  EXRContext *s = avctx->priv_data;
96 
97  ff_init_float2half_tables(&s->f2h_tables);
98 
99  switch (avctx->pix_fmt) {
100  case AV_PIX_FMT_GBRPF32:
101  s->planes = 3;
102  s->ch_names = bgr_chlist;
103  s->ch_order = gbr_order;
104  break;
105  case AV_PIX_FMT_GBRAPF32:
106  s->planes = 4;
107  s->ch_names = abgr_chlist;
108  s->ch_order = gbra_order;
109  break;
110  case AV_PIX_FMT_GRAYF32:
111  s->planes = 1;
112  s->ch_names = y_chlist;
113  s->ch_order = y_order;
114  break;
115  default:
116  av_assert0(0);
117  }
118 
119  switch (s->compression) {
120  case EXR_RAW:
121  case EXR_RLE:
122  case EXR_ZIP1:
123  s->scanline_height = 1;
124  s->nb_scanlines = avctx->height;
125  break;
126  case EXR_ZIP16:
127  s->scanline_height = 16;
128  s->nb_scanlines = (avctx->height + s->scanline_height - 1) / s->scanline_height;
129  break;
130  default:
131  av_assert0(0);
132  }
133 
134  s->scanline = av_calloc(s->nb_scanlines, sizeof(*s->scanline));
135  if (!s->scanline)
136  return AVERROR(ENOMEM);
137 
138  return 0;
139 }
140 
142 {
143  EXRContext *s = avctx->priv_data;
144 
145  for (int y = 0; y < s->nb_scanlines && s->scanline; y++) {
146  EXRScanlineData *scanline = &s->scanline[y];
147 
148  av_freep(&scanline->tmp);
149  av_freep(&scanline->compressed_data);
150  av_freep(&scanline->uncompressed_data);
151  }
152 
153  av_freep(&s->scanline);
154 
155  return 0;
156 }
157 
158 static void reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size)
159 {
160  const ptrdiff_t half_size = (size + 1) / 2;
161  uint8_t *t1 = dst;
162  uint8_t *t2 = dst + half_size;
163 
164  for (ptrdiff_t i = 0; i < half_size; i++) {
165  t1[i] = *(src++);
166  t2[i] = *(src++);
167  }
168 }
169 
170 static void predictor(uint8_t *src, ptrdiff_t size)
171 {
172  int p = src[0];
173 
174  for (ptrdiff_t i = 1; i < size; i++) {
175  int d = src[i] - p + 384;
176 
177  p = src[i];
178  src[i] = d;
179  }
180 }
181 
182 static int64_t rle_compress(uint8_t *out, int64_t out_size,
183  const uint8_t *in, int64_t in_size)
184 {
185  int64_t i = 0, o = 0, run = 1, copy = 0;
186 
187  while (i < in_size) {
188  while (i + run < in_size && in[i] == in[i + run] && run < 128)
189  run++;
190 
191  if (run >= 3) {
192  if (o + 2 >= out_size)
193  return -1;
194  out[o++] = run - 1;
195  out[o++] = in[i];
196  i += run;
197  } else {
198  if (i + run < in_size)
199  copy += run;
200  while (i + copy < in_size && copy < 127 && in[i + copy] != in[i + copy - 1])
201  copy++;
202 
203  if (o + 1 + copy >= out_size)
204  return -1;
205  out[o++] = -copy;
206 
207  for (int x = 0; x < copy; x++)
208  out[o + x] = in[i + x];
209 
210  o += copy;
211  i += copy;
212  copy = 0;
213  }
214 
215  run = 1;
216  }
217 
218  return o;
219 }
220 
222 {
223  const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL;
224 
225  for (int y = 0; y < frame->height; y++) {
226  EXRScanlineData *scanline = &s->scanline[y];
227  int64_t tmp_size = element_size * s->planes * frame->width;
228  int64_t max_compressed_size = tmp_size * 3 / 2;
229 
230  av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size);
231  if (!scanline->uncompressed_data)
232  return AVERROR(ENOMEM);
233 
234  av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size);
235  if (!scanline->tmp)
236  return AVERROR(ENOMEM);
237 
238  av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size);
239  if (!scanline->compressed_data)
240  return AVERROR(ENOMEM);
241 
242  switch (s->pixel_type) {
243  case EXR_FLOAT:
244  for (int p = 0; p < s->planes; p++) {
245  int ch = s->ch_order[p];
246 
247  memcpy(scanline->uncompressed_data + frame->width * 4 * p,
248  frame->data[ch] + y * frame->linesize[ch], frame->width * 4);
249  }
250  break;
251  case EXR_HALF:
252  for (int p = 0; p < s->planes; p++) {
253  int ch = s->ch_order[p];
254  uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + frame->width * 2 * p);
255  const uint32_t *src = (const uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
256 
257  for (int x = 0; x < frame->width; x++)
258  dst[x] = float2half(src[x], &s->f2h_tables);
259  }
260  break;
261  }
262 
263  reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size);
264  predictor(scanline->tmp, tmp_size);
265  scanline->actual_size = rle_compress(scanline->compressed_data,
266  max_compressed_size,
267  scanline->tmp, tmp_size);
268 
269  if (scanline->actual_size <= 0 || scanline->actual_size >= tmp_size) {
270  FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data);
271  FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size);
272  scanline->actual_size = tmp_size;
273  }
274  }
275 
276  return 0;
277 }
278 
280 {
281  const int64_t element_size = s->pixel_type == EXR_HALF ? 2LL : 4LL;
282 
283  for (int y = 0; y < s->nb_scanlines; y++) {
284  EXRScanlineData *scanline = &s->scanline[y];
285  const int scanline_height = FFMIN(s->scanline_height, frame->height - y * s->scanline_height);
286  int64_t tmp_size = element_size * s->planes * frame->width * scanline_height;
287  int64_t max_compressed_size = tmp_size * 3 / 2;
288  unsigned long actual_size, source_size;
289 
290  av_fast_padded_malloc(&scanline->uncompressed_data, &scanline->uncompressed_size, tmp_size);
291  if (!scanline->uncompressed_data)
292  return AVERROR(ENOMEM);
293 
294  av_fast_padded_malloc(&scanline->tmp, &scanline->tmp_size, tmp_size);
295  if (!scanline->tmp)
296  return AVERROR(ENOMEM);
297 
298  av_fast_padded_malloc(&scanline->compressed_data, &scanline->compressed_size, max_compressed_size);
299  if (!scanline->compressed_data)
300  return AVERROR(ENOMEM);
301 
302  switch (s->pixel_type) {
303  case EXR_FLOAT:
304  for (int l = 0; l < scanline_height; l++) {
305  const int scanline_size = frame->width * 4 * s->planes;
306 
307  for (int p = 0; p < s->planes; p++) {
308  int ch = s->ch_order[p];
309 
310  memcpy(scanline->uncompressed_data + scanline_size * l + p * frame->width * 4,
311  frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch],
312  frame->width * 4);
313  }
314  }
315  break;
316  case EXR_HALF:
317  for (int l = 0; l < scanline_height; l++) {
318  const int scanline_size = frame->width * 2 * s->planes;
319 
320  for (int p = 0; p < s->planes; p++) {
321  int ch = s->ch_order[p];
322  uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + scanline_size * l + p * frame->width * 2);
323  const uint32_t *src = (const uint32_t *)(frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch]);
324 
325  for (int x = 0; x < frame->width; x++)
326  dst[x] = float2half(src[x], &s->f2h_tables);
327  }
328  }
329  break;
330  }
331 
332  reorder_pixels(scanline->tmp, scanline->uncompressed_data, tmp_size);
333  predictor(scanline->tmp, tmp_size);
334  source_size = tmp_size;
335  actual_size = max_compressed_size;
336  compress(scanline->compressed_data, &actual_size,
337  scanline->tmp, source_size);
338 
339  scanline->actual_size = actual_size;
340  if (scanline->actual_size >= tmp_size) {
341  FFSWAP(uint8_t *, scanline->uncompressed_data, scanline->compressed_data);
342  FFSWAP(int, scanline->uncompressed_size, scanline->compressed_size);
343  scanline->actual_size = tmp_size;
344  }
345  }
346 
347  return 0;
348 }
349 
351  const AVFrame *frame, int *got_packet)
352 {
353  EXRContext *s = avctx->priv_data;
354  PutByteContext *pb = &s->pb;
355  int64_t offset;
356  int ret;
357  int64_t out_size = 2048LL + avctx->height * 16LL +
359  avctx->width,
360  avctx->height, 64) * 3LL / 2;
361 
362  if ((ret = ff_get_encode_buffer(avctx, pkt, out_size, 0)) < 0)
363  return ret;
364 
366 
367  bytestream2_put_le32(pb, 20000630);
368  bytestream2_put_byte(pb, 2);
369  bytestream2_put_le24(pb, 0);
370  bytestream2_put_buffer(pb, "channels\0chlist\0", 16);
371  bytestream2_put_le32(pb, s->planes * 18 + 1);
372 
373  for (int p = 0; p < s->planes; p++) {
374  bytestream2_put_byte(pb, s->ch_names[p]);
375  bytestream2_put_byte(pb, 0);
376  bytestream2_put_le32(pb, s->pixel_type);
377  bytestream2_put_le32(pb, 0);
378  bytestream2_put_le32(pb, 1);
379  bytestream2_put_le32(pb, 1);
380  }
381  bytestream2_put_byte(pb, 0);
382 
383  bytestream2_put_buffer(pb, "compression\0compression\0", 24);
384  bytestream2_put_le32(pb, 1);
385  bytestream2_put_byte(pb, s->compression);
386 
387  bytestream2_put_buffer(pb, "dataWindow\0box2i\0", 17);
388  bytestream2_put_le32(pb, 16);
389  bytestream2_put_le32(pb, 0);
390  bytestream2_put_le32(pb, 0);
391  bytestream2_put_le32(pb, avctx->width - 1);
392  bytestream2_put_le32(pb, avctx->height - 1);
393 
394  bytestream2_put_buffer(pb, "displayWindow\0box2i\0", 20);
395  bytestream2_put_le32(pb, 16);
396  bytestream2_put_le32(pb, 0);
397  bytestream2_put_le32(pb, 0);
398  bytestream2_put_le32(pb, avctx->width - 1);
399  bytestream2_put_le32(pb, avctx->height - 1);
400 
401  bytestream2_put_buffer(pb, "lineOrder\0lineOrder\0", 20);
402  bytestream2_put_le32(pb, 1);
403  bytestream2_put_byte(pb, 0);
404 
405  bytestream2_put_buffer(pb, "screenWindowCenter\0v2f\0", 23);
406  bytestream2_put_le32(pb, 8);
407  bytestream2_put_le64(pb, 0);
408 
409  bytestream2_put_buffer(pb, "screenWindowWidth\0float\0", 24);
410  bytestream2_put_le32(pb, 4);
411  bytestream2_put_le32(pb, av_float2int(1.f));
412 
413  if (avctx->sample_aspect_ratio.num && avctx->sample_aspect_ratio.den) {
414  bytestream2_put_buffer(pb, "pixelAspectRatio\0float\0", 23);
415  bytestream2_put_le32(pb, 4);
416  bytestream2_put_le32(pb, av_float2int(av_q2d(avctx->sample_aspect_ratio)));
417  }
418 
419  if (avctx->framerate.num && avctx->framerate.den) {
420  bytestream2_put_buffer(pb, "framesPerSecond\0rational\0", 25);
421  bytestream2_put_le32(pb, 8);
422  bytestream2_put_le32(pb, avctx->framerate.num);
423  bytestream2_put_le32(pb, avctx->framerate.den);
424  }
425 
426  bytestream2_put_buffer(pb, "gamma\0float\0", 12);
427  bytestream2_put_le32(pb, 4);
428  bytestream2_put_le32(pb, av_float2int(s->gamma));
429 
430  bytestream2_put_buffer(pb, "writer\0string\0", 14);
431  bytestream2_put_le32(pb, 4);
432  bytestream2_put_buffer(pb, "lavc", 4);
433  bytestream2_put_byte(pb, 0);
434 
435  switch (s->compression) {
436  case EXR_RAW:
437  /* nothing to do */
438  break;
439  case EXR_RLE:
441  break;
442  case EXR_ZIP16:
443  case EXR_ZIP1:
445  break;
446  default:
447  av_assert0(0);
448  }
449 
450  switch (s->compression) {
451  case EXR_RAW:
452  offset = bytestream2_tell_p(pb) + avctx->height * 8LL;
453 
454  if (s->pixel_type == EXR_FLOAT) {
455 
456  for (int y = 0; y < avctx->height; y++) {
457  bytestream2_put_le64(pb, offset);
458  offset += avctx->width * s->planes * 4 + 8;
459  }
460 
461  for (int y = 0; y < avctx->height; y++) {
462  bytestream2_put_le32(pb, y);
463  bytestream2_put_le32(pb, s->planes * avctx->width * 4);
464  for (int p = 0; p < s->planes; p++) {
465  int ch = s->ch_order[p];
466  bytestream2_put_buffer(pb, frame->data[ch] + y * frame->linesize[ch],
467  avctx->width * 4);
468  }
469  }
470  } else {
471  for (int y = 0; y < avctx->height; y++) {
472  bytestream2_put_le64(pb, offset);
473  offset += avctx->width * s->planes * 2 + 8;
474  }
475 
476  for (int y = 0; y < avctx->height; y++) {
477  bytestream2_put_le32(pb, y);
478  bytestream2_put_le32(pb, s->planes * avctx->width * 2);
479  for (int p = 0; p < s->planes; p++) {
480  int ch = s->ch_order[p];
481  const uint32_t *src = (const uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
482 
483  for (int x = 0; x < frame->width; x++)
484  bytestream2_put_le16(pb, float2half(src[x], &s->f2h_tables));
485  }
486  }
487  }
488  break;
489  case EXR_ZIP16:
490  case EXR_ZIP1:
491  case EXR_RLE:
492  offset = bytestream2_tell_p(pb) + s->nb_scanlines * 8LL;
493 
494  for (int y = 0; y < s->nb_scanlines; y++) {
495  EXRScanlineData *scanline = &s->scanline[y];
496 
497  bytestream2_put_le64(pb, offset);
498  offset += scanline->actual_size + 8;
499  }
500 
501  for (int y = 0; y < s->nb_scanlines; y++) {
502  EXRScanlineData *scanline = &s->scanline[y];
503 
504  bytestream2_put_le32(pb, y * s->scanline_height);
505  bytestream2_put_le32(pb, scanline->actual_size);
507  scanline->actual_size);
508  }
509  break;
510  default:
511  av_assert0(0);
512  }
513 
515 
516  *got_packet = 1;
517 
518  return 0;
519 }
520 
521 #define OFFSET(x) offsetof(EXRContext, x)
522 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
523 static const AVOption options[] = {
524  { "compression", "set compression type", OFFSET(compression), AV_OPT_TYPE_INT, {.i64=0}, 0, EXR_NBCOMPR-1, VE, "compr" },
525  { "none", "none", 0, AV_OPT_TYPE_CONST, {.i64=EXR_RAW}, 0, 0, VE, "compr" },
526  { "rle" , "RLE", 0, AV_OPT_TYPE_CONST, {.i64=EXR_RLE}, 0, 0, VE, "compr" },
527  { "zip1", "ZIP1", 0, AV_OPT_TYPE_CONST, {.i64=EXR_ZIP1}, 0, 0, VE, "compr" },
528  { "zip16", "ZIP16", 0, AV_OPT_TYPE_CONST, {.i64=EXR_ZIP16}, 0, 0, VE, "compr" },
529  { "format", "set pixel type", OFFSET(pixel_type), AV_OPT_TYPE_INT, {.i64=EXR_FLOAT}, EXR_HALF, EXR_UNKNOWN-1, VE, "pixel" },
530  { "half" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=EXR_HALF}, 0, 0, VE, "pixel" },
531  { "float", NULL, 0, AV_OPT_TYPE_CONST, {.i64=EXR_FLOAT}, 0, 0, VE, "pixel" },
532  { "gamma", "set gamma", OFFSET(gamma), AV_OPT_TYPE_FLOAT, {.dbl=1.f}, 0.001, FLT_MAX, VE },
533  { NULL},
534 };
535 
536 static const AVClass exr_class = {
537  .class_name = "exr",
538  .item_name = av_default_item_name,
539  .option = options,
540  .version = LIBAVUTIL_VERSION_INT,
541 };
542 
544  .p.name = "exr",
545  CODEC_LONG_NAME("OpenEXR image"),
546  .priv_data_size = sizeof(EXRContext),
547  .p.priv_class = &exr_class,
548  .p.type = AVMEDIA_TYPE_VIDEO,
549  .p.id = AV_CODEC_ID_EXR,
550  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
551  .init = encode_init,
553  .close = encode_close,
554  .p.pix_fmts = (const enum AVPixelFormat[]) {
558  AV_PIX_FMT_NONE },
559 };
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
Float2HalfTables
Definition: float2half.h:27
ff_init_float2half_tables
void ff_init_float2half_tables(Float2HalfTables *t)
Definition: float2half.c:21
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:119
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:536
EXRContext::scanline_height
int scanline_height
Definition: exrenc.c:82
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1735
EXR_RAW
@ EXR_RAW
Definition: exrenc.c:41
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:123
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:307
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:491
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:264
EXRContext::ch_order
const uint8_t * ch_order
Definition: exrenc.c:85
OFFSET
#define OFFSET(x)
Definition: exrenc.c:521
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:232
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:182
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:203
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
EXRScanlineData::tmp_size
unsigned int tmp_size
Definition: exrenc.c:70
EXRContext::f2h_tables
Float2HalfTables f2h_tables
Definition: exrenc.c:90
encode_scanline_zip
static int encode_scanline_zip(EXRContext *s, const AVFrame *frame)
Definition: exrenc.c:279
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
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:488
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:543
encode_init
static av_cold int encode_init(AVCodecContext *avctx)
Definition: exrenc.c:93
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:170
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:141
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:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
EXR_UINT
@ EXR_UINT
Definition: exrenc.c:49
EXRScanlineData
Definition: exrenc.c:62
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:211
EXR_HALF
@ EXR_HALF
Definition: exrenc.c:50
AVCodecContext::height
int height
Definition: avcodec.h:571
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:608
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
avcodec.h
options
static const AVOption options[]
Definition: exrenc.c:523
encode_scanline_rle
static int encode_scanline_rle(EXRContext *s, const AVFrame *frame)
Definition: exrenc.c:221
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
float2half
static uint16_t float2half(uint32_t f, const Float2HalfTables *t)
Definition: float2half.h:38
reorder_pixels
static void reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size)
Definition: exrenc.c:158
AVCodecContext
main external API structure.
Definition: avcodec.h:398
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:489
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:425
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:156
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:571
bytestream.h
VE
#define VE
Definition: exrenc.c:522
imgutils.h
encode_frame
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: exrenc.c:350
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:768
EXRContext
Definition: exr.c:146