[Libav-user] EXR channel support?

Gonzalo Garramuno ggarra13 at gmail.com
Sat Feb 15 14:23:57 CET 2014


On 15/02/14 04:56, Paul B Mahol wrote:
> Also the layer option is not used at all....
>

Here's a patch with layer being printed that segfaults.  It seems the 
field is never initialized nor parsed, even though command-line works.
-------------- next part --------------
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index f231b70..0d3a793 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,
@@ -90,6 +91,8 @@ typedef struct EXRContext {
     uint64_t scan_line_size;
     int scan_lines_per_block;
 
+    char* layer;
+
     const uint8_t *buf, *table;
     int buf_size;
 
@@ -100,6 +103,20 @@ typedef struct EXRContext {
     int thread_data_size;
 } 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
  *
@@ -951,6 +968,7 @@ static int decode_frame(AVCodecContext *avctx,
     s->buf = buf;
     s->buf_size = buf_size;
 
+    
     if (buf_size < 10) {
         av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
         return AVERROR_INVALIDDATA;
@@ -974,6 +992,7 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_PATCHWELCOME;
     }
 
+
     // Parse the header
     while (buf < buf_end && buf[0]) {
         unsigned int variable_buffer_data_size;
@@ -990,13 +1009,17 @@ static int decode_frame(AVCodecContext *avctx,
                 int channel_index = -1;
                 int xsub, ysub;
 
-                if (!strcmp(buf, "R"))
+		const char* b = buf + strlen(buf) - 1;
+		
+		av_log( avctx, AV_LOG_INFO, "Layer %s\n", s->layer );
+
+                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"))
                     channel_index = 2;
-                else if (!strcmp(buf, "A"))
+                else if (!strcmp(b, "A")||!strcmp(b, "W"))
                     channel_index = 3;
                 else
                     av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
@@ -1275,4 +1298,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