mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lavfi/extractplanes: packed rgb support
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
8245520b88
commit
c4a5499d25
@ -23,6 +23,7 @@
|
|||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
|
#include "drawutils.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define PLANE_R 0x01
|
#define PLANE_R 0x01
|
||||||
@ -38,6 +39,9 @@ typedef struct {
|
|||||||
int requested_planes;
|
int requested_planes;
|
||||||
int map[4];
|
int map[4];
|
||||||
int linesize[4];
|
int linesize[4];
|
||||||
|
int is_packed_rgb;
|
||||||
|
int depth;
|
||||||
|
int step;
|
||||||
} ExtractPlanesContext;
|
} ExtractPlanesContext;
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(ExtractPlanesContext, x)
|
#define OFFSET(x) offsetof(ExtractPlanesContext, x)
|
||||||
@ -47,8 +51,8 @@ static const AVOption extractplanes_options[] = {
|
|||||||
{ "y", "set luma plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_Y}, 0, 0, FLAGS, "flags"},
|
{ "y", "set luma plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_Y}, 0, 0, FLAGS, "flags"},
|
||||||
{ "u", "set u plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_U}, 0, 0, FLAGS, "flags"},
|
{ "u", "set u plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_U}, 0, 0, FLAGS, "flags"},
|
||||||
{ "v", "set v plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_V}, 0, 0, FLAGS, "flags"},
|
{ "v", "set v plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_V}, 0, 0, FLAGS, "flags"},
|
||||||
{ "g", "set green plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_G}, 0, 0, FLAGS, "flags"},
|
|
||||||
{ "r", "set red plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_R}, 0, 0, FLAGS, "flags"},
|
{ "r", "set red plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_R}, 0, 0, FLAGS, "flags"},
|
||||||
|
{ "g", "set green plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_G}, 0, 0, FLAGS, "flags"},
|
||||||
{ "b", "set blue plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_B}, 0, 0, FLAGS, "flags"},
|
{ "b", "set blue plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_B}, 0, 0, FLAGS, "flags"},
|
||||||
{ "a", "set alpha plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_A}, 0, 0, FLAGS, "flags"},
|
{ "a", "set alpha plane", 0, AV_OPT_TYPE_CONST, {.i64=PLANE_A}, 0, 0, FLAGS, "flags"},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
@ -75,6 +79,13 @@ static int query_formats(AVFilterContext *ctx)
|
|||||||
AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUVA444P16BE,
|
AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUVA444P16BE,
|
||||||
AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A,
|
AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A,
|
||||||
AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE,
|
AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE,
|
||||||
|
AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
|
||||||
|
AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
|
||||||
|
AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
|
||||||
|
AV_PIX_FMT_RGB48LE, AV_PIX_FMT_BGR48LE,
|
||||||
|
AV_PIX_FMT_RGB48BE, AV_PIX_FMT_BGR48BE,
|
||||||
|
AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_BGRA64LE,
|
||||||
|
AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_BGRA64BE,
|
||||||
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
|
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
|
||||||
AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRP16BE,
|
AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRP16BE,
|
||||||
AV_PIX_FMT_GBRAP16LE, AV_PIX_FMT_GBRAP16BE,
|
AV_PIX_FMT_GBRAP16LE, AV_PIX_FMT_GBRAP16BE,
|
||||||
@ -125,7 +136,8 @@ static int config_input(AVFilterLink *inlink)
|
|||||||
AVFilterContext *ctx = inlink->dst;
|
AVFilterContext *ctx = inlink->dst;
|
||||||
ExtractPlanesContext *e = ctx->priv;
|
ExtractPlanesContext *e = ctx->priv;
|
||||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
|
||||||
int plane_avail, ret;
|
int plane_avail, ret, i;
|
||||||
|
uint8_t rgba_map[4];
|
||||||
|
|
||||||
plane_avail = ((desc->flags & PIX_FMT_RGB) ? PLANE_R|PLANE_G|PLANE_B :
|
plane_avail = ((desc->flags & PIX_FMT_RGB) ? PLANE_R|PLANE_G|PLANE_B :
|
||||||
PLANE_Y |
|
PLANE_Y |
|
||||||
@ -138,6 +150,15 @@ static int config_input(AVFilterLink *inlink)
|
|||||||
if ((ret = av_image_fill_linesizes(e->linesize, inlink->format, inlink->w)) < 0)
|
if ((ret = av_image_fill_linesizes(e->linesize, inlink->format, inlink->w)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
e->depth = (desc->comp[0].depth_minus1 + 1) >> 3;
|
||||||
|
e->step = av_get_padded_bits_per_pixel(desc) >> 3;
|
||||||
|
e->is_packed_rgb = !(desc->flags & PIX_FMT_PLANAR);
|
||||||
|
if (desc->flags & PIX_FMT_RGB) {
|
||||||
|
ff_fill_rgba_map(rgba_map, inlink->format);
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
e->map[i] = rgba_map[e->map[i]];
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +178,31 @@ static int config_output(AVFilterLink *outlink)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void extract_from_packed(uint8_t *dst, int dst_linesize,
|
||||||
|
const uint8_t *src, int src_linesize,
|
||||||
|
int width, int height,
|
||||||
|
int depth, int step, int comp)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
switch (depth) {
|
||||||
|
case 1:
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
dst[x] = src[x * step + comp];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
dst[x * 2 ] = src[x * step + comp * 2 ];
|
||||||
|
dst[x * 2 + 1] = src[x * step + comp * 2 + 1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dst += dst_linesize;
|
||||||
|
src += src_linesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
|
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
|
||||||
{
|
{
|
||||||
AVFilterContext *ctx = inlink->dst;
|
AVFilterContext *ctx = inlink->dst;
|
||||||
@ -168,7 +214,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
|
|||||||
const int idx = e->map[i];
|
const int idx = e->map[i];
|
||||||
AVFrame *out;
|
AVFrame *out;
|
||||||
|
|
||||||
if (outlink->closed || !frame->data[idx])
|
if (outlink->closed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
|
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
|
||||||
@ -178,9 +224,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
|
|||||||
}
|
}
|
||||||
av_frame_copy_props(out, frame);
|
av_frame_copy_props(out, frame);
|
||||||
|
|
||||||
av_image_copy_plane(out->data[0], out->linesize[0],
|
if (e->is_packed_rgb) {
|
||||||
frame->data[idx], frame->linesize[idx],
|
extract_from_packed(out->data[0], out->linesize[0],
|
||||||
e->linesize[idx], outlink->h);
|
frame->data[0], frame->linesize[0],
|
||||||
|
outlink->w, outlink->h,
|
||||||
|
e->depth,
|
||||||
|
e->step, idx);
|
||||||
|
} else {
|
||||||
|
av_image_copy_plane(out->data[0], out->linesize[0],
|
||||||
|
frame->data[idx], frame->linesize[idx],
|
||||||
|
e->linesize[idx], outlink->h);
|
||||||
|
}
|
||||||
|
|
||||||
ret = ff_filter_frame(outlink, out);
|
ret = ff_filter_frame(outlink, out);
|
||||||
if (ret == AVERROR_EOF)
|
if (ret == AVERROR_EOF)
|
||||||
eof++;
|
eof++;
|
||||||
|
Loading…
Reference in New Issue
Block a user