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