LCOV - code coverage report
Current view: top level - filters - inspect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1210 2208 54.8 %
Date: 2021-04-29 23:48:07 Functions: 32 37 86.5 %

          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             : 

Generated by: LCOV version 1.13