mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-17 21:14:47 +00:00
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>
This commit is contained in:
parent
7716eda0aa
commit
3d20260157
@ -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,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user