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)
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 AVPixelFormat pix_fmts[] = {
00047 AV_PIX_FMT_YUV420P,
00048 AV_PIX_FMT_YUV444P,
00049 AV_PIX_FMT_YUV440P,
00050 AV_PIX_FMT_YUV422P,
00051 AV_PIX_FMT_YUV411P,
00052 AV_PIX_FMT_NONE,
00053 };
00054
00055 ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
00056 return 0;
00057 }
00058
00059 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
00060 {
00061 AVFilterContext *ctx = inlink->dst;
00062 BBoxContext *bbox = ctx->priv;
00063 FFBoundingBox box;
00064 int has_bbox, w, h;
00065
00066 has_bbox =
00067 ff_calculate_bounding_box(&box,
00068 picref->data[0], picref->linesize[0],
00069 inlink->w, inlink->h, 16);
00070 w = box.x2 - box.x1 + 1;
00071 h = box.y2 - box.y1 + 1;
00072
00073 av_log(ctx, AV_LOG_INFO,
00074 "n:%d pts:%s pts_time:%s", bbox->frame,
00075 av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base));
00076
00077 if (has_bbox) {
00078 av_log(ctx, AV_LOG_INFO,
00079 " x1:%d x2:%d y1:%d y2:%d w:%d h:%d"
00080 " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d",
00081 box.x1, box.x2, box.y1, box.y2, w, h,
00082 w, h, box.x1, box.y1,
00083 box.x1, box.y1, w, h);
00084 }
00085 av_log(ctx, AV_LOG_INFO, "\n");
00086
00087 bbox->frame++;
00088 return ff_filter_frame(inlink->dst->outputs[0], picref);
00089 }
00090
00091 static const AVFilterPad bbox_inputs[] = {
00092 {
00093 .name = "default",
00094 .type = AVMEDIA_TYPE_VIDEO,
00095 .get_video_buffer = ff_null_get_video_buffer,
00096 .filter_frame = filter_frame,
00097 .min_perms = AV_PERM_READ,
00098 },
00099 { NULL }
00100 };
00101
00102 static const AVFilterPad bbox_outputs[] = {
00103 {
00104 .name = "default",
00105 .type = AVMEDIA_TYPE_VIDEO,
00106 },
00107 { NULL }
00108 };
00109
00110 AVFilter avfilter_vf_bbox = {
00111 .name = "bbox",
00112 .description = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
00113 .priv_size = sizeof(BBoxContext),
00114 .query_formats = query_formats,
00115 .init = init,
00116 .inputs = bbox_inputs,
00117 .outputs = bbox_outputs,
00118 };