Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2012 Stefano Sabatini
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. /**
  22.  * @file
  23.  * bounding box detection filter
  24.  */
  25.  
  26. #include "libavutil/opt.h"
  27. #include "libavutil/pixdesc.h"
  28. #include "libavutil/timestamp.h"
  29. #include "avfilter.h"
  30. #include "bbox.h"
  31. #include "internal.h"
  32.  
  33. typedef struct {
  34.     const AVClass *class;
  35.     int min_val;
  36. } BBoxContext;
  37.  
  38. #define OFFSET(x) offsetof(BBoxContext, x)
  39. #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  40.  
  41. static const AVOption bbox_options[] = {
  42.     { "min_val", "set minimum luminance value for bounding box", OFFSET(min_val), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 254, FLAGS },
  43.     { NULL }
  44. };
  45.  
  46. AVFILTER_DEFINE_CLASS(bbox);
  47.  
  48. static int query_formats(AVFilterContext *ctx)
  49. {
  50.     static const enum AVPixelFormat pix_fmts[] = {
  51.         AV_PIX_FMT_YUV420P,
  52.         AV_PIX_FMT_YUV444P,
  53.         AV_PIX_FMT_YUV440P,
  54.         AV_PIX_FMT_YUV422P,
  55.         AV_PIX_FMT_YUV411P,
  56.         AV_PIX_FMT_NONE,
  57.     };
  58.  
  59.     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
  60.     return 0;
  61. }
  62.  
  63. #define SET_META(key, value) \
  64.     snprintf(buf, sizeof(buf), "%d", value);  \
  65.     av_dict_set(metadata, key, buf, 0);
  66.  
  67. static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
  68. {
  69.     AVFilterContext *ctx = inlink->dst;
  70.     BBoxContext *bbox = ctx->priv;
  71.     FFBoundingBox box;
  72.     int has_bbox, w, h;
  73.     char buf[32];
  74.  
  75.     has_bbox =
  76.         ff_calculate_bounding_box(&box,
  77.                                   frame->data[0], frame->linesize[0],
  78.                                   inlink->w, inlink->h, bbox->min_val);
  79.     w = box.x2 - box.x1 + 1;
  80.     h = box.y2 - box.y1 + 1;
  81.  
  82.     av_log(ctx, AV_LOG_INFO,
  83.            "n:%"PRId64" pts:%s pts_time:%s", inlink->frame_count,
  84.            av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base));
  85.  
  86.     if (has_bbox) {
  87.         AVDictionary **metadata = avpriv_frame_get_metadatap(frame);
  88.  
  89.         SET_META("lavfi.bbox.x1", box.x1)
  90.         SET_META("lavfi.bbox.x2", box.x2)
  91.         SET_META("lavfi.bbox.y1", box.y1)
  92.         SET_META("lavfi.bbox.y2", box.y2)
  93.         SET_META("lavfi.bbox.w",  w)
  94.         SET_META("lavfi.bbox.h",  h)
  95.  
  96.         av_log(ctx, AV_LOG_INFO,
  97.                " x1:%d x2:%d y1:%d y2:%d w:%d h:%d"
  98.                " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d",
  99.                box.x1, box.x2, box.y1, box.y2, w, h,
  100.                w, h, box.x1, box.y1,    /* crop params */
  101.                box.x1, box.y1, w, h);   /* drawbox params */
  102.     }
  103.     av_log(ctx, AV_LOG_INFO, "\n");
  104.  
  105.     return ff_filter_frame(inlink->dst->outputs[0], frame);
  106. }
  107.  
  108. static const AVFilterPad bbox_inputs[] = {
  109.     {
  110.         .name         = "default",
  111.         .type         = AVMEDIA_TYPE_VIDEO,
  112.         .filter_frame = filter_frame,
  113.     },
  114.     { NULL }
  115. };
  116.  
  117. static const AVFilterPad bbox_outputs[] = {
  118.     {
  119.         .name = "default",
  120.         .type = AVMEDIA_TYPE_VIDEO,
  121.     },
  122.     { NULL }
  123. };
  124.  
  125. AVFilter avfilter_vf_bbox = {
  126.     .name          = "bbox",
  127.     .description   = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
  128.     .priv_size     = sizeof(BBoxContext),
  129.     .priv_class    = &bbox_class,
  130.     .query_formats = query_formats,
  131.     .inputs        = bbox_inputs,
  132.     .outputs       = bbox_outputs,
  133.     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
  134. };
  135.