diff options
author | Gonzalo Garramuno <ggarra13@gmail.com> | 2014-02-17 14:53:30 -0300 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-02-18 18:11:23 +0100 |
commit | 3d20260157cb65582cb547befe744b9cbfaeac1d (patch) | |
tree | d52721b9c21d030527e119c05bd50f0ce5016ae9 | |
parent | 7716eda0aad718855547e78f1b5cffde18183aa0 (diff) | |
download | ffmpeg-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.c | 39 |
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, }; |