[Libav-user] EXR channel support?

Gonzalo Garramuno ggarra13 at gmail.com
Sat Feb 15 22:24:41 CET 2014


Here's the final patch that works out the layers for exr.  This patch 
works fine if run under valgrind but segfaults otherwise if run 
normally.  The problem appears to be the parsing of options (and thus in 
my options definition I guess).  Commenting out: priv_class = 
&exr_class, makes it work fine (albeit with no options of course).

-------------- next part --------------
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index f231b70..c8ba1e9 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -40,6 +40,7 @@
 #include "thread.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/avassert.h"
+#include "libavutil/opt.h"
 
 enum ExrCompr {
     EXR_RAW   = 0,
@@ -98,8 +99,24 @@ typedef struct EXRContext {
 
     EXRThreadData *thread_data;
     int thread_data_size;
+
+    const char* layer;
 } EXRContext;
 
+#define OFFSET(x) offsetof(EXRContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    { "layer",        "Set the decoding layer",   OFFSET(layer),        AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD},
+    { NULL },
+};
+
+static const AVClass exr_class = {
+    .class_name = "EXR",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 /**
  * Converts from 32-bit float as uint32_t to uint16_t
  *
@@ -990,13 +1007,26 @@ static int decode_frame(AVCodecContext *avctx,
                 int channel_index = -1;
                 int xsub, ysub;
 
-                if (!strcmp(buf, "R"))
+		const char* b = buf;
+
+		if ( strcmp( s->layer, "" ) != 0 )
+		{
+		   if ( strncmp( b, s->layer, strlen(s->layer) ) == 0 )
+		   {
+		      b += strlen(s->layer);
+		      if ( *b == '.' ) ++b;   /* skip dot if not given */
+		      av_log( avctx, AV_LOG_INFO, "Layer %s.%s matched\n", s->layer, b );
+		   }
+		}
+
+
+                if (!strcmp(b, "R")||!strcmp(b, "X")||!strcmp(b,"U"))
                     channel_index = 0;
-                else if (!strcmp(buf, "G"))
+                else if (!strcmp(b, "G")||!strcmp(b, "Y")||!strcmp(b,"V"))
                     channel_index = 1;
-                else if (!strcmp(buf, "B"))
+                else if (!strcmp(b, "B")||!strcmp(b, "Z")||!strcmp(b,"W"))
                     channel_index = 2;
-                else if (!strcmp(buf, "A"))
+                else if (!strcmp(b, "A"))
                     channel_index = 3;
                 else
                     av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
@@ -1275,4 +1305,5 @@ AVCodec ff_exr_decoder = {
     .close              = decode_end,
     .decode             = decode_frame,
     .capabilities       = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
+    .priv_class         = &exr_class,
 };


More information about the Libav-user mailing list