| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 <ctype.h> | ||
| 26 | #include <inttypes.h> | ||
| 27 | |||
| 28 | #include "libavutil/bswap.h" | ||
| 29 | #include "libavutil/adler32.h" | ||
| 30 | #include "libavutil/display.h" | ||
| 31 | #include "libavutil/dovi_meta.h" | ||
| 32 | #include "libavutil/imgutils.h" | ||
| 33 | #include "libavutil/internal.h" | ||
| 34 | #include "libavutil/film_grain_params.h" | ||
| 35 | #include "libavutil/hdr_dynamic_metadata.h" | ||
| 36 | #include "libavutil/hdr_dynamic_vivid_metadata.h" | ||
| 37 | #include "libavutil/opt.h" | ||
| 38 | #include "libavutil/pixdesc.h" | ||
| 39 | #include "libavutil/spherical.h" | ||
| 40 | #include "libavutil/stereo3d.h" | ||
| 41 | #include "libavutil/tdrdi.h" | ||
| 42 | #include "libavutil/timestamp.h" | ||
| 43 | #include "libavutil/timecode.h" | ||
| 44 | #include "libavutil/mastering_display_metadata.h" | ||
| 45 | #include "libavutil/video_enc_params.h" | ||
| 46 | #include "libavutil/detection_bbox.h" | ||
| 47 | #include "libavutil/ambient_viewing_environment.h" | ||
| 48 | #include "libavutil/uuid.h" | ||
| 49 | |||
| 50 | #include "avfilter.h" | ||
| 51 | #include "filters.h" | ||
| 52 | #include "video.h" | ||
| 53 | |||
| 54 | typedef struct ShowInfoContext { | ||
| 55 | const AVClass *class; | ||
| 56 | int calculate_checksums; | ||
| 57 | int udu_sei_as_ascii; | ||
| 58 | } ShowInfoContext; | ||
| 59 | |||
| 60 | #define OFFSET(x) offsetof(ShowInfoContext, x) | ||
| 61 | #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM | ||
| 62 | |||
| 63 | static const AVOption showinfo_options[] = { | ||
| 64 | { "checksum", "calculate checksums", OFFSET(calculate_checksums), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, VF }, | ||
| 65 | { "udu_sei_as_ascii", "try to print user data unregistered SEI as ascii character when possible", | ||
| 66 | OFFSET(udu_sei_as_ascii), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VF }, | ||
| 67 | { NULL } | ||
| 68 | }; | ||
| 69 | |||
| 70 | AVFILTER_DEFINE_CLASS(showinfo); | ||
| 71 | |||
| 72 | ✗ | static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, const AVFrameSideData *sd) | |
| 73 | { | ||
| 74 | ✗ | const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data; | |
| 75 | double yaw, pitch, roll; | ||
| 76 | |||
| 77 | ✗ | av_log(ctx, AV_LOG_INFO, "%s ", av_spherical_projection_name(spherical->projection)); | |
| 78 | |||
| 79 | ✗ | if (spherical->yaw || spherical->pitch || spherical->roll) { | |
| 80 | ✗ | yaw = ((double)spherical->yaw) / (1 << 16); | |
| 81 | ✗ | pitch = ((double)spherical->pitch) / (1 << 16); | |
| 82 | ✗ | roll = ((double)spherical->roll) / (1 << 16); | |
| 83 | ✗ | av_log(ctx, AV_LOG_INFO, "(%f/%f/%f) ", yaw, pitch, roll); | |
| 84 | } | ||
| 85 | |||
| 86 | ✗ | if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { | |
| 87 | size_t l, t, r, b; | ||
| 88 | ✗ | av_spherical_tile_bounds(spherical, frame->width, frame->height, | |
| 89 | &l, &t, &r, &b); | ||
| 90 | ✗ | av_log(ctx, AV_LOG_INFO, "[%zu, %zu, %zu, %zu] ", | |
| 91 | l, t, r, b); | ||
| 92 | ✗ | } else if (spherical->projection == AV_SPHERICAL_CUBEMAP) { | |
| 93 | ✗ | av_log(ctx, AV_LOG_INFO, "[pad %"PRIu32"] ", spherical->padding); | |
| 94 | } | ||
| 95 | ✗ | } | |
| 96 | |||
| 97 | ✗ | static void dump_stereo3d(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 98 | { | ||
| 99 | ✗ | const AVStereo3D *stereo = (const AVStereo3D *)sd->data; | |
| 100 | |||
| 101 | ✗ | av_log(ctx, AV_LOG_INFO, "type - %s", av_stereo3d_type_name(stereo->type)); | |
| 102 | |||
| 103 | ✗ | if (stereo->flags & AV_STEREO3D_FLAG_INVERT) | |
| 104 | ✗ | av_log(ctx, AV_LOG_INFO, " (inverted)"); | |
| 105 | |||
| 106 | ✗ | av_log(ctx, AV_LOG_INFO, ", view - %s, primary_eye - %s", av_stereo3d_view_name(stereo->view), | |
| 107 | ✗ | av_stereo3d_primary_eye_name(stereo->primary_eye)); | |
| 108 | ✗ | if (stereo->baseline) | |
| 109 | ✗ | av_log(ctx, AV_LOG_INFO, ", baseline: %"PRIu32"", stereo->baseline); | |
| 110 | ✗ | if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den) | |
| 111 | ✗ | av_log(ctx, AV_LOG_INFO, ", horizontal_disparity_adjustment: %0.4f", | |
| 112 | av_q2d(stereo->horizontal_disparity_adjustment)); | ||
| 113 | ✗ | if (stereo->horizontal_field_of_view.num && stereo->horizontal_field_of_view.den) | |
| 114 | ✗ | av_log(ctx, AV_LOG_INFO, ", horizontal_field_of_view: %0.3f", av_q2d(stereo->horizontal_field_of_view)); | |
| 115 | ✗ | } | |
| 116 | |||
| 117 | ✗ | static void dump_s12m_timecode(AVFilterContext *ctx, AVFilterLink *inlink, const AVFrameSideData *sd) | |
| 118 | { | ||
| 119 | ✗ | FilterLink *l = ff_filter_link(inlink); | |
| 120 | ✗ | const uint32_t *tc = (const uint32_t *)sd->data; | |
| 121 | |||
| 122 | ✗ | if ((sd->size != sizeof(uint32_t) * 4) || (tc[0] > 3)) { | |
| 123 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid data\n"); | |
| 124 | ✗ | return; | |
| 125 | } | ||
| 126 | |||
| 127 | ✗ | for (int j = 1; j <= tc[0]; j++) { | |
| 128 | char tcbuf[AV_TIMECODE_STR_SIZE]; | ||
| 129 | ✗ | av_timecode_make_smpte_tc_string2(tcbuf, l->frame_rate, tc[j], 0, 0); | |
| 130 | ✗ | av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : ""); | |
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | ✗ | static void dump_roi(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 135 | { | ||
| 136 | int nb_rois; | ||
| 137 | const AVRegionOfInterest *roi; | ||
| 138 | uint32_t roi_size; | ||
| 139 | |||
| 140 | ✗ | roi = (const AVRegionOfInterest *)sd->data; | |
| 141 | ✗ | roi_size = roi->self_size; | |
| 142 | ✗ | if (!roi_size || sd->size % roi_size != 0) { | |
| 143 | ✗ | av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n"); | |
| 144 | ✗ | return; | |
| 145 | } | ||
| 146 | ✗ | nb_rois = sd->size / roi_size; | |
| 147 | |||
| 148 | ✗ | for (int i = 0; i < nb_rois; i++) { | |
| 149 | ✗ | roi = (const AVRegionOfInterest *)(sd->data + roi_size * i); | |
| 150 | ✗ | av_log(ctx, AV_LOG_INFO, "index: %d, region: (%d, %d) -> (%d, %d), qp offset: %d/%d.\n", | |
| 151 | ✗ | i, roi->left, roi->top, roi->right, roi->bottom, roi->qoffset.num, roi->qoffset.den); | |
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | ✗ | static void dump_tdrdi(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 156 | { | ||
| 157 | ✗ | const AV3DReferenceDisplaysInfo *tdrdi = (const AV3DReferenceDisplaysInfo *)sd->data; | |
| 158 | |||
| 159 | |||
| 160 | ✗ | av_log(ctx, AV_LOG_INFO, "number of reference displays: %u", tdrdi->num_ref_displays); | |
| 161 | ✗ | } | |
| 162 | |||
| 163 | ✗ | static void dump_detection_bbox(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 164 | { | ||
| 165 | int nb_bboxes; | ||
| 166 | const AVDetectionBBoxHeader *header; | ||
| 167 | const AVDetectionBBox *bbox; | ||
| 168 | |||
| 169 | ✗ | header = (const AVDetectionBBoxHeader *)sd->data; | |
| 170 | ✗ | nb_bboxes = header->nb_bboxes; | |
| 171 | ✗ | av_log(ctx, AV_LOG_INFO, "source: %s\n", header->source); | |
| 172 | |||
| 173 | ✗ | for (int i = 0; i < nb_bboxes; i++) { | |
| 174 | ✗ | bbox = av_get_detection_bbox(header, i); | |
| 175 | ✗ | av_log(ctx, AV_LOG_INFO, "index: %d,\tregion: (%d, %d) -> (%d, %d), label: %s, confidence: %d/%d.\n", | |
| 176 | ✗ | i, bbox->x, bbox->y, bbox->x + bbox->w, bbox->y + bbox->h, | |
| 177 | ✗ | bbox->detect_label, bbox->detect_confidence.num, bbox->detect_confidence.den); | |
| 178 | ✗ | if (bbox->classify_count > 0) { | |
| 179 | ✗ | for (int j = 0; j < bbox->classify_count; j++) { | |
| 180 | ✗ | av_log(ctx, AV_LOG_INFO, "\t\tclassify: label: %s, confidence: %d/%d.\n", | |
| 181 | ✗ | bbox->classify_labels[j], bbox->classify_confidences[j].num, bbox->classify_confidences[j].den); | |
| 182 | } | ||
| 183 | } | ||
| 184 | } | ||
| 185 | ✗ | } | |
| 186 | |||
| 187 | ✗ | static void dump_mastering_display(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 188 | { | ||
| 189 | const AVMasteringDisplayMetadata *mastering_display; | ||
| 190 | |||
| 191 | ✗ | if (sd->size < sizeof(*mastering_display)) { | |
| 192 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid data\n"); | |
| 193 | ✗ | return; | |
| 194 | } | ||
| 195 | |||
| 196 | ✗ | mastering_display = (const AVMasteringDisplayMetadata *)sd->data; | |
| 197 | |||
| 198 | ✗ | av_log(ctx, AV_LOG_INFO, "has_primaries:%d has_luminance:%d " | |
| 199 | "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) " | ||
| 200 | "min_luminance=%f, max_luminance=%f", | ||
| 201 | ✗ | mastering_display->has_primaries, mastering_display->has_luminance, | |
| 202 | av_q2d(mastering_display->display_primaries[0][0]), | ||
| 203 | av_q2d(mastering_display->display_primaries[0][1]), | ||
| 204 | av_q2d(mastering_display->display_primaries[1][0]), | ||
| 205 | av_q2d(mastering_display->display_primaries[1][1]), | ||
| 206 | av_q2d(mastering_display->display_primaries[2][0]), | ||
| 207 | av_q2d(mastering_display->display_primaries[2][1]), | ||
| 208 | av_q2d(mastering_display->white_point[0]), av_q2d(mastering_display->white_point[1]), | ||
| 209 | av_q2d(mastering_display->min_luminance), av_q2d(mastering_display->max_luminance)); | ||
| 210 | } | ||
| 211 | |||
| 212 | ✗ | static void dump_dynamic_hdr_plus(AVFilterContext *ctx, AVFrameSideData *sd) | |
| 213 | { | ||
| 214 | AVDynamicHDRPlus *hdr_plus; | ||
| 215 | |||
| 216 | ✗ | if (sd->size < sizeof(*hdr_plus)) { | |
| 217 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid data\n"); | |
| 218 | ✗ | return; | |
| 219 | } | ||
| 220 | |||
| 221 | ✗ | hdr_plus = (AVDynamicHDRPlus *)sd->data; | |
| 222 | ✗ | av_log(ctx, AV_LOG_INFO, "application version: %d, ", hdr_plus->application_version); | |
| 223 | ✗ | av_log(ctx, AV_LOG_INFO, "num_windows: %d, ", hdr_plus->num_windows); | |
| 224 | ✗ | for (int w = 1; w < hdr_plus->num_windows; w++) { | |
| 225 | ✗ | AVHDRPlusColorTransformParams *params = &hdr_plus->params[w]; | |
| 226 | ✗ | av_log(ctx, AV_LOG_INFO, w > 1 ? ", window %d { " : "window %d { ", w); | |
| 227 | ✗ | av_log(ctx, AV_LOG_INFO, "window_upper_left_corner: (%5.4f,%5.4f),", | |
| 228 | av_q2d(params->window_upper_left_corner_x), | ||
| 229 | av_q2d(params->window_upper_left_corner_y)); | ||
| 230 | ✗ | av_log(ctx, AV_LOG_INFO, "window_lower_right_corner: (%5.4f,%5.4f), ", | |
| 231 | av_q2d(params->window_lower_right_corner_x), | ||
| 232 | av_q2d(params->window_lower_right_corner_y)); | ||
| 233 | ✗ | av_log(ctx, AV_LOG_INFO, "window_upper_left_corner: (%5.4f, %5.4f), ", | |
| 234 | av_q2d(params->window_upper_left_corner_x), | ||
| 235 | av_q2d(params->window_upper_left_corner_y)); | ||
| 236 | ✗ | av_log(ctx, AV_LOG_INFO, "center_of_ellipse_x: (%d,%d), ", | |
| 237 | ✗ | params->center_of_ellipse_x, | |
| 238 | ✗ | params->center_of_ellipse_y); | |
| 239 | ✗ | av_log(ctx, AV_LOG_INFO, "rotation_angle: %d, ", | |
| 240 | ✗ | params->rotation_angle); | |
| 241 | ✗ | av_log(ctx, AV_LOG_INFO, "semimajor_axis_internal_ellipse: %d, ", | |
| 242 | ✗ | params->semimajor_axis_internal_ellipse); | |
| 243 | ✗ | av_log(ctx, AV_LOG_INFO, "semimajor_axis_external_ellipse: %d, ", | |
| 244 | ✗ | params->semimajor_axis_external_ellipse); | |
| 245 | ✗ | av_log(ctx, AV_LOG_INFO, "semiminor_axis_external_ellipse: %d, ", | |
| 246 | ✗ | params->semiminor_axis_external_ellipse); | |
| 247 | ✗ | av_log(ctx, AV_LOG_INFO, "overlap_process_option: %d}", | |
| 248 | ✗ | params->overlap_process_option); | |
| 249 | } | ||
| 250 | ✗ | av_log(ctx, AV_LOG_INFO, "targeted_system_display_maximum_luminance: %9.4f, ", | |
| 251 | av_q2d(hdr_plus->targeted_system_display_maximum_luminance)); | ||
| 252 | ✗ | if (hdr_plus->targeted_system_display_actual_peak_luminance_flag) { | |
| 253 | ✗ | av_log(ctx, AV_LOG_INFO, "targeted_system_display_actual_peak_luminance: {"); | |
| 254 | ✗ | for (int i = 0; i < hdr_plus->num_rows_targeted_system_display_actual_peak_luminance; i++) { | |
| 255 | ✗ | av_log(ctx, AV_LOG_INFO, "("); | |
| 256 | ✗ | for (int j = 0; j < hdr_plus->num_cols_targeted_system_display_actual_peak_luminance; j++) { | |
| 257 | ✗ | av_log(ctx, AV_LOG_INFO, i ? ",%5.4f" : "%5.4f", | |
| 258 | av_q2d(hdr_plus->targeted_system_display_actual_peak_luminance[i][j])); | ||
| 259 | } | ||
| 260 | ✗ | av_log(ctx, AV_LOG_INFO, ")"); | |
| 261 | } | ||
| 262 | ✗ | av_log(ctx, AV_LOG_INFO, "}, "); | |
| 263 | } | ||
| 264 | |||
| 265 | ✗ | for (int w = 0; w < hdr_plus->num_windows; w++) { | |
| 266 | ✗ | AVHDRPlusColorTransformParams *params = &hdr_plus->params[w]; | |
| 267 | ✗ | av_log(ctx, AV_LOG_INFO, "window %d {maxscl: {", w); | |
| 268 | ✗ | for (int i = 0; i < 3; i++) { | |
| 269 | ✗ | av_log(ctx, AV_LOG_INFO, i ? ",%5.4f" : "%5.4f",av_q2d(params->maxscl[i])); | |
| 270 | } | ||
| 271 | ✗ | av_log(ctx, AV_LOG_INFO, "}, average_maxrgb: %5.4f, ", | |
| 272 | av_q2d(params->average_maxrgb)); | ||
| 273 | ✗ | av_log(ctx, AV_LOG_INFO, "distribution_maxrgb: {"); | |
| 274 | ✗ | for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) { | |
| 275 | ✗ | av_log(ctx, AV_LOG_INFO, "(%d,%5.4f)", | |
| 276 | ✗ | params->distribution_maxrgb[i].percentage, | |
| 277 | av_q2d(params->distribution_maxrgb[i].percentile)); | ||
| 278 | } | ||
| 279 | ✗ | av_log(ctx, AV_LOG_INFO, "}, fraction_bright_pixels: %5.4f", | |
| 280 | av_q2d(params->fraction_bright_pixels)); | ||
| 281 | ✗ | if (params->tone_mapping_flag) { | |
| 282 | ✗ | av_log(ctx, AV_LOG_INFO, ", knee_point: (%5.4f,%5.4f), ", av_q2d(params->knee_point_x), av_q2d(params->knee_point_y)); | |
| 283 | ✗ | av_log(ctx, AV_LOG_INFO, "bezier_curve_anchors: {"); | |
| 284 | ✗ | for (int i = 0; i < params->num_bezier_curve_anchors; i++) { | |
| 285 | ✗ | av_log(ctx, AV_LOG_INFO, i ? ",%5.4f" : "%5.4f", | |
| 286 | av_q2d(params->bezier_curve_anchors[i])); | ||
| 287 | } | ||
| 288 | ✗ | av_log(ctx, AV_LOG_INFO, "}"); | |
| 289 | } | ||
| 290 | ✗ | if (params->color_saturation_mapping_flag) { | |
| 291 | ✗ | av_log(ctx, AV_LOG_INFO, ", color_saturation_weight: %5.4f", | |
| 292 | av_q2d(params->color_saturation_weight)); | ||
| 293 | } | ||
| 294 | ✗ | av_log(ctx, AV_LOG_INFO, "}"); | |
| 295 | } | ||
| 296 | |||
| 297 | ✗ | if (hdr_plus->mastering_display_actual_peak_luminance_flag) { | |
| 298 | ✗ | av_log(ctx, AV_LOG_INFO, ", mastering_display_actual_peak_luminance: {"); | |
| 299 | ✗ | for (int i = 0; i < hdr_plus->num_rows_mastering_display_actual_peak_luminance; i++) { | |
| 300 | ✗ | av_log(ctx, AV_LOG_INFO, "("); | |
| 301 | ✗ | for (int j = 0; j < hdr_plus->num_cols_mastering_display_actual_peak_luminance; j++) { | |
| 302 | ✗ | av_log(ctx, AV_LOG_INFO, i ? ",%5.4f" : "%5.4f", | |
| 303 | av_q2d(hdr_plus->mastering_display_actual_peak_luminance[i][j])); | ||
| 304 | } | ||
| 305 | ✗ | av_log(ctx, AV_LOG_INFO, ")"); | |
| 306 | } | ||
| 307 | ✗ | av_log(ctx, AV_LOG_INFO, "}"); | |
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | ✗ | static void dump_dynamic_hdr_vivid(AVFilterContext *ctx, AVFrameSideData *sd) | |
| 312 | { | ||
| 313 | AVDynamicHDRVivid *hdr_vivid; | ||
| 314 | |||
| 315 | ✗ | if (sd->size < sizeof(*hdr_vivid)) { | |
| 316 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid hdr vivid data\n"); | |
| 317 | ✗ | return; | |
| 318 | } | ||
| 319 | |||
| 320 | ✗ | hdr_vivid = (AVDynamicHDRVivid *)sd->data; | |
| 321 | ✗ | av_log(ctx, AV_LOG_INFO, "system_start_code: %d, ", hdr_vivid->system_start_code); | |
| 322 | ✗ | av_log(ctx, AV_LOG_INFO, "num_windows: %d, ", hdr_vivid->num_windows); | |
| 323 | ✗ | for (int w = 0; w < hdr_vivid->num_windows; w++) { | |
| 324 | ✗ | const AVHDRVividColorTransformParams *params = &hdr_vivid->params[w]; | |
| 325 | |||
| 326 | ✗ | av_log(ctx, AV_LOG_INFO, "minimum_maxrgb[%d]: %.4f, ", w, av_q2d(params->minimum_maxrgb)); | |
| 327 | ✗ | av_log(ctx, AV_LOG_INFO, "average_maxrgb[%d]: %.4f, ", w, av_q2d(params->average_maxrgb)); | |
| 328 | ✗ | av_log(ctx, AV_LOG_INFO, "variance_maxrgb[%d]:%.4f, ", w, av_q2d(params->variance_maxrgb)); | |
| 329 | ✗ | av_log(ctx, AV_LOG_INFO, "maximum_maxrgb[%d]: %.4f, ", w, av_q2d(params->maximum_maxrgb)); | |
| 330 | } | ||
| 331 | |||
| 332 | ✗ | for (int w = 0; w < hdr_vivid->num_windows; w++) { | |
| 333 | ✗ | const AVHDRVividColorTransformParams *params = &hdr_vivid->params[w]; | |
| 334 | |||
| 335 | ✗ | av_log(ctx, AV_LOG_INFO, "tone_mapping_mode_flag[%d]: %d, ", w, params->tone_mapping_mode_flag); | |
| 336 | ✗ | av_log(ctx, AV_LOG_INFO, "tone_mapping_param_num[%d]: %d, ", w, params->tone_mapping_param_num); | |
| 337 | ✗ | if (params->tone_mapping_mode_flag) { | |
| 338 | ✗ | for (int i = 0; i < params->tone_mapping_param_num; i++) { | |
| 339 | ✗ | const AVHDRVividColorToneMappingParams *tm_params = ¶ms->tm_params[i]; | |
| 340 | |||
| 341 | ✗ | av_log(ctx, AV_LOG_INFO, "targeted_system_display_maximum_luminance[%d][%d]: %.4f, ", | |
| 342 | w, i, av_q2d(tm_params->targeted_system_display_maximum_luminance)); | ||
| 343 | ✗ | av_log(ctx, AV_LOG_INFO, "base_enable_flag[%d][%d]: %d, ", | |
| 344 | ✗ | w, i, tm_params->base_enable_flag); | |
| 345 | ✗ | if (tm_params->base_enable_flag) { | |
| 346 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_m_p[%d][%d]: %.4f, ", w, i, av_q2d(tm_params->base_param_m_p)); | |
| 347 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_m_m[%d][%d]: %.4f, ", w, i, av_q2d(tm_params->base_param_m_m)); | |
| 348 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_m_a[%d][%d]: %.4f, ", w, i, av_q2d(tm_params->base_param_m_a)); | |
| 349 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_m_b[%d][%d]: %.4f, ", w, i, av_q2d(tm_params->base_param_m_b)); | |
| 350 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_m_n[%d][%d]: %.4f, ", w, i, av_q2d(tm_params->base_param_m_n)); | |
| 351 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_k1[%d][%d]: %d, ", w, i, tm_params->base_param_k1); | |
| 352 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_k2[%d][%d]: %d, ", w, i, tm_params->base_param_k2); | |
| 353 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_k3[%d][%d]: %d, ", w, i, tm_params->base_param_k3); | |
| 354 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_Delta_enable_mode[%d][%d]: %d, ", w, i, | |
| 355 | ✗ | tm_params->base_param_Delta_enable_mode); | |
| 356 | ✗ | av_log(ctx, AV_LOG_INFO, "base_param_Delta[%d][%d]: %.4f, ", w, i, av_q2d(tm_params->base_param_Delta)); | |
| 357 | } | ||
| 358 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_enable_flag[%d][%d]: %d, ", | |
| 359 | ✗ | w, i, tm_params->three_Spline_enable_flag); | |
| 360 | ✗ | if (tm_params->three_Spline_enable_flag) { | |
| 361 | ✗ | for (int j = 0; j < tm_params->three_Spline_num; j++) { | |
| 362 | ✗ | const AVHDRVivid3SplineParams *three_spline = &tm_params->three_spline[j]; | |
| 363 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_TH_mode[%d][%d]: %d, ", w, i, three_spline->th_mode); | |
| 364 | ✗ | if (three_spline->th_mode == 0 || three_spline->th_mode == 2) | |
| 365 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_TH_enable_MB[%d][%d][%d]: %.4f, ", | |
| 366 | w, i, j, av_q2d(three_spline->th_enable_mb)); | ||
| 367 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_TH_enable[%d][%d][%d]: %.4f, ", | |
| 368 | w, i, j, av_q2d(three_spline->th_enable)); | ||
| 369 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_TH_Delta1[%d][%d][%d]: %.4f, ", | |
| 370 | w, i, j, av_q2d(three_spline->th_delta1)); | ||
| 371 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_TH_Delta2[%d][%d][%d]: %.4f, ", | |
| 372 | w, i, j, av_q2d(three_spline->th_delta2)); | ||
| 373 | ✗ | av_log(ctx, AV_LOG_INFO, "3Spline_enable_Strength[%d][%d][%d]: %.4f, ", | |
| 374 | w, i, j, av_q2d(three_spline->enable_strength)); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | ✗ | av_log(ctx, AV_LOG_INFO, "color_saturation_mapping_flag[%d]: %d", | |
| 381 | ✗ | w, params->color_saturation_mapping_flag); | |
| 382 | ✗ | if (params->color_saturation_mapping_flag) { | |
| 383 | ✗ | av_log(ctx, AV_LOG_INFO, ", color_saturation_num[%d]: %d", | |
| 384 | ✗ | w, params->color_saturation_num); | |
| 385 | ✗ | for (int i = 0; i < params->color_saturation_num; i++) { | |
| 386 | ✗ | av_log(ctx, AV_LOG_INFO, ", color_saturation_gain[%d][%d]: %.4f", | |
| 387 | w, i, av_q2d(params->color_saturation_gain[i])); | ||
| 388 | } | ||
| 389 | } | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | |||
| 394 | ✗ | static void dump_content_light_metadata(AVFilterContext *ctx, AVFrameSideData *sd) | |
| 395 | { | ||
| 396 | ✗ | const AVContentLightMetadata *metadata = (const AVContentLightMetadata *)sd->data; | |
| 397 | |||
| 398 | ✗ | av_log(ctx, AV_LOG_INFO, | |
| 399 | "MaxCLL=%d, MaxFALL=%d", | ||
| 400 | ✗ | metadata->MaxCLL, metadata->MaxFALL); | |
| 401 | ✗ | } | |
| 402 | |||
| 403 | ✗ | static void dump_video_enc_params(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 404 | { | ||
| 405 | ✗ | const AVVideoEncParams *par = (const AVVideoEncParams *)sd->data; | |
| 406 | int plane, acdc; | ||
| 407 | |||
| 408 | ✗ | av_log(ctx, AV_LOG_INFO, "type %d; ", par->type); | |
| 409 | ✗ | if (par->qp) | |
| 410 | ✗ | av_log(ctx, AV_LOG_INFO, "qp=%d; ", par->qp); | |
| 411 | ✗ | for (plane = 0; plane < FF_ARRAY_ELEMS(par->delta_qp); plane++) | |
| 412 | ✗ | for (acdc = 0; acdc < FF_ARRAY_ELEMS(par->delta_qp[plane]); acdc++) { | |
| 413 | ✗ | int delta_qp = par->delta_qp[plane][acdc]; | |
| 414 | ✗ | if (delta_qp) | |
| 415 | ✗ | av_log(ctx, AV_LOG_INFO, "delta_qp[%d][%d]=%d; ", | |
| 416 | plane, acdc, delta_qp); | ||
| 417 | } | ||
| 418 | ✗ | if (par->nb_blocks) | |
| 419 | ✗ | av_log(ctx, AV_LOG_INFO, "%u blocks; ", par->nb_blocks); | |
| 420 | ✗ | } | |
| 421 | |||
| 422 | ✗ | static void dump_sei_unregistered_metadata(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 423 | { | ||
| 424 | ✗ | const uint8_t *user_data = sd->data; | |
| 425 | ✗ | ShowInfoContext *s = ctx->priv; | |
| 426 | |||
| 427 | ✗ | if (sd->size < AV_UUID_LEN) { | |
| 428 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid data (%zu < UUID(%d-bytes))\n", | |
| 429 | ✗ | sd->size, AV_UUID_LEN); | |
| 430 | ✗ | return; | |
| 431 | } | ||
| 432 | |||
| 433 | ✗ | av_log(ctx, AV_LOG_INFO, "UUID=" AV_PRI_UUID "\n", AV_UUID_ARG(user_data)); | |
| 434 | |||
| 435 | ✗ | av_log(ctx, AV_LOG_INFO, "User Data="); | |
| 436 | ✗ | for (size_t i = 16; i < sd->size; i++) { | |
| 437 | ✗ | const char *format = "%02x"; | |
| 438 | |||
| 439 | ✗ | if (s->udu_sei_as_ascii) | |
| 440 | ✗ | format = isprint(user_data[i]) ? "%c" : "\\x%02x"; | |
| 441 | ✗ | av_log(ctx, AV_LOG_INFO, format, user_data[i]); | |
| 442 | } | ||
| 443 | ✗ | av_log(ctx, AV_LOG_INFO, "\n"); | |
| 444 | } | ||
| 445 | |||
| 446 | ✗ | static void dump_sei_film_grain_params_metadata(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 447 | { | ||
| 448 | ✗ | const AVFilmGrainParams *fgp = (const AVFilmGrainParams *)sd->data; | |
| 449 | ✗ | const char *const film_grain_type_names[] = { | |
| 450 | [AV_FILM_GRAIN_PARAMS_NONE] = "none", | ||
| 451 | [AV_FILM_GRAIN_PARAMS_AV1] = "av1", | ||
| 452 | [AV_FILM_GRAIN_PARAMS_H274] = "h274", | ||
| 453 | }; | ||
| 454 | |||
| 455 | ✗ | const char *color_range_str = av_color_range_name(fgp->color_range); | |
| 456 | ✗ | const char *color_primaries_str = av_color_primaries_name(fgp->color_primaries); | |
| 457 | ✗ | const char *color_trc_str = av_color_transfer_name(fgp->color_trc); | |
| 458 | ✗ | const char *colorspace_str = av_color_space_name(fgp->color_space); | |
| 459 | |||
| 460 | ✗ | if (fgp->type >= FF_ARRAY_ELEMS(film_grain_type_names)) { | |
| 461 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid data\n"); | |
| 462 | ✗ | return; | |
| 463 | } | ||
| 464 | |||
| 465 | ✗ | av_log(ctx, AV_LOG_INFO, "type %s; ", film_grain_type_names[fgp->type]); | |
| 466 | ✗ | av_log(ctx, AV_LOG_INFO, "seed=%"PRIu64"; ", fgp->seed); | |
| 467 | ✗ | av_log(ctx, AV_LOG_INFO, "width=%d; ", fgp->width); | |
| 468 | ✗ | av_log(ctx, AV_LOG_INFO, "height=%d; ", fgp->height); | |
| 469 | ✗ | av_log(ctx, AV_LOG_INFO, "subsampling_x=%d; ", fgp->subsampling_x); | |
| 470 | ✗ | av_log(ctx, AV_LOG_INFO, "subsampling_y=%d; ", fgp->subsampling_y); | |
| 471 | ✗ | av_log(ctx, AV_LOG_INFO, "color_range=%s; ", color_range_str ? color_range_str : "unknown"); | |
| 472 | ✗ | av_log(ctx, AV_LOG_INFO, "color_primaries=%s; ", color_primaries_str ? color_primaries_str : "unknown"); | |
| 473 | ✗ | av_log(ctx, AV_LOG_INFO, "color_trc=%s; ", color_trc_str ? color_trc_str : "unknown"); | |
| 474 | ✗ | av_log(ctx, AV_LOG_INFO, "color_space=%s; ", colorspace_str ? colorspace_str : "unknown"); | |
| 475 | ✗ | av_log(ctx, AV_LOG_INFO, "bit_depth_luma=%d; ", fgp->bit_depth_luma); | |
| 476 | ✗ | av_log(ctx, AV_LOG_INFO, "bit_depth_chroma=%d; ", fgp->bit_depth_chroma); | |
| 477 | |||
| 478 | ✗ | switch (fgp->type) { | |
| 479 | ✗ | case AV_FILM_GRAIN_PARAMS_NONE: | |
| 480 | ✗ | break; | |
| 481 | ✗ | case AV_FILM_GRAIN_PARAMS_AV1: { | |
| 482 | ✗ | const AVFilmGrainAOMParams *aom = &fgp->codec.aom; | |
| 483 | ✗ | const int num_ar_coeffs_y = 2 * aom->ar_coeff_lag * (aom->ar_coeff_lag + 1); | |
| 484 | ✗ | const int num_ar_coeffs_uv = num_ar_coeffs_y + !!aom->num_y_points; | |
| 485 | ✗ | av_log(ctx, AV_LOG_INFO, "y_points={ "); | |
| 486 | ✗ | for (int i = 0; i < aom->num_y_points; i++) | |
| 487 | ✗ | av_log(ctx, AV_LOG_INFO, "(%d,%d) ", aom->y_points[i][0], aom->y_points[i][1]); | |
| 488 | ✗ | av_log(ctx, AV_LOG_INFO, "}; chroma_scaling_from_luma=%d; ", aom->chroma_scaling_from_luma); | |
| 489 | ✗ | for (int uv = 0; uv < 2; uv++) { | |
| 490 | ✗ | av_log(ctx, AV_LOG_INFO, "uv_points[%d]={ ", uv); | |
| 491 | ✗ | for (int i = 0; i < aom->num_uv_points[uv]; i++) | |
| 492 | ✗ | av_log(ctx, AV_LOG_INFO, "(%d,%d) ", aom->uv_points[uv][i][0], aom->uv_points[uv][i][1]); | |
| 493 | ✗ | av_log(ctx, AV_LOG_INFO, "}; "); | |
| 494 | } | ||
| 495 | ✗ | av_log(ctx, AV_LOG_INFO, "scaling_shift=%d; ", aom->scaling_shift); | |
| 496 | ✗ | av_log(ctx, AV_LOG_INFO, "ar_coeff_lag=%d; ", aom->ar_coeff_lag); | |
| 497 | ✗ | if (num_ar_coeffs_y) { | |
| 498 | ✗ | av_log(ctx, AV_LOG_INFO, "ar_coeffs_y={ "); | |
| 499 | ✗ | for (int i = 0; i < num_ar_coeffs_y; i++) | |
| 500 | ✗ | av_log(ctx, AV_LOG_INFO, "%d ", aom->ar_coeffs_y[i]); | |
| 501 | ✗ | av_log(ctx, AV_LOG_INFO, "}; "); | |
| 502 | } | ||
| 503 | ✗ | for (int uv = 0; num_ar_coeffs_uv && uv < 2; uv++) { | |
| 504 | ✗ | av_log(ctx, AV_LOG_INFO, "ar_coeffs_uv[%d]={ ", uv); | |
| 505 | ✗ | for (int i = 0; i < num_ar_coeffs_uv; i++) | |
| 506 | ✗ | av_log(ctx, AV_LOG_INFO, "%d ", aom->ar_coeffs_uv[uv][i]); | |
| 507 | ✗ | av_log(ctx, AV_LOG_INFO, "}; "); | |
| 508 | } | ||
| 509 | ✗ | av_log(ctx, AV_LOG_INFO, "ar_coeff_shift=%d; ", aom->ar_coeff_shift); | |
| 510 | ✗ | av_log(ctx, AV_LOG_INFO, "grain_scale_shift=%d; ", aom->grain_scale_shift); | |
| 511 | ✗ | for (int uv = 0; uv < 2; uv++) { | |
| 512 | ✗ | av_log(ctx, AV_LOG_INFO, "uv_mult[%d] = %d; ", uv, aom->uv_mult[uv]); | |
| 513 | ✗ | av_log(ctx, AV_LOG_INFO, "uv_mult_luma[%d] = %d; ", uv, aom->uv_mult_luma[uv]); | |
| 514 | ✗ | av_log(ctx, AV_LOG_INFO, "uv_offset[%d] = %d; ", uv, aom->uv_offset[uv]); | |
| 515 | } | ||
| 516 | ✗ | av_log(ctx, AV_LOG_INFO, "overlap_flag=%d; ", aom->overlap_flag); | |
| 517 | ✗ | av_log(ctx, AV_LOG_INFO, "limit_output_range=%d; ", aom->limit_output_range); | |
| 518 | ✗ | break; | |
| 519 | } | ||
| 520 | ✗ | case AV_FILM_GRAIN_PARAMS_H274: { | |
| 521 | ✗ | const AVFilmGrainH274Params *h274 = &fgp->codec.h274; | |
| 522 | ✗ | av_log(ctx, AV_LOG_INFO, "model_id=%d; ", h274->model_id); | |
| 523 | ✗ | av_log(ctx, AV_LOG_INFO, "blending_mode_id=%d; ", h274->blending_mode_id); | |
| 524 | ✗ | av_log(ctx, AV_LOG_INFO, "log2_scale_factor=%d; ", h274->log2_scale_factor); | |
| 525 | |||
| 526 | ✗ | for (int c = 0; c < 3; c++) | |
| 527 | ✗ | if (h274->component_model_present[c] && (h274->num_model_values[c] > 6 || | |
| 528 | ✗ | h274->num_intensity_intervals[c] < 1 || | |
| 529 | ✗ | h274->num_intensity_intervals[c] > 256)) { | |
| 530 | ✗ | av_log(ctx, AV_LOG_ERROR, "invalid data\n"); | |
| 531 | ✗ | return; | |
| 532 | } | ||
| 533 | |||
| 534 | ✗ | for (int c = 0; c < 3; c++) { | |
| 535 | ✗ | if (!h274->component_model_present[c]) | |
| 536 | ✗ | continue; | |
| 537 | |||
| 538 | ✗ | av_log(ctx, AV_LOG_INFO, "num_intensity_intervals[%d]=%u; ", c, h274->num_intensity_intervals[c]); | |
| 539 | ✗ | av_log(ctx, AV_LOG_INFO, "num_model_values[%d]=%u; ", c, h274->num_model_values[c]); | |
| 540 | ✗ | for (int i = 0; i < h274->num_intensity_intervals[c]; i++) { | |
| 541 | ✗ | av_log(ctx, AV_LOG_INFO, "intensity_interval_lower_bound[%d][%d]=%u; ", | |
| 542 | ✗ | c, i, h274->intensity_interval_lower_bound[c][i]); | |
| 543 | ✗ | av_log(ctx, AV_LOG_INFO, "intensity_interval_upper_bound[%d][%d]=%u; ", | |
| 544 | ✗ | c, i, h274->intensity_interval_upper_bound[c][i]); | |
| 545 | ✗ | for (int j = 0; j < h274->num_model_values[c]; j++) | |
| 546 | ✗ | av_log(ctx, AV_LOG_INFO, "comp_model_value[%d][%d][%d]=%d; ", | |
| 547 | ✗ | c, i, j, h274->comp_model_value[c][i][j]); | |
| 548 | } | ||
| 549 | } | ||
| 550 | ✗ | break; | |
| 551 | } | ||
| 552 | } | ||
| 553 | } | ||
| 554 | |||
| 555 | ✗ | static void dump_dovi_metadata(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 556 | { | ||
| 557 | ✗ | const AVDOVIMetadata *dovi = (AVDOVIMetadata *) sd->data; | |
| 558 | ✗ | const AVDOVIRpuDataHeader *hdr = av_dovi_get_header(dovi); | |
| 559 | ✗ | const AVDOVIDataMapping *mapping = av_dovi_get_mapping(dovi); | |
| 560 | ✗ | const AVDOVIColorMetadata *color = av_dovi_get_color(dovi); | |
| 561 | |||
| 562 | ✗ | av_log(ctx, AV_LOG_INFO, " rpu_type=%"PRIu8"; ", hdr->rpu_type); | |
| 563 | ✗ | av_log(ctx, AV_LOG_INFO, "rpu_format=%"PRIu16"; ", hdr->rpu_format); | |
| 564 | ✗ | av_log(ctx, AV_LOG_INFO, "vdr_rpu_profile=%"PRIu8"; ", hdr->vdr_rpu_profile); | |
| 565 | ✗ | av_log(ctx, AV_LOG_INFO, "vdr_rpu_level=%"PRIu8"; ", hdr->vdr_rpu_level); | |
| 566 | ✗ | av_log(ctx, AV_LOG_INFO, "chroma_resampling_explicit_filter_flag=%"PRIu8"; ", hdr->chroma_resampling_explicit_filter_flag); | |
| 567 | ✗ | av_log(ctx, AV_LOG_INFO, "coef_data_type=%"PRIu8"; ", hdr->coef_data_type); | |
| 568 | ✗ | av_log(ctx, AV_LOG_INFO, "coef_log2_denom=%"PRIu8"; ", hdr->coef_log2_denom); | |
| 569 | ✗ | av_log(ctx, AV_LOG_INFO, "vdr_rpu_normalized_idc=%"PRIu8"; ", hdr->vdr_rpu_normalized_idc); | |
| 570 | ✗ | av_log(ctx, AV_LOG_INFO, "bl_video_full_range_flag=%"PRIu8"; ", hdr->bl_video_full_range_flag); | |
| 571 | ✗ | av_log(ctx, AV_LOG_INFO, "bl_bit_depth=%"PRIu8"; ", hdr->bl_bit_depth); | |
| 572 | ✗ | av_log(ctx, AV_LOG_INFO, "el_bit_depth=%"PRIu8"; ", hdr->el_bit_depth); | |
| 573 | ✗ | av_log(ctx, AV_LOG_INFO, "vdr_bit_depth=%"PRIu8"; ", hdr->vdr_bit_depth); | |
| 574 | ✗ | av_log(ctx, AV_LOG_INFO, "spatial_resampling_filter_flag=%"PRIu8"; ", hdr->spatial_resampling_filter_flag); | |
| 575 | ✗ | av_log(ctx, AV_LOG_INFO, "el_spatial_resampling_filter_flag=%"PRIu8"; ", hdr->el_spatial_resampling_filter_flag); | |
| 576 | ✗ | av_log(ctx, AV_LOG_INFO, "disable_residual_flag=%"PRIu8"\n", hdr->disable_residual_flag); | |
| 577 | |||
| 578 | ✗ | av_log(ctx, AV_LOG_INFO, " data mapping: "); | |
| 579 | ✗ | av_log(ctx, AV_LOG_INFO, "vdr_rpu_id=%"PRIu8"; ", mapping->vdr_rpu_id); | |
| 580 | ✗ | av_log(ctx, AV_LOG_INFO, "mapping_color_space=%"PRIu8"; ", mapping->mapping_color_space); | |
| 581 | ✗ | av_log(ctx, AV_LOG_INFO, "mapping_chroma_format_idc=%"PRIu8"; ", mapping->mapping_chroma_format_idc); | |
| 582 | ✗ | av_log(ctx, AV_LOG_INFO, "nlq_method_idc=%d; ", (int) mapping->nlq_method_idc); | |
| 583 | ✗ | av_log(ctx, AV_LOG_INFO, "num_x_partitions=%"PRIu32"; ", mapping->num_x_partitions); | |
| 584 | ✗ | av_log(ctx, AV_LOG_INFO, "num_y_partitions=%"PRIu32"\n", mapping->num_y_partitions); | |
| 585 | |||
| 586 | ✗ | for (int c = 0; c < 3; c++) { | |
| 587 | ✗ | const AVDOVIReshapingCurve *curve = &mapping->curves[c]; | |
| 588 | ✗ | const AVDOVINLQParams *nlq = &mapping->nlq[c]; | |
| 589 | ✗ | av_log(ctx, AV_LOG_INFO, " channel %d: ", c); | |
| 590 | ✗ | av_log(ctx, AV_LOG_INFO, "pivots={ "); | |
| 591 | ✗ | for (int i = 0; i < curve->num_pivots; i++) | |
| 592 | ✗ | av_log(ctx, AV_LOG_INFO, "%"PRIu16" ", curve->pivots[i]); | |
| 593 | ✗ | av_log(ctx, AV_LOG_INFO, "}; mapping_idc={ "); | |
| 594 | ✗ | for (int i = 0; i < curve->num_pivots - 1; i++) | |
| 595 | ✗ | av_log(ctx, AV_LOG_INFO, "%d ", (int) curve->mapping_idc[i]); | |
| 596 | ✗ | av_log(ctx, AV_LOG_INFO, "}; poly_order={ "); | |
| 597 | ✗ | for (int i = 0; i < curve->num_pivots - 1; i++) | |
| 598 | ✗ | av_log(ctx, AV_LOG_INFO, "%"PRIu8" ", curve->poly_order[i]); | |
| 599 | ✗ | av_log(ctx, AV_LOG_INFO, "}; poly_coef={ "); | |
| 600 | ✗ | for (int i = 0; i < curve->num_pivots - 1; i++) { | |
| 601 | ✗ | av_log(ctx, AV_LOG_INFO, "{%"PRIi64", %"PRIi64", %"PRIi64"} ", | |
| 602 | ✗ | curve->poly_coef[i][0], | |
| 603 | ✗ | curve->poly_coef[i][1], | |
| 604 | ✗ | curve->poly_coef[i][2]); | |
| 605 | } | ||
| 606 | |||
| 607 | ✗ | av_log(ctx, AV_LOG_INFO, "}; mmr_order={ "); | |
| 608 | ✗ | for (int i = 0; i < curve->num_pivots - 1; i++) | |
| 609 | ✗ | av_log(ctx, AV_LOG_INFO, "%"PRIu8" ", curve->mmr_order[i]); | |
| 610 | ✗ | av_log(ctx, AV_LOG_INFO, "}; mmr_constant={ "); | |
| 611 | ✗ | for (int i = 0; i < curve->num_pivots - 1; i++) | |
| 612 | ✗ | av_log(ctx, AV_LOG_INFO, "%"PRIi64" ", curve->mmr_constant[i]); | |
| 613 | ✗ | av_log(ctx, AV_LOG_INFO, "}; mmr_coef={ "); | |
| 614 | ✗ | for (int i = 0; i < curve->num_pivots - 1; i++) { | |
| 615 | ✗ | av_log(ctx, AV_LOG_INFO, "{"); | |
| 616 | ✗ | for (int j = 0; j < curve->mmr_order[i]; j++) { | |
| 617 | ✗ | for (int k = 0; k < 7; k++) | |
| 618 | ✗ | av_log(ctx, AV_LOG_INFO, "%"PRIi64" ", curve->mmr_coef[i][j][k]); | |
| 619 | } | ||
| 620 | ✗ | av_log(ctx, AV_LOG_INFO, "} "); | |
| 621 | } | ||
| 622 | |||
| 623 | ✗ | av_log(ctx, AV_LOG_INFO, "}; nlq_offset=%"PRIu16"; ", nlq->nlq_offset); | |
| 624 | ✗ | av_log(ctx, AV_LOG_INFO, "vdr_in_max=%"PRIu64"; ", nlq->vdr_in_max); | |
| 625 | ✗ | switch (mapping->nlq_method_idc) { | |
| 626 | ✗ | case AV_DOVI_NLQ_LINEAR_DZ: | |
| 627 | ✗ | av_log(ctx, AV_LOG_INFO, "linear_deadzone_slope=%"PRIu64"; ", nlq->linear_deadzone_slope); | |
| 628 | ✗ | av_log(ctx, AV_LOG_INFO, "linear_deadzone_threshold=%"PRIu64"\n", nlq->linear_deadzone_threshold); | |
| 629 | ✗ | break; | |
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | ✗ | av_log(ctx, AV_LOG_INFO, " color metadata: "); | |
| 634 | ✗ | av_log(ctx, AV_LOG_INFO, "dm_metadata_id=%"PRIu8"; ", color->dm_metadata_id); | |
| 635 | ✗ | av_log(ctx, AV_LOG_INFO, "scene_refresh_flag=%"PRIu8"; ", color->scene_refresh_flag); | |
| 636 | ✗ | av_log(ctx, AV_LOG_INFO, "ycc_to_rgb_matrix={ "); | |
| 637 | ✗ | for (int i = 0; i < 9; i++) | |
| 638 | ✗ | av_log(ctx, AV_LOG_INFO, "%f ", av_q2d(color->ycc_to_rgb_matrix[i])); | |
| 639 | ✗ | av_log(ctx, AV_LOG_INFO, "}; ycc_to_rgb_offset={ "); | |
| 640 | ✗ | for (int i = 0; i < 3; i++) | |
| 641 | ✗ | av_log(ctx, AV_LOG_INFO, "%f ", av_q2d(color->ycc_to_rgb_offset[i])); | |
| 642 | ✗ | av_log(ctx, AV_LOG_INFO, "}; rgb_to_lms_matrix={ "); | |
| 643 | ✗ | for (int i = 0; i < 9; i++) | |
| 644 | ✗ | av_log(ctx, AV_LOG_INFO, "%f ", av_q2d(color->rgb_to_lms_matrix[i])); | |
| 645 | ✗ | av_log(ctx, AV_LOG_INFO, "}; signal_eotf=%"PRIu16"; ", color->signal_eotf); | |
| 646 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_eotf_param0=%"PRIu16"; ", color->signal_eotf_param0); | |
| 647 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_eotf_param1=%"PRIu16"; ", color->signal_eotf_param1); | |
| 648 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_eotf_param2=%"PRIu32"; ", color->signal_eotf_param2); | |
| 649 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_bit_depth=%"PRIu8"; ", color->signal_bit_depth); | |
| 650 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_color_space=%"PRIu8"; ", color->signal_color_space); | |
| 651 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_chroma_format=%"PRIu8"; ", color->signal_chroma_format); | |
| 652 | ✗ | av_log(ctx, AV_LOG_INFO, "signal_full_range_flag=%"PRIu8"; ", color->signal_full_range_flag); | |
| 653 | ✗ | av_log(ctx, AV_LOG_INFO, "source_min_pq=%"PRIu16"; ", color->source_min_pq); | |
| 654 | ✗ | av_log(ctx, AV_LOG_INFO, "source_max_pq=%"PRIu16"; ", color->source_max_pq); | |
| 655 | ✗ | av_log(ctx, AV_LOG_INFO, "source_diagonal=%"PRIu16"; ", color->source_diagonal); | |
| 656 | ✗ | } | |
| 657 | |||
| 658 | ✗ | static void dump_ambient_viewing_environment(AVFilterContext *ctx, const AVFrameSideData *sd) | |
| 659 | { | ||
| 660 | ✗ | const AVAmbientViewingEnvironment *ambient_viewing_environment = | |
| 661 | (const AVAmbientViewingEnvironment *)sd->data; | ||
| 662 | |||
| 663 | ✗ | av_log(ctx, AV_LOG_INFO, "ambient_illuminance=%f, ambient_light_x=%f, ambient_light_y=%f", | |
| 664 | av_q2d(ambient_viewing_environment->ambient_illuminance), | ||
| 665 | av_q2d(ambient_viewing_environment->ambient_light_x), | ||
| 666 | av_q2d(ambient_viewing_environment->ambient_light_y)); | ||
| 667 | ✗ | } | |
| 668 | |||
| 669 | ✗ | static void dump_color_property(AVFilterContext *ctx, AVFrame *frame) | |
| 670 | { | ||
| 671 | ✗ | const char *color_range_str = av_color_range_name(frame->color_range); | |
| 672 | ✗ | const char *colorspace_str = av_color_space_name(frame->colorspace); | |
| 673 | ✗ | const char *color_primaries_str = av_color_primaries_name(frame->color_primaries); | |
| 674 | ✗ | const char *color_trc_str = av_color_transfer_name(frame->color_trc); | |
| 675 | |||
| 676 | ✗ | if (!color_range_str || frame->color_range == AVCOL_RANGE_UNSPECIFIED) { | |
| 677 | ✗ | av_log(ctx, AV_LOG_INFO, "color_range:unknown"); | |
| 678 | } else { | ||
| 679 | ✗ | av_log(ctx, AV_LOG_INFO, "color_range:%s", color_range_str); | |
| 680 | } | ||
| 681 | |||
| 682 | ✗ | if (!colorspace_str || frame->colorspace == AVCOL_SPC_UNSPECIFIED) { | |
| 683 | ✗ | av_log(ctx, AV_LOG_INFO, " color_space:unknown"); | |
| 684 | } else { | ||
| 685 | ✗ | av_log(ctx, AV_LOG_INFO, " color_space:%s", colorspace_str); | |
| 686 | } | ||
| 687 | |||
| 688 | ✗ | if (!color_primaries_str || frame->color_primaries == AVCOL_PRI_UNSPECIFIED) { | |
| 689 | ✗ | av_log(ctx, AV_LOG_INFO, " color_primaries:unknown"); | |
| 690 | } else { | ||
| 691 | ✗ | av_log(ctx, AV_LOG_INFO, " color_primaries:%s", color_primaries_str); | |
| 692 | } | ||
| 693 | |||
| 694 | ✗ | if (!color_trc_str || frame->color_trc == AVCOL_TRC_UNSPECIFIED) { | |
| 695 | ✗ | av_log(ctx, AV_LOG_INFO, " color_trc:unknown"); | |
| 696 | } else { | ||
| 697 | ✗ | av_log(ctx, AV_LOG_INFO, " color_trc:%s", color_trc_str); | |
| 698 | } | ||
| 699 | ✗ | av_log(ctx, AV_LOG_INFO, "\n"); | |
| 700 | ✗ | } | |
| 701 | |||
| 702 | ✗ | static void update_sample_stats_8(const uint8_t *src, int len, int64_t *sum, int64_t *sum2) | |
| 703 | { | ||
| 704 | int i; | ||
| 705 | |||
| 706 | ✗ | for (i = 0; i < len; i++) { | |
| 707 | ✗ | *sum += src[i]; | |
| 708 | ✗ | *sum2 += src[i] * src[i]; | |
| 709 | } | ||
| 710 | ✗ | } | |
| 711 | |||
| 712 | ✗ | static void update_sample_stats_16(int be, const uint8_t *src, int len, int64_t *sum, int64_t *sum2) | |
| 713 | { | ||
| 714 | ✗ | const uint16_t *src1 = (const uint16_t *)src; | |
| 715 | int i; | ||
| 716 | |||
| 717 | ✗ | for (i = 0; i < len / 2; i++) { | |
| 718 | ✗ | if ((HAVE_BIGENDIAN && !be) || (!HAVE_BIGENDIAN && be)) { | |
| 719 | ✗ | *sum += av_bswap16(src1[i]); | |
| 720 | ✗ | *sum2 += (uint32_t)av_bswap16(src1[i]) * (uint32_t)av_bswap16(src1[i]); | |
| 721 | } else { | ||
| 722 | ✗ | *sum += src1[i]; | |
| 723 | ✗ | *sum2 += (uint32_t)src1[i] * (uint32_t)src1[i]; | |
| 724 | } | ||
| 725 | } | ||
| 726 | ✗ | } | |
| 727 | |||
| 728 | ✗ | static void update_sample_stats(int depth, int be, const uint8_t *src, int len, int64_t *sum, int64_t *sum2) | |
| 729 | { | ||
| 730 | ✗ | if (depth <= 8) | |
| 731 | ✗ | update_sample_stats_8(src, len, sum, sum2); | |
| 732 | else | ||
| 733 | ✗ | update_sample_stats_16(be, src, len, sum, sum2); | |
| 734 | ✗ | } | |
| 735 | |||
| 736 | ✗ | static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | |
| 737 | { | ||
| 738 | ✗ | FilterLink *inl = ff_filter_link(inlink); | |
| 739 | ✗ | AVFilterContext *ctx = inlink->dst; | |
| 740 | ✗ | ShowInfoContext *s = ctx->priv; | |
| 741 | ✗ | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); | |
| 742 | ✗ | uint32_t plane_checksum[4] = {0}, checksum = 0; | |
| 743 | ✗ | int64_t sum[4] = {0}, sum2[4] = {0}; | |
| 744 | ✗ | int32_t pixelcount[4] = {0}; | |
| 745 | ✗ | int bitdepth = desc->comp[0].depth; | |
| 746 | ✗ | int be = desc->flags & AV_PIX_FMT_FLAG_BE; | |
| 747 | ✗ | int i, plane, vsub = desc->log2_chroma_h; | |
| 748 | |||
| 749 | ✗ | for (plane = 0; plane < 4 && s->calculate_checksums && frame->data[plane] && frame->linesize[plane]; plane++) { | |
| 750 | ✗ | uint8_t *data = frame->data[plane]; | |
| 751 | ✗ | int h = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT(inlink->h, vsub) : inlink->h; | |
| 752 | ✗ | int linesize = av_image_get_linesize(frame->format, frame->width, plane); | |
| 753 | ✗ | int width = linesize >> (bitdepth > 8); | |
| 754 | |||
| 755 | ✗ | if (linesize < 0) | |
| 756 | ✗ | return linesize; | |
| 757 | |||
| 758 | ✗ | for (i = 0; i < h; i++) { | |
| 759 | ✗ | plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize); | |
| 760 | ✗ | checksum = av_adler32_update(checksum, data, linesize); | |
| 761 | |||
| 762 | ✗ | update_sample_stats(bitdepth, be, data, linesize, sum+plane, sum2+plane); | |
| 763 | ✗ | pixelcount[plane] += width; | |
| 764 | ✗ | data += frame->linesize[plane]; | |
| 765 | } | ||
| 766 | } | ||
| 767 | |||
| 768 | ✗ | av_log(ctx, AV_LOG_INFO, | |
| 769 | "n:%4"PRId64" pts:%7s pts_time:%-7s duration:%7"PRId64 | ||
| 770 | " duration_time:%-7s " | ||
| 771 | "fmt:%s cl:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c ", | ||
| 772 | inl->frame_count_out, | ||
| 773 | ✗ | av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base), | |
| 774 | ✗ | frame->duration, av_ts2timestr(frame->duration, &inlink->time_base), | |
| 775 | ✗ | desc->name, av_chroma_location_name(frame->chroma_location), | |
| 776 | frame->sample_aspect_ratio.num, frame->sample_aspect_ratio.den, | ||
| 777 | frame->width, frame->height, | ||
| 778 | ✗ | !(frame->flags & AV_FRAME_FLAG_INTERLACED) ? 'P' : /* Progressive */ | |
| 779 | ✗ | (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 'T' : 'B', /* Top / Bottom */ | |
| 780 | ✗ | !!(frame->flags & AV_FRAME_FLAG_KEY), | |
| 781 | ✗ | av_get_picture_type_char(frame->pict_type)); | |
| 782 | |||
| 783 | ✗ | if (s->calculate_checksums) { | |
| 784 | ✗ | av_log(ctx, AV_LOG_INFO, | |
| 785 | "checksum:%08"PRIX32" plane_checksum:[%08"PRIX32, | ||
| 786 | checksum, plane_checksum[0]); | ||
| 787 | |||
| 788 | ✗ | for (plane = 1; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) | |
| 789 | ✗ | av_log(ctx, AV_LOG_INFO, " %08"PRIX32, plane_checksum[plane]); | |
| 790 | ✗ | av_log(ctx, AV_LOG_INFO, "] mean:["); | |
| 791 | ✗ | for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) | |
| 792 | ✗ | av_log(ctx, AV_LOG_INFO, "%s%"PRId64, | |
| 793 | plane ? " ":"", | ||
| 794 | ✗ | (sum[plane] + pixelcount[plane]/2) / pixelcount[plane]); | |
| 795 | ✗ | av_log(ctx, AV_LOG_INFO, "] stdev:["); | |
| 796 | ✗ | for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) | |
| 797 | ✗ | av_log(ctx, AV_LOG_INFO, "%s%3.1f", | |
| 798 | plane ? " ":"", | ||
| 799 | ✗ | sqrt((sum2[plane] - sum[plane]*(double)sum[plane]/pixelcount[plane])/pixelcount[plane])); | |
| 800 | ✗ | av_log(ctx, AV_LOG_INFO, "]"); | |
| 801 | } | ||
| 802 | ✗ | av_log(ctx, AV_LOG_INFO, "\n"); | |
| 803 | |||
| 804 | ✗ | for (i = 0; i < frame->nb_side_data; i++) { | |
| 805 | ✗ | AVFrameSideData *sd = frame->side_data[i]; | |
| 806 | ✗ | const char *name = av_frame_side_data_name(sd->type); | |
| 807 | |||
| 808 | ✗ | av_log(ctx, AV_LOG_INFO, " side data - "); | |
| 809 | ✗ | if (name) | |
| 810 | ✗ | av_log(ctx, AV_LOG_INFO, "%s: ", name); | |
| 811 | ✗ | switch (sd->type) { | |
| 812 | ✗ | case AV_FRAME_DATA_SPHERICAL: | |
| 813 | ✗ | dump_spherical(ctx, frame, sd); | |
| 814 | ✗ | break; | |
| 815 | ✗ | case AV_FRAME_DATA_STEREO3D: | |
| 816 | ✗ | dump_stereo3d(ctx, sd); | |
| 817 | ✗ | break; | |
| 818 | ✗ | case AV_FRAME_DATA_S12M_TIMECODE: { | |
| 819 | ✗ | dump_s12m_timecode(ctx, inlink, sd); | |
| 820 | ✗ | break; | |
| 821 | } | ||
| 822 | ✗ | case AV_FRAME_DATA_DISPLAYMATRIX: | |
| 823 | ✗ | av_log(ctx, AV_LOG_INFO, "rotation of %.2f degrees", | |
| 824 | ✗ | av_display_rotation_get((int32_t *)sd->data)); | |
| 825 | ✗ | break; | |
| 826 | ✗ | case AV_FRAME_DATA_AFD: | |
| 827 | ✗ | av_log(ctx, AV_LOG_INFO, "value of %"PRIu8, sd->data[0]); | |
| 828 | ✗ | break; | |
| 829 | ✗ | case AV_FRAME_DATA_REGIONS_OF_INTEREST: | |
| 830 | ✗ | dump_roi(ctx, sd); | |
| 831 | ✗ | break; | |
| 832 | ✗ | case AV_FRAME_DATA_DETECTION_BBOXES: | |
| 833 | ✗ | dump_detection_bbox(ctx, sd); | |
| 834 | ✗ | break; | |
| 835 | ✗ | case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: | |
| 836 | ✗ | dump_mastering_display(ctx, sd); | |
| 837 | ✗ | break; | |
| 838 | ✗ | case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: | |
| 839 | ✗ | dump_dynamic_hdr_plus(ctx, sd); | |
| 840 | ✗ | break; | |
| 841 | ✗ | case AV_FRAME_DATA_DYNAMIC_HDR_VIVID: | |
| 842 | ✗ | dump_dynamic_hdr_vivid(ctx, sd); | |
| 843 | ✗ | break; | |
| 844 | ✗ | case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: | |
| 845 | ✗ | dump_content_light_metadata(ctx, sd); | |
| 846 | ✗ | break; | |
| 847 | ✗ | case AV_FRAME_DATA_GOP_TIMECODE: { | |
| 848 | char tcbuf[AV_TIMECODE_STR_SIZE]; | ||
| 849 | ✗ | av_timecode_make_mpeg_tc_string(tcbuf, *(int64_t *)(sd->data)); | |
| 850 | ✗ | av_log(ctx, AV_LOG_INFO, "%s", tcbuf); | |
| 851 | ✗ | break; | |
| 852 | } | ||
| 853 | ✗ | case AV_FRAME_DATA_VIDEO_ENC_PARAMS: | |
| 854 | ✗ | dump_video_enc_params(ctx, sd); | |
| 855 | ✗ | break; | |
| 856 | ✗ | case AV_FRAME_DATA_SEI_UNREGISTERED: | |
| 857 | ✗ | dump_sei_unregistered_metadata(ctx, sd); | |
| 858 | ✗ | break; | |
| 859 | ✗ | case AV_FRAME_DATA_FILM_GRAIN_PARAMS: | |
| 860 | ✗ | dump_sei_film_grain_params_metadata(ctx, sd); | |
| 861 | ✗ | break; | |
| 862 | ✗ | case AV_FRAME_DATA_DOVI_METADATA: | |
| 863 | ✗ | dump_dovi_metadata(ctx, sd); | |
| 864 | ✗ | break; | |
| 865 | ✗ | case AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT: | |
| 866 | ✗ | dump_ambient_viewing_environment(ctx, sd); | |
| 867 | ✗ | break; | |
| 868 | ✗ | case AV_FRAME_DATA_VIEW_ID: | |
| 869 | ✗ | av_log(ctx, AV_LOG_INFO, "view id: %d\n", *(int*)sd->data); | |
| 870 | ✗ | break; | |
| 871 | ✗ | case AV_FRAME_DATA_3D_REFERENCE_DISPLAYS: | |
| 872 | ✗ | dump_tdrdi(ctx, sd); | |
| 873 | ✗ | break; | |
| 874 | ✗ | default: | |
| 875 | ✗ | if (name) | |
| 876 | ✗ | av_log(ctx, AV_LOG_INFO, "(%zu bytes)", sd->size); | |
| 877 | else | ||
| 878 | ✗ | av_log(ctx, AV_LOG_WARNING, "unknown side data type %d " | |
| 879 | ✗ | "(%zu bytes)", sd->type, sd->size); | |
| 880 | ✗ | break; | |
| 881 | } | ||
| 882 | |||
| 883 | ✗ | av_log(ctx, AV_LOG_INFO, "\n"); | |
| 884 | } | ||
| 885 | |||
| 886 | ✗ | dump_color_property(ctx, frame); | |
| 887 | |||
| 888 | ✗ | if (desc->flags & AV_PIX_FMT_FLAG_ALPHA) { | |
| 889 | ✗ | const char *alpha_mode_str = av_alpha_mode_name(frame->alpha_mode); | |
| 890 | ✗ | if (!alpha_mode_str || frame->alpha_mode == AVALPHA_MODE_UNSPECIFIED) | |
| 891 | ✗ | av_log(ctx, AV_LOG_INFO, "alpha_mode:unspecified\n"); | |
| 892 | else | ||
| 893 | ✗ | av_log(ctx, AV_LOG_INFO, "alpha_mode:%s\n", alpha_mode_str); | |
| 894 | } | ||
| 895 | |||
| 896 | ✗ | return ff_filter_frame(inlink->dst->outputs[0], frame); | |
| 897 | } | ||
| 898 | |||
| 899 | ✗ | static int config_props(AVFilterContext *ctx, AVFilterLink *link, int is_out) | |
| 900 | { | ||
| 901 | ✗ | FilterLink *l = ff_filter_link(link); | |
| 902 | |||
| 903 | ✗ | av_log(ctx, AV_LOG_INFO, "config %s time_base: %d/%d, frame_rate: %d/%d\n", | |
| 904 | is_out ? "out" : "in", | ||
| 905 | link->time_base.num, link->time_base.den, | ||
| 906 | l->frame_rate.num, l->frame_rate.den); | ||
| 907 | |||
| 908 | ✗ | return 0; | |
| 909 | } | ||
| 910 | |||
| 911 | ✗ | static int config_props_in(AVFilterLink *link) | |
| 912 | { | ||
| 913 | ✗ | AVFilterContext *ctx = link->dst; | |
| 914 | ✗ | return config_props(ctx, link, 0); | |
| 915 | } | ||
| 916 | |||
| 917 | ✗ | static int config_props_out(AVFilterLink *link) | |
| 918 | { | ||
| 919 | ✗ | AVFilterContext *ctx = link->src; | |
| 920 | ✗ | return config_props(ctx, link, 1); | |
| 921 | } | ||
| 922 | |||
| 923 | static const AVFilterPad avfilter_vf_showinfo_inputs[] = { | ||
| 924 | { | ||
| 925 | .name = "default", | ||
| 926 | .type = AVMEDIA_TYPE_VIDEO, | ||
| 927 | .filter_frame = filter_frame, | ||
| 928 | .config_props = config_props_in, | ||
| 929 | }, | ||
| 930 | }; | ||
| 931 | |||
| 932 | static const AVFilterPad avfilter_vf_showinfo_outputs[] = { | ||
| 933 | { | ||
| 934 | .name = "default", | ||
| 935 | .type = AVMEDIA_TYPE_VIDEO, | ||
| 936 | .config_props = config_props_out, | ||
| 937 | }, | ||
| 938 | }; | ||
| 939 | |||
| 940 | const FFFilter ff_vf_showinfo = { | ||
| 941 | .p.name = "showinfo", | ||
| 942 | .p.description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."), | ||
| 943 | .p.priv_class = &showinfo_class, | ||
| 944 | .p.flags = AVFILTER_FLAG_METADATA_ONLY, | ||
| 945 | FILTER_INPUTS(avfilter_vf_showinfo_inputs), | ||
| 946 | FILTER_OUTPUTS(avfilter_vf_showinfo_outputs), | ||
| 947 | .priv_size = sizeof(ShowInfoContext), | ||
| 948 | }; | ||
| 949 |