00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "libavutil/pixdesc.h"
00027 #include "libavutil/timestamp.h"
00028 #include "avfilter.h"
00029 #include "bbox.h"
00030 #include "internal.h"
00031
00032 typedef struct {
00033 unsigned int frame;
00034 int vsub, hsub;
00035 } BBoxContext;
00036
00037 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
00038 {
00039 BBoxContext *bbox = ctx->priv;
00040 bbox->frame = 0;
00041 return 0;
00042 }
00043
00044 static int query_formats(AVFilterContext *ctx)
00045 {
00046 static const enum PixelFormat pix_fmts[] = {
00047 PIX_FMT_YUV420P,
00048 PIX_FMT_YUV444P,
00049 PIX_FMT_YUV440P,
00050 PIX_FMT_YUV422P,
00051 PIX_FMT_YUV411P,
00052 PIX_FMT_NONE,
00053 };
00054
00055 avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
00056 return 0;
00057 }
00058
00059 static void end_frame(AVFilterLink *inlink)
00060 {
00061 AVFilterContext *ctx = inlink->dst;
00062 BBoxContext *bbox = ctx->priv;
00063 AVFilterBufferRef *picref = inlink->cur_buf;
00064 FFBoundingBox box;
00065 int has_bbox, w, h;
00066
00067 has_bbox =
00068 ff_calculate_bounding_box(&box,
00069 picref->data[0], picref->linesize[0],
00070 inlink->w, inlink->h, 16);
00071 w = box.x2 - box.x1 + 1;
00072 h = box.y2 - box.y1 + 1;
00073
00074 av_log(ctx, AV_LOG_INFO,
00075 "n:%d pts:%s pts_time:%s", bbox->frame,
00076 av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base));
00077
00078 if (has_bbox) {
00079 av_log(ctx, AV_LOG_INFO,
00080 " x1:%d x2:%d y1:%d y2:%d w:%d h:%d"
00081 " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d",
00082 box.x1, box.x2, box.y1, box.y2, w, h,
00083 w, h, box.x1, box.y1,
00084 box.x1, box.y1, w, h);
00085 }
00086 av_log(ctx, AV_LOG_INFO, "\n");
00087
00088 bbox->frame++;
00089 avfilter_unref_buffer(picref);
00090 avfilter_end_frame(inlink->dst->outputs[0]);
00091 }
00092
00093 AVFilter avfilter_vf_bbox = {
00094 .name = "bbox",
00095 .description = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
00096 .priv_size = sizeof(BBoxContext),
00097 .query_formats = query_formats,
00098 .init = init,
00099
00100 .inputs = (const AVFilterPad[]) {
00101 { .name = "default",
00102 .type = AVMEDIA_TYPE_VIDEO,
00103 .get_video_buffer = avfilter_null_get_video_buffer,
00104 .start_frame = ff_null_start_frame_keep_ref,
00105 .end_frame = end_frame,
00106 .min_perms = AV_PERM_READ, },
00107 { .name = NULL }
00108 },
00109
00110 .outputs = (const AVFilterPad[]) {
00111 { .name = "default",
00112 .type = AVMEDIA_TYPE_VIDEO },
00113 { .name = NULL }
00114 },
00115 };