mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
vf_codecview: added new options
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
2234566cfb
commit
7a2b9dd060
@ -4790,16 +4790,48 @@ backward predicted MVs of B-frames
|
||||
@end table
|
||||
|
||||
@item qp
|
||||
Display quantization parameters using the chroma planes
|
||||
Display quantization parameters using the chroma planes.
|
||||
|
||||
@item mv_type, mvt
|
||||
Set motion vectors type to visualize. Includes MVs from all frames unless specified by @var{frame_type} option.
|
||||
|
||||
Available flags for @var{mv_type} are:
|
||||
|
||||
@table @samp
|
||||
@item fp
|
||||
forward predicted MVs
|
||||
@item bp
|
||||
backward predicted MVs
|
||||
@end table
|
||||
|
||||
@item frame_type, ft
|
||||
Set frame type to visualize motion vectors of.
|
||||
|
||||
Available flags for @var{frame_type} are:
|
||||
|
||||
@table @samp
|
||||
@item if
|
||||
intra-coded frames (I-frames)
|
||||
@item pf
|
||||
predicted frames (P-frames)
|
||||
@item bf
|
||||
bi-directionally predicted frames (B-frames)
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Visualizes multi-directionals MVs from P and B-Frames using @command{ffplay}:
|
||||
Visualize forward predicted MVs of all frames using @command{ffplay}:
|
||||
@example
|
||||
ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=pf+bf+bb
|
||||
ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv_type=fp
|
||||
@end example
|
||||
|
||||
@item
|
||||
Visualize multi-directionals MVs of P and B-Frames using @command{ffplay}:
|
||||
@example
|
||||
ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv=pf+bf+bb
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
|
@ -38,22 +38,40 @@
|
||||
#define MV_P_FOR (1<<0)
|
||||
#define MV_B_FOR (1<<1)
|
||||
#define MV_B_BACK (1<<2)
|
||||
#define MV_TYPE_FOR (1<<0)
|
||||
#define MV_TYPE_BACK (1<<1)
|
||||
#define FRAME_TYPE_I (1<<0)
|
||||
#define FRAME_TYPE_P (1<<1)
|
||||
#define FRAME_TYPE_B (1<<2)
|
||||
|
||||
typedef struct {
|
||||
const AVClass *class;
|
||||
unsigned mv;
|
||||
unsigned frame_type;
|
||||
unsigned mv_type;
|
||||
int hsub, vsub;
|
||||
int qp;
|
||||
} CodecViewContext;
|
||||
|
||||
#define OFFSET(x) offsetof(CodecViewContext, x)
|
||||
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
|
||||
#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, unit }
|
||||
|
||||
static const AVOption codecview_options[] = {
|
||||
{ "mv", "set motion vectors to visualize", OFFSET(mv), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "mv" },
|
||||
{"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = MV_P_FOR }, INT_MIN, INT_MAX, FLAGS, "mv"},
|
||||
{"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = MV_B_FOR }, INT_MIN, INT_MAX, FLAGS, "mv"},
|
||||
{"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = MV_B_BACK }, INT_MIN, INT_MAX, FLAGS, "mv"},
|
||||
CONST("pf", "forward predicted MVs of P-frames", MV_P_FOR, "mv"),
|
||||
CONST("bf", "forward predicted MVs of B-frames", MV_B_FOR, "mv"),
|
||||
CONST("bb", "backward predicted MVs of B-frames", MV_B_BACK, "mv"),
|
||||
{ "qp", NULL, OFFSET(qp), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
|
||||
{ "mv_type", "set motion vectors type", OFFSET(mv_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "mv_type" },
|
||||
{ "mvt", "set motion vectors type", OFFSET(mv_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "mv_type" },
|
||||
CONST("fp", "forward predicted MVs", MV_TYPE_FOR, "mv_type"),
|
||||
CONST("bp", "backward predicted MVs", MV_TYPE_BACK, "mv_type"),
|
||||
{ "frame_type", "set frame types to visualize motion vectors of", OFFSET(frame_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "frame_type" },
|
||||
{ "ft", "set frame types to visualize motion vectors of", OFFSET(frame_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "frame_type" },
|
||||
CONST("if", "I-frames", FRAME_TYPE_I, "frame_type"),
|
||||
CONST("pf", "P-frames", FRAME_TYPE_P, "frame_type"),
|
||||
CONST("bf", "B-frames", FRAME_TYPE_B, "frame_type"),
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -224,20 +242,37 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
|
||||
}
|
||||
}
|
||||
|
||||
if (s->mv) {
|
||||
if (s->mv || s->mv_type) {
|
||||
AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
|
||||
if (sd) {
|
||||
int i;
|
||||
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
|
||||
const int is_iframe = (s->frame_type & FRAME_TYPE_I) && frame->pict_type == AV_PICTURE_TYPE_I;
|
||||
const int is_pframe = (s->frame_type & FRAME_TYPE_P) && frame->pict_type == AV_PICTURE_TYPE_P;
|
||||
const int is_bframe = (s->frame_type & FRAME_TYPE_B) && frame->pict_type == AV_PICTURE_TYPE_B;
|
||||
|
||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
||||
const AVMotionVector *mv = &mvs[i];
|
||||
const int direction = mv->source > 0;
|
||||
if ((direction == 0 && (s->mv & MV_P_FOR) && frame->pict_type == AV_PICTURE_TYPE_P) ||
|
||||
(direction == 0 && (s->mv & MV_B_FOR) && frame->pict_type == AV_PICTURE_TYPE_B) ||
|
||||
(direction == 1 && (s->mv & MV_B_BACK) && frame->pict_type == AV_PICTURE_TYPE_B))
|
||||
draw_arrow(frame->data[0], mv->dst_x, mv->dst_y, mv->src_x, mv->src_y,
|
||||
frame->width, frame->height, frame->linesize[0],
|
||||
100, 0, mv->source > 0);
|
||||
|
||||
if (s->mv_type) {
|
||||
const int is_fp = direction == 0 && (s->mv_type & MV_TYPE_FOR);
|
||||
const int is_bp = direction == 1 && (s->mv_type & MV_TYPE_BACK);
|
||||
|
||||
if ((!s->frame_type && (is_fp || is_bp)) ||
|
||||
is_iframe && is_fp || is_iframe && is_bp ||
|
||||
is_pframe && is_fp ||
|
||||
is_bframe && is_fp || is_bframe && is_bp)
|
||||
draw_arrow(frame->data[0], mv->dst_x, mv->dst_y, mv->src_x, mv->src_y,
|
||||
frame->width, frame->height, frame->linesize[0],
|
||||
100, 0, direction);
|
||||
} else if (s->mv)
|
||||
if ((direction == 0 && (s->mv & MV_P_FOR) && frame->pict_type == AV_PICTURE_TYPE_P) ||
|
||||
(direction == 0 && (s->mv & MV_B_FOR) && frame->pict_type == AV_PICTURE_TYPE_B) ||
|
||||
(direction == 1 && (s->mv & MV_B_BACK) && frame->pict_type == AV_PICTURE_TYPE_B))
|
||||
draw_arrow(frame->data[0], mv->dst_x, mv->dst_y, mv->src_x, mv->src_y,
|
||||
frame->width, frame->height, frame->linesize[0],
|
||||
100, 0, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user