Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2017-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / inspection filter
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/filters.h>
27 : #include <gpac/constants.h>
28 : #include <gpac/list.h>
29 : #include <gpac/xml.h>
30 : #include <gpac/internal/media_dev.h>
31 :
32 : typedef struct
33 : {
34 : GF_FilterPid *src_pid;
35 : FILE *tmp;
36 : u64 pck_num;
37 : u32 idx;
38 : u8 dump_pid; //0: no, 1: configure/reconfig, 2: info update
39 : u8 init_pid_config_done;
40 : u64 pck_for_config;
41 : u64 prev_dts, prev_cts, init_ts;
42 : u32 codec_id;
43 : u32 stream_type;
44 :
45 : #ifndef GPAC_DISABLE_AV_PARSERS
46 : HEVCState *hevc_state;
47 : AVCState *avc_state;
48 : VVCState *vvc_state;
49 : AV1State *av1_state;
50 : GF_M4VParser *mv124_state;
51 : GF_M4VDecSpecInfo dsi;
52 : #endif
53 : GF_VPConfig *vpcc;
54 :
55 : //for analyzing
56 : GF_BitStream *bs;
57 :
58 : Bool has_svcc;
59 : u32 nalu_size_length;
60 : Bool is_adobe_protected;
61 : Bool is_cenc_protected;
62 : Bool aborted;
63 :
64 : GF_Fraction tmcd_rate;
65 : u32 tmcd_flags;
66 : u32 tmcd_fpt;
67 :
68 : u32 csize;
69 : Bool buffer_done, no_analysis;
70 : } PidCtx;
71 :
72 : enum
73 : {
74 : INSPECT_MODE_PCK=0,
75 : INSPECT_MODE_BLOCK,
76 : INSPECT_MODE_REFRAME,
77 : INSPECT_MODE_RAW
78 : };
79 :
80 : enum
81 : {
82 : INSPECT_TEST_NO=0,
83 : INSPECT_TEST_NOPROP,
84 : INSPECT_TEST_NETWORK,
85 : INSPECT_TEST_NETX,
86 : INSPECT_TEST_ENCODE,
87 : INSPECT_TEST_ENCX,
88 : INSPECT_TEST_NOCRC,
89 : INSPECT_TEST_NOBR
90 : };
91 :
92 : enum
93 : {
94 : INSPECT_ANALYZE_OFF=0,
95 : INSPECT_ANALYZE_ON,
96 : INSPECT_ANALYZE_BS,
97 : INSPECT_ANALYZE_BS_BITS,
98 : };
99 :
100 : typedef struct
101 : {
102 : u32 mode;
103 : Bool interleave;
104 : Bool dump_data;
105 : Bool deep;
106 : char *log;
107 : char *fmt;
108 : u32 analyze;
109 : Bool props, hdr, allp, info, pcr, xml;
110 : Double speed, start;
111 : u32 test;
112 : GF_Fraction dur;
113 : Bool crc, dtype;
114 : Bool fftmcd;
115 : u32 buffer;
116 :
117 : FILE *dump;
118 :
119 : GF_List *src_pids;
120 :
121 : Bool is_prober, probe_done, hdr_done, dump_pck;
122 : Bool args_updated;
123 : Bool has_seen_eos;
124 : } GF_InspectCtx;
125 :
126 :
127 : GF_Err gf_bs_set_logger(GF_BitStream *bs, void (*on_bs_log)(void *udta, const char *field_name, u32 nb_bits, u64 field_val, s32 idx1, s32 idx2, s32 idx3), void *udta);
128 :
129 :
130 : #define DUMP_ATT_STR(_name, _val) if (ctx->xml) { \
131 : gf_fprintf(dump, " %s=\"%s\"", _name, _val); \
132 : } else { \
133 : gf_fprintf(dump, " %s %s", _name, _val); \
134 : }
135 :
136 : #define DUMP_ATT_LLU(_name, _val) if (ctx->xml) { \
137 : gf_fprintf(dump, " %s=\""LLU"\"", _name, _val);\
138 : } else {\
139 : gf_fprintf(dump, " %s "LLU, _name, _val);\
140 : }
141 :
142 : #define DUMP_ATT_U(_name, _val) if (ctx->xml) { \
143 : gf_fprintf(dump, " %s=\"%u\"", _name, _val);\
144 : } else {\
145 : gf_fprintf(dump, " %s %u", _name, _val);\
146 : }
147 :
148 : #define DUMP_ATT_D(_name, _val) if (ctx->xml) { \
149 : gf_fprintf(dump, " %s=\"%d\"", _name, _val);\
150 : } else {\
151 : gf_fprintf(dump, " %s %d", _name, _val);\
152 : }
153 :
154 : #define DUMP_ATT_X(_name, _val) if (ctx->xml) { \
155 : gf_fprintf(dump, " %s=\"0x%08X\"", _name, _val);\
156 : } else {\
157 : gf_fprintf(dump, " %s 0x%08X", _name, _val);\
158 : }
159 :
160 : #define DUMP_ATT_F(_name, _val) if (ctx->xml) { \
161 : gf_fprintf(dump, " %s=\"%f\"", _name, _val);\
162 : } else {\
163 : gf_fprintf(dump, " %s %f", _name, _val);\
164 : }
165 :
166 :
167 :
168 : #ifndef GPAC_DISABLE_AV_PARSERS
169 : static u32 inspect_get_nal_size(char *ptr, u32 nalh_size)
170 : {
171 : u32 nal_size=0;
172 : u32 v = nalh_size;
173 34750 : while (v) {
174 27800 : nal_size |= (u8) *ptr;
175 27800 : ptr++;
176 27800 : v-=1;
177 27800 : if (v) nal_size <<= 8;
178 : }
179 : return nal_size;
180 : }
181 :
182 1790 : static const char *get_sei_name(u32 sei_type, u32 is_hevc)
183 : {
184 1790 : switch (sei_type) {
185 : case 0: return "buffering_period";
186 502 : case 1: return "pic_timing";
187 0 : case 2: return "pan_scan_rect";
188 0 : case 3: return "filler_payload";
189 0 : case 4: return "itu_t_t35";
190 6 : case 5: return "user_data_unregistered";
191 0 : case 6: return "recovery_point";
192 0 : case 7: return "dec_ref_pic_marking_repetition";
193 0 : case 8: return "spare_pic";
194 0 : case 9: return "scene_info";
195 0 : case 10: return "sub_seq_info";
196 0 : case 11: return "sub_seq_layer_characteristics";
197 0 : case 12: return "sub_seq_characteristics";
198 0 : case 13: return "full_frame_freeze";
199 0 : case 14: return "full_frame_freeze_release";
200 0 : case 15: return "picture_snapshot";
201 0 : case 16: return "progressive_refinement_segment_start";
202 0 : case 17: return "progressive_refinement_segment_end";
203 0 : case 18: return "motion_constrained_slice_group_set";
204 0 : case 19: return "film_grain_characteristics";
205 0 : case 20: return "deblocking_filter_display_preference";
206 0 : case 21: return "stereo_video_info";
207 0 : case 22: return "post_filter_hint";
208 0 : case 23: return "tone_mapping_info";
209 :
210 12 : case 24: return "scalability_info";
211 0 : case 25: return "sub_pic_scalable_layer";
212 0 : case 26: return "non_required_layer_rep";
213 0 : case 27: return "priority_layer_info";
214 0 : case 28: return "layers_not_present";
215 0 : case 29: return "layer_dependency_change";
216 0 : case 30: return "scalable_nesting";
217 0 : case 31: return "base_layer_temporal_hrd";
218 0 : case 32: return "quality_layer_integrity_check";
219 0 : case 33: return "redundant_pic_property";
220 0 : case 34: return "tl0_dep_rep_index";
221 0 : case 35: return "tl_switching_point";
222 0 : case 36: return "parallel_decoding_info";
223 0 : case 37: return "mvc_scalable_nesting";
224 0 : case 38: return "view_scalability_info";
225 0 : case 39: return "multiview_scene_info";
226 0 : case 40: return "multiview_acquisition_info";
227 0 : case 41: return "non_required_view_component";
228 0 : case 42: return "view_dependency_change";
229 0 : case 43: return "operation_points_not_present";
230 0 : case 44: return "base_view_temporal_hrd";
231 0 : case 45: return "frame_packing_arrangement";
232 0 : case 47: return "display_orientation";
233 0 : case 56: return "green_metadata";
234 0 : case 128: return "structure_of_pictures_info";
235 1 : case 129: return "active_parameter_sets";
236 0 : case 130: return "decoding_unit_info";
237 0 : case 131: return "temporal_sub_layer_zero_index";
238 1256 : case 132: return "decoded_picture_hash";
239 0 : case 133: return "scalable_nesting";
240 0 : case 134: return "region_refresh_info";
241 0 : case 135: return "no_display";
242 0 : case 136: return "time_code";
243 0 : case 137: return "mastering_display_colour_volume";
244 0 : case 138: return "segmented_rect_frame_packing_arrangement";
245 0 : case 140: return "temporal_motion_constrained_tile_sets";
246 0 : case 141: return "knee_function_info";
247 0 : case 142: return "colour_remapping_info";
248 0 : case 143: return "deinterlaced_field_identification";
249 0 : case 144: return "content_light_level_info";
250 0 : case 145: return "dependent_rap_indication";
251 0 : case 146: return "coded_region_completion";
252 0 : case 147: return "alternative_transfer_characteristics";
253 0 : case 148: return "ambient_viewing_environment";
254 0 : case 160: return "layers_not_present";
255 0 : case 161: return "inter_layer_constrained_tile_sets";
256 0 : case 162: return "bsp_nesting";
257 0 : case 163: return "bsp_initial_arrival_time";
258 0 : case 164: return "sub_bitstream_property";
259 0 : case 165: return "alpha_channel_info";
260 0 : case 166: return "overlay_info";
261 0 : case 167: return "temporal_mv_prediction_constraints";
262 0 : case 168: return "frame_field_info";
263 0 : case 176: return "three_dimensional_reference_displays_info";
264 0 : case 177: return "depth_representation_info";
265 0 : case 178: return "multiview_scene_info";
266 0 : case 179: return "multiview_acquisition_info";
267 0 : case 180: return "multiview_view_position";
268 0 : case 181: return "alternative_depth_info";
269 : }
270 : return "Unknown";
271 : }
272 :
273 : typedef struct
274 : {
275 : FILE *dump;
276 : Bool dump_bits;
277 : } InspectLogCbk;
278 :
279 50475 : static void inspect_log_bs(Bool is_nalu, void *udta, const char *field_name, u32 nb_bits, u64 field_val, s32 idx1, s32 idx2, s32 idx3)
280 : {
281 : InspectLogCbk *cbk = (InspectLogCbk*)udta;
282 :
283 50475 : if (!nb_bits)
284 : return;
285 :
286 48215 : if (is_nalu)
287 2499 : gf_fprintf(cbk->dump, "\"");
288 :
289 48215 : gf_fprintf(cbk->dump, " %s", field_name);
290 48215 : if (idx1>=0) {
291 5750 : gf_fprintf(cbk->dump, "_%d", idx1);
292 5750 : if (idx2>=0) {
293 44 : gf_fprintf(cbk->dump, "_%d", idx2);
294 44 : if (idx3>=0) {
295 0 : gf_fprintf(cbk->dump, "_%d", idx3);
296 : }
297 : }
298 : }
299 48215 : gf_fprintf(cbk->dump, "=\""LLD, field_val);
300 48215 : if (cbk->dump_bits && ((s32) nb_bits > 1) )
301 27522 : gf_fprintf(cbk->dump, "(%u)", nb_bits);
302 :
303 48215 : if (!is_nalu)
304 45716 : gf_fprintf(cbk->dump, "\"");
305 : }
306 :
307 2499 : static void shifted_bs_log(void *udta, const char *field_name, u32 nb_bits, u64 field_val, s32 idx1, s32 idx2, s32 idx3)
308 : {
309 2499 : inspect_log_bs(GF_TRUE, udta, field_name, nb_bits, field_val, idx1, idx2, idx3);
310 2499 : }
311 47976 : static void regular_bs_log(void *udta, const char *field_name, u32 nb_bits, u64 field_val, s32 idx1, s32 idx2, s32 idx3)
312 : {
313 47976 : inspect_log_bs(GF_FALSE, udta, field_name, nb_bits, field_val, idx1, idx2, idx3);
314 47976 : }
315 :
316 :
317 1778 : static void dump_sei(FILE *dump, GF_BitStream *bs, Bool is_hevc)
318 : {
319 : u32 i;
320 1778 : gf_bs_enable_emulation_byte_removal(bs, GF_TRUE);
321 :
322 : //skip nal header
323 1778 : gf_bs_read_int(bs, is_hevc ? 16 : 8);
324 :
325 3568 : while (gf_bs_available(bs) ) {
326 : u32 sei_type = 0;
327 : u32 sei_size = 0;
328 1790 : while (gf_bs_peek_bits(bs, 8, 0) == 0xFF) {
329 0 : sei_type += 255;
330 0 : gf_bs_read_int(bs, 8);
331 : }
332 1790 : sei_type += gf_bs_read_int(bs, 8);
333 3583 : while (gf_bs_peek_bits(bs, 8, 0) == 0xFF) {
334 3 : sei_size += 255;
335 3 : gf_bs_read_int(bs, 8);
336 : }
337 1790 : sei_size += gf_bs_read_int(bs, 8);
338 : i=0;
339 46388 : while (i < sei_size) {
340 42808 : gf_bs_read_u8(bs);
341 42808 : i++;
342 : }
343 :
344 1790 : gf_fprintf(dump, " <SEIMessage ptype=\"%u\" psize=\"%u\" type=\"%s\"/>\n", sei_type, sei_size, get_sei_name(sei_type, is_hevc) );
345 1790 : if (gf_bs_peek_bits(bs, 8, 0) == 0x80) {
346 : break;
347 : }
348 : }
349 1778 : }
350 :
351 :
352 12529 : static void gf_inspect_dump_nalu_internal(FILE *dump, u8 *ptr, u32 ptr_size, Bool is_svc, HEVCState *hevc, AVCState *avc, VVCState *vvc, u32 nalh_size, Bool dump_crc, Bool is_encrypted, u32 full_bs_dump, PidCtx *pctx)
353 : {
354 : s32 res = 0;
355 : u8 type, nal_ref_idc;
356 : u8 dependency_id, quality_id, temporal_id;
357 : u8 track_ref_index;
358 : s8 sample_offset;
359 : u32 data_offset, data_size;
360 : s32 idx;
361 : InspectLogCbk lcbk;
362 : GF_BitStream *bs = NULL;
363 :
364 :
365 12529 : if (full_bs_dump<INSPECT_ANALYZE_BS)
366 : full_bs_dump = 0;
367 : else {
368 2723 : lcbk.dump = dump;
369 2723 : lcbk.dump_bits = full_bs_dump==INSPECT_ANALYZE_BS_BITS ? GF_TRUE : GF_FALSE;
370 : }
371 :
372 12529 : if (!ptr_size) {
373 0 : gf_fprintf(dump, "error=\"invalid nal size 0\"/>\n");
374 0 : return;
375 : }
376 :
377 12529 : if (dump_crc) gf_fprintf(dump, "crc=\"%u\" ", gf_crc_32(ptr, ptr_size) );
378 :
379 12529 : if (hevc) {
380 : #ifndef GPAC_DISABLE_HEVC
381 :
382 9126 : if (ptr_size==1) {
383 0 : gf_fprintf(dump, "error=\"invalid nal size 1\"/>\n");
384 0 : return;
385 : }
386 :
387 9126 : if (full_bs_dump) {
388 2545 : if (pctx) {
389 2545 : if (!pctx->bs)
390 0 : pctx->bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
391 : else
392 2545 : gf_bs_reassign_buffer(pctx->bs, ptr, ptr_size);
393 2545 : bs = pctx->bs;
394 : } else {
395 0 : bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
396 : }
397 2545 : gf_bs_set_logger(bs, regular_bs_log, &lcbk);
398 2545 : res = gf_hevc_parse_nalu_bs(bs, hevc, &type, &temporal_id, &quality_id);
399 : } else {
400 : bs = NULL;
401 6581 : res = gf_hevc_parse_nalu(ptr, ptr_size, hevc, &type, &temporal_id, &quality_id);
402 6581 : gf_fprintf(dump, "code=\"%d\"", type);
403 : }
404 :
405 9126 : if (res==-1) {
406 0 : gf_fprintf(dump, " status=\"error parsing\"", type);
407 : }
408 9126 : gf_fprintf(dump, " type=\"", type);
409 :
410 9126 : switch (type) {
411 0 : case GF_HEVC_NALU_SLICE_TRAIL_N:
412 0 : gf_fputs("TRAIL_N slice segment", dump);
413 0 : break;
414 6483 : case GF_HEVC_NALU_SLICE_TRAIL_R:
415 6483 : gf_fputs("TRAIL_R slice segment", dump);
416 6483 : break;
417 368 : case GF_HEVC_NALU_SLICE_TSA_N:
418 368 : gf_fputs("TSA_N slice segment", dump);
419 368 : break;
420 0 : case GF_HEVC_NALU_SLICE_TSA_R:
421 0 : gf_fputs("TSA_R slice segment", dump);
422 0 : break;
423 0 : case GF_HEVC_NALU_SLICE_STSA_N:
424 0 : gf_fputs("STSA_N slice segment", dump);
425 0 : break;
426 53 : case GF_HEVC_NALU_SLICE_STSA_R:
427 53 : gf_fputs("STSA_R slice segment", dump);
428 53 : break;
429 0 : case GF_HEVC_NALU_SLICE_RADL_N:
430 0 : gf_fputs("RADL_N slice segment", dump);
431 0 : break;
432 0 : case GF_HEVC_NALU_SLICE_RADL_R:
433 0 : gf_fputs("RADL_R slice segment", dump);
434 0 : break;
435 70 : case GF_HEVC_NALU_SLICE_RASL_N:
436 70 : gf_fputs("RASL_N slice segment", dump);
437 70 : break;
438 0 : case GF_HEVC_NALU_SLICE_RASL_R:
439 0 : gf_fputs("RASL_R slice segment", dump);
440 0 : break;
441 0 : case GF_HEVC_NALU_SLICE_BLA_W_LP:
442 0 : gf_fputs("Broken link access slice (W LP)", dump);
443 0 : break;
444 0 : case GF_HEVC_NALU_SLICE_BLA_W_DLP:
445 0 : gf_fputs("Broken link access slice (W DLP)", dump);
446 0 : break;
447 0 : case GF_HEVC_NALU_SLICE_BLA_N_LP:
448 0 : gf_fputs("Broken link access slice (N LP)", dump);
449 0 : break;
450 299 : case GF_HEVC_NALU_SLICE_IDR_W_DLP:
451 299 : gf_fputs("IDR slice (W DLP)", dump);
452 299 : break;
453 0 : case GF_HEVC_NALU_SLICE_IDR_N_LP:
454 0 : gf_fputs("IDR slice (N LP)", dump);
455 0 : break;
456 10 : case GF_HEVC_NALU_SLICE_CRA:
457 10 : gf_fputs("CRA slice", dump);
458 10 : break;
459 :
460 25 : case GF_HEVC_NALU_VID_PARAM:
461 25 : gf_fputs("Video Parameter Set", dump);
462 25 : if (full_bs_dump) break;
463 14 : idx = gf_hevc_read_vps(ptr, ptr_size, hevc);
464 14 : if (idx<0) gf_fprintf(dump, "\" vps_id=\"PARSING FAILURE");
465 14 : else gf_fprintf(dump, "\" vps_id=\"%d", idx);
466 : break;
467 26 : case GF_HEVC_NALU_SEQ_PARAM:
468 26 : gf_fputs("Sequence Parameter Set", dump);
469 26 : if (full_bs_dump) break;
470 15 : idx = gf_hevc_read_sps(ptr, ptr_size, hevc);
471 15 : if (idx<0) {
472 0 : gf_fprintf(dump, "\" sps_id=\"PARSING FAILURE");
473 0 : break;
474 : }
475 : {
476 : HEVC_SPS *sps= &hevc->sps[idx];
477 15 : gf_fprintf(dump, "\" sps_id=\"%d", idx);
478 15 : if (gf_sys_is_test_mode()) break;
479 :
480 0 : gf_fprintf(dump, "\" aspect_ratio_info_present_flag=\"%d", sps->aspect_ratio_info_present_flag);
481 0 : gf_fprintf(dump, "\" bit_depth_chroma=\"%d", sps->bit_depth_chroma);
482 0 : gf_fprintf(dump, "\" bit_depth_luma=\"%d", sps->bit_depth_luma);
483 0 : gf_fprintf(dump, "\" chroma_format_idc=\"%d", sps->chroma_format_idc);
484 0 : gf_fprintf(dump, "\" colour_description_present_flag=\"%d", sps->colour_description_present_flag);
485 0 : gf_fprintf(dump, "\" colour_primaries=\"%d", sps->colour_primaries);
486 0 : gf_fprintf(dump, "\" cw_flag=\"%d", sps->cw_flag);
487 0 : if (sps->cw_flag) {
488 0 : gf_fprintf(dump, "\" cw_bottom=\"%d", sps->cw_bottom);
489 0 : gf_fprintf(dump, "\" cw_top=\"%d", sps->cw_top);
490 0 : gf_fprintf(dump, "\" cw_left=\"%d", sps->cw_left);
491 0 : gf_fprintf(dump, "\" cw_right=\"%d", sps->cw_right);
492 : }
493 0 : gf_fprintf(dump, "\" height=\"%d", sps->height);
494 0 : gf_fprintf(dump, "\" width=\"%d", sps->width);
495 0 : gf_fprintf(dump, "\" log2_max_pic_order_cnt_lsb=\"%d", sps->log2_max_pic_order_cnt_lsb);
496 0 : gf_fprintf(dump, "\" long_term_ref_pics_present_flag=\"%d", sps->long_term_ref_pics_present_flag);
497 0 : gf_fprintf(dump, "\" matrix_coeffs=\"%d", sps->matrix_coeffs);
498 0 : gf_fprintf(dump, "\" max_CU_depth=\"%d", sps->max_CU_depth);
499 0 : gf_fprintf(dump, "\" max_CU_width=\"%d", sps->max_CU_width);
500 0 : gf_fprintf(dump, "\" max_CU_height=\"%d", sps->max_CU_height);
501 0 : gf_fprintf(dump, "\" num_long_term_ref_pic_sps=\"%d", sps->num_long_term_ref_pic_sps);
502 0 : gf_fprintf(dump, "\" num_short_term_ref_pic_sets=\"%d", sps->num_short_term_ref_pic_sets);
503 0 : gf_fprintf(dump, "\" has_timing_info=\"%d", sps->has_timing_info);
504 0 : if (sps->has_timing_info) {
505 0 : gf_fprintf(dump, "\" time_scale=\"%d", sps->time_scale);
506 0 : gf_fprintf(dump, "\" num_ticks_poc_diff_one_minus1=\"%d", sps->num_ticks_poc_diff_one_minus1);
507 0 : gf_fprintf(dump, "\" num_units_in_tick=\"%d", sps->num_units_in_tick);
508 0 : gf_fprintf(dump, "\" poc_proportional_to_timing_flag=\"%d", sps->poc_proportional_to_timing_flag);
509 : }
510 0 : gf_fprintf(dump, "\" rep_format_idx=\"%d", sps->rep_format_idx);
511 0 : gf_fprintf(dump, "\" sample_adaptive_offset_enabled_flag=\"%d", sps->sample_adaptive_offset_enabled_flag);
512 0 : gf_fprintf(dump, "\" sar_idc=\"%d", sps->sar_idc);
513 0 : gf_fprintf(dump, "\" separate_colour_plane_flag=\"%d", sps->separate_colour_plane_flag);
514 0 : gf_fprintf(dump, "\" temporal_mvp_enable_flag=\"%d", sps->temporal_mvp_enable_flag);
515 0 : gf_fprintf(dump, "\" transfer_characteristic=\"%d", sps->transfer_characteristic);
516 0 : gf_fprintf(dump, "\" video_full_range_flag=\"%d", sps->video_full_range_flag);
517 0 : gf_fprintf(dump, "\" sps_ext_or_max_sub_layers_minus1=\"%d", sps->sps_ext_or_max_sub_layers_minus1);
518 0 : gf_fprintf(dump, "\" max_sub_layers_minus1=\"%d", sps->max_sub_layers_minus1);
519 0 : gf_fprintf(dump, "\" update_rep_format_flag=\"%d", sps->update_rep_format_flag);
520 0 : gf_fprintf(dump, "\" sub_layer_ordering_info_present_flag=\"%d", sps->sub_layer_ordering_info_present_flag);
521 0 : gf_fprintf(dump, "\" scaling_list_enable_flag=\"%d", sps->scaling_list_enable_flag);
522 0 : gf_fprintf(dump, "\" infer_scaling_list_flag=\"%d", sps->infer_scaling_list_flag);
523 0 : gf_fprintf(dump, "\" scaling_list_ref_layer_id=\"%d", sps->scaling_list_ref_layer_id);
524 0 : gf_fprintf(dump, "\" scaling_list_data_present_flag=\"%d", sps->scaling_list_data_present_flag);
525 0 : gf_fprintf(dump, "\" asymmetric_motion_partitions_enabled_flag=\"%d", sps->asymmetric_motion_partitions_enabled_flag);
526 0 : gf_fprintf(dump, "\" pcm_enabled_flag=\"%d", sps->pcm_enabled_flag);
527 0 : gf_fprintf(dump, "\" strong_intra_smoothing_enable_flag=\"%d", sps->strong_intra_smoothing_enable_flag);
528 0 : gf_fprintf(dump, "\" vui_parameters_present_flag=\"%d", sps->vui_parameters_present_flag);
529 0 : gf_fprintf(dump, "\" log2_diff_max_min_luma_coding_block_size=\"%d", sps->log2_diff_max_min_luma_coding_block_size);
530 0 : gf_fprintf(dump, "\" log2_min_transform_block_size=\"%d", sps->log2_min_transform_block_size);
531 0 : gf_fprintf(dump, "\" log2_min_luma_coding_block_size=\"%d", sps->log2_min_luma_coding_block_size);
532 0 : gf_fprintf(dump, "\" log2_max_transform_block_size=\"%d", sps->log2_max_transform_block_size);
533 0 : gf_fprintf(dump, "\" max_transform_hierarchy_depth_inter=\"%d", sps->max_transform_hierarchy_depth_inter);
534 0 : gf_fprintf(dump, "\" max_transform_hierarchy_depth_intra=\"%d", sps->max_transform_hierarchy_depth_intra);
535 0 : gf_fprintf(dump, "\" pcm_sample_bit_depth_luma_minus1=\"%d", sps->pcm_sample_bit_depth_luma_minus1);
536 0 : gf_fprintf(dump, "\" pcm_sample_bit_depth_chroma_minus1=\"%d", sps->pcm_sample_bit_depth_chroma_minus1);
537 0 : gf_fprintf(dump, "\" pcm_loop_filter_disable_flag=\"%d", sps->pcm_loop_filter_disable_flag);
538 0 : gf_fprintf(dump, "\" log2_min_pcm_luma_coding_block_size_minus3=\"%d", sps->log2_min_pcm_luma_coding_block_size_minus3);
539 0 : gf_fprintf(dump, "\" log2_diff_max_min_pcm_luma_coding_block_size=\"%d", sps->log2_diff_max_min_pcm_luma_coding_block_size);
540 0 : gf_fprintf(dump, "\" overscan_info_present=\"%d", sps->overscan_info_present);
541 0 : gf_fprintf(dump, "\" overscan_appropriate=\"%d", sps->overscan_appropriate);
542 0 : gf_fprintf(dump, "\" video_signal_type_present_flag=\"%d", sps->video_signal_type_present_flag);
543 0 : gf_fprintf(dump, "\" video_format=\"%d", sps->video_format);
544 0 : gf_fprintf(dump, "\" chroma_loc_info_present_flag=\"%d", sps->chroma_loc_info_present_flag);
545 0 : gf_fprintf(dump, "\" chroma_sample_loc_type_top_field=\"%d", sps->chroma_sample_loc_type_top_field);
546 0 : gf_fprintf(dump, "\" chroma_sample_loc_type_bottom_field=\"%d", sps->chroma_sample_loc_type_bottom_field);
547 0 : gf_fprintf(dump, "\" neutra_chroma_indication_flag=\"%d", sps->neutra_chroma_indication_flag);
548 0 : gf_fprintf(dump, "\" field_seq_flag=\"%d", sps->field_seq_flag);
549 0 : gf_fprintf(dump, "\" frame_field_info_present_flag=\"%d", sps->frame_field_info_present_flag);
550 0 : gf_fprintf(dump, "\" default_display_window_flag=\"%d", sps->default_display_window_flag);
551 0 : gf_fprintf(dump, "\" left_offset=\"%d", sps->left_offset);
552 0 : gf_fprintf(dump, "\" right_offset=\"%d", sps->right_offset);
553 0 : gf_fprintf(dump, "\" top_offset=\"%d", sps->top_offset);
554 0 : gf_fprintf(dump, "\" bottom_offset=\"%d", sps->bottom_offset);
555 0 : gf_fprintf(dump, "\" hrd_parameters_present_flag=\"%d", sps->hrd_parameters_present_flag);
556 : }
557 0 : break;
558 26 : case GF_HEVC_NALU_PIC_PARAM:
559 26 : gf_fputs("Picture Parameter Set", dump);
560 26 : if (full_bs_dump) break;
561 15 : idx = gf_hevc_read_pps(ptr, ptr_size, hevc);
562 15 : if (idx<0) {
563 0 : gf_fprintf(dump, "\" pps_id=\"PARSING FAILURE");
564 0 : break;
565 : }
566 : {
567 : HEVC_PPS *pps= &hevc->pps[idx];
568 15 : gf_fprintf(dump, "\" pps_id=\"%d", idx);
569 :
570 15 : if (gf_sys_is_test_mode()) break;
571 :
572 0 : gf_fprintf(dump, "\" cabac_init_present_flag=\"%d", pps->cabac_init_present_flag);
573 0 : gf_fprintf(dump, "\" dependent_slice_segments_enabled_flag=\"%d", pps->dependent_slice_segments_enabled_flag);
574 0 : gf_fprintf(dump, "\" entropy_coding_sync_enabled_flag=\"%d", pps->entropy_coding_sync_enabled_flag);
575 0 : gf_fprintf(dump, "\" lists_modification_present_flag=\"%d", pps->lists_modification_present_flag);
576 0 : gf_fprintf(dump, "\" loop_filter_across_slices_enabled_flag=\"%d", pps->loop_filter_across_slices_enabled_flag);
577 0 : gf_fprintf(dump, "\" loop_filter_across_tiles_enabled_flag=\"%d", pps->loop_filter_across_tiles_enabled_flag);
578 0 : gf_fprintf(dump, "\" num_extra_slice_header_bits=\"%d", pps->num_extra_slice_header_bits);
579 0 : gf_fprintf(dump, "\" num_ref_idx_l0_default_active=\"%d", pps->num_ref_idx_l0_default_active);
580 0 : gf_fprintf(dump, "\" num_ref_idx_l1_default_active=\"%d", pps->num_ref_idx_l1_default_active);
581 0 : gf_fprintf(dump, "\" tiles_enabled_flag=\"%d", pps->tiles_enabled_flag);
582 0 : if (pps->tiles_enabled_flag) {
583 0 : gf_fprintf(dump, "\" uniform_spacing_flag=\"%d", pps->uniform_spacing_flag);
584 0 : if (!pps->uniform_spacing_flag) {
585 : u32 k;
586 0 : gf_fprintf(dump, "\" num_tile_columns=\"%d", pps->num_tile_columns);
587 0 : gf_fprintf(dump, "\" num_tile_rows=\"%d", pps->num_tile_rows);
588 0 : gf_fprintf(dump, "\" colomns_width=\"");
589 0 : for (k=0; k<pps->num_tile_columns-1; k++)
590 0 : gf_fprintf(dump, "%d ", pps->column_width[k]);
591 0 : gf_fprintf(dump, "\" rows_height=\"");
592 0 : for (k=0; k<pps->num_tile_rows-1; k++)
593 0 : gf_fprintf(dump, "%d ", pps->row_height[k]);
594 : }
595 : }
596 0 : gf_fprintf(dump, "\" output_flag_present_flag=\"%d", pps->output_flag_present_flag);
597 0 : gf_fprintf(dump, "\" pic_init_qp_minus26=\"%d", pps->pic_init_qp_minus26);
598 0 : gf_fprintf(dump, "\" slice_chroma_qp_offsets_present_flag=\"%d", pps->slice_chroma_qp_offsets_present_flag);
599 0 : gf_fprintf(dump, "\" slice_segment_header_extension_present_flag=\"%d", pps->slice_segment_header_extension_present_flag);
600 0 : gf_fprintf(dump, "\" weighted_pred_flag=\"%d", pps->weighted_pred_flag);
601 0 : gf_fprintf(dump, "\" weighted_bipred_flag=\"%d", pps->weighted_bipred_flag);
602 :
603 0 : gf_fprintf(dump, "\" sign_data_hiding_flag=\"%d", pps->sign_data_hiding_flag);
604 0 : gf_fprintf(dump, "\" constrained_intra_pred_flag=\"%d", pps->constrained_intra_pred_flag);
605 0 : gf_fprintf(dump, "\" transform_skip_enabled_flag=\"%d", pps->transform_skip_enabled_flag);
606 0 : gf_fprintf(dump, "\" cu_qp_delta_enabled_flag=\"%d", pps->cu_qp_delta_enabled_flag);
607 0 : if (pps->cu_qp_delta_enabled_flag)
608 0 : gf_fprintf(dump, "\" diff_cu_qp_delta_depth=\"%d", pps->diff_cu_qp_delta_depth);
609 0 : gf_fprintf(dump, "\" transquant_bypass_enable_flag=\"%d", pps->transquant_bypass_enable_flag);
610 0 : gf_fprintf(dump, "\" pic_cb_qp_offset=\"%d", pps->pic_cb_qp_offset);
611 0 : gf_fprintf(dump, "\" pic_cr_qp_offset=\"%d", pps->pic_cr_qp_offset);
612 :
613 0 : gf_fprintf(dump, "\" deblocking_filter_control_present_flag=\"%d", pps->deblocking_filter_control_present_flag);
614 0 : if (pps->deblocking_filter_control_present_flag) {
615 0 : gf_fprintf(dump, "\" deblocking_filter_override_enabled_flag=\"%d", pps->deblocking_filter_override_enabled_flag);
616 0 : gf_fprintf(dump, "\" pic_disable_deblocking_filter_flag=\"%d", pps->pic_disable_deblocking_filter_flag);
617 0 : gf_fprintf(dump, "\" beta_offset_div2=\"%d", pps->beta_offset_div2);
618 0 : gf_fprintf(dump, "\" tc_offset_div2=\"%d", pps->tc_offset_div2);
619 : }
620 0 : gf_fprintf(dump, "\" pic_scaling_list_data_present_flag=\"%d", pps->pic_scaling_list_data_present_flag);
621 0 : gf_fprintf(dump, "\" log2_parallel_merge_level_minus2=\"%d", pps->log2_parallel_merge_level_minus2);
622 : }
623 0 : break;
624 1 : case GF_HEVC_NALU_ACCESS_UNIT:
625 1 : gf_fputs("AU Delimiter", dump);
626 1 : gf_fprintf(dump, "\" primary_pic_type=\"%d", ptr[2] >> 5);
627 1 : break;
628 0 : case GF_HEVC_NALU_END_OF_SEQ:
629 0 : gf_fputs("End of Sequence", dump);
630 0 : break;
631 0 : case GF_HEVC_NALU_END_OF_STREAM:
632 0 : gf_fputs("End of Stream", dump);
633 0 : break;
634 0 : case GF_HEVC_NALU_FILLER_DATA:
635 0 : gf_fputs("Filler Data", dump);
636 0 : break;
637 6 : case GF_HEVC_NALU_SEI_PREFIX:
638 6 : gf_fputs("SEI Prefix", dump);
639 6 : break;
640 1256 : case GF_HEVC_NALU_SEI_SUFFIX:
641 1256 : gf_fputs("SEI Suffix", dump);
642 1256 : break;
643 0 : case 48:
644 0 : gf_fputs("HEVCAggregator", dump);
645 0 : break;
646 502 : case 49:
647 : {
648 502 : u32 remain = ptr_size-2;
649 502 : char *s = ptr+2;
650 :
651 502 : gf_fputs("HEVCExtractor ", dump);
652 :
653 1506 : while (remain) {
654 502 : u32 mode = s[0];
655 502 : remain -= 1;
656 502 : s += 1;
657 502 : if (mode) {
658 0 : u32 len = s[0];
659 0 : if (len+1>remain) {
660 0 : gf_fprintf(dump, "error=\"invalid inband data extractor size: %d vs %d remaining\"/>\n", len, remain);
661 0 : return;
662 : }
663 0 : remain -= len+1;
664 0 : s += len+1;
665 0 : gf_fprintf(dump, "\" inband_size=\"%d", len);
666 : } else {
667 502 : if (remain < 2 + 2*nalh_size) {
668 0 : gf_fprintf(dump, "error=\"invalid ref data extractor size: %d vs %d remaining\"/>\n", 2 + 2*nalh_size, remain);
669 0 : return;
670 : }
671 502 : track_ref_index = (u8) s[0];
672 502 : sample_offset = (s8) s[1];
673 502 : data_offset = inspect_get_nal_size(&s[2], nalh_size);
674 502 : data_size = inspect_get_nal_size(&s[2+nalh_size], nalh_size);
675 502 : gf_fprintf(dump, "\" track_ref_index=\"%d\" sample_offset=\"%d\" data_offset=\"%d\" data_size=\"%d", track_ref_index, sample_offset, data_offset, data_size);
676 :
677 502 : remain -= 2 + 2*nalh_size;
678 502 : s += 2 + 2*nalh_size;
679 : }
680 : }
681 : }
682 : break;
683 1 : default:
684 1 : gf_fprintf(dump, "UNKNOWN (parsing return %d)", res);
685 1 : break;
686 : }
687 9189 : gf_fputs("\"", dump);
688 :
689 9126 : if (!full_bs_dump && (type < GF_HEVC_NALU_VID_PARAM)) {
690 5023 : gf_fprintf(dump, " slice=\"%s\" poc=\"%d\"", (hevc->s_info.slice_type==GF_HEVC_SLICE_TYPE_I) ? "I" : (hevc->s_info.slice_type==GF_HEVC_SLICE_TYPE_P) ? "P" : (hevc->s_info.slice_type==GF_HEVC_SLICE_TYPE_B) ? "B" : "Unknown", hevc->s_info.poc);
691 5023 : gf_fprintf(dump, " first_slice_in_pic=\"%d\"", hevc->s_info.first_slice_segment_in_pic_flag);
692 5023 : gf_fprintf(dump, " dependent_slice_segment=\"%d\"", hevc->s_info.dependent_slice_segment_flag);
693 :
694 5023 : if (!gf_sys_is_test_mode()) {
695 0 : gf_fprintf(dump, " redundant_pic_cnt=\"%d\"", hevc->s_info.redundant_pic_cnt);
696 0 : gf_fprintf(dump, " slice_qp_delta=\"%d\"", hevc->s_info.slice_qp_delta);
697 0 : gf_fprintf(dump, " slice_segment_address=\"%d\"", hevc->s_info.slice_segment_address);
698 0 : gf_fprintf(dump, " slice_type=\"%d\"", hevc->s_info.slice_type);
699 : }
700 : }
701 9126 : if (!full_bs_dump)
702 6581 : gf_fprintf(dump, " layer_id=\"%d\" temporal_id=\"%d\"", quality_id, temporal_id);
703 :
704 9126 : if (bs) {
705 2545 : if (!pctx)
706 0 : gf_bs_del(bs);
707 : else
708 2545 : gf_bs_set_logger(bs, NULL, NULL);
709 : }
710 :
711 9126 : if ((type == GF_HEVC_NALU_SEI_PREFIX) || (type == GF_HEVC_NALU_SEI_SUFFIX)) {
712 1262 : gf_fprintf(dump, ">\n");
713 1262 : if (pctx) {
714 504 : if (!pctx->bs)
715 0 : pctx->bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
716 : else
717 504 : gf_bs_reassign_buffer(pctx->bs, ptr, ptr_size);
718 504 : bs = pctx->bs;
719 : } else {
720 758 : bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
721 : }
722 1262 : dump_sei(dump, bs, GF_TRUE);
723 1262 : if (!pctx) gf_bs_del(bs);
724 1262 : gf_fprintf(dump, " </NALU>\n");
725 : } else {
726 7864 : gf_fprintf(dump, "/>\n");
727 : }
728 :
729 : #else
730 : gf_fprintf(dump, "/>\n");
731 : #endif //GPAC_DISABLE_HEVC
732 : return;
733 : }
734 :
735 3403 : if (vvc) {
736 : u8 lid, tid;
737 :
738 0 : if (full_bs_dump) {
739 0 : if (pctx) {
740 0 : if (!pctx->bs)
741 0 : pctx->bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
742 : else
743 0 : gf_bs_reassign_buffer(pctx->bs, ptr, ptr_size);
744 0 : bs = pctx->bs;
745 : } else {
746 0 : bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
747 : }
748 0 : gf_bs_set_logger(bs, regular_bs_log, &lcbk);
749 0 : res = gf_media_vvc_parse_nalu_bs(bs, vvc, &type, &lid, &tid);
750 : } else {
751 : bs = NULL;
752 0 : u32 forb_zero = (ptr[0] & 0x80) ? 1 : 0;
753 0 : u32 res_zero = (ptr[0] & 0x40) ? 1 : 0;
754 0 : lid = (ptr[0] & 0x3F);
755 0 : tid = (ptr[1] & 0x7);
756 0 : if (forb_zero || res_zero || !tid) {
757 0 : gf_fprintf(dump, "error=\"invalid header (forb %d res_zero %d tid %d)\"/>\n", forb_zero, res_zero, tid);
758 0 : return;
759 : }
760 0 : tid -= 1;
761 0 : type = ptr[1]>>3;
762 :
763 0 : res = gf_media_vvc_parse_nalu(ptr, ptr_size, vvc, &type, &lid, &tid);
764 0 : gf_fprintf(dump, "code=\"%d\" temporalid=\"%d\" layerid=\"%d\"", type, tid, lid);
765 : }
766 0 : if (res==-1) {
767 0 : gf_fprintf(dump, " status=\"error parsing\"", type);
768 : }
769 :
770 0 : gf_fprintf(dump, " type=\"");
771 0 : switch (type) {
772 0 : case GF_VVC_NALU_SLICE_TRAIL:
773 0 : gf_fprintf(dump, "Slice_TRAIL");
774 0 : break;
775 0 : case GF_VVC_NALU_SLICE_STSA:
776 0 : gf_fprintf(dump, "Slice_STSA");
777 0 : break;
778 0 : case GF_VVC_NALU_SLICE_RADL:
779 0 : gf_fprintf(dump, "Slice_RADL");
780 0 : break;
781 0 : case GF_VVC_NALU_SLICE_RASL:
782 0 : gf_fprintf(dump, "Slice_RASL");
783 0 : break;
784 0 : case GF_VVC_NALU_SLICE_IDR_W_RADL:
785 0 : gf_fprintf(dump, "IDR_RADL");
786 0 : break;
787 0 : case GF_VVC_NALU_SLICE_IDR_N_LP:
788 0 : gf_fprintf(dump, "IDR");
789 0 : break;
790 0 : case GF_VVC_NALU_SLICE_CRA:
791 0 : gf_fprintf(dump, "CRA");
792 0 : break;
793 0 : case GF_VVC_NALU_SLICE_GDR:
794 0 : gf_fprintf(dump, "GDR");
795 0 : break;
796 0 : case GF_VVC_NALU_OPI:
797 0 : gf_fprintf(dump, "OperationPointInfo");
798 0 : break;
799 0 : case GF_VVC_NALU_DEC_PARAM:
800 0 : gf_fprintf(dump, "DecodeParameterSet");
801 0 : break;
802 0 : case GF_VVC_NALU_VID_PARAM:
803 0 : gf_fprintf(dump, "VideoParameterSet");
804 0 : if ((res>=0) && !full_bs_dump) {
805 : u32 j;
806 0 : VVC_VPS *vps = &vvc->vps[vvc->last_parsed_vps_id];
807 0 : gf_fprintf(dump, "\" id=\"%d\" num_ptl=\"%d\" max_layers=\"%d\" max_sublayers=\"%d", vps->id, vps->num_ptl, vps->max_layers, vps->max_sub_layers);
808 0 : if (vps->max_layers>1) {
809 0 : gf_fprintf(dump, "\" max_layer_id=\"%d\" all_layers_independent=\"%d\" each_layer_is_ols=\"%d", vps->max_layer_id, vps->all_layers_independent, vps->each_layer_is_ols);
810 : }
811 0 : for (j=0; j<vps->num_ptl; j++) {
812 : VVC_ProfileTierLevel *ptl = &vps->ptl[j];
813 0 : gf_fprintf(dump, "\" general_level_idc=\"%d\" frame_only_constraint=\"%d\" multilayer_enabled=\"%d\" max_tid=\"%d", ptl->general_level_idc, ptl->frame_only_constraint, ptl->multilayer_enabled, ptl->ptl_max_tid);
814 :
815 0 : if (ptl->pt_present) {
816 0 : gf_fprintf(dump, "\" general_profile_idc=\"%d\" general_tier_flag=\"%d\" gci_present=\"%d", ptl->general_profile_idc, ptl->general_tier_flag, ptl->gci_present);
817 : }
818 : }
819 : }
820 : res = -2;
821 : break;
822 0 : case GF_VVC_NALU_SEQ_PARAM:
823 0 : gf_fprintf(dump, "SequenceParameterSet");
824 0 : if ((res>=0) && !full_bs_dump) {
825 0 : VVC_SPS *sps = &vvc->sps[vvc->last_parsed_sps_id];
826 :
827 0 : gf_fprintf(dump, "\" id=\"%d\" vps_id=\"%d\" max_sublayers=\"%d\" chroma_idc=\"%d\" bit_depth=\"%d\" CTBsizeY=\"%d\" gdr_enabled=\"%d\" ref_pic_sampling=\"%d\" subpic_info_present=\"%d\" poc_msb_cycle_flag=\"%d", sps->id, sps->vps_id, sps->max_sublayers, sps->chroma_format_idc, sps->bitdepth, 1<<sps->log2_ctu_size, sps->gdr_enabled, sps->ref_pic_resampling, sps->subpic_info_present, sps->poc_msb_cycle_flag);
828 0 : if (sps->ref_pic_resampling) {
829 0 : gf_fprintf(dump, "\" res_change_in_clvs=\"%d", sps->res_change_in_clvs);
830 : }
831 0 : gf_fprintf(dump, "\" width=\"%d\" height=\"%d", sps->width, sps->height);
832 0 : if (!sps->vps_id) {
833 : VVC_ProfileTierLevel *ptl = &vvc->vps[0].ptl[0];
834 0 : gf_fprintf(dump, "\" general_level_idc=\"%d\" frame_only_constraint=\"%d\" multilayer_enabled=\"%d\" max_tid=\"%d", ptl->general_level_idc, ptl->frame_only_constraint, ptl->multilayer_enabled, ptl->ptl_max_tid);
835 :
836 0 : if (ptl->pt_present) {
837 0 : gf_fprintf(dump, "\" general_profile_idc=\"%d\" general_tier_flag=\"%d\" gci_present=\"%d", ptl->general_profile_idc, ptl->general_tier_flag, ptl->gci_present);
838 : }
839 : }
840 0 : gf_fprintf(dump, "\" conf_window=\"%d", sps->conf_window);
841 0 : if (sps->conf_window) {
842 0 : gf_fprintf(dump, "\" cw_left=\"%d\" cw_right=\"%d\" cw_top=\"%d\" cw_bottom=\"%d", sps->cw_left, sps->cw_right, sps->cw_top, sps->cw_bottom);
843 : }
844 : }
845 : res=-2;
846 : break;
847 0 : case GF_VVC_NALU_PIC_PARAM:
848 0 : gf_fprintf(dump, "PictureParameterSet");
849 0 : if ((res>=0) && !full_bs_dump) {
850 0 : VVC_PPS *pps = &vvc->pps[vvc->last_parsed_pps_id];
851 0 : gf_fprintf(dump, "\" id=\"%d\" sps_id=\"%d\" width=\"%d\" height=\"%d\" mixed_nal_types=\"%d\" conf_window=\"%d", pps->id, pps->sps_id, pps->width, pps->height, pps->mixed_nal_types, pps->conf_window);
852 :
853 0 : if (pps->conf_window) {
854 0 : gf_fprintf(dump, "\" cw_left=\"%d\" cw_right=\"%d\" cw_top=\"%d\" cw_bottom=\"%d", pps->cw_left, pps->cw_right, pps->cw_top, pps->cw_bottom);
855 : }
856 0 : gf_fprintf(dump, "\" output_flag_present_flag=\"%d\" no_pic_partition_flag=\"%d\" subpic_id_mapping_present_flag=\"%d", pps->output_flag_present_flag, pps->no_pic_partition_flag, pps->subpic_id_mapping_present_flag);
857 : }
858 : res=-2;
859 : break;
860 0 : case GF_VVC_NALU_APS_PREFIX:
861 0 : gf_fprintf(dump, "AdaptationParameterSet_Prefix");
862 : res=-2;
863 0 : break;
864 0 : case GF_VVC_NALU_APS_SUFFIX:
865 0 : gf_fprintf(dump, "AdaptationParameterSet_Suffix");
866 : res=-2;
867 0 : break;
868 0 : case GF_VVC_NALU_ACCESS_UNIT:
869 0 : gf_fprintf(dump, "AUDelimiter");
870 : res=-2;
871 0 : break;
872 0 : case GF_VVC_NALU_END_OF_SEQ:
873 0 : gf_fprintf(dump, "EOS");
874 : res=-2;
875 0 : break;
876 0 : case GF_VVC_NALU_END_OF_STREAM:
877 0 : gf_fprintf(dump, "EOB");
878 : res=-2;
879 0 : break;
880 0 : case GF_VVC_NALU_FILLER_DATA:
881 0 : gf_fprintf(dump, "FillerData");
882 : res=-2;
883 0 : break;
884 0 : case GF_VVC_NALU_SEI_PREFIX:
885 0 : gf_fprintf(dump, "SEI_Prefix");
886 : res=-2;
887 0 : break;
888 0 : case GF_VVC_NALU_SEI_SUFFIX:
889 0 : gf_fprintf(dump, "SEI_Suffix");
890 : res=-2;
891 0 : break;
892 0 : case GF_VVC_NALU_PIC_HEADER:
893 0 : gf_fprintf(dump, "PictureHeader");
894 0 : break;
895 0 : default:
896 0 : gf_fprintf(dump, "Unknwon");
897 : res = -2;
898 0 : break;
899 : }
900 0 : gf_fprintf(dump, "\"");
901 :
902 : //picture header or slice
903 0 : if ((res>=0) && !full_bs_dump) {
904 0 : if (type!=GF_VVC_NALU_PIC_HEADER)
905 0 : gf_fprintf(dump, " picture_header_in_slice_header_flag=\"%d\"", vvc->s_info.picture_header_in_slice_header_flag);
906 :
907 0 : if ((type==GF_VVC_NALU_PIC_HEADER) || vvc->s_info.picture_header_in_slice_header_flag) {
908 0 : gf_fprintf(dump, " pps_id=\"%d\" poc=\"%d\" irap_or_gdr_pic=\"%d\" non_ref_pic=\"%d\" inter_slice_allowed_flag=\"%d\" poc_lsb=\"%d\"", vvc->s_info.pps->id, vvc->s_info.poc, vvc->s_info.irap_or_gdr_pic, vvc->s_info.non_ref_pic, vvc->s_info.inter_slice_allowed_flag, vvc->s_info.poc_lsb);
909 0 : if (vvc->s_info.irap_or_gdr_pic)
910 0 : gf_fprintf(dump, " gdr_pic=\"%d\" gdr_recovery_count=\"%d\"", vvc->s_info.gdr_pic, vvc->s_info.gdr_recovery_count);
911 0 : if (vvc->s_info.inter_slice_allowed_flag)
912 0 : gf_fprintf(dump, " intra_slice_allowed_flag=\"%d\"", vvc->s_info.intra_slice_allowed_flag);
913 0 : if (vvc->s_info.sps->poc_msb_cycle_flag && vvc->s_info.poc_msb_cycle_present_flag)
914 0 : gf_fprintf(dump, " poc_msb_cycle=\"%d\"", vvc->s_info.poc_msb_cycle);
915 : }
916 0 : if (type!=GF_VVC_NALU_PIC_HEADER)
917 0 : gf_fprintf(dump, " slice_type=\"%d\"", vvc->s_info.slice_type);
918 : }
919 :
920 0 : if (bs) {
921 0 : if (!pctx)
922 0 : gf_bs_del(bs);
923 : else
924 0 : gf_bs_set_logger(bs, NULL, NULL);
925 : }
926 :
927 0 : if ((type == GF_VVC_NALU_SEI_PREFIX) || (type == GF_VVC_NALU_SEI_SUFFIX)) {
928 0 : gf_fprintf(dump, ">\n");
929 0 : if (pctx) {
930 0 : if (!pctx->bs)
931 0 : pctx->bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
932 : else
933 0 : gf_bs_reassign_buffer(pctx->bs, ptr, ptr_size);
934 0 : bs = pctx->bs;
935 : } else {
936 0 : bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
937 : }
938 0 : dump_sei(dump, bs, GF_TRUE);
939 0 : if (!pctx) gf_bs_del(bs);
940 0 : gf_fprintf(dump, " </NALU>\n");
941 : } else {
942 0 : gf_fprintf(dump, "/>\n");
943 : }
944 : return;
945 : }
946 :
947 : //avc
948 3403 : type = ptr[0] & 0x1F;
949 : nal_ref_idc = ptr[0] & 0x60;
950 3403 : nal_ref_idc>>=5;
951 3403 : if (! full_bs_dump)
952 3225 : gf_fprintf(dump, "code=\"%d\" ", type);
953 :
954 3403 : gf_fprintf(dump, "type=\"");
955 : res = -2;
956 :
957 3403 : if (pctx) {
958 356 : if (!pctx->bs)
959 0 : pctx->bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
960 : else
961 356 : gf_bs_reassign_buffer(pctx->bs, ptr, ptr_size);
962 356 : bs = pctx->bs;
963 : } else {
964 3047 : bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ);
965 : }
966 :
967 3403 : if (full_bs_dump)
968 178 : gf_bs_set_logger(bs, shifted_bs_log, &lcbk);
969 :
970 3403 : switch (type) {
971 1327 : case GF_AVC_NALU_NON_IDR_SLICE:
972 1327 : gf_fputs("Non IDR slice", dump);
973 1327 : if (is_encrypted) break;
974 1327 : res = gf_avc_parse_nalu(bs, avc);
975 1327 : break;
976 0 : case GF_AVC_NALU_DP_A_SLICE:
977 0 : gf_fputs("DP Type A slice", dump);
978 0 : break;
979 0 : case GF_AVC_NALU_DP_B_SLICE:
980 0 : gf_fputs("DP Type B slice", dump);
981 0 : break;
982 0 : case GF_AVC_NALU_DP_C_SLICE:
983 0 : gf_fputs("DP Type C slice", dump);
984 0 : break;
985 38 : case GF_AVC_NALU_IDR_SLICE:
986 38 : gf_fputs("IDR slice", dump);
987 38 : if (is_encrypted) break;
988 38 : res = gf_avc_parse_nalu(bs, avc);
989 38 : break;
990 516 : case GF_AVC_NALU_SEI:
991 516 : gf_fputs("SEI Message", dump);
992 516 : break;
993 9 : case GF_AVC_NALU_SEQ_PARAM:
994 9 : gf_fputs("SequenceParameterSet", dump);
995 9 : if (is_encrypted) break;
996 9 : idx = gf_avc_read_sps_bs(bs, avc, 0, NULL);
997 9 : if (idx<0) {
998 0 : gf_fprintf(dump, "\" sps_id=\"PARSING FAILURE");
999 0 : break;
1000 : }
1001 9 : if (full_bs_dump) break;
1002 7 : gf_fprintf(dump, "\" sps_id=\"%d", idx);
1003 7 : gf_fprintf(dump, "\" frame_mbs_only_flag=\"%d", avc->sps->frame_mbs_only_flag);
1004 7 : gf_fprintf(dump, "\" mb_adaptive_frame_field_flag=\"%d", avc->sps->mb_adaptive_frame_field_flag);
1005 7 : gf_fprintf(dump, "\" vui_parameters_present_flag=\"%d", avc->sps->vui_parameters_present_flag);
1006 7 : gf_fprintf(dump, "\" max_num_ref_frames=\"%d", avc->sps->max_num_ref_frames);
1007 7 : gf_fprintf(dump, "\" gaps_in_frame_num_value_allowed_flag=\"%d", avc->sps->gaps_in_frame_num_value_allowed_flag);
1008 7 : gf_fprintf(dump, "\" chroma_format_idc=\"%d", avc->sps->chroma_format);
1009 7 : gf_fprintf(dump, "\" bit_depth_luma_minus8=\"%d", avc->sps->luma_bit_depth_m8);
1010 7 : gf_fprintf(dump, "\" bit_depth_chroma_minus8=\"%d", avc->sps->chroma_bit_depth_m8);
1011 7 : gf_fprintf(dump, "\" width=\"%d", avc->sps->width);
1012 7 : gf_fprintf(dump, "\" height=\"%d", avc->sps->height);
1013 7 : gf_fprintf(dump, "\" crop_top=\"%d", avc->sps->crop.top);
1014 7 : gf_fprintf(dump, "\" crop_left=\"%d", avc->sps->crop.left);
1015 7 : gf_fprintf(dump, "\" crop_bottom=\"%d", avc->sps->crop.bottom);
1016 7 : gf_fprintf(dump, "\" crop_right=\"%d", avc->sps->crop.right);
1017 7 : if (avc->sps->vui_parameters_present_flag) {
1018 5 : gf_fprintf(dump, "\" vui_video_full_range_flag=\"%d", avc->sps->vui.video_full_range_flag);
1019 5 : gf_fprintf(dump, "\" vui_video_signal_type_present_flag=\"%d", avc->sps->vui.video_signal_type_present_flag);
1020 5 : gf_fprintf(dump, "\" vui_aspect_ratio_info_present_flag=\"%d", avc->sps->vui.aspect_ratio_info_present_flag);
1021 5 : gf_fprintf(dump, "\" vui_aspect_ratio_num=\"%d", avc->sps->vui.par_num);
1022 5 : gf_fprintf(dump, "\" vui_aspect_ratio_den=\"%d", avc->sps->vui.par_den);
1023 5 : gf_fprintf(dump, "\" vui_overscan_info_present_flag=\"%d", avc->sps->vui.overscan_info_present_flag);
1024 5 : gf_fprintf(dump, "\" vui_colour_description_present_flag=\"%d", avc->sps->vui.colour_description_present_flag);
1025 5 : gf_fprintf(dump, "\" vui_colour_primaries=\"%d", avc->sps->vui.colour_primaries);
1026 5 : gf_fprintf(dump, "\" vui_transfer_characteristics=\"%d", avc->sps->vui.transfer_characteristics);
1027 5 : gf_fprintf(dump, "\" vui_matrix_coefficients=\"%d", avc->sps->vui.matrix_coefficients);
1028 5 : gf_fprintf(dump, "\" vui_low_delay_hrd_flag=\"%d", avc->sps->vui.low_delay_hrd_flag);
1029 : }
1030 7 : if (gf_sys_is_test_mode()) break;
1031 0 : gf_fprintf(dump, "\" log2_max_poc_lsb=\"%d", avc->sps->log2_max_poc_lsb);
1032 0 : gf_fprintf(dump, "\" log2_max_frame_num=\"%d", avc->sps->log2_max_frame_num);
1033 0 : gf_fprintf(dump, "\" delta_pic_order_always_zero_flag=\"%d", avc->sps->delta_pic_order_always_zero_flag);
1034 0 : gf_fprintf(dump, "\" offset_for_non_ref_pic=\"%d", avc->sps->offset_for_non_ref_pic);
1035 :
1036 0 : break;
1037 11 : case GF_AVC_NALU_PIC_PARAM:
1038 11 : gf_fputs("PictureParameterSet", dump);
1039 11 : if (is_encrypted) break;
1040 11 : idx = gf_avc_read_pps_bs(bs, avc);
1041 11 : if (idx<0) {
1042 0 : gf_fprintf(dump, "\" pps_id=\"PARSING FAILURE\" ");
1043 0 : break;
1044 : }
1045 11 : if (full_bs_dump) break;
1046 9 : gf_fprintf(dump, "\" pps_id=\"%d\" sps_id=\"%d", idx, avc->pps[idx].sps_id);
1047 9 : gf_fprintf(dump, "\" entropy_coding_mode_flag=\"%d", avc->pps[idx].entropy_coding_mode_flag);
1048 9 : if (gf_sys_is_test_mode()) break;
1049 0 : gf_fprintf(dump, "\" deblocking_filter_control_present_flag=\"%d", avc->pps[idx].deblocking_filter_control_present_flag);
1050 0 : gf_fprintf(dump, "\" mb_slice_group_map_type=\"%d", avc->pps[idx].mb_slice_group_map_type);
1051 0 : gf_fprintf(dump, "\" num_ref_idx_l0_default_active_minus1=\"%d", avc->pps[idx].num_ref_idx_l0_default_active_minus1);
1052 0 : gf_fprintf(dump, "\" num_ref_idx_l1_default_active_minus1=\"%d", avc->pps[idx].num_ref_idx_l1_default_active_minus1);
1053 0 : gf_fprintf(dump, "\" pic_order_present=\"%d", avc->pps[idx].pic_order_present);
1054 0 : gf_fprintf(dump, "\" pic_size_in_map_units_minus1=\"%d", avc->pps[idx].pic_size_in_map_units_minus1);
1055 0 : gf_fprintf(dump, "\" redundant_pic_cnt_present=\"%d", avc->pps[idx].redundant_pic_cnt_present);
1056 0 : gf_fprintf(dump, "\" slice_group_change_rate_minus1=\"%d", avc->pps[idx].slice_group_change_rate_minus1);
1057 0 : gf_fprintf(dump, "\" slice_group_count=\"%d", avc->pps[idx].slice_group_count);
1058 0 : gf_fprintf(dump, "\" weighted_pred_flag=\"%d", avc->pps[idx].weighted_pred_flag);
1059 0 : gf_fprintf(dump, "\" weighted_bipred_idc=\"%d", avc->pps[idx].weighted_bipred_idc);
1060 0 : break;
1061 0 : case GF_AVC_NALU_ACCESS_UNIT:
1062 0 : gf_fputs("AccessUnit delimiter", dump);
1063 0 : if (is_encrypted) break;
1064 0 : if (full_bs_dump) break;
1065 0 : gf_fprintf(dump, "\" primary_pic_type=\"%d", gf_bs_read_u8(bs) >> 5);
1066 0 : break;
1067 0 : case GF_AVC_NALU_END_OF_SEQ:
1068 0 : gf_fputs("EndOfSequence", dump);
1069 0 : break;
1070 0 : case GF_AVC_NALU_END_OF_STREAM:
1071 0 : gf_fputs("EndOfStream", dump);
1072 0 : break;
1073 0 : case GF_AVC_NALU_FILLER_DATA:
1074 0 : gf_fputs("Filler data", dump);
1075 0 : break;
1076 0 : case GF_AVC_NALU_SEQ_PARAM_EXT:
1077 0 : gf_fputs("SequenceParameterSetExtension", dump);
1078 0 : break;
1079 501 : case GF_AVC_NALU_SVC_PREFIX_NALU:
1080 501 : gf_fputs("SVCPrefix", dump);
1081 501 : break;
1082 2 : case GF_AVC_NALU_SVC_SUBSEQ_PARAM:
1083 2 : gf_fputs("SVCSubsequenceParameterSet", dump);
1084 2 : if (is_encrypted) break;
1085 2 : idx = gf_avc_read_sps_bs(bs, avc, 1, NULL);
1086 : assert (idx >= 0);
1087 2 : if (full_bs_dump) break;
1088 2 : gf_fprintf(dump, "\" sps_id=\"%d", idx - GF_SVC_SSPS_ID_SHIFT);
1089 2 : break;
1090 0 : case GF_AVC_NALU_SLICE_AUX:
1091 0 : gf_fputs("Auxiliary Slice", dump);
1092 0 : break;
1093 :
1094 749 : case GF_AVC_NALU_SVC_SLICE:
1095 749 : gf_fputs(is_svc ? "SVCSlice" : "CodedSliceExtension", dump);
1096 749 : if (is_encrypted) break;
1097 749 : gf_avc_parse_nalu(bs, avc);
1098 749 : dependency_id = (ptr[2] & 0x70) >> 4;
1099 749 : quality_id = (ptr[2] & 0x0F);
1100 749 : temporal_id = (ptr[3] & 0xE0) >> 5;
1101 749 : gf_fprintf(dump, "\" dependency_id=\"%d\" quality_id=\"%d\" temporal_id=\"%d", dependency_id, quality_id, temporal_id);
1102 749 : gf_fprintf(dump, "\" poc=\"%d", avc->s_info.poc);
1103 749 : break;
1104 0 : case 30:
1105 0 : gf_fputs("SVCAggregator", dump);
1106 0 : break;
1107 250 : case 31:
1108 250 : gf_fputs("SVCExtractor", dump);
1109 250 : if (is_encrypted) break;
1110 250 : track_ref_index = (u8) ptr[4];
1111 250 : sample_offset = (s8) ptr[5];
1112 250 : data_offset = inspect_get_nal_size(&ptr[6], nalh_size);
1113 250 : data_size = inspect_get_nal_size(&ptr[6+nalh_size], nalh_size);
1114 250 : gf_fprintf(dump, "\" track_ref_index=\"%d\" sample_offset=\"%d\" data_offset=\"%d\" data_size=\"%d\"", track_ref_index, sample_offset, data_offset, data_size);
1115 250 : break;
1116 :
1117 0 : default:
1118 0 : gf_fputs("UNKNOWN", dump);
1119 0 : break;
1120 : }
1121 3423 : gf_fputs("\"", dump);
1122 :
1123 3403 : if (!full_bs_dump) {
1124 3225 : if (nal_ref_idc) {
1125 1246 : gf_fprintf(dump, " nal_ref_idc=\"%d\"", nal_ref_idc);
1126 : }
1127 3225 : if (res>=0) {
1128 1192 : gf_fprintf(dump, " poc=\"%d\" pps_id=\"%d\" field_pic_flag=\"%d\"", avc->s_info.poc, avc->s_info.pps->id, (int)avc->s_info.field_pic_flag);
1129 : }
1130 : }
1131 :
1132 3403 : if (res == -1)
1133 0 : gf_fprintf(dump, " status=\"error decoding slice\"");
1134 :
1135 3403 : if (!is_encrypted && (type == GF_AVC_NALU_SEI)) {
1136 516 : gf_fprintf(dump, ">\n");
1137 516 : gf_bs_set_logger(bs, NULL, NULL);
1138 516 : dump_sei(dump, bs, GF_FALSE);
1139 516 : gf_fprintf(dump, " </NALU>\n");
1140 : } else {
1141 2887 : gf_fprintf(dump, "/>\n");
1142 : }
1143 :
1144 3403 : if (bs) {
1145 3403 : if (!pctx)
1146 3047 : gf_bs_del(bs);
1147 : else
1148 356 : gf_bs_set_logger(bs, NULL, NULL);
1149 : }
1150 : }
1151 :
1152 : GF_EXPORT
1153 7083 : void gf_inspect_dump_nalu(FILE *dump, u8 *ptr, u32 ptr_size, Bool is_svc, HEVCState *hevc, AVCState *avc, VVCState *vvc, u32 nalh_size, Bool dump_crc, Bool is_encrypted)
1154 : {
1155 7083 : gf_inspect_dump_nalu_internal(dump, ptr, ptr_size, is_svc, hevc, avc, vvc, nalh_size, dump_crc, is_encrypted, 0, NULL);
1156 7083 : }
1157 :
1158 : static void av1_dump_tile(FILE *dump, u32 idx, AV1Tile *tile)
1159 : {
1160 78185 : gf_fprintf(dump, " <Tile number=\"%d\" start=\"%d\" size=\"%d\"/>\n", idx, tile->obu_start_offset, tile->size);
1161 : }
1162 :
1163 26903 : static u64 gf_inspect_dump_obu_internal(FILE *dump, AV1State *av1, u8 *obu, u64 obu_length, ObuType obu_type, u64 obu_size, u32 hdr_size, Bool dump_crc, PidCtx *pctx, u32 full_dump)
1164 : {
1165 26903 : if (pctx) {
1166 : InspectLogCbk lcbk;
1167 :
1168 384 : if (full_dump>=INSPECT_ANALYZE_BS) {
1169 192 : lcbk.dump = dump;
1170 192 : lcbk.dump_bits = (full_dump==INSPECT_ANALYZE_BS_BITS) ? GF_TRUE : GF_FALSE;
1171 192 : gf_bs_set_logger(pctx->bs, regular_bs_log, &lcbk);
1172 :
1173 192 : gf_fprintf(dump, " <OBU");
1174 : }
1175 384 : gf_av1_parse_obu(pctx->bs, &obu_type, &obu_size, &hdr_size, pctx->av1_state);
1176 :
1177 :
1178 384 : if (full_dump>=INSPECT_ANALYZE_BS) {
1179 192 : gf_bs_set_logger(pctx->bs, NULL, NULL);
1180 : } else {
1181 : full_dump = 0;
1182 : }
1183 : }
1184 :
1185 26711 : if (!full_dump) {
1186 26711 : gf_fprintf(dump, " <OBU");
1187 : }
1188 :
1189 :
1190 : #define DUMP_OBU_INT(_v) gf_fprintf(dump, #_v"=\"%d\" ", av1->_v);
1191 : #define DUMP_OBU_INT2(_n, _v) gf_fprintf(dump, _n"=\"%d\" ", _v);
1192 :
1193 26903 : gf_fprintf(dump, " size=\""LLU"\" type=\"%s\" header_size=\"%d\" ", obu_size, gf_av1_get_obu_name(obu_type), hdr_size);
1194 :
1195 26903 : if (!full_dump) {
1196 26711 : gf_fprintf(dump, "has_size_field=\"%d\" has_ext=\"%d\" temporalID=\"%d\" spatialID=\"%d\" ", av1->obu_has_size_field, av1->obu_extension_flag, av1->temporal_id , av1->spatial_id);
1197 : }
1198 :
1199 26903 : if (dump_crc && (obu_length<0xFFFFFFFFUL))
1200 0 : gf_fprintf(dump, "crc=\"%u\" ", gf_crc_32(obu, (u32) obu_length) );
1201 26903 : switch (obu_type) {
1202 177 : case OBU_SEQUENCE_HEADER:
1203 177 : if (full_dump) break;
1204 175 : DUMP_OBU_INT(sequence_width)
1205 175 : DUMP_OBU_INT(sequence_height)
1206 175 : DUMP_OBU_INT(bit_depth)
1207 175 : DUMP_OBU_INT(still_picture)
1208 175 : DUMP_OBU_INT(OperatingPointIdc)
1209 175 : DUMP_OBU_INT(color_range)
1210 175 : DUMP_OBU_INT(color_description_present_flag)
1211 175 : DUMP_OBU_INT(color_primaries)
1212 175 : DUMP_OBU_INT(transfer_characteristics)
1213 175 : DUMP_OBU_INT(matrix_coefficients)
1214 175 : DUMP_OBU_INT2("profile", av1->config->seq_profile)
1215 175 : DUMP_OBU_INT2("level", av1->config->seq_level_idx_0)
1216 175 : break;
1217 26686 : case OBU_FRAME_HEADER:
1218 : case OBU_FRAME:
1219 26686 : if (!full_dump) {
1220 26496 : if (av1->frame_id_numbers_present_flag) {
1221 0 : DUMP_OBU_INT2("delta_frame_id_length_minus_2", av1->delta_frame_id_length_minus_2)
1222 : }
1223 26496 : if (av1->reduced_still_picture_header) {
1224 0 : DUMP_OBU_INT(reduced_still_picture_header)
1225 : }
1226 26496 : DUMP_OBU_INT2("uncompressed_header_bytes", av1->frame_state.uncompressed_header_bytes);
1227 26496 : if (av1->frame_state.uncompressed_header_bytes) {
1228 26496 : if (av1->frame_state.frame_type==AV1_KEY_FRAME) gf_fprintf(dump, "frame_type=\"key\" ");
1229 26330 : else if (av1->frame_state.frame_type==AV1_INTER_FRAME) gf_fprintf(dump, "frame_type=\"inter\" ");
1230 0 : else if (av1->frame_state.frame_type==AV1_INTRA_ONLY_FRAME) gf_fprintf(dump, "frame_type=\"intra_only\" ");
1231 0 : else if (av1->frame_state.frame_type==AV1_SWITCH_FRAME) gf_fprintf(dump, "frame_type=\"switch\" ");
1232 26496 : gf_fprintf(dump, "refresh_frame_flags=\"%d\" ", av1->frame_state.refresh_frame_flags);
1233 :
1234 26496 : DUMP_OBU_INT2("show_frame", av1->frame_state.show_frame);
1235 26496 : DUMP_OBU_INT2("show_existing_frame", av1->frame_state.show_existing_frame);
1236 26496 : DUMP_OBU_INT(width);
1237 26496 : DUMP_OBU_INT(height);
1238 : }
1239 26496 : if (obu_type==OBU_FRAME_HEADER)
1240 : break;
1241 : }
1242 :
1243 : case OBU_TILE_GROUP:
1244 20012 : if (av1->frame_state.nb_tiles_in_obu) {
1245 : u32 i;
1246 20012 : DUMP_OBU_INT2("nb_tiles", av1->frame_state.nb_tiles_in_obu)
1247 : fprintf(dump, ">\n");
1248 98197 : for (i = 0; i < av1->frame_state.nb_tiles_in_obu; i++) {
1249 : av1_dump_tile(dump, i, &av1->frame_state.tiles[i]);
1250 : }
1251 : } else {
1252 0 : gf_fprintf(dump, "nb_tiles=\"unknown\">\n");
1253 : }
1254 20012 : gf_fprintf(dump, " </OBU>\n");
1255 20012 : break;
1256 : default:
1257 : break;
1258 :
1259 : }
1260 33619 : if (obu_type != OBU_TILE_GROUP && obu_type != OBU_FRAME)
1261 6891 : gf_fprintf(dump, "/>\n");
1262 :
1263 26903 : return obu_size;
1264 : }
1265 :
1266 : GF_EXPORT
1267 26519 : void gf_inspect_dump_obu(FILE *dump, AV1State *av1, u8 *obu, u64 obu_length, ObuType obu_type, u64 obu_size, u32 hdr_size, Bool dump_crc)
1268 : {
1269 26519 : gf_inspect_dump_obu_internal(dump, av1, obu, obu_length, obu_type, obu_size, hdr_size, dump_crc, NULL, 0);
1270 26519 : }
1271 :
1272 31 : static void gf_inspect_dump_prores_internal(FILE *dump, u8 *ptr, u64 frame_size, Bool dump_crc, PidCtx *pctx)
1273 : {
1274 : GF_ProResFrameInfo prores_frame;
1275 : GF_Err e;
1276 : GF_BitStream *bs;
1277 31 : if (pctx) {
1278 0 : gf_bs_reassign_buffer(pctx->bs, ptr, frame_size);
1279 0 : bs = pctx->bs;
1280 : } else {
1281 31 : bs = gf_bs_new(ptr, frame_size, GF_BITSTREAM_READ);
1282 : }
1283 31 : e = gf_media_prores_parse_bs(bs, &prores_frame);
1284 31 : if (!pctx) gf_bs_del(bs);
1285 :
1286 31 : if (e) {
1287 0 : gf_fprintf(dump, " <!-- Error reading frame %s -->\n", gf_error_to_string(e) );
1288 0 : return;
1289 : }
1290 31 : gf_fprintf(dump, " <ProResFrame framesize=\"%d\" frameID=\"%s\" version=\"%d\""
1291 : , prores_frame.frame_size
1292 : , gf_4cc_to_str(prores_frame.frame_identifier)
1293 31 : , prores_frame.version
1294 : );
1295 62 : gf_fprintf(dump, " encoderID=\"%s\" width=\"%d\" height=\"%d\""
1296 : , gf_4cc_to_str(prores_frame.encoder_id)
1297 31 : , prores_frame.width
1298 31 : , prores_frame.height
1299 : );
1300 31 : switch (prores_frame.chroma_format) {
1301 0 : case 0: gf_fprintf(dump, " chromaFormat=\"reserved(0)\""); break;
1302 0 : case 1: gf_fprintf(dump, " chromaFormat=\"reserved(1)\""); break;
1303 31 : case 2: gf_fprintf(dump, " chromaFormat=\"4:2:2\""); break;
1304 0 : case 3: gf_fprintf(dump, " chromaFormat=\"4:4:4\""); break;
1305 : }
1306 31 : switch (prores_frame.interlaced_mode) {
1307 0 : case 0: gf_fprintf(dump, " interlacedMode=\"progressive\""); break;
1308 0 : case 1: gf_fprintf(dump, " interlacedMode=\"interlaced_top_first\""); break;
1309 31 : case 2: gf_fprintf(dump, " interlacedMode=\"interlaced_bottom_first\""); break;
1310 0 : case 3: gf_fprintf(dump, " interlacedMode=\"reserved\""); break;
1311 : }
1312 31 : switch (prores_frame.aspect_ratio_information) {
1313 31 : case 0: gf_fprintf(dump, " aspectRatio=\"unknown\""); break;
1314 0 : case 1: gf_fprintf(dump, " aspectRatio=\"1:1\""); break;
1315 0 : case 2: gf_fprintf(dump, " aspectRatio=\"4:3\""); break;
1316 0 : case 3: gf_fprintf(dump, " aspectRatio=\"16:9\""); break;
1317 0 : default: gf_fprintf(dump, " aspectRatio=\"reserved(%d)\"", prores_frame.aspect_ratio_information); break;
1318 : }
1319 31 : switch (prores_frame.framerate_code) {
1320 31 : case 0: gf_fprintf(dump, " framerate=\"unknown\""); break;
1321 0 : case 1: gf_fprintf(dump, " framerate=\"23.976\""); break;
1322 0 : case 2: gf_fprintf(dump, " framerate=\"24\""); break;
1323 0 : case 3: gf_fprintf(dump, " framerate=\"25\""); break;
1324 0 : case 4: gf_fprintf(dump, " framerate=\"29.97\""); break;
1325 0 : case 5: gf_fprintf(dump, " framerate=\"30\""); break;
1326 0 : case 6: gf_fprintf(dump, " framerate=\"50\""); break;
1327 0 : case 7: gf_fprintf(dump, " framerate=\"59.94\""); break;
1328 0 : case 8: gf_fprintf(dump, " framerate=\"60\""); break;
1329 0 : case 9: gf_fprintf(dump, " framerate=\"100\""); break;
1330 0 : case 10: gf_fprintf(dump, " framerate=\"119.88\""); break;
1331 0 : case 11: gf_fprintf(dump, " framerate=\"120\""); break;
1332 0 : default: gf_fprintf(dump, " framerate=\"reserved(%d)\"", prores_frame.framerate_code); break;
1333 : }
1334 31 : switch (prores_frame.color_primaries) {
1335 31 : case 0: case 2: gf_fprintf(dump, " colorPrimaries=\"unknown\""); break;
1336 0 : case 1: gf_fprintf(dump, " colorPrimaries=\"BT.709\""); break;
1337 0 : case 5: gf_fprintf(dump, " colorPrimaries=\"BT.601-625\""); break;
1338 0 : case 6: gf_fprintf(dump, " colorPrimaries=\"BT.601-525\""); break;
1339 0 : case 9: gf_fprintf(dump, " colorPrimaries=\"BT.2020\""); break;
1340 0 : case 11: gf_fprintf(dump, " colorPrimaries=\"P3\""); break;
1341 0 : case 12: gf_fprintf(dump, " colorPrimaries=\"P3-D65\""); break;
1342 0 : default: gf_fprintf(dump, " colorPrimaries=\"reserved(%d)\"", prores_frame.color_primaries); break;
1343 : }
1344 31 : switch (prores_frame.matrix_coefficients) {
1345 0 : case 0: case 2: gf_fprintf(dump, " matrixCoefficients=\"unknown\""); break;
1346 0 : case 1: gf_fprintf(dump, " matrixCoefficients=\"BT.709\""); break;
1347 31 : case 6: gf_fprintf(dump, " matrixCoefficients=\"BT.601\""); break;
1348 0 : case 9: gf_fprintf(dump, " matrixCoefficients=\"BT.2020\""); break;
1349 0 : default: gf_fprintf(dump, " matrixCoefficients=\"reserved(%d)\"", prores_frame.matrix_coefficients); break;
1350 : }
1351 31 : switch (prores_frame.transfer_characteristics) {
1352 0 : case 0: gf_fprintf(dump, " transferCharacteristics=\"unknown\""); break;
1353 0 : case 1: gf_fprintf(dump, " transferCharacteristics=\"BT-709\""); break;
1354 0 : case 16: gf_fprintf(dump, " transferCharacteristics=\"ST-2084\""); break;
1355 0 : case 18: gf_fprintf(dump, " transferCharacteristics=\"STD-B67\""); break;
1356 31 : case 2:
1357 : default:
1358 31 : gf_fprintf(dump, " transferCharacteristics=\"unspecified\""); break;
1359 : }
1360 31 : switch (prores_frame.alpha_channel_type) {
1361 31 : case 0: gf_fprintf(dump, " alphaChannel=\"none\""); break;
1362 0 : case 1: gf_fprintf(dump, " alphaChannel=\"8bits\""); break;
1363 0 : case 2: gf_fprintf(dump, " alphaChannel=\"16bits\""); break;
1364 0 : default: gf_fprintf(dump, " alphaChannel=\"reserved(%d)\"", prores_frame.alpha_channel_type); break;
1365 : }
1366 31 : gf_fprintf(dump, " numPictures=\"%d\"" , prores_frame.transfer_characteristics, prores_frame.nb_pic);
1367 :
1368 31 : if (dump_crc) {
1369 0 : gf_fprintf(dump, " crc=\"%d\"" , gf_crc_32(ptr, (u32) frame_size) );
1370 : }
1371 31 : if (!prores_frame.load_luma_quant_matrix && !prores_frame.load_chroma_quant_matrix) {
1372 0 : gf_fprintf(dump, "/>\n");
1373 : } else {
1374 : u32 j, k;
1375 31 : gf_fprintf(dump, ">\n");
1376 31 : if (prores_frame.load_luma_quant_matrix) {
1377 31 : gf_fprintf(dump, " <LumaQuantMatrix coefs=\"");
1378 279 : for (j=0; j<8; j++) {
1379 1984 : for (k=0; k<8; k++) {
1380 1984 : gf_fprintf(dump, " %02X", prores_frame.luma_quant_matrix[j][k]);
1381 : }
1382 : }
1383 31 : gf_fprintf(dump, "\">\n");
1384 : }
1385 31 : if (prores_frame.load_chroma_quant_matrix) {
1386 31 : gf_fprintf(dump, " <ChromaQuantMatrix coefs=\"");
1387 279 : for (j=0; j<8; j++) {
1388 1984 : for (k=0; k<8; k++) {
1389 1984 : gf_fprintf(dump, " %02X", prores_frame.chroma_quant_matrix[j][k]);
1390 : }
1391 : }
1392 31 : gf_fprintf(dump, "\">\n");
1393 : }
1394 31 : gf_fprintf(dump, " </ProResFrame>\n");
1395 : }
1396 : }
1397 :
1398 : GF_EXPORT
1399 31 : void gf_inspect_dump_prores(FILE *dump, u8 *ptr, u64 frame_size, Bool dump_crc)
1400 : {
1401 31 : gf_inspect_dump_prores_internal(dump, ptr, frame_size, dump_crc, NULL);
1402 31 : }
1403 : enum {
1404 : MHAS_FILLER = 0,
1405 : MHAS_CONFIG,
1406 : MHAS_FRAME,
1407 : MHAS_SCENE_INFO,
1408 : MHAS_RES4,
1409 : MHAS_RES5,
1410 : MHAS_SYNC,
1411 : MHAS_SYNC_GAP,
1412 : MHAS_MARKER,
1413 : MHAS_CRC16,
1414 : MHAS_CRC32,
1415 : MHAS_DESCRIPTOR,
1416 : MHAS_INTERACTION,
1417 : MHAS_LOUDNESS_CRC,
1418 : MHAS_BUFFER_INFO,
1419 : MHAS_GLOBAL_CRC16,
1420 : MHAS_GLOBAL_CRC32,
1421 : MHAS_AUDIO_TRUNCATION,
1422 : MHAS_GEN_DATA,
1423 : };
1424 : static struct {
1425 : u32 type;
1426 : const char *name;
1427 : } mhas_pack_types[] =
1428 : {
1429 : {MHAS_FILLER, "filler"},
1430 : {MHAS_CONFIG, "config"},
1431 : {MHAS_FRAME, "frame"},
1432 : {MHAS_SCENE_INFO, "scene_info"},
1433 : {MHAS_SYNC, "sync"},
1434 : {MHAS_SYNC_GAP, "sync_gap"},
1435 : {MHAS_MARKER, "marker"},
1436 : {MHAS_CRC16, "crc16"},
1437 : {MHAS_CRC32, "crc32"},
1438 : {MHAS_DESCRIPTOR, "descriptor"},
1439 : {MHAS_INTERACTION, "interaction"},
1440 : {MHAS_LOUDNESS_CRC, "loudness_drc"},
1441 : {MHAS_BUFFER_INFO, "buffer_info"},
1442 : {MHAS_GLOBAL_CRC16, "global_crc16"},
1443 : {MHAS_GLOBAL_CRC32, "global_crc32"},
1444 : {MHAS_AUDIO_TRUNCATION, "audio_truncation"},
1445 : {MHAS_GEN_DATA, "gen_data"},
1446 : };
1447 :
1448 0 : static void dump_mha_config(FILE *dump, GF_BitStream *bs, const char *indent)
1449 : {
1450 : u32 val;
1451 0 : gf_fprintf(dump, "%s<MPEGHConfig", indent);
1452 0 : val = gf_bs_read_int(bs, 8);
1453 0 : gf_fprintf(dump, " ProfileLevelIndication=\"%d\"", val);
1454 0 : val = gf_bs_read_int(bs, 5);
1455 0 : gf_fprintf(dump, " usacSamplerateIndex=\"%d\"", val);
1456 0 : if (val==0x1f) {
1457 0 : val = gf_bs_read_int(bs, 24);
1458 0 : gf_fprintf(dump, " usacSamplerate=\"%d\"", val);
1459 : }
1460 0 : val = gf_bs_read_int(bs, 3);
1461 0 : gf_fprintf(dump, " coreSbrFrameLengthIndex=\"%d\"", val);
1462 0 : gf_bs_read_int(bs, 1);
1463 0 : val = gf_bs_read_int(bs, 1);
1464 0 : gf_fprintf(dump, " receiverDelayCompensation=\"%d\"", val);
1465 0 : gf_fprintf(dump, "/>\n");
1466 0 : }
1467 0 : static void gf_inspect_dump_mha_frame(FILE *dump, GF_BitStream *bs, const char *indent)
1468 : {
1469 : u32 val;
1470 0 : gf_fprintf(dump, "%s<MPEGHFrame", indent);
1471 0 : val = gf_bs_read_int(bs, 1);
1472 0 : gf_fprintf(dump, " usacIndependencyFlag=\"%d\"", val);
1473 0 : gf_fprintf(dump, "/>\n");
1474 0 : }
1475 0 : static void gf_inspect_dump_mhas(FILE *dump, u8 *ptr, u64 frame_size, Bool dump_crc, PidCtx *pctx)
1476 : {
1477 : u64 gf_mpegh_escaped_value(GF_BitStream *bs, u32 nBits1, u32 nBits2, u32 nBits3);
1478 0 : gf_bs_reassign_buffer(pctx->bs, ptr, frame_size);
1479 0 : GF_BitStream *bs = pctx->bs;
1480 :
1481 0 : gf_fprintf(dump, " <MHASFrame>\n");
1482 :
1483 0 : while (gf_bs_available(bs)) {
1484 : u32 i, count;
1485 : const char *type_name="uknown";
1486 : u64 pos;
1487 0 : u32 type = (u32) gf_mpegh_escaped_value(bs, 3, 8, 8);
1488 0 : u64 label = gf_mpegh_escaped_value(bs, 2, 8, 32);
1489 0 : u64 size = gf_mpegh_escaped_value(bs, 11, 24, 24);
1490 :
1491 : count = GF_ARRAY_LENGTH(mhas_pack_types);
1492 0 : for (i=0; i<count; i++) {
1493 0 : if (mhas_pack_types[i].type==type) {
1494 0 : type_name = mhas_pack_types[i].name;
1495 : break;
1496 : }
1497 : }
1498 0 : gf_fprintf(dump, " <MHASPacket type=\"%s\" label=\""LLU"\" size=\""LLU"\"", type_name, label, size);
1499 :
1500 0 : pos = gf_bs_get_position(bs);
1501 0 : switch (type) {
1502 0 : case MHAS_CONFIG:
1503 0 : gf_fprintf(dump, ">\n");
1504 0 : dump_mha_config(dump, bs, " ");
1505 0 : gf_fprintf(dump, " </MHASPacket>\n");
1506 : break;
1507 0 : case MHAS_FRAME:
1508 0 : gf_fprintf(dump, ">\n");
1509 0 : gf_inspect_dump_mha_frame(dump, bs, " ");
1510 0 : gf_fprintf(dump, " </MHASPacket>\n");
1511 : break;
1512 0 : case MHAS_BUFFER_INFO:
1513 0 : if (gf_bs_read_int(bs, 1)) {
1514 0 : gf_fprintf(dump, " buffer_fullness_present=\"1\" buffer_fullness=\""LLU"\"", gf_mpegh_escaped_value(bs, 15,24,32) );
1515 : } else {
1516 0 : gf_fprintf(dump, " buffer_fullness_present=\"0\"");
1517 :
1518 : }
1519 0 : gf_fprintf(dump, "/>\n");
1520 : break;
1521 0 : case MHAS_SYNC:
1522 0 : gf_fprintf(dump, " sync=\"0x%02X\"/>\n", gf_bs_read_u8(bs) );
1523 : break;
1524 0 : case MHAS_SYNC_GAP:
1525 0 : gf_fprintf(dump, " syncSpacingLength=\"0x%02" LLX_SUF "\"/>\n", gf_mpegh_escaped_value(bs, 16, 24, 24) );
1526 : break;
1527 0 : case MHAS_MARKER:
1528 : case MHAS_DESCRIPTOR:
1529 0 : gf_fprintf(dump, " %s=\"0x", (type==MHAS_MARKER) ? "markers" : "descriptors");
1530 0 : for (i=0; i<size; i++)
1531 0 : gf_fprintf(dump, "%02X", gf_bs_read_u8(bs) );
1532 0 : gf_fprintf(dump, "\"/>\n");
1533 : break;
1534 0 : default:
1535 0 : gf_fprintf(dump, "/>\n");
1536 : break;
1537 : }
1538 0 : gf_bs_align(bs);
1539 0 : pos = gf_bs_get_position(bs) - pos;
1540 0 : if (pos < size)
1541 0 : gf_bs_skip_bytes(bs, size - pos);
1542 :
1543 : }
1544 0 : gf_fprintf(dump, " </MHASFrame>\n");
1545 0 : }
1546 :
1547 : #endif
1548 :
1549 :
1550 1392 : static void finalize_dump(GF_InspectCtx *ctx, u32 streamtype, Bool concat)
1551 : {
1552 : char szLine[1025];
1553 1392 : u32 i, count = gf_list_count(ctx->src_pids);
1554 3534 : for (i=0; i<count; i++) {
1555 2142 : PidCtx *pctx = gf_list_get(ctx->src_pids, i);
1556 : //already done
1557 2142 : if (!pctx->tmp) continue;
1558 : //not our streamtype
1559 607 : if (streamtype && (pctx->stream_type!=streamtype)) continue;
1560 :
1561 290 : if (concat) {
1562 290 : gf_fseek(pctx->tmp, 0, SEEK_SET);
1563 21402 : while (!gf_feof(pctx->tmp)) {
1564 20822 : u32 read = (u32) gf_fread(szLine, 1024, pctx->tmp);
1565 20822 : gf_fwrite(szLine, read, ctx->dump);
1566 : }
1567 : }
1568 290 : gf_fclose(pctx->tmp);
1569 290 : if (ctx->xml)
1570 0 : gf_fprintf(ctx->dump, "</PIDInspect>\n");
1571 290 : pctx->tmp = NULL;
1572 : }
1573 1392 : }
1574 :
1575 437 : static void inspect_finalize(GF_Filter *filter)
1576 : {
1577 : Bool concat=GF_FALSE;
1578 437 : GF_InspectCtx *ctx = (GF_InspectCtx *) gf_filter_get_udta(filter);
1579 :
1580 437 : if (ctx->dump) {
1581 374 : if ((ctx->dump!=stderr) && (ctx->dump!=stdout)) concat=GF_TRUE;
1582 23 : else if (!ctx->interleave) concat=GF_TRUE;
1583 : }
1584 437 : if (!ctx->interleave) {
1585 232 : finalize_dump(ctx, GF_STREAM_AUDIO, concat);
1586 232 : finalize_dump(ctx, GF_STREAM_VISUAL, concat);
1587 232 : finalize_dump(ctx, GF_STREAM_SCENE, concat);
1588 232 : finalize_dump(ctx, GF_STREAM_OD, concat);
1589 232 : finalize_dump(ctx, GF_STREAM_TEXT, concat);
1590 232 : finalize_dump(ctx, 0, concat);
1591 : }
1592 :
1593 1004 : while (gf_list_count(ctx->src_pids)) {
1594 567 : PidCtx *pctx = gf_list_pop_front(ctx->src_pids);
1595 :
1596 : #ifndef GPAC_DISABLE_AV_PARSERS
1597 567 : if (pctx->avc_state) gf_free(pctx->avc_state);
1598 567 : if (pctx->hevc_state) gf_free(pctx->hevc_state);
1599 567 : if (pctx->vvc_state) gf_free(pctx->vvc_state);
1600 567 : if (pctx->av1_state) {
1601 2 : if (pctx->av1_state->config) gf_odf_av1_cfg_del(pctx->av1_state->config);
1602 2 : gf_av1_reset_state(pctx->av1_state, GF_TRUE);
1603 2 : gf_free(pctx->av1_state);
1604 : }
1605 : #endif
1606 567 : if (pctx->vpcc) gf_odf_vp_cfg_del(pctx->vpcc);
1607 567 : if (pctx->bs) gf_bs_del(pctx->bs);
1608 567 : gf_free(pctx);
1609 : }
1610 437 : gf_list_del(ctx->src_pids);
1611 :
1612 437 : if (ctx->dump) {
1613 374 : if (ctx->xml) gf_fprintf(ctx->dump, "</GPACInspect>\n");
1614 374 : if ((ctx->dump!=stderr) && (ctx->dump!=stdout)) {
1615 :
1616 : #ifdef GPAC_ENABLE_COVERAGE
1617 351 : if (gf_sys_is_cov_mode()) {
1618 351 : gf_fflush(ctx->dump);
1619 351 : gf_ferror(ctx->dump);
1620 : }
1621 : #endif
1622 351 : gf_fclose(ctx->dump);
1623 : }
1624 : }
1625 :
1626 437 : }
1627 :
1628 41 : static void dump_temi_loc(GF_InspectCtx *ctx, PidCtx *pctx, FILE *dump, const char *pname, const GF_PropertyValue *att)
1629 : {
1630 : u32 val;
1631 : Double dval;
1632 41 : if (ctx->xml) {
1633 0 : gf_fprintf(dump, " <TEMILocation");
1634 : } else {
1635 41 : gf_fprintf(dump, " TEMILocation");
1636 : }
1637 41 : if (!pctx->bs)
1638 3 : pctx->bs = gf_bs_new(att->value.data.ptr, att->value.data.size, GF_BITSTREAM_READ);
1639 : else
1640 38 : gf_bs_reassign_buffer(pctx->bs, att->value.data.ptr, att->value.data.size);
1641 :
1642 : while (1) {
1643 738 : u8 achar = gf_bs_read_u8(pctx->bs);
1644 738 : if (!achar) break;
1645 : }
1646 :
1647 82 : val = atoi(pname+7);
1648 :
1649 41 : DUMP_ATT_D("timeline", val)
1650 41 : DUMP_ATT_STR("url", att->value.data.ptr)
1651 41 : if (gf_bs_read_int(pctx->bs, 1)) {
1652 0 : DUMP_ATT_D("announce", 1)
1653 : }
1654 41 : if (gf_bs_read_int(pctx->bs, 1)) {
1655 0 : DUMP_ATT_D("splicing", 1)
1656 : }
1657 41 : if (gf_bs_read_int(pctx->bs, 1)) {
1658 0 : DUMP_ATT_D("reload", 1)
1659 : }
1660 41 : gf_bs_read_int(pctx->bs, 5);
1661 41 : dval = gf_bs_read_double(pctx->bs);
1662 41 : if (dval) {
1663 0 : DUMP_ATT_F("splice_start", dval)
1664 : }
1665 41 : dval = gf_bs_read_double(pctx->bs);
1666 41 : if (dval) {
1667 0 : DUMP_ATT_F("splice_end", dval)
1668 : }
1669 41 : if (ctx->xml) {
1670 0 : gf_fprintf(dump, "/>\n");
1671 : } else {
1672 41 : gf_fprintf(dump, "\n");
1673 : }
1674 41 : }
1675 :
1676 1351 : static void dump_temi_time(GF_InspectCtx *ctx, PidCtx *pctx, FILE *dump, const char *pname, const GF_PropertyValue *att)
1677 : {
1678 : u32 val;
1679 : u64 lval;
1680 1351 : if (ctx->xml) {
1681 0 : gf_fprintf(dump, " <TEMITiming");
1682 : } else {
1683 1351 : gf_fprintf(dump, " TEMITiming");
1684 : }
1685 2702 : val = atoi(pname+7);
1686 1351 : if (!pctx->bs)
1687 3 : pctx->bs = gf_bs_new(att->value.data.ptr, att->value.data.size, GF_BITSTREAM_READ);
1688 : else
1689 1348 : gf_bs_reassign_buffer(pctx->bs, att->value.data.ptr, att->value.data.size);
1690 :
1691 1351 : DUMP_ATT_D("timeline", val)
1692 1351 : val = gf_bs_read_u32(pctx->bs);
1693 1351 : DUMP_ATT_D("media_timescale", val)
1694 1351 : lval = gf_bs_read_u64(pctx->bs);
1695 1351 : DUMP_ATT_LLU("media_timestamp", lval)
1696 1351 : lval = gf_bs_read_u64(pctx->bs);
1697 1351 : DUMP_ATT_LLU("media_pts", lval)
1698 :
1699 1351 : if (gf_bs_read_int(pctx->bs, 1)) {
1700 0 : DUMP_ATT_D("reload", 1)
1701 : }
1702 1351 : if (gf_bs_read_int(pctx->bs, 1)) {
1703 0 : DUMP_ATT_D("paused", 1)
1704 : }
1705 1351 : if (gf_bs_read_int(pctx->bs, 1)) {
1706 0 : DUMP_ATT_D("discontinuity", 1)
1707 : }
1708 1351 : val = gf_bs_read_int(pctx->bs, 1);
1709 1351 : gf_bs_read_int(pctx->bs, 4);
1710 :
1711 1351 : if (val) {
1712 0 : lval = gf_bs_read_u64(pctx->bs);
1713 0 : DUMP_ATT_LLU("ntp", lval)
1714 : }
1715 1351 : if (ctx->xml) {
1716 0 : gf_fprintf(dump, "/>\n");
1717 : } else {
1718 1351 : gf_fprintf(dump, "\n");
1719 : }
1720 1351 : }
1721 :
1722 0 : static void gf_inspect_dump_truehd_frame(FILE *dump, GF_BitStream *bs)
1723 : {
1724 : u8 nibble;
1725 : u16 frame_size, timing;
1726 : u32 sync;
1727 0 : gf_fprintf(dump, " <TrueHDAudioFrame");
1728 0 : nibble = gf_bs_read_int(bs, 4);
1729 0 : frame_size = gf_bs_read_int(bs, 12);
1730 0 : timing = gf_bs_read_u16(bs);
1731 0 : sync = gf_bs_read_u32(bs);
1732 0 : gf_fprintf(dump, " nibble=\"%u\" size=\"%u\" timing=\"%u\"", nibble, frame_size, timing);
1733 0 : if (sync != 0xF8726FBA) {
1734 0 : gf_fprintf(dump, " major_sync=\"no\"/>\n");
1735 0 : return;
1736 : }
1737 0 : u32 fmt = gf_bs_read_u32(bs);
1738 0 : u32 sig = gf_bs_read_u16(bs);
1739 0 : u32 flags = gf_bs_read_u16(bs);
1740 0 : gf_bs_read_u16(bs);
1741 0 : Bool vrate = gf_bs_read_int(bs, 1);
1742 0 : u32 prate = gf_bs_read_int(bs, 15);
1743 0 : u32 nb_substreams = gf_bs_read_int(bs, 4);
1744 0 : gf_bs_read_int(bs, 2);
1745 0 : u32 ext_substream_info = gf_bs_read_int(bs, 2);
1746 0 : gf_fprintf(dump, " major_sync=\"yes\" format=\"%u\" signature=\"%u\" flags=\"0x%04X\" vrate=\"%u\" peak_data_rate=\"%u\" substreams=\"%u\" extended_substream_info=\"%u\" ", fmt, sig, flags, vrate, prate, nb_substreams, ext_substream_info);
1747 :
1748 0 : gf_fprintf(dump, "/>\n");
1749 : }
1750 :
1751 20602 : static void inspect_dump_property(GF_InspectCtx *ctx, FILE *dump, u32 p4cc, const char *pname, const GF_PropertyValue *att, PidCtx *pctx)
1752 : {
1753 : char szDump[GF_PROP_DUMP_ARG_SIZE];
1754 :
1755 20602 : if (!pname)
1756 17721 : pname = gf_props_4cc_get_name(p4cc);
1757 : else {
1758 : //all properties starting with __ are not dumped
1759 2881 : if (!strncmp(pname, "__", 2))
1760 1808 : return;
1761 2881 : if (!strcmp(pname, "isom_force_ctts"))
1762 : return;
1763 : }
1764 :
1765 20572 : if (p4cc==GF_PROP_PID_DOWNLOAD_SESSION)
1766 : return;
1767 :
1768 20523 : if (p4cc==GF_PROP_PID_CENC_KEY_INFO) {
1769 : u32 i, nb_keys, kpos;
1770 : u8 *data;
1771 33 : if (ctx->xml) {
1772 0 : if (ctx->dtype)
1773 0 : gf_fprintf(dump, " type=\"%s\"", gf_props_get_type_name(att->type) );
1774 0 : gf_fprintf(dump, " %s=\"", pname);
1775 : } else {
1776 33 : if (ctx->dtype) {
1777 0 : gf_fprintf(dump, "\t%s (%s): ", pname, gf_props_get_type_name(att->type));
1778 : } else {
1779 33 : gf_fprintf(dump, "\t%s: ", pname);
1780 : }
1781 : }
1782 33 : data = att->value.data.ptr;
1783 : nb_keys = 1;
1784 33 : if (data[0]) {
1785 0 : nb_keys = data[1];
1786 0 : nb_keys <<= 8;
1787 0 : nb_keys |= data[2];
1788 : }
1789 0 : if (nb_keys>1) gf_fprintf(dump, "[");
1790 : kpos = 3;
1791 66 : for (i=0; i<nb_keys; i++) {
1792 : u32 j;
1793 : bin128 KID;
1794 33 : u8 iv_size = data[kpos];
1795 33 : memcpy(KID, data+kpos+1, 16);
1796 33 : gf_fprintf(dump, "IV_size:%d,KID:0x", iv_size);
1797 561 : for (j=0; j<16; j++) {
1798 528 : gf_fprintf(dump, "%02X", (unsigned char) data[kpos + 1 + j]);
1799 : }
1800 33 : kpos+=17;
1801 33 : if (!iv_size) {
1802 0 : iv_size = data[kpos];
1803 0 : gf_fprintf(dump, ",const_IV_size:%d", iv_size);
1804 0 : if (iv_size) {
1805 0 : gf_fprintf(dump, ",const_IV:0x");
1806 0 : for (j=0; j<iv_size; j++) {
1807 0 : gf_fprintf(dump, "%02X", (unsigned char) data[kpos + 1 + j]);
1808 : }
1809 : }
1810 0 : kpos += iv_size+1;
1811 : }
1812 : }
1813 :
1814 33 : if (nb_keys>1) gf_fprintf(dump, "]");
1815 33 : if (ctx->xml) {
1816 0 : gf_fprintf(dump, "\"");
1817 : } else {
1818 33 : gf_fprintf(dump, "\n");
1819 : }
1820 :
1821 : return;
1822 : }
1823 :
1824 20490 : if (gf_sys_is_test_mode() || ctx->test) {
1825 20132 : switch (p4cc) {
1826 : case GF_PROP_PID_FILEPATH:
1827 : case GF_PROP_PID_URL:
1828 : case GF_PROP_PID_MUX_SRC:
1829 : return;
1830 812 : case GF_PROP_PID_FILE_CACHED:
1831 : case GF_PROP_PID_DURATION:
1832 812 : if ((ctx->test==INSPECT_TEST_NETWORK) || (ctx->test==INSPECT_TEST_NETX))
1833 : return;
1834 : break;
1835 889 : case GF_PROP_PID_DECODER_CONFIG:
1836 : case GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT:
1837 : case GF_PROP_PID_DOWN_SIZE:
1838 889 : if (ctx->test>=INSPECT_TEST_ENCODE)
1839 : return;
1840 : break;
1841 236 : case GF_PROP_PID_BITRATE:
1842 236 : if (ctx->test==INSPECT_TEST_NOBR)
1843 : return;
1844 : case GF_PROP_PID_MEDIA_DATA_SIZE:
1845 : case GF_PROP_PID_MAXRATE:
1846 : case GF_PROP_PID_AVG_FRAME_SIZE:
1847 : case GF_PROP_PID_MAX_FRAME_SIZE:
1848 : case GF_PROP_PID_DBSIZE:
1849 1117 : if (ctx->test==INSPECT_TEST_ENCX)
1850 : return;
1851 : break;
1852 :
1853 586 : case GF_PROP_PID_ISOM_TRACK_TEMPLATE:
1854 : case GF_PROP_PID_ISOM_MOVIE_TIME:
1855 586 : if (ctx->test==INSPECT_TEST_NETX)
1856 : return;
1857 : break;
1858 :
1859 479 : case GF_PROP_PID_ISOM_TREX_TEMPLATE:
1860 : case GF_PROP_PID_ISOM_STSD_TEMPLATE:
1861 : //TODO once all OK: remove this test and regenerate all hashes
1862 479 : if (gf_sys_is_test_mode())
1863 : return;
1864 : default:
1865 15128 : if (gf_sys_is_test_mode() && (att->type==GF_PROP_POINTER) )
1866 : return;
1867 : break;
1868 : }
1869 358 : }
1870 :
1871 18794 : if (ctx->xml) {
1872 240 : if (ctx->dtype)
1873 0 : gf_fprintf(dump, " type=\"%s\"", gf_props_get_type_name(att->type) );
1874 :
1875 243 : if (pname && (strchr(pname, ' ') || strchr(pname, ':'))) {
1876 : u32 i=0, k;
1877 3 : char *pname_no_space = gf_strdup(pname);
1878 50 : while (pname_no_space[i]) {
1879 44 : if (pname_no_space[i]==' ') pname_no_space[i]='_';
1880 44 : if (pname_no_space[i]==':') pname_no_space[i]='_';
1881 44 : i++;
1882 : }
1883 :
1884 3 : if ((att->type==GF_PROP_UINT_LIST) || (att->type==GF_PROP_4CC_LIST)) {
1885 0 : for (k=0; k < att->value.uint_list.nb_items; k++) {
1886 0 : if (k) gf_fprintf(dump, ", ");
1887 0 : if ((att->type==GF_PROP_4CC_LIST) && ! gf_sys_is_test_mode()) {
1888 0 : gf_fprintf(dump, "%s", gf_4cc_to_str(att->value.uint_list.vals[k]) );
1889 : } else {
1890 0 : gf_fprintf(dump, "%d", att->value.uint_list.vals[k]);
1891 : }
1892 : }
1893 3 : } else if (att->type==GF_PROP_STRING_LIST) {
1894 0 : for (k=0; k < att->value.string_list.nb_items; k++) {
1895 0 : if (k) gf_fprintf(dump, ", ");
1896 0 : gf_xml_dump_string(dump, NULL, (char *) att->value.string_list.vals[k], NULL);
1897 : }
1898 3 : } else if ((att->type==GF_PROP_STRING) || (att->type==GF_PROP_STRING_NO_COPY)) {
1899 0 : gf_xml_dump_string(dump, NULL, att->value.string, NULL);
1900 : } else {
1901 3 : gf_fprintf(dump, " %s=\"%s\"", pname_no_space, gf_props_dump(p4cc, att, szDump, (GF_PropDumDataMode) ctx->dump_data));
1902 : }
1903 3 : gf_free(pname_no_space);
1904 : } else {
1905 237 : gf_fprintf(dump, " %s=\"%s\"", pname ? pname : gf_4cc_to_str(p4cc), gf_props_dump(p4cc, att, szDump, (GF_PropDumDataMode) ctx->dump_data));
1906 : }
1907 : } else {
1908 18554 : if (ctx->dtype) {
1909 0 : gf_fprintf(dump, "\t%s (%s): ", pname ? pname : gf_4cc_to_str(p4cc), gf_props_get_type_name(att->type));
1910 : } else {
1911 18554 : if (!p4cc && !strncmp(pname, "temi_l", 6))
1912 41 : dump_temi_loc(ctx, pctx, dump, pname, att);
1913 18513 : else if (!p4cc && !strncmp(pname, "temi_t", 6))
1914 1351 : dump_temi_time(ctx, pctx, dump, pname, att);
1915 : else
1916 17162 : gf_fprintf(dump, "\t%s: ", pname ? pname : gf_4cc_to_str(p4cc));
1917 : }
1918 :
1919 18554 : if ((att->type==GF_PROP_UINT_LIST) || (att->type==GF_PROP_4CC_LIST)) {
1920 : u32 k;
1921 742 : for (k=0; k < att->value.uint_list.nb_items; k++) {
1922 742 : if (k) gf_fprintf(dump, ", ");
1923 742 : if ((att->type==GF_PROP_4CC_LIST) && ! gf_sys_is_test_mode()) {
1924 18 : gf_fprintf(dump, "%s", gf_4cc_to_str(att->value.uint_list.vals[k]) );
1925 : } else {
1926 724 : gf_fprintf(dump, "%d", att->value.uint_list.vals[k]);
1927 : }
1928 : }
1929 18226 : } else if (att->type==GF_PROP_STRING_LIST) {
1930 : u32 k;
1931 1 : for (k=0; k < att->value.string_list.nb_items; k++) {
1932 1 : if (k) gf_fprintf(dump, ", ");
1933 1 : gf_fprintf(dump, "%s", (const char *) att->value.string_list.vals[k]);
1934 : }
1935 : }else{
1936 18225 : gf_fprintf(dump, "%s", gf_props_dump(p4cc, att, szDump, (GF_PropDumDataMode) ctx->dump_data) );
1937 : }
1938 18554 : gf_fprintf(dump, "\n");
1939 : }
1940 : }
1941 :
1942 18746 : static void inspect_dump_packet_fmt(GF_InspectCtx *ctx, FILE *dump, GF_FilterPacket *pck, PidCtx *pctx, u64 pck_num)
1943 : {
1944 : char szDump[GF_PROP_DUMP_ARG_SIZE];
1945 18746 : u32 size=0;
1946 : const char *data=NULL;
1947 18746 : char *str = ctx->fmt;
1948 18746 : if (!dump) return;
1949 : assert(str);
1950 :
1951 18746 : if (pck) {
1952 18630 : data = gf_filter_pck_get_data(pck, &size);
1953 18630 : pctx->csize += size;
1954 : }
1955 :
1956 123676 : while (str) {
1957 : char csep;
1958 : char *sep, *key;
1959 123676 : if (!str[0]) break;
1960 :
1961 104930 : if ((str[0] != '$') && (str[0] != '%') && (str[0] != '@')) {
1962 33719 : gf_fprintf(dump, "%c", str[0]);
1963 33719 : str = str+1;
1964 33719 : continue;
1965 : }
1966 : csep = str[0];
1967 71211 : if (str[1] == csep) {
1968 0 : gf_fprintf(dump, "%c", str[0]);
1969 0 : str = str+2;
1970 0 : continue;
1971 : }
1972 71211 : sep = strchr(str+1, csep);
1973 71211 : if (!sep) {
1974 0 : gf_fprintf(dump, "%c", str[0]);
1975 : str = str+1;
1976 0 : continue;
1977 : }
1978 71211 : sep[0] = 0;
1979 : key = str+1;
1980 :
1981 71211 : if (!pck) {
1982 435 : if (!strcmp(key, "lf")) gf_fprintf(dump, "\n" );
1983 319 : else if (!strcmp(key, "cr")) gf_fprintf(dump, "\r" );
1984 319 : else if (!strcmp(key, "t")) gf_fprintf(dump, "\t" );
1985 319 : else if (!strncmp(key, "pid.", 4)) gf_fprintf(dump, "%s", key+4);
1986 319 : else gf_fprintf(dump, "%s", key);
1987 435 : sep[0] = csep;
1988 435 : str = sep+1;
1989 435 : continue;
1990 : }
1991 :
1992 70776 : if (!strcmp(key, "pn")) gf_fprintf(dump, LLU, pck_num);
1993 64441 : else if (!strcmp(key, "dts")) {
1994 14034 : u64 ts = gf_filter_pck_get_dts(pck);
1995 14034 : if (ts==GF_FILTER_NO_TS) gf_fprintf(dump, "N/A");
1996 13951 : else gf_fprintf(dump, LLU, ts );
1997 : }
1998 50407 : else if (!strcmp(key, "cts")) {
1999 17140 : u64 ts = gf_filter_pck_get_cts(pck);
2000 17140 : if (ts==GF_FILTER_NO_TS) gf_fprintf(dump, "N/A");
2001 16287 : else gf_fprintf(dump, LLU, ts );
2002 : }
2003 33267 : else if (!strcmp(key, "ddts")) {
2004 0 : u64 ts = gf_filter_pck_get_dts(pck);
2005 0 : if ((ts==GF_FILTER_NO_TS) || (pctx->prev_dts==GF_FILTER_NO_TS)) gf_fprintf(dump, "N/A");
2006 0 : else if (pctx->pck_num<=1) gf_fprintf(dump, "N/A");
2007 : else {
2008 : s64 diff = ts;
2009 0 : diff -= pctx->prev_dts;
2010 0 : gf_fprintf(dump, LLD, diff);
2011 : }
2012 0 : pctx->prev_dts = ts;
2013 : }
2014 33267 : else if (!strcmp(key, "dcts")) {
2015 0 : u64 ts = gf_filter_pck_get_cts(pck);
2016 0 : if ((ts==GF_FILTER_NO_TS) || (pctx->prev_cts==GF_FILTER_NO_TS)) gf_fprintf(dump, "N/A");
2017 0 : else if (pctx->pck_num<=1) gf_fprintf(dump, "N/A");
2018 : else {
2019 : s64 diff = ts;
2020 0 : diff -= pctx->prev_cts;
2021 0 : gf_fprintf(dump, LLD, diff);
2022 : }
2023 0 : pctx->prev_cts = ts;
2024 : }
2025 33267 : else if (!strcmp(key, "ctso")) {
2026 0 : u64 dts = gf_filter_pck_get_dts(pck);
2027 0 : u64 cts = gf_filter_pck_get_cts(pck);
2028 0 : if (dts==GF_FILTER_NO_TS) dts = cts;
2029 0 : if (cts==GF_FILTER_NO_TS) gf_fprintf(dump, "N/A");
2030 0 : else gf_fprintf(dump, LLD, ((s64)cts) - ((s64)dts) );
2031 : }
2032 :
2033 33267 : else if (!strcmp(key, "dur")) gf_fprintf(dump, "%u", gf_filter_pck_get_duration(pck) );
2034 33267 : else if (!strcmp(key, "frame")) {
2035 : Bool start, end;
2036 0 : gf_filter_pck_get_framing(pck, &start, &end);
2037 0 : if (start && end) gf_fprintf(dump, "frame_full");
2038 0 : else if (start) gf_fprintf(dump, "frame_start");
2039 0 : else if (end) gf_fprintf(dump, "frame_end");
2040 0 : else gf_fprintf(dump, "frame_cont");
2041 : }
2042 33267 : else if (!strcmp(key, "sap") || !strcmp(key, "rap")) {
2043 10041 : u32 sap = gf_filter_pck_get_sap(pck);
2044 10041 : if (sap==GF_FILTER_SAP_4_PROL) {
2045 0 : gf_fprintf(dump, "4 (prol)");
2046 : } else {
2047 10041 : gf_fprintf(dump, "%u", sap );
2048 : }
2049 : }
2050 23226 : else if (!strcmp(key, "ilace")) gf_fprintf(dump, "%d", gf_filter_pck_get_interlaced(pck) );
2051 23226 : else if (!strcmp(key, "corr")) gf_fprintf(dump, "%d", gf_filter_pck_get_corrupted(pck) );
2052 23226 : else if (!strcmp(key, "seek")) gf_fprintf(dump, "%d", gf_filter_pck_get_seek_flag(pck) );
2053 23226 : else if (!strcmp(key, "bo")) {
2054 774 : u64 bo = gf_filter_pck_get_byte_offset(pck);
2055 774 : if (bo==GF_FILTER_NO_BO) gf_fprintf(dump, "N/A");
2056 774 : else gf_fprintf(dump, LLU, bo);
2057 : }
2058 22452 : else if (!strcmp(key, "roll")) gf_fprintf(dump, "%d", gf_filter_pck_get_roll_info(pck) );
2059 22452 : else if (!strcmp(key, "crypt")) gf_fprintf(dump, "%d", gf_filter_pck_get_crypt_flags(pck) );
2060 22452 : else if (!strcmp(key, "vers")) gf_fprintf(dump, "%d", gf_filter_pck_get_carousel_version(pck) );
2061 22452 : else if (!strcmp(key, "size")) gf_fprintf(dump, "%d", size );
2062 18630 : else if (!strcmp(key, "csize")) gf_fprintf(dump, "%d", pctx->csize);
2063 18630 : else if (!strcmp(key, "crc")) gf_fprintf(dump, "0x%08X", gf_crc_32(data, size) );
2064 18630 : else if (!strcmp(key, "lf")) gf_fprintf(dump, "\n" );
2065 0 : else if (!strcmp(key, "cr")) gf_fprintf(dump, "\r" );
2066 0 : else if (!strcmp(key, "t")) gf_fprintf(dump, "\t" );
2067 0 : else if (!strcmp(key, "data")) {
2068 : u32 i;
2069 0 : for (i=0; i<size; i++) {
2070 0 : gf_fprintf(dump, "%02X", (unsigned char) data[i]);
2071 : }
2072 : }
2073 0 : else if (!strcmp(key, "lp")) {
2074 0 : u8 flags = gf_filter_pck_get_dependency_flags(pck);
2075 0 : flags >>= 6;
2076 0 : gf_fprintf(dump, "%u", flags);
2077 : }
2078 0 : else if (!strcmp(key, "depo")) {
2079 0 : u8 flags = gf_filter_pck_get_dependency_flags(pck);
2080 0 : flags >>= 4;
2081 0 : flags &= 0x3;
2082 0 : gf_fprintf(dump, "%u", flags);
2083 : }
2084 0 : else if (!strcmp(key, "depf")) {
2085 0 : u8 flags = gf_filter_pck_get_dependency_flags(pck);
2086 0 : flags >>= 2;
2087 0 : flags &= 0x3;
2088 0 : gf_fprintf(dump, "%u", flags);
2089 : }
2090 0 : else if (!strcmp(key, "red")) {
2091 0 : u8 flags = gf_filter_pck_get_dependency_flags(pck);
2092 0 : flags &= 0x3;
2093 0 : gf_fprintf(dump, "%u", flags);
2094 : }
2095 0 : else if (!strcmp(key, "ck")) gf_fprintf(dump, "%d", gf_filter_pck_get_clock_type(pck) );
2096 0 : else if (!strncmp(key, "pid.", 4)) {
2097 : const GF_PropertyValue *prop = NULL;
2098 : u32 prop_4cc=0;
2099 0 : const char *pkey = key+4;
2100 0 : prop_4cc = gf_props_get_id(pkey);
2101 0 : if (!prop_4cc && strlen(pkey)==4) prop_4cc = GF_4CC(pkey[0],pkey[1],pkey[2],pkey[3]);
2102 :
2103 0 : if (prop_4cc) {
2104 0 : prop = gf_filter_pid_get_property(pctx->src_pid, prop_4cc);
2105 : }
2106 0 : if (!prop) prop = gf_filter_pid_get_property_str(pctx->src_pid, key);
2107 :
2108 0 : if (prop) {
2109 0 : gf_fprintf(dump, "%s", gf_props_dump(prop_4cc, prop, szDump, (GF_PropDumDataMode) ctx->dump_data) );
2110 : }
2111 : }
2112 : else {
2113 : const GF_PropertyValue *prop = NULL;
2114 0 : u32 prop_4cc = gf_props_get_id(key);
2115 0 : if (!prop_4cc && strlen(key)==4) prop_4cc = GF_4CC(key[0],key[1],key[2],key[3]);
2116 :
2117 0 : if (prop_4cc) {
2118 0 : prop = gf_filter_pck_get_property(pck, prop_4cc);
2119 : }
2120 0 : if (!prop) prop = gf_filter_pck_get_property_str(pck, key);
2121 :
2122 0 : if (prop) {
2123 0 : gf_fprintf(dump, "%s", gf_props_dump(prop_4cc, prop, szDump, (GF_PropDumDataMode) ctx->dump_data) );
2124 : }
2125 : }
2126 :
2127 70776 : sep[0] = csep;
2128 70776 : str = sep+1;
2129 : }
2130 : }
2131 :
2132 : void gf_m4v_parser_set_inspect(GF_M4VParser *m4v);
2133 : u32 gf_m4v_parser_get_obj_type(GF_M4VParser *m4v);
2134 :
2135 : #ifndef GPAC_DISABLE_AV_PARSERS
2136 251 : static void inspect_dump_mpeg124(PidCtx *pctx, char *data, u32 size, FILE *dump)
2137 : {
2138 : u8 ftype;
2139 : u32 tinc, o_type;
2140 : u64 fsize, start;
2141 251 : Bool is_coded, is_m4v=(pctx->codec_id==GF_CODECID_MPEG4_PART2) ? GF_TRUE : GF_FALSE;
2142 : GF_Err e;
2143 251 : GF_M4VParser *m4v = gf_m4v_parser_new(data, size, !is_m4v);
2144 :
2145 251 : gf_m4v_parser_set_inspect(m4v);
2146 : while (1) {
2147 507 : ftype = 0;
2148 507 : is_coded = GF_FALSE;
2149 507 : e = gf_m4v_parse_frame(m4v, &pctx->dsi, &ftype, &tinc, &fsize, &start, &is_coded);
2150 507 : if (e)
2151 : break;
2152 :
2153 256 : o_type = gf_m4v_parser_get_obj_type(m4v);
2154 256 : if (is_m4v) {
2155 256 : gf_fprintf(dump, "<MPEG4P2VideoObj type=\"0x%02X\"", o_type);
2156 256 : switch (o_type) {
2157 : /*vosh*/
2158 1 : case M4V_VOS_START_CODE:
2159 1 : gf_fprintf(dump, " name=\"VOS\" PL=\"%d\"", pctx->dsi.VideoPL);
2160 1 : break;
2161 1 : case M4V_VOL_START_CODE:
2162 1 : gf_fprintf(dump, " name=\"VOL\" RAPStream=\"%d\" objectType=\"%d\" par=\"%d/%d\" hasShape=\"%d\"", pctx->dsi.RAP_stream, pctx->dsi.objectType, pctx->dsi.par_num, pctx->dsi.par_den, pctx->dsi.has_shape);
2163 1 : if (pctx->dsi.clock_rate)
2164 1 : gf_fprintf(dump, " clockRate=\"%d\"", pctx->dsi.clock_rate);
2165 1 : if (pctx->dsi.time_increment)
2166 1 : gf_fprintf(dump, " timeIncrement=\"%d\"", pctx->dsi.time_increment);
2167 1 : if (!pctx->dsi.has_shape)
2168 1 : gf_fprintf(dump, " width=\"%d\" height=\"%d\"", pctx->dsi.width, pctx->dsi.height);
2169 :
2170 : break;
2171 :
2172 250 : case M4V_VOP_START_CODE:
2173 250 : gf_fprintf(dump, " name=\"VOP\" RAP=\"%d\" frameType=\"%d\" timeInc=\"%d\" isCoded=\"%d\"", (ftype==0) ? 1 : 0, ftype, tinc, is_coded);
2174 250 : break;
2175 0 : case M4V_GOV_START_CODE:
2176 0 : gf_fprintf(dump, " name=\"GOV\"");
2177 0 : break;
2178 : /*don't interest us*/
2179 2 : case M4V_UDTA_START_CODE:
2180 2 : gf_fprintf(dump, " name=\"UDTA\"");
2181 2 : break;
2182 :
2183 1 : case M4V_VO_START_CODE:
2184 1 : gf_fprintf(dump, " name=\"VO\"");
2185 1 : break;
2186 1 : case M4V_VISOBJ_START_CODE:
2187 1 : gf_fprintf(dump, " name=\"VisObj\"");
2188 1 : break;
2189 : default:
2190 : break;
2191 : }
2192 256 : gf_fprintf(dump, "/>\n");
2193 : } else {
2194 0 : gf_fprintf(dump, "<MPEG12VideoObj type=\"0x%02X\"", o_type);
2195 0 : switch (o_type) {
2196 0 : case M2V_SEQ_START_CODE:
2197 0 : gf_fprintf(dump, " name=\"SeqStart\" width=\"%d\" height=\"%d\" sar=\"%d/%d\" fps=\"%f\"", pctx->dsi.width, pctx->dsi.height, pctx->dsi.par_num, pctx->dsi.par_den, pctx->dsi.fps);
2198 0 : break;
2199 :
2200 0 : case M2V_EXT_START_CODE:
2201 0 : gf_fprintf(dump, " name=\"SeqStartEXT\" width=\"%d\" height=\"%d\" PL=\"%d\"", pctx->dsi.width, pctx->dsi.height, pctx->dsi.VideoPL);
2202 0 : break;
2203 0 : case M2V_PIC_START_CODE:
2204 0 : gf_fprintf(dump, " name=\"PicStart\" frameType=\"%d\" isCoded=\"%d\"", ftype, is_coded);
2205 0 : break;
2206 0 : case M2V_GOP_START_CODE:
2207 0 : gf_fprintf(dump, " name=\"GOPStart\"");
2208 0 : break;
2209 : default:
2210 : break;
2211 : }
2212 0 : gf_fprintf(dump, "/>\n");
2213 : }
2214 : }
2215 251 : gf_m4v_parser_del(m4v);
2216 251 : }
2217 : #endif
2218 :
2219 2 : static void inspect_format_tmcd_internal(const u8 *data, u32 size, u32 tmcd_flags, u32 tc_num, u32 tc_den, u32 tmcd_fpt, char szFmt[100], GF_BitStream *bs, Bool force_ff, FILE *dump)
2220 : {
2221 : u32 h, m, s, f, value;
2222 : Bool neg=GF_FALSE;
2223 : u32 parse_fmt = 1;
2224 : Bool is_drop = GF_FALSE;
2225 : GF_BitStream *loc_bs = NULL;
2226 :
2227 2 : if (szFmt)
2228 1 : szFmt[0] = 0;
2229 :
2230 2 : if (!tc_num || !tc_den)
2231 : return;
2232 :
2233 2 : if (!bs) {
2234 1 : loc_bs = gf_bs_new(data, size, GF_BITSTREAM_READ);
2235 : bs = loc_bs;
2236 : } else {
2237 1 : gf_bs_reassign_buffer(bs, data, size);
2238 : }
2239 :
2240 2 : value = gf_bs_read_u32(bs);
2241 2 : gf_bs_seek(bs, 0);
2242 :
2243 2 : if (tmcd_flags & 0x00000001)
2244 : is_drop = GF_TRUE;
2245 :
2246 2 : if (tmcd_flags & 0x00000004)
2247 : neg = GF_TRUE;
2248 :
2249 2 : if (dump)
2250 1 : gf_fprintf(dump, "<TimeCode");
2251 :
2252 2 : if (!force_ff && !(tmcd_flags & 0x00000008)) {
2253 2 : h = gf_bs_read_u8(bs);
2254 2 : neg = gf_bs_read_int(bs, 1);
2255 2 : m = gf_bs_read_int(bs, 7);
2256 2 : s = gf_bs_read_u8(bs);
2257 2 : f = gf_bs_read_u8(bs);
2258 :
2259 2 : if (tmcd_fpt && (f > tmcd_fpt))
2260 : parse_fmt = 2;
2261 0 : else if ((m>=60) || (s>=60))
2262 : parse_fmt = 2;
2263 : else
2264 : parse_fmt = 0;
2265 : }
2266 :
2267 2 : if (parse_fmt) {
2268 2 : u64 nb_secs, nb_frames = value;
2269 : neg = GF_FALSE;
2270 2 : if (parse_fmt==2) force_ff = GF_TRUE;
2271 :
2272 2 : if (!force_ff && tmcd_fpt)
2273 0 : nb_frames *= tmcd_fpt;
2274 :
2275 2 : if (is_drop && tc_num) {
2276 : u32 tc_drop_frames, min_10;
2277 :
2278 : nb_secs = nb_frames;
2279 2 : nb_secs *= tc_den;
2280 2 : nb_secs /= tc_num;
2281 :
2282 2 : m = (u32) (nb_secs/60);
2283 :
2284 2 : min_10 = m / 10;
2285 2 : m-= min_10;
2286 :
2287 2 : tc_drop_frames = m*2;
2288 2 : nb_frames += tc_drop_frames;
2289 : }
2290 :
2291 2 : if (!tmcd_fpt) tmcd_fpt = 30;
2292 :
2293 2 : nb_secs = nb_frames / tmcd_fpt;
2294 2 : h = (u32) nb_secs/3600;
2295 2 : m = (u32) (nb_secs/60 - h*60);
2296 2 : s = (u32) (nb_secs - m*60 - h*3600);
2297 :
2298 2 : nb_secs *= tmcd_fpt;
2299 :
2300 2 : f = (u32) (nb_frames - nb_secs);
2301 2 : if (tmcd_fpt && (f==tmcd_fpt)) {
2302 : f = 0;
2303 0 : s++;
2304 0 : if (s==60) {
2305 : s = 0;
2306 0 : m++;
2307 0 : if (m==60) {
2308 : m = 0;
2309 0 : h++;
2310 : }
2311 : }
2312 : }
2313 : }
2314 2 : if (dump)
2315 1 : gf_fprintf(dump, " time=\"%s%02d:%02d:%02d%c%02d\"/>\n", neg ? "-" : "", h, m, s, is_drop ? ';' : ':', f);
2316 1 : else if (szFmt)
2317 1 : sprintf(szFmt, "%s%02d:%02d:%02d%c%02d", neg ? "-" : "", h, m, s, is_drop ? ';' : ':', f);
2318 :
2319 2 : if (loc_bs) gf_bs_del(loc_bs);
2320 : }
2321 :
2322 :
2323 : GF_EXPORT
2324 1 : void gf_inspect_format_timecode(const u8 *data, u32 size, u32 tmcd_flags, u32 tc_num, u32 tc_den, u32 tmcd_fpt, char szFmt[100])
2325 : {
2326 1 : inspect_format_tmcd_internal(data, size, tmcd_flags, tc_num, tc_den, tmcd_fpt, szFmt, NULL, GF_FALSE, NULL);
2327 1 : }
2328 :
2329 1 : static void inspect_dump_tmcd(GF_InspectCtx *ctx, PidCtx *pctx, const u8 *data, u32 size, FILE *dump)
2330 : {
2331 1 : inspect_format_tmcd_internal(data, size, pctx->tmcd_flags, pctx->tmcd_rate.num, pctx->tmcd_rate.den, pctx->tmcd_fpt, NULL, pctx->bs, ctx->fftmcd, dump);
2332 1 : }
2333 :
2334 348 : static void inspect_dump_vpx(GF_InspectCtx *ctx, FILE *dump, u8 *ptr, u64 frame_size, Bool dump_crc, PidCtx *pctx, u32 vpversion)
2335 : {
2336 : GF_Err e;
2337 348 : Bool key_frame = GF_FALSE;
2338 348 : u32 width = 0, height = 0, renderWidth, renderHeight;
2339 348 : u32 num_frames_in_superframe = 0, superframe_index_size = 0, i = 0;
2340 : u32 frame_sizes[VP9_MAX_FRAMES_IN_SUPERFRAME];
2341 348 : gf_bs_reassign_buffer(pctx->bs, ptr, frame_size);
2342 : InspectLogCbk lcbk;
2343 :
2344 348 : if (ctx->analyze>=INSPECT_ANALYZE_BS) {
2345 174 : lcbk.dump = dump;
2346 174 : lcbk.dump_bits = ctx->analyze==INSPECT_ANALYZE_BS_BITS ? GF_TRUE : GF_FALSE;
2347 174 : gf_bs_set_logger(pctx->bs, regular_bs_log, &lcbk);
2348 : }
2349 :
2350 : /*check if it is a superframe*/
2351 348 : e = gf_media_vp9_parse_superframe(pctx->bs, frame_size, &num_frames_in_superframe, frame_sizes, &superframe_index_size);
2352 :
2353 348 : gf_fprintf(dump, "<VP%d%sFrame", vpversion, superframe_index_size ? "Super" : "");
2354 348 : if (e) {
2355 0 : gf_fprintf(dump, " status=\"error parsing superframe\"/>\n");
2356 0 : gf_bs_set_logger(pctx->bs, NULL, NULL);
2357 0 : return;
2358 : }
2359 348 : if (superframe_index_size)
2360 0 : gf_fprintf(dump, " nb_frames=\"%u\" index_size=\"%u\">\n", num_frames_in_superframe, superframe_index_size);
2361 : else {
2362 : assert(num_frames_in_superframe==1);
2363 : }
2364 348 : for (i = 0; i < num_frames_in_superframe; ++i) {
2365 348 : u64 pos2 = gf_bs_get_position(pctx->bs);
2366 :
2367 348 : if (superframe_index_size)
2368 0 : gf_fprintf(dump, "<VP%dFrame", vpversion);
2369 :
2370 348 : gf_fprintf(dump, " size=\"%u\"", frame_sizes[i]);
2371 348 : if (gf_media_vp9_parse_sample(pctx->bs, pctx->vpcc, &key_frame, &width, &height, &renderWidth, &renderHeight) != GF_OK) {
2372 0 : gf_fprintf(dump, " status=\"error parsing frame\"/>\n");
2373 : goto exit;
2374 : }
2375 348 : gf_fprintf(dump, " key_frame=\"%u\" width=\"%u\" height=\"%u\" renderWidth=\"%u\" renderHeight=\"%u\"", key_frame, width, height, renderWidth, renderHeight);
2376 348 : e = gf_bs_seek(pctx->bs, pos2 + frame_sizes[i]);
2377 348 : if (e) {
2378 0 : gf_fprintf(dump, " status=\"error seeking %s (offset "LLU")\"/>\n", gf_error_to_string(e), pos2 + frame_sizes[i]);
2379 : goto exit;
2380 : }
2381 :
2382 348 : gf_fprintf(dump, "/>\n");
2383 : }
2384 :
2385 348 : exit:
2386 348 : if (superframe_index_size)
2387 0 : gf_fprintf(dump, "</VP%dSuperFrame>\n", vpversion);
2388 348 : gf_bs_set_logger(pctx->bs, NULL, NULL);
2389 : }
2390 :
2391 1724 : static void inspect_dump_ac3_eac3(GF_InspectCtx *ctx, FILE *dump, u8 *ptr, u64 frame_size, Bool dump_crc, PidCtx *pctx, Bool is_ec3)
2392 : {
2393 : GF_AC3Header hdr;
2394 : InspectLogCbk lcbk;
2395 :
2396 1724 : if (!pctx->bs) pctx->bs = gf_bs_new(ptr, frame_size, GF_BITSTREAM_READ);
2397 1724 : else gf_bs_reassign_buffer(pctx->bs, ptr, frame_size);
2398 :
2399 1724 : if (ctx->analyze>=INSPECT_ANALYZE_BS) {
2400 862 : lcbk.dump = dump;
2401 862 : lcbk.dump_bits = ctx->analyze==INSPECT_ANALYZE_BS_BITS ? GF_TRUE : GF_FALSE;
2402 862 : gf_bs_set_logger(pctx->bs, regular_bs_log, &lcbk);
2403 : }
2404 1724 : gf_fprintf(dump, "<%sSample ", is_ec3 ? "EC3" : "AC3");
2405 : memset(&hdr, 0, sizeof(GF_AC3Header));
2406 1724 : gf_ac3_parser_bs(pctx->bs, &hdr, GF_TRUE);
2407 1724 : if (ctx->analyze<INSPECT_ANALYZE_BS) {
2408 862 : gf_fprintf(dump, "bitrate=\"%u\" channels=\"%u\" framesize=\"%u\"", hdr.bitrate, hdr.channels, hdr.framesize);
2409 862 : if (hdr.is_ec3) {
2410 0 : gf_fprintf(dump, " nb_streams=\"%u\" ", hdr.nb_streams);
2411 : }
2412 : }
2413 :
2414 1724 : gf_fprintf(dump, "/>\n");
2415 1724 : gf_bs_set_logger(pctx->bs, NULL, NULL);
2416 1724 : }
2417 :
2418 138427 : static void inspect_dump_packet(GF_InspectCtx *ctx, FILE *dump, GF_FilterPacket *pck, u32 pid_idx, u64 pck_num, PidCtx *pctx)
2419 : {
2420 138427 : u32 idx=0, size, sap;
2421 : u64 ts;
2422 : u8 dflags = 0;
2423 : GF_FilterClockType ck_type;
2424 : GF_FilterFrameInterface *fifce=NULL;
2425 : Bool start, end;
2426 : u8 *data;
2427 272290 : if (!dump) return;
2428 :
2429 138427 : if (!ctx->deep && !ctx->fmt) return;
2430 :
2431 138427 : data = (u8 *) gf_filter_pck_get_data(pck, &size);
2432 138427 : gf_filter_pck_get_framing(pck, &start, &end);
2433 :
2434 138427 : ck_type = ctx->pcr ? gf_filter_pck_get_clock_type(pck) : 0;
2435 138427 : if (!size && !ck_type) {
2436 607 : fifce = gf_filter_pck_get_frame_interface(pck);
2437 607 : if (!fifce) return;
2438 : }
2439 :
2440 138425 : if (ctx->xml) {
2441 4564 : gf_fprintf(dump, "<Packet number=\""LLU"\"", pck_num);
2442 4564 : if (ctx->interleave)
2443 4564 : gf_fprintf(dump, " PID=\"%d\"", pid_idx);
2444 : } else {
2445 133861 : gf_fprintf(dump, "PID %d PCK "LLU" - ", pid_idx, pck_num);
2446 : }
2447 138425 : if (ck_type) {
2448 3503 : ts = gf_filter_pck_get_cts(pck);
2449 3503 : if (ctx->xml) {
2450 0 : if (ts==GF_FILTER_NO_TS) gf_fprintf(dump, " PCR=\"N/A\"");
2451 0 : else gf_fprintf(dump, " PCR=\""LLU"\" ", ts );
2452 0 : if (ck_type!=GF_FILTER_CLOCK_PCR) gf_fprintf(dump, " discontinuity=\"true\"");
2453 0 : gf_fprintf(dump, "/>");
2454 : } else {
2455 3503 : if (ts==GF_FILTER_NO_TS) gf_fprintf(dump, " PCR N/A");
2456 3503 : else gf_fprintf(dump, " PCR%s "LLU"\n", (ck_type==GF_FILTER_CLOCK_PCR) ? "" : " discontinuity", ts );
2457 : }
2458 : return;
2459 : }
2460 134922 : if (ctx->xml) {
2461 4564 : if (fifce) gf_fprintf(dump, " framing=\"interface\"");
2462 4564 : else if (start && end) gf_fprintf(dump, " framing=\"complete\"");
2463 0 : else if (start) gf_fprintf(dump, " framing=\"start\"");
2464 0 : else if (end) gf_fprintf(dump, " framing=\"end\"");
2465 0 : else gf_fprintf(dump, " framing=\"continuation\"");
2466 : } else {
2467 130358 : if (fifce) gf_fprintf(dump, "interface");
2468 129753 : else if (start && end) gf_fprintf(dump, "full frame");
2469 4 : else if (start) gf_fprintf(dump, "frame start");
2470 2 : else if (end) gf_fprintf(dump, "frame end");
2471 0 : else gf_fprintf(dump, "frame continuation");
2472 : }
2473 134922 : ts = gf_filter_pck_get_dts(pck);
2474 134922 : if (ts==GF_FILTER_NO_TS) DUMP_ATT_STR("dts", "N/A")
2475 134919 : else DUMP_ATT_LLU("dts", ts )
2476 :
2477 134922 : ts = gf_filter_pck_get_cts(pck);
2478 134922 : if (ts==GF_FILTER_NO_TS) DUMP_ATT_STR("cts", "N/A")
2479 134919 : else DUMP_ATT_LLU("cts", ts )
2480 :
2481 134922 : DUMP_ATT_U("dur", gf_filter_pck_get_duration(pck) )
2482 134922 : sap = gf_filter_pck_get_sap(pck);
2483 134922 : if (sap==GF_FILTER_SAP_4_PROL) {
2484 0 : DUMP_ATT_STR(sap, "4 (prol)");
2485 : } else {
2486 134922 : DUMP_ATT_U("sap", gf_filter_pck_get_sap(pck) )
2487 : }
2488 134922 : DUMP_ATT_D("ilace", gf_filter_pck_get_interlaced(pck) )
2489 134922 : DUMP_ATT_D("corr", gf_filter_pck_get_corrupted(pck) )
2490 134922 : DUMP_ATT_D("seek", gf_filter_pck_get_seek_flag(pck) )
2491 :
2492 134922 : ts = gf_filter_pck_get_byte_offset(pck);
2493 134922 : if (ts==GF_FILTER_NO_BO) DUMP_ATT_STR("bo", "N/A")
2494 5470 : else DUMP_ATT_LLU("bo", ts )
2495 :
2496 134922 : DUMP_ATT_U("roll", gf_filter_pck_get_roll_info(pck) )
2497 134922 : DUMP_ATT_U("crypt", gf_filter_pck_get_crypt_flags(pck) )
2498 134922 : DUMP_ATT_U("vers", gf_filter_pck_get_carousel_version(pck) )
2499 :
2500 134922 : if (!fifce) {
2501 134317 : DUMP_ATT_U("size", size )
2502 : }
2503 134922 : dflags = gf_filter_pck_get_dependency_flags(pck);
2504 134922 : DUMP_ATT_U("lp", (dflags>>6) & 0x3 )
2505 134922 : DUMP_ATT_U("depo", (dflags>>4) & 0x3 )
2506 134922 : DUMP_ATT_U("depf", (dflags>>2) & 0x3 )
2507 134922 : DUMP_ATT_U("red", (dflags) & 0x3 )
2508 :
2509 134922 : if (!data) size = 0;
2510 134922 : if (ctx->dump_data) {
2511 : u32 i;
2512 0 : DUMP_ATT_STR("data", "")
2513 0 : for (i=0; i<size; i++) {
2514 0 : gf_fprintf(dump, "%02X", (unsigned char) data[i]);
2515 : }
2516 0 : if (ctx->xml) gf_fprintf(dump, "\"");
2517 134922 : } else if (fifce) {
2518 : u32 i;
2519 605 : char *name = fifce->get_gl_texture ? "Interface_GLTexID" : "Interface_NumPlanes";
2520 605 : if (ctx->xml) {
2521 0 : gf_fprintf(dump, " %s=\"", name);
2522 : } else {
2523 605 : gf_fprintf(dump, " %s ", name);
2524 : }
2525 605 : for (i=0; i<4; i++) {
2526 1210 : if (fifce->get_gl_texture) {
2527 : GF_Matrix mx;
2528 1210 : gf_mx_init(mx);
2529 : u32 gl_tex_format, gl_tex_id;
2530 1210 : if (fifce->get_gl_texture(fifce, i, &gl_tex_format, &gl_tex_id, &mx) != GF_OK)
2531 : break;
2532 605 : if (i) gf_fprintf(dump, ",");
2533 605 : gf_fprintf(dump, "%d", gl_tex_id);
2534 : } else {
2535 : u32 stride;
2536 : const u8 *plane;
2537 0 : if (fifce->get_plane(fifce, i, &plane, &stride) != GF_OK)
2538 : break;
2539 : }
2540 : }
2541 605 : if (!fifce->get_gl_texture) {
2542 0 : gf_fprintf(dump, "%d", i);
2543 : }
2544 :
2545 605 : if (ctx->xml) {
2546 0 : gf_fprintf(dump, "\"");
2547 : }
2548 134317 : } else if (data && (ctx->test!=INSPECT_TEST_NOCRC) ) {
2549 134227 : DUMP_ATT_X("CRC32", gf_crc_32(data, size) )
2550 : }
2551 134922 : if (ctx->xml) {
2552 4564 : if (!ctx->props) goto props_done;
2553 :
2554 : } else {
2555 130358 : gf_fprintf(dump, "\n");
2556 : }
2557 :
2558 134922 : if (!ctx->props) return;
2559 5072 : while (1) {
2560 : u32 prop_4cc;
2561 : const char *prop_name;
2562 139994 : const GF_PropertyValue * p = gf_filter_pck_enum_properties(pck, &idx, &prop_4cc, &prop_name);
2563 139994 : if (!p) break;
2564 5072 : if (idx==0) gf_fprintf(dump, "properties:\n");
2565 :
2566 5072 : inspect_dump_property(ctx, dump, prop_4cc, prop_name, p, pctx);
2567 : }
2568 :
2569 :
2570 134922 : props_done:
2571 134922 : if (!ctx->analyze) {
2572 130358 : if (ctx->xml) {
2573 0 : gf_fprintf(dump, "/>\n");
2574 : }
2575 : return;
2576 : }
2577 4564 : gf_fprintf(dump, ">\n");
2578 :
2579 : #ifndef GPAC_DISABLE_AV_PARSERS
2580 4564 : if (pctx->hevc_state || pctx->avc_state || pctx->vvc_state) {
2581 850 : idx=1;
2582 :
2583 850 : if (pctx->is_adobe_protected && size) {
2584 0 : u8 encrypted_au = data[0];
2585 0 : if (encrypted_au) {
2586 0 : gf_fprintf(dump, " <!-- Packet is an Adobe's protected frame and can not be dumped -->\n");
2587 0 : gf_fprintf(dump, "</Packet>\n");
2588 0 : return;
2589 : }
2590 : else {
2591 0 : data++;
2592 0 : size--;
2593 : }
2594 : }
2595 6296 : while (size) {
2596 5446 : u32 nal_size = inspect_get_nal_size((char*)data, pctx->nalu_size_length);
2597 5446 : data += pctx->nalu_size_length;
2598 :
2599 5446 : if (pctx->nalu_size_length + nal_size > size) {
2600 0 : gf_fprintf(dump, " <!-- NALU is corrupted: size is %d but only %d remains -->\n", nal_size, size);
2601 0 : break;
2602 : } else {
2603 5446 : gf_fprintf(dump, " <NALU size=\"%d\" ", nal_size);
2604 5446 : gf_inspect_dump_nalu_internal(dump, data, nal_size, pctx->has_svcc ? 1 : 0, pctx->hevc_state, pctx->avc_state, pctx->vvc_state, pctx->nalu_size_length, ctx->crc, pctx->is_cenc_protected, ctx->analyze, pctx);
2605 : }
2606 5446 : idx++;
2607 5446 : data += nal_size;
2608 5446 : size -= nal_size + pctx->nalu_size_length;
2609 : }
2610 3714 : } else if (pctx->av1_state) {
2611 346 : gf_bs_reassign_buffer(pctx->bs, data, size);
2612 1074 : while (size) {
2613 : ObuType obu_type = 0;
2614 : u64 obu_size = 0;
2615 : u32 hdr_size = 0;
2616 :
2617 :
2618 382 : obu_size = gf_inspect_dump_obu_internal(dump, pctx->av1_state, (char *) data, obu_size, obu_type, obu_size, hdr_size, ctx->crc, pctx, ctx->analyze);
2619 :
2620 382 : if (obu_size > size) {
2621 0 : gf_fprintf(dump, " <!-- OBU is corrupted: size is %d but only %d remains -->\n", (u32) obu_size, size);
2622 0 : break;
2623 : }
2624 382 : data += obu_size;
2625 382 : size -= (u32)obu_size;
2626 382 : idx++;
2627 : }
2628 : } else {
2629 : u32 hdr, pos, fsize, i;
2630 3368 : switch (pctx->codec_id) {
2631 250 : case GF_CODECID_MPEG1:
2632 : case GF_CODECID_MPEG2_422:
2633 : case GF_CODECID_MPEG2_SNR:
2634 : case GF_CODECID_MPEG2_HIGH:
2635 : case GF_CODECID_MPEG2_MAIN:
2636 : case GF_CODECID_MPEG4_PART2:
2637 250 : inspect_dump_mpeg124(pctx, (char *) data, size, dump);
2638 250 : break;
2639 385 : case GF_CODECID_MPEG_AUDIO:
2640 : case GF_CODECID_MPEG2_PART3:
2641 385 : pos = 0;
2642 1155 : while (size) {
2643 385 : hdr = gf_mp3_get_next_header_mem(data, size, &pos);
2644 385 : fsize = gf_mp3_frame_size(hdr);
2645 385 : gf_fprintf(dump, "<MPEGAudioFrame size=\"%d\" layer=\"%d\" version=\"%d\" bitrate=\"%d\" channels=\"%d\" samplesPerFrame=\"%d\" samplerate=\"%d\"/>\n", fsize, gf_mp3_layer(hdr), gf_mp3_version(hdr), gf_mp3_bit_rate(hdr), gf_mp3_num_channels(hdr), gf_mp3_window_size(hdr), gf_mp3_sampling_rate(hdr));
2646 385 : if (size<pos+fsize) break;
2647 385 : data += pos + fsize;
2648 385 : size -= pos + fsize;
2649 : }
2650 : break;
2651 1 : case GF_CODECID_TMCD:
2652 1 : inspect_dump_tmcd(ctx, pctx, (char *) data, size, dump);
2653 1 : break;
2654 0 : case GF_CODECID_SUBS_TEXT:
2655 : case GF_CODECID_META_TEXT:
2656 0 : gf_fprintf(dump, "<![CDATA[");
2657 0 : for (i=0; i<size; i++) {
2658 0 : gf_fputc(data[i], dump);
2659 : }
2660 0 : gf_fprintf(dump, "]]>\n");
2661 0 : break;
2662 : case GF_CODECID_SUBS_XML:
2663 : case GF_CODECID_META_XML:
2664 0 : for (i=0; i<size; i++) {
2665 0 : gf_fputc(data[i], dump);
2666 : }
2667 : break;
2668 0 : case GF_CODECID_APCH:
2669 : case GF_CODECID_APCO:
2670 : case GF_CODECID_APCN:
2671 : case GF_CODECID_APCS:
2672 : case GF_CODECID_AP4X:
2673 : case GF_CODECID_AP4H:
2674 0 : gf_inspect_dump_prores_internal(dump, (char *) data, size, ctx->crc, pctx);
2675 0 : break;
2676 :
2677 0 : case GF_CODECID_MPHA:
2678 0 : gf_bs_reassign_buffer(pctx->bs, data, size);
2679 0 : gf_inspect_dump_mha_frame(dump, pctx->bs, "");
2680 0 : break;
2681 :
2682 0 : case GF_CODECID_MHAS:
2683 0 : gf_inspect_dump_mhas(dump, (char *) data, size, ctx->crc, pctx);
2684 0 : break;
2685 0 : case GF_CODECID_VP8:
2686 0 : inspect_dump_vpx(ctx, dump, (char *) data, size, ctx->crc, pctx, 8);
2687 0 : break;
2688 348 : case GF_CODECID_VP9:
2689 348 : inspect_dump_vpx(ctx, dump, (char *) data, size, ctx->crc, pctx, 9);
2690 348 : break;
2691 1724 : case GF_CODECID_AC3:
2692 1724 : inspect_dump_ac3_eac3(ctx, dump, (char *) data, size, ctx->crc, pctx, 0);
2693 1724 : break;
2694 0 : case GF_CODECID_EAC3:
2695 0 : inspect_dump_ac3_eac3(ctx, dump, (char *) data, size, ctx->crc, pctx, 1);
2696 0 : break;
2697 0 : case GF_CODECID_TRUEHD:
2698 0 : gf_bs_reassign_buffer(pctx->bs, data, size);
2699 0 : gf_inspect_dump_truehd_frame(dump, pctx->bs);
2700 0 : break;
2701 : }
2702 : }
2703 : #endif
2704 4564 : gf_fprintf(dump, "</Packet>\n");
2705 : }
2706 :
2707 : #define DUMP_ARRAY(arr, name, loc, _is_svc)\
2708 : if (arr && gf_list_count(arr)) {\
2709 : gf_fprintf(dump, " <%sArray location=\"%s\">\n", name, loc);\
2710 : for (i=0; i<gf_list_count(arr); i++) {\
2711 : slc = gf_list_get(arr, i);\
2712 : gf_fprintf(dump, " <NALU size=\"%d\" ", slc->size);\
2713 : gf_inspect_dump_nalu_internal(dump, slc->data, slc->size, _is_svc, pctx->hevc_state, pctx->avc_state, pctx->vvc_state, nalh_size, ctx->crc, GF_FALSE, ctx->analyze, pctx);\
2714 : }\
2715 : gf_fprintf(dump, " </%sArray>\n", name);\
2716 : }\
2717 :
2718 :
2719 : #ifndef GPAC_DISABLE_AV_PARSERS
2720 9 : static void inspect_reset_parsers(PidCtx *pctx, void *keep_parser_address)
2721 : {
2722 9 : if ((&pctx->hevc_state != keep_parser_address) && pctx->hevc_state) {
2723 0 : gf_free(pctx->hevc_state);
2724 0 : pctx->hevc_state = NULL;
2725 : }
2726 9 : if ((&pctx->avc_state != keep_parser_address) && pctx->avc_state) {
2727 0 : gf_free(pctx->avc_state);
2728 0 : pctx->avc_state = NULL;
2729 : }
2730 9 : if ((&pctx->vvc_state != keep_parser_address) && pctx->vvc_state) {
2731 0 : gf_free(pctx->vvc_state);
2732 0 : pctx->vvc_state = NULL;
2733 : }
2734 9 : if ((&pctx->av1_state != keep_parser_address) && pctx->av1_state) {
2735 0 : if (pctx->av1_state->config) gf_odf_av1_cfg_del(pctx->av1_state->config);
2736 0 : gf_free(pctx->av1_state);
2737 0 : pctx->av1_state = NULL;
2738 : }
2739 9 : if ((&pctx->mv124_state != keep_parser_address) && pctx->mv124_state) {
2740 0 : gf_m4v_parser_del(pctx->mv124_state);
2741 0 : pctx->mv124_state = NULL;
2742 : }
2743 9 : if (pctx->vpcc) gf_odf_vp_cfg_del(pctx->vpcc);
2744 9 : }
2745 : #endif
2746 :
2747 671 : static void inspect_dump_pid(GF_InspectCtx *ctx, FILE *dump, GF_FilterPid *pid, u32 pid_idx, Bool is_connect, Bool is_remove, u64 pck_for_config, Bool is_info, PidCtx *pctx)
2748 : {
2749 671 : u32 idx=0, nalh_size;
2750 : #ifndef GPAC_DISABLE_AV_PARSERS
2751 : u32 i;
2752 : GF_NALUFFParam *slc;
2753 : #endif
2754 : GF_AVCConfig *avcc, *svcc;
2755 : GF_HEVCConfig *hvcc, *lhcc;
2756 : GF_VVCConfig *vvcC;
2757 : Bool is_enh = GF_FALSE;
2758 : Bool is_svc=GF_FALSE;
2759 : char *elt_name = NULL;
2760 : const GF_PropertyValue *p, *dsi, *dsi_enh;
2761 :
2762 1331 : if (!ctx->dump) return;
2763 671 : if (ctx->test==INSPECT_TEST_NOPROP) return;
2764 :
2765 : //disconnect of src pid (not yet supported)
2766 615 : if (ctx->xml) {
2767 15 : if (is_info) {
2768 : elt_name = "PIDInfoUpdate";
2769 15 : } else if (is_remove) {
2770 : elt_name = "PIDRemove";
2771 : } else {
2772 15 : elt_name = is_connect ? "PIDConfigure" : "PIDReconfigure";
2773 : }
2774 15 : gf_fprintf(dump, "<%s PID=\"%d\" name=\"%s\"",elt_name, pid_idx, gf_filter_pid_get_name(pid) );
2775 :
2776 15 : if (pck_for_config)
2777 0 : gf_fprintf(dump, " packetsSinceLastConfig=\""LLU"\"", pck_for_config);
2778 : } else {
2779 600 : if (is_info) {
2780 30 : gf_fprintf(dump, "PID %d name %s info update\n", pid_idx, gf_filter_pid_get_name(pid) );
2781 570 : } else if (is_remove) {
2782 0 : gf_fprintf(dump, "PID %d name %s delete\n", pid_idx, gf_filter_pid_get_name(pid) );
2783 : } else {
2784 570 : gf_fprintf(dump, "PID %d name %s %sonfigure", pid_idx, gf_filter_pid_get_name(pid), is_connect ? "C" : "Rec" );
2785 570 : if (pck_for_config)
2786 130 : gf_fprintf(dump, " after "LLU" packets", pck_for_config);
2787 570 : gf_fprintf(dump, " - properties:\n");
2788 : }
2789 : }
2790 :
2791 615 : if (!is_info) {
2792 15500 : while (1) {
2793 : u32 prop_4cc;
2794 : const char *prop_name;
2795 16085 : p = gf_filter_pid_enum_properties(pid, &idx, &prop_4cc, &prop_name);
2796 16085 : if (!p) break;
2797 15500 : inspect_dump_property(ctx, dump, prop_4cc, prop_name, p, pctx);
2798 :
2799 15500 : if (prop_name) {
2800 297 : if (!strcmp(prop_name, "tmcd:flags"))
2801 2 : pctx->tmcd_flags = p->value.uint;
2802 295 : else if (!strcmp(prop_name, "tmcd:framerate"))
2803 2 : pctx->tmcd_rate = p->value.frac;
2804 293 : else if (!strcmp(prop_name, "tmcd:frames_per_tick"))
2805 2 : pctx->tmcd_fpt = p->value.uint;
2806 :
2807 : }
2808 : }
2809 : } else {
2810 60 : while (ctx->info) {
2811 : u32 prop_4cc;
2812 : const char *prop_name;
2813 60 : p = gf_filter_pid_enum_info(pid, &idx, &prop_4cc, &prop_name);
2814 60 : if (!p) break;
2815 30 : inspect_dump_property(ctx, dump, prop_4cc, prop_name, p, pctx);
2816 : }
2817 : }
2818 :
2819 615 : if (!ctx->analyze) {
2820 600 : if (ctx->xml) {
2821 0 : gf_fprintf(dump, "/>\n");
2822 : }
2823 : return;
2824 : }
2825 :
2826 15 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_CODECID);
2827 15 : if (!p) {
2828 0 : gf_fprintf(dump, "/>\n");
2829 0 : return;
2830 : }
2831 15 : pctx->codec_id = p->value.uint;
2832 :
2833 15 : dsi = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
2834 15 : dsi_enh = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT);
2835 :
2836 : avcc = NULL;
2837 : svcc = NULL;
2838 : hvcc = NULL;
2839 : lhcc = NULL;
2840 : vvcC = NULL;
2841 15 : pctx->has_svcc = 0;
2842 :
2843 15 : switch (pctx->codec_id) {
2844 0 : case GF_CODECID_SVC:
2845 : case GF_CODECID_MVC:
2846 0 : if (!dsi) is_enh = GF_TRUE;
2847 : case GF_CODECID_AVC:
2848 : case GF_CODECID_AVC_PS:
2849 2 : if (!dsi && !dsi_enh) {
2850 0 : gf_fprintf(dump, "/>\n");
2851 0 : return;
2852 : }
2853 : #ifndef GPAC_DISABLE_AV_PARSERS
2854 2 : inspect_reset_parsers(pctx, &pctx->avc_state);
2855 :
2856 2 : if (!pctx->avc_state) {
2857 2 : GF_SAFEALLOC(pctx->avc_state, AVCState);
2858 2 : if (!pctx->avc_state) return;
2859 : }
2860 : #endif
2861 2 : gf_fprintf(dump, ">\n");
2862 2 : gf_fprintf(dump, "<AVCParameterSets>\n");
2863 2 : if (dsi) {
2864 2 : if (is_enh) {
2865 0 : svcc = gf_odf_avc_cfg_read(dsi->value.data.ptr, dsi->value.data.size);
2866 0 : if (svcc)
2867 0 : pctx->nalu_size_length = svcc->nal_unit_size;
2868 : } else {
2869 2 : avcc = gf_odf_avc_cfg_read(dsi->value.data.ptr, dsi->value.data.size);
2870 2 : if (avcc)
2871 2 : pctx->nalu_size_length = avcc->nal_unit_size;
2872 : }
2873 : }
2874 2 : if (dsi_enh && !svcc) {
2875 0 : svcc = gf_odf_avc_cfg_read(dsi_enh->value.data.ptr, dsi_enh->value.data.size);
2876 0 : if (svcc)
2877 0 : pctx->nalu_size_length = svcc->nal_unit_size;
2878 : }
2879 2 : nalh_size = pctx->nalu_size_length;
2880 2 : is_svc = (svcc != NULL) ? 1 : 0;
2881 : #ifndef GPAC_DISABLE_AV_PARSERS
2882 2 : if (avcc) {
2883 2 : DUMP_ARRAY(avcc->sequenceParameterSets, "AVCSPS", "decoderConfig", is_svc)
2884 2 : DUMP_ARRAY(avcc->pictureParameterSets, "AVCPPS", "decoderConfig", is_svc)
2885 2 : DUMP_ARRAY(avcc->sequenceParameterSetExtensions, "AVCSPSEx", "decoderConfig", is_svc)
2886 : }
2887 2 : if (is_svc) {
2888 0 : DUMP_ARRAY(svcc->sequenceParameterSets, "SVCSPS", dsi_enh ? "decoderConfigEnhancement" : "decoderConfig", is_svc)
2889 0 : DUMP_ARRAY(svcc->pictureParameterSets, "SVCPPS", dsi_enh ? "decoderConfigEnhancement" : "decoderConfig", is_svc)
2890 0 : pctx->has_svcc = 1;
2891 : }
2892 : #endif
2893 2 : gf_fprintf(dump, "</AVCParameterSets>\n");
2894 2 : break;
2895 0 : case GF_CODECID_LHVC:
2896 : is_enh = GF_TRUE;
2897 2 : case GF_CODECID_HEVC:
2898 : case GF_CODECID_HEVC_TILES:
2899 2 : if (!dsi && !dsi_enh) {
2900 0 : gf_fprintf(dump, "/>\n");
2901 0 : return;
2902 : }
2903 :
2904 : #ifndef GPAC_DISABLE_AV_PARSERS
2905 2 : inspect_reset_parsers(pctx, &pctx->hevc_state);
2906 :
2907 2 : if (!pctx->hevc_state) {
2908 2 : GF_SAFEALLOC(pctx->hevc_state, HEVCState);
2909 2 : if (!pctx->hevc_state) return;
2910 : }
2911 : #endif
2912 :
2913 2 : if (dsi) {
2914 2 : if (is_enh && !dsi_enh) {
2915 0 : lhcc = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, GF_TRUE);
2916 0 : if (lhcc)
2917 0 : pctx->nalu_size_length = lhcc->nal_unit_size;
2918 : } else {
2919 2 : hvcc = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, GF_FALSE);
2920 2 : if (hvcc)
2921 2 : pctx->nalu_size_length = hvcc->nal_unit_size;
2922 : }
2923 : }
2924 2 : if (dsi_enh && !lhcc) {
2925 0 : lhcc = gf_odf_hevc_cfg_read(dsi_enh->value.data.ptr, dsi_enh->value.data.size, GF_TRUE);
2926 0 : if (lhcc)
2927 0 : pctx->nalu_size_length = lhcc->nal_unit_size;
2928 : }
2929 2 : nalh_size = pctx->nalu_size_length;
2930 :
2931 2 : gf_fprintf(dump, ">\n");
2932 2 : gf_fprintf(dump, "<HEVCParameterSets>\n");
2933 : #ifndef GPAC_DISABLE_AV_PARSERS
2934 2 : if (hvcc) {
2935 2 : for (idx=0; idx<gf_list_count(hvcc->param_array); idx++) {
2936 0 : GF_NALUFFParamArray *ar = gf_list_get(hvcc->param_array, idx);
2937 0 : if (ar->type==GF_HEVC_NALU_SEQ_PARAM) {
2938 0 : DUMP_ARRAY(ar->nalus, "HEVCSPS", "hvcC", 0)
2939 0 : } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) {
2940 0 : DUMP_ARRAY(ar->nalus, "HEVCPPS", "hvcC", 0)
2941 0 : } else if (ar->type==GF_HEVC_NALU_VID_PARAM) {
2942 0 : DUMP_ARRAY(ar->nalus, "HEVCVPS", "hvcC", 0)
2943 : } else {
2944 0 : DUMP_ARRAY(ar->nalus, "HEVCUnknownPS", "hvcC", 0)
2945 : }
2946 : }
2947 : }
2948 2 : if (lhcc) {
2949 0 : for (idx=0; idx<gf_list_count(lhcc->param_array); idx++) {
2950 0 : GF_NALUFFParamArray *ar = gf_list_get(lhcc->param_array, idx);
2951 0 : if (ar->type==GF_HEVC_NALU_SEQ_PARAM) {
2952 0 : DUMP_ARRAY(ar->nalus, "HEVCSPS", "lhcC", 0)
2953 0 : } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) {
2954 0 : DUMP_ARRAY(ar->nalus, "HEVCPPS", "lhcC", 0)
2955 0 : } else if (ar->type==GF_HEVC_NALU_VID_PARAM) {
2956 0 : DUMP_ARRAY(ar->nalus, "HEVCVPS", "lhcC", 0)
2957 : } else {
2958 0 : DUMP_ARRAY(ar->nalus, "HEVCUnknownPS", "lhcC", 0)
2959 : }
2960 : }
2961 : }
2962 : #endif
2963 2 : gf_fprintf(dump, "</HEVCParameterSets>\n");
2964 2 : break;
2965 :
2966 0 : case GF_CODECID_VVC:
2967 0 : if (!dsi) {
2968 0 : gf_fprintf(dump, "/>\n");
2969 0 : return;
2970 : }
2971 :
2972 : #ifndef GPAC_DISABLE_AV_PARSERS
2973 0 : inspect_reset_parsers(pctx, &pctx->vvc_state);
2974 :
2975 0 : if (!pctx->vvc_state) {
2976 0 : GF_SAFEALLOC(pctx->vvc_state, VVCState);
2977 0 : if (!pctx->vvc_state) return;
2978 : }
2979 : #endif
2980 :
2981 0 : vvcC = gf_odf_vvc_cfg_read(dsi->value.data.ptr, dsi->value.data.size);
2982 0 : if (vvcC)
2983 0 : pctx->nalu_size_length = vvcC->nal_unit_size;
2984 :
2985 0 : nalh_size = pctx->nalu_size_length;
2986 :
2987 0 : gf_fprintf(dump, ">\n");
2988 0 : gf_fprintf(dump, "<VVCParameterSets>\n");
2989 : #ifndef GPAC_DISABLE_AV_PARSERS
2990 0 : if (vvcC) {
2991 0 : for (idx=0; idx<gf_list_count(vvcC->param_array); idx++) {
2992 0 : GF_NALUFFParamArray *ar = gf_list_get(vvcC->param_array, idx);
2993 0 : if (ar->type==GF_VVC_NALU_SEQ_PARAM) {
2994 0 : DUMP_ARRAY(ar->nalus, "VVCSPS", "vvcC", 0)
2995 0 : } else if (ar->type==GF_VVC_NALU_PIC_PARAM) {
2996 0 : DUMP_ARRAY(ar->nalus, "VVCPPS", "vvcC", 0)
2997 0 : } else if (ar->type==GF_VVC_NALU_VID_PARAM) {
2998 0 : DUMP_ARRAY(ar->nalus, "VVCVPS", "vvcC", 0)
2999 0 : } else if (ar->type==GF_VVC_NALU_APS_PREFIX) {
3000 0 : DUMP_ARRAY(ar->nalus, "VVCAPS", "vvcC", 0)
3001 0 : } else if (ar->type==GF_VVC_NALU_SEI_PREFIX) {
3002 0 : DUMP_ARRAY(ar->nalus, "VVCSEI", "vvcC", 0)
3003 0 : } else if (ar->type==GF_VVC_NALU_DEC_PARAM) {
3004 0 : DUMP_ARRAY(ar->nalus, "VVCDCI", "vvcC", 0)
3005 : } else {
3006 0 : DUMP_ARRAY(ar->nalus, "VVCUnknownPS", "vvcC", 0)
3007 : }
3008 : }
3009 : }
3010 : #endif
3011 0 : gf_fprintf(dump, "</VVCParameterSets>\n");
3012 0 : break;
3013 :
3014 2 : case GF_CODECID_AV1:
3015 : #ifndef GPAC_DISABLE_AV_PARSERS
3016 2 : inspect_reset_parsers(pctx, &pctx->av1_state);
3017 2 : if (!pctx->av1_state) {
3018 2 : GF_SAFEALLOC(pctx->av1_state, AV1State);
3019 2 : if (!pctx->av1_state) return;
3020 2 : gf_av1_init_state(pctx->av1_state);
3021 : }
3022 : #endif
3023 2 : if (!dsi) {
3024 0 : gf_fprintf(dump, "/>\n");
3025 0 : return;
3026 : }
3027 : #ifndef GPAC_DISABLE_AV_PARSERS
3028 2 : if (pctx->av1_state->config) gf_odf_av1_cfg_del(pctx->av1_state->config);
3029 2 : pctx->av1_state->config = gf_odf_av1_cfg_read(dsi->value.data.ptr, dsi->value.data.size);
3030 2 : gf_fprintf(dump, ">\n");
3031 2 : gf_fprintf(dump, " <OBUConfig>\n");
3032 :
3033 2 : idx = 1;
3034 4 : for (i=0; i<gf_list_count(pctx->av1_state->config->obu_array); i++) {
3035 : ObuType obu_type=0;
3036 : u64 obu_size = 0;
3037 : u32 hdr_size = 0;
3038 2 : GF_AV1_OBUArrayEntry *obu = gf_list_get(pctx->av1_state->config->obu_array, i);
3039 :
3040 2 : if (!pctx->bs)
3041 0 : pctx->bs = gf_bs_new((const u8 *) obu->obu, (u32) obu->obu_length, GF_BITSTREAM_READ);
3042 : else
3043 2 : gf_bs_reassign_buffer(pctx->bs, (const u8 *)obu->obu, (u32) obu->obu_length);
3044 :
3045 2 : gf_inspect_dump_obu_internal(dump, pctx->av1_state, (char*)obu->obu, obu->obu_length, obu_type, obu_size, hdr_size, ctx->crc, pctx, ctx->analyze);
3046 2 : idx++;
3047 : }
3048 : #endif
3049 2 : gf_fprintf(dump, " </OBUConfig>\n");
3050 2 : break;
3051 :
3052 1 : case GF_CODECID_MPEG1:
3053 : case GF_CODECID_MPEG2_422:
3054 : case GF_CODECID_MPEG2_SNR:
3055 : case GF_CODECID_MPEG2_HIGH:
3056 : case GF_CODECID_MPEG2_MAIN:
3057 : case GF_CODECID_MPEG4_PART2:
3058 :
3059 : #ifndef GPAC_DISABLE_AV_PARSERS
3060 1 : inspect_reset_parsers(pctx, &pctx->mv124_state);
3061 : #endif
3062 1 : if (!dsi) {
3063 0 : gf_fprintf(dump, "/>\n");
3064 0 : return;
3065 : }
3066 1 : gf_fprintf(dump, ">\n");
3067 1 : gf_fprintf(dump, " <MPEGVideoConfig>\n");
3068 : #ifndef GPAC_DISABLE_AV_PARSERS
3069 1 : inspect_dump_mpeg124(pctx, dsi->value.data.ptr, dsi->value.data.size, dump);
3070 : #endif
3071 1 : gf_fprintf(dump, " </MPEGVideoConfig>\n");
3072 : #ifndef GPAC_DISABLE_AV_PARSERS
3073 1 : if (pctx->mv124_state) gf_m4v_parser_del(pctx->mv124_state);
3074 : #endif
3075 : break;
3076 2 : case GF_CODECID_MPEG_AUDIO:
3077 : case GF_CODECID_MPEG2_PART3:
3078 : case GF_CODECID_TMCD:
3079 2 : gf_fprintf(dump, "/>\n");
3080 2 : return;
3081 0 : case GF_CODECID_SUBS_XML:
3082 : case GF_CODECID_META_XML:
3083 0 : if (!dsi) {
3084 0 : gf_fprintf(dump, "/>\n");
3085 0 : return;
3086 : }
3087 0 : gf_fprintf(dump, " <XMLTextConfig>\n");
3088 0 : for (i=0; i<dsi->value.data.size; i++) {
3089 0 : gf_fputc(dsi->value.data.ptr[i], dump);
3090 : }
3091 0 : gf_fprintf(dump, "\n </XMLTextConfig>\n");
3092 0 : break;
3093 0 : case GF_CODECID_SUBS_TEXT:
3094 : case GF_CODECID_META_TEXT:
3095 0 : if (!dsi) {
3096 0 : gf_fprintf(dump, "/>\n");
3097 0 : return;
3098 : }
3099 0 : gf_fprintf(dump, " <TextConfig>\n");
3100 0 : gf_fprintf(dump, "<![CDATA[");
3101 0 : for (i=0; i<dsi->value.data.size; i++) {
3102 0 : gf_fputc(dsi->value.data.ptr[i], dump);
3103 : }
3104 0 : gf_fprintf(dump, "]]>\n");
3105 0 : gf_fprintf(dump, " </TextConfig>\n");
3106 0 : break;
3107 0 : case GF_CODECID_APCH:
3108 : case GF_CODECID_APCN:
3109 : case GF_CODECID_APCS:
3110 : case GF_CODECID_APCO:
3111 : case GF_CODECID_AP4H:
3112 : case GF_CODECID_AP4X:
3113 0 : gf_fprintf(dump, "/>\n");
3114 0 : return;
3115 0 : case GF_CODECID_MPHA:
3116 : case GF_CODECID_MHAS:
3117 0 : if (!dsi) {
3118 0 : gf_fprintf(dump, "/>\n");
3119 0 : return;
3120 : }
3121 : {
3122 : u16 size;
3123 0 : if (!pctx->bs)
3124 0 : pctx->bs = gf_bs_new(dsi->value.data.ptr, dsi->value.data.size, GF_BITSTREAM_READ);
3125 : else
3126 0 : gf_bs_reassign_buffer(pctx->bs, dsi->value.data.ptr, dsi->value.data.size);
3127 :
3128 0 : gf_fprintf(dump, " <MPEGHAudioConfig");
3129 0 : gf_fprintf(dump, " version=\"%d\"", gf_bs_read_u8(pctx->bs) );
3130 0 : gf_fprintf(dump, " ProfileLevelIndication=\"%d\"", gf_bs_read_u8(pctx->bs) );
3131 0 : gf_fprintf(dump, " ReferenceChannelLayout=\"%d\"", gf_bs_read_u8(pctx->bs) );
3132 0 : size = gf_bs_read_u16(pctx->bs);
3133 0 : if (size) {
3134 0 : gf_fprintf(dump, ">\n");
3135 0 : dump_mha_config(dump, pctx->bs, " ");
3136 0 : gf_fprintf(dump, " </MPEGHAudioConfig>\n");
3137 : } else {
3138 0 : gf_fprintf(dump, "/>\n");
3139 : }
3140 0 : gf_fprintf(dump, "/>\n");
3141 : }
3142 0 : break;
3143 2 : case GF_CODECID_VP8:
3144 : case GF_CODECID_VP9:
3145 2 : if (!dsi) {
3146 0 : gf_fprintf(dump, "/>\n");
3147 0 : return;
3148 : }
3149 :
3150 : #ifndef GPAC_DISABLE_AV_PARSERS
3151 2 : inspect_reset_parsers(pctx, NULL);
3152 : #endif
3153 :
3154 2 : pctx->vpcc = gf_odf_vp_cfg_read(dsi->value.data.ptr, dsi->value.data.size);
3155 2 : gf_fprintf(dump, ">\n");
3156 2 : if (pctx->vpcc) {
3157 2 : u32 v = (pctx->codec_id==GF_CODECID_VP9) ? 9 : 8;
3158 14 : gf_fprintf(dump, "<VP%dConfiguration profile=\"%d\" level=\"%d\" bit_depth=\"%u\" chroma_subsampling=\"%u\" colour_primaries=\"%u\" transfer_characteristics=\"%u\" matrix_coefficients=\"%u\" video_full_range=\"%u\"", v,
3159 14 : pctx->vpcc->profile, pctx->vpcc->level, pctx->vpcc->bit_depth, pctx->vpcc->chroma_subsampling, pctx->vpcc->colour_primaries, pctx->vpcc->transfer_characteristics, pctx->vpcc->matrix_coefficients, pctx->vpcc->video_fullRange_flag
3160 : );
3161 2 : if (pctx->vpcc->codec_initdata && pctx->vpcc->codec_initdata_size) {
3162 0 : gf_fprintf(dump, " init_data=\"");
3163 0 : for (idx=0; idx<pctx->vpcc->codec_initdata_size; idx++)
3164 0 : gf_fprintf(dump, "%02X", (unsigned char) pctx->vpcc->codec_initdata[idx]);
3165 0 : gf_fprintf(dump, "\"");
3166 : }
3167 2 : gf_fprintf(dump, "/>\n");
3168 : }
3169 : break;
3170 :
3171 2 : case GF_CODECID_AAC_MPEG4:
3172 : case GF_CODECID_AAC_MPEG2_MP:
3173 : case GF_CODECID_AAC_MPEG2_LCP:
3174 : case GF_CODECID_AAC_MPEG2_SSRP:
3175 : case GF_CODECID_USAC:
3176 2 : if (!pctx->no_analysis) {
3177 2 : pctx->no_analysis = GF_TRUE;
3178 2 : GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[Inspect] bitstream analysis for codec %s not supported, only configuration is\n", gf_codecid_name(pctx->codec_id)));
3179 : }
3180 2 : if (dsi) {
3181 : GF_M4ADecSpecInfo acfg;
3182 : InspectLogCbk lcbk;
3183 :
3184 2 : gf_fprintf(dump, ">\n");
3185 2 : gf_fprintf(dump, "<MPEG4AudioConfiguration ");
3186 :
3187 2 : if (!pctx->bs)
3188 0 : pctx->bs = gf_bs_new(dsi->value.data.ptr, dsi->value.data.size, GF_BITSTREAM_READ);
3189 : else
3190 2 : gf_bs_reassign_buffer(pctx->bs, dsi->value.data.ptr, dsi->value.data.size);
3191 :
3192 2 : if (ctx->analyze>=INSPECT_ANALYZE_BS) {
3193 1 : lcbk.dump = dump;
3194 1 : lcbk.dump_bits = (ctx->analyze==INSPECT_ANALYZE_BS_BITS) ? GF_TRUE : GF_FALSE;
3195 1 : gf_bs_set_logger(pctx->bs, regular_bs_log, &lcbk);
3196 : }
3197 :
3198 2 : gf_m4a_parse_config(pctx->bs, &acfg, GF_TRUE);
3199 2 : if (ctx->analyze<INSPECT_ANALYZE_BS) {
3200 1 : gf_fprintf(dump, "base_object_type=\"%u\" sample_rate=\"%u\" channels=\"%u\" ", acfg.base_object_type, acfg.base_sr, acfg.nb_chan);
3201 1 : if (acfg.has_sbr)
3202 0 : gf_fprintf(dump, "sbr_sample_rate=\"%u\" ", acfg.sbr_sr);
3203 1 : if (acfg.has_ps)
3204 0 : gf_fprintf(dump, "parametricStereo=\"yes\" ");
3205 : }
3206 2 : if (acfg.comments[0])
3207 0 : gf_fprintf(dump, "comments=\"%s\" ", acfg.comments);
3208 2 : gf_fprintf(dump, "/>\n");
3209 : } else {
3210 0 : gf_fprintf(dump, "/>\n");
3211 0 : return;
3212 : }
3213 2 : break;
3214 2 : case GF_CODECID_AC3:
3215 : case GF_CODECID_EAC3:
3216 2 : gf_fprintf(dump, "/>\n");
3217 2 : return;
3218 :
3219 0 : case GF_CODECID_TRUEHD:
3220 0 : if (dsi) {
3221 : u16 fmt, prate;
3222 0 : gf_fprintf(dump, ">\n");
3223 0 : gf_fprintf(dump, "<TrueHDAudioConfiguration");
3224 :
3225 0 : if (!pctx->bs)
3226 0 : pctx->bs = gf_bs_new(dsi->value.data.ptr, dsi->value.data.size, GF_BITSTREAM_READ);
3227 : else
3228 0 : gf_bs_reassign_buffer(pctx->bs, dsi->value.data.ptr, dsi->value.data.size);
3229 :
3230 0 : fmt = gf_bs_read_u32(pctx->bs);
3231 0 : prate = gf_bs_read_int(pctx->bs, 15);
3232 :
3233 0 : gf_fprintf(dump, " format=\"%u\" peak_data_rate=\"%u\"/>\n", fmt, prate);
3234 : } else {
3235 0 : gf_fprintf(dump, "/>\n");
3236 0 : return;
3237 : }
3238 0 : break;
3239 :
3240 0 : default:
3241 0 : if (!pctx->no_analysis) {
3242 0 : pctx->no_analysis = GF_TRUE;
3243 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[Inspect] bitstream analysis for codec %s not supported\n", gf_codecid_name(pctx->codec_id)));
3244 : }
3245 0 : gf_fprintf(dump, "/>\n");
3246 0 : return;
3247 : }
3248 :
3249 11 : if (avcc) gf_odf_avc_cfg_del(avcc);
3250 11 : if (svcc) gf_odf_avc_cfg_del(svcc);
3251 11 : if (hvcc) gf_odf_hevc_cfg_del(hvcc);
3252 11 : if (lhcc) gf_odf_hevc_cfg_del(lhcc);
3253 11 : if (vvcC) gf_odf_vvc_cfg_del(vvcC);
3254 11 : gf_fprintf(dump, "</%s>\n", elt_name);
3255 : }
3256 :
3257 1810954 : static GF_Err inspect_process(GF_Filter *filter)
3258 : {
3259 : u32 i, count, nb_done=0, nb_hdr_done=0;
3260 1810954 : GF_InspectCtx *ctx = (GF_InspectCtx *) gf_filter_get_udta(filter);
3261 :
3262 1810954 : count = gf_list_count(ctx->src_pids);
3263 :
3264 1810954 : if (ctx->args_updated) {
3265 0 : ctx->args_updated = GF_FALSE;
3266 0 : for (i=0; i<count; i++) {
3267 0 : PidCtx *pctx = gf_list_get(ctx->src_pids, i);
3268 0 : switch (ctx->mode) {
3269 0 : case INSPECT_MODE_PCK:
3270 : case INSPECT_MODE_REFRAME:
3271 0 : gf_filter_pid_set_framing_mode(pctx->src_pid, GF_TRUE);
3272 0 : break;
3273 0 : default:
3274 0 : gf_filter_pid_set_framing_mode(pctx->src_pid, GF_FALSE);
3275 0 : break;
3276 : }
3277 0 : gf_filter_pid_set_clock_mode(pctx->src_pid, ctx->pcr);
3278 : }
3279 0 : if (ctx->is_prober || ctx->deep || ctx->fmt) {
3280 0 : ctx->dump_pck = GF_TRUE;
3281 : } else {
3282 0 : ctx->dump_pck = GF_FALSE;
3283 : }
3284 : }
3285 1810954 : count = gf_list_count(ctx->src_pids);
3286 5531015 : for (i=0; i<count; i++) {
3287 3720209 : PidCtx *pctx = gf_list_get(ctx->src_pids, i);
3288 : GF_FilterPacket *pck = NULL;
3289 3720209 : pck = pctx->src_pid ? gf_filter_pid_get_packet(pctx->src_pid) : NULL;
3290 :
3291 3720209 : if (pctx->init_pid_config_done)
3292 459957 : nb_hdr_done++;
3293 :
3294 3720209 : if (!pck) {
3295 305309 : if (pctx->src_pid && !gf_filter_pid_is_eos(pctx->src_pid))
3296 124074 : continue;
3297 : else
3298 181235 : ctx->has_seen_eos = GF_TRUE;
3299 : }
3300 3596135 : if (pctx->aborted)
3301 1656 : continue;
3302 :
3303 3594479 : if (!pctx->buffer_done) {
3304 3257589 : if (pck && !ctx->has_seen_eos) {
3305 3257588 : u64 dur = gf_filter_pid_query_buffer_duration(pctx->src_pid, GF_FALSE);
3306 3257588 : if ((dur < ctx->buffer * 1000) && !gf_filter_pid_has_seen_eos(pctx->src_pid)) {
3307 3257551 : continue;
3308 : }
3309 : }
3310 38 : pctx->buffer_done = GF_TRUE;
3311 : }
3312 :
3313 336928 : if (pctx->dump_pid) {
3314 671 : inspect_dump_pid(ctx, pctx->tmp, pctx->src_pid, pctx->idx, pctx->init_pid_config_done ? GF_FALSE : GF_TRUE, GF_FALSE, pctx->pck_for_config, (pctx->dump_pid==2) ? GF_TRUE : GF_FALSE, pctx);
3315 671 : pctx->dump_pid = 0;
3316 671 : pctx->init_pid_config_done = 1;
3317 671 : pctx->pck_for_config=0;
3318 :
3319 671 : if (!ctx->hdr_done) {
3320 369 : ctx->hdr_done=GF_TRUE;
3321 : //dump header on main output file, not on pid one!
3322 369 : if (ctx->hdr && ctx->fmt && !ctx->xml)
3323 116 : inspect_dump_packet_fmt(ctx, ctx->dump, NULL, 0, 0);
3324 : }
3325 : }
3326 336928 : if (!pck) continue;
3327 :
3328 157349 : pctx->pck_for_config++;
3329 157349 : pctx->pck_num++;
3330 :
3331 157349 : if (ctx->dump_pck) {
3332 :
3333 157142 : if (ctx->is_prober) {
3334 85 : nb_done++;
3335 : } else {
3336 157057 : GF_LOG(GF_LOG_DEBUG, GF_LOG_AUTHOR, ("[Inspect] PID %d (codec %s) dump packet CTS "LLU"\n", pctx->idx, gf_codecid_name(pctx->codec_id), gf_filter_pck_get_cts(pck) ));
3337 157057 : if (ctx->fmt) {
3338 18630 : inspect_dump_packet_fmt(ctx, pctx->tmp, pck, pctx, pctx->pck_num);
3339 : } else {
3340 138427 : inspect_dump_packet(ctx, pctx->tmp, pck, pctx->idx, pctx->pck_num, pctx);
3341 : }
3342 : }
3343 : }
3344 :
3345 157349 : if (ctx->dur.num && ctx->dur.den) {
3346 17181 : u64 timescale = gf_filter_pck_get_timescale(pck);
3347 17181 : u64 ts = gf_filter_pck_get_dts(pck);
3348 17181 : u64 dur = gf_filter_pck_get_duration(pck);
3349 17181 : if (ts == GF_FILTER_NO_TS) ts = gf_filter_pck_get_cts(pck);
3350 :
3351 17181 : if (!pctx->init_ts) pctx->init_ts = ts+1;
3352 17017 : else if ((ts + dur - pctx->init_ts + 1) * (u64)ctx->dur.den >= timescale * (u64) ctx->dur.num) {
3353 : GF_FilterEvent evt;
3354 148 : GF_FEVT_INIT(evt, GF_FEVT_STOP, pctx->src_pid);
3355 :
3356 148 : GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[Inspect] PID %d (codec %s) done dumping, aborting\n", pctx->idx, gf_codecid_name(pctx->codec_id) ));
3357 148 : gf_filter_pid_drop_packet(pctx->src_pid);
3358 :
3359 148 : gf_filter_pid_send_event(pctx->src_pid, &evt);
3360 148 : gf_filter_pid_set_discard(pctx->src_pid, GF_TRUE);
3361 148 : pctx->aborted = GF_TRUE;
3362 : break;
3363 : }
3364 : }
3365 157201 : gf_filter_pid_drop_packet(pctx->src_pid);
3366 : }
3367 1810954 : if ((ctx->is_prober && !ctx->probe_done && (nb_done==count) && !ctx->allp)
3368 1810891 : || (!ctx->is_prober && !ctx->allp && !ctx->dump_pck && (nb_hdr_done==count) && !gf_filter_connections_pending(filter))
3369 : ) {
3370 182 : for (i=0; i<count; i++) {
3371 182 : PidCtx *pctx = gf_list_get(ctx->src_pids, i);
3372 : GF_FilterEvent evt;
3373 182 : GF_FEVT_INIT(evt, GF_FEVT_STOP, pctx->src_pid);
3374 182 : gf_filter_pid_send_event(pctx->src_pid, &evt);
3375 : }
3376 157 : if (ctx->is_prober)
3377 63 : ctx->probe_done = GF_TRUE;
3378 : return GF_EOS;
3379 : }
3380 : return GF_OK;
3381 : }
3382 :
3383 873 : static GF_Err inspect_config_input(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
3384 : {
3385 : GF_FilterEvent evt;
3386 : PidCtx *pctx;
3387 : u32 w, h, sr, ch;
3388 : const GF_PropertyValue *p;
3389 873 : GF_InspectCtx *ctx = (GF_InspectCtx *) gf_filter_get_udta(filter);
3390 :
3391 873 : if (!ctx->src_pids) ctx->src_pids = gf_list_new();
3392 :
3393 873 : pctx = gf_filter_pid_get_udta(pid);
3394 873 : if (pctx) {
3395 : assert(pctx->src_pid == pid);
3396 306 : if (is_remove)
3397 1 : pctx->src_pid = NULL;
3398 305 : else if (!ctx->is_prober)
3399 290 : pctx->dump_pid = 1;
3400 : return GF_OK;
3401 : }
3402 567 : GF_SAFEALLOC(pctx, PidCtx);
3403 567 : if (!pctx) return GF_OUT_OF_MEM;
3404 567 : if (ctx->analyze)
3405 15 : pctx->bs = gf_bs_new((u8 *)pctx, 0, GF_BITSTREAM_READ);
3406 567 : if (!ctx->buffer) {
3407 527 : pctx->buffer_done = GF_TRUE;
3408 : } else {
3409 40 : GF_FEVT_INIT(evt, GF_FEVT_BUFFER_REQ, pid);
3410 40 : evt.buffer_req.max_buffer_us = ctx->buffer * 1000;
3411 40 : evt.buffer_req.pid_only = GF_TRUE;
3412 40 : gf_filter_pid_send_event(pid, &evt);
3413 : }
3414 :
3415 567 : pctx->src_pid = pid;
3416 567 : gf_filter_pid_set_udta(pid, pctx);
3417 :
3418 :
3419 567 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_STREAM_TYPE);
3420 567 : pctx->stream_type = p ? p->value.uint : 0;
3421 567 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_CODECID);
3422 567 : pctx->codec_id = p ? p->value.uint : 0;
3423 :
3424 : w = h = sr = ch = 0;
3425 567 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_WIDTH);
3426 567 : if (p) w = p->value.uint;
3427 567 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_HEIGHT);
3428 567 : if (p) h = p->value.uint;
3429 567 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_SAMPLE_RATE);
3430 567 : if (p) sr = p->value.uint;
3431 567 : p = gf_filter_pid_get_property(pid, GF_PROP_PID_NUM_CHANNELS);
3432 567 : if (p) ch = p->value.uint;
3433 :
3434 567 : if (! ctx->interleave) {
3435 : u32 insert_idx = 0;
3436 : u32 i;
3437 : //sort all PIDs by codec IDs
3438 230 : for (i=0; i<gf_list_count(ctx->src_pids); i++) {
3439 : Bool insert = GF_FALSE;
3440 265 : PidCtx *actx = gf_list_get(ctx->src_pids, i);
3441 :
3442 265 : if (pctx->codec_id < actx->codec_id) {
3443 : insert = GF_TRUE;
3444 : }
3445 : //same codec ID, sort by increasing width/height/samplerate/channels
3446 240 : else if (pctx->codec_id==actx->codec_id) {
3447 : u32 aw, ah, asr, ach;
3448 :
3449 : aw = ah = asr = ach = 0;
3450 109 : p = gf_filter_pid_get_property(actx->src_pid, GF_PROP_PID_WIDTH);
3451 109 : if (p) aw = p->value.uint;
3452 109 : p = gf_filter_pid_get_property(actx->src_pid, GF_PROP_PID_HEIGHT);
3453 109 : if (p) ah = p->value.uint;
3454 109 : p = gf_filter_pid_get_property(actx->src_pid, GF_PROP_PID_SAMPLE_RATE);
3455 109 : if (p) asr = p->value.uint;
3456 109 : p = gf_filter_pid_get_property(actx->src_pid, GF_PROP_PID_NUM_CHANNELS);
3457 109 : if (p) ach = p->value.uint;
3458 :
3459 109 : if (w && aw && (w<aw)) insert = GF_TRUE;
3460 109 : if (h && ah && (h<ah)) insert = GF_TRUE;
3461 109 : if (sr && asr && (sr<asr)) insert = GF_TRUE;
3462 109 : if (ch && ach && (ch<ach)) insert = GF_TRUE;
3463 : }
3464 :
3465 109 : if (insert) {
3466 35 : insert_idx = i+1;
3467 35 : break;
3468 : }
3469 : }
3470 357 : if (insert_idx) {
3471 35 : gf_list_insert(ctx->src_pids, pctx, insert_idx-1);
3472 156 : for (i=insert_idx; i<gf_list_count(ctx->src_pids); i++) {
3473 86 : PidCtx *actx = gf_list_get(ctx->src_pids, i);
3474 86 : actx->idx = i+1;
3475 : }
3476 : } else {
3477 322 : gf_list_add(ctx->src_pids, pctx);
3478 : }
3479 : } else {
3480 210 : pctx->tmp = ctx->dump;
3481 210 : gf_list_add(ctx->src_pids, pctx);
3482 : }
3483 :
3484 567 : pctx->idx = gf_list_find(ctx->src_pids, pctx) + 1;
3485 :
3486 567 : if (! ctx->interleave && !pctx->tmp && ctx->dump) {
3487 290 : pctx->tmp = gf_file_temp(NULL);
3488 290 : if (ctx->xml)
3489 0 : gf_fprintf(pctx->tmp, "<PIDInspect ID=\"%d\" name=\"%s\">\n", pctx->idx, gf_filter_pid_get_name(pid) );
3490 : }
3491 :
3492 567 : switch (ctx->mode) {
3493 563 : case INSPECT_MODE_PCK:
3494 : case INSPECT_MODE_REFRAME:
3495 563 : gf_filter_pid_set_framing_mode(pid, GF_TRUE);
3496 563 : break;
3497 4 : default:
3498 4 : gf_filter_pid_set_framing_mode(pid, GF_FALSE);
3499 4 : break;
3500 : }
3501 :
3502 567 : if (!ctx->is_prober) {
3503 500 : pctx->dump_pid = 1;
3504 : }
3505 :
3506 567 : gf_filter_pid_init_play_event(pid, &evt, ctx->start, ctx->speed, "Inspect");
3507 567 : gf_filter_pid_send_event(pid, &evt);
3508 :
3509 567 : if (ctx->is_prober || ctx->deep || ctx->fmt) {
3510 544 : ctx->dump_pck = GF_TRUE;
3511 : } else {
3512 23 : ctx->dump_pck = GF_FALSE;
3513 : }
3514 567 : if (ctx->pcr)
3515 17 : gf_filter_pid_set_clock_mode(pid, GF_TRUE);
3516 : return GF_OK;
3517 : }
3518 :
3519 : static const GF_FilterCapability InspecterDemuxedCaps[] =
3520 : {
3521 : //accept any stream but files, framed
3522 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_FILE),
3523 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
3524 : {0},
3525 : };
3526 :
3527 : static const GF_FilterCapability InspecterReframeCaps[] =
3528 : {
3529 : //accept any stream but files, framed
3530 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_FILE),
3531 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
3532 : CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
3533 : {0},
3534 : };
3535 :
3536 0 : static GF_Err inspect_update_arg(GF_Filter *filter, const char *arg_name, const GF_PropertyValue *new_val)
3537 : {
3538 370 : GF_InspectCtx *ctx = (GF_InspectCtx *) gf_filter_get_udta(filter);
3539 370 : ctx->args_updated = GF_TRUE;
3540 0 : return GF_OK;
3541 : }
3542 :
3543 437 : GF_Err inspect_initialize(GF_Filter *filter)
3544 : {
3545 437 : const char *name = gf_filter_get_name(filter);
3546 437 : GF_InspectCtx *ctx = (GF_InspectCtx *) gf_filter_get_udta(filter);
3547 :
3548 437 : if (name && !strcmp(name, "probe") ) {
3549 63 : ctx->is_prober = GF_TRUE;
3550 63 : return GF_OK;
3551 : }
3552 :
3553 : #ifdef GPAC_DISABLE_AVPARSE_LOGS
3554 : if (ctx->analyze>=INSPECT_ANALYZE_BS) {
3555 : GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[Inspect] Bitstream logging is disable in this build\n"));
3556 : return GF_NOT_SUPPORTED;
3557 : }
3558 : #endif
3559 :
3560 374 : if (!ctx->log) return GF_BAD_PARAM;
3561 374 : if (!strcmp(ctx->log, "stderr")) ctx->dump = stderr;
3562 351 : else if (!strcmp(ctx->log, "stdout")) ctx->dump = stdout;
3563 351 : else if (!strcmp(ctx->log, "null")) ctx->dump = NULL;
3564 : else {
3565 351 : ctx->dump = gf_fopen(ctx->log, "wt");
3566 351 : if (!ctx->dump) {
3567 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[Inspect] Failed to open file %s\n", ctx->log));
3568 : return GF_IO_ERR;
3569 : }
3570 : }
3571 374 : if (ctx->analyze) {
3572 15 : ctx->xml = GF_TRUE;
3573 : }
3574 :
3575 374 : if (ctx->xml && ctx->dump) {
3576 15 : ctx->fmt = NULL;
3577 15 : gf_fprintf(ctx->dump, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
3578 15 : gf_fprintf(ctx->dump, "<GPACInspect>\n");
3579 : }
3580 :
3581 374 : switch (ctx->mode) {
3582 : case INSPECT_MODE_RAW:
3583 : break;
3584 9 : case INSPECT_MODE_REFRAME:
3585 9 : gf_filter_override_caps(filter, InspecterReframeCaps, sizeof(InspecterReframeCaps)/sizeof(GF_FilterCapability) );
3586 9 : break;
3587 363 : default:
3588 363 : gf_filter_override_caps(filter, InspecterDemuxedCaps, sizeof(InspecterDemuxedCaps)/sizeof(GF_FilterCapability) );
3589 363 : break;
3590 : }
3591 :
3592 : #ifdef GPAC_ENABLE_COVERAGE
3593 374 : if (gf_sys_is_cov_mode()) {
3594 : inspect_update_arg(filter, NULL, NULL);
3595 370 : ctx->args_updated = GF_FALSE;
3596 : }
3597 : #endif
3598 : return GF_OK;
3599 : }
3600 :
3601 3277373 : static Bool inspect_process_event(GF_Filter *filter, const GF_FilterEvent *evt)
3602 : {
3603 : PidCtx *pctx;
3604 3277373 : GF_InspectCtx *ctx = (GF_InspectCtx *) gf_filter_get_udta(filter);
3605 3277373 : if (evt->base.type != GF_FEVT_INFO_UPDATE) return GF_TRUE;
3606 3277313 : if (!ctx->info) return GF_TRUE;
3607 30 : pctx = gf_filter_pid_get_udta(evt->base.on_pid);
3608 30 : pctx->dump_pid = 2;
3609 30 : return GF_TRUE;
3610 : }
3611 :
3612 : #define OFFS(_n) #_n, offsetof(GF_InspectCtx, _n)
3613 : static const GF_FilterArgs InspectArgs[] =
3614 : {
3615 : { OFFS(log), "set inspect log filename", GF_PROP_STRING, "stderr", "fileName, stderr, stdout or null", 0},
3616 : { OFFS(mode), "dump mode\n"
3617 : "- pck: dump full packet\n"
3618 : "- blk: dump packets before reconstruction\n"
3619 : "- frame: force reframer\n"
3620 : "- raw: dump source packets without demuxing", GF_PROP_UINT, "pck", "pck|blk|frame|raw", 0},
3621 : { OFFS(interleave), "dump packets as they are received on each pid. If false, report per pid is generated", GF_PROP_BOOL, "true", NULL, GF_FS_ARG_HINT_ADVANCED},
3622 : { OFFS(deep), "dump packets along with PID state change, implied when [-fmt]() is set", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED|GF_FS_ARG_UPDATE},
3623 : { OFFS(props), "dump packet properties, ignored when [-fmt]() is set (see filter help)", GF_PROP_BOOL, "true", NULL, GF_FS_ARG_HINT_ADVANCED|GF_FS_ARG_UPDATE},
3624 : { OFFS(dump_data), "enable full data dump (__heavy!__), ignored when [-fmt]() is set (see filter help)", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE|GF_FS_ARG_HINT_ADVANCED|GF_FS_ARG_UPDATE},
3625 : { OFFS(fmt), "set packet dump format (see filter help)", GF_PROP_STRING, NULL, NULL, GF_FS_ARG_UPDATE|GF_FS_ARG_HINT_ADVANCED},
3626 : { OFFS(hdr), "print a header corresponding to fmt string without '$' or \"pid\"", GF_PROP_BOOL, "true", NULL, GF_FS_ARG_HINT_ADVANCED},
3627 : { OFFS(allp), "analyse for the entire duration, rather than stopping when all pids are found", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED},
3628 : { OFFS(info), "monitor PID info changes", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED|GF_FS_ARG_UPDATE},
3629 : { OFFS(pcr), "dump M2TS PCR info", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_EXPERT|GF_FS_ARG_UPDATE},
3630 : { OFFS(speed), "set playback command speed. If speed is negative and start is 0, start is set to -1", GF_PROP_DOUBLE, "1.0", NULL, 0},
3631 : { OFFS(start), "set playback start offset. Negative value means percent of media duration with -1 equal to duration", GF_PROP_DOUBLE, "0.0", NULL, 0},
3632 : { OFFS(dur), "set inspect duration", GF_PROP_FRACTION, "0/0", NULL, 0},
3633 : { OFFS(analyze), "analyze sample content (NALU, OBU)\n"
3634 : "- off: no analyzing\n"
3635 : "- on: simple analyzing\n"
3636 : "- bs: log bitstream syntax (all elements read from bitstream)\n"
3637 : "- full: log bitstream syntax and bit sizes signaled as `(N)` after field value, except 1-bit fields (omitted)", GF_PROP_UINT, "off", "off|on|bs|full", GF_FS_ARG_HINT_ADVANCED|GF_FS_ARG_UPDATE},
3638 : { OFFS(xml), "use xml formatting (implied if (-analyze]() is set) and disable [-fmt]()", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
3639 : { OFFS(crc), "dump crc of NALU/OBU/... when analyzing", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
3640 : { OFFS(fftmcd), "consider timecodes use ffmpeg-compatible signaling rather than QT compliant one", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_EXPERT|GF_FS_ARG_UPDATE},
3641 : { OFFS(dtype), "dump property type", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
3642 : { OFFS(buffer), "set buffer in ms (mostly used for testing DASH algo)", GF_PROP_UINT, "0", NULL, GF_ARG_HINT_EXPERT},
3643 : { OFFS(test), "skip predefined set of properties, used for test mode\n"
3644 : "- no: no properties skipped\n"
3645 : "- noprop: all properties/info changes on pid are skipped, only packets are dumped\n"
3646 : "- network: URL/path dump, cache state, file size properties skipped (used for hashing network results)\n"
3647 : "- netx: same as network but skip track duration and templates (used for hashing progressive load of fmp4)\n"
3648 : "- encode: same as network plus skip decoder config (used for hashing encoding results)\n"
3649 : "- encx: same as encode and skip bitrates, media data size and co\n"
3650 : "- nocrc: disable packet CRC dump\n"
3651 : "- nobr: skip bitrate"
3652 : , GF_PROP_UINT, "no", "no|noprop|network|netx|encode|encx|nocrc|nobr", GF_FS_ARG_HINT_EXPERT|GF_FS_ARG_UPDATE},
3653 : {0}
3654 : };
3655 :
3656 : static const GF_FilterCapability InspectCaps[] =
3657 : {
3658 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_UNKNOWN),
3659 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
3660 : };
3661 :
3662 : const GF_FilterRegister InspectRegister = {
3663 : .name = "inspect",
3664 : GF_FS_SET_DESCRIPTION("Inspect packets")
3665 : GF_FS_SET_HELP("The inspect filter can be used to dump pid and packets. It may also be used to check parts of payload of the packets. The default options inspect only pid changes.\n"\
3666 : "The packet inspector can be configured to dump specific properties of packets using [-fmt]().\n"\
3667 : "When the option is not present, all properties are dumped. Otherwise, only properties identified by `$TOKEN$` "
3668 : "are printed. You may use '$', '@' or '%' for `TOKEN` separator. `TOKEN` can be:\n"\
3669 : "- pn: packet (frame in framed mode) number\n"\
3670 : "- dts: decoding time stamp in stream timescale, N/A if not available\n"\
3671 : "- ddts: difference between current and previous packets decoding time stamp in stream timescale, N/A if not available\n"\
3672 : "- cts: composition time stamp in stream timescale, N/A if not available\n"\
3673 : "- dcts: difference between current and previous packets composition time stamp in stream timescale, N/A if not available\n"\
3674 : "- ctso: difference between composition time stamp and decoding time stamp in stream timescale, N/A if not available\n"\
3675 : "- dur: duration in stream timescale\n"\
3676 : "- frame: framing status\n"
3677 : " - interface: complete AU, interface object (no size info). Typically a GL texture\n"
3678 : " - frame_full: complete AU\n"
3679 : " - frame_start: beginning of frame\n"
3680 : " - frame_end: end of frame\n"
3681 : " - frame_cont: frame continuation (not beginning, not end)\n"
3682 : "- sap or rap: SAP type of the frame\n"\
3683 : "- ilace: interlacing flag (0: progressive, 1: top field, 2: bottom field)\n"\
3684 : "- corr: corrupted packet flag\n"\
3685 : "- seek: seek flag\n"\
3686 : "- bo: byte offset in source, N/A if not available\n"\
3687 : "- roll: roll info\n"\
3688 : "- crypt: crypt flag\n"\
3689 : "- vers: carousel version number\n"\
3690 : "- size: size of packet\n"\
3691 : "- csize: cumulated size of packets\n"\
3692 : "- crc: 32 bit CRC of packet\n"\
3693 : "- lf: insert linefeed\n"\
3694 : "- cr: insert carriage return\n"\
3695 : "- t: insert tab\n"\
3696 : "- data: hex dump of packet (__big output!__)\n"\
3697 : "- lp: leading picture flag\n"\
3698 : "- depo: depends on other packet flag\n"\
3699 : "- depf: is depended on other packet flag\n"\
3700 : "- red: redundant coding flag\n"\
3701 : "- ck: clock type used for PCR discontinuities\n"\
3702 : "- P4CC: 4CC of packet property\n"\
3703 : "- PropName: Name of packet property\n"\
3704 : "- pid.P4CC: 4CC of PID property\n"\
3705 : "- pid.PropName: Name of PID property\n"\
3706 : "\n"\
3707 : "EX fmt=\"PID $pid.ID$ packet $pn$ DTS $dts$ CTS $cts$ $lf$\"\n"
3708 : "This dumps packet number, cts and dts as follows: `PID 1 packet 10 DTS 100 CTS 108 \\n`\n"\
3709 : " \n"\
3710 : "An unrecognized keyword or missing property will resolve to an empty string.\n"\
3711 : "\n"\
3712 : "Note: when dumping in interleaved mode, there is no guarantee that the packets will be dumped in their original sequence order since the inspector fetches one packet at a time on each PID.\n")
3713 : .private_size = sizeof(GF_InspectCtx),
3714 : .flags = GF_FS_REG_EXPLICIT_ONLY,
3715 : .max_extra_pids = (u32) -1,
3716 : .args = InspectArgs,
3717 : SETCAPS(InspectCaps),
3718 : .initialize = inspect_initialize,
3719 : .finalize = inspect_finalize,
3720 : .process = inspect_process,
3721 : .process_event = inspect_process_event,
3722 : .configure_pid = inspect_config_input,
3723 : .update_arg = inspect_update_arg,
3724 : };
3725 :
3726 : static const GF_FilterCapability ProberCaps[] =
3727 : {
3728 : //accept any stream but files, framed
3729 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_FILE),
3730 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_SCENE),
3731 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_OD),
3732 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_TEXT),
3733 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
3734 : CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
3735 : {0},
3736 : CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_SCENE),
3737 : CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_OD),
3738 : CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_TEXT),
3739 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_NONE),
3740 : CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_RAW),
3741 : CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
3742 : {0},
3743 : };
3744 :
3745 :
3746 : const GF_FilterRegister ProbeRegister = {
3747 : .name = "probe",
3748 : GF_FS_SET_DESCRIPTION("Probe source")
3749 : GF_FS_SET_HELP("The Probe filter is used by applications (typically `MP4Box`) to query demuxed pids available in a source chain.\n"
3750 : "The filter does not produce any output nor feedback, it is up to the app developer to query input pids of the prober and take appropriated decisions.")
3751 : .private_size = sizeof(GF_InspectCtx),
3752 : .flags = GF_FS_REG_EXPLICIT_ONLY,
3753 : .max_extra_pids = (u32) -1,
3754 : .initialize = inspect_initialize,
3755 : SETCAPS(ProberCaps),
3756 : .finalize = inspect_finalize,
3757 : .process = inspect_process,
3758 : .configure_pid = inspect_config_input,
3759 : };
3760 :
3761 2877 : const GF_FilterRegister *inspect_register(GF_FilterSession *session)
3762 : {
3763 2877 : return &InspectRegister;
3764 : }
3765 :
3766 2877 : const GF_FilterRegister *probe_register(GF_FilterSession *session)
3767 : {
3768 2877 : return &ProbeRegister;
3769 : }
3770 :
3771 :
3772 :
|