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