2 * Various pretty-printing functions for use within FFmpeg
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
5 * This file is part of FFmpeg.
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.
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.
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
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"
43 #include "libavcodec/avcodec.h"
48 #define HEXDUMP_PRINT(...) \
51 av_log(avcl, level, __VA_ARGS__); \
53 fprintf(f, __VA_ARGS__); \
56 static void hex_dump_internal(void *avcl
, FILE *f
, int level
,
57 const uint8_t *buf
, int size
)
61 for (i
= 0; i
< size
; i
+= 16) {
65 HEXDUMP_PRINT("%08x ", i
);
66 for (j
= 0; j
< 16; j
++) {
68 HEXDUMP_PRINT(" %02x", buf
[i
+ j
]);
73 for (j
= 0; j
< len
; j
++) {
75 if (c
< ' ' || c
> '~')
77 HEXDUMP_PRINT("%c", c
);
83 void av_hex_dump(FILE *f
, const uint8_t *buf
, int size
)
85 hex_dump_internal(NULL
, f
, 0, buf
, size
);
88 void av_hex_dump_log(void *avcl
, int level
, const uint8_t *buf
, int size
)
90 hex_dump_internal(avcl
, NULL
, level
, buf
, size
);
93 static void pkt_dump_internal(void *avcl
, FILE *f
, int level
, const AVPacket
*pkt
,
94 int dump_payload
, AVRational time_base
)
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");
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");
110 HEXDUMP_PRINT("%0.3f", pkt
->pts
* av_q2d(time_base
));
112 HEXDUMP_PRINT(" size=%d\n", pkt
->size
);
114 hex_dump_internal(avcl
, f
, level
, pkt
->data
, pkt
->size
);
117 void av_pkt_dump2(FILE *f
, const AVPacket
*pkt
, int dump_payload
, const AVStream
*st
)
119 pkt_dump_internal(NULL
, f
, 0, pkt
, dump_payload
, st
->time_base
);
122 void av_pkt_dump_log2(void *avcl
, int level
, const AVPacket
*pkt
, int dump_payload
,
125 pkt_dump_internal(avcl
, NULL
, level
, pkt
, dump_payload
, st
->time_base
);
129 static void print_fps(double d
, const char *postfix
, int log_level
)
131 uint64_t v
= lrintf(d
* 100);
133 av_log(NULL
, log_level
, "%1.4f %s", d
, postfix
);
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
);
139 av_log(NULL
, log_level
, "%1.0fk %s", d
/ 1000, postfix
);
142 static void dump_dictionary(void *ctx
, const AVDictionary
*m
,
143 const char *name
, const char *indent
,
146 const AVDictionaryEntry
*tag
= NULL
;
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
);
158 size_t len
= strcspn(p
, "\x8\xa\xb\xc\xd");
159 av_log(ctx
, log_level
, "%.*s", (int)(FFMIN(255, len
)), p
);
161 if (*p
== 0xd) av_log(ctx
, log_level
, " ");
162 if (*p
== 0xa) av_log(ctx
, log_level
, "\n%s %-16s: ", indent
, "");
165 av_log(ctx
, log_level
, "\n");
169 static void dump_metadata(void *ctx
, const AVDictionary
*m
, const char *indent
,
172 if (m
&& !(av_dict_count(m
) == 1 && av_dict_get(m
, "language", NULL
, 0)))
173 dump_dictionary(ctx
, m
, "Metadata", indent
, log_level
);
176 /* param change side data*/
177 static void dump_paramchange(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
180 const uint8_t *data
= sd
->data
;
181 uint32_t flags
, sample_rate
, width
, height
;
183 if (!data
|| sd
->size
< 4)
186 flags
= AV_RL32(data
);
190 if (flags
& AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE
) {
193 sample_rate
= AV_RL32(data
);
196 av_log(ctx
, log_level
, "sample_rate %"PRIu32
", ", sample_rate
);
198 if (flags
& AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS
) {
201 width
= AV_RL32(data
);
204 height
= AV_RL32(data
);
207 av_log(ctx
, log_level
, "width %"PRIu32
" height %"PRIu32
, width
, height
);
212 av_log(ctx
, AV_LOG_ERROR
, "unknown param\n");
215 /* replaygain side data*/
216 static void print_gain(void *ctx
, const char *str
, int32_t gain
, int log_level
)
218 av_log(ctx
, log_level
, "%s - ", str
);
219 if (gain
== INT32_MIN
)
220 av_log(ctx
, log_level
, "unknown");
222 av_log(ctx
, log_level
, "%f", gain
/ 100000.0f
);
223 av_log(ctx
, log_level
, ", ");
226 static void print_peak(void *ctx
, const char *str
, uint32_t peak
, int log_level
)
228 av_log(ctx
, log_level
, "%s - ", str
);
230 av_log(ctx
, log_level
, "unknown");
232 av_log(ctx
, log_level
, "%f", (float) peak
/ UINT32_MAX
);
233 av_log(ctx
, log_level
, ", ");
236 static void dump_replaygain(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
238 const AVReplayGain
*rg
;
240 if (sd
->size
< sizeof(*rg
)) {
241 av_log(ctx
, AV_LOG_ERROR
, "invalid data\n");
244 rg
= (const AVReplayGain
*)sd
->data
;
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
);
252 static void dump_stereo3d(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
254 const AVStereo3D
*stereo
;
256 if (sd
->size
< sizeof(*stereo
)) {
257 av_log(ctx
, AV_LOG_ERROR
, "invalid data\n");
261 stereo
= (const AVStereo3D
*)sd
->data
;
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
));
274 if (stereo
->flags
& AV_STEREO3D_FLAG_INVERT
)
275 av_log(ctx
, log_level
, " (inverted)");
278 static void dump_audioservicetype(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
280 const enum AVAudioServiceType
*ast
= (const enum AVAudioServiceType
*)sd
->data
;
282 if (sd
->size
< sizeof(*ast
)) {
283 av_log(ctx
, AV_LOG_ERROR
, "invalid data\n");
288 case AV_AUDIO_SERVICE_TYPE_MAIN
:
289 av_log(ctx
, log_level
, "main");
291 case AV_AUDIO_SERVICE_TYPE_EFFECTS
:
292 av_log(ctx
, log_level
, "effects");
294 case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED
:
295 av_log(ctx
, log_level
, "visually impaired");
297 case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED
:
298 av_log(ctx
, log_level
, "hearing impaired");
300 case AV_AUDIO_SERVICE_TYPE_DIALOGUE
:
301 av_log(ctx
, log_level
, "dialogue");
303 case AV_AUDIO_SERVICE_TYPE_COMMENTARY
:
304 av_log(ctx
, log_level
, "commentary");
306 case AV_AUDIO_SERVICE_TYPE_EMERGENCY
:
307 av_log(ctx
, log_level
, "emergency");
309 case AV_AUDIO_SERVICE_TYPE_VOICE_OVER
:
310 av_log(ctx
, log_level
, "voice over");
312 case AV_AUDIO_SERVICE_TYPE_KARAOKE
:
313 av_log(ctx
, log_level
, "karaoke");
316 av_log(ctx
, AV_LOG_WARNING
, "unknown");
321 static void dump_cpb(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
323 const AVCPBProperties
*cpb
= (const AVCPBProperties
*)sd
->data
;
325 if (sd
->size
< sizeof(*cpb
)) {
326 av_log(ctx
, AV_LOG_ERROR
, "invalid data\n");
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
,
334 if (cpb
->vbv_delay
== UINT64_MAX
)
335 av_log(ctx
, log_level
, "vbv_delay: N/A");
337 av_log(ctx
, log_level
, "vbv_delay: %"PRIu64
"", cpb
->vbv_delay
);
340 static void dump_mastering_display_metadata(void *ctx
, const AVPacketSideData
*sd
,
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
));
360 static void dump_content_light_metadata(void *ctx
, const AVPacketSideData
*sd
,
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
);
370 static void dump_ambient_viewing_environment_metadata(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
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
));
381 static void dump_spherical(void *ctx
, int w
, int h
,
382 const AVPacketSideData
*sd
, int log_level
)
384 const AVSphericalMapping
*spherical
= (const AVSphericalMapping
*)sd
->data
;
385 double yaw
, pitch
, roll
;
387 if (sd
->size
< sizeof(*spherical
)) {
388 av_log(ctx
, AV_LOG_ERROR
, "invalid data\n");
392 av_log(ctx
, log_level
, "%s ", av_spherical_projection_name(spherical
->projection
));
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
);
401 if (spherical
->projection
== AV_SPHERICAL_EQUIRECTANGULAR_TILE
) {
403 av_spherical_tile_bounds(spherical
, w
, h
,
405 av_log(ctx
, log_level
,
406 "[%"SIZE_SPECIFIER
", %"SIZE_SPECIFIER
", %"SIZE_SPECIFIER
", %"SIZE_SPECIFIER
"] ",
408 } else if (spherical
->projection
== AV_SPHERICAL_CUBEMAP
) {
409 av_log(ctx
, log_level
, "[pad %"PRIu32
"] ", spherical
->padding
);
413 static void dump_dovi_conf(void *ctx
, const AVPacketSideData
*sd
,
416 const AVDOVIDecoderConfigurationRecord
*dovi
=
417 (const AVDOVIDecoderConfigurationRecord
*)sd
->data
;
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, "
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
);
431 static void dump_s12m_timecode(void *ctx
, AVRational avg_frame_rate
, const AVPacketSideData
*sd
,
434 const uint32_t *tc
= (const uint32_t *)sd
->data
;
436 if ((sd
->size
!= sizeof(uint32_t) * 4) || (tc
[0] > 3)) {
437 av_log(ctx
, AV_LOG_ERROR
, "invalid data\n");
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] ? ", " : "");
448 static void dump_cropping(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
450 uint32_t top
, bottom
, left
, right
;
452 if (sd
->size
< sizeof(uint32_t) * 4) {
453 av_log(ctx
, log_level
, "invalid data\n");
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);
462 av_log(ctx
, log_level
, "%d/%d/%d/%d", left
, right
, top
, bottom
);
465 static void dump_tdrdi(void *ctx
, const AVPacketSideData
*sd
, int log_level
)
467 const AV3DReferenceDisplaysInfo
*tdrdi
=
468 (const AV3DReferenceDisplaysInfo
*)sd
->data
;
470 av_log(ctx
, log_level
, "number of reference displays: %u", tdrdi
->num_ref_displays
);
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
)
480 av_log(ctx
, log_level
, "%sSide data:\n", indent
);
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
);
486 av_log(ctx
, log_level
, "%s ", indent
);
488 av_log(ctx
, log_level
, "%s: ", name
);
490 case AV_PKT_DATA_PARAM_CHANGE
:
491 dump_paramchange(ctx
, sd
, log_level
);
493 case AV_PKT_DATA_REPLAYGAIN
:
494 dump_replaygain(ctx
, sd
, log_level
);
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
));
500 case AV_PKT_DATA_STEREO3D
:
501 dump_stereo3d(ctx
, sd
, log_level
);
503 case AV_PKT_DATA_AUDIO_SERVICE_TYPE
:
504 dump_audioservicetype(ctx
, sd
, log_level
);
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]));
510 case AV_PKT_DATA_CPB_PROPERTIES
:
511 dump_cpb(ctx
, sd
, log_level
);
513 case AV_PKT_DATA_MASTERING_DISPLAY_METADATA
:
514 dump_mastering_display_metadata(ctx
, sd
, log_level
);
516 case AV_PKT_DATA_SPHERICAL
:
517 dump_spherical(ctx
, w
, h
, sd
, log_level
);
519 case AV_PKT_DATA_CONTENT_LIGHT_LEVEL
:
520 dump_content_light_metadata(ctx
, sd
, log_level
);
522 case AV_PKT_DATA_DOVI_CONF
:
523 dump_dovi_conf(ctx
, sd
, log_level
);
525 case AV_PKT_DATA_S12M_TIMECODE
:
526 dump_s12m_timecode(ctx
, avg_frame_rate
, sd
, log_level
);
528 case AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
:
529 dump_ambient_viewing_environment_metadata(ctx
, sd
, log_level
);
531 case AV_PKT_DATA_FRAME_CROPPING
:
532 dump_cropping(ctx
, sd
, log_level
);
534 case AV_PKT_DATA_3D_REFERENCE_DISPLAYS
:
535 dump_tdrdi(ctx
, sd
, log_level
);
539 av_log(ctx
, log_level
,
540 "(%"SIZE_SPECIFIER
" bytes)", sd
->size
);
542 av_log(ctx
, log_level
, "unknown side data type %d "
543 "(%"SIZE_SPECIFIER
" bytes)", sd
->type
, sd
->size
);
547 av_log(ctx
, log_level
, "\n");
551 static void dump_disposition(int disposition
, int log_level
)
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)");
593 /* "user interface" functions */
594 static void dump_stream_format(const AVFormatContext
*ic
, int i
,
595 int group_index
, int index
, int is_output
,
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
;
609 avctx
= avcodec_alloc_context3(NULL
);
613 ret
= avcodec_parameters_to_context(avctx
, st
->codecpar
);
615 avcodec_free_context(&avctx
);
619 // Fields which are missing from AVCodecParameters need to be taken from the AVCodecContext
621 #if FF_API_CODEC_PROPS
622 FF_DISABLE_DEPRECATION_WARNINGS
623 avctx
->properties
= sti
->avctx
->properties
;
624 FF_ENABLE_DEPRECATION_WARNINGS
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
;
634 av_opt_set(avctx
, "dump_separator", separator
, 0);
635 avcodec_string(buf
, sizeof(buf
), avctx
, is_output
);
636 avcodec_free_context(&avctx
);
638 av_log(NULL
, log_level
, "%s Stream #%d", group_indent
, index
);
639 av_log(NULL
, log_level
, ":%d", i
);
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
);
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
);
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
,
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
);
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
;
668 if (fps
|| tbr
|| tbn
)
669 av_log(NULL
, log_level
, "%s", separator
);
672 print_fps(av_q2d(st
->avg_frame_rate
), tbr
|| tbn
? "fps, " : "fps", log_level
);
674 print_fps(av_q2d(st
->r_frame_rate
), tbn
? "tbr, " : "tbr", log_level
);
676 print_fps(1 / av_q2d(st
->time_base
), "tbn", log_level
);
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
);
684 dump_disposition(st
->disposition
, log_level
);
685 av_log(NULL
, log_level
, "\n");
687 dump_metadata(NULL
, st
->metadata
, extra_indent
, log_level
);
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
);
694 static void dump_stream_group(const AVFormatContext
*ic
, uint8_t *printed
,
695 int i
, int index
, int is_output
)
697 const AVStreamGroup
*stg
= ic
->stream_groups
[i
];
698 int flags
= (is_output
? ic
->oformat
->flags
: ic
->iformat
->flags
);
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
, ":");
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
));
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
;
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
];
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
);
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
));
766 av_log(NULL
, AV_LOG_INFO
, " %s", buf
);
768 av_log(NULL
, AV_LOG_INFO
, "\n");
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);
786 avcodec_string(buf
, sizeof(buf
), avctx
, is_output
);
787 ptr
= av_stristr(buf
, " ");
789 avcodec_free_context(&avctx
);
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},
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;
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;
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);
829 avcodec_string(buf
, sizeof(buf
), avctx
, is_output
);
830 ptr
= av_stristr(buf
, " ");
832 avcodec_free_context(&avctx
);
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;
848 void av_dump_format(AVFormatContext
*ic
, int index
,
849 const char *url
, int is_output
)
852 uint8_t *printed
= ic
->nb_streams
? av_mallocz(ic
->nb_streams
) : NULL
;
853 if (ic
->nb_streams
&& !printed
)
856 av_log(NULL
, AV_LOG_INFO
, "%s #%d, %s, %s '%s':\n",
857 is_output
? "Output" : "Input",
859 is_output
? ic
->oformat
->name
: ic
->iformat
->name
,
860 is_output
? "to" : "from", url
);
861 dump_metadata(NULL
, ic
->metadata
, " ", AV_LOG_INFO
);
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
;
874 av_log(NULL
, AV_LOG_INFO
, "%02"PRId64
":%02"PRId64
":%02"PRId64
".%02"PRId64
"", hours
, mins
, secs
,
875 (100 * us
) / AV_TIME_BASE
);
877 av_log(NULL
, AV_LOG_INFO
, "N/A");
879 if (ic
->start_time
!= AV_NOPTS_VALUE
) {
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 ? "" : "-",
887 (int) av_rescale(us
, 1000000, AV_TIME_BASE
));
889 av_log(NULL
, AV_LOG_INFO
, ", bitrate: ");
891 av_log(NULL
, AV_LOG_INFO
, "%"PRId64
" kb/s", ic
->bit_rate
/ 1000);
893 av_log(NULL
, AV_LOG_INFO
, "N/A");
894 av_log(NULL
, AV_LOG_INFO
, "\n");
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
));
907 dump_metadata(NULL
, ch
->metadata
, " ", AV_LOG_INFO
);
910 if (ic
->nb_programs
) {
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
,
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;
924 total
+= program
->nb_stream_indexes
;
926 if (total
< ic
->nb_streams
)
927 av_log(NULL
, AV_LOG_INFO
, " No Program\n");
930 for (i
= 0; i
< ic
->nb_stream_groups
; i
++)
931 dump_stream_group(ic
, printed
, i
, index
, is_output
);
933 for (i
= 0; i
< ic
->nb_streams
; i
++)
935 dump_stream_format(ic
, i
, -1, index
, is_output
, AV_LOG_INFO
);