/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 | } |