LCOV - code coverage report
Current view: top level - libavfilter - vf_showinfo.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 109 0.0 %
Date: 2017-12-15 18:13:28 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2011 Stefano Sabatini
       3             :  * This file is part of FFmpeg.
       4             :  *
       5             :  * FFmpeg is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU Lesser General Public
       7             :  * License as published by the Free Software Foundation; either
       8             :  * version 2.1 of the License, or (at your option) any later version.
       9             :  *
      10             :  * FFmpeg is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * Lesser General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public
      16             :  * License along with FFmpeg; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      18             :  */
      19             : 
      20             : /**
      21             :  * @file
      22             :  * filter for showing textual video frame information
      23             :  */
      24             : 
      25             : #include <inttypes.h>
      26             : 
      27             : #include "libavutil/adler32.h"
      28             : #include "libavutil/display.h"
      29             : #include "libavutil/imgutils.h"
      30             : #include "libavutil/internal.h"
      31             : #include "libavutil/pixdesc.h"
      32             : #include "libavutil/spherical.h"
      33             : #include "libavutil/stereo3d.h"
      34             : #include "libavutil/timestamp.h"
      35             : 
      36             : #include "avfilter.h"
      37             : #include "internal.h"
      38             : #include "video.h"
      39             : 
      40           0 : static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, AVFrameSideData *sd)
      41             : {
      42           0 :     AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
      43             :     double yaw, pitch, roll;
      44             : 
      45           0 :     av_log(ctx, AV_LOG_INFO, "spherical information: ");
      46           0 :     if (sd->size < sizeof(*spherical)) {
      47           0 :         av_log(ctx, AV_LOG_INFO, "invalid data");
      48           0 :         return;
      49             :     }
      50             : 
      51           0 :     if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR)
      52           0 :         av_log(ctx, AV_LOG_INFO, "equirectangular ");
      53           0 :     else if (spherical->projection == AV_SPHERICAL_CUBEMAP)
      54           0 :         av_log(ctx, AV_LOG_INFO, "cubemap ");
      55           0 :     else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE)
      56           0 :         av_log(ctx, AV_LOG_INFO, "tiled equirectangular ");
      57             :     else {
      58           0 :         av_log(ctx, AV_LOG_WARNING, "unknown");
      59           0 :         return;
      60             :     }
      61             : 
      62           0 :     yaw = ((double)spherical->yaw) / (1 << 16);
      63           0 :     pitch = ((double)spherical->pitch) / (1 << 16);
      64           0 :     roll = ((double)spherical->roll) / (1 << 16);
      65           0 :     av_log(ctx, AV_LOG_INFO, "(%f/%f/%f) ", yaw, pitch, roll);
      66             : 
      67           0 :     if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
      68             :         size_t l, t, r, b;
      69           0 :         av_spherical_tile_bounds(spherical, frame->width, frame->height,
      70             :                                  &l, &t, &r, &b);
      71           0 :         av_log(ctx, AV_LOG_INFO, "[%zu, %zu, %zu, %zu] ", l, t, r, b);
      72           0 :     } else if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
      73           0 :         av_log(ctx, AV_LOG_INFO, "[pad %"PRIu32"] ", spherical->padding);
      74             :     }
      75             : }
      76             : 
      77           0 : static void dump_stereo3d(AVFilterContext *ctx, AVFrameSideData *sd)
      78             : {
      79             :     AVStereo3D *stereo;
      80             : 
      81           0 :     av_log(ctx, AV_LOG_INFO, "stereoscopic information: ");
      82           0 :     if (sd->size < sizeof(*stereo)) {
      83           0 :         av_log(ctx, AV_LOG_INFO, "invalid data");
      84           0 :         return;
      85             :     }
      86             : 
      87           0 :     stereo = (AVStereo3D *)sd->data;
      88             : 
      89           0 :     av_log(ctx, AV_LOG_INFO, "type - %s", av_stereo3d_type_name(stereo->type));
      90             : 
      91           0 :     if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
      92           0 :         av_log(ctx, AV_LOG_INFO, " (inverted)");
      93             : }
      94             : 
      95           0 : static void update_sample_stats(const uint8_t *src, int len, int64_t *sum, int64_t *sum2)
      96             : {
      97             :     int i;
      98             : 
      99           0 :     for (i = 0; i < len; i++) {
     100           0 :         *sum += src[i];
     101           0 :         *sum2 += src[i] * src[i];
     102             :     }
     103           0 : }
     104             : 
     105           0 : static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
     106             : {
     107           0 :     AVFilterContext *ctx = inlink->dst;
     108           0 :     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     109           0 :     uint32_t plane_checksum[4] = {0}, checksum = 0;
     110           0 :     int64_t sum[4] = {0}, sum2[4] = {0};
     111           0 :     int32_t pixelcount[4] = {0};
     112           0 :     int i, plane, vsub = desc->log2_chroma_h;
     113             : 
     114           0 :     for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
     115           0 :         uint8_t *data = frame->data[plane];
     116           0 :         int h = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
     117           0 :         int linesize = av_image_get_linesize(frame->format, frame->width, plane);
     118             : 
     119           0 :         if (linesize < 0)
     120           0 :             return linesize;
     121             : 
     122           0 :         for (i = 0; i < h; i++) {
     123           0 :             plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize);
     124           0 :             checksum = av_adler32_update(checksum, data, linesize);
     125             : 
     126           0 :             update_sample_stats(data, linesize, sum+plane, sum2+plane);
     127           0 :             pixelcount[plane] += linesize;
     128           0 :             data += frame->linesize[plane];
     129             :         }
     130             :     }
     131             : 
     132           0 :     av_log(ctx, AV_LOG_INFO,
     133             :            "n:%4"PRId64" pts:%7s pts_time:%-7s pos:%9"PRId64" "
     134             :            "fmt:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c "
     135             :            "checksum:%08"PRIX32" plane_checksum:[%08"PRIX32,
     136             :            inlink->frame_count_out,
     137           0 :            av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base), frame->pkt_pos,
     138             :            desc->name,
     139             :            frame->sample_aspect_ratio.num, frame->sample_aspect_ratio.den,
     140             :            frame->width, frame->height,
     141           0 :            !frame->interlaced_frame ? 'P' :         /* Progressive  */
     142           0 :            frame->top_field_first   ? 'T' : 'B',    /* Top / Bottom */
     143             :            frame->key_frame,
     144           0 :            av_get_picture_type_char(frame->pict_type),
     145             :            checksum, plane_checksum[0]);
     146             : 
     147           0 :     for (plane = 1; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++)
     148           0 :         av_log(ctx, AV_LOG_INFO, " %08"PRIX32, plane_checksum[plane]);
     149           0 :     av_log(ctx, AV_LOG_INFO, "] mean:[");
     150           0 :     for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++)
     151           0 :         av_log(ctx, AV_LOG_INFO, "%"PRId64" ", (sum[plane] + pixelcount[plane]/2) / pixelcount[plane]);
     152           0 :     av_log(ctx, AV_LOG_INFO, "\b] stdev:[");
     153           0 :     for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++)
     154           0 :         av_log(ctx, AV_LOG_INFO, "%3.1f ",
     155           0 :                sqrt((sum2[plane] - sum[plane]*(double)sum[plane]/pixelcount[plane])/pixelcount[plane]));
     156           0 :     av_log(ctx, AV_LOG_INFO, "\b]\n");
     157             : 
     158           0 :     for (i = 0; i < frame->nb_side_data; i++) {
     159           0 :         AVFrameSideData *sd = frame->side_data[i];
     160             : 
     161           0 :         av_log(ctx, AV_LOG_INFO, "  side data - ");
     162           0 :         switch (sd->type) {
     163           0 :         case AV_FRAME_DATA_PANSCAN:
     164           0 :             av_log(ctx, AV_LOG_INFO, "pan/scan");
     165           0 :             break;
     166           0 :         case AV_FRAME_DATA_A53_CC:
     167           0 :             av_log(ctx, AV_LOG_INFO, "A/53 closed captions (%d bytes)", sd->size);
     168           0 :             break;
     169           0 :         case AV_FRAME_DATA_SPHERICAL:
     170           0 :             dump_spherical(ctx, frame, sd);
     171           0 :             break;
     172           0 :         case AV_FRAME_DATA_STEREO3D:
     173           0 :             dump_stereo3d(ctx, sd);
     174           0 :             break;
     175           0 :         case AV_FRAME_DATA_DISPLAYMATRIX:
     176           0 :             av_log(ctx, AV_LOG_INFO, "displaymatrix: rotation of %.2f degrees",
     177           0 :                    av_display_rotation_get((int32_t *)sd->data));
     178           0 :             break;
     179           0 :         case AV_FRAME_DATA_AFD:
     180           0 :             av_log(ctx, AV_LOG_INFO, "afd: value of %"PRIu8, sd->data[0]);
     181           0 :             break;
     182           0 :         default:
     183           0 :             av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)",
     184           0 :                    sd->type, sd->size);
     185           0 :             break;
     186             :         }
     187             : 
     188           0 :         av_log(ctx, AV_LOG_INFO, "\n");
     189             :     }
     190             : 
     191           0 :     return ff_filter_frame(inlink->dst->outputs[0], frame);
     192             : }
     193             : 
     194           0 : static int config_props(AVFilterContext *ctx, AVFilterLink *link, int is_out)
     195             : {
     196             : 
     197           0 :     av_log(ctx, AV_LOG_INFO, "config %s time_base: %d/%d, frame_rate: %d/%d\n",
     198             :            is_out ? "out" : "in",
     199             :            link->time_base.num, link->time_base.den,
     200             :            link->frame_rate.num, link->frame_rate.den);
     201             : 
     202           0 :     return 0;
     203             : }
     204             : 
     205           0 : static int config_props_in(AVFilterLink *link)
     206             : {
     207           0 :     AVFilterContext *ctx = link->dst;
     208           0 :     return config_props(ctx, link, 0);
     209             : }
     210             : 
     211           0 : static int config_props_out(AVFilterLink *link)
     212             : {
     213           0 :     AVFilterContext *ctx = link->src;
     214           0 :     return config_props(ctx, link, 1);
     215             : }
     216             : 
     217             : static const AVFilterPad avfilter_vf_showinfo_inputs[] = {
     218             :     {
     219             :         .name             = "default",
     220             :         .type             = AVMEDIA_TYPE_VIDEO,
     221             :         .filter_frame     = filter_frame,
     222             :         .config_props     = config_props_in,
     223             :     },
     224             :     { NULL }
     225             : };
     226             : 
     227             : static const AVFilterPad avfilter_vf_showinfo_outputs[] = {
     228             :     {
     229             :         .name = "default",
     230             :         .type = AVMEDIA_TYPE_VIDEO,
     231             :         .config_props  = config_props_out,
     232             :     },
     233             :     { NULL }
     234             : };
     235             : 
     236             : AVFilter ff_vf_showinfo = {
     237             :     .name        = "showinfo",
     238             :     .description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."),
     239             :     .inputs      = avfilter_vf_showinfo_inputs,
     240             :     .outputs     = avfilter_vf_showinfo_outputs,
     241             : };

Generated by: LCOV version 1.13