Coverage Report

Created: 2026-04-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/dump.c
Line
Count
Source
1
/*
2
 * Various pretty-printing functions for use within FFmpeg
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include <stdio.h>
23
#include <stdint.h>
24
25
#include "libavutil/avstring.h"
26
#include "libavutil/channel_layout.h"
27
#include "libavutil/display.h"
28
#include "libavutil/iamf.h"
29
#include "libavutil/intreadwrite.h"
30
#include "libavutil/log.h"
31
#include "libavutil/mastering_display_metadata.h"
32
#include "libavutil/ambient_viewing_environment.h"
33
#include "libavutil/dovi_meta.h"
34
#include "libavutil/mathematics.h"
35
#include "libavutil/mem.h"
36
#include "libavutil/opt.h"
37
#include "libavutil/replaygain.h"
38
#include "libavutil/spherical.h"
39
#include "libavutil/stereo3d.h"
40
#include "libavutil/tdrdi.h"
41
#include "libavutil/timecode.h"
42
43
#include "libavcodec/avcodec.h"
44
45
#include "avformat.h"
46
#include "internal.h"
47
48
#define HEXDUMP_PRINT(...)                                                    \
49
19.8M
    do {                                                                      \
50
19.8M
        if (!f)                                                               \
51
19.8M
            av_log(avcl, level, __VA_ARGS__);                                 \
52
19.8M
        else                                                                  \
53
19.8M
            fprintf(f, __VA_ARGS__);                                          \
54
19.8M
    } while (0)
55
56
static void hex_dump_internal(void *avcl, FILE *f, int level,
57
                              const uint8_t *buf, int size)
58
522
{
59
522
    int len, i, j, c;
60
61
568k
    for (i = 0; i < size; i += 16) {
62
567k
        len = size - i;
63
567k
        if (len > 16)
64
567k
            len = 16;
65
567k
        HEXDUMP_PRINT("%08x ", i);
66
9.65M
        for (j = 0; j < 16; j++) {
67
9.08M
            if (j < len)
68
9.08M
                HEXDUMP_PRINT(" %02x", buf[i + j]);
69
3.84k
            else
70
3.84k
                HEXDUMP_PRINT("   ");
71
9.08M
        }
72
567k
        HEXDUMP_PRINT(" ");
73
9.65M
        for (j = 0; j < len; j++) {
74
9.08M
            c = buf[i + j];
75
9.08M
            if (c < ' ' || c > '~')
76
8.80M
                c = '.';
77
9.08M
            HEXDUMP_PRINT("%c", c);
78
9.08M
        }
79
567k
        HEXDUMP_PRINT("\n");
80
567k
    }
81
522
}
82
83
void av_hex_dump(FILE *f, const uint8_t *buf, int size)
84
0
{
85
0
    hex_dump_internal(NULL, f, 0, buf, size);
86
0
}
87
88
void av_hex_dump_log(void *avcl, int level, const uint8_t *buf, int size)
89
522
{
90
522
    hex_dump_internal(avcl, NULL, level, buf, size);
91
522
}
92
93
static void pkt_dump_internal(void *avcl, FILE *f, int level, const AVPacket *pkt,
94
                              int dump_payload, AVRational time_base)
95
0
{
96
0
    HEXDUMP_PRINT("stream #%d:\n", pkt->stream_index);
97
0
    HEXDUMP_PRINT("  keyframe=%d\n", (pkt->flags & AV_PKT_FLAG_KEY) != 0);
98
0
    HEXDUMP_PRINT("  duration=%0.3f\n", pkt->duration * av_q2d(time_base));
99
    /* DTS is _always_ valid after av_read_frame() */
100
0
    HEXDUMP_PRINT("  dts=");
101
0
    if (pkt->dts == AV_NOPTS_VALUE)
102
0
        HEXDUMP_PRINT("N/A");
103
0
    else
104
0
        HEXDUMP_PRINT("%0.3f", pkt->dts * av_q2d(time_base));
105
    /* PTS may not be known if B-frames are present. */
106
0
    HEXDUMP_PRINT("  pts=");
107
0
    if (pkt->pts == AV_NOPTS_VALUE)
108
0
        HEXDUMP_PRINT("N/A");
109
0
    else
110
0
        HEXDUMP_PRINT("%0.3f", pkt->pts * av_q2d(time_base));
111
0
    HEXDUMP_PRINT("\n");
112
0
    HEXDUMP_PRINT("  size=%d\n", pkt->size);
113
0
    if (dump_payload)
114
0
        hex_dump_internal(avcl, f, level, pkt->data, pkt->size);
115
0
}
116
117
void av_pkt_dump2(FILE *f, const AVPacket *pkt, int dump_payload, const AVStream *st)
118
0
{
119
0
    pkt_dump_internal(NULL, f, 0, pkt, dump_payload, st->time_base);
120
0
}
121
122
void av_pkt_dump_log2(void *avcl, int level, const AVPacket *pkt, int dump_payload,
123
                      const AVStream *st)
124
0
{
125
0
    pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, st->time_base);
126
0
}
127
128
129
static void print_fps(double d, const char *postfix, int log_level)
130
0
{
131
0
    uint64_t v = lrintf(d * 100);
132
0
    if (!v)
133
0
        av_log(NULL, log_level, "%1.4f %s", d, postfix);
134
0
    else if (v % 100)
135
0
        av_log(NULL, log_level, "%3.2f %s", d, postfix);
136
0
    else if (v % (100 * 1000))
137
0
        av_log(NULL, log_level, "%1.0f %s", d, postfix);
138
0
    else
139
0
        av_log(NULL, log_level, "%1.0fk %s", d / 1000, postfix);
140
0
}
141
142
static void dump_dictionary(void *ctx, const AVDictionary *m,
143
                            const char *name, const char *indent,
144
                            int log_level)
145
0
{
146
0
    const AVDictionaryEntry *tag = NULL;
147
148
0
    if (!m)
149
0
        return;
150
151
0
    av_log(ctx, log_level, "%s%s:\n", indent, name);
152
0
    while ((tag = av_dict_iterate(m, tag)))
153
0
        if (strcmp("language", tag->key)) {
154
0
            const char *p = tag->value;
155
0
            av_log(ctx, log_level,
156
0
                   "%s  %-16s: ", indent, tag->key);
157
0
            while (*p) {
158
0
                size_t len = strcspn(p, "\x8\xa\xb\xc\xd");
159
0
                av_log(ctx, log_level, "%.*s", (int)(FFMIN(255, len)), p);
160
0
                p += len;
161
0
                if (*p == 0xd) av_log(ctx, log_level, " ");
162
0
                if (*p == 0xa) av_log(ctx, log_level, "\n%s  %-16s: ", indent, "");
163
0
                if (*p) p++;
164
0
            }
165
0
            av_log(ctx, log_level, "\n");
166
0
        }
167
0
}
168
169
static void dump_metadata(void *ctx, const AVDictionary *m, const char *indent,
170
                          int log_level)
171
0
{
172
0
    if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0)))
173
0
        dump_dictionary(ctx, m, "Metadata", indent, log_level);
174
0
}
175
176
/* param change side data*/
177
static void dump_paramchange(void *ctx, const AVPacketSideData *sd, int log_level)
178
0
{
179
0
    int size = sd->size;
180
0
    const uint8_t *data = sd->data;
181
0
    uint32_t flags, sample_rate, width, height;
182
183
0
    if (!data || sd->size < 4)
184
0
        goto fail;
185
186
0
    flags = AV_RL32(data);
187
0
    data += 4;
188
0
    size -= 4;
189
190
0
    if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
191
0
        if (size < 4)
192
0
            goto fail;
193
0
        sample_rate = AV_RL32(data);
194
0
        data += 4;
195
0
        size -= 4;
196
0
        av_log(ctx, log_level, "sample_rate %"PRIu32", ", sample_rate);
197
0
    }
198
0
    if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) {
199
0
        if (size < 8)
200
0
            goto fail;
201
0
        width = AV_RL32(data);
202
0
        data += 4;
203
0
        size -= 4;
204
0
        height = AV_RL32(data);
205
0
        data += 4;
206
0
        size -= 4;
207
0
        av_log(ctx, log_level, "width %"PRIu32" height %"PRIu32, width, height);
208
0
    }
209
210
0
    return;
211
0
fail:
212
0
    av_log(ctx, AV_LOG_ERROR, "unknown param\n");
213
0
}
214
215
/* replaygain side data*/
216
static void print_gain(void *ctx, const char *str, int32_t gain, int log_level)
217
0
{
218
0
    av_log(ctx, log_level, "%s - ", str);
219
0
    if (gain == INT32_MIN)
220
0
        av_log(ctx, log_level, "unknown");
221
0
    else
222
0
        av_log(ctx, log_level, "%f", gain / 100000.0f);
223
0
    av_log(ctx, log_level, ", ");
224
0
}
225
226
static void print_peak(void *ctx, const char *str, uint32_t peak, int log_level)
227
0
{
228
0
    av_log(ctx, log_level, "%s - ", str);
229
0
    if (!peak)
230
0
        av_log(ctx, log_level, "unknown");
231
0
    else
232
0
        av_log(ctx, log_level, "%f", (float) peak / UINT32_MAX);
233
0
    av_log(ctx, log_level, ", ");
234
0
}
235
236
static void dump_replaygain(void *ctx, const AVPacketSideData *sd, int log_level)
237
0
{
238
0
    const AVReplayGain *rg;
239
240
0
    if (sd->size < sizeof(*rg)) {
241
0
        av_log(ctx, AV_LOG_ERROR, "invalid data\n");
242
0
        return;
243
0
    }
244
0
    rg = (const AVReplayGain *)sd->data;
245
246
0
    print_gain(ctx, "track gain", rg->track_gain, log_level);
247
0
    print_peak(ctx, "track peak", rg->track_peak, log_level);
248
0
    print_gain(ctx, "album gain", rg->album_gain, log_level);
249
0
    print_peak(ctx, "album peak", rg->album_peak, log_level);
250
0
}
251
252
static void dump_stereo3d(void *ctx, const AVPacketSideData *sd, int log_level)
253
0
{
254
0
    const AVStereo3D *stereo;
255
256
0
    if (sd->size < sizeof(*stereo)) {
257
0
        av_log(ctx, AV_LOG_ERROR, "invalid data\n");
258
0
        return;
259
0
    }
260
261
0
    stereo = (const AVStereo3D *)sd->data;
262
263
0
    av_log(ctx, log_level, "%s, view: %s, primary eye: %s",
264
0
           av_stereo3d_type_name(stereo->type), av_stereo3d_view_name(stereo->view),
265
0
           av_stereo3d_primary_eye_name(stereo->primary_eye));
266
0
    if (stereo->baseline)
267
0
        av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo->baseline);
268
0
    if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den)
269
0
        av_log(ctx, log_level, ", horizontal_disparity_adjustment: %0.4f",
270
0
               av_q2d(stereo->horizontal_disparity_adjustment));
271
0
    if (stereo->horizontal_field_of_view.num && stereo->horizontal_field_of_view.den)
272
0
        av_log(ctx, log_level, ", horizontal_field_of_view: %0.3f", av_q2d(stereo->horizontal_field_of_view));
273
274
0
    if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
275
0
        av_log(ctx, log_level, " (inverted)");
276
0
}
277
278
static void dump_audioservicetype(void *ctx, const AVPacketSideData *sd, int log_level)
279
0
{
280
0
    const enum AVAudioServiceType *ast = (const enum AVAudioServiceType *)sd->data;
281
282
0
    if (sd->size < sizeof(*ast)) {
283
0
        av_log(ctx, AV_LOG_ERROR, "invalid data\n");
284
0
        return;
285
0
    }
286
287
0
    switch (*ast) {
288
0
    case AV_AUDIO_SERVICE_TYPE_MAIN:
289
0
        av_log(ctx, log_level, "main");
290
0
        break;
291
0
    case AV_AUDIO_SERVICE_TYPE_EFFECTS:
292
0
        av_log(ctx, log_level, "effects");
293
0
        break;
294
0
    case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED:
295
0
        av_log(ctx, log_level, "visually impaired");
296
0
        break;
297
0
    case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED:
298
0
        av_log(ctx, log_level, "hearing impaired");
299
0
        break;
300
0
    case AV_AUDIO_SERVICE_TYPE_DIALOGUE:
301
0
        av_log(ctx, log_level, "dialogue");
302
0
        break;
303
0
    case AV_AUDIO_SERVICE_TYPE_COMMENTARY:
304
0
        av_log(ctx, log_level, "commentary");
305
0
        break;
306
0
    case AV_AUDIO_SERVICE_TYPE_EMERGENCY:
307
0
        av_log(ctx, log_level, "emergency");
308
0
        break;
309
0
    case AV_AUDIO_SERVICE_TYPE_VOICE_OVER:
310
0
        av_log(ctx, log_level, "voice over");
311
0
        break;
312
0
    case AV_AUDIO_SERVICE_TYPE_KARAOKE:
313
0
        av_log(ctx, log_level, "karaoke");
314
0
        break;
315
0
    default:
316
0
        av_log(ctx, AV_LOG_WARNING, "unknown");
317
0
        break;
318
0
    }
319
0
}
320
321
static void dump_cpb(void *ctx, const AVPacketSideData *sd, int log_level)
322
0
{
323
0
    const AVCPBProperties *cpb = (const AVCPBProperties *)sd->data;
324
325
0
    if (sd->size < sizeof(*cpb)) {
326
0
        av_log(ctx, AV_LOG_ERROR, "invalid data\n");
327
0
        return;
328
0
    }
329
330
0
    av_log(ctx, log_level,
331
0
           "bitrate max/min/avg: %"PRId64"/%"PRId64"/%"PRId64" buffer size: %"PRId64" ",
332
0
           cpb->max_bitrate, cpb->min_bitrate, cpb->avg_bitrate,
333
0
           cpb->buffer_size);
334
0
    if (cpb->vbv_delay == UINT64_MAX)
335
0
        av_log(ctx, log_level, "vbv_delay: N/A");
336
0
    else
337
0
        av_log(ctx, log_level, "vbv_delay: %"PRIu64"", cpb->vbv_delay);
338
0
}
339
340
static void dump_mastering_display_metadata(void *ctx, const AVPacketSideData *sd,
341
                                            int log_level)
342
0
{
343
0
    const AVMasteringDisplayMetadata *metadata =
344
0
        (const AVMasteringDisplayMetadata *)sd->data;
345
0
    av_log(ctx, log_level,
346
0
           "has_primaries:%d has_luminance:%d "
347
0
           "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) "
348
0
           "min_luminance=%f, max_luminance=%f",
349
0
           metadata->has_primaries, metadata->has_luminance,
350
0
           av_q2d(metadata->display_primaries[0][0]),
351
0
           av_q2d(metadata->display_primaries[0][1]),
352
0
           av_q2d(metadata->display_primaries[1][0]),
353
0
           av_q2d(metadata->display_primaries[1][1]),
354
0
           av_q2d(metadata->display_primaries[2][0]),
355
0
           av_q2d(metadata->display_primaries[2][1]),
356
0
           av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]),
357
0
           av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
358
0
}
359
360
static void dump_content_light_metadata(void *ctx, const AVPacketSideData *sd,
361
                                        int log_level)
362
0
{
363
0
    const AVContentLightMetadata *metadata =
364
0
        (const AVContentLightMetadata *)sd->data;
365
0
    av_log(ctx, log_level,
366
0
           "MaxCLL=%d, MaxFALL=%d",
367
0
           metadata->MaxCLL, metadata->MaxFALL);
368
0
}
369
370
static void dump_ambient_viewing_environment_metadata(void *ctx, const AVPacketSideData *sd, int log_level)
371
0
{
372
0
    const AVAmbientViewingEnvironment *ambient =
373
0
        (const AVAmbientViewingEnvironment *)sd->data;
374
0
    av_log(ctx, log_level,
375
0
           "ambient_illuminance=%f, ambient_light_x=%f, ambient_light_y=%f",
376
0
           av_q2d(ambient->ambient_illuminance),
377
0
           av_q2d(ambient->ambient_light_x),
378
0
           av_q2d(ambient->ambient_light_y));
379
0
}
380
381
static void dump_spherical(void *ctx, int w, int h,
382
                           const AVPacketSideData *sd, int log_level)
383
0
{
384
0
    const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data;
385
0
    double yaw, pitch, roll;
386
387
0
    if (sd->size < sizeof(*spherical)) {
388
0
        av_log(ctx, AV_LOG_ERROR, "invalid data\n");
389
0
        return;
390
0
    }
391
392
0
    av_log(ctx, log_level, "%s ", av_spherical_projection_name(spherical->projection));
393
394
0
    if (spherical->yaw || spherical->pitch || spherical->roll) {
395
0
        yaw = ((double)spherical->yaw) / (1 << 16);
396
0
        pitch = ((double)spherical->pitch) / (1 << 16);
397
0
        roll = ((double)spherical->roll) / (1 << 16);
398
0
        av_log(ctx, log_level, "(%f/%f/%f) ", yaw, pitch, roll);
399
0
    }
400
401
0
    if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
402
0
        size_t l, t, r, b;
403
0
        av_spherical_tile_bounds(spherical, w, h,
404
0
                                 &l, &t, &r, &b);
405
0
        av_log(ctx, log_level, "[%zu, %zu, %zu, %zu] ", l, t, r, b);
406
0
    } else if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
407
0
        av_log(ctx, log_level, "[pad %"PRIu32"] ", spherical->padding);
408
0
    }
409
0
}
410
411
static void dump_dovi_conf(void *ctx, const AVPacketSideData *sd,
412
                           int log_level)
413
0
{
414
0
    const AVDOVIDecoderConfigurationRecord *dovi =
415
0
        (const AVDOVIDecoderConfigurationRecord *)sd->data;
416
417
0
    av_log(ctx, log_level, "version: %d.%d, profile: %d, level: %d, "
418
0
           "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d, "
419
0
           "compression: %d",
420
0
           dovi->dv_version_major, dovi->dv_version_minor,
421
0
           dovi->dv_profile, dovi->dv_level,
422
0
           dovi->rpu_present_flag,
423
0
           dovi->el_present_flag,
424
0
           dovi->bl_present_flag,
425
0
           dovi->dv_bl_signal_compatibility_id,
426
0
           dovi->dv_md_compression);
427
0
}
428
429
static void dump_s12m_timecode(void *ctx, AVRational avg_frame_rate, const AVPacketSideData *sd,
430
                               int log_level)
431
0
{
432
0
    const uint32_t *tc = (const uint32_t *)sd->data;
433
434
0
    if ((sd->size != sizeof(uint32_t) * 4) || (tc[0] > 3)) {
435
0
        av_log(ctx, AV_LOG_ERROR, "invalid data\n");
436
0
        return;
437
0
    }
438
439
0
    for (int j = 1; j <= tc[0]; j++) {
440
0
        char tcbuf[AV_TIMECODE_STR_SIZE];
441
0
        av_timecode_make_smpte_tc_string2(tcbuf, avg_frame_rate, tc[j], 0, 0);
442
0
        av_log(ctx, log_level, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : "");
443
0
    }
444
0
}
445
446
static void dump_cropping(void *ctx, const AVPacketSideData *sd, int log_level)
447
0
{
448
0
    uint32_t top, bottom, left, right;
449
450
0
    if (sd->size < sizeof(uint32_t) * 4) {
451
0
        av_log(ctx, log_level, "invalid data\n");
452
0
        return;
453
0
    }
454
455
0
    top    = AV_RL32(sd->data +  0);
456
0
    bottom = AV_RL32(sd->data +  4);
457
0
    left   = AV_RL32(sd->data +  8);
458
0
    right  = AV_RL32(sd->data + 12);
459
460
0
    av_log(ctx, log_level, "%"PRIu32"/%"PRIu32"/%"PRIu32"/%"PRIu32"", left, right, top, bottom);
461
0
}
462
463
static void dump_tdrdi(void *ctx, const AVPacketSideData *sd, int log_level)
464
0
{
465
0
    const AV3DReferenceDisplaysInfo *tdrdi =
466
0
        (const AV3DReferenceDisplaysInfo *)sd->data;
467
468
0
    av_log(ctx, log_level, "number of reference displays: %u", tdrdi->num_ref_displays);
469
0
}
470
471
static void dump_sidedata(void *ctx, const AVPacketSideData *side_data, int nb_side_data,
472
                          int w, int h, AVRational avg_frame_rate,
473
                          const char *indent, int log_level)
474
0
{
475
0
    int i;
476
477
0
    if (nb_side_data)
478
0
        av_log(ctx, log_level, "%sSide data:\n", indent);
479
480
0
    for (i = 0; i < nb_side_data; i++) {
481
0
        const AVPacketSideData *sd = &side_data[i];
482
0
        const char *name = av_packet_side_data_name(sd->type);
483
484
0
        av_log(ctx, log_level, "%s  ", indent);
485
0
        if (name)
486
0
            av_log(ctx, log_level, "%s: ", name);
487
0
        switch (sd->type) {
488
0
        case AV_PKT_DATA_PARAM_CHANGE:
489
0
            dump_paramchange(ctx, sd, log_level);
490
0
            break;
491
0
        case AV_PKT_DATA_REPLAYGAIN:
492
0
            dump_replaygain(ctx, sd, log_level);
493
0
            break;
494
0
        case AV_PKT_DATA_DISPLAYMATRIX:
495
0
            av_log(ctx, log_level, "rotation of %.2f degrees",
496
0
                   av_display_rotation_get((const int32_t *)sd->data));
497
0
            break;
498
0
        case AV_PKT_DATA_STEREO3D:
499
0
            dump_stereo3d(ctx, sd, log_level);
500
0
            break;
501
0
        case AV_PKT_DATA_AUDIO_SERVICE_TYPE:
502
0
            dump_audioservicetype(ctx, sd, log_level);
503
0
            break;
504
0
        case AV_PKT_DATA_QUALITY_STATS:
505
0
            av_log(ctx, log_level, "%"PRId32", pict_type: %c",
506
0
                   AV_RL32(sd->data), av_get_picture_type_char(sd->data[4]));
507
0
            break;
508
0
        case AV_PKT_DATA_CPB_PROPERTIES:
509
0
            dump_cpb(ctx, sd, log_level);
510
0
            break;
511
0
        case AV_PKT_DATA_MASTERING_DISPLAY_METADATA:
512
0
            dump_mastering_display_metadata(ctx, sd, log_level);
513
0
            break;
514
0
        case AV_PKT_DATA_SPHERICAL:
515
0
            dump_spherical(ctx, w, h, sd, log_level);
516
0
            break;
517
0
        case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:
518
0
            dump_content_light_metadata(ctx, sd, log_level);
519
0
            break;
520
0
        case AV_PKT_DATA_DOVI_CONF:
521
0
            dump_dovi_conf(ctx, sd, log_level);
522
0
            break;
523
0
        case AV_PKT_DATA_S12M_TIMECODE:
524
0
            dump_s12m_timecode(ctx, avg_frame_rate, sd, log_level);
525
0
            break;
526
0
        case AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT:
527
0
            dump_ambient_viewing_environment_metadata(ctx, sd, log_level);
528
0
            break;
529
0
        case AV_PKT_DATA_FRAME_CROPPING:
530
0
            dump_cropping(ctx, sd, log_level);
531
0
            break;
532
0
        case AV_PKT_DATA_3D_REFERENCE_DISPLAYS:
533
0
            dump_tdrdi(ctx, sd, log_level);
534
0
            break;
535
0
        default:
536
0
            if (name)
537
0
                av_log(ctx, log_level, "(%zu bytes)", sd->size);
538
0
            else
539
0
                av_log(ctx, log_level, "unknown side data type %d "
540
0
                       "(%zu bytes)", sd->type, sd->size);
541
0
            break;
542
0
        }
543
544
0
        av_log(ctx, log_level, "\n");
545
0
    }
546
0
}
547
548
static void dump_disposition(int disposition, int log_level)
549
0
{
550
0
    if (disposition & AV_DISPOSITION_DEFAULT)
551
0
        av_log(NULL, log_level, " (default)");
552
0
    if (disposition & AV_DISPOSITION_DUB)
553
0
        av_log(NULL, log_level, " (dub)");
554
0
    if (disposition & AV_DISPOSITION_ORIGINAL)
555
0
        av_log(NULL, log_level, " (original)");
556
0
    if (disposition & AV_DISPOSITION_COMMENT)
557
0
        av_log(NULL, log_level, " (comment)");
558
0
    if (disposition & AV_DISPOSITION_LYRICS)
559
0
        av_log(NULL, log_level, " (lyrics)");
560
0
    if (disposition & AV_DISPOSITION_KARAOKE)
561
0
        av_log(NULL, log_level, " (karaoke)");
562
0
    if (disposition & AV_DISPOSITION_FORCED)
563
0
        av_log(NULL, log_level, " (forced)");
564
0
    if (disposition & AV_DISPOSITION_HEARING_IMPAIRED)
565
0
        av_log(NULL, log_level, " (hearing impaired)");
566
0
    if (disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
567
0
        av_log(NULL, log_level, " (visual impaired)");
568
0
    if (disposition & AV_DISPOSITION_CLEAN_EFFECTS)
569
0
        av_log(NULL, log_level, " (clean effects)");
570
0
    if (disposition & AV_DISPOSITION_ATTACHED_PIC)
571
0
        av_log(NULL, log_level, " (attached pic)");
572
0
    if (disposition & AV_DISPOSITION_TIMED_THUMBNAILS)
573
0
        av_log(NULL, log_level, " (timed thumbnails)");
574
0
    if (disposition & AV_DISPOSITION_CAPTIONS)
575
0
        av_log(NULL, log_level, " (captions)");
576
0
    if (disposition & AV_DISPOSITION_DESCRIPTIONS)
577
0
        av_log(NULL, log_level, " (descriptions)");
578
0
    if (disposition & AV_DISPOSITION_METADATA)
579
0
        av_log(NULL, log_level, " (metadata)");
580
0
    if (disposition & AV_DISPOSITION_DEPENDENT)
581
0
        av_log(NULL, log_level, " (dependent)");
582
0
    if (disposition & AV_DISPOSITION_STILL_IMAGE)
583
0
        av_log(NULL, log_level, " (still image)");
584
0
    if (disposition & AV_DISPOSITION_NON_DIEGETIC)
585
0
        av_log(NULL, log_level, " (non-diegetic)");
586
0
    if (disposition & AV_DISPOSITION_MULTILAYER)
587
0
        av_log(NULL, log_level, " (multilayer)");
588
0
}
589
590
/* "user interface" functions */
591
static void dump_stream_format(const AVFormatContext *ic, int i,
592
                               int group_index, int index, int is_output,
593
                               int log_level)
594
0
{
595
0
    char buf[256];
596
0
    int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
597
0
    const AVStream *st = ic->streams[i];
598
0
    const FFStream *const sti = cffstream(st);
599
0
    const AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
600
0
    const char *separator = ic->dump_separator;
601
0
    const char *group_indent = group_index >= 0 ? "  " : "";
602
0
    const char *extra_indent = group_index >= 0 ? "      " : "    ";
603
0
    AVCodecContext *avctx;
604
0
    int ret;
605
606
0
    avctx = avcodec_alloc_context3(NULL);
607
0
    if (!avctx)
608
0
        return;
609
610
0
    ret = avcodec_parameters_to_context(avctx, st->codecpar);
611
0
    if (ret < 0) {
612
0
        avcodec_free_context(&avctx);
613
0
        return;
614
0
    }
615
616
    // Fields which are missing from AVCodecParameters need to be taken from the AVCodecContext
617
0
    if (sti->avctx) {
618
0
#if FF_API_CODEC_PROPS
619
0
FF_DISABLE_DEPRECATION_WARNINGS
620
0
        avctx->properties   = sti->avctx->properties;
621
0
FF_ENABLE_DEPRECATION_WARNINGS
622
0
#endif
623
0
        avctx->codec        = sti->avctx->codec;
624
0
        avctx->qmin         = sti->avctx->qmin;
625
0
        avctx->qmax         = sti->avctx->qmax;
626
0
        avctx->coded_width  = sti->avctx->coded_width;
627
0
        avctx->coded_height = sti->avctx->coded_height;
628
0
    }
629
630
0
    if (separator)
631
0
        av_opt_set(avctx, "dump_separator", separator, 0);
632
0
    avcodec_string(buf, sizeof(buf), avctx, is_output);
633
0
    avcodec_free_context(&avctx);
634
635
0
    av_log(NULL, log_level, "%s  Stream #%d", group_indent, index);
636
0
    av_log(NULL, log_level, ":%d", i);
637
638
    /* the pid is an important information, so we display it */
639
    /* XXX: add a generic system */
640
0
    if (flags & AVFMT_SHOW_IDS)
641
0
        av_log(NULL, log_level, "[0x%x]", st->id);
642
0
    if (lang)
643
0
        av_log(NULL, log_level, "(%s)", lang->value);
644
0
    av_log(NULL, AV_LOG_DEBUG, ", %d, %d/%d", sti->codec_info_nb_frames,
645
0
           st->time_base.num, st->time_base.den);
646
0
    av_log(NULL, log_level, ": %s", buf);
647
648
0
    if (st->sample_aspect_ratio.num &&
649
0
        av_cmp_q(st->sample_aspect_ratio, st->codecpar->sample_aspect_ratio)) {
650
0
        AVRational display_aspect_ratio;
651
0
        av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
652
0
                  st->codecpar->width  * (int64_t)st->sample_aspect_ratio.num,
653
0
                  st->codecpar->height * (int64_t)st->sample_aspect_ratio.den,
654
0
                  1024 * 1024);
655
0
        av_log(NULL, log_level, ", SAR %d:%d DAR %d:%d",
656
0
               st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
657
0
               display_aspect_ratio.num, display_aspect_ratio.den);
658
0
    }
659
660
0
    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
661
0
        int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
662
0
        int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
663
0
        int tbn = st->time_base.den && st->time_base.num;
664
665
0
        if (fps || tbr || tbn)
666
0
            av_log(NULL, log_level, "%s", separator);
667
668
0
        if (fps)
669
0
            print_fps(av_q2d(st->avg_frame_rate), tbr || tbn ? "fps, " : "fps", log_level);
670
0
        if (tbr)
671
0
            print_fps(av_q2d(st->r_frame_rate), tbn ? "tbr, " : "tbr", log_level);
672
0
        if (tbn)
673
0
            print_fps(1 / av_q2d(st->time_base), "tbn", log_level);
674
0
    }
675
676
0
    if (st->start_time != AV_NOPTS_VALUE && st->start_time != 0 && st->time_base.den && st->time_base.num) {
677
0
        const double stream_start = av_q2d(st->time_base) * st->start_time;
678
0
        av_log(NULL, log_level, ", start %.6f", stream_start);
679
0
    }
680
681
0
    dump_disposition(st->disposition, log_level);
682
0
    av_log(NULL, log_level, "\n");
683
684
0
    dump_metadata(NULL, st->metadata, extra_indent, log_level);
685
686
0
    dump_sidedata(NULL, st->codecpar->coded_side_data, st->codecpar->nb_coded_side_data,
687
0
                  st->codecpar->width, st->codecpar->height, st->avg_frame_rate,
688
0
                  extra_indent, log_level);
689
0
}
690
691
static void dump_stream_group(const AVFormatContext *ic, uint8_t *printed,
692
                              int i, int index, int is_output)
693
0
{
694
0
    const AVStreamGroup *stg = ic->stream_groups[i];
695
0
    int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
696
0
    char buf[512];
697
0
    int ret;
698
699
0
    av_log(NULL, AV_LOG_INFO, "  Stream group #%d:%d", index, i);
700
0
    if (flags & AVFMT_SHOW_IDS)
701
0
        av_log(NULL, AV_LOG_INFO, "[0x%"PRIx64"]", stg->id);
702
0
    av_log(NULL, AV_LOG_INFO, ":");
703
704
0
    switch (stg->type) {
705
0
    case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: {
706
0
        const AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
707
0
        av_log(NULL, AV_LOG_INFO, " IAMF Audio Element:");
708
0
        dump_disposition(stg->disposition, AV_LOG_INFO);
709
0
        av_log(NULL, AV_LOG_INFO, "\n");
710
0
        dump_metadata(NULL, stg->metadata, "    ", AV_LOG_INFO);
711
0
        for (int j = 0; j < audio_element->nb_layers; j++) {
712
0
            const AVIAMFLayer *layer = audio_element->layers[j];
713
0
            int channel_count = layer->ch_layout.nb_channels;
714
0
            av_log(NULL, AV_LOG_INFO, "    Layer %d:", j);
715
0
            ret = av_channel_layout_describe(&layer->ch_layout, buf, sizeof(buf));
716
0
            if (ret >= 0)
717
0
                av_log(NULL, AV_LOG_INFO, " %s", buf);
718
0
            av_log(NULL, AV_LOG_INFO, "\n");
719
0
            for (int k = 0; channel_count > 0 && k < stg->nb_streams; k++) {
720
0
                AVStream *st = stg->streams[k];
721
0
                dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_VERBOSE);
722
0
                printed[st->index] = 1;
723
0
                channel_count -= st->codecpar->ch_layout.nb_channels;
724
0
            }
725
0
        }
726
0
        break;
727
0
    }
728
0
    case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: {
729
0
        const AVIAMFMixPresentation *mix_presentation = stg->params.iamf_mix_presentation;
730
0
        av_log(NULL, AV_LOG_INFO, " IAMF Mix Presentation:");
731
0
        dump_disposition(stg->disposition, AV_LOG_INFO);
732
0
        av_log(NULL, AV_LOG_INFO, "\n");
733
0
        dump_metadata(NULL, stg->metadata, "    ", AV_LOG_INFO);
734
0
        dump_dictionary(NULL, mix_presentation->annotations, "Annotations", "    ", AV_LOG_INFO);
735
0
        for (int j = 0; j < mix_presentation->nb_submixes; j++) {
736
0
            AVIAMFSubmix *sub_mix = mix_presentation->submixes[j];
737
0
            av_log(NULL, AV_LOG_INFO, "    Submix %d:\n", j);
738
0
            for (int k = 0; k < sub_mix->nb_elements; k++) {
739
0
                const AVIAMFSubmixElement *submix_element = sub_mix->elements[k];
740
0
                const AVStreamGroup *audio_element = NULL;
741
0
                for (int l = 0; l < ic->nb_stream_groups; l++)
742
0
                    if (ic->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
743
0
                        ic->stream_groups[l]->id   == submix_element->audio_element_id) {
744
0
                        audio_element = ic->stream_groups[l];
745
0
                        break;
746
0
                    }
747
0
                if (audio_element) {
748
0
                    av_log(NULL, AV_LOG_INFO, "      IAMF Audio Element #%d:%d",
749
0
                           index, audio_element->index);
750
0
                    if (flags & AVFMT_SHOW_IDS)
751
0
                        av_log(NULL, AV_LOG_INFO, "[0x%"PRIx64"]", audio_element->id);
752
0
                    av_log(NULL, AV_LOG_INFO, "\n");
753
0
                    dump_dictionary(NULL, submix_element->annotations, "Annotations", "        ", AV_LOG_INFO);
754
0
                }
755
0
            }
756
0
            for (int k = 0; k < sub_mix->nb_layouts; k++) {
757
0
                const AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[k];
758
0
                av_log(NULL, AV_LOG_INFO, "      Layout #%d:", k);
759
0
                if (submix_layout->layout_type == 2 ||
760
0
                    submix_layout->layout_type == 3) {
761
0
                    ret = av_channel_layout_describe(&submix_layout->sound_system, buf, sizeof(buf));
762
0
                    if (ret >= 0)
763
0
                        av_log(NULL, AV_LOG_INFO, " %s", buf);
764
0
                }
765
0
                av_log(NULL, AV_LOG_INFO, "\n");
766
0
            }
767
0
        }
768
0
        break;
769
0
    }
770
0
    case AV_STREAM_GROUP_PARAMS_TILE_GRID: {
771
0
        const AVStreamGroupTileGrid *tile_grid = stg->params.tile_grid;
772
0
        AVCodecContext *avctx = avcodec_alloc_context3(NULL);
773
0
        const char *ptr = NULL;
774
0
        av_log(NULL, AV_LOG_INFO, " Tile Grid:");
775
0
        if (avctx && stg->nb_streams && !avcodec_parameters_to_context(avctx, stg->streams[0]->codecpar)) {
776
0
            avctx->width  = tile_grid->width;
777
0
            avctx->height = tile_grid->height;
778
0
            avctx->coded_width  = tile_grid->coded_width;
779
0
            avctx->coded_height = tile_grid->coded_height;
780
0
            if (ic->dump_separator)
781
0
                av_opt_set(avctx, "dump_separator", ic->dump_separator, 0);
782
0
            buf[0] = 0;
783
0
            avcodec_string(buf, sizeof(buf), avctx, is_output);
784
0
            ptr = av_stristr(buf, " ");
785
0
        }
786
0
        avcodec_free_context(&avctx);
787
0
        if (ptr)
788
0
            av_log(NULL, AV_LOG_INFO, "%s", ptr);
789
0
        dump_disposition(stg->disposition, AV_LOG_INFO);
790
0
        av_log(NULL, AV_LOG_INFO, "\n");
791
0
        dump_metadata(NULL, stg->metadata, "    ", AV_LOG_INFO);
792
0
        dump_sidedata(NULL, tile_grid->coded_side_data, tile_grid->nb_coded_side_data,
793
0
                      tile_grid->width, tile_grid->height, (AVRational) {0,1},
794
0
                      "    ", AV_LOG_INFO);
795
0
        for (int i = 0; i < tile_grid->nb_tiles; i++) {
796
0
            const AVStream *st = NULL;
797
0
            if (tile_grid->offsets[i].idx < stg->nb_streams)
798
0
                st = stg->streams[tile_grid->offsets[i].idx];
799
0
            if (st && !printed[st->index]) {
800
0
                dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_VERBOSE);
801
0
                printed[st->index] = 1;
802
0
            }
803
0
        }
804
0
        for (int i = 0; i < stg->nb_streams; i++) {
805
0
            const AVStream *st = stg->streams[i];
806
0
            if (!printed[st->index]) {
807
0
                dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_INFO);
808
0
                printed[st->index] = 1;
809
0
            }
810
0
        }
811
0
        break;
812
0
    }
813
0
    case AV_STREAM_GROUP_PARAMS_LCEVC: {
814
0
        const AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
815
0
        AVCodecContext *avctx = avcodec_alloc_context3(NULL);
816
0
        const char *ptr = NULL;
817
0
        av_log(NULL, AV_LOG_INFO, " LCEVC:");
818
0
        if (avctx && stg->nb_streams && !avcodec_parameters_to_context(avctx, stg->streams[0]->codecpar)) {
819
0
            avctx->width  = lcevc->width;
820
0
            avctx->height = lcevc->height;
821
0
            avctx->coded_width  = lcevc->width;
822
0
            avctx->coded_height = lcevc->height;
823
0
            if (ic->dump_separator)
824
0
                av_opt_set(avctx, "dump_separator", ic->dump_separator, 0);
825
0
            buf[0] = 0;
826
0
            avcodec_string(buf, sizeof(buf), avctx, is_output);
827
0
            ptr = av_stristr(buf, " ");
828
0
        }
829
0
        avcodec_free_context(&avctx);
830
0
        if (ptr)
831
0
            av_log(NULL, AV_LOG_INFO, "%s", ptr);
832
0
        av_log(NULL, AV_LOG_INFO, "\n");
833
0
        for (int i = 0; i < stg->nb_streams; i++) {
834
0
            const AVStream *st = stg->streams[i];
835
0
            dump_stream_format(ic, st->index, i, index, is_output, AV_LOG_VERBOSE);
836
0
            printed[st->index] = 1;
837
0
        }
838
0
        break;
839
0
    }
840
0
    default:
841
0
        break;
842
0
    }
843
0
}
844
845
void av_dump_format(AVFormatContext *ic, int index,
846
                    const char *url, int is_output)
847
0
{
848
0
    int i;
849
0
    uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL;
850
0
    if (ic->nb_streams && !printed)
851
0
        return;
852
853
0
    av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
854
0
           is_output ? "Output" : "Input",
855
0
           index,
856
0
           is_output ? ic->oformat->name : ic->iformat->name,
857
0
           is_output ? "to" : "from", url);
858
0
    dump_metadata(NULL, ic->metadata, "  ", AV_LOG_INFO);
859
860
0
    if (!is_output) {
861
0
        av_log(NULL, AV_LOG_INFO, "  Duration: ");
862
0
        if (ic->duration != AV_NOPTS_VALUE) {
863
0
            int64_t hours, mins, secs, us;
864
0
            int64_t duration = ic->duration + (ic->duration <= INT64_MAX - 5000 ? 5000 : 0);
865
0
            secs  = duration / AV_TIME_BASE;
866
0
            us    = duration % AV_TIME_BASE;
867
0
            mins  = secs / 60;
868
0
            secs %= 60;
869
0
            hours = mins / 60;
870
0
            mins %= 60;
871
0
            av_log(NULL, AV_LOG_INFO, "%02"PRId64":%02"PRId64":%02"PRId64".%02"PRId64"", hours, mins, secs,
872
0
                   (100 * us) / AV_TIME_BASE);
873
0
        } else {
874
0
            av_log(NULL, AV_LOG_INFO, "N/A");
875
0
        }
876
0
        if (ic->start_time != AV_NOPTS_VALUE) {
877
0
            int secs, us;
878
0
            av_log(NULL, AV_LOG_INFO, ", start: ");
879
0
            secs = llabs(ic->start_time / AV_TIME_BASE);
880
0
            us   = llabs(ic->start_time % AV_TIME_BASE);
881
0
            av_log(NULL, AV_LOG_INFO, "%s%d.%06d",
882
0
                   ic->start_time >= 0 ? "" : "-",
883
0
                   secs,
884
0
                   (int) av_rescale(us, 1000000, AV_TIME_BASE));
885
0
        }
886
0
        av_log(NULL, AV_LOG_INFO, ", bitrate: ");
887
0
        if (ic->bit_rate)
888
0
            av_log(NULL, AV_LOG_INFO, "%"PRId64" kb/s", ic->bit_rate / 1000);
889
0
        else
890
0
            av_log(NULL, AV_LOG_INFO, "N/A");
891
0
        av_log(NULL, AV_LOG_INFO, "\n");
892
0
    }
893
894
0
    if (ic->nb_chapters)
895
0
        av_log(NULL, AV_LOG_INFO, "  Chapters:\n");
896
0
    for (i = 0; i < ic->nb_chapters; i++) {
897
0
        const AVChapter *ch = ic->chapters[i];
898
0
        av_log(NULL, AV_LOG_INFO, "    Chapter #%d:%d: ", index, i);
899
0
        av_log(NULL, AV_LOG_INFO,
900
0
               "start %f, ", ch->start * av_q2d(ch->time_base));
901
0
        av_log(NULL, AV_LOG_INFO,
902
0
               "end %f\n", ch->end * av_q2d(ch->time_base));
903
904
0
        dump_metadata(NULL, ch->metadata, "      ", AV_LOG_INFO);
905
0
    }
906
907
0
    if (ic->nb_programs) {
908
0
        int j, k, total = 0;
909
0
        for (j = 0; j < ic->nb_programs; j++) {
910
0
            const AVProgram *program = ic->programs[j];
911
0
            const AVDictionaryEntry *name = av_dict_get(program->metadata,
912
0
                                                        "name", NULL, 0);
913
0
            av_log(NULL, AV_LOG_INFO, "  Program %d %s\n", program->id,
914
0
                   name ? name->value : "");
915
0
            dump_metadata(NULL, program->metadata, "    ", AV_LOG_INFO);
916
0
            for (k = 0; k < program->nb_stream_indexes; k++) {
917
0
                dump_stream_format(ic, program->stream_index[k],
918
0
                                   -1, index, is_output, AV_LOG_INFO);
919
0
                printed[program->stream_index[k]] = 1;
920
0
            }
921
0
            total += program->nb_stream_indexes;
922
0
        }
923
0
        if (total < ic->nb_streams)
924
0
            av_log(NULL, AV_LOG_INFO, "  No Program\n");
925
0
    }
926
927
0
    for (i = 0; i < ic->nb_stream_groups; i++)
928
0
         dump_stream_group(ic, printed, i, index, is_output);
929
930
0
    for (i = 0; i < ic->nb_streams; i++)
931
0
        if (!printed[i])
932
0
            dump_stream_format(ic, i, -1, index, is_output, AV_LOG_INFO);
933
934
0
    av_free(printed);
935
0
}