aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Garramuno <ggarra13@gmail.com>2014-02-17 14:53:30 -0300
committerMichael Niedermayer <michaelni@gmx.at>2014-02-18 18:11:23 +0100
commit3d20260157cb65582cb547befe744b9cbfaeac1d (patch)
treed52721b9c21d030527e119c05bd50f0ce5016ae9
parent7716eda0aad718855547e78f1b5cffde18183aa0 (diff)
downloadffmpeg-3d20260157cb65582cb547befe744b9cbfaeac1d.tar.gz
avcodec/exr: read layers
EXR files have, like tiffs, multiple channels and layers. I have a patch for exr.c that allows you to select the layer you want to process thru a -layer flag. It is not bulletproof but works for all layers that have 3 channels in them (normals, motion vectors, etc). The calling convention for ffmpeg is: ffmpeg -layer Diffuse -i myexr.%d.exr test.mov Here's an exr image with multiple layers: http://www.datafilehost.com/d/e45d9a1c Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/exr.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index f231b70375..77247fcb81 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,
@@ -75,6 +76,7 @@ typedef struct EXRThreadData {
} EXRThreadData;
typedef struct EXRContext {
+ AVClass *class;
AVFrame *picture;
int compr;
enum ExrPixelType pixel_type;
@@ -98,8 +100,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 +1008,25 @@ 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,
};