From 5cb2fdc8a7bafc280f41c5c1e1f7fdb39f06ca59 Mon Sep 17 00:00:00 2001 From: jeanlf Date: Tue, 15 Oct 2024 17:01:50 +0200 Subject: [PATCH 1/5] lower stack size requirements down to 16k --- applications/gpac/compositor_tools.c | 39 ++-- applications/mp4box/filedump.c | 48 ++-- applications/mp4box/fileimport.c | 259 +++++++++++---------- applications/mp4box/live.c | 23 +- include/gpac/ietf.h | 4 +- include/gpac/internal/ietf_dev.h | 5 +- include/gpac/internal/media_dev.h | 4 +- src/filters/dasher.c | 52 +++-- src/filters/dec_mediacodec.c | 5 +- src/filters/dec_openhevc.c | 50 ++-- src/filters/dmx_saf.c | 14 +- src/filters/encrypt_cenc_isma.c | 73 +++--- src/filters/jsfilter.c | 334 ++++++++++++++------------- src/filters/load_text.c | 11 +- src/filters/mux_isom.c | 24 +- src/filters/reframe_av1.c | 52 +++-- src/filters/reframe_nalu.c | 13 +- src/ietf/rtp_depacketizer.c | 4 +- src/ietf/rtp_packetizer.c | 48 ++-- src/ietf/rtp_pck_3gpp.c | 4 +- src/ietf/rtp_streamer.c | 141 +++++------ src/isomedia/avc_ext.c | 21 +- src/isomedia/box_dump.c | 190 +++++++-------- src/media_tools/av_parsers.c | 55 +++-- src/media_tools/isom_hinter.c | 161 +++++++------ src/media_tools/isom_tools.c | 318 ++++++++++++++----------- src/media_tools/media_export.c | 13 +- src/media_tools/mpd.c | 39 ++-- src/media_tools/mpegts.c | 3 +- src/odf/descriptors.c | 16 +- src/utils/downloader.c | 264 +++------------------ 31 files changed, 1137 insertions(+), 1150 deletions(-) diff --git a/applications/gpac/compositor_tools.c b/applications/gpac/compositor_tools.c index d97eca7348..43cdd3228c 100644 --- a/applications/gpac/compositor_tools.c +++ b/applications/gpac/compositor_tools.c @@ -1227,19 +1227,19 @@ Bool mp4c_task() Bool mp4c_handle_prompt(u8 char_val) { + char szBuf[8192]; MP4C_Command cmdtype = get_gui_cmd(char_val); switch (cmdtype) { case MP4C_OPEN: { - char szURL[2000]; gf_sc_disconnect(compositor); fprintf(stderr, "Enter the absolute URL\n"); - if (1 > scanf("%1999s", szURL)) { + if (1 > scanf("%8191s", szBuf)) { fprintf(stderr, "Cannot read absolute URL, aborting\n"); break; } if (rti_file) init_rti_logs(rti_file, use_rtix); - gf_sc_connect_from_time(compositor, szURL, 0, 0, 0, NULL); + gf_sc_connect_from_time(compositor, szBuf, 0, 0, 0, NULL); } break; case MP4C_RELOAD: @@ -1333,21 +1333,21 @@ Bool mp4c_handle_prompt(u8 char_val) case MP4C_DUMPSCENE: if (is_connected) { - char radname[GF_MAX_PATH], *sExt; + char *sExt; Bool xml_dump, std_out; - radname[0] = 0; + szBuf[0] = 0; do { fprintf(stderr, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stderr: "); fflush(stderr); - } while( 1 > scanf("%1023s", radname)); - sExt = strrchr(radname, '.'); + } while( 1 > scanf("%8191s", szBuf)); + sExt = strrchr(szBuf, '.'); xml_dump = 0; if (sExt) { if (!stricmp(sExt, ".x")) xml_dump = 1; sExt[0] = 0; } - std_out = strnicmp(radname, "std", 3) ? 0 : 1; - GF_Err e = gf_sc_dump_scene(compositor, std_out ? NULL : radname, NULL, xml_dump, 0); + std_out = strnicmp(szBuf, "std", 3) ? 0 : 1; + GF_Err e = gf_sc_dump_scene(compositor, std_out ? NULL : szBuf, NULL, xml_dump, 0); if (e<0) fprintf(stderr, "Dump failed: %s\n", gf_error_to_string(e)); else @@ -1395,42 +1395,41 @@ Bool mp4c_handle_prompt(u8 char_val) break; case MP4C_UPDATE: { - char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); - szCom[0] = 0; - if (1 > scanf("%8191[^\t\n]", szCom)) { + szBuf[0] = 0; + if (1 > scanf("%8191[^\t\n]", szBuf)) { fprintf(stderr, "Cannot read command to send, aborting.\n"); break; } - GF_Err e = gf_sc_scene_update(compositor, NULL, szCom); + GF_Err e = gf_sc_scene_update(compositor, NULL, szBuf); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); } break; case MP4C_EVALJS: { - char jsCode[8192]; fprintf(stderr, "Enter JavaScript code to evaluate:\n"); - jsCode[0] = 0; - if (1 > scanf("%8191[^\t\n]", jsCode)) { + szBuf[0] = 0; + if (1 > scanf("%8191[^\t\n]", szBuf)) { fprintf(stderr, "Cannot read code to evaluate, aborting.\n"); break; } - GF_Err e = gf_sc_scene_update(compositor, "application/ecmascript", jsCode); + GF_Err e = gf_sc_scene_update(compositor, "application/ecmascript", szBuf); if (e) fprintf(stderr, "Processing JS code failed: %s\n", gf_error_to_string(e)); } break; case MP4C_LOGS: { - char szLog[1024], *cur_logs; + char *cur_logs; cur_logs = gf_log_get_tools_levels(); fprintf(stderr, "Enter new log level (current tools %s):\n", cur_logs); gf_free(cur_logs); - if (scanf("%1023s", szLog) < 1) { + szBuf[0] = 0; + if (scanf("%8191s", szBuf) < 1) { fprintf(stderr, "Cannot read new log level, aborting.\n"); break; } - gf_log_modify_tools_levels(szLog); + gf_log_modify_tools_levels(szBuf); } break; diff --git a/applications/mp4box/filedump.c b/applications/mp4box/filedump.c index 058e43a275..97553aa85e 100644 --- a/applications/mp4box/filedump.c +++ b/applications/mp4box/filedump.c @@ -1523,7 +1523,7 @@ static GF_Err dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, GF_Err e = GF_OK; #if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_INSPECT) u32 i, count, track, timescale; - AV1State av1; + AV1State *av1_state; ObuType obu_type = 0; u64 obu_size = 0; u32 hdr_size = 0; @@ -1532,10 +1532,13 @@ static GF_Err dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, track = gf_isom_get_track_by_id(file, trackID); - gf_av1_init_state(&av1); - av1.config = gf_isom_av1_config_get(file, track, 1); - if (!av1.config) { + GF_SAFEALLOC(av1_state, AV1State); + if (!av1_state) return GF_OUT_OF_MEM; + gf_av1_init_state(av1_state); + av1_state->config = gf_isom_av1_config_get(file, track, 1); + if (!av1_state->config) { M4_LOG(GF_LOG_ERROR, ("Error: Track #%d is not AV1!\n", trackID)); + gf_free(av1_state); return GF_ISOM_INVALID_FILE; } @@ -1546,16 +1549,17 @@ static GF_Err dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, fprintf(dump, " \n"); - for (i=0; iobu_array); i++) { - GF_AV1_OBUArrayEntry *obu = gf_list_get(av1.config->obu_array, i); + for (i=0; iconfig->obu_array); i++) { + GF_AV1_OBUArrayEntry *obu = gf_list_get(av1_state->config->obu_array, i); bs = gf_bs_new(obu->obu, (u32) obu->obu_length, GF_BITSTREAM_READ); - e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, av1_state); if (econfig) gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); return e; } - gf_inspect_dump_obu(dump, &av1, obu->obu, obu->obu_length, obu_type, obu_size, hdr_size, dump_crc); + gf_inspect_dump_obu(dump, av1_state, obu->obu, obu->obu_length, obu_type, obu_size, hdr_size, dump_crc); gf_bs_del(bs); } fprintf(dump, " \n"); @@ -1584,14 +1588,14 @@ static GF_Err dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, bs = gf_bs_new(ptr, size, GF_BITSTREAM_READ); while (size) { - e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, av1_state); if (e size) { fprintf(dump, " \n", idx, (u32) obu_size, size); break; } - gf_inspect_dump_obu(dump, &av1, ptr, obu_size, obu_type, obu_size, hdr_size, dump_crc); + gf_inspect_dump_obu(dump, av1_state, ptr, obu_size, obu_type, obu_size, hdr_size, dump_crc); ptr += obu_size; size -= (u32)obu_size; idx++; @@ -1608,8 +1612,9 @@ static GF_Err dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, fprintf(dump, " \n"); fprintf(dump, "\n"); - if (av1.config) gf_odf_av1_cfg_del(av1.config); - gf_av1_reset_state(&av1, GF_TRUE); + if (av1_state->config) gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); #endif return e; } @@ -2991,9 +2996,10 @@ static void DumpStsdInfo(GF_ISOFile *file, u32 trackNum, Bool full_dump, Bool du GF_HEVCConfig *hevccfg, *lhvccfg; GF_OperatingPointsInformation *oinf; #if !defined(GPAC_DISABLE_AV_PARSERS) - HEVCState hevc_state; - memset(&hevc_state, 0, sizeof(HEVCState)); - hevc_state.sps_active_idx = -1; + HEVCState *hvc_state; + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return; + hvc_state->sps_active_idx = -1; #endif gf_isom_get_visual_info(file, trackNum, stsd_idx, &w, &h); @@ -3024,7 +3030,7 @@ static void DumpStsdInfo(GF_ISOFile *file, u32 trackNum, Bool full_dump, Bool du if (hevccfg) { dump_hevc_track_info(file, trackNum, hevccfg #if !defined(GPAC_DISABLE_AV_PARSERS) - , &hevc_state + , hvc_state #endif ); gf_odf_hevc_cfg_del(hevccfg); @@ -3033,12 +3039,14 @@ static void DumpStsdInfo(GF_ISOFile *file, u32 trackNum, Bool full_dump, Bool du if (lhvccfg) { dump_hevc_track_info(file, trackNum, lhvccfg #if !defined(GPAC_DISABLE_AV_PARSERS) - , &hevc_state + , hvc_state #endif ); gf_odf_hevc_cfg_del(lhvccfg); } - +#if !defined(GPAC_DISABLE_AV_PARSERS) + gf_free(hvc_state); +#endif if (gf_isom_get_oinf_info(file, trackNum, &oinf)) { fprintf(stderr, "\n\tOperating Points Information -"); fprintf(stderr, " scalability_mask %d (", oinf->scalability_mask); diff --git a/applications/mp4box/fileimport.c b/applications/mp4box/fileimport.c index 5354825f3e..4d67d32db9 100644 --- a/applications/mp4box/fileimport.c +++ b/applications/mp4box/fileimport.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / mp4box application @@ -118,39 +118,42 @@ GF_Err convert_file_info(char *inName, TrackIdentifier *track_id) GF_Err e; u32 i, cur=1; Bool found; - GF_MediaImporter import; - memset(&import, 0, sizeof(GF_MediaImporter)); + GF_MediaImporter *import = gf_malloc(sizeof(GF_MediaImporter)); + if (!import) return GF_OUT_OF_MEM; + memset(import, 0, sizeof(GF_MediaImporter)); if (!track_id->type) - import.trackID = track_id->ID_or_num; + import->trackID = track_id->ID_or_num; - import.in_name = inName; - import.flags = GF_IMPORT_PROBE_ONLY; - import.print_stats_graph = fs_dump_flags; + import->in_name = inName; + import->flags = GF_IMPORT_PROBE_ONLY; + import->print_stats_graph = fs_dump_flags; - e = gf_media_import(&import); + e = gf_media_import(import); if (e) { M4_LOG(GF_LOG_ERROR, ("Error probing file %s: %s\n", inName, gf_error_to_string(e))); + gf_free(import); return e; } if (track_id->ID_or_num) { fprintf(stderr, "Import probing results for %s track %s%d:\n", inName, track_id->type ? "#" : "ID ", track_id->ID_or_num); } else { fprintf(stderr, "Import probing results for %s:\n", inName); - if (!import.nb_tracks) { + if (!import->nb_tracks) { M4_LOG(GF_LOG_WARNING, ("File has no selectable tracks\n")); + gf_free(import); return GF_OK; } - fprintf(stderr, "File has %d tracks\n", import.nb_tracks); + fprintf(stderr, "File has %d tracks\n", import->nb_tracks); } - if (import.probe_duration) { - fprintf(stderr, "Duration: %g s\n", (Double) (import.probe_duration/1000.0)); + if (import->probe_duration) { + fprintf(stderr, "Duration: %g s\n", (Double) (import->probe_duration/1000.0)); } found = 0; - for (i=0; inb_tracks; i++) { + u32 stype = import->tk_info[i].stream_type; switch (track_id->type) { case 0: //by trackID - if (track_id->ID_or_num && (track_id->ID_or_num != import.tk_info[i].track_num) ) continue; + if (track_id->ID_or_num && (track_id->ID_or_num != import->tk_info[i].track_num) ) continue; break; case 1: //by track nul if (track_id->ID_or_num && (track_id->ID_or_num != i+1) ) continue; @@ -168,15 +171,15 @@ GF_Err convert_file_info(char *inName, TrackIdentifier *track_id) if ((track_id->type>1) && track_id->ID_or_num && (track_id->ID_or_numID_or_num) fprintf(stderr, "- Track %d type: ", import.tk_info[i].track_num); + if (!track_id->ID_or_num) fprintf(stderr, "- Track %d type: ", import->tk_info[i].track_num); else fprintf(stderr, "Track type: "); switch (stype) { case GF_STREAM_VISUAL: - if (import.tk_info[i].media_subtype == GF_ISOM_MEDIA_AUXV) fprintf(stderr, "Auxiliary Video"); - else if (import.tk_info[i].media_subtype == GF_ISOM_MEDIA_PICT) fprintf(stderr, "Picture Sequence"); + if (import->tk_info[i].media_subtype == GF_ISOM_MEDIA_AUXV) fprintf(stderr, "Auxiliary Video"); + else if (import->tk_info[i].media_subtype == GF_ISOM_MEDIA_PICT) fprintf(stderr, "Picture Sequence"); else fprintf(stderr, "Video"); - if (import.tk_info[i].video_info.temporal_enhancement) fprintf(stderr, " Temporal Enhancement"); + if (import->tk_info[i].video_info.temporal_enhancement) fprintf(stderr, " Temporal Enhancement"); break; case GF_STREAM_AUDIO: fprintf(stderr, "Audio"); @@ -194,41 +197,41 @@ GF_Err convert_file_info(char *inName, TrackIdentifier *track_id) fprintf(stderr, "Metadata"); break; default: - fprintf(stderr, "Other (%s)", gf_4cc_to_str(import.tk_info[i].stream_type)); + fprintf(stderr, "Other (%s)", gf_4cc_to_str(import->tk_info[i].stream_type)); break; } - if (import.tk_info[i].codecid) fprintf(stderr, " - Codec %s", gf_codecid_name(import.tk_info[i].codecid)); + if (import->tk_info[i].codecid) fprintf(stderr, " - Codec %s", gf_codecid_name(import->tk_info[i].codecid)); - if (import.tk_info[i].lang) fprintf(stderr, " lang %s", gf_4cc_to_str(import.tk_info[i].lang)); + if (import->tk_info[i].lang) fprintf(stderr, " lang %s", gf_4cc_to_str(import->tk_info[i].lang)); - if (import.tk_info[i].mpeg4_es_id) fprintf(stderr, " MPEG-4 ESID %d", import.tk_info[i].mpeg4_es_id); + if (import->tk_info[i].mpeg4_es_id) fprintf(stderr, " MPEG-4 ESID %d", import->tk_info[i].mpeg4_es_id); - if (import.tk_info[i].prog_num) { - if (!import.nb_progs) { - fprintf(stderr, " Program %d", import.tk_info[i].prog_num); + if (import->tk_info[i].prog_num) { + if (!import->nb_progs) { + fprintf(stderr, " Program %d", import->tk_info[i].prog_num); } else { u32 j; - for (j=0; jnb_progs; j++) { + if (import->tk_info[i].prog_num != import->pg_info[j].number) continue; + fprintf(stderr, " Program %s", import->pg_info[j].name); break; } } } fprintf(stderr, "\n"); - if (import.tk_info[i].video_info.width && import.tk_info[i].video_info.height + if (import->tk_info[i].video_info.width && import->tk_info[i].video_info.height ) { - fprintf(stderr, "\tSize %dx%d", import.tk_info[i].video_info.width, import.tk_info[i].video_info.height); - if (import.tk_info[i].video_info.FPS) fprintf(stderr, " @ %g FPS", import.tk_info[i].video_info.FPS); - if (import.tk_info[i].stream_type==GF_STREAM_VISUAL) { - if (import.tk_info[i].video_info.par) fprintf(stderr, " PAR: %d:%d", import.tk_info[i].video_info.par >> 16, import.tk_info[i].video_info.par & 0xFFFF); + fprintf(stderr, "\tSize %dx%d", import->tk_info[i].video_info.width, import->tk_info[i].video_info.height); + if (import->tk_info[i].video_info.FPS) fprintf(stderr, " @ %g FPS", import->tk_info[i].video_info.FPS); + if (import->tk_info[i].stream_type==GF_STREAM_VISUAL) { + if (import->tk_info[i].video_info.par) fprintf(stderr, " PAR: %d:%d", import->tk_info[i].video_info.par >> 16, import->tk_info[i].video_info.par & 0xFFFF); } fprintf(stderr, "\n"); } - else if ((import.tk_info[i].stream_type==GF_STREAM_AUDIO) && import.tk_info[i].audio_info.sample_rate) { - fprintf(stderr, "\tSampleRate %d - %d channels\n", import.tk_info[i].audio_info.sample_rate, import.tk_info[i].audio_info.nb_channels); + else if ((import->tk_info[i].stream_type==GF_STREAM_AUDIO) && import->tk_info[i].audio_info.sample_rate) { + fprintf(stderr, "\tSampleRate %d - %d channels\n", import->tk_info[i].audio_info.sample_rate, import->tk_info[i].audio_info.nb_channels); } if (track_id->ID_or_num || (track_id->type>1)) { @@ -243,6 +246,7 @@ GF_Err convert_file_info(char *inName, TrackIdentifier *track_id) return GF_BAD_PARAM; } M4_LOG(GF_LOG_INFO, ("For more details, use `gpac -i %s inspect[:deep][:analyze=on|bs]`\n", gf_file_basename(inName))); + gf_free(import); return GF_OK; } @@ -702,7 +706,6 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction u32 tmcd_track = 0, neg_ctts_mode=0; Bool keep_audelim = GF_FALSE; u32 print_stats_graph=fs_dump_flags; - GF_MediaImporter import; char *ext, *final_name=NULL, *handler_name, *rvc_config, *chapter_name; GF_List *kinds; GF_TextFlagsMode txt_mode = GF_ISOM_TEXT_FLAGS_OVERWRITE; @@ -752,6 +755,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction u32 set_tk_idx=0; u32 *reorder_tk_ids = NULL; u32 reorder_tk_ids_count = 0; + GF_MediaImporter *import = NULL; dv_profile[0] = 0; rvc_predefined = 0; @@ -770,8 +774,12 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction import_flags = 0; fake_import = 1; } - - memset(&import, 0, sizeof(GF_MediaImporter)); + import = gf_malloc(sizeof(GF_MediaImporter)); + if (!import) { + e = GF_OUT_OF_MEM; + goto exit; + } + memset(import, 0, sizeof(GF_MediaImporter)); final_name = gf_strdup(inName); #ifdef WIN32 @@ -845,15 +853,15 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction CHECK_FAKEIMPORT("dur") if (strchr(ext, '-')) { - import.duration.num = parse_s32(ext+5, "dur"); - import.duration.den = 1; + import->duration.num = parse_s32(ext+5, "dur"); + import->duration.den = 1; } else { - gf_parse_frac(ext+5, &import.duration); + gf_parse_frac(ext+5, &import->duration); } } else if (!strnicmp(ext+1, "start=", 6)) { CHECK_FAKEIMPORT("start") - import.start_time = atof(ext+7); + import->start_time = atof(ext+7); } else if (!strnicmp(ext+1, "lang=", 5)) { /* prevent leak if param is set twice */ @@ -923,11 +931,11 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction CHECK_FAKEIMPORT("ext") /*extensions begin with '.'*/ if (*(ext+5) == '.') - import.force_ext = gf_strdup(ext+5); + import->force_ext = gf_strdup(ext+5); else { - import.force_ext = gf_calloc(1+strlen(ext+5)+1, 1); - import.force_ext[0] = '.'; - strcat(import.force_ext+1, ext+5); + import->force_ext = gf_calloc(1+strlen(ext+5)+1, 1); + import->force_ext[0] = '.'; + strcat(import->force_ext+1, ext+5); } } else if (!strnicmp(ext+1, "hdlr=", 5)) handler = GF_4CC(ext[6], ext[7], ext[8], ext[9]); @@ -1023,7 +1031,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction else if (!stricmp(ext+1, "subsamples")) { CHECK_FAKEIMPORT("subsamples") import_flags |= GF_IMPORT_SET_SUBSAMPLES; } else if (!stricmp(ext+1, "deps")) { CHECK_FAKEIMPORT("deps") import_flags |= GF_IMPORT_SAMPLE_DEPS; } else if (!stricmp(ext+1, "ccst")) { CHECK_FAKEIMPORT("ccst") set_ccst = GF_TRUE; } - else if (!stricmp(ext+1, "alpha")) { CHECK_FAKEIMPORT("alpha") import.is_alpha = GF_TRUE; } + else if (!stricmp(ext+1, "alpha")) { CHECK_FAKEIMPORT("alpha") import->is_alpha = GF_TRUE; } else if (!stricmp(ext+1, "forcesync")) { CHECK_FAKEIMPORT("forcesync") import_flags |= GF_IMPORT_FORCE_SYNC; } else if (!stricmp(ext+1, "xps_inband")) { CHECK_FAKEIMPORT("xps_inband") xps_inband = 1; } else if (!stricmp(ext+1, "xps_inbandx")) { CHECK_FAKEIMPORT("xps_inbandx") xps_inband = 2; } @@ -1096,7 +1104,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction rvc_config = gf_strdup(ext+5); } } - else if (!strnicmp(ext+1, "fmt=", 4)) import.streamFormat = gf_strdup(ext+5); + else if (!strnicmp(ext+1, "fmt=", 4)) import->streamFormat = gf_strdup(ext+5); else if (!strnicmp(ext+1, "profile=", 8)) { if (!stricmp(ext+9, "high444")) profile = 244; @@ -1126,8 +1134,8 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction else if (!strnicmp(ext+1, "novpsext", 8)) { CHECK_FAKEIMPORT("novpsext") import_flags |= GF_IMPORT_NO_VPS_EXTENSIONS; } else if (!strnicmp(ext+1, "keepav1t", 8)) { CHECK_FAKEIMPORT("keepav1t") import_flags |= GF_IMPORT_KEEP_AV1_TEMPORAL_OBU; } - else if (!strnicmp(ext+1, "font=", 5)) { CHECK_FAKEIMPORT("font") import.fontName = gf_strdup(ext+6); } - else if (!strnicmp(ext+1, "size=", 5)) { CHECK_FAKEIMPORT("size") import.fontSize = parse_u32(ext+6, "size"); } + else if (!strnicmp(ext+1, "font=", 5)) { CHECK_FAKEIMPORT("font") import->fontName = gf_strdup(ext+6); } + else if (!strnicmp(ext+1, "size=", 5)) { CHECK_FAKEIMPORT("size") import->fontSize = parse_u32(ext+6, "size"); } else if (!strnicmp(ext+1, "text_layout=", 12)) { if ( sscanf(ext+13, "%dx%dx%dx%d", &txtw, &txth, &txtx, &txty)==4) { text_layout = 1; @@ -1138,17 +1146,17 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction } #ifndef GPAC_DISABLE_SWF_IMPORT - else if (!stricmp(ext+1, "swf-global")) { CHECK_FAKEIMPORT("swf-global") import.swf_flags |= GF_SM_SWF_STATIC_DICT; } - else if (!stricmp(ext+1, "swf-no-ctrl")) { CHECK_FAKEIMPORT("swf-no-ctrl") import.swf_flags &= ~GF_SM_SWF_SPLIT_TIMELINE; } - else if (!stricmp(ext+1, "swf-no-text")) { CHECK_FAKEIMPORT("swf-no-text") import.swf_flags |= GF_SM_SWF_NO_TEXT; } - else if (!stricmp(ext+1, "swf-no-font")) { CHECK_FAKEIMPORT("swf-no-font") import.swf_flags |= GF_SM_SWF_NO_FONT; } - else if (!stricmp(ext+1, "swf-no-line")) { CHECK_FAKEIMPORT("swf-no-line") import.swf_flags |= GF_SM_SWF_NO_LINE; } - else if (!stricmp(ext+1, "swf-no-grad")) { CHECK_FAKEIMPORT("swf-no-grad") import.swf_flags |= GF_SM_SWF_NO_GRADIENT; } - else if (!stricmp(ext+1, "swf-quad")) { CHECK_FAKEIMPORT("swf-quad") import.swf_flags |= GF_SM_SWF_QUAD_CURVE; } - else if (!stricmp(ext+1, "swf-xlp")) { CHECK_FAKEIMPORT("swf-xlp") import.swf_flags |= GF_SM_SWF_SCALABLE_LINE; } - else if (!stricmp(ext+1, "swf-ic2d")) { CHECK_FAKEIMPORT("swf-ic2d") import.swf_flags |= GF_SM_SWF_USE_IC2D; } - else if (!stricmp(ext+1, "swf-same-app")) { CHECK_FAKEIMPORT("swf-same-app") import.swf_flags |= GF_SM_SWF_REUSE_APPEARANCE; } - else if (!strnicmp(ext+1, "swf-flatten=", 12)) { CHECK_FAKEIMPORT("swf-flatten") import.swf_flatten_angle = (Float) atof(ext+13); } + else if (!stricmp(ext+1, "swf-global")) { CHECK_FAKEIMPORT("swf-global") import->swf_flags |= GF_SM_SWF_STATIC_DICT; } + else if (!stricmp(ext+1, "swf-no-ctrl")) { CHECK_FAKEIMPORT("swf-no-ctrl") import->swf_flags &= ~GF_SM_SWF_SPLIT_TIMELINE; } + else if (!stricmp(ext+1, "swf-no-text")) { CHECK_FAKEIMPORT("swf-no-text") import->swf_flags |= GF_SM_SWF_NO_TEXT; } + else if (!stricmp(ext+1, "swf-no-font")) { CHECK_FAKEIMPORT("swf-no-font") import->swf_flags |= GF_SM_SWF_NO_FONT; } + else if (!stricmp(ext+1, "swf-no-line")) { CHECK_FAKEIMPORT("swf-no-line") import->swf_flags |= GF_SM_SWF_NO_LINE; } + else if (!stricmp(ext+1, "swf-no-grad")) { CHECK_FAKEIMPORT("swf-no-grad") import->swf_flags |= GF_SM_SWF_NO_GRADIENT; } + else if (!stricmp(ext+1, "swf-quad")) { CHECK_FAKEIMPORT("swf-quad") import->swf_flags |= GF_SM_SWF_QUAD_CURVE; } + else if (!stricmp(ext+1, "swf-xlp")) { CHECK_FAKEIMPORT("swf-xlp") import->swf_flags |= GF_SM_SWF_SCALABLE_LINE; } + else if (!stricmp(ext+1, "swf-ic2d")) { CHECK_FAKEIMPORT("swf-ic2d") import->swf_flags |= GF_SM_SWF_USE_IC2D; } + else if (!stricmp(ext+1, "swf-same-app")) { CHECK_FAKEIMPORT("swf-same-app") import->swf_flags |= GF_SM_SWF_REUSE_APPEARANCE; } + else if (!strnicmp(ext+1, "swf-flatten=", 12)) { CHECK_FAKEIMPORT("swf-flatten") import->swf_flatten_angle = (Float) atof(ext+13); } #endif else if (!strnicmp(ext+1, "kind=", 5)) { @@ -1197,16 +1205,16 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction if (opt_dst) opt_dst[0] = 0; if (fchain) fchain[0] = 0; - if (opt_src) import.filter_src_opts = opt_src+6; - if (opt_dst) import.filter_dst_opts = opt_dst+6; + if (opt_src) import->filter_src_opts = opt_src+6; + if (opt_dst) import->filter_dst_opts = opt_dst+6; if (fchain) { //check for old syntax (0.9->1.0) :@@ if (fchain[2]=='@') { - import.filter_chain = fchain + 3; - import.is_chain_old_syntax = GF_TRUE; + import->filter_chain = fchain + 3; + import->is_chain_old_syntax = GF_TRUE; } else { - import.filter_chain = fchain + 2; - import.is_chain_old_syntax = GF_FALSE; + import->filter_chain = fchain + 2; + import->is_chain_old_syntax = GF_FALSE; } } @@ -1217,13 +1225,13 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction else if (!strnicmp(ext+1, "asemode=", 8)){ char *mode = ext+9; if (!stricmp(mode, "v0-bs")) - import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_BS; + import->asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_BS; else if (!stricmp(mode, "v0-2")) - import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_2; + import->asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_2; else if (!stricmp(mode, "v1")) - import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v1_MPEG; + import->asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v1_MPEG; else if (!stricmp(mode, "v1-qt")) - import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v1_QTFF; + import->asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v1_QTFF; else M4_LOG(GF_LOG_ERROR, ("Unrecognized audio sample entry mode %s, ignoring\n", mode)); } @@ -1375,7 +1383,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction } } else if (!strnicmp(ext+1, "ID=", 3)) { - import.target_trackID = (u32) parse_u32(ext+4, "ID"); + import->target_trackID = (u32) parse_u32(ext+4, "ID"); } else if (!strnicmp(ext+1, "tkgp=", 5)) { e = GF_BAD_PARAM; @@ -1429,7 +1437,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction /*check duration import (old syntax)*/ ext = strrchr(final_name, '%'); if (ext && gf_sys_old_arch_compat()) { - if (gf_parse_frac(ext+1, &import.duration)) + if (gf_parse_frac(ext+1, &import->duration)) ext[0] = 0; else ext = NULL; @@ -1459,9 +1467,9 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction if (sep) sep[0] = 0; //we have a fragment, we need to check if the track or the program is present in source - import.in_name = final_name; - import.flags = GF_IMPORT_PROBE_ONLY; - e = gf_media_import(&import); + import->in_name = final_name; + import->flags = GF_IMPORT_PROBE_ONLY; + e = gf_media_import(import); GOTO_EXIT("importing import"); if (!strnicmp(ext, "audio", 5)) do_audio = 1; @@ -1471,9 +1479,9 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction else if (!strnicmp(ext, "trackID=", 8)) track_id = parse_u32(&ext[8], "trackID"); else if (!strnicmp(ext, "PID=", 4)) track_id = parse_u32(&ext[4], "ID"); else if (!strnicmp(ext, "program=", 8)) { - for (i=0; inb_progs; i++) { + if (!stricmp(import->pg_info[i].name, ext+8)) { + prog_id = import->pg_info[i].number; do_all = 0; break; } @@ -1488,25 +1496,25 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction //figure out trackID if (do_audio || do_video || do_auxv || do_pict || track_id) { Bool found = track_id ? GF_FALSE : GF_TRUE; - for (i=0; inb_tracks; i++) { + if (track_id && (import->tk_info[i].track_num==track_id)) { found=GF_TRUE; break; } - if (do_audio && (import.tk_info[i].stream_type==GF_STREAM_AUDIO)) { - track_id = import.tk_info[i].track_num; + if (do_audio && (import->tk_info[i].stream_type==GF_STREAM_AUDIO)) { + track_id = import->tk_info[i].track_num; break; } - else if (do_video && (import.tk_info[i].stream_type==GF_STREAM_VISUAL)) { - track_id = import.tk_info[i].track_num; + else if (do_video && (import->tk_info[i].stream_type==GF_STREAM_VISUAL)) { + track_id = import->tk_info[i].track_num; break; } - else if (do_auxv && (import.tk_info[i].media_subtype==GF_ISOM_MEDIA_AUXV)) { - track_id = import.tk_info[i].track_num; + else if (do_auxv && (import->tk_info[i].media_subtype==GF_ISOM_MEDIA_AUXV)) { + track_id = import->tk_info[i].track_num; break; } - else if (do_pict && (import.tk_info[i].media_subtype==GF_ISOM_MEDIA_PICT)) { - track_id = import.tk_info[i].track_num; + else if (do_pict && (import->tk_info[i].media_subtype==GF_ISOM_MEDIA_PICT)) { + track_id = import->tk_info[i].track_num; break; } } @@ -1549,40 +1557,40 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction if (!tw) tw = w; if (!th) th = h; if (ty==-1) ty = (h>(u32)th) ? h-th : 0; - import.text_width = tw; - import.text_height = th; + import->text_width = tw; + import->text_height = th; } if (is_chap && chap_ref) import_flags |= GF_IMPORT_NO_TEXT_FLUSH; } if (text_layout && txtw && txth) { - import.text_track_width = import.text_width ? import.text_width : txtw; - import.text_track_height = import.text_height ? import.text_height : txth; - import.text_width = txtw; - import.text_height = txth; - import.text_x = txtx; - import.text_y = txty; + import->text_track_width = import->text_width ? import->text_width : txtw; + import->text_track_height = import->text_height ? import->text_height : txth; + import->text_width = txtw; + import->text_height = txth; + import->text_x = txtx; + import->text_y = txty; } check_track_for_svc = check_track_for_lhvc = check_track_for_hevc = 0; source_magic = (u64) gf_crc_32((u8 *)inName, (u32) strlen(inName)); if (!fake_import && (!fsess || mux_args_if_first_pass)) { - import.in_name = final_name; - import.dest = dest; - import.video_fps = force_fps; - import.frames_per_sample = frames_per_sample; - import.flags = import_flags; - import.keep_audelim = keep_audelim; - import.print_stats_graph = print_stats_graph; - import.xps_inband = xps_inband; - import.prog_id = prog_id; - import.trackID = track_id; - import.source_magic = source_magic; - import.track_index = tk_idx; + import->in_name = final_name; + import->dest = dest; + import->video_fps = force_fps; + import->frames_per_sample = frames_per_sample; + import->flags = import_flags; + import->keep_audelim = keep_audelim; + import->print_stats_graph = print_stats_graph; + import->xps_inband = xps_inband; + import->prog_id = prog_id; + import->trackID = track_id; + import->source_magic = source_magic; + import->track_index = tk_idx; //if moov timescale is <0 (auto mode) set it at import time if (moov_timescale<0) { - import.moov_timescale = moov_timescale; + import->moov_timescale = moov_timescale; } //otherwise force it now else if (moov_timescale>0) { @@ -1590,22 +1598,22 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction GOTO_EXIT("changing timescale") } - import.run_in_session = fsess; - import.update_mux_args = NULL; + import->run_in_session = fsess; + import->update_mux_args = NULL; if (do_all) - import.flags |= GF_IMPORT_KEEP_REFS; + import->flags |= GF_IMPORT_KEEP_REFS; - e = gf_media_import(&import); + e = gf_media_import(import); if (e) { - if (import.update_mux_args) gf_free(import.update_mux_args); + if (import->update_mux_args) gf_free(import->update_mux_args); GOTO_EXIT("importing media"); } if (fsess) { - *mux_args_if_first_pass = import.update_mux_args; - import.update_mux_args = NULL; - *mux_sid_if_first_pass = import.update_mux_sid; - import.update_mux_sid = NULL; + *mux_args_if_first_pass = import->update_mux_args; + import->update_mux_args = NULL; + *mux_sid_if_first_pass = import->update_mux_sid; + import->update_mux_sid = NULL; goto exit; } } @@ -1796,10 +1804,10 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction GOTO_EXIT("changing timescale") } - if (import.asemode && (media_type==GF_ISOM_MEDIA_AUDIO)) { + if (import->asemode && (media_type==GF_ISOM_MEDIA_AUDIO)) { u32 sr, ch, bps; gf_isom_get_audio_info(dest, track, 1, &sr, &ch, &bps); - gf_isom_set_audio_info(dest, track, 1, sr, ch, bps, import.asemode); + gf_isom_set_audio_info(dest, track, 1, sr, ch, bps, import->asemode); } } @@ -2116,15 +2124,16 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction gf_list_del(kinds); if (handler_name) gf_free(handler_name); if (chapter_name ) gf_free(chapter_name); - if (import.fontName) gf_free(import.fontName); - if (import.streamFormat) gf_free(import.streamFormat); - if (import.force_ext) gf_free(import.force_ext); + if (import->fontName) gf_free(import->fontName); + if (import->streamFormat) gf_free(import->streamFormat); + if (import->force_ext) gf_free(import->force_ext); if (rvc_config) gf_free(rvc_config); if (edits) gf_free(edits); if (szLan) gf_free((char *)szLan); if (icc_data) gf_free(icc_data); if (final_name) gf_free(final_name); if (reorder_tk_ids) gf_free(reorder_tk_ids); + if (import) gf_free(import); if (!e) return GF_OK; if (fail_msg) { diff --git a/applications/mp4box/live.c b/applications/mp4box/live.c index 15e1466659..53a37303e5 100644 --- a/applications/mp4box/live.c +++ b/applications/mp4box/live.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2019 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * Authors: Jean Le Feuvre @@ -332,6 +332,7 @@ int live_session(int argc, char **argv) char *dst = NULL; const char *ifce_addr = NULL; char *sdp_name = "session.sdp"; + char szBuf[8192]; u16 dst_port = 7000; u32 load_type=0; u32 check; @@ -504,16 +505,15 @@ int live_session(int argc, char **argv) case 'U': case 'u': { - char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); - szCom[0] = 0; - if (1 > scanf("%8191[^\t\n]", szCom)) { + szBuf[0] = 0; + if (1 > scanf("%8191[^\t\n]", szBuf)) { fprintf(stderr, "No command entered properly, aborting.\n"); break; } /*stdin flush bug*/ while (getchar()!='\n') {} - e = gf_seng_encode_from_string(livesess.seng, 0, 0, szCom, live_session_callback); + e = gf_seng_encode_from_string(livesess.seng, 0, 0, szBuf, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); e = gf_seng_aggregate_context(livesess.seng, 0); if (e) fprintf(stderr, "Aggregating context failed: %s\n", gf_error_to_string(e)); @@ -524,16 +524,15 @@ int live_session(int argc, char **argv) case 'E': case 'e': { - char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); - szCom[0] = 0; - if (1 > scanf("%8191[^\t\n]", szCom)) { + szBuf[0] = 0; + if (1 > scanf("%8191[^\t\n]", szBuf)) { printf("No command entered properly, aborting.\n"); break; } /*stdin flush bug*/ while (getchar()!='\n') {} - e = gf_seng_encode_from_string(livesess.seng, 0, 1, szCom, live_session_callback); + e = gf_seng_encode_from_string(livesess.seng, 0, 1, szBuf, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); livesess.critical = (c=='E') ? 1 : 0; e = gf_seng_aggregate_context(livesess.seng, 0); @@ -544,13 +543,13 @@ int live_session(int argc, char **argv) case 'p': { - char rad[GF_MAX_PATH]; + szBuf[0] = 0; fprintf(stderr, "Enter output file name - \"std\" for stderr: "); - if (1 > scanf("%1023s", rad)) { + if (1 > scanf("%8191s", szBuf)) { fprintf(stderr, "No output file name entered, aborting.\n"); break; } - e = gf_seng_save_context(livesess.seng, !strcmp(rad, "std") ? NULL : rad); + e = gf_seng_save_context(livesess.seng, !strcmp(szBuf, "std") ? NULL : szBuf); fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e)); } break; diff --git a/include/gpac/ietf.h b/include/gpac/ietf.h index 174aa72aa7..a605f58e79 100644 --- a/include/gpac/ietf.h +++ b/include/gpac/ietf.h @@ -1597,12 +1597,12 @@ GF_Err gf_rtp_builder_process(GP_RTPPacketizer *builder, u8 *data, u32 data_size /*! formats the "fmtp: " attribute for the MPEG-4 generic packetizer. sdpline shall be at least 2000 char \param builder the target RTP packetizer \param payload_name name of the payload to use (profile of RFC 3640) -\param sdp_line SDP line buffer to fill +\param sdp_line SDP line buffer produced - must be freed by caller \param dsi decoder config of stream if any, or NULL \param dsi_size size of the decoder config \return error if any */ -GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdp_line, char *dsi, u32 dsi_size); +GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, char **out_sdp_line, char *dsi, u32 dsi_size); /*! formats SDP payload name and media name \param builder the target RTP packetizer \param payload_name the buffer to fill with the payload name diff --git a/include/gpac/internal/ietf_dev.h b/include/gpac/internal/ietf_dev.h index c7d0501e87..ea5d3326b4 100644 --- a/include/gpac/internal/ietf_dev.h +++ b/include/gpac/internal/ietf_dev.h @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / IETF RTP/RTSP/SDP sub-project @@ -494,6 +494,9 @@ GF_Err gp_rtp_builder_do_hevc(GP_RTPPacketizer *builder, u8 *data, u32 data_size GF_Err gp_rtp_builder_do_mp2t(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); GF_Err gp_rtp_builder_do_vvc(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); GF_Err gp_rtp_builder_do_opus(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); +#if GPAC_ENABLE_3GPP_DIMS_RTP +GF_Err gp_rtp_builder_do_dims(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration); +#endif #define RTP_VVC_AGG_NAL 0x1C //28 #define RTP_VVC_FRAG_NAL 0x1D //29 diff --git a/include/gpac/internal/media_dev.h b/include/gpac/internal/media_dev.h index a24d222bb5..bcf76a3c72 100644 --- a/include/gpac/internal/media_dev.h +++ b/include/gpac/internal/media_dev.h @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Media Tools sub-project @@ -1139,7 +1139,7 @@ GP_RTPPacketizer *gf_rtp_packetizer_create_and_init_from_file(GF_ISOFile *file, u32 InterleaveGroupID, u8 InterleaveGroupPriority); -void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, u32 w, u32 h, s32 tx, s32 ty, s16 l, u32 max_w, u32 max_h, char *tx3g_base64); +void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char **out_sdp_line, u32 w, u32 h, s32 tx, s32 ty, s16 l, u32 max_w, u32 max_h, char *tx3g_base64); #endif diff --git a/src/filters/dasher.c b/src/filters/dasher.c index 670d4dbac7..6759398e8d 100644 --- a/src/filters/dasher.c +++ b/src/filters/dasher.c @@ -1476,40 +1476,46 @@ static GF_Err dasher_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is GF_HEVCConfig* hevccfg = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, GF_FALSE); if (hevccfg) { Bool is_interlaced; - HEVCState hevc; + HEVCState *hvc_state; HEVC_SPS* sps; - memset(&hevc, 0, sizeof(HEVCState)); - gf_hevc_parse_ps(hevccfg, &hevc, GF_HEVC_NALU_VID_PARAM); - gf_hevc_parse_ps(hevccfg, &hevc, GF_HEVC_NALU_SEQ_PARAM); - sps = &hevc.sps[hevc.sps_active_idx]; - if (sps && sps->colour_description_present_flag) { - DasherHDRType old_hdr_type = ds->hdr_type; - if (sps->colour_primaries == 9 && sps->matrix_coeffs == 9) { - if (sps->transfer_characteristic == 14) ds->hdr_type = DASHER_HDR_HLG; //TODO: parse alternative_transfer_characteristics SEI - if (sps->transfer_characteristic == 16) ds->hdr_type = DASHER_HDR_PQ10; + GF_SAFEALLOC(hvc_state, HEVCState); + if (hvc_state) { + gf_hevc_parse_ps(hevccfg, hvc_state, GF_HEVC_NALU_VID_PARAM); + gf_hevc_parse_ps(hevccfg, hvc_state, GF_HEVC_NALU_SEQ_PARAM); + sps = &hvc_state->sps[hvc_state->sps_active_idx]; + if (sps && sps->colour_description_present_flag) { + DasherHDRType old_hdr_type = ds->hdr_type; + if (sps->colour_primaries == 9 && sps->matrix_coeffs == 9) { + if (sps->transfer_characteristic == 14) ds->hdr_type = DASHER_HDR_HLG; //TODO: parse alternative_transfer_characteristics SEI + if (sps->transfer_characteristic == 16) ds->hdr_type = DASHER_HDR_PQ10; + } + if (old_hdr_type != ds->hdr_type) period_switch = GF_TRUE; } - if (old_hdr_type != ds->hdr_type) period_switch = GF_TRUE; - } - is_interlaced = hevccfg->interlaced_source_flag ? GF_TRUE : GF_FALSE; - if (ds->interlaced != is_interlaced) period_switch = GF_TRUE; - ds->interlaced = is_interlaced; + is_interlaced = hevccfg->interlaced_source_flag ? GF_TRUE : GF_FALSE; + if (ds->interlaced != is_interlaced) period_switch = GF_TRUE; + ds->interlaced = is_interlaced; - gf_odf_hevc_cfg_del(hevccfg); + gf_odf_hevc_cfg_del(hevccfg); + gf_free(hvc_state); + } } } else if (ds->codec_id == GF_CODECID_AVC || ds->codec_id == GF_CODECID_SVC || ds->codec_id == GF_CODECID_MVC) { - AVCState avc; GF_AVCConfig* avccfg = gf_odf_avc_cfg_read(dsi->value.data.ptr, dsi->value.data.size); if (avccfg) { GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(avccfg->sequenceParameterSets, 0); if (sl) { s32 idx; - memset(&avc, 0, sizeof(AVCState)); - idx = gf_avc_read_sps(sl->data, sl->size, &avc, 0, NULL); - if (idx>=0) { - Bool is_interlaced = avc.sps[idx].frame_mbs_only_flag ? GF_FALSE : GF_TRUE; - if (ds->interlaced != is_interlaced) period_switch = GF_TRUE; - ds->interlaced = is_interlaced; + AVCState *avc_state; + GF_SAFEALLOC(avc_state, AVCState); + if (avc_state) { + idx = gf_avc_read_sps(sl->data, sl->size, avc_state, 0, NULL); + if (idx>=0) { + Bool is_interlaced = avc_state->sps[idx].frame_mbs_only_flag ? GF_FALSE : GF_TRUE; + if (ds->interlaced != is_interlaced) period_switch = GF_TRUE; + ds->interlaced = is_interlaced; + } + gf_free(avc_state); } } gf_odf_avc_cfg_del(avccfg); diff --git a/src/filters/dec_mediacodec.c b/src/filters/dec_mediacodec.c index eaf7189d8d..101a6493ca 100644 --- a/src/filters/dec_mediacodec.c +++ b/src/filters/dec_mediacodec.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / mediacodec decoder filter @@ -696,11 +696,8 @@ static GF_Err mcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_ ctx->mime = "video/hevc"; GF_HEVCConfig *hvcc; GF_NALUFFParam *sl; - HEVCState hevc; u32 j; - memset(&hevc, 0, sizeof(HEVCState)); - hvcc = gf_odf_hevc_cfg_read(dcd->value.data.ptr, dcd->value.data.size, GF_FALSE); if (!hvcc) return GF_NON_COMPLIANT_BITSTREAM; ctx->nalu_size_length = hvcc->nal_unit_size; diff --git a/src/filters/dec_openhevc.c b/src/filters/dec_openhevc.c index b655b76e83..be14ddaf20 100644 --- a/src/filters/dec_openhevc.c +++ b/src/filters/dec_openhevc.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2010-2023 + * Copyright (c) Telecom ParisTech 2010-2024 * All rights reserved * * This file is part of GPAC / OpenHEVC decoder filter @@ -481,18 +481,22 @@ static GF_Err ohevcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool #ifdef OPENHEVC_HAS_AVC_BASE if (codecid==GF_CODECID_AVC) { GF_AVCConfig *avcc = NULL; - AVCState avc; - memset(&avc, 0, sizeof(AVCState)); + AVCState *avc_state; + GF_SAFEALLOC(avc_state, AVCState); + if (!avc_state) return GF_OUT_OF_MEM; avcc = gf_odf_avc_cfg_read(dsi->value.data.ptr, dsi->value.data.size); - if (!avcc) return GF_NON_COMPLIANT_BITSTREAM; + if (!avcc) { + gf_free(avc_state); + return GF_NON_COMPLIANT_BITSTREAM; + } ctx->avc_nalu_size_length = avcc->nal_unit_size; for (i=0; i< gf_list_count(avcc->sequenceParameterSets); i++) { GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(avcc->sequenceParameterSets, i); - s32 idx = gf_avc_read_sps(sl->data, sl->size, &avc, 0, NULL); - ctx->width = MAX(avc.sps[idx].width, ctx->width); - ctx->height = MAX(avc.sps[idx].height, ctx->height); + s32 idx = gf_avc_read_sps(sl->data, sl->size, avc_state, 0, NULL); + ctx->width = MAX(avc_state->sps[idx].width, ctx->width); + ctx->height = MAX(avc_state->sps[idx].height, ctx->height); ctx->luma_bpp = avcc->luma_bit_depth; ctx->chroma_bpp = avcc->chroma_bit_depth; ctx->chroma_format_idc = avcc->chroma_format; @@ -510,20 +514,25 @@ static GF_Err ohevcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool } } gf_odf_avc_cfg_del(avcc); + gf_free(avc_state); } else #endif { GF_HEVCConfig *hvcc = NULL; GF_HEVCConfig *hvcc_enh = NULL; - HEVCState hevc; + HEVCState *hvc_state; u32 j; GF_List *SPSs=NULL, *PPSs=NULL, *VPSs=NULL; - memset(&hevc, 0, sizeof(HEVCState)); - hvcc = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, GF_FALSE); - if (!hvcc) return GF_NON_COMPLIANT_BITSTREAM; + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return GF_OUT_OF_MEM; + hvcc = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, GF_FALSE); + if (!hvcc) { + gf_free(hvc_state); + return GF_NON_COMPLIANT_BITSTREAM; + } ctx->hevc_nalu_size_length = hvcc->nal_unit_size; if (dsi_enh) { @@ -546,12 +555,12 @@ static GF_Err ohevcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool u16 hdr = sl->data[0] << 8 | sl->data[1]; if (ar->type==GF_HEVC_NALU_SEQ_PARAM) { - idx = gf_hevc_read_sps(sl->data, sl->size, &hevc); - ctx->width = MAX(hevc.sps[idx].width, ctx->width); - ctx->height = MAX(hevc.sps[idx].height, ctx->height); - ctx->luma_bpp = MAX(hevc.sps[idx].bit_depth_luma, ctx->luma_bpp); - ctx->chroma_bpp = MAX(hevc.sps[idx].bit_depth_chroma, ctx->chroma_bpp); - ctx->chroma_format_idc = hevc.sps[idx].chroma_format_idc; + idx = gf_hevc_read_sps(sl->data, sl->size, hvc_state); + ctx->width = MAX(hvc_state->sps[idx].width, ctx->width); + ctx->height = MAX(hvc_state->sps[idx].height, ctx->height); + ctx->luma_bpp = MAX(hvc_state->sps[idx].bit_depth_luma, ctx->luma_bpp); + ctx->chroma_bpp = MAX(hvc_state->sps[idx].bit_depth_chroma, ctx->chroma_bpp); + ctx->chroma_format_idc = hvc_state->sps[idx].chroma_format_idc; if (hdr & 0x1f8) { ctx->nb_layers ++; @@ -559,15 +568,15 @@ static GF_Err ohevcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool SPSs = ar->nalus; } else if (ar->type==GF_HEVC_NALU_VID_PARAM) { - s32 vps_id = gf_hevc_read_vps(sl->data, sl->size, &hevc); + s32 vps_id = gf_hevc_read_vps(sl->data, sl->size, hvc_state); //multiview - if ((vps_id>=0) && (hevc.vps[vps_id].scalability_mask[1])) { + if ((vps_id>=0) && (hvc_state->vps[vps_id].scalability_mask[1])) { ctx->is_multiview = GF_TRUE; } VPSs = ar->nalus; } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) { - gf_hevc_read_pps(sl->data, sl->size, &hevc); + gf_hevc_read_pps(sl->data, sl->size, hvc_state); PPSs = ar->nalus; } } @@ -587,6 +596,7 @@ static GF_Err ohevcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool gf_odf_hevc_cfg_write(hvcc, &patched_dsi, &patched_dsi_size); } gf_odf_hevc_cfg_del(hvcc); + gf_free(hvc_state); } } diff --git a/src/filters/dmx_saf.c b/src/filters/dmx_saf.c index e7baa49c51..c6c22f65a2 100644 --- a/src/filters/dmx_saf.c +++ b/src/filters/dmx_saf.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2005-2023 + * Copyright (c) Telecom ParisTech 2005-2024 * All rights reserved * * This file is part of GPAC / SAF demuxer filter @@ -233,7 +233,6 @@ static void safdmx_check_dur(GF_SAFDmxCtx *ctx) GF_BitStream *bs; GF_Fraction64 dur; const GF_PropertyValue *p; - StreamInfo si[1024]; FILE *stream; @@ -259,6 +258,7 @@ static void safdmx_check_dur(GF_SAFDmxCtx *ctx) bs = gf_bs_from_file(stream, GF_BITSTREAM_READ); ctx->file_size = gf_bs_get_size(bs); + StreamInfo *si = NULL; dur.num = 0; dur.den = 1000; nb_streams=0; @@ -279,9 +279,12 @@ static void safdmx_check_dur(GF_SAFDmxCtx *ctx) gf_bs_read_u16(bs); ts_res = gf_bs_read_u24(bs); au_size -= 5; - si[nb_streams].stream_id = stream_id; - si[nb_streams].ts_res = ts_res; - nb_streams++; + si = gf_realloc(si, sizeof(StreamInfo)*(nb_streams+1)); + if (si) { + si[nb_streams].stream_id = stream_id; + si[nb_streams].ts_res = ts_res; + nb_streams++; + } } } if (ts_res && (au_type==4)) { @@ -291,6 +294,7 @@ static void safdmx_check_dur(GF_SAFDmxCtx *ctx) } gf_bs_skip_bytes(bs, au_size); } + gf_free(si); gf_bs_del(bs); gf_fclose(stream); diff --git a/src/filters/encrypt_cenc_isma.c b/src/filters/encrypt_cenc_isma.c index 8148612933..ddc0d86574 100644 --- a/src/filters/encrypt_cenc_isma.c +++ b/src/filters/encrypt_cenc_isma.c @@ -64,6 +64,11 @@ typedef struct u32 IV_size; } CENC_MKey; +typedef struct +{ + u32 clear, encrypted; +} OBURange; + typedef struct { Bool passthrough; @@ -113,7 +118,10 @@ typedef struct AVCState *avc_state; HEVCState *hevc_state; AV1State *av1_state; + OBURange *av1_vpx_ranges; //[AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS]; + GF_VPConfig *vp9_cfg; + u32 *vpx_frame_sizes; //[VP9_MAX_FRAMES_IN_SUPERFRAME]; VVCState *vvc_state; #endif @@ -616,6 +624,10 @@ static void cenc_pid_reset_codec_states(GF_CENCStream *cstr) gf_free(cstr->av1_state); cstr->av1_state = NULL; } + if (cstr->av1_vpx_ranges) { + gf_free(cstr->av1_vpx_ranges); + cstr->av1_vpx_ranges = NULL; + } if (cstr->avc_state) { gf_free(cstr->avc_state); cstr->avc_state = NULL; @@ -632,6 +644,10 @@ static void cenc_pid_reset_codec_states(GF_CENCStream *cstr) gf_odf_vp_cfg_del(cstr->vp9_cfg); cstr->vp9_cfg = NULL; } + if (cstr->vpx_frame_sizes) { + gf_free(cstr->vpx_frame_sizes); + cstr->vpx_frame_sizes = NULL; + } #endif } @@ -723,7 +739,16 @@ static GF_Err cenc_enc_configure(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, const case CENC_AV1: GF_SAFEALLOC(cstr->av1_state, AV1State); if (!cstr->av1_state) return GF_OUT_OF_MEM; + if (!cstr->av1_vpx_ranges) cstr->av1_vpx_ranges = gf_malloc(sizeof(OBURange) * AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS); + if (!cstr->av1_vpx_ranges) return GF_OUT_OF_MEM; break; + case CENC_VPX: + if (!cstr->vpx_frame_sizes) cstr->vpx_frame_sizes = gf_malloc(sizeof(u32) * VP9_MAX_FRAMES_IN_SUPERFRAME); + if (!cstr->vpx_frame_sizes) return GF_OUT_OF_MEM; + if (!cstr->av1_vpx_ranges) cstr->av1_vpx_ranges = gf_malloc(sizeof(OBURange) * AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS); + if (!cstr->av1_vpx_ranges) return GF_OUT_OF_MEM; + break; + #endif } } @@ -1747,10 +1772,6 @@ static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_Fi #ifndef GPAC_DISABLE_AV_PARSERS ObuType obut = 0; u32 num_frames_in_superframe = 0, superframe_index_size = 0; - u32 frame_sizes[VP9_MAX_FRAMES_IN_SUPERFRAME]; - struct { - int clear, encrypted; - } ranges[AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS]; u64 obu_size = 0; u32 hdr_size = 0; #else @@ -1796,14 +1817,14 @@ static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_Fi } else { nb_ranges = cstr->av1_state->frame_state.nb_tiles_in_obu; - ranges[0].clear = cstr->av1_state->frame_state.tiles[0].obu_start_offset; - ranges[0].encrypted = cstr->av1_state->frame_state.tiles[0].size; + cstr->av1_vpx_ranges[0].clear = cstr->av1_state->frame_state.tiles[0].obu_start_offset; + cstr->av1_vpx_ranges[0].encrypted = cstr->av1_state->frame_state.tiles[0].size; for (i = 1; i < nb_ranges; ++i) { - ranges[i].clear = cstr->av1_state->frame_state.tiles[i].obu_start_offset - (cstr->av1_state->frame_state.tiles[i - 1].obu_start_offset + cstr->av1_state->frame_state.tiles[i - 1].size); - ranges[i].encrypted = cstr->av1_state->frame_state.tiles[i].size; + cstr->av1_vpx_ranges[i].clear = cstr->av1_state->frame_state.tiles[i].obu_start_offset - (cstr->av1_state->frame_state.tiles[i - 1].obu_start_offset + cstr->av1_state->frame_state.tiles[i - 1].size); + cstr->av1_vpx_ranges[i].encrypted = cstr->av1_state->frame_state.tiles[i].size; } - clear_bytes = ranges[0].clear; - nalu_size = clear_bytes + ranges[0].encrypted; + clear_bytes = cstr->av1_vpx_ranges[0].clear; + nalu_size = clear_bytes + cstr->av1_vpx_ranges[0].encrypted; /* A subsample SHALL be created for each tile even if less than 16 bytes see https://github.com/AOMediaCodec/av1-isobmff/pull/116#discussion_r340176740 @@ -1837,7 +1858,7 @@ static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_Fi } pos = gf_bs_get_position(ctx->bs_r); - e = gf_vp9_parse_superframe(ctx->bs_r, pck_size, &num_frames_in_superframe, frame_sizes, &superframe_index_size); + e = gf_vp9_parse_superframe(ctx->bs_r, pck_size, &num_frames_in_superframe, cstr->vpx_frame_sizes, &superframe_index_size); if (e) return e; gf_bs_seek(ctx->bs_r, pos); @@ -1853,10 +1874,10 @@ static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_Fi return e; } - ranges[i].clear = (int)(gf_bs_get_position(ctx->bs_r) - pos2); - ranges[i].encrypted = frame_sizes[i] - ranges[i].clear; + cstr->av1_vpx_ranges[i].clear = (int)(gf_bs_get_position(ctx->bs_r) - pos2); + cstr->av1_vpx_ranges[i].encrypted = cstr->vpx_frame_sizes[i] - cstr->av1_vpx_ranges[i].clear; - gf_bs_seek(ctx->bs_r, pos2 + frame_sizes[i]); + gf_bs_seek(ctx->bs_r, pos2 + cstr->vpx_frame_sizes[i]); } if (gf_bs_get_position(ctx->bs_r) + superframe_index_size != pos + pck_size) { GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[CENC] Inconsistent VP9 size %u (parsed "LLU") at DTS "LLU". Re-import raw VP9/IVF for more details.\n", @@ -1864,19 +1885,19 @@ static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_Fi } gf_bs_seek(ctx->bs_r, pos); - clear_bytes = ranges[0].clear; - gf_assert(frame_sizes[0] == ranges[0].clear + ranges[0].encrypted); - nalu_size = frame_sizes[0]; + clear_bytes = cstr->av1_vpx_ranges[0].clear; + gf_assert(cstr->vpx_frame_sizes[0] == cstr->av1_vpx_ranges[0].clear + cstr->av1_vpx_ranges[0].encrypted); + nalu_size = cstr->vpx_frame_sizes[0]; //final superframe index must be in clear if (superframe_index_size > 0) { - ranges[nb_ranges].clear = superframe_index_size; - ranges[nb_ranges].encrypted = 0; + cstr->av1_vpx_ranges[nb_ranges].clear = superframe_index_size; + cstr->av1_vpx_ranges[nb_ranges].encrypted = 0; nb_ranges++; } //not clearly defined in the spec (so we do the same as in AV1 which is more clearly defined): - if (frame_sizes[0] - clear_bytes >= 16) { + if (cstr->vpx_frame_sizes[0] - clear_bytes >= 16) { //A subsample SHALL be created for each tile >= 16 bytes. If previous range had encrypted bytes, create a new one, otherwise merge in prev if (prev_entry_bytes_crypt) { if (!nb_subsamples) gf_bs_write_int(sai_bs, 0, nb_subsamples_bits); @@ -2123,16 +2144,16 @@ static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_Fi #endif switch (cstr->cenc_codec) { case CENC_AV1: - clear_bytes = ranges[range_idx].clear; - nalu_size = clear_bytes + ranges[range_idx].encrypted; + clear_bytes = cstr->av1_vpx_ranges[range_idx].clear; + nalu_size = clear_bytes + cstr->av1_vpx_ranges[range_idx].encrypted; break; case CENC_VPX: if (nb_ranges > 1) { - clear_bytes = ranges[range_idx].clear; - nalu_size = clear_bytes + ranges[range_idx].encrypted; + clear_bytes = cstr->av1_vpx_ranges[range_idx].clear; + nalu_size = clear_bytes + cstr->av1_vpx_ranges[range_idx].encrypted; } else { /*last*/ - nalu_size = clear_bytes = ranges[range_idx].clear; - gf_assert(ranges[range_idx].encrypted == 0); + nalu_size = clear_bytes = cstr->av1_vpx_ranges[range_idx].clear; + gf_assert(cstr->av1_vpx_ranges[range_idx].encrypted == 0); } break; default: diff --git a/src/filters/jsfilter.c b/src/filters/jsfilter.c index f8dd4dc5e7..da2ca68bbb 100644 --- a/src/filters/jsfilter.c +++ b/src/filters/jsfilter.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2019-2023 + * Copyright (c) Telecom ParisTech 2019-2024 * All rights reserved * * This file is part of GPAC / QuickJS bindings for GF_Filter @@ -4465,173 +4465,11 @@ static GF_Err jsfilter_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool return e; } -void js_load_constants(JSContext *ctx, JSValue global_obj) -{ - JSValue val; - - val = JS_NewObject(ctx); - JS_SetPropertyStr(ctx, val, "log", JS_NewCFunction(ctx, js_print, "log", 1)); - JS_SetPropertyStr(ctx, global_obj, "console", val); - #define DEF_CONST( _val ) \ JS_SetPropertyStr(ctx, global_obj, #_val, JS_NewInt32(ctx, _val)); - DEF_CONST(GF_LOG_ERROR) - DEF_CONST(GF_LOG_WARNING) - DEF_CONST(GF_LOG_INFO) - DEF_CONST(GF_LOG_DEBUG) - - DEF_CONST(GF_PROP_BOOL) - DEF_CONST(GF_PROP_UINT) - DEF_CONST(GF_PROP_SINT) - DEF_CONST(GF_PROP_LUINT) - DEF_CONST(GF_PROP_LSINT) - DEF_CONST(GF_PROP_FRACTION) - DEF_CONST(GF_PROP_FRACTION64) - DEF_CONST(GF_PROP_FLOAT) - DEF_CONST(GF_PROP_DOUBLE) - DEF_CONST(GF_PROP_VEC2I) - DEF_CONST(GF_PROP_VEC2) - DEF_CONST(GF_PROP_VEC3I) - DEF_CONST(GF_PROP_VEC4I) - DEF_CONST(GF_PROP_STRING) - DEF_CONST(GF_PROP_STRING) - DEF_CONST(GF_PROP_STRING_NO_COPY) - DEF_CONST(GF_PROP_DATA) - DEF_CONST(GF_PROP_NAME) - DEF_CONST(GF_PROP_DATA_NO_COPY) - DEF_CONST(GF_PROP_CONST_DATA) - DEF_CONST(GF_PROP_POINTER) - DEF_CONST(GF_PROP_STRING_LIST) - DEF_CONST(GF_PROP_UINT_LIST) - DEF_CONST(GF_PROP_SINT_LIST) - DEF_CONST(GF_PROP_VEC2I_LIST) - DEF_CONST(GF_PROP_4CC) - DEF_CONST(GF_PROP_4CC_LIST) - - DEF_CONST(GF_PROP_PIXFMT) - DEF_CONST(GF_PROP_PCMFMT) - DEF_CONST(GF_PROP_CICP_COL_PRIM) - DEF_CONST(GF_PROP_CICP_COL_TFC) - DEF_CONST(GF_PROP_CICP_COL_MX) - DEF_CONST(GF_PROP_CICP_LAYOUT) - - DEF_CONST(GF_FEVT_PLAY) - DEF_CONST(GF_FEVT_SET_SPEED) - DEF_CONST(GF_FEVT_STOP) - DEF_CONST(GF_FEVT_PAUSE) - DEF_CONST(GF_FEVT_RESUME) - DEF_CONST(GF_FEVT_SOURCE_SEEK) - DEF_CONST(GF_FEVT_SOURCE_SWITCH) - DEF_CONST(GF_FEVT_SEGMENT_SIZE) - DEF_CONST(GF_FEVT_QUALITY_SWITCH) - DEF_CONST(GF_FEVT_VISIBILITY_HINT) - DEF_CONST(GF_FEVT_INFO_UPDATE) - DEF_CONST(GF_FEVT_BUFFER_REQ) - DEF_CONST(GF_FEVT_CAPS_CHANGE) - DEF_CONST(GF_FEVT_CONNECT_FAIL) - DEF_CONST(GF_FEVT_USER) - - DEF_CONST(GF_STATS_LOCAL) - DEF_CONST(GF_STATS_LOCAL_INPUTS) - DEF_CONST(GF_STATS_DECODER_SINK) - DEF_CONST(GF_STATS_DECODER_SOURCE) - DEF_CONST(GF_STATS_ENCODER_SINK) - DEF_CONST(GF_STATS_ENCODER_SOURCE) - DEF_CONST(GF_STATS_SINK) - - DEF_CONST(GF_FILTER_CLOCK_NONE) - DEF_CONST(GF_FILTER_CLOCK_PCR) - DEF_CONST(GF_FILTER_CLOCK_PCR_DISC) - - DEF_CONST(GF_FILTER_SAP_NONE) - DEF_CONST(GF_FILTER_SAP_1) - DEF_CONST(GF_FILTER_SAP_2) - DEF_CONST(GF_FILTER_SAP_3) - DEF_CONST(GF_FILTER_SAP_4) - DEF_CONST(GF_FILTER_SAP_4_PROL) - - DEF_CONST(GF_STATS_LOCAL) - DEF_CONST(GF_STATS_LOCAL_INPUTS) - DEF_CONST(GF_STATS_DECODER_SINK) - DEF_CONST(GF_STATS_DECODER_SOURCE) - DEF_CONST(GF_STATS_ENCODER_SINK) - DEF_CONST(GF_STATS_ENCODER_SOURCE) - DEF_CONST(GF_STATS_SINK) - - DEF_CONST(GF_EOS); - DEF_CONST(GF_OK) - DEF_CONST(GF_BAD_PARAM) - DEF_CONST(GF_OUT_OF_MEM) - DEF_CONST(GF_IO_ERR) - DEF_CONST(GF_NOT_SUPPORTED) - DEF_CONST(GF_CORRUPTED_DATA) - DEF_CONST(GF_SG_UNKNOWN_NODE) - DEF_CONST(GF_SG_INVALID_PROTO) - DEF_CONST(GF_SCRIPT_ERROR) - DEF_CONST(GF_BUFFER_TOO_SMALL) - DEF_CONST(GF_NON_COMPLIANT_BITSTREAM) - DEF_CONST(GF_FILTER_NOT_FOUND) - DEF_CONST(GF_URL_ERROR) - DEF_CONST(GF_SERVICE_ERROR) - DEF_CONST(GF_REMOTE_SERVICE_ERROR) - DEF_CONST(GF_STREAM_NOT_FOUND) - DEF_CONST(GF_ISOM_INVALID_FILE) - DEF_CONST(GF_ISOM_INCOMPLETE_FILE) - DEF_CONST(GF_ISOM_INVALID_MEDIA) - DEF_CONST(GF_ISOM_INVALID_MODE) - DEF_CONST(GF_ISOM_UNKNOWN_DATA_REF) - DEF_CONST(GF_ODF_INVALID_DESCRIPTOR) - DEF_CONST(GF_ODF_FORBIDDEN_DESCRIPTOR) - DEF_CONST(GF_ODF_INVALID_COMMAND) - DEF_CONST(GF_BIFS_UNKNOWN_VERSION) - DEF_CONST(GF_IP_ADDRESS_NOT_FOUND) - DEF_CONST(GF_IP_CONNECTION_FAILURE) - DEF_CONST(GF_IP_NETWORK_FAILURE) - DEF_CONST(GF_IP_CONNECTION_CLOSED) - DEF_CONST(GF_IP_NETWORK_EMPTY) - DEF_CONST(GF_IP_UDP_TIMEOUT) - DEF_CONST(GF_AUTHENTICATION_FAILURE) - DEF_CONST(GF_NOT_READY) - DEF_CONST(GF_INVALID_CONFIGURATION) - DEF_CONST(GF_NOT_FOUND) - DEF_CONST(GF_PROFILE_NOT_SUPPORTED) - DEF_CONST(GF_REQUIRES_NEW_INSTANCE) - DEF_CONST(GF_FILTER_NOT_SUPPORTED) - - DEF_CONST(JSF_SETUP_ERROR) - DEF_CONST(JSF_NOTIF_ERROR) - DEF_CONST(JSF_NOTIF_ERROR_AND_DISCONNECT) - - DEF_CONST(GF_FILTER_UPDATE_DOWNSTREAM) - DEF_CONST(GF_FILTER_UPDATE_UPSTREAM) - - DEF_CONST(GF_EVENT_CLICK) - DEF_CONST(GF_EVENT_MOUSEUP) - DEF_CONST(GF_EVENT_MOUSEDOWN) - DEF_CONST(GF_EVENT_MOUSEMOVE) - DEF_CONST(GF_EVENT_MOUSEWHEEL) - DEF_CONST(GF_EVENT_DBLCLICK) - DEF_CONST(GF_EVENT_MULTITOUCH) - DEF_CONST(GF_EVENT_KEYUP) - DEF_CONST(GF_EVENT_KEYDOWN) - DEF_CONST(GF_EVENT_TEXTINPUT) - DEF_CONST(GF_EVENT_DROPFILE) - DEF_CONST(GF_EVENT_TIMESHIFT_DEPTH) - DEF_CONST(GF_EVENT_TIMESHIFT_UPDATE) - DEF_CONST(GF_EVENT_TIMESHIFT_OVERFLOW) - DEF_CONST(GF_EVENT_TIMESHIFT_UNDERRUN) - DEF_CONST(GF_EVENT_PASTE_TEXT) - DEF_CONST(GF_EVENT_COPY_TEXT) - DEF_CONST(GF_EVENT_SIZE) - DEF_CONST(GF_EVENT_SHOWHIDE) - DEF_CONST(GF_EVENT_MOVE) - DEF_CONST(GF_EVENT_SET_CAPTION) - DEF_CONST(GF_EVENT_REFRESH) - DEF_CONST(GF_EVENT_QUIT) - DEF_CONST(GF_EVENT_CODEC_SLOW) - DEF_CONST(GF_EVENT_CODEC_OK) - +static void js_load_key_names(JSContext *ctx, JSValue global_obj) +{ DEF_CONST(GF_KEY_UNIDENTIFIED) DEF_CONST(GF_KEY_ACCEPT) DEF_CONST(GF_KEY_AGAIN) @@ -4846,7 +4684,173 @@ void js_load_constants(JSContext *ctx, JSValue global_obj) DEF_CONST(GF_KEY_EXT_NUMPAD) DEF_CONST(GF_KEY_EXT_LEFT) DEF_CONST(GF_KEY_EXT_RIGHT) +} + +void js_load_constants(JSContext *ctx, JSValue global_obj) +{ + JSValue val; + + val = JS_NewObject(ctx); + JS_SetPropertyStr(ctx, val, "log", JS_NewCFunction(ctx, js_print, "log", 1)); + JS_SetPropertyStr(ctx, global_obj, "console", val); + + DEF_CONST(GF_LOG_ERROR) + DEF_CONST(GF_LOG_WARNING) + DEF_CONST(GF_LOG_INFO) + DEF_CONST(GF_LOG_DEBUG) + + DEF_CONST(GF_PROP_BOOL) + DEF_CONST(GF_PROP_UINT) + DEF_CONST(GF_PROP_SINT) + DEF_CONST(GF_PROP_LUINT) + DEF_CONST(GF_PROP_LSINT) + DEF_CONST(GF_PROP_FRACTION) + DEF_CONST(GF_PROP_FRACTION64) + DEF_CONST(GF_PROP_FLOAT) + DEF_CONST(GF_PROP_DOUBLE) + DEF_CONST(GF_PROP_VEC2I) + DEF_CONST(GF_PROP_VEC2) + DEF_CONST(GF_PROP_VEC3I) + DEF_CONST(GF_PROP_VEC4I) + DEF_CONST(GF_PROP_STRING) + DEF_CONST(GF_PROP_STRING) + DEF_CONST(GF_PROP_STRING_NO_COPY) + DEF_CONST(GF_PROP_DATA) + DEF_CONST(GF_PROP_NAME) + DEF_CONST(GF_PROP_DATA_NO_COPY) + DEF_CONST(GF_PROP_CONST_DATA) + DEF_CONST(GF_PROP_POINTER) + DEF_CONST(GF_PROP_STRING_LIST) + DEF_CONST(GF_PROP_UINT_LIST) + DEF_CONST(GF_PROP_SINT_LIST) + DEF_CONST(GF_PROP_VEC2I_LIST) + DEF_CONST(GF_PROP_4CC) + DEF_CONST(GF_PROP_4CC_LIST) + + DEF_CONST(GF_PROP_PIXFMT) + DEF_CONST(GF_PROP_PCMFMT) + DEF_CONST(GF_PROP_CICP_COL_PRIM) + DEF_CONST(GF_PROP_CICP_COL_TFC) + DEF_CONST(GF_PROP_CICP_COL_MX) + DEF_CONST(GF_PROP_CICP_LAYOUT) + + DEF_CONST(GF_FEVT_PLAY) + DEF_CONST(GF_FEVT_SET_SPEED) + DEF_CONST(GF_FEVT_STOP) + DEF_CONST(GF_FEVT_PAUSE) + DEF_CONST(GF_FEVT_RESUME) + DEF_CONST(GF_FEVT_SOURCE_SEEK) + DEF_CONST(GF_FEVT_SOURCE_SWITCH) + DEF_CONST(GF_FEVT_SEGMENT_SIZE) + DEF_CONST(GF_FEVT_QUALITY_SWITCH) + DEF_CONST(GF_FEVT_VISIBILITY_HINT) + DEF_CONST(GF_FEVT_INFO_UPDATE) + DEF_CONST(GF_FEVT_BUFFER_REQ) + DEF_CONST(GF_FEVT_CAPS_CHANGE) + DEF_CONST(GF_FEVT_CONNECT_FAIL) + DEF_CONST(GF_FEVT_USER) + + DEF_CONST(GF_STATS_LOCAL) + DEF_CONST(GF_STATS_LOCAL_INPUTS) + DEF_CONST(GF_STATS_DECODER_SINK) + DEF_CONST(GF_STATS_DECODER_SOURCE) + DEF_CONST(GF_STATS_ENCODER_SINK) + DEF_CONST(GF_STATS_ENCODER_SOURCE) + DEF_CONST(GF_STATS_SINK) + + DEF_CONST(GF_FILTER_CLOCK_NONE) + DEF_CONST(GF_FILTER_CLOCK_PCR) + DEF_CONST(GF_FILTER_CLOCK_PCR_DISC) + + DEF_CONST(GF_FILTER_SAP_NONE) + DEF_CONST(GF_FILTER_SAP_1) + DEF_CONST(GF_FILTER_SAP_2) + DEF_CONST(GF_FILTER_SAP_3) + DEF_CONST(GF_FILTER_SAP_4) + DEF_CONST(GF_FILTER_SAP_4_PROL) + + DEF_CONST(GF_STATS_LOCAL) + DEF_CONST(GF_STATS_LOCAL_INPUTS) + DEF_CONST(GF_STATS_DECODER_SINK) + DEF_CONST(GF_STATS_DECODER_SOURCE) + DEF_CONST(GF_STATS_ENCODER_SINK) + DEF_CONST(GF_STATS_ENCODER_SOURCE) + DEF_CONST(GF_STATS_SINK) + + DEF_CONST(GF_EOS); + DEF_CONST(GF_OK) + DEF_CONST(GF_BAD_PARAM) + DEF_CONST(GF_OUT_OF_MEM) + DEF_CONST(GF_IO_ERR) + DEF_CONST(GF_NOT_SUPPORTED) + DEF_CONST(GF_CORRUPTED_DATA) + DEF_CONST(GF_SG_UNKNOWN_NODE) + DEF_CONST(GF_SG_INVALID_PROTO) + DEF_CONST(GF_SCRIPT_ERROR) + DEF_CONST(GF_BUFFER_TOO_SMALL) + DEF_CONST(GF_NON_COMPLIANT_BITSTREAM) + DEF_CONST(GF_FILTER_NOT_FOUND) + DEF_CONST(GF_URL_ERROR) + DEF_CONST(GF_SERVICE_ERROR) + DEF_CONST(GF_REMOTE_SERVICE_ERROR) + DEF_CONST(GF_STREAM_NOT_FOUND) + DEF_CONST(GF_ISOM_INVALID_FILE) + DEF_CONST(GF_ISOM_INCOMPLETE_FILE) + DEF_CONST(GF_ISOM_INVALID_MEDIA) + DEF_CONST(GF_ISOM_INVALID_MODE) + DEF_CONST(GF_ISOM_UNKNOWN_DATA_REF) + DEF_CONST(GF_ODF_INVALID_DESCRIPTOR) + DEF_CONST(GF_ODF_FORBIDDEN_DESCRIPTOR) + DEF_CONST(GF_ODF_INVALID_COMMAND) + DEF_CONST(GF_BIFS_UNKNOWN_VERSION) + DEF_CONST(GF_IP_ADDRESS_NOT_FOUND) + DEF_CONST(GF_IP_CONNECTION_FAILURE) + DEF_CONST(GF_IP_NETWORK_FAILURE) + DEF_CONST(GF_IP_CONNECTION_CLOSED) + DEF_CONST(GF_IP_NETWORK_EMPTY) + DEF_CONST(GF_IP_UDP_TIMEOUT) + DEF_CONST(GF_AUTHENTICATION_FAILURE) + DEF_CONST(GF_NOT_READY) + DEF_CONST(GF_INVALID_CONFIGURATION) + DEF_CONST(GF_NOT_FOUND) + DEF_CONST(GF_PROFILE_NOT_SUPPORTED) + DEF_CONST(GF_REQUIRES_NEW_INSTANCE) + DEF_CONST(GF_FILTER_NOT_SUPPORTED) + + DEF_CONST(JSF_SETUP_ERROR) + DEF_CONST(JSF_NOTIF_ERROR) + DEF_CONST(JSF_NOTIF_ERROR_AND_DISCONNECT) + + DEF_CONST(GF_FILTER_UPDATE_DOWNSTREAM) + DEF_CONST(GF_FILTER_UPDATE_UPSTREAM) + + DEF_CONST(GF_EVENT_CLICK) + DEF_CONST(GF_EVENT_MOUSEUP) + DEF_CONST(GF_EVENT_MOUSEDOWN) + DEF_CONST(GF_EVENT_MOUSEMOVE) + DEF_CONST(GF_EVENT_MOUSEWHEEL) + DEF_CONST(GF_EVENT_DBLCLICK) + DEF_CONST(GF_EVENT_MULTITOUCH) + DEF_CONST(GF_EVENT_KEYUP) + DEF_CONST(GF_EVENT_KEYDOWN) + DEF_CONST(GF_EVENT_TEXTINPUT) + DEF_CONST(GF_EVENT_DROPFILE) + DEF_CONST(GF_EVENT_TIMESHIFT_DEPTH) + DEF_CONST(GF_EVENT_TIMESHIFT_UPDATE) + DEF_CONST(GF_EVENT_TIMESHIFT_OVERFLOW) + DEF_CONST(GF_EVENT_TIMESHIFT_UNDERRUN) + DEF_CONST(GF_EVENT_PASTE_TEXT) + DEF_CONST(GF_EVENT_COPY_TEXT) + DEF_CONST(GF_EVENT_SIZE) + DEF_CONST(GF_EVENT_SHOWHIDE) + DEF_CONST(GF_EVENT_MOVE) + DEF_CONST(GF_EVENT_SET_CAPTION) + DEF_CONST(GF_EVENT_REFRESH) + DEF_CONST(GF_EVENT_QUIT) + DEF_CONST(GF_EVENT_CODEC_SLOW) + DEF_CONST(GF_EVENT_CODEC_OK) + js_load_key_names(ctx, global_obj); JS_SetPropertyStr(ctx, global_obj, "print", JS_NewCFunction(ctx, js_print, "print", 1)); JS_SetPropertyStr(ctx, global_obj, "alert", JS_NewCFunction(ctx, js_print, "alert", 1)); diff --git a/src/filters/load_text.c b/src/filters/load_text.c index 061189157e..b50945264a 100644 --- a/src/filters/load_text.c +++ b/src/filters/load_text.c @@ -766,13 +766,19 @@ static GF_Err parse_srt_line(GF_TXTIn *ctx, char *szLine, u32 *char_l, Bool *set u32 i, char_line, j, rem_styles, len; Bool rem_color; char *ptr = szLine; - unsigned short uniLine[5000], uniText[5000], *sptr; + unsigned short *uniLine, *uniText, *sptr; char szText[2048]; + len = (u32)strlen(szLine)+1; + uniLine = gf_malloc(sizeof(u16)*len); + uniText = gf_malloc(sizeof(u16)*len); + len = gf_utf8_mbstowcs(uniLine, 5000, (const char **) &ptr); if (len == GF_UTF8_FAIL) { GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[TXTIn] Invalid UTF data (line %d)\n", ctx->curLine)); ctx->state = 0; + if (uniLine) gf_free(uniLine); + if (uniText) gf_free(uniText); return GF_NON_COMPLIANT_BITSTREAM; } @@ -990,6 +996,9 @@ static GF_Err parse_srt_line(GF_TXTIn *ctx, char *szLine, u32 *char_l, Bool *set gf_isom_text_add_text(ctx->samp, szText, len); if (ctx->forced_sub) gf_isom_text_set_forced(ctx->samp, GF_TRUE); *char_l += char_line; + + if (uniLine) gf_free(uniLine); + if (uniText) gf_free(uniText); return GF_OK; } diff --git a/src/filters/mux_isom.c b/src/filters/mux_isom.c index 950f2f6e07..607f637236 100644 --- a/src/filters/mux_isom.c +++ b/src/filters/mux_isom.c @@ -3922,18 +3922,20 @@ static GF_Err mp4_mux_setup_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_tr } #ifndef GPAC_DISABLE_AV_PARSERS if (tkw->svcc) { - AVCState avc; - memset(&avc, 0, sizeof(AVCState)); - count = gf_list_count(tkw->svcc->sequenceParameterSets); - for (i=0; isvcc->sequenceParameterSets, i); - u8 nal_type = sl->data[0] & 0x1F; - Bool is_subseq = (nal_type == GF_AVC_NALU_SVC_SUBSEQ_PARAM) ? GF_TRUE : GF_FALSE; - s32 ps_idx = gf_avc_read_sps(sl->data, sl->size, &avc, is_subseq, NULL); - if (ps_idx>=0) { - GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("SVC Detected - SSPS ID %d - frame size %d x %d\n", ps_idx-GF_SVC_SSPS_ID_SHIFT, avc.sps[ps_idx].width, avc.sps[ps_idx].height )); - + AVCState *avc_state; + GF_SAFEALLOC(avc_state, AVCState); + if (avc_state) { + count = gf_list_count(tkw->svcc->sequenceParameterSets); + for (i=0; isvcc->sequenceParameterSets, i); + u8 nal_type = sl->data[0] & 0x1F; + Bool is_subseq = (nal_type == GF_AVC_NALU_SVC_SUBSEQ_PARAM) ? GF_TRUE : GF_FALSE; + s32 ps_idx = gf_avc_read_sps(sl->data, sl->size, avc_state, is_subseq, NULL); + if (ps_idx>=0) { + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("SVC Detected - SSPS ID %d - frame size %d x %d\n", ps_idx-GF_SVC_SSPS_ID_SHIFT, avc_state->sps[ps_idx].width, avc_state->sps[ps_idx].height )); + } } + gf_free(avc_state); } } #endif diff --git a/src/filters/reframe_av1.c b/src/filters/reframe_av1.c index 5cbe443534..1ec33b424c 100644 --- a/src/filters/reframe_av1.c +++ b/src/filters/reframe_av1.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Romain Bouqueau, Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2018-2023 + * Copyright (c) Telecom ParisTech 2018-2024 * All rights reserved * * This file is part of GPAC / AV1 IVF/OBU/annexB reframer filter @@ -322,7 +322,7 @@ static void av1dmx_check_dur(GF_Filter *filter, GF_AV1DmxCtx *ctx) GF_Err e; GF_BitStream *bs; u64 duration, cur_dur, last_cdur, file_size, max_pts, last_pts, probe_size=0; - AV1State av1state; + AV1State *av1state=NULL; const char *filepath=NULL; const GF_PropertyValue *p; if (!ctx->opid || ctx->timescale || ctx->file_loaded) return; @@ -364,6 +364,10 @@ static void av1dmx_check_dur(GF_Filter *filter, GF_AV1DmxCtx *ctx) } ctx->index_size = 0; + GF_SAFEALLOC(av1state, AV1State); + if (!av1state) { + return; + } bs = gf_bs_from_file(stream, GF_BITSTREAM_READ); #ifndef GPAC_DISABLE_LOG @@ -375,9 +379,9 @@ static void av1dmx_check_dur(GF_Filter *filter, GF_AV1DmxCtx *ctx) gf_bs_seek(bs, ctx->file_hdr_size); } file_size = gf_bs_available(bs); - gf_av1_init_state(&av1state); - av1state.skip_frames = GF_TRUE; - av1state.config = gf_odf_av1_cfg_new(); + gf_av1_init_state(av1state); + av1state->skip_frames = GF_TRUE; + av1state->config = gf_odf_av1_cfg_new(); max_pts = last_pts = 0; duration = 0; @@ -390,19 +394,19 @@ static void av1dmx_check_dur(GF_Filter *filter, GF_AV1DmxCtx *ctx) if (probe_size && (frame_start>probe_size)) break; - gf_av1_reset_state(&av1state, GF_FALSE); + gf_av1_reset_state(av1state, GF_FALSE); /*we process each TU and extract only the necessary OBUs*/ switch (ctx->bsmode) { case OBUs: - e = aom_av1_parse_temporal_unit_from_section5(bs, &av1state); + e = aom_av1_parse_temporal_unit_from_section5(bs, av1state); break; case AnnexB: - e = aom_av1_parse_temporal_unit_from_annexb(bs, &av1state); + e = aom_av1_parse_temporal_unit_from_annexb(bs, av1state); break; case IVF: if (ctx->is_av1) { - e = aom_av1_parse_temporal_unit_from_ivf(bs, &av1state); + e = aom_av1_parse_temporal_unit_from_ivf(bs, av1state); } else { u64 frame_size; e = gf_media_parse_ivf_frame_header(bs, &frame_size, &pts); @@ -430,7 +434,7 @@ static void av1dmx_check_dur(GF_Filter *filter, GF_AV1DmxCtx *ctx) duration += ctx->cur_fps.den; cur_dur += ctx->cur_fps.den; } - if (av1state.frame_state.key_frame) + if (av1state->frame_state.key_frame) is_sap = GF_TRUE; //only index at I-frame start @@ -450,8 +454,9 @@ static void av1dmx_check_dur(GF_Filter *filter, GF_AV1DmxCtx *ctx) probe_size = gf_bs_get_position(bs); gf_bs_del(bs); gf_fclose(stream); - gf_odf_av1_cfg_del(av1state.config); - gf_av1_reset_state(&av1state, GF_TRUE); + if (av1state->config) gf_odf_av1_cfg_del(av1state->config); + gf_av1_reset_state(av1state, GF_TRUE); + gf_free(av1state); if (!ctx->duration.num || (ctx->duration.num * ctx->cur_fps.num != duration * ctx->duration.den)) { if (probe_size) { @@ -1283,18 +1288,20 @@ static const char * av1dmx_probe_data(const u8 *data, u32 size, GF_FilterProbeSc if (res) { *score = GF_FPROBE_SUPPORTED; } else { - AV1State state; + AV1State *av1_state; Bool has_seq_header = GF_FALSE; GF_Err e; u32 nb_units = 0; + GF_SAFEALLOC(av1_state, AV1State); + if (!av1_state) return NULL; - gf_av1_init_state(&state); - state.config = gf_odf_av1_cfg_new(); + gf_av1_init_state(av1_state); + av1_state->config = gf_odf_av1_cfg_new(); while (gf_bs_available(bs)) { - e = aom_av1_parse_temporal_unit_from_section5(bs, &state); + e = aom_av1_parse_temporal_unit_from_section5(bs, av1_state); if ((e==GF_OK) || (nb_units && (e==GF_BUFFER_TOO_SMALL) ) ) { - if (!nb_units || gf_list_count(state.frame_state.header_obus) || gf_list_count(state.frame_state.frame_obus)) { - if (gf_list_count(state.frame_state.header_obus)) { + if (!nb_units || gf_list_count(av1_state->frame_state.header_obus) || gf_list_count(av1_state->frame_state.frame_obus)) { + if (gf_list_count(av1_state->frame_state.header_obus)) { has_seq_header = GF_TRUE; } nb_units++; @@ -1311,7 +1318,7 @@ static const char * av1dmx_probe_data(const u8 *data, u32 size, GF_FilterProbeSc } //very large frame else if (!nb_units && (e==GF_BUFFER_TOO_SMALL)) { - if (gf_list_count(state.frame_state.header_obus) && state.width && state.height) { + if (gf_list_count(av1_state->frame_state.header_obus) && av1_state->width && av1_state->height) { res = GF_TRUE; *score = GF_FPROBE_MAYBE_SUPPORTED; } @@ -1319,15 +1326,16 @@ static const char * av1dmx_probe_data(const u8 *data, u32 size, GF_FilterProbeSc } else { break; } - gf_av1_reset_state(&state, GF_FALSE); + gf_av1_reset_state(av1_state, GF_FALSE); if (nb_units>2) { res = GF_TRUE; *score = GF_FPROBE_SUPPORTED; break; } } - gf_odf_av1_cfg_del(state.config); - gf_av1_reset_state(&state, GF_TRUE); + gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); } } diff --git a/src/filters/reframe_nalu.c b/src/filters/reframe_nalu.c index cd8a9449b1..fc935bffd6 100644 --- a/src/filters/reframe_nalu.c +++ b/src/filters/reframe_nalu.c @@ -860,12 +860,14 @@ static void naludmx_add_param_nalu(GF_List *param_list, GF_NALUFFParam *sl, u8 n static void naludmx_hevc_set_parall_type(GF_NALUDmxCtx *ctx, GF_HEVCConfig *hevc_cfg) { u32 use_tiles, use_wpp, nb_pps, i, count; - HEVCState hevc; + HEVCState *hvc_state; count = gf_list_count(ctx->pps); - memset(&hevc, 0, sizeof(HEVCState)); - hevc.sps_active_idx = -1; + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return; + + hvc_state->sps_active_idx = -1; use_tiles = 0; use_wpp = 0; @@ -873,12 +875,12 @@ static void naludmx_hevc_set_parall_type(GF_NALUDmxCtx *ctx, GF_HEVCConfig *hevc for (i=0; ipps, i); - s32 idx = gf_hevc_read_pps(slc->data, slc->size, &hevc); + s32 idx = gf_hevc_read_pps(slc->data, slc->size, hvc_state); if (idx>=0) { HEVC_PPS *pps; nb_pps++; - pps = &hevc.pps[idx]; + pps = &hvc_state->pps[idx]; if (!pps->entropy_coding_sync_enabled_flag && pps->tiles_enabled_flag) use_tiles++; else if (pps->entropy_coding_sync_enabled_flag && !pps->tiles_enabled_flag) @@ -889,6 +891,7 @@ static void naludmx_hevc_set_parall_type(GF_NALUDmxCtx *ctx, GF_HEVCConfig *hevc else if (!use_wpp && (use_tiles==nb_pps) ) hevc_cfg->parallelismType = 2; else if (!use_tiles && (use_wpp==nb_pps) ) hevc_cfg->parallelismType = 3; else hevc_cfg->parallelismType = 0; + gf_free(hvc_state); } GF_Err naludmx_set_hevc_oinf(GF_NALUDmxCtx *ctx, u8 *max_temporal_id) diff --git a/src/ietf/rtp_depacketizer.c b/src/ietf/rtp_depacketizer.c index 3420c03c3f..e720fdc1de 100644 --- a/src/ietf/rtp_depacketizer.c +++ b/src/ietf/rtp_depacketizer.c @@ -1040,7 +1040,7 @@ static void gf_rtp_parse_latm(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, u8 *pa #endif #if GPAC_ENABLE_3GPP_DIMS_RTP -static void gf_rtp_parse_3gpp_dims(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) +static void gf_rtp_parse_3gpp_dims(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, u8 *payload, u32 size) { u32 du_size, offset, dsize, hdr_size; char *data, dhdr[6]; @@ -1090,7 +1090,7 @@ static void gf_rtp_parse_3gpp_dims(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, c case 3: if (!rtp->inter_bs) return; gf_bs_write_data(rtp->inter_bs, payload+offset, size-offset); - gf_bs_get_content(rtp->inter_bs, &data, &dsize); + gf_bs_get_content(rtp->inter_bs, (u8**)&data, &dsize); gf_bs_del(rtp->inter_bs); /*send unit header - if dims size is >0xFFFF, use our internal hack for large units*/ diff --git a/src/ietf/rtp_packetizer.c b/src/ietf/rtp_packetizer.c index 051667da8e..e3f1af1f8e 100644 --- a/src/ietf/rtp_packetizer.c +++ b/src/ietf/rtp_packetizer.c @@ -579,32 +579,35 @@ Bool gf_rtp_builder_get_payload_name(GP_RTPPacketizer *rtpb, char szPayloadName[ GF_EXPORT -GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, char *dsi, u32 dsi_size) +GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, char **out_sdp_line, char *dsi, u32 dsi_size) { - char buffer[20100], dsiString[20000]; - u32 i, k; + char buffer[100]; + u32 i; Bool is_first = GF_TRUE; - char *sdp = NULL; GF_Err e = GF_OK; + if (!out_sdp_line) return GF_BAD_PARAM; + if (*out_sdp_line) + (*out_sdp_line)[0] = 0; if ((builder->rtp_payt!=GF_RTP_PAYT_MPEG4) && (builder->rtp_payt!=GF_RTP_PAYT_LATM) ) return GF_BAD_PARAM; #define SDP_ADD_INT(_name, _val) {\ - if (!is_first) gf_dynstrcat(&sdp, "; ", NULL); \ - sprintf(buffer, "%s=%d", _name, _val);\ - gf_dynstrcat(&sdp, buffer, NULL);\ + if (!is_first) gf_dynstrcat(out_sdp_line, "; ", NULL); \ + gf_dynstrcat(out_sdp_line, _name, NULL);\ + sprintf(buffer, "%d", _val);\ + gf_dynstrcat(out_sdp_line, buffer, "=");\ is_first = 0;\ } #define SDP_ADD_STR(_name, _val) {\ - if (!is_first) gf_dynstrcat(&sdp, "; ", NULL);\ - sprintf(buffer, "%s=%s", _name, _val);\ - gf_dynstrcat(&sdp, buffer, NULL);\ + if (!is_first) gf_dynstrcat(out_sdp_line, "; ", NULL);\ + gf_dynstrcat(out_sdp_line, _name, NULL);\ + gf_dynstrcat(out_sdp_line, _val, "=");\ is_first = 0;\ } sprintf(buffer, "a=fmtp:%d ", builder->PayloadType); - gf_dynstrcat(&sdp, buffer, NULL); + gf_dynstrcat(out_sdp_line, buffer, NULL); /*mandatory fields*/ if (builder->slMap.PL_ID) SDP_ADD_INT("profile-level-id", builder->slMap.PL_ID); @@ -612,17 +615,18 @@ GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, if (builder->rtp_payt == GF_RTP_PAYT_LATM) SDP_ADD_INT("cpresent", 0); if (dsi && dsi_size) { - k = 0; if (dsi_size>10000) { e = GF_OUT_OF_MEM; goto exit; } + if (!is_first) gf_dynstrcat(out_sdp_line, "; ", NULL); + gf_dynstrcat(out_sdp_line, "config=", NULL); + buffer[2]=0; for (i=0; irtp_payt == GF_RTP_PAYT_LATM) ) { e = GF_OK; @@ -663,17 +667,7 @@ GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, } exit: - sdpLine[0] = 0; - if (sdp) { - k = (u32) strlen(sdp); - if (k<20000) - strcpy(sdpLine, sdp); - else - e = GF_OUT_OF_MEM; - gf_free(sdp); - } else { - e = GF_OUT_OF_MEM; - } + if (!out_sdp_line) return GF_OUT_OF_MEM; return e; } diff --git a/src/ietf/rtp_pck_3gpp.c b/src/ietf/rtp_pck_3gpp.c index 15ed2b6fef..562b93356c 100644 --- a/src/ietf/rtp_pck_3gpp.c +++ b/src/ietf/rtp_pck_3gpp.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / IETF RTP/RTSP/SDP sub-project @@ -585,7 +585,7 @@ GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, u8 *data, u32 data_size #if GPAC_ENABLE_3GPP_DIMS_RTP -GF_Err gp_rtp_builder_do_dims(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration) +GF_Err gp_rtp_builder_do_dims(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration) { u32 frag_state; GF_BitStream *bs; diff --git a/src/ietf/rtp_streamer.c b/src/ietf/rtp_streamer.c index 80c91ee9c4..6a26db0a9e 100644 --- a/src/ietf/rtp_streamer.c +++ b/src/ietf/rtp_streamer.c @@ -575,20 +575,26 @@ void gf_rtp_streamer_del(GF_RTPStreamer *streamer) #if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING) -void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, u32 w, u32 h, s32 tx, s32 ty, s16 l, u32 max_w, u32 max_h, char *tx3g_base64) +void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char **out_sdp_line, u32 w, u32 h, s32 tx, s32 ty, s16 l, u32 max_w, u32 max_h, char *tx3g_base64) { - char buffer[2000]; - sprintf(sdpLine, "a=fmtp:%d sver=60; ", builder->PayloadType); + char tmp_buf[101]; + if (!out_sdp_line) return; + if (*out_sdp_line) + (*out_sdp_line)[0] = 0; - sprintf(buffer, "width=%d; height=%d; tx=%d; ty=%d; layer=%d; ", w, h, tx, ty, l); - strcat(sdpLine, buffer); + tmp_buf[100] = 0; + snprintf(tmp_buf, 100, "a=fmtp:%d sver=60; ", builder->PayloadType); + gf_dynstrcat(out_sdp_line, tmp_buf, NULL); - sprintf(buffer, "max-w=%d; max-h=%d", max_w, max_h); - strcat(sdpLine, buffer); + snprintf(tmp_buf, 100, "width=%d; height=%d; tx=%d; ty=%d; layer=%d; ", w, h, tx, ty, l); + gf_dynstrcat(out_sdp_line, tmp_buf, NULL); + + snprintf(tmp_buf, 100, "max-w=%d; max-h=%d", max_w, max_h); + gf_dynstrcat(out_sdp_line, tmp_buf, NULL); if (tx3g_base64) { - strcat(sdpLine, "; tx3g="); - strcat(sdpLine, tx3g_base64); + gf_dynstrcat(out_sdp_line, "; tx3g=", NULL); + gf_dynstrcat(out_sdp_line, tx3g_base64, NULL); } } @@ -598,11 +604,11 @@ void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, cha GF_EXPORT GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, const u8 *dsi, u32 dsi_len, const u8 *dsi_enh, u32 dsi_enh_len, char *KMS_URI, u32 width, u32 height, u32 tw, u32 th, s32 tx, s32 ty, s16 tl, u32 nb_channels, Bool for_rtsp, char **out_sdp_buffer) { - u32 size; u16 port=0; char mediaName[30], payloadName[30]; - char sdp[20000], sdpLine[10000]; + char tmp_buf[101]; + tmp_buf[100]=0; if (!out_sdp_buffer) return GF_BAD_PARAM; gf_rtp_builder_get_payload_name(rtp->packetizer, payloadName, mediaName); @@ -612,12 +618,13 @@ GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, const gf_rtp_get_ports(rtp->channel, &port, NULL); } - sprintf(sdp, "m=%s %d RTP/%s %u\n", mediaName, for_rtsp ? 0 : port, rtp->packetizer->slMap.IV_length ? "SAVP" : "AVP", rtp->packetizer->PayloadType); + snprintf(tmp_buf, 100, "m=%s %d RTP/%s %u\n", mediaName, for_rtsp ? 0 : port, rtp->packetizer->slMap.IV_length ? "SAVP" : "AVP", rtp->packetizer->PayloadType); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); if (nb_channels > 1) - sprintf(sdpLine, "a=rtpmap:%u %s/%u/%u\n", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution, nb_channels); + snprintf(tmp_buf, 100, "a=rtpmap:%u %s/%u/%u\n", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution, nb_channels); else - sprintf(sdpLine, "a=rtpmap:%u %s/%u\n", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution); - strcat(sdp, sdpLine); + snprintf(tmp_buf, 100, "a=rtpmap:%u %s/%u\n", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); if (ESID #if GPAC_ENABLE_3GPP_DIMS_RTP @@ -625,67 +632,73 @@ GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, const #endif && (rtp->packetizer->rtp_payt != GF_RTP_PAYT_OPUS) ) { - sprintf(sdpLine, "a=mpeg4-esid:%d\n", ESID); - strcat(sdp, sdpLine); + snprintf(tmp_buf, 100, "a=mpeg4-esid:%d\n", ESID); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); } if (width && height) { if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H263) { - sprintf(sdpLine, "a=cliprect:0,0,%d,%d\n", height, width); - strcat(sdp, sdpLine); + snprintf(tmp_buf, 100, "a=cliprect:0,0,%d,%d\n", height, width); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); } /*extensions for some mobile phones*/ - sprintf(sdpLine, "a=framesize:%d %d-%d\n", rtp->packetizer->PayloadType, width, height); - strcat(sdp, sdpLine); + snprintf(tmp_buf, 100, "a=framesize:%d %d-%d\n", rtp->packetizer->PayloadType, width, height); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); } - strcpy(sdpLine, ""); - /*AMR*/ if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_AMR) || (rtp->packetizer->rtp_payt == GF_RTP_PAYT_AMR_WB)) { - sprintf(sdpLine, "a=fmtp:%d octet-align=1\n", rtp->packetizer->PayloadType); + snprintf(tmp_buf, 100, "a=fmtp:%d octet-align=1\n", rtp->packetizer->PayloadType); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); } #if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING) /*Text*/ else if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_3GPP_TEXT) { - gf_media_format_ttxt_sdp(rtp->packetizer, payloadName, sdpLine, tw, th, tx, ty, tl, width, height, (u8 *)dsi_enh); - strcat(sdpLine, "\n"); + char *sdp = NULL; + gf_media_format_ttxt_sdp(rtp->packetizer, payloadName, &sdp, tw, th, tx, ty, tl, width, height, (u8 *)dsi_enh); + gf_dynstrcat(out_sdp_buffer, sdp, NULL); + gf_dynstrcat(out_sdp_buffer, "\n", NULL); + if (sdp) gf_free(sdp); } #endif /*EVRC/SMV in non header-free mode*/ else if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_EVRC_SMV) && (rtp->packetizer->auh_size>1)) { - sprintf(sdpLine, "a=fmtp:%d maxptime=%d\n", rtp->packetizer->PayloadType, rtp->packetizer->auh_size*20); + snprintf(tmp_buf, 100, "a=fmtp:%d maxptime=%d\n", rtp->packetizer->PayloadType, rtp->packetizer->auh_size*20); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); } /*H264/AVC*/ else if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_H264_AVC) || (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H264_SVC)) { GF_AVCConfig *avcc = dsi ? gf_odf_avc_cfg_read((u8*)dsi, dsi_len) : NULL; if (avcc) { - sprintf(sdpLine, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", rtp->packetizer->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication); + snprintf(tmp_buf, 100, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", rtp->packetizer->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); + if (gf_list_count(avcc->pictureParameterSets) || gf_list_count(avcc->sequenceParameterSets)) { u32 i, count, b64s; char b64[200]; - strcat(sdpLine, "; sprop-parameter-sets="); + gf_dynstrcat(out_sdp_buffer, "; sprop-parameter-sets=", NULL); + count = gf_list_count(avcc->sequenceParameterSets); for (i=0; isequenceParameterSets, i); b64s = gf_base64_encode(sl->data, sl->size, b64, 200); b64[b64s]=0; - strcat(sdpLine, b64); - if (i+1pictureParameterSets); for (i=0; ipictureParameterSets, i); b64s = gf_base64_encode(sl->data, sl->size, b64, 200); b64[b64s]=0; - strcat(sdpLine, b64); - if (i+1packetizer->rtp_payt == GF_RTP_PAYT_HEVC) @@ -717,53 +730,59 @@ GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, const if (param_array) { u32 count, i, j, b64s; char b64[200]; - sprintf(sdpLine, "a=fmtp:%d", rtp->packetizer->PayloadType); + snprintf(tmp_buf, 100, "a=fmtp:%d", rtp->packetizer->PayloadType); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); + count = gf_list_count(param_array); for (i = 0; i < count; i++) { GF_NALUFFParamArray *ar = (GF_NALUFFParamArray *)gf_list_get(param_array, i); if (ar->type==sps_nut) { - strcat(sdpLine, "; sprop-sps="); + gf_dynstrcat(out_sdp_buffer, "; sprop-sps=", NULL); } else if (ar->type==pps_nut) { - strcat(sdpLine, "; sprop-pps="); + gf_dynstrcat(out_sdp_buffer, "; sprop-pps=", NULL); } else if (ar->type==vps_nut) { - strcat(sdpLine, "; sprop-vps="); + gf_dynstrcat(out_sdp_buffer, "; sprop-vps=", NULL); } for (j = 0; j < gf_list_count(ar->nalus); j++) { GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(ar->nalus, j); b64s = gf_base64_encode(sl->data, sl->size, b64, 200); b64[b64s]=0; - if (j) strcat(sdpLine, ", "); - strcat(sdpLine, b64); + if (j) gf_dynstrcat(out_sdp_buffer, ", ", NULL); + gf_dynstrcat(out_sdp_buffer, b64, NULL); } } if (vvcc) gf_odf_vvc_cfg_del(vvcc); if (hvcc) gf_odf_hevc_cfg_del(hvcc); - strcat(sdpLine, "\n"); + gf_dynstrcat(out_sdp_buffer, "\n", NULL); } } /*MPEG-4 decoder config*/ else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_MPEG4) { - gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, (u8*)dsi, dsi_len); - strcat(sdpLine, "\n"); + char *sdp = NULL; + gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, &sdp, (u8*)dsi, dsi_len); + gf_dynstrcat(out_sdp_buffer, sdp, NULL); + gf_dynstrcat(out_sdp_buffer, "\n", NULL); + if (sdp) gf_free(sdp); if (rtp->packetizer->slMap.IV_length && KMS_URI) { if (!strnicmp(KMS_URI, "(key)", 5) || !strnicmp(KMS_URI, "(ipmp)", 6) || !strnicmp(KMS_URI, "(uri)", 5)) { - strcat(sdpLine, "; ISMACrypKey="); + gf_dynstrcat(out_sdp_buffer, "; ISMACrypKey=", NULL); } else { - strcat(sdpLine, "; ISMACrypKey=(uri)"); + gf_dynstrcat(out_sdp_buffer, "; ISMACrypKey=(uri)", NULL); } - strcat(sdpLine, KMS_URI); - strcat(sdpLine, "\n"); + gf_dynstrcat(out_sdp_buffer, KMS_URI, NULL); + gf_dynstrcat(out_sdp_buffer, "\n", NULL); } } #if GPAC_ENABLE_3GPP_DIMS_RTP /*DIMS decoder config*/ else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_3GPP_DIMS) { - sprintf(sdpLine, "a=fmtp:%d Version-profile=%d", rtp->packetizer->PayloadType, 10); + snprintf(tmp_buf, 100, "a=fmtp:%d Version-profile=%d", rtp->packetizer->PayloadType, 10); + gf_dynstrcat(out_sdp_buffer, tmp_buf, NULL); if (rtp->packetizer->flags & GP_RTP_DIMS_COMPRESSED) { - strcat(sdpLine, ";content-coding=deflate"); + gf_dynstrcat(out_sdp_buffer, ";content-coding=deflate", NULL); } - strcat(sdpLine, "\n"); + gf_dynstrcat(out_sdp_buffer, "\n", NULL); } #endif /*MPEG-4 Audio LATM*/ @@ -791,22 +810,12 @@ GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, const gf_bs_get_content(bs, &config_bytes, &config_size); gf_bs_del(bs); - gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, config_bytes, config_size); + char *sdp = NULL; + gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, &sdp, config_bytes, config_size); gf_free(config_bytes); - strcat(sdpLine, "\n"); - } - - strcat(sdp, sdpLine); - - size = (u32) strlen(sdp) + (*out_sdp_buffer ? (u32) strlen(*out_sdp_buffer) : 0) + 1; - if ( !*out_sdp_buffer) { - *out_sdp_buffer = (char*)gf_malloc(sizeof(char)*size); - if (! *out_sdp_buffer) return GF_OUT_OF_MEM; - strcpy(*out_sdp_buffer, sdp); - } else { - *out_sdp_buffer = (char*)gf_realloc(*out_sdp_buffer, sizeof(char)*size); - if (! *out_sdp_buffer) return GF_OUT_OF_MEM; - strcat(*out_sdp_buffer, sdp); + gf_dynstrcat(out_sdp_buffer, sdp, NULL); + gf_dynstrcat(out_sdp_buffer, "\n", NULL); + if (sdp) gf_free(sdp); } return GF_OK; } diff --git a/src/isomedia/avc_ext.c b/src/isomedia/avc_ext.c index ef44dae863..5a6165e392 100644 --- a/src/isomedia/avc_ext.c +++ b/src/isomedia/avc_ext.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / ISO Media File Format sub-project @@ -2835,16 +2835,19 @@ GF_Err avcc_box_read(GF_Box *s, GF_BitStream *bs) #ifndef GPAC_DISABLE_AV_PARSERS GF_NALUFFParam *sl = (GF_NALUFFParam*)gf_list_get(ptr->config->sequenceParameterSets, 0); if (sl) { - AVCState avc; + AVCState *avc_state; s32 idx; - memset(&avc, 0, sizeof(AVCState)); - idx = gf_avc_read_sps(sl->data, sl->size, &avc, 0, NULL); - if (idx>=0) { - ptr->config->chroma_format = avc.sps[idx].chroma_format; - ptr->config->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8; - ptr->config->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8; + GF_SAFEALLOC(avc_state, AVCState); + if (avc_state) { + idx = gf_avc_read_sps(sl->data, sl->size, avc_state, 0, NULL); + if (idx>=0) { + ptr->config->chroma_format = avc_state->sps[idx].chroma_format; + ptr->config->luma_bit_depth = 8 + avc_state->sps[idx].luma_bit_depth_m8; + ptr->config->chroma_bit_depth = 8 + avc_state->sps[idx].chroma_bit_depth_m8; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[isom/avcc] Missing REXT profile signaling, patching using SPS.\n")); + gf_free(avc_state); } - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[isom/avcc] Missing REXT profile signaling, patching using SPS.\n")); } else #endif { diff --git a/src/isomedia/box_dump.c b/src/isomedia/box_dump.c index d0e8ae3f67..c473db0d2d 100644 --- a/src/isomedia/box_dump.c +++ b/src/isomedia/box_dump.c @@ -3714,7 +3714,8 @@ void dump_ttxt_sample(FILE *dump, GF_TextSample *s_txt, u64 ts, u32 timescale, u gf_fprintf(dump, " xml:space=\"preserve\">"); if (s_txt->len) { - unsigned short utf16Line[10000]; + unsigned short *utf16Line = gf_malloc( sizeof(u16) * s_txt->len); + if (!utf16Line) return; /*UTF16*/ if ((s_txt->len>2) && ((unsigned char) s_txt->text[0] == (unsigned char) 0xFE) && ((unsigned char) s_txt->text[1] == (unsigned char) 0xFF)) { /*copy 2 more chars because the lib always add 2 '0' at the end for UTF16 end of string*/ @@ -3764,6 +3765,7 @@ void dump_ttxt_sample(FILE *dump, GF_TextSample *s_txt, u64 ts, u32 timescale, u } } } + if (utf16Line) gf_free(utf16Line); } if (box_dump) { @@ -3976,112 +3978,114 @@ GF_Err dump_ttxt_sample_srt(FILE *dump, GF_TextSample *txt, GF_Tx3gSampleEntryBo u32 len, j, k; if (!txt || !txt->len) { gf_fprintf(dump, "\n"); - } else { - u32 styles, char_num, new_styles, color, new_color; - u16 utf16Line[10000]; + return GF_OK; + } - /*UTF16*/ - if ((txt->len>2) && ((unsigned char) txt->text[0] == (unsigned char) 0xFE) && ((unsigned char) txt->text[1] == (unsigned char) 0xFF)) { - memcpy(utf16Line, txt->text+2, sizeof(char)*txt->len); - ( ((char *)utf16Line)[txt->len] ) = 0; - len = txt->len; - } else { - u8 *str = (u8 *) (txt->text); - len = gf_utf8_mbstowcs(utf16Line, 10000, (const char **) &str); - if (len == GF_UTF8_FAIL) return GF_NON_COMPLIANT_BITSTREAM; - utf16Line[len] = 0; - } - char_num = 0; - styles = 0; - new_styles = txtd->default_style.style_flags; - color = new_color = txtd->default_style.text_color; + u32 styles, char_num, new_styles, color, new_color; + u16 *utf16_buf = gf_malloc(sizeof(u16)*txt->len); + if (!utf16_buf) return GF_OUT_OF_MEM; - for (j=0; jlen>2) && ((unsigned char) txt->text[0] == (unsigned char) 0xFE) && ((unsigned char) txt->text[1] == (unsigned char) 0xFF) + ) { + memcpy(utf16_buf, txt->text+2, txt->len); + ( ((char *)utf16_buf)[txt->len] ) = 0; + len = txt->len; + } else { + u8 *str = (u8 *) (txt->text); + len = gf_utf8_mbstowcs(utf16_buf, txt->len, (const char **) &str); + if (len == GF_UTF8_FAIL) return GF_NON_COMPLIANT_BITSTREAM; + utf16_buf[len] = 0; + } + char_num = 0; + styles = 0; + new_styles = txtd->default_style.style_flags; + color = new_color = txtd->default_style.text_color; + + for (j=0; jstyles) { + new_styles = txtd->default_style.style_flags; + new_color = txtd->default_style.text_color; + for (k=0; kstyles->entry_count; k++) { + if (txt->styles->styles[k].startCharOffset>char_num) continue; + if (txt->styles->styles[k].endCharOffsetstyles->styles[k].style_flags & (GF_TXT_STYLE_ITALIC | GF_TXT_STYLE_BOLD | GF_TXT_STYLE_UNDERLINED | GF_TXT_STYLE_STRIKETHROUGH)) + new_styles = txt->styles->styles[k].style_flags; + if (txt->styles->styles[k].text_color) + new_color = txt->styles->styles[k].text_color; - if (txt->styles) { - new_styles = txtd->default_style.style_flags; - new_color = txtd->default_style.text_color; - for (k=0; kstyles->entry_count; k++) { - if (txt->styles->styles[k].startCharOffset>char_num) continue; - if (txt->styles->styles[k].endCharOffset"); + if ((new_styles & GF_TXT_STYLE_ITALIC) && !(styles & GF_TXT_STYLE_ITALIC)) gf_fprintf(dump, ""); + if ((new_styles & GF_TXT_STYLE_UNDERLINED) && !(styles & GF_TXT_STYLE_UNDERLINED)) gf_fprintf(dump, ""); + if ((new_styles & GF_TXT_STYLE_STRIKETHROUGH) && !(styles & GF_TXT_STYLE_STRIKETHROUGH)) gf_fprintf(dump, ""); - if (txt->styles->styles[k].style_flags & (GF_TXT_STYLE_ITALIC | GF_TXT_STYLE_BOLD | GF_TXT_STYLE_UNDERLINED | GF_TXT_STYLE_STRIKETHROUGH)) - new_styles = txt->styles->styles[k].style_flags; - if (txt->styles->styles[k].text_color) - new_color = txt->styles->styles[k].text_color; + if ((styles & GF_TXT_STYLE_STRIKETHROUGH) && !(new_styles & GF_TXT_STYLE_STRIKETHROUGH)) gf_fprintf(dump, ""); + if ((styles & GF_TXT_STYLE_UNDERLINED) && !(new_styles & GF_TXT_STYLE_UNDERLINED)) gf_fprintf(dump, ""); + if ((styles & GF_TXT_STYLE_ITALIC) && !(new_styles & GF_TXT_STYLE_ITALIC)) gf_fprintf(dump, ""); + if ((styles & GF_TXT_STYLE_BOLD) && !(new_styles & GF_TXT_STYLE_BOLD)) gf_fprintf(dump, ""); - break; - } - } - if (new_styles != styles) { - if ((new_styles & GF_TXT_STYLE_BOLD) && !(styles & GF_TXT_STYLE_BOLD)) gf_fprintf(dump, ""); - if ((new_styles & GF_TXT_STYLE_ITALIC) && !(styles & GF_TXT_STYLE_ITALIC)) gf_fprintf(dump, ""); - if ((new_styles & GF_TXT_STYLE_UNDERLINED) && !(styles & GF_TXT_STYLE_UNDERLINED)) gf_fprintf(dump, ""); - if ((new_styles & GF_TXT_STYLE_STRIKETHROUGH) && !(styles & GF_TXT_STYLE_STRIKETHROUGH)) gf_fprintf(dump, ""); - - if ((styles & GF_TXT_STYLE_STRIKETHROUGH) && !(new_styles & GF_TXT_STYLE_STRIKETHROUGH)) gf_fprintf(dump, ""); - if ((styles & GF_TXT_STYLE_UNDERLINED) && !(new_styles & GF_TXT_STYLE_UNDERLINED)) gf_fprintf(dump, ""); - if ((styles & GF_TXT_STYLE_ITALIC) && !(new_styles & GF_TXT_STYLE_ITALIC)) gf_fprintf(dump, ""); - if ((styles & GF_TXT_STYLE_BOLD) && !(new_styles & GF_TXT_STYLE_BOLD)) gf_fprintf(dump, ""); - - styles = new_styles; - } - if (!vtt_dump && (new_color != color)) { - if (new_color ==txtd->default_style.text_color) { - gf_fprintf(dump, ""); + styles = new_styles; + } + if (!vtt_dump && (new_color != color)) { + if (new_color ==txtd->default_style.text_color) { + gf_fprintf(dump, ""); + } else { + const char *cname = gf_color_get_name(new_color); + if (cname) { + gf_fprintf(dump, "", cname); } else { - const char *cname = gf_color_get_name(new_color); - if (cname) { - gf_fprintf(dump, "", cname); - } else { - if (new_color >> 24 < 0xFF) - gf_fprintf(dump, "", new_color); - else - gf_fprintf(dump, "", new_color&0x00FFFFFF); - } + if (new_color >> 24 < 0xFF) + gf_fprintf(dump, "", new_color); + else + gf_fprintf(dump, "", new_color&0x00FFFFFF); } - color = new_color; } - - /*not sure if styles must be reseted at line breaks in srt...*/ - is_new_line = GF_FALSE; - if ((utf16Line[j]=='\n') || (utf16Line[j]=='\r') ) { - if ((utf16Line[j]=='\r') && (utf16Line[j+1]=='\n')) j++; - gf_fprintf(dump, "\n"); - is_new_line = GF_TRUE; - } - - if (!is_new_line) { - u32 sl; - char szChar[30]; - s16 swT[2], *swz; - swT[0] = utf16Line[j]; - swT[1] = 0; - swz= (s16 *)swT; - sl = gf_utf8_wcstombs(szChar, 30, (const unsigned short **) &swz); - if (sl == GF_UTF8_FAIL) sl=0; - szChar[sl]=0; - gf_fprintf(dump, "%s", szChar); - } - char_num++; + color = new_color; } - new_styles = 0; - if (new_styles != styles) { - if (styles & GF_TXT_STYLE_STRIKETHROUGH) gf_fprintf(dump, ""); - if (styles & GF_TXT_STYLE_UNDERLINED) gf_fprintf(dump, ""); - if (styles & GF_TXT_STYLE_ITALIC) gf_fprintf(dump, ""); - if (styles & GF_TXT_STYLE_BOLD) gf_fprintf(dump, ""); -// styles = 0; + /*not sure if styles must be reseted at line breaks in srt...*/ + is_new_line = GF_FALSE; + if ((utf16_buf[j]=='\n') || (utf16_buf[j]=='\r') ) { + if ((utf16_buf[j]=='\r') && (utf16_buf[j+1]=='\n')) j++; + gf_fprintf(dump, "\n"); + is_new_line = GF_TRUE; } - if (color != txtd->default_style.text_color) { - gf_fprintf(dump, ""); -// color = txtd->default_style.text_color; + if (!is_new_line) { + u32 sl; + char szChar[30]; + s16 swT[2], *swz; + swT[0] = utf16_buf[j]; + swT[1] = 0; + swz= (s16 *)swT; + sl = gf_utf8_wcstombs(szChar, 30, (const unsigned short **) &swz); + if (sl == GF_UTF8_FAIL) sl=0; + szChar[sl]=0; + gf_fprintf(dump, "%s", szChar); } - gf_fprintf(dump, "\n"); + char_num++; } + new_styles = 0; + if (new_styles != styles) { + if (styles & GF_TXT_STYLE_STRIKETHROUGH) gf_fprintf(dump, ""); + if (styles & GF_TXT_STYLE_UNDERLINED) gf_fprintf(dump, ""); + if (styles & GF_TXT_STYLE_ITALIC) gf_fprintf(dump, ""); + if (styles & GF_TXT_STYLE_BOLD) gf_fprintf(dump, ""); + } + + if (color != txtd->default_style.text_color) { + gf_fprintf(dump, ""); + } + gf_fprintf(dump, "\n"); + gf_free(utf16_buf); + return GF_OK; } #else diff --git a/src/media_tools/av_parsers.c b/src/media_tools/av_parsers.c index ab7711b99c..edaf4cde47 100644 --- a/src/media_tools/av_parsers.c +++ b/src/media_tools/av_parsers.c @@ -6903,7 +6903,7 @@ static void avc_hevc_vvc_rewrite_vui(GF_VUIInfo *vui_info, GF_BitStream *orig, G GF_Err gf_avc_change_vui(GF_AVCConfig *avcc, GF_VUIInfo *vui_info) { - AVCState avc; + AVCState *avc_state; u32 i, bit_offset, flag; s32 idx; GF_AVCConfigSlot *slc; @@ -6911,15 +6911,16 @@ GF_Err gf_avc_change_vui(GF_AVCConfig *avcc, GF_VUIInfo *vui_info) if (!avcc) return GF_NON_COMPLIANT_BITSTREAM; - memset(&avc, 0, sizeof(AVCState)); - avc.sps_active_idx = -1; + GF_SAFEALLOC(avc_state, AVCState); + if (!avc_state) return GF_OUT_OF_MEM; + avc_state->sps_active_idx = -1; i=0; while ((slc = (GF_AVCConfigSlot *)gf_list_enum(avcc->sequenceParameterSets, &i))) { GF_BitStream *orig, *mod; u8 *no_emulation_buf = NULL; u32 no_emulation_buf_size = 0, emulation_bytes = 0; - idx = gf_avc_read_sps(slc->data, slc->size, &avc, 0, &bit_offset); + idx = gf_avc_read_sps(slc->data, slc->size, avc_state, 0, &bit_offset); if (idx<0) { continue; } @@ -6961,6 +6962,7 @@ GF_Err gf_avc_change_vui(GF_AVCConfig *avcc, GF_VUIInfo *vui_info) gf_bs_del(mod); gf_free(no_emulation_buf); } + gf_free(avc_state); return GF_OK; } @@ -6998,22 +7000,25 @@ GF_Err gf_avc_change_color(GF_AVCConfig *avcc, s32 fullrange, s32 vidformat, s32 GF_EXPORT GF_Err gf_avc_get_sps_info(u8 *sps_data, u32 sps_size, u32 *sps_id, u32 *width, u32 *height, s32 *par_n, s32 *par_d) { - AVCState avc; + AVCState *avc_state; s32 idx; - memset(&avc, 0, sizeof(AVCState)); - avc.sps_active_idx = -1; + GF_SAFEALLOC(avc_state, AVCState); + if (!avc_state) return GF_OUT_OF_MEM; + avc_state->sps_active_idx = -1; - idx = gf_avc_read_sps(sps_data, sps_size, &avc, 0, NULL); + idx = gf_avc_read_sps(sps_data, sps_size, avc_state, 0, NULL); if (idx < 0) { + gf_free(avc_state); return GF_NON_COMPLIANT_BITSTREAM; } if (sps_id) *sps_id = idx; - if (width) *width = avc.sps[idx].width; - if (height) *height = avc.sps[idx].height; - if (par_n) *par_n = avc.sps[idx].vui.par_num ? avc.sps[idx].vui.par_num : (u32)-1; - if (par_d) *par_d = avc.sps[idx].vui.par_den ? avc.sps[idx].vui.par_den : (u32)-1; + if (width) *width = avc_state->sps[idx].width; + if (height) *height = avc_state->sps[idx].height; + if (par_n) *par_n = avc_state->sps[idx].vui.par_num ? avc_state->sps[idx].vui.par_num : (u32)-1; + if (par_d) *par_d = avc_state->sps[idx].vui.par_den ? avc_state->sps[idx].vui.par_den : (u32)-1; + gf_free(avc_state); return GF_OK; } @@ -9222,15 +9227,16 @@ GF_EXPORT GF_Err gf_hevc_change_vui(GF_HEVCConfig *hvcc, GF_VUIInfo *vui_info) { GF_BitStream *orig, *mod; - HEVCState hevc; + HEVCState *hvc_state; u32 i, bit_offset, flag; s32 idx; GF_NALUFFParamArray *spss; GF_NALUFFParam *slc; orig = NULL; - memset(&hevc, 0, sizeof(HEVCState)); - hevc.sps_active_idx = -1; + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return GF_OUT_OF_MEM; + hvc_state->sps_active_idx = -1; i = 0; spss = NULL; @@ -9239,7 +9245,10 @@ GF_Err gf_hevc_change_vui(GF_HEVCConfig *hvcc, GF_VUIInfo *vui_info) break; spss = NULL; } - if (!spss) return GF_NON_COMPLIANT_BITSTREAM; + if (!spss) { + gf_free(hvc_state); + return GF_NON_COMPLIANT_BITSTREAM; + } i = 0; while ((slc = (GF_NALUFFParam *)gf_list_enum(spss->nalus, &i))) { @@ -9250,7 +9259,7 @@ GF_Err gf_hevc_change_vui(GF_HEVCConfig *hvcc, GF_VUIInfo *vui_info) no_emulation_buf = gf_malloc((slc->size) * sizeof(char)); no_emulation_buf_size = gf_media_nalu_remove_emulation_bytes(slc->data, no_emulation_buf, slc->size); - idx = gf_hevc_read_sps_ex(no_emulation_buf, no_emulation_buf_size, &hevc, &bit_offset); + idx = gf_hevc_read_sps_ex(no_emulation_buf, no_emulation_buf_size, hvc_state, &bit_offset); if (idx < 0) { if (orig) gf_bs_del(orig); @@ -9290,6 +9299,7 @@ GF_Err gf_hevc_change_vui(GF_HEVCConfig *hvcc, GF_VUIInfo *vui_info) gf_bs_del(mod); gf_free(no_emulation_buf); } + gf_free(hvc_state); return GF_OK; } @@ -9345,10 +9355,13 @@ GF_Err gf_hevc_get_sps_info_with_state(HEVCState *hevc, u8 *sps_data, u32 sps_si GF_EXPORT GF_Err gf_hevc_get_sps_info(u8 *sps_data, u32 sps_size, u32 *sps_id, u32 *width, u32 *height, s32 *par_n, s32 *par_d) { - HEVCState hevc; - memset(&hevc, 0, sizeof(HEVCState)); - hevc.sps_active_idx = -1; - return gf_hevc_get_sps_info_with_state(&hevc, sps_data, sps_size, sps_id, width, height, par_n, par_d); + HEVCState *hvc_state; + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return GF_OUT_OF_MEM; + hvc_state->sps_active_idx = -1; + GF_Err res = gf_hevc_get_sps_info_with_state(hvc_state, sps_data, sps_size, sps_id, width, height, par_n, par_d); + gf_free(hvc_state); + return res; } static u32 AC3_FindSyncCode(u8 *buf, u32 buflen) diff --git a/src/media_tools/isom_hinter.c b/src/media_tools/isom_hinter.c index 84b0f2bd1e..00cb858411 100644 --- a/src/media_tools/isom_hinter.c +++ b/src/media_tools/isom_hinter.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Media Tools sub-project @@ -858,7 +858,7 @@ GF_Err gf_hinter_track_process(GF_RTPHinter *tkHint) return GF_OK; } -static u32 write_nalu_config_array(char *sdpLine, GF_List *nalus) +static u32 write_nalu_config_array(char **sdpLine, GF_List *nalus) { u32 i, count, b64s; char b64[200]; @@ -868,13 +868,13 @@ static u32 write_nalu_config_array(char *sdpLine, GF_List *nalus) GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(nalus, i); b64s = gf_base64_encode(sl->data, sl->size, b64, 200); b64[b64s]=0; - strcat(sdpLine, b64); - if (i+1sequenceParameterSets) + gf_list_count(svcc->pictureParameterSets); if (!count) return; - strcat(sdpLine, "; sprop-parameter-sets="); + gf_dynstrcat(sdpLine, "; sprop-parameter-sets=", NULL); if (avcc) { count = write_nalu_config_array(sdpLine, avcc->sequenceParameterSets); - if (count) strcat(sdpLine, ","); + if (count) gf_dynstrcat(sdpLine, ",", NULL); count = write_nalu_config_array(sdpLine, avcc->sequenceParameterSetExtensions); - if (count) strcat(sdpLine, ","); + if (count) gf_dynstrcat(sdpLine, ",", NULL); count = write_nalu_config_array(sdpLine, avcc->pictureParameterSets); - if (count) strcat(sdpLine, ","); + if (count) gf_dynstrcat(sdpLine, ",", NULL); } if (svcc) { count = write_nalu_config_array(sdpLine, svcc->sequenceParameterSets); - if (count) strcat(sdpLine, ","); + if (count) gf_dynstrcat(sdpLine, ",", NULL); count = write_nalu_config_array(sdpLine, svcc->pictureParameterSets); - if (count) strcat(sdpLine, ","); + if (count) gf_dynstrcat(sdpLine, ",", NULL); } - count = (u32) strlen(sdpLine); - if (sdpLine[count-1] == ',') - sdpLine[count-1] = 0; + count = (u32) strlen(*sdpLine); + if (count && (*sdpLine)[count-1] == ',') + (*sdpLine)[count-1] = 0; } GF_EXPORT @@ -909,10 +909,11 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) { u32 Width, Height; GF_ESD *esd; - char sdpLine[20000]; + char tmp_buf[101]; char mediaName[30], payloadName[30]; u32 mtype; + tmp_buf[100]=0; Width = Height = 0; gf_isom_sdp_clean_track(tkHint->file, tkHint->TrackNum); mtype = gf_isom_get_media_type(tkHint->file, tkHint->TrackNum); @@ -922,36 +923,36 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) gf_rtp_builder_get_payload_name(tkHint->rtp_p, payloadName, mediaName); /*TODO- extract out of rtp_p for future live tools*/ - sprintf(sdpLine, "m=%s 0 RTP/%s %d", mediaName, tkHint->rtp_p->slMap.IV_length ? "SAVP" : "AVP", tkHint->rtp_p->PayloadType); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "m=%s 0 RTP/%s %d", mediaName, tkHint->rtp_p->slMap.IV_length ? "SAVP" : "AVP", tkHint->rtp_p->PayloadType); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); if (tkHint->bandwidth) { - sprintf(sdpLine, "b=AS:%d", tkHint->bandwidth); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "b=AS:%d", tkHint->bandwidth); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } if (tkHint->nb_chan) { - sprintf(sdpLine, "a=rtpmap:%d %s/%d/%d", tkHint->rtp_p->PayloadType, payloadName, tkHint->rtp_p->sl_config.timestampResolution, tkHint->nb_chan); + snprintf(tmp_buf, 100, "a=rtpmap:%d %s/%d/%d", tkHint->rtp_p->PayloadType, payloadName, tkHint->rtp_p->sl_config.timestampResolution, tkHint->nb_chan); } else { - sprintf(sdpLine, "a=rtpmap:%d %s/%d", tkHint->rtp_p->PayloadType, payloadName, tkHint->rtp_p->sl_config.timestampResolution); + snprintf(tmp_buf, 100, "a=rtpmap:%d %s/%d", tkHint->rtp_p->PayloadType, payloadName, tkHint->rtp_p->sl_config.timestampResolution); } - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); /*control for MPEG-4*/ if (AddSystemInfo) { - sprintf(sdpLine, "a=mpeg4-esid:%d", gf_isom_get_track_id(tkHint->file, tkHint->TrackNum)); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "a=mpeg4-esid:%d", gf_isom_get_track_id(tkHint->file, tkHint->TrackNum)); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } /*control for QTSS/DSS*/ - sprintf(sdpLine, "a=control:trackID=%d", gf_isom_get_track_id(tkHint->file, tkHint->HintTrack)); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "a=control:trackID=%d", gf_isom_get_track_id(tkHint->file, tkHint->HintTrack)); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); /*H263 extensions*/ if (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_H263) { - sprintf(sdpLine, "a=cliprect:0,0,%d,%d", Height, Width); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "a=cliprect:0,0,%d,%d", Height, Width); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } /*AMR*/ else if ((tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_AMR) || (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_AMR_WB)) { - sprintf(sdpLine, "a=fmtp:%d octet-align=1", tkHint->rtp_p->PayloadType); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "a=fmtp:%d octet-align=1", tkHint->rtp_p->PayloadType); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } /*Text*/ else if (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_3GPP_TEXT) { @@ -977,9 +978,9 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) } } - gf_media_format_ttxt_sdp(tkHint->rtp_p, payloadName, sdpLine, w, h, tx, ty, l, m_w, m_h, NULL); - - strcat(sdpLine, "; tx3g="); + char *sdp_line = NULL; + gf_media_format_ttxt_sdp(tkHint->rtp_p, payloadName, &sdp_line, w, h, tx, ty, l, m_w, m_h, NULL); + gf_dynstrcat(&sdp_line, "; tx3g=", NULL); for (i=0; ifile, tkHint->TrackNum); i++) { u8 *tx3g; GF_Err e; @@ -993,15 +994,16 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) len = gf_base64_encode(tx3g, tx3g_len, buffer, 2000); gf_free(tx3g); buffer[len] = 0; - if (i) strcat(sdpLine, ", "); - strcat(sdpLine, buffer); + if (i) gf_dynstrcat(&sdp_line, ", ", NULL); + gf_dynstrcat(&sdp_line, buffer, NULL); } - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdp_line); + gf_free(sdp_line); } /*EVRC/SMV in non header-free mode*/ else if ((tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_EVRC_SMV) && (tkHint->rtp_p->auh_size>1)) { - sprintf(sdpLine, "a=fmtp:%d maxptime=%d", tkHint->rtp_p->PayloadType, tkHint->rtp_p->auh_size*20); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "a=fmtp:%d maxptime=%d", tkHint->rtp_p->PayloadType, tkHint->rtp_p->auh_size*20); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } /*H264/AVC*/ else if ((tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_H264_AVC) || (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_H264_SVC)) { @@ -1010,16 +1012,17 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) /*TODO - check syntax for SVC (might be some extra signaling)*/ if (avcc) { - sprintf(sdpLine, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", tkHint->rtp_p->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication); + snprintf(tmp_buf, 100, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", tkHint->rtp_p->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication); } else { if (!svcc) return GF_ISOM_INVALID_FILE; - sprintf(sdpLine, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", tkHint->rtp_p->PayloadType, svcc->AVCProfileIndication, svcc->profile_compatibility, svcc->AVCLevelIndication); + snprintf(tmp_buf, 100, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", tkHint->rtp_p->PayloadType, svcc->AVCProfileIndication, svcc->profile_compatibility, svcc->AVCLevelIndication); } - write_avc_config(sdpLine, avcc, svcc); - - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + char *sdp_line = gf_strdup(tmp_buf); + write_avc_config(&sdp_line, avcc, svcc); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdp_line); + gf_free(sdp_line); gf_odf_avc_cfg_del(avcc); gf_odf_avc_cfg_del(svcc); } @@ -1027,27 +1030,29 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) else if (tkHint->rtp_p->rtp_payt==GF_RTP_PAYT_MPEG4) { GF_Err e; esd = gf_isom_get_esd(tkHint->file, tkHint->TrackNum, 1); - + char *sdp = NULL; if (esd && esd->decoderConfig && esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { - e = gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + e = gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, &sdp, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); } else { - e = gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, NULL, 0); + e = gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, &sdp, NULL, 0); } if (esd) gf_odf_desc_del((GF_Descriptor *)esd); - if (e) return e; - + if (e) { + if (sdp) gf_free(sdp); + return e; + } if (tkHint->rtp_p->slMap.IV_length) { const char *kms; gf_isom_get_ismacryp_info(tkHint->file, tkHint->TrackNum, 1, NULL, NULL, NULL, NULL, &kms, NULL, NULL, NULL); if (!strnicmp(kms, "(key)", 5) || !strnicmp(kms, "(ipmp)", 6) || !strnicmp(kms, "(uri)", 5)) { - strcat(sdpLine, "; ISMACrypKey="); + gf_dynstrcat(&sdp, "; ISMACrypKey=", NULL); } else { - strcat(sdpLine, "; ISMACrypKey=(uri)"); + gf_dynstrcat(&sdp, "; ISMACrypKey=(uri)", NULL); } - strcat(sdpLine, kms); + gf_dynstrcat(&sdp, kms, NULL); } - - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdp); + if (sdp) gf_free(sdp); } /*MPEG-4 Audio LATM*/ else if (tkHint->rtp_p->rtp_payt==GF_RTP_PAYT_LATM) { @@ -1079,9 +1084,11 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) gf_bs_get_content(bs, &config_bytes, &config_size); gf_bs_del(bs); - gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, config_bytes, config_size); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + char *sdp = NULL; + gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, &sdp, config_bytes, config_size); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdp); gf_free(config_bytes); + if (sdp) gf_free(sdp); } #if GPAC_ENABLE_3GPP_DIMS_RTP /*3GPP DIMS*/ @@ -1090,51 +1097,53 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) gf_isom_get_visual_info(tkHint->file, tkHint->TrackNum, 1, &Width, &Height); gf_isom_get_dims_description(tkHint->file, tkHint->TrackNum, 1, &dims); - sprintf(sdpLine, "a=fmtp:%d Version-profile=%d", tkHint->rtp_p->PayloadType, dims.profile); + char *sdp = NULL; + sprintf(tmp_buf, "a=fmtp:%d Version-profile=%d", tkHint->rtp_p->PayloadType, dims.profile); + gf_dynstrcat(&sdp, tmp_buf, NULL); if (! dims.fullRequestHost) { - char fmt[200]; - strcat(sdpLine, ";useFullRequestHost=0"); - sprintf(fmt, ";pathComponents=%d", dims.pathComponents); - strcat(sdpLine, fmt); + gf_dynstrcat(&sdp, ";useFullRequestHost=0", NULL); + sprintf(tmp_buf, ";pathComponents=%d", dims.pathComponents); + gf_dynstrcat(&sdp, tmp_buf, NULL); } - if (!dims.streamType) strcat(sdpLine, ";stream-type=secondary"); - if (dims.containsRedundant == 1) strcat(sdpLine, ";contains-redundant=main"); - else if (dims.containsRedundant == 2) strcat(sdpLine, ";contains-redundant=redundant"); + if (!dims.streamType) gf_dynstrcat(&sdp, ";stream-type=secondary", NULL); + if (dims.containsRedundant == 1) gf_dynstrcat(&sdp, ";contains-redundant=main", NULL); + else if (dims.containsRedundant == 2) gf_dynstrcat(&sdp, ";contains-redundant=redundant", NULL); if (dims.textEncoding && strlen(dims.textEncoding)) { - strcat(sdpLine, ";text-encoding="); - strcat(sdpLine, dims.textEncoding); + gf_dynstrcat(&sdp, ";text-encoding=", NULL); + gf_dynstrcat(&sdp, dims.textEncoding, NULL); } if (dims.contentEncoding && strlen(dims.contentEncoding)) { - strcat(sdpLine, ";content-coding="); - strcat(sdpLine, dims.contentEncoding); + gf_dynstrcat(&sdp, ";content-coding=", NULL); + gf_dynstrcat(&sdp, dims.contentEncoding, NULL); } if (dims.contentEncoding && dims.content_script_types && strlen(dims.content_script_types) ) { - strcat(sdpLine, ";content-script-types="); - strcat(sdpLine, dims.contentEncoding); + gf_dynstrcat(&sdp, ";content-script-types=", NULL); + gf_dynstrcat(&sdp, dims.contentEncoding, NULL); } - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdp); + if (sdp) gf_free(sdp); } #endif /*extensions for some mobile phones*/ if (Width && Height) { - sprintf(sdpLine, "a=framesize:%d %d-%d", tkHint->rtp_p->PayloadType, Width, Height); - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + snprintf(tmp_buf, 100, "a=framesize:%d %d-%d", tkHint->rtp_p->PayloadType, Width, Height); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } esd = gf_isom_get_esd(tkHint->file, tkHint->TrackNum, 1); if (esd && esd->decoderConfig && (esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config)) { if (esd->decoderConfig->predefined_rvc_config) { - sprintf(sdpLine, "a=rvc-config-predef:%d", esd->decoderConfig->predefined_rvc_config); + snprintf(tmp_buf, 100, "a=rvc-config-predef:%d", esd->decoderConfig->predefined_rvc_config); } else { /*temporary ...*/ if ((esd->decoderConfig->objectTypeIndication==GF_CODECID_AVC) || (esd->decoderConfig->objectTypeIndication==GF_CODECID_SVC)) { - sprintf(sdpLine, "a=rvc-config:%s", "http://download.tsi.telecom-paristech.fr/gpac/RVC/rvc_config_avc.xml"); + snprintf(tmp_buf, 100, "a=rvc-config:%s", "http://download.tsi.telecom-paristech.fr/gpac/RVC/rvc_config_avc.xml"); } else { - sprintf(sdpLine, "a=rvc-config:%s", "http://download.tsi.telecom-paristech.fr/gpac/RVC/rvc_config_sp.xml"); + snprintf(tmp_buf, 100, "a=rvc-config:%s", "http://download.tsi.telecom-paristech.fr/gpac/RVC/rvc_config_sp.xml"); } } - gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, tmp_buf); } if (esd) gf_odf_desc_del((GF_Descriptor *)esd); diff --git a/src/media_tools/isom_tools.c b/src/media_tools/isom_tools.c index 0d67a97756..a9d19ae2b0 100644 --- a/src/media_tools/isom_tools.c +++ b/src/media_tools/isom_tools.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Media Tools sub-project @@ -965,32 +965,35 @@ GF_Err gf_media_get_color_info(GF_ISOFile *file, u32 track, u32 sampleDescriptio || (stype==GF_ISOM_SUBTYPE_AVC3_H264) || (stype==GF_ISOM_SUBTYPE_AVC4_H264) ) { - AVCState avc; + AVCState *avc_state; GF_AVCConfig *avcc = gf_isom_avc_config_get(file, track, sampleDescriptionIndex); u32 i; s32 idx; GF_NALUFFParam *slc; - memset(&avc, 0, sizeof(AVCState)); - avc.sps_active_idx = -1; + GF_SAFEALLOC(avc_state, AVCState); + if (!avc_state) return GF_OUT_OF_MEM; + avc_state->sps_active_idx = -1; i=0; while ((slc = (GF_NALUFFParam *)gf_list_enum(avcc->sequenceParameterSets, &i))) { - idx = gf_avc_read_sps(slc->data, slc->size, &avc, 0, NULL); + idx = gf_avc_read_sps(slc->data, slc->size, avc_state, 0, NULL); if (idx<0) continue; - if (! avc.sps[idx].vui_parameters_present_flag ) + if (! avc_state->sps[idx].vui_parameters_present_flag ) continue; - *colour_type = avc.sps[idx].vui.video_format; - *colour_primaries = avc.sps[idx].vui.colour_primaries; - *transfer_characteristics = avc.sps[idx].vui.transfer_characteristics; - *matrix_coefficients = avc.sps[idx].vui.matrix_coefficients; - *full_range_flag = avc.sps[idx].vui.video_full_range_flag; + *colour_type = avc_state->sps[idx].vui.video_format; + *colour_primaries = avc_state->sps[idx].vui.colour_primaries; + *transfer_characteristics = avc_state->sps[idx].vui.transfer_characteristics; + *matrix_coefficients = avc_state->sps[idx].vui.matrix_coefficients; + *full_range_flag = avc_state->sps[idx].vui.video_full_range_flag; gf_odf_avc_cfg_del(avcc); + gf_free(avc_state); return GF_OK; } gf_odf_avc_cfg_del(avcc); + gf_free(avc_state); return GF_NOT_FOUND; } if ((stype==GF_ISOM_SUBTYPE_HEV1) @@ -1000,13 +1003,14 @@ GF_Err gf_media_get_color_info(GF_ISOFile *file, u32 track, u32 sampleDescriptio || (stype==GF_ISOM_SUBTYPE_LHV1) || (stype==GF_ISOM_SUBTYPE_LHE1) ) { - HEVCState hvc; + HEVCState *hvc_state; GF_HEVCConfig *hvcc = gf_isom_hevc_config_get(file, track, sampleDescriptionIndex); u32 i; GF_NALUFFParamArray *pa; - memset(&hvc, 0, sizeof(HEVCState)); - hvc.sps_active_idx = -1; + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return GF_OUT_OF_MEM; + hvc_state->sps_active_idx = -1; i=0; while ((pa = (GF_NALUFFParamArray *)gf_list_enum(hvcc->param_array, &i))) { @@ -1017,55 +1021,61 @@ GF_Err gf_media_get_color_info(GF_ISOFile *file, u32 track, u32 sampleDescriptio j=0; while ((slc = (GF_NALUFFParam *)gf_list_enum(pa->nalus, &j))) { - idx = gf_hevc_read_sps(slc->data, slc->size, &hvc); + idx = gf_hevc_read_sps(slc->data, slc->size, hvc_state); if (idx<0) continue; - if (! hvc.sps[idx].vui_parameters_present_flag) + if (! hvc_state->sps[idx].vui_parameters_present_flag) continue; - *colour_type = hvc.sps[idx].video_format; - *colour_primaries = hvc.sps[idx].colour_primaries; - *transfer_characteristics = hvc.sps[idx].transfer_characteristic; - *matrix_coefficients = hvc.sps[idx].matrix_coeffs; - *full_range_flag = hvc.sps[idx].video_full_range_flag; + *colour_type = hvc_state->sps[idx].video_format; + *colour_primaries = hvc_state->sps[idx].colour_primaries; + *transfer_characteristics = hvc_state->sps[idx].transfer_characteristic; + *matrix_coefficients = hvc_state->sps[idx].matrix_coeffs; + *full_range_flag = hvc_state->sps[idx].video_full_range_flag; gf_odf_hevc_cfg_del(hvcc); + gf_free(hvc_state); return GF_OK; } } gf_odf_hevc_cfg_del(hvcc); + gf_free(hvc_state); return GF_NOT_FOUND; } if (stype==GF_ISOM_SUBTYPE_AV01) { - AV1State av1; + AV1State *av1_state; - gf_av1_init_state(&av1); - av1.config = gf_isom_av1_config_get(file, track, sampleDescriptionIndex); - if (av1.config) { + GF_SAFEALLOC(av1_state, AV1State); + if (!av1_state) return GF_OUT_OF_MEM; + gf_av1_init_state(av1_state); + av1_state->config = gf_isom_av1_config_get(file, track, sampleDescriptionIndex); + if (av1_state->config) { u32 i; - for (i=0; iobu_array); i++) { + for (i=0; iconfig->obu_array); i++) { GF_BitStream *bs; ObuType obu_type = 0; u32 hdr_size = 0; u64 obu_size = 0; - GF_AV1_OBUArrayEntry *obu = gf_list_get(av1.config->obu_array, i); + GF_AV1_OBUArrayEntry *obu = gf_list_get(av1_state->config->obu_array, i); bs = gf_bs_new(obu->obu, (u32) obu->obu_length, GF_BITSTREAM_READ); - gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, av1_state); gf_bs_del(bs); - if (av1.color_description_present_flag) { + if (av1_state->color_description_present_flag) { *colour_type = 0; - *colour_primaries = av1.color_primaries; - *transfer_characteristics = av1.transfer_characteristics; - *matrix_coefficients = av1.matrix_coefficients; - *full_range_flag = av1.color_range; - if (av1.config) gf_odf_av1_cfg_del(av1.config); - gf_av1_reset_state(&av1, GF_TRUE); + *colour_primaries = av1_state->color_primaries; + *transfer_characteristics = av1_state->transfer_characteristics; + *matrix_coefficients = av1_state->matrix_coefficients; + *full_range_flag = av1_state->color_range; + if (av1_state->config) gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); return GF_OK; } } } - if (av1.config) gf_odf_av1_cfg_del(av1.config); - gf_av1_reset_state(&av1, GF_TRUE); + if (av1_state->config) gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); return GF_NOT_FOUND; } @@ -1704,7 +1714,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) u32 num_svc_track, num_sample, svc_track, dst_track, ref_trackID, ref_trackNum, max_id, di, width, height, size, nalu_size_length, i, j, t, max_size, num_pps, num_sps, num_subseq, NALUnitHeader, data_offset, data_length, count, timescale, cur_extract_mode; GF_Err e; GF_NALUFFParam *slc, *sl; - AVCState avc; + AVCState *avc_state=NULL; s32 sps_id, pps_id; GF_ISOSample *samp, *dst_samp; GF_BitStream *bs, *dst_bs; @@ -1776,8 +1786,13 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) max_id = gf_isom_get_track_id_max(file); di = 0; - memset(&avc, 0, sizeof(AVCState)); - avc.sps_active_idx = -1; + GF_SAFEALLOC(avc_state, AVCState); + if (!avc_state) { + e = GF_OUT_OF_MEM; + goto exit; + } + + avc_state->sps_active_idx = -1; nalu_size_length = 8 * svccfg->nal_unit_size; /*read all sps, but we need only the subset sequence parameter sets*/ sps = (s32 *) gf_malloc(num_subseq * sizeof(s32)); @@ -1787,7 +1802,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) { slc = (GF_NALUFFParam *)gf_list_get(svccfg->sequenceParameterSets, i); nal_type = slc->data[0] & 0x1F; - sps_id = gf_avc_read_sps(slc->data, slc->size, &avc, 0, NULL); + sps_id = gf_avc_read_sps(slc->data, slc->size, avc_state, 0, NULL); if (sps_id < 0) { e = GF_NON_COMPLIANT_BITSTREAM; goto exit; @@ -1806,7 +1821,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) for (j = 0; j < num_pps; j++) { slc = (GF_NALUFFParam *)gf_list_get(svccfg->pictureParameterSets, j); - pps_id = gf_avc_read_pps(slc->data, slc->size, &avc); + pps_id = gf_avc_read_pps(slc->data, slc->size, avc_state); if (pps_id < 0) { e = GF_NON_COMPLIANT_BITSTREAM; goto exit; @@ -1844,8 +1859,8 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) max_size = size; } - gf_avc_parse_nalu(bs, &avc); - nal_type = avc.last_nal_type_parsed; + gf_avc_parse_nalu(bs, avc_state); + nal_type = avc_state->last_nal_type_parsed; e = gf_bs_seek(bs, offset+nalu_size_length/8); if (e) @@ -1856,24 +1871,24 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) { for (i = 0; i < num_pps; i++) { - if (avc.s_info.pps->id == pps[i]) + if (avc_state->s_info.pps->id == pps[i]) { is_subseq_pps[i] = 1; break; } } - if ((count > 0) && (avc.s_info.pps->sps_id == sps[count-1])) + if ((count > 0) && (avc_state->s_info.pps->sps_id == sps[count-1])) continue; /*verify the order of SPS, reorder if necessary*/ - if (avc.s_info.pps->sps_id != sps[count]) + if (avc_state->s_info.pps->sps_id != sps[count]) { for (i = count+1; i < num_subseq; i++) { /*swap two SPS*/ - if (avc.s_info.pps->sps_id == sps[i]) + if (avc_state->s_info.pps->sps_id == sps[i]) { sps[i] = sps[count]; - sps[count] = avc.s_info.pps->sps_id; + sps[count] = avc_state->s_info.pps->sps_id; sps_track[count] = i; break; } @@ -1918,16 +1933,16 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) if (splitAll) { sps_id = sps[t]; - width = avc.sps[sps_id].width; - height = avc.sps[sps_id].height; + width = avc_state->sps[sps_id].width; + height = avc_state->sps[sps_id].height; gf_isom_set_visual_info(file, svc_track, di, width, height); cfg->configurationVersion = 1; - cfg->chroma_bit_depth = 8 + avc.sps[sps_id].chroma_bit_depth_m8; - cfg->chroma_format = avc.sps[sps_id].chroma_format; - cfg->luma_bit_depth = 8 + avc.sps[sps_id].luma_bit_depth_m8; - cfg->profile_compatibility = avc.sps[sps_id].prof_compat; - cfg->AVCLevelIndication = avc.sps[sps_id].level_idc; - cfg->AVCProfileIndication = avc.sps[sps_id].profile_idc; + cfg->chroma_bit_depth = 8 + avc_state->sps[sps_id].chroma_bit_depth_m8; + cfg->chroma_format = avc_state->sps[sps_id].chroma_format; + cfg->luma_bit_depth = 8 + avc_state->sps[sps_id].luma_bit_depth_m8; + cfg->profile_compatibility = avc_state->sps[sps_id].prof_compat; + cfg->AVCLevelIndication = avc_state->sps[sps_id].level_idc; + cfg->AVCProfileIndication = avc_state->sps[sps_id].profile_idc; cfg->nal_unit_size = svccfg->nal_unit_size; slc = (GF_NALUFFParam *)gf_list_get(svccfg->sequenceParameterSets, sps_track[t]); sl = (GF_NALUFFParam*)gf_malloc(sizeof(GF_NALUFFParam)); @@ -1939,7 +1954,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) for (j = 0; j < num_pps; j++) { pps_id = pps[j]; - if (is_subseq_pps[j] && (avc.pps[pps_id].sps_id == sps_id)) + if (is_subseq_pps[j] && (avc_state->pps[pps_id].sps_id == sps_id)) { slc = (GF_NALUFFParam *)gf_list_get(svccfg->pictureParameterSets, j); sl = (GF_NALUFFParam*)gf_malloc(sizeof(GF_NALUFFParam)); @@ -1956,16 +1971,16 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) for (i = 0; i < num_subseq; i++) { sps_id = sps[i]; - width = avc.sps[sps_id].width; - height = avc.sps[sps_id].height; + width = avc_state->sps[sps_id].width; + height = avc_state->sps[sps_id].height; gf_isom_set_visual_info(file, svc_track, di, width, height); cfg->configurationVersion = 1; - cfg->chroma_bit_depth = 8 + avc.sps[sps_id].chroma_bit_depth_m8; - cfg->chroma_format = avc.sps[sps_id].chroma_format; - cfg->luma_bit_depth = 8 + avc.sps[sps_id].luma_bit_depth_m8; - cfg->profile_compatibility = avc.sps[sps_id].prof_compat; - cfg->AVCLevelIndication = avc.sps[sps_id].level_idc; - cfg->AVCProfileIndication = avc.sps[sps_id].profile_idc; + cfg->chroma_bit_depth = 8 + avc_state->sps[sps_id].chroma_bit_depth_m8; + cfg->chroma_format = avc_state->sps[sps_id].chroma_format; + cfg->luma_bit_depth = 8 + avc_state->sps[sps_id].luma_bit_depth_m8; + cfg->profile_compatibility = avc_state->sps[sps_id].prof_compat; + cfg->AVCLevelIndication = avc_state->sps[sps_id].level_idc; + cfg->AVCProfileIndication = avc_state->sps[sps_id].profile_idc; cfg->nal_unit_size = svccfg->nal_unit_size; slc = (GF_NALUFFParam *)gf_list_get(svccfg->sequenceParameterSets, sps_track[i]); sl = (GF_NALUFFParam*)gf_malloc(sizeof(GF_NALUFFParam)); @@ -1977,7 +1992,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) for (j = 0; j < num_pps; j++) { pps_id = pps[j]; - if (avc.pps[pps_id].sps_id == sps_id) + if (avc_state->pps[pps_id].sps_id == sps_id) { slc = (GF_NALUFFParam *)gf_list_get(svccfg->pictureParameterSets, j); sl = (GF_NALUFFParam*)gf_malloc(sizeof(GF_NALUFFParam)); @@ -2076,8 +2091,8 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) max_size = size; } - gf_avc_parse_nalu(bs, &avc); - nal_type = avc.last_nal_type_parsed; + gf_avc_parse_nalu(bs, avc_state); + nal_type = avc_state->last_nal_type_parsed; e = gf_bs_seek(bs, offset+nalu_size_length/8); if (e) goto exit; @@ -2086,7 +2101,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) switch (nal_type) { case GF_AVC_NALU_PIC_PARAM: - pps_id = avc.last_ps_idx; + pps_id = avc_state->last_ps_idx; j = 0; dst_track = 0; while (j < num_pps) @@ -2101,7 +2116,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) { for (t = 0; t < num_svc_track; t++) { - if (sps[t] == avc.pps[pps_id].sps_id) + if (sps[t] == avc_state->pps[pps_id].sps_id) { dst_track = t + 1; break; @@ -2114,7 +2129,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) dst_bs = sample_bs[dst_track]; break; case GF_AVC_NALU_SVC_SUBSEQ_PARAM: - sps_id = avc.last_ps_idx; + sps_id = avc_state->last_ps_idx; dst_track = 0; if (splitAll) { @@ -2137,7 +2152,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) { for (t = 0; t < num_svc_track; t++) { - if (sps[t] == (avc.s_info.pps)->sps_id) + if (sps[t] == (avc_state->s_info.pps)->sps_id) { dst_track = t + 1; break; @@ -2221,7 +2236,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) for (i = 0; i < gf_list_count(svccfg->sequenceParameterSets); i++) { slc = (GF_NALUFFParam *)gf_list_get(svccfg->sequenceParameterSets, i); - sps_id = gf_avc_read_sps(slc->data, slc->size, &avc, 0, NULL); + sps_id = gf_avc_read_sps(slc->data, slc->size, avc_state, 0, NULL); if (sps_id < 0) { e = GF_NON_COMPLIANT_BITSTREAM; goto exit; @@ -2239,7 +2254,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) for (j = 0; j < gf_list_count(svccfg->pictureParameterSets); j++) { slc = (GF_NALUFFParam *)gf_list_get(svccfg->pictureParameterSets, j); - pps_id = gf_avc_read_pps(slc->data, slc->size, &avc); + pps_id = gf_avc_read_pps(slc->data, slc->size, avc_state); if (pps_id < 0) { e = GF_NON_COMPLIANT_BITSTREAM; goto exit; @@ -2779,7 +2794,6 @@ GF_EXPORT GF_Err gf_media_split_lhvc(GF_ISOFile *file, u32 track, Bool for_temporal_sublayers, Bool splitAll, GF_LHVCExtractoreMode extractor_mode) { #if !defined(GPAC_DISABLE_AV_PARSERS) - LHVCTrackInfo sti[64]; GF_HEVCConfig *hevccfg, *lhvccfg; u32 sample_num, count, cur_extract_mode, j, k, max_layer_id; char *nal_data=NULL; @@ -2787,26 +2801,32 @@ GF_Err gf_media_split_lhvc(GF_ISOFile *file, u32 track, Bool for_temporal_sublay u32 nal_unit_size=0; Bool single_layer_per_track=GF_TRUE; GF_Err e = GF_OK; - HEVCState hevc_state; + HEVCState *hvc_state; - memset(&hevc_state, 0, sizeof(HEVCState)); + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return GF_OUT_OF_MEM; hevccfg = gf_isom_hevc_config_get(file, track, 1); lhvccfg = gf_isom_lhvc_config_get(file, track, 1); if (!lhvccfg && !for_temporal_sublayers) { if (hevccfg) gf_odf_hevc_cfg_del(hevccfg); + gf_free(hvc_state); return GF_OK; } else if (for_temporal_sublayers) { if (lhvccfg) { if (hevccfg) gf_odf_hevc_cfg_del(hevccfg); gf_odf_hevc_cfg_del(lhvccfg); + gf_free(hvc_state); + return GF_NOT_SUPPORTED; + } + if (!hevccfg) { + gf_free(hvc_state); return GF_NOT_SUPPORTED; } - if (!hevccfg) return GF_NOT_SUPPORTED; - if (hevccfg->numTemporalLayers<=1) { gf_odf_hevc_cfg_del(hevccfg); + gf_free(hvc_state); return GF_OK; } } @@ -2814,7 +2834,11 @@ GF_Err gf_media_split_lhvc(GF_ISOFile *file, u32 track, Bool for_temporal_sublay cur_extract_mode = gf_isom_get_nalu_extract_mode(file, track); gf_isom_set_nalu_extract_mode(file, track, GF_ISOM_NALU_EXTRACT_INSPECT); - memset(sti, 0, sizeof(sti)); + LHVCTrackInfo *sti; + sti = gf_malloc(sizeof(LHVCTrackInfo)*64); + if (!sti) return GF_OUT_OF_MEM; + + memset(sti, 0, sizeof(LHVCTrackInfo)*64); sti[0].track_num = track; sti[0].has_samples=GF_TRUE; max_layer_id = 0; @@ -2845,15 +2869,15 @@ GF_Err gf_media_split_lhvc(GF_ISOFile *file, u32 track, Bool for_temporal_sublay if (ar->type==GF_HEVC_NALU_SEQ_PARAM) { u32 lw, lh; - s32 idx = gf_hevc_get_sps_info_with_state(&hevc_state, sl->data, sl->size, NULL, &lw, &lh, NULL, NULL); + s32 idx = gf_hevc_get_sps_info_with_state(hvc_state, sl->data, sl->size, NULL, &lw, &lh, NULL, NULL); if (idx>=0) { if (lw > sti[layer_id].width) sti[layer_id].width = lw; if (lh > sti[layer_id].height) sti[layer_id].height = lh; } } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) { - gf_hevc_read_pps(sl->data, sl->size, &hevc_state); + gf_hevc_read_pps(sl->data, sl->size, hvc_state); } else if (ar->type==GF_HEVC_NALU_VID_PARAM) { - gf_hevc_read_vps(sl->data, sl->size, &hevc_state); + gf_hevc_read_vps(sl->data, sl->size, hvc_state); } //don't touch base layer @@ -3027,15 +3051,15 @@ GF_Err gf_media_split_lhvc(GF_ISOFile *file, u32 track, Bool for_temporal_sublay if (nal_type==GF_HEVC_NALU_SEQ_PARAM) { u32 lw, lh; - s32 idx = gf_hevc_get_sps_info_with_state(&hevc_state, sample->data + offset, nal_size, NULL, &lw, &lh, NULL, NULL); + s32 idx = gf_hevc_get_sps_info_with_state(hvc_state, sample->data + offset, nal_size, NULL, &lw, &lh, NULL, NULL); if (idx>=0) { if (lw > sti[layer_id].width) sti[layer_id].width = lw; if (lh > sti[layer_id].height) sti[layer_id].height = lh; } } else if (nal_type==GF_HEVC_NALU_PIC_PARAM) { - gf_hevc_read_pps(sample->data + offset, nal_size, &hevc_state); + gf_hevc_read_pps(sample->data + offset, nal_size, hvc_state); } else if (nal_type==GF_HEVC_NALU_VID_PARAM) { - gf_hevc_read_vps(sample->data + offset, nal_size, &hevc_state); + gf_hevc_read_vps(sample->data + offset, nal_size, hvc_state); } } @@ -3311,6 +3335,9 @@ GF_Err gf_media_split_lhvc(GF_ISOFile *file, u32 track, Bool for_temporal_sublay if (lhvccfg) gf_odf_hevc_cfg_del(lhvccfg); if (hevccfg) gf_odf_hevc_cfg_del(hevccfg); if (nal_data) gf_free(nal_data); + gf_free(hvc_state); + + gf_free(sti); return e; #else return GF_NOT_SUPPORTED; @@ -3473,7 +3500,7 @@ GF_Err gf_media_split_hevc_tiles(GF_ISOFile *file, u32 signal_mode) u32 i, j, cur_tile, count, stype, track, nb_tiles, di, nalu_size_length, tx, ty, tw, th; s32 pps_idx=-1, sps_idx=-1, ret; GF_Err e = GF_OK; - HEVCState hevc; + HEVCState *hvc_state; HEVCTileImport *tiles; GF_HEVCConfig *hvcc; Bool filter_disabled=GF_TRUE; @@ -3499,7 +3526,8 @@ GF_Err gf_media_split_hevc_tiles(GF_ISOFile *file, u32 signal_mode) hvcc = gf_isom_hevc_config_get(file, track, 1); nalu_size_length = hvcc->nal_unit_size; - memset(&hevc, 0, sizeof(HEVCState)); + GF_SAFEALLOC(hvc_state, HEVCState); + if (!hvc_state) return GF_OUT_OF_MEM; count = gf_list_count(hvcc->param_array); for (i=0; itype) { case GF_HEVC_NALU_PIC_PARAM: - pps_idx = gf_hevc_read_pps(sl->data, sl->size, &hevc); + pps_idx = gf_hevc_read_pps(sl->data, sl->size, hvc_state); break; case GF_HEVC_NALU_SEQ_PARAM: - sps_idx = gf_hevc_read_sps(sl->data, sl->size, &hevc); + sps_idx = gf_hevc_read_sps(sl->data, sl->size, hvc_state); break; case GF_HEVC_NALU_VID_PARAM: - gf_hevc_read_vps(sl->data, sl->size, &hevc); + gf_hevc_read_vps(sl->data, sl->size, hvc_state); break; } } @@ -3538,17 +3566,17 @@ GF_Err gf_media_split_hevc_tiles(GF_ISOFile *file, u32 signal_mode) for (j=0; jpps[pps_idx].loop_filter_across_tiles_enabled_flag) filter_disabled=GF_FALSE; - if (! hevc.pps[pps_idx].tiles_enabled_flag) { - hevc_add_trif(file, track, gf_isom_get_track_id(file, track), GF_TRUE, 1, filter_disabled, 0, 0, hevc.sps[pps_idx].width, hevc.sps[pps_idx].height, GF_TRUE); + if (! hvc_state->pps[pps_idx].tiles_enabled_flag) { + hevc_add_trif(file, track, gf_isom_get_track_id(file, track), GF_TRUE, 1, filter_disabled, 0, 0, hvc_state->sps[pps_idx].width, hvc_state->sps[pps_idx].height, GF_TRUE); GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[HEVC Tiles] Tiles not enabled, signal only single tile full picture\n")); + gf_free(hvc_state); return GF_OK; } - nb_tiles = hevc.pps[pps_idx].num_tile_columns * hevc.pps[pps_idx].num_tile_rows; + nb_tiles = hvc_state->pps[pps_idx].num_tile_columns * hvc_state->pps[pps_idx].num_tile_rows; tiles = gf_malloc(sizeof(HEVCTileImport) * nb_tiles); - if (!tiles) return GF_OUT_OF_MEM; + if (!tiles) { + gf_free(hvc_state); + return GF_OUT_OF_MEM; + } memset(tiles, 0, sizeof(HEVCTileImport) * nb_tiles); for (i=0; i=nb_tiles) { GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[HEVC Tiles] Tile index %d is greater than number of tiles %d in PPS\n", cur_tile, nb_tiles)); e = GF_NON_COMPLIANT_BITSTREAM; @@ -3669,7 +3703,7 @@ GF_Err gf_media_split_hevc_tiles(GF_ISOFile *file, u32 signal_mode) tiles[cur_tile].ty = ty; tiles[cur_tile].tw = tw; tiles[cur_tile].th = th; - if (hevc.s_info.slice_type != GF_HEVC_SLICE_TYPE_I) { + if (hvc_state->s_info.slice_type != GF_HEVC_SLICE_TYPE_I) { tiles[cur_tile].all_intra = 0; } @@ -3795,6 +3829,7 @@ GF_Err gf_media_split_hevc_tiles(GF_ISOFile *file, u32 signal_mode) err_exit: + gf_free(hvc_state); gf_free(tiles); if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISOBMF] Could not split HEVC tiles into tracks: %s\n", gf_error_to_string(e) )); @@ -4050,11 +4085,13 @@ GF_Err rfc_6381_get_codec_av1(char *szCodec, u32 subtype, GF_AV1Config *av1c, CO #ifndef GPAC_DISABLE_AV_PARSERS GF_Err e; u32 i = 0; - AV1State av1_state; + AV1State *av1_state; gf_assert(av1c); - gf_av1_init_state(&av1_state); - av1_state.config = av1c; + GF_SAFEALLOC(av1_state, AV1State); + if (!av1_state) return GF_OUT_OF_MEM; + gf_av1_init_state(av1_state); + av1_state->config = av1c; for (i = 0; i < gf_list_count(av1c->obu_array); ++i) { GF_BitStream *bs; @@ -4063,7 +4100,7 @@ GF_Err rfc_6381_get_codec_av1(char *szCodec, u32 subtype, GF_AV1Config *av1c, CO if (!av1_is_obu_header(a->obu_type)) GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[RFC6381] AV1: unexpected obu_type %d - Parsing anyway.\n", a->obu_type, gf_4cc_to_str(subtype))); - e = aom_av1_parse_temporal_unit_from_section5(bs, &av1_state); + e = aom_av1_parse_temporal_unit_from_section5(bs, av1_state); gf_bs_del(bs); bs = NULL; if (e) { @@ -4072,27 +4109,28 @@ GF_Err rfc_6381_get_codec_av1(char *szCodec, u32 subtype, GF_AV1Config *av1c, CO } snprintf(szCodec, RFC6381_CODEC_NAME_SIZE_MAX, "%s.%01u.%02u%c.%02u", gf_4cc_to_str(subtype), - av1_state.config->seq_profile, av1_state.config->seq_level_idx_0, av1_state.config->seq_tier_0 ? 'H' : 'M', av1_state.bit_depth); + av1_state->config->seq_profile, av1_state->config->seq_level_idx_0, av1_state->config->seq_tier_0 ? 'H' : 'M', av1_state->bit_depth); - if (av1_state.color_description_present_flag) { + if (av1_state->color_description_present_flag) { char tmp[RFC6381_CODEC_NAME_SIZE_MAX]; snprintf(tmp, RFC6381_CODEC_NAME_SIZE_MAX, ".%01u.%01u%01u%01u.%02u.%02u.%02u.%01u", - av1_state.config->monochrome, av1_state.config->chroma_subsampling_x, av1_state.config->chroma_subsampling_y, - av1_state.config->chroma_subsampling_x && av1_state.config->chroma_subsampling_y ? av1_state.config->chroma_sample_position : 0, - colr.override == GF_TRUE ? colr.colour_primaries : av1_state.color_primaries, - colr.override == GF_TRUE ? colr.transfer_characteristics : av1_state.transfer_characteristics, - colr.override == GF_TRUE ? colr.matrix_coefficients : av1_state.matrix_coefficients, - colr.override == GF_TRUE ? colr.full_range : av1_state.color_range); + av1_state->config->monochrome, av1_state->config->chroma_subsampling_x, av1_state->config->chroma_subsampling_y, + av1_state->config->chroma_subsampling_x && av1_state->config->chroma_subsampling_y ? av1_state->config->chroma_sample_position : 0, + colr.override == GF_TRUE ? colr.colour_primaries : av1_state->color_primaries, + colr.override == GF_TRUE ? colr.transfer_characteristics : av1_state->transfer_characteristics, + colr.override == GF_TRUE ? colr.matrix_coefficients : av1_state->matrix_coefficients, + colr.override == GF_TRUE ? colr.full_range : av1_state->color_range); strcat(szCodec, tmp); } else { - if ((av1_state.color_primaries == 2) && (av1_state.transfer_characteristics == 2) && (av1_state.matrix_coefficients == 2) && av1_state.color_range == GF_FALSE) { + if ((av1_state->color_primaries == 2) && (av1_state->transfer_characteristics == 2) && (av1_state->matrix_coefficients == 2) && av1_state->color_range == GF_FALSE) { } else { GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[RFC6381] incoherent color characteristics primaries %d transfer %d matrix %d color range %d\n", - av1_state.color_primaries, av1_state.transfer_characteristics, av1_state.matrix_coefficients, av1_state.color_range)); + av1_state->color_primaries, av1_state->transfer_characteristics, av1_state->matrix_coefficients, av1_state->color_range)); } } - gf_av1_reset_state(&av1_state, GF_TRUE); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); return GF_OK; #else return GF_NOT_SUPPORTED; @@ -4494,7 +4532,7 @@ GF_Err gf_media_av1_layer_size_get(GF_ISOFile *file, u32 trackNumber, u32 sample { #ifndef GPAC_DISABLE_AV_PARSERS u32 i; - AV1State av1; + AV1State *av1_state; ObuType obu_type; u64 obu_size = 0; u32 hdr_size; @@ -4515,17 +4553,23 @@ GF_Err gf_media_av1_layer_size_get(GF_ISOFile *file, u32 trackNumber, u32 sample return GF_BAD_PARAM; } - gf_av1_init_state(&av1); - av1.config = gf_isom_av1_config_get(file, trackNumber, sdidx); - if (!av1.config) { + GF_SAFEALLOC(av1_state, AV1State); + if (!av1_state) { + gf_isom_sample_del(&samp); + return GF_OUT_OF_MEM; + } + gf_av1_init_state(av1_state); + av1_state->config = gf_isom_av1_config_get(file, trackNumber, sdidx); + if (!av1_state->config) { gf_isom_sample_del(&samp); + gf_free(av1_state); return GF_ISOM_INVALID_FILE; } - for (i=0; iobu_array); i++) { - GF_AV1_OBUArrayEntry *obu = gf_list_get(av1.config->obu_array, i); + for (i=0; iconfig->obu_array); i++) { + GF_AV1_OBUArrayEntry *obu = gf_list_get(av1_state->config->obu_array, i); bs = gf_bs_new(obu->obu, (u32) obu->obu_length, GF_BITSTREAM_READ); - e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, av1_state); gf_bs_del(bs); if (e) break; } @@ -4533,29 +4577,31 @@ GF_Err gf_media_av1_layer_size_get(GF_ISOFile *file, u32 trackNumber, u32 sample if (!e) { bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ); while (gf_bs_available(bs)) { - e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + e = gf_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, av1_state); if (e) break; } gf_bs_del(bs); } gf_isom_sample_del(&samp); - if (op_index > av1.operating_points_count) { - if (av1.config) gf_odf_av1_cfg_del(av1.config); - gf_av1_reset_state(&av1, GF_TRUE); + if (op_index > av1_state->operating_points_count) { + if (av1_state->config) gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); return GF_BAD_PARAM; } for (i=0; i<3; i++) { - if (av1.layer_size[i+1]==av1.layer_size[i]) { + if (av1_state->layer_size[i+1]==av1_state->layer_size[i]) { layer_size[i] = 0; } else { - layer_size[i] = av1.layer_size[i]; + layer_size[i] = av1_state->layer_size[i]; } } - if (av1.config) gf_odf_av1_cfg_del(av1.config); - gf_av1_reset_state(&av1, GF_TRUE); + if (av1_state->config) gf_odf_av1_cfg_del(av1_state->config); + gf_av1_reset_state(av1_state, GF_TRUE); + gf_free(av1_state); return e; #else diff --git a/src/media_tools/media_export.c b/src/media_tools/media_export.c index b0c3f5c023..c75abe2522 100644 --- a/src/media_tools/media_export.c +++ b/src/media_tools/media_export.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Media Tools sub-project @@ -830,14 +830,18 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper) u32 size; Bool is_stdout = 0; FILE *saf_f; - SAFInfo safs[1024]; GF_Err e=GF_OK; if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK; s_count = tot_samp = 0; - mux = gf_saf_mux_new(); count = gf_isom_get_track_count(dumper->file); + + SAFInfo *safs; + safs = gf_malloc(sizeof(SAFInfo) * count); + if (!safs) return GF_OUT_OF_MEM; + memset(safs, 0, sizeof(SAFInfo) * count); + for (i=0; ifile, safs[i].track_num, safs[i].last_sample + 1, &di); if (!samp) { gf_saf_mux_del(mux); + gf_free(safs); return gf_isom_last_error(dumper->file); } @@ -946,6 +952,7 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper) gf_fclose(saf_f); gf_saf_mux_del(mux); + gf_free(safs); return e; #else return GF_NOT_SUPPORTED; diff --git a/src/media_tools/mpd.c b/src/media_tools/mpd.c index 5888450090..659d260c39 100644 --- a/src/media_tools/mpd.c +++ b/src/media_tools/mpd.c @@ -1835,9 +1835,10 @@ static GF_Err gf_m3u8_fill_mpd_struct(MasterPlaylist *pl, const char *m3u8_file, #ifndef GPAC_DISABLE_MEDIA_IMPORT if (elt && import_file) { - GF_MediaImporter import; char *elt_url = elt->init_segment_url ? elt->init_segment_url : elt->url; char *tmp_file = NULL; + GF_MediaImporter *import = gf_malloc(sizeof(GF_MediaImporter)); + if (!import) return GF_OUT_OF_MEM; #ifndef GPAC_DISABLE_NETWORK u64 br_start = elt->init_segment_url ? elt->init_byte_range_start : elt->byte_range_start; @@ -1847,9 +1848,9 @@ static GF_Err gf_m3u8_fill_mpd_struct(MasterPlaylist *pl, const char *m3u8_file, elt_url = gf_url_concatenate(par_url, elt_url); gf_free(par_url); - memset(&import, 0, sizeof(GF_MediaImporter)); - import.trackID = 0; - import.flags = GF_IMPORT_PROBE_ONLY; + memset(import, 0, sizeof(GF_MediaImporter)); + import->trackID = 0; + import->flags = GF_IMPORT_PROBE_ONLY; if (strstr(elt_url, "://") && !strstr(elt_url, "file://")) { tmp_file = strrchr(elt_url, '/'); @@ -1860,12 +1861,12 @@ static GF_Err gf_m3u8_fill_mpd_struct(MasterPlaylist *pl, const char *m3u8_file, #ifndef GPAC_DISABLE_NETWORK e = gf_dm_wget(elt_url, tmp_file, br_start, br_end, NULL); if (e == GF_OK) { - import.in_name = tmp_file; + import->in_name = tmp_file; } #endif } } else { - import.in_name = elt_url; + import->in_name = elt_url; } if (!strstr(elt_url, "://") && !gf_file_exists(elt_url)) { @@ -1873,19 +1874,20 @@ static GF_Err gf_m3u8_fill_mpd_struct(MasterPlaylist *pl, const char *m3u8_file, if (elt_url) gf_free(elt_url); goto retry_import; } - e = gf_media_import(&import); + e = gf_media_import(import); if (e != GF_OK) { k++; if (elt_url) gf_free(elt_url); + gf_free(import); goto try_next_segment; } - if (import.in_name && !pe->bandwidth && !elt->init_segment_url && pe->duration_info) { + if (import->in_name && !pe->bandwidth && !elt->init_segment_url && pe->duration_info) { u64 pos = 0; Double bw; - FILE *t = gf_fopen(import.in_name, "rb"); + FILE *t = gf_fopen(import->in_name, "rb"); if (t) { pos = gf_fsize(t); gf_fclose(t); @@ -1904,26 +1906,27 @@ static GF_Err gf_m3u8_fill_mpd_struct(MasterPlaylist *pl, const char *m3u8_file, if (!pe->codecs) { char *codecs = NULL; - for (k=0; knb_tracks; k++) { + if (strlen(import->tk_info[k].szCodecProfile)) { + gf_dynstrcat(&codecs, import->tk_info[k].szCodecProfile, ","); } } pe->codecs = codecs; } - for (k=0; knb_tracks; k++) { + switch (import->tk_info[k].stream_type) { case GF_STREAM_VISUAL: - width = import.tk_info[k].video_info.width; - height = import.tk_info[k].video_info.height; + width = import->tk_info[k].video_info.width; + height = import->tk_info[k].video_info.height; break; case GF_STREAM_AUDIO: - samplerate = import.tk_info[k].audio_info.sample_rate; - num_channels = import.tk_info[k].audio_info.nb_channels; + samplerate = import->tk_info[k].audio_info.sample_rate; + num_channels = import->tk_info[k].audio_info.nb_channels; break; } } if (elt_url) gf_free(elt_url); + gf_free(import); } #endif GF_SAFEALLOC(rep, GF_MPD_Representation); diff --git a/src/media_tools/mpegts.c b/src/media_tools/mpegts.c index fb6513eed5..a304273a50 100644 --- a/src/media_tools/mpegts.c +++ b/src/media_tools/mpegts.c @@ -3198,7 +3198,8 @@ void gf_m2ts_print_info(GF_M2TS_Demuxer *ts) } #endif -#define M2TS_PROBE_SIZE 188000 +//50 packets max +#define M2TS_PROBE_SIZE 188*50 static Bool gf_m2ts_probe_buffer(char *buf, u32 size) { GF_Err e; diff --git a/src/odf/descriptors.c b/src/odf/descriptors.c index e3a9456f83..38ebaec204 100644 --- a/src/odf/descriptors.c +++ b/src/odf/descriptors.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project @@ -1624,16 +1624,18 @@ GF_EXPORT GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size) { #ifndef GPAC_DISABLE_AV_PARSERS - AV1State state; + AV1State *av1_state; u8 reserved; GF_AV1Config *cfg; if (!size) size = (u32) gf_bs_available(bs); if (!size) return NULL; + GF_SAFEALLOC(av1_state, AV1State); + if (!av1_state) return NULL; cfg = gf_odf_av1_cfg_new(); - gf_av1_init_state(&state); - state.config = cfg; + gf_av1_init_state(av1_state); + av1_state->config = cfg; cfg->marker = gf_bs_read_int(bs, 1); cfg->version = gf_bs_read_int(bs, 7); @@ -1660,6 +1662,7 @@ GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size) if (reserved != 0 || cfg->marker != 1 || cfg->version != 1) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] wrong av1C reserved %d / marker %d / version %d expecting 0 1 1\n", reserved, cfg->marker, cfg->version)); gf_odf_av1_cfg_del(cfg); + gf_free(av1_state); return NULL; } @@ -1671,7 +1674,7 @@ GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size) pos = gf_bs_get_position(bs); obu_size = 0; - if (gf_av1_parse_obu(bs, &obu_type, &obu_size, NULL, &state) != GF_OK) { + if (gf_av1_parse_obu(bs, &obu_type, &obu_size, NULL, av1_state) != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] could not parse AV1 OBU at position "LLU". Leaving parsing.\n", pos)); break; } @@ -1700,8 +1703,9 @@ GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size) } size -= (u32) obu_size; } - gf_av1_reset_state(& state, GF_TRUE); + gf_av1_reset_state(av1_state, GF_TRUE); gf_bs_align(bs); + gf_free(av1_state); return cfg; #else return NULL; diff --git a/src/utils/downloader.c b/src/utils/downloader.c index eb5cddfb59..8432bf5a8d 100644 --- a/src/utils/downloader.c +++ b/src/utils/downloader.c @@ -89,8 +89,7 @@ typedef SSIZE_T ssize_t; #include #define GF_DOWNLOAD_AGENT_NAME "GPAC/"GPAC_VERSION "-rev" GPAC_GIT_REVISION -//let's be agressive with socket buffer size -#define GF_DOWNLOAD_BUFFER_SIZE 131072 +#define GF_DOWNLOAD_BUFFER_SIZE 50000 #define GF_DOWNLOAD_BUFFER_SIZE_LIMIT_RATE GF_DOWNLOAD_BUFFER_SIZE/20 @@ -191,6 +190,10 @@ struct __gf_download_session DownloadedCacheEntry cache_entry; Bool reused_cache_entry, from_cache_only; + u32 http_buf_size; + //we alloc http_buf_size+1 for text dump + char *http_buf; + //mime type, only used when the session is not cached. char *mime_type; GF_List *headers; @@ -2453,11 +2456,13 @@ void gf_dm_sess_del(GF_DownloadSession *sess) #endif gf_mx_del(sess->mx); + if (sess->http_buf) gf_free(sess->http_buf); if (sess->ftask) { sess->ftask->sess = NULL; sess->ftask = NULL; } + gf_free(sess); } @@ -3304,6 +3309,8 @@ static GF_DownloadSession *gf_dm_sess_new_internal(GF_DownloadManager * dm, cons sess->usr_cbk = usr_cbk; sess->creds = NULL; sess->log_name = gf_strdup("HTTP"); + sess->http_buf_size = dm ? dm->read_buf_size : GF_DOWNLOAD_BUFFER_SIZE; + sess->http_buf = gf_malloc(sess->http_buf_size + 1); sess->conn_timeout = gf_opts_get_int("core", "tcp-timeout"); if (!sess->conn_timeout) sess->conn_timeout = 5000; @@ -4065,8 +4072,6 @@ static void gf_dm_connect(GF_DownloadSession *sess) sess->connect_time = (u32) (gf_sys_clock_high_res() - now); GF_LOG(GF_LOG_INFO, GF_LOG_HTTP, ("[%s] Connected to %s:%d\n", sess->log_name, proxy, proxy_port)); gf_dm_sess_notify_state(sess, GF_NETIO_CONNECTED, GF_OK); -// gf_sk_set_buffer_size(sess->sock, GF_TRUE, GF_DOWNLOAD_BUFFER_SIZE); -// gf_sk_set_buffer_size(sess->sock, GF_FALSE, GF_DOWNLOAD_BUFFER_SIZE); } if (sess->status == GF_NETIO_SETUP) @@ -4308,10 +4313,9 @@ GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u64 start_range, u64 end_r #ifdef GPAC_HAS_HTTP2 static void gf_dm_sess_flush_input(GF_DownloadSession *sess) { - char sHTTP[GF_DOWNLOAD_BUFFER_SIZE+1]; u32 res; - sHTTP[0] = 0; - GF_Err e = gf_dm_read_data(sess, sHTTP, GF_DOWNLOAD_BUFFER_SIZE, &res); + sess->http_buf[0] = 0; + GF_Err e = gf_dm_read_data(sess, sess->http_buf, sess->http_buf_size, &res); switch (e) { case GF_IP_NETWORK_EMPTY: case GF_OK: @@ -5421,7 +5425,7 @@ void gf_dm_sess_abort(GF_DownloadSession * sess) \param sHTTP buffer containing the request \return GF_OK if everything went fine, the error otherwise */ -static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { +static GF_Err http_send_headers(GF_DownloadSession *sess) { GF_Err e; GF_NETIO_Parameter par; Bool no_cache = GF_FALSE; @@ -5438,6 +5442,8 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { Bool has_accept, has_connection, has_range, has_agent, has_language, send_profile, has_mime, has_chunk_transfer; assert (sess->status == GF_NETIO_CONNECTED); + char * sHTTP = sess->http_buf; + gf_dm_sess_clear_headers(sess); gf_assert(sess->remaining_data_size == 0); @@ -5877,10 +5883,9 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { \param sHTTP the data buffer \return The error code if any */ -static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) +static GF_Err http_parse_remaining_body(GF_DownloadSession * sess) { GF_Err e; - u32 buf_size = sess->dm ? sess->dm->read_buf_size : GF_DOWNLOAD_BUFFER_SIZE; while (1) { u32 prev_remaining_data_size, size=0, rewrite_size=0; @@ -5896,13 +5901,13 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) //the data remaining from the last buffer (i.e size for chunk that couldn't be read because the buffer does not contain enough bytes) if (sess->remaining_data && sess->remaining_data_size) { - if (sess->remaining_data_size >= buf_size) { + if (sess->remaining_data_size >= sess->http_buf_size) { GF_LOG(GF_LOG_ERROR, GF_LOG_HTTP, ("[%s] No HTTP chunk header found for %d bytes, assuming broken chunk transfer and aborting\n", sess->log_name, sess->remaining_data_size)); return GF_NON_COMPLIANT_BITSTREAM; } - memcpy(sHTTP, sess->remaining_data, sess->remaining_data_size); + memcpy(sess->http_buf, sess->remaining_data, sess->remaining_data_size); } - e = gf_dm_read_data(sess, sHTTP + sess->remaining_data_size, buf_size - sess->remaining_data_size, &size); + e = gf_dm_read_data(sess, sess->http_buf + sess->remaining_data_size, sess->http_buf_size - sess->remaining_data_size, &size); if ((e != GF_IP_CONNECTION_CLOSED) && (!size || e == GF_IP_NETWORK_EMPTY)) { if (!sess->total_size && !sess->chunked && (gf_sys_clock_high_res() - sess->start_time > 5000000)) { sess->total_size = sess->bytes_done; @@ -5923,7 +5928,7 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) h2_flush_data(sess, GF_FALSE); } else #endif - gf_dm_data_received(sess, (u8 *) sHTTP, size, GF_FALSE, NULL, NULL); + gf_dm_data_received(sess, (u8 *) sess->http_buf, size, GF_FALSE, NULL, NULL); } if ( ( (len == 0) && sess->use_cache_file) || sess->bytes_done) { @@ -5946,7 +5951,7 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) prev_remaining_data_size = sess->remaining_data_size; sess->remaining_data_size = 0; - sHTTP[size + prev_remaining_data_size] = 0; + sess->http_buf[size + prev_remaining_data_size] = 0; #ifdef GPAC_HAS_HTTP2 if (sess->h2_sess) { @@ -5957,14 +5962,14 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) } } else #endif - gf_dm_data_received(sess, (u8 *) sHTTP, size + prev_remaining_data_size, GF_FALSE, &rewrite_size, NULL); + gf_dm_data_received(sess, (u8 *) sess->http_buf, size + prev_remaining_data_size, GF_FALSE, &rewrite_size, NULL); if (sess->chunked) gf_dm_sess_estimate_chunk_rate(sess, rewrite_size); /*socket empty*/ - if (size < buf_size) { + if (size < sess->http_buf_size) { return GF_OK; } } @@ -6017,7 +6022,7 @@ static u32 http_parse_method(const char *comp) \param sess The session \param sHTTP the data buffer */ -static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) +static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess) { GF_NETIO_Parameter par; s32 bytesRead, BodyStart; @@ -6037,6 +6042,9 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) Bool upgrade_to_http2 = GF_FALSE; #endif + char *sHTTP = sess->http_buf; + sHTTP[0] = 0; + if (sess->creds && sess->creds->req_state) { if (sess->creds->req_state==GF_CREDS_STATE_PENDING) return GF_OK; @@ -6140,7 +6148,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) } #endif - buf_size = sess->dm ? sess->dm->read_buf_size : GF_DOWNLOAD_BUFFER_SIZE; + buf_size = sess->http_buf_size; //always set start time to the time at last attempt reply parsing sess->start_time = gf_sys_clock_high_res(); @@ -6152,8 +6160,6 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->chunk_bytes = 0; sess->cumulated_chunk_rate = 0; - sHTTP[0] = 0; - while (1) { Bool probe = (!bytesRead || (sess->flags & GF_NETIO_SESSION_NO_BLOCK) ) ? GF_TRUE : GF_FALSE; e = gf_dm_read_data(sess, sHTTP + bytesRead, buf_size - bytesRead, &res); @@ -6586,6 +6592,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->last_fetch_time = sess->request_start_time = gf_sys_clock_high_res(); } + par.msg_type = GF_NETIO_PARSE_REPLY; par.error = GF_OK; par.reply = sess->rsp_code; @@ -6663,7 +6670,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) break; //does not fit in our buffer, too bad we'll kill the connection - if (bytesRead == GF_DOWNLOAD_BUFFER_SIZE) + if (bytesRead == buf_size) break; } @@ -6711,7 +6718,6 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) } #endif - if (sess->server_mode) { if (ContentLength) { par.data = sHTTP + BodyStart; @@ -6740,6 +6746,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->connection_close = connection_closed; gf_assert(sess->rsp_code); + switch (sess->rsp_code) { //100 continue case 100: @@ -6820,11 +6827,10 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->status = GF_NETIO_DATA_EXCHANGE; if (! (sess->flags & GF_NETIO_SESSION_NOT_THREADED) || sess->force_data_write_callback) { - char file_cache_buff[16544]; s32 read = 0; total_size = gf_cache_get_cache_filesize(sess->cache_entry); do { - read = (s32) gf_fread(file_cache_buff, 16384, f); + read = (s32) gf_fread(sess->http_buf, sess->http_buf_size, f); if (read > 0) { sess->bytes_done += read; sess->total_size = total_size; @@ -6833,7 +6839,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) par.msg_type = GF_NETIO_DATA_EXCHANGE; par.error = GF_EOS; par.reply = 2; - par.data = file_cache_buff; + par.data = sess->http_buf; gf_dm_sess_user_io(sess, &par); } } while ( read > 0); @@ -7086,8 +7092,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) */ void http_do_requests(GF_DownloadSession *sess) { - char sHTTP[GF_DOWNLOAD_BUFFER_SIZE+1]; - sHTTP[0] = 0; + sess->http_buf[0] = 0; if (sess->reused_cache_entry) { //main session is done downloading, notify - to do we should send progress events on this session also ... @@ -7110,16 +7115,16 @@ void http_do_requests(GF_DownloadSession *sess) switch (sess->status) { case GF_NETIO_CONNECTED: if (sess->server_mode) { - wait_for_header_and_parse(sess, sHTTP); + wait_for_header_and_parse(sess); } else { - http_send_headers(sess, sHTTP); + http_send_headers(sess); } break; case GF_NETIO_WAIT_FOR_REPLY: if (sess->server_mode) { - http_send_headers(sess, sHTTP); + http_send_headers(sess); } else { - wait_for_header_and_parse(sess, sHTTP); + wait_for_header_and_parse(sess); } break; case GF_NETIO_DATA_EXCHANGE: @@ -7144,7 +7149,7 @@ void http_do_requests(GF_DownloadSession *sess) } sess->reassigned = GF_FALSE; } - http_parse_remaining_body(sess, sHTTP); + http_parse_remaining_body(sess); break; default: break; @@ -7301,195 +7306,6 @@ const char *gf_dm_sess_get_resource_name(GF_DownloadSession *dnload) } -#if 0 //unused -/*! -\brief Get session original resource url - * - *Returns the original resource URL before any redirection associated with the session -\param sess the download session -\return the associated URL - */ -const char *gf_dm_sess_get_original_resource_name(GF_DownloadSession *dnload) -{ - if (dnload) return dnload->orig_url_before_redirect ? dnload->orig_url_before_redirect : dnload->orig_url; - return NULL; -} - -/*! -\brief fetch session status - * - *Fetch the session current status -\param sess the download session -\return the session status*/ -u32 gf_dm_sess_get_status(GF_DownloadSession *dnload) -{ - return dnload ? dnload->status : GF_NETIO_STATE_ERROR; -} - - -/*! -\brief Reset session - * - *Resets the session for new processing of the same url -\param sess the download session -\return error code if any - */ -GF_Err gf_dm_sess_reset(GF_DownloadSession *sess) -{ - if (!sess) - return GF_BAD_PARAM; - sess->status = GF_NETIO_SETUP; - sess->needs_range = GF_FALSE; - sess->range_start = sess->range_end = 0; - sess->bytes_done = sess->bytes_per_sec = 0; - if (sess->init_data) gf_free(sess->init_data); - sess->init_data = NULL; - sess->init_data_size = 0; - SET_LAST_ERR(GF_OK) - sess->total_size = 0; - sess->start_time = 0; - sess->start_time_utc = 0; - sess->max_chunk_size = 0; - sess->max_chunk_bytes_per_sec = 0; - return GF_OK; -} - -/*! - * Get a range of a cache entry file -\param sess The session -\param startOffset The first byte of the request to get -\param endOffset The last byte of request to get -\param The temporary name for the file created to have a range of the file - */ -const char * gf_cache_get_cache_filename_range( const GF_DownloadSession * sess, u64 startOffset, u64 endOffset ) { - u32 i, count; - if (!sess || !sess->dm || endOffset < startOffset) - return NULL; - count = gf_list_count(sess->dm->partial_downloads); - for (i = 0 ; i < count ; i++) { - GF_PartialDownload * pd = (GF_PartialDownload*)gf_list_get(sess->dm->partial_downloads, i); - gf_assert( pd->filename && pd->url); - if (!strcmp(pd->url, sess->orig_url) && pd->startOffset == startOffset && pd->endOffset == endOffset) { - /* File already created, just return the file */ - return pd->filename; - } - } - { - /* Not found, we are gonna create the file */ - char * newFilename; - GF_PartialDownload * partial; - FILE * fw, *fr; - u32 maxLen; - const char * orig = gf_cache_get_cache_filename(sess->cache_entry); - if (orig == NULL) - return NULL; - /* 22 if 1G + 1G + 2 dashes */ - maxLen = (u32) strlen(orig) + 22; - newFilename = (char*)gf_malloc( maxLen ); - if (newFilename == NULL) - return NULL; - snprintf(newFilename, maxLen, "%s " LLU LLU, orig, startOffset, endOffset); - fw = gf_fopen(newFilename, "wb"); - if (!fw) { - GF_LOG(GF_LOG_ERROR, GF_LOG_HTTP, ("[CACHE] Cannot open partial cache file %s for write\n", newFilename)); - gf_free( newFilename ); - return NULL; - } - fr = gf_fopen(orig, "rb"); - if (!fr) { - GF_LOG(GF_LOG_ERROR, GF_LOG_HTTP, ("[CACHE] Cannot open full cache file %s\n", orig)); - gf_free( newFilename ); - gf_fclose( fw ); - } - /* Now, we copy ! */ - { - char copyBuff[GF_DOWNLOAD_BUFFER_SIZE+1]; - s64 read, write, total; - total = endOffset - startOffset; - read = gf_fseek(fr, startOffset, SEEK_SET); - if (read != startOffset) { - GF_LOG(GF_LOG_ERROR, GF_LOG_HTTP, ("[CACHE] Cannot seek at right start offset in %s\n", orig)); - gf_fclose( fr ); - gf_fclose( fw ); - gf_free( newFilename ); - return NULL; - } - do { - read = gf_fread(copyBuff, MIN(sizeof(copyBuff), (size_t) total), fr); - if (read > 0) { - total-= read; - write = gf_fwrite(copyBuff, (size_t) read, fw); - if (write != read) { - /* Something bad happened */ - gf_fclose( fw ); - gf_fclose (fr ); - gf_free( newFilename ); - return NULL; - } - } else { - if (read < 0) { - gf_fclose( fw ); - gf_fclose( fr ); - gf_free( newFilename ); - return NULL; - } - } - } while (total > 0); - gf_fclose( fr ); - gf_fclose (fw); - partial = (GF_PartialDownload*)gf_malloc( sizeof(GF_PartialDownload)); - if (partial == NULL) { - gf_free(newFilename); - return NULL; - } - partial->filename = newFilename; - partial->url = sess->orig_url; - partial->endOffset = endOffset; - partial->startOffset = startOffset; - gf_list_add(sess->dm->partial_downloads, partial); - return newFilename; - } - } -} - -/*! - * Reassigns session flags and callbacks. This is only possible if the session is not threaded. -\param sess The session -\param flags The new flags for the session - if flags is 0xFFFFFFFF, existing flags are not modified -\param user_io The new callback function -\param cbk The new user data to be used in the callback function -\param GF_OK or error - */ -GF_Err gf_dm_sess_reassign(GF_DownloadSession *sess, u32 flags, gf_dm_user_io user_io, void *cbk) -{ - /*shall only be called for non-threaded sessions!! */ - if (sess->th) - return GF_BAD_PARAM; - - if (flags == 0xFFFFFFFF) { - sess->user_proc = user_io; - sess->usr_cbk = cbk; - return GF_OK; - } - - if (sess->flags & GF_DOWNLOAD_SESSION_USE_SSL) flags |= GF_DOWNLOAD_SESSION_USE_SSL; - sess->flags = flags; - if (sess->flags & GF_NETIO_SESSION_NOTIFY_DATA) - sess->force_data_write_callback = GF_TRUE; - - sess->user_proc = user_io; - sess->usr_cbk = cbk; - sess->reassigned = sess->init_data ? GF_TRUE : GF_FALSE; - sess->num_retry = SESSION_RETRY_COUNT; - - if (sess->status==GF_NETIO_DISCONNECTED) - sess->status = GF_NETIO_SETUP; - - /*threaded session shall be started with gf_dm_sess_process*/ - return GF_OK; -} -#endif - GF_EXPORT void gf_dm_set_data_rate(GF_DownloadManager *dm, u32 rate_in_bits_per_sec) @@ -7505,10 +7321,6 @@ void gf_dm_set_data_rate(GF_DownloadManager *dm, u32 rate_in_bits_per_sec) //temporary store of maxrate gf_opts_set_key("temp", "maxrate", opt); - dm->read_buf_size = GF_DOWNLOAD_BUFFER_SIZE; - //when rate is limited, use smaller smaller read size - if (dm->limit_data_rate) dm->read_buf_size = GF_DOWNLOAD_BUFFER_SIZE_LIMIT_RATE; - #ifdef GPAC_ENABLE_COVERAGE if (gf_sys_is_cov_mode()) { dm_exceeds_cap_rate(dm); From a9fc9489b67852840d1cb92d4af2b87f72ebdd6b Mon Sep 17 00:00:00 2001 From: jeanlf Date: Wed, 16 Oct 2024 09:52:45 +0200 Subject: [PATCH 2/5] fixed memleak --- src/media_tools/isom_tools.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/media_tools/isom_tools.c b/src/media_tools/isom_tools.c index a9d19ae2b0..87caf86284 100644 --- a/src/media_tools/isom_tools.c +++ b/src/media_tools/isom_tools.c @@ -2297,6 +2297,7 @@ GF_Err gf_media_split_svc(GF_ISOFile *file, u32 track, Bool splitAll) if (first_DTS_track) gf_free(first_DTS_track); if (buffer) gf_free(buffer); if (is_subseq_pps) gf_free(is_subseq_pps); + if (avc_state) gf_free(avc_state); gf_isom_set_nalu_extract_mode(file, track, cur_extract_mode); return e; #else From 1b501e228490ed450697dc1d6bf10b31350cfd35 Mon Sep 17 00:00:00 2001 From: jeanlf Date: Wed, 16 Oct 2024 13:05:25 +0200 Subject: [PATCH 3/5] lower stack size requirements down to 8k --- applications/gpac/compositor_tools.c | 3 +- applications/mp4box/fileimport.c | 4 +- applications/mp4box/live.c | 2 +- applications/mp4box/mp4box.c | 37 +- include/gpac/events_constants.h | 5 +- modules/pulseaudio/pulseaudio.c | 10 +- share/nodejs/src/gpac_napi.c | 224 +---- share/scripts/vout.js | 64 +- src/bifs/field_encode.c | 4 +- src/filters/dec_j2k.c | 13 +- src/filters/dec_ttxt.c | 42 +- src/filters/dmx_ogg.c | 6 +- src/filters/isoffin_load.c | 1152 +++++++++++++------------- src/filters/jsfilter.c | 226 +---- src/filters/reframe_latm.c | 7 +- src/ietf/sdp.c | 124 +-- src/isomedia/isom_store.c | 3 +- src/media_tools/isom_hinter.c | 60 +- src/media_tools/isom_tools.c | 93 +-- src/media_tools/media_export.c | 21 +- src/media_tools/media_import.c | 31 +- src/media_tools/mpegts.c | 4 +- src/quickjs/quickjs.c | 227 ++--- src/scene_manager/encode_isom.c | 64 +- src/scene_manager/loader_bt.c | 59 +- src/scene_manager/scene_engine.c | 52 +- src/utils/base_encoding.c | 7 +- src/utils/xml_parser.c | 18 +- 28 files changed, 1092 insertions(+), 1470 deletions(-) diff --git a/applications/gpac/compositor_tools.c b/applications/gpac/compositor_tools.c index 43cdd3228c..0e6b228331 100644 --- a/applications/gpac/compositor_tools.c +++ b/applications/gpac/compositor_tools.c @@ -1225,9 +1225,10 @@ Bool mp4c_task() return GF_FALSE; } +static char szBuf[8192]; + Bool mp4c_handle_prompt(u8 char_val) { - char szBuf[8192]; MP4C_Command cmdtype = get_gui_cmd(char_val); switch (cmdtype) { case MP4C_OPEN: diff --git a/applications/mp4box/fileimport.c b/applications/mp4box/fileimport.c index 4d67d32db9..6726ecf8ae 100644 --- a/applications/mp4box/fileimport.c +++ b/applications/mp4box/fileimport.c @@ -3323,11 +3323,11 @@ GF_Err cat_playlist(GF_ISOFile *dest, char *playlistName, u32 import_flags, GF_F e = GF_OK; while (!feof(pl)) { - char szLine[10000]; + char szLine[1000]; char *url; u32 len; szLine[0] = 0; - if (gf_fgets(szLine, 10000, pl) == NULL) break; + if (gf_fgets(szLine, 1000, pl) == NULL) break; if (szLine[0]=='#') continue; len = (u32) strlen(szLine); while (len && strchr("\r\n \t", szLine[len-1])) { diff --git a/applications/mp4box/live.c b/applications/mp4box/live.c index 53a37303e5..206a0a7afc 100644 --- a/applications/mp4box/live.c +++ b/applications/mp4box/live.c @@ -324,6 +324,7 @@ static RTPChannel *set_broadcast_params(LiveSession *livesess, u16 esid, u32 per return rtpch; } +char szBuf[8192]; int live_session(int argc, char **argv) { GF_Err e; @@ -332,7 +333,6 @@ int live_session(int argc, char **argv) char *dst = NULL; const char *ifce_addr = NULL; char *sdp_name = "session.sdp"; - char szBuf[8192]; u16 dst_port = 7000; u32 load_type=0; u32 check; diff --git a/applications/mp4box/mp4box.c b/applications/mp4box/mp4box.c index f411ca51a7..44864b859d 100644 --- a/applications/mp4box/mp4box.c +++ b/applications/mp4box/mp4box.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / mp4box application @@ -4392,20 +4392,27 @@ static u32 do_import_sub() possibly for later export (e.g. when converting SRT to TTXT, ...) */ #ifndef GPAC_DISABLE_MEDIA_IMPORT GF_Err e; - GF_MediaImporter import; + GF_MediaImporter *import; + /* Prepare the importer */ + GF_SAFEALLOC(import, GF_MediaImporter); + if (!import) { + M4_LOG(GF_LOG_ERROR, ("Allocation failed for importer\n")); + return mp4box_cleanup(1); + } + file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL); if (timescale && file) gf_isom_set_timescale(file, timescale); - memset(&import, 0, sizeof(GF_MediaImporter)); - import.dest = file; - import.in_name = inName; + import->dest = file; + import->in_name = inName; /* Start the import */ - e = gf_media_import(&import); + e = gf_media_import(import); if (e) { M4_LOG(GF_LOG_ERROR, ("Error importing %s: %s\n", inName, gf_error_to_string(e))); gf_isom_delete(file); gf_file_delete("ttxt_convert"); + gf_free(import); return mp4box_cleanup(1); } /* Prepare the export */ @@ -4424,6 +4431,7 @@ static u32 do_import_sub() /* Clean the importer */ gf_isom_delete(file); gf_file_delete("ttxt_convert"); + gf_free(import); if (e) { M4_LOG(GF_LOG_ERROR, ("Error converting %s: %s\n", inName, gf_error_to_string(e))); return mp4box_cleanup(1); @@ -6398,17 +6406,22 @@ int mp4box_main(int argc, char **argv) #ifndef GPAC_DISABLE_MEDIA_IMPORT if(dvbhdemux) { - GF_MediaImporter import; + GF_MediaImporter *import; file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL); - memset(&import, 0, sizeof(GF_MediaImporter)); - import.dest = file; - import.in_name = inName; - import.flags = GF_IMPORT_MPE_DEMUX; - e = gf_media_import(&import); + GF_SAFEALLOC(import, GF_MediaImporter); + if (import) { + import->dest = file; + import->in_name = inName; + import->flags = GF_IMPORT_MPE_DEMUX; + e = gf_media_import(import); + } else { + e = GF_OUT_OF_MEM; + } if (e) { M4_LOG(GF_LOG_ERROR, ("Error importing %s: %s\n", inName, gf_error_to_string(e))); gf_isom_delete(file); gf_file_delete("ttxt_convert"); + if (import) gf_free(import); return mp4box_cleanup(1); } } diff --git a/include/gpac/events_constants.h b/include/gpac/events_constants.h index de5429ca5e..2ded375e33 100644 --- a/include/gpac/events_constants.h +++ b/include/gpac/events_constants.h @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2022 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Events management @@ -706,9 +706,6 @@ typedef enum { /*non-dom keys, used in LASeR*/ GF_KEY_CELL_SOFT1, /*soft1 key of cell phones*/ GF_KEY_CELL_SOFT2, /*soft2 key of cell phones*/ - - /*for joystick handling*/ - GF_KEY_JOYSTICK } GF_KeyCode; diff --git a/modules/pulseaudio/pulseaudio.c b/modules/pulseaudio/pulseaudio.c index c40b7c2528..4adc36f671 100644 --- a/modules/pulseaudio/pulseaudio.c +++ b/modules/pulseaudio/pulseaudio.c @@ -33,6 +33,8 @@ #include #include +#define BUFF_SIZE 8192 + typedef struct { pa_simple *playback_handle; @@ -41,6 +43,7 @@ typedef struct const char *output_description; u32 errors; u32 consecutive_zero_reads; + char data[BUFF_SIZE]; } PulseAudioContext; static void @@ -137,12 +140,9 @@ PulseAudio_Configure(GF_AudioOutput *dr, u32 *SampleRate, u32 *NbChannels, u32 * return GF_OK; } -#define BUFF_SIZE 8192 - static void PulseAudio_WriteAudio (GF_AudioOutput * dr) { - char data[BUFF_SIZE]; int written = 0; int pa_error = 0; PulseAudioContext *ctx = (PulseAudioContext *) dr->opaque; @@ -157,7 +157,7 @@ PulseAudio_WriteAudio (GF_AudioOutput * dr) } return; } - written = dr->FillBuffer (dr->audio_renderer, data, BUFF_SIZE / 4); + written = dr->FillBuffer (dr->audio_renderer, ctx->data, BUFF_SIZE / 4); if (written <= 0) { ctx->consecutive_zero_reads++; @@ -171,7 +171,7 @@ PulseAudio_WriteAudio (GF_AudioOutput * dr) return; } ctx->consecutive_zero_reads = 0; - /*written = */pa_simple_write (ctx->playback_handle, data, written, &pa_error); + /*written = */pa_simple_write (ctx->playback_handle, ctx->data, written, &pa_error); if (pa_error != 0) { if (ctx->errors < 1) diff --git a/share/nodejs/src/gpac_napi.c b/share/nodejs/src/gpac_napi.c index 7521fb8ccb..6493d76713 100644 --- a/share/nodejs/src/gpac_napi.c +++ b/share/nodejs/src/gpac_napi.c @@ -207,6 +207,21 @@ napi_value gpac_sys_clock_high_res(napi_env env, napi_callback_info info) return val; } +napi_value gpac_sys_keyname(napi_env env, napi_callback_info info) +{ + napi_value val; +#ifndef GPAC_DISABLE_SVG + const char *gf_dom_get_friendly_name(u32 key_identifier); + + NARG_ARGS(1, 1) + NARG_S32(code, 0, 0); + NAPI_CALL( napi_create_string_utf8(env, gf_dom_get_friendly_name(code), NAPI_AUTO_LENGTH, &val) ); +#else + NAPI_CALL( napi_create_string_utf8(env, "unknwon", NAPI_AUTO_LENGTH, &val) ); +#endif + return val; +} + void gpac_rmt_callback_exec(napi_env env, GPAC_NAPI *gpac) { napi_status status; @@ -4803,6 +4818,7 @@ napi_value Init(napi_env env, napi_value exports) DEF_FUN("set_args", gpac_set_args); DEF_FUN("sys_clock", gpac_sys_clock); DEF_FUN("sys_clock_high_res", gpac_sys_clock_high_res); + DEF_FUN("sys_keyname", gpac_sys_keyname); DEF_FUN("set_rmt_fun", gpac_set_rmt_fun); DEF_FUN("rmt_send", gpac_rmt_send); @@ -5014,214 +5030,6 @@ static napi_status InitConstants(napi_env env, napi_value exports) DEF_CONST(GF_EVENT_CODEC_SLOW) DEF_CONST(GF_EVENT_CODEC_OK) - DEF_CONST(GF_KEY_UNIDENTIFIED) - DEF_CONST(GF_KEY_ACCEPT) - DEF_CONST(GF_KEY_AGAIN) - DEF_CONST(GF_KEY_ALLCANDIDATES) - DEF_CONST(GF_KEY_ALPHANUM) - DEF_CONST(GF_KEY_ALT) - DEF_CONST(GF_KEY_ALTGRAPH) - DEF_CONST(GF_KEY_APPS) - DEF_CONST(GF_KEY_ATTN) - DEF_CONST(GF_KEY_BROWSERBACK) - DEF_CONST(GF_KEY_BROWSERFAVORITES) - DEF_CONST(GF_KEY_BROWSERFORWARD) - DEF_CONST(GF_KEY_BROWSERHOME) - DEF_CONST(GF_KEY_BROWSERREFRESH) - DEF_CONST(GF_KEY_BROWSERSEARCH) - DEF_CONST(GF_KEY_BROWSERSTOP) - DEF_CONST(GF_KEY_CAPSLOCK) - DEF_CONST(GF_KEY_CLEAR) - DEF_CONST(GF_KEY_CODEINPUT) - DEF_CONST(GF_KEY_COMPOSE) - DEF_CONST(GF_KEY_CONTROL) - DEF_CONST(GF_KEY_CRSEL) - DEF_CONST(GF_KEY_CONVERT) - DEF_CONST(GF_KEY_COPY) - DEF_CONST(GF_KEY_CUT) - DEF_CONST(GF_KEY_DOWN) - DEF_CONST(GF_KEY_END) - DEF_CONST(GF_KEY_ENTER) - DEF_CONST(GF_KEY_ERASEEOF) - DEF_CONST(GF_KEY_EXECUTE) - DEF_CONST(GF_KEY_EXSEL) - DEF_CONST(GF_KEY_F1) - DEF_CONST(GF_KEY_F2) - DEF_CONST(GF_KEY_F3) - DEF_CONST(GF_KEY_F4) - DEF_CONST(GF_KEY_F5) - DEF_CONST(GF_KEY_F6) - DEF_CONST(GF_KEY_F7) - DEF_CONST(GF_KEY_F8) - DEF_CONST(GF_KEY_F9) - DEF_CONST(GF_KEY_F10) - DEF_CONST(GF_KEY_F11) - DEF_CONST(GF_KEY_F12) - DEF_CONST(GF_KEY_F13) - DEF_CONST(GF_KEY_F14) - DEF_CONST(GF_KEY_F15) - DEF_CONST(GF_KEY_F16) - DEF_CONST(GF_KEY_F17) - DEF_CONST(GF_KEY_F18) - DEF_CONST(GF_KEY_F19) - DEF_CONST(GF_KEY_F20) - DEF_CONST(GF_KEY_F21) - DEF_CONST(GF_KEY_F22) - DEF_CONST(GF_KEY_F23) - DEF_CONST(GF_KEY_F24) - DEF_CONST(GF_KEY_FINALMODE) - DEF_CONST(GF_KEY_FIND) - DEF_CONST(GF_KEY_FULLWIDTH) - DEF_CONST(GF_KEY_HALFWIDTH) - DEF_CONST(GF_KEY_HANGULMODE) - DEF_CONST(GF_KEY_HANJAMODE) - DEF_CONST(GF_KEY_HELP) - DEF_CONST(GF_KEY_HIRAGANA) - DEF_CONST(GF_KEY_HOME) - DEF_CONST(GF_KEY_INSERT) - DEF_CONST(GF_KEY_JAPANESEHIRAGANA) - DEF_CONST(GF_KEY_JAPANESEKATAKANA) - DEF_CONST(GF_KEY_JAPANESEROMAJI) - DEF_CONST(GF_KEY_JUNJAMODE) - DEF_CONST(GF_KEY_KANAMODE) - DEF_CONST(GF_KEY_KANJIMODE) - DEF_CONST(GF_KEY_KATAKANA) - DEF_CONST(GF_KEY_LAUNCHAPPLICATION1) - DEF_CONST(GF_KEY_LAUNCHAPPLICATION2) - DEF_CONST(GF_KEY_LAUNCHMAIL) - DEF_CONST(GF_KEY_LEFT) - DEF_CONST(GF_KEY_META) - DEF_CONST(GF_KEY_MEDIANEXTTRACK) - DEF_CONST(GF_KEY_MEDIAPLAYPAUSE) - DEF_CONST(GF_KEY_MEDIAPREVIOUSTRACK) - DEF_CONST(GF_KEY_MEDIASTOP) - DEF_CONST(GF_KEY_MODECHANGE) - DEF_CONST(GF_KEY_NONCONVERT) - DEF_CONST(GF_KEY_NUMLOCK) - DEF_CONST(GF_KEY_PAGEDOWN) - DEF_CONST(GF_KEY_PAGEUP) - DEF_CONST(GF_KEY_PASTE) - DEF_CONST(GF_KEY_PAUSE) - DEF_CONST(GF_KEY_PLAY) - DEF_CONST(GF_KEY_PREVIOUSCANDIDATE) - DEF_CONST(GF_KEY_PRINTSCREEN) - DEF_CONST(GF_KEY_PROCESS) - DEF_CONST(GF_KEY_PROPS) - DEF_CONST(GF_KEY_RIGHT) - DEF_CONST(GF_KEY_ROMANCHARACTERS) - DEF_CONST(GF_KEY_SCROLL) - DEF_CONST(GF_KEY_SELECT) - DEF_CONST(GF_KEY_SELECTMEDIA) - DEF_CONST(GF_KEY_SHIFT) - DEF_CONST(GF_KEY_STOP) - DEF_CONST(GF_KEY_UP) - DEF_CONST(GF_KEY_UNDO) - DEF_CONST(GF_KEY_VOLUMEDOWN) - DEF_CONST(GF_KEY_VOLUMEMUTE) - DEF_CONST(GF_KEY_VOLUMEUP) - DEF_CONST(GF_KEY_WIN) - DEF_CONST(GF_KEY_ZOOM) - DEF_CONST(GF_KEY_BACKSPACE) - DEF_CONST(GF_KEY_TAB) - DEF_CONST(GF_KEY_CANCEL) - DEF_CONST(GF_KEY_ESCAPE) - DEF_CONST(GF_KEY_SPACE) - DEF_CONST(GF_KEY_EXCLAMATION) - DEF_CONST(GF_KEY_QUOTATION) - DEF_CONST(GF_KEY_NUMBER) - DEF_CONST(GF_KEY_DOLLAR) - DEF_CONST(GF_KEY_AMPERSAND) - DEF_CONST(GF_KEY_APOSTROPHE) - DEF_CONST(GF_KEY_LEFTPARENTHESIS) - DEF_CONST(GF_KEY_RIGHTPARENTHESIS) - DEF_CONST(GF_KEY_STAR) - DEF_CONST(GF_KEY_PLUS) - DEF_CONST(GF_KEY_COMMA) - DEF_CONST(GF_KEY_HYPHEN) - DEF_CONST(GF_KEY_FULLSTOP) - DEF_CONST(GF_KEY_SLASH) - DEF_CONST(GF_KEY_0) - DEF_CONST(GF_KEY_1) - DEF_CONST(GF_KEY_2) - DEF_CONST(GF_KEY_3) - DEF_CONST(GF_KEY_4) - DEF_CONST(GF_KEY_5) - DEF_CONST(GF_KEY_6) - DEF_CONST(GF_KEY_7) - DEF_CONST(GF_KEY_8) - DEF_CONST(GF_KEY_9) - DEF_CONST(GF_KEY_COLON) - DEF_CONST(GF_KEY_SEMICOLON) - DEF_CONST(GF_KEY_LESSTHAN) - DEF_CONST(GF_KEY_EQUALS) - DEF_CONST(GF_KEY_GREATERTHAN) - DEF_CONST(GF_KEY_QUESTION) - DEF_CONST(GF_KEY_AT) - DEF_CONST(GF_KEY_A) - DEF_CONST(GF_KEY_B) - DEF_CONST(GF_KEY_C) - DEF_CONST(GF_KEY_D) - DEF_CONST(GF_KEY_E) - DEF_CONST(GF_KEY_F) - DEF_CONST(GF_KEY_G) - DEF_CONST(GF_KEY_H) - DEF_CONST(GF_KEY_I) - DEF_CONST(GF_KEY_J) - DEF_CONST(GF_KEY_K) - DEF_CONST(GF_KEY_L) - DEF_CONST(GF_KEY_M) - DEF_CONST(GF_KEY_N) - DEF_CONST(GF_KEY_O) - DEF_CONST(GF_KEY_P) - DEF_CONST(GF_KEY_Q) - DEF_CONST(GF_KEY_R) - DEF_CONST(GF_KEY_S) - DEF_CONST(GF_KEY_T) - DEF_CONST(GF_KEY_U) - DEF_CONST(GF_KEY_V) - DEF_CONST(GF_KEY_W) - DEF_CONST(GF_KEY_X) - DEF_CONST(GF_KEY_Y) - DEF_CONST(GF_KEY_Z) - DEF_CONST(GF_KEY_LEFTSQUAREBRACKET) - DEF_CONST(GF_KEY_BACKSLASH) - DEF_CONST(GF_KEY_RIGHTSQUAREBRACKET) - DEF_CONST(GF_KEY_CIRCUM) - DEF_CONST(GF_KEY_UNDERSCORE) - DEF_CONST(GF_KEY_GRAVEACCENT) - DEF_CONST(GF_KEY_LEFTCURLYBRACKET) - DEF_CONST(GF_KEY_PIPE) - DEF_CONST(GF_KEY_RIGHTCURLYBRACKET) - DEF_CONST(GF_KEY_DEL) - DEF_CONST(GF_KEY_INVERTEXCLAMATION) - DEF_CONST(GF_KEY_DEADGRAVE) - DEF_CONST(GF_KEY_DEADEACUTE) - DEF_CONST(GF_KEY_DEADCIRCUM) - DEF_CONST(GF_KEY_DEADTILDE) - DEF_CONST(GF_KEY_DEADMACRON) - DEF_CONST(GF_KEY_DEADBREVE) - DEF_CONST(GF_KEY_DEADABOVEDOT) - DEF_CONST(GF_KEY_DEADDIARESIS) - DEF_CONST(GF_KEY_DEADRINGABOVE) - DEF_CONST(GF_KEY_DEADDOUBLEACUTE) - DEF_CONST(GF_KEY_DEADCARON) - DEF_CONST(GF_KEY_DEADCEDILLA) - DEF_CONST(GF_KEY_DEADOGONEK) - DEF_CONST(GF_KEY_DEADIOTA) - DEF_CONST(GF_KEY_EURO) - DEF_CONST(GF_KEY_DEADVOICESOUND) - DEF_CONST(GF_KEY_DEADSEMIVOICESOUND) - DEF_CONST(GF_KEY_CHANNELUP) - DEF_CONST(GF_KEY_CHANNELDOWN) - DEF_CONST(GF_KEY_TEXT) - DEF_CONST(GF_KEY_INFO) - DEF_CONST(GF_KEY_EPG) - DEF_CONST(GF_KEY_RECORD) - DEF_CONST(GF_KEY_BEGINPAGE) - DEF_CONST(GF_KEY_CELL_SOFT1) - DEF_CONST(GF_KEY_CELL_SOFT2) - DEF_CONST(GF_KEY_JOYSTICK) - DEF_CONST(GF_KEY_MOD_SHIFT) DEF_CONST(GF_KEY_MOD_CTRL) DEF_CONST(GF_KEY_MOD_ALT) diff --git a/share/scripts/vout.js b/share/scripts/vout.js index 1f4de4e8d0..4fa3fa81ad 100644 --- a/share/scripts/vout.js +++ b/share/scripts/vout.js @@ -3,7 +3,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2020-2023 + * Copyright (c) Telecom ParisTech 2020-2024 * All rights reserved * * This file is part of GPAC / vout default ui @@ -397,7 +397,7 @@ function update_help() shortcuts.forEach( (key, index) => { if (use_libcaca && (index>10)) return; - args.push( '' + sys.keyname(key.code) + ': ' + key.desc); + args.push( key.code + ': ' + key.desc); }); if (audio_only) text.fontsize = 20; @@ -992,20 +992,20 @@ function toggle_overlay() } let shortcuts = [ - { "code": GF_KEY_B, "desc": "speeds up by 2"}, - { "code": GF_KEY_V, "desc": "speeds down by 2"}, - { "code": GF_KEY_N, "desc": "normal play speed"}, - { "code": GF_KEY_SPACE, "desc": "pause/resume"}, - { "code": GF_KEY_S, "desc": "step one frame"}, - { "code": GF_KEY_RIGHT, "desc": "seek forward by 1%, 10% if alt down, 30% if ctrl down"}, - { "code": GF_KEY_LEFT, "desc": "seek backward "}, - { "code": GF_KEY_UP, "desc": "seek forward by 30s, 10m if alt down, 30m if ctrl down"}, - { "code": GF_KEY_DOWN, "desc": "seek backward"}, - { "code": GF_KEY_I, "desc": "show info and statistics"}, - { "code": GF_KEY_P, "desc": "show playback info"}, - { "code": GF_KEY_F, "desc": "fullscreen mode"}, - { "code": GF_KEY_M, "desc": "flip video"}, - { "code": GF_KEY_R, "desc": "rotate video by 90 degree"}, + { "code": "B", "desc": "speeds up by 2"}, + { "code": "V", "desc": "speeds down by 2"}, + { "code": "N", "desc": "normal play speed"}, + { "code": "space", "desc": "pause/resume"}, + { "code": "S", "desc": "step one frame"}, + { "code": "Right", "desc": "seek forward by 1%, 10% if alt down, 30% if ctrl down"}, + { "code": "Left", "desc": "seek backward "}, + { "code": "Up", "desc": "seek forward by 30s, 10m if alt down, 30m if ctrl down"}, + { "code": "Down", "desc": "seek backward"}, + { "code": "I", "desc": "show info and statistics"}, + { "code": "P", "desc": "show playback info"}, + { "code": "F", "desc": "fullscreen mode"}, + { "code": "M", "desc": "flip video"}, + { "code": "R", "desc": "rotate video by 90 degree"}, ]; function set_speed(speed) @@ -1030,55 +1030,55 @@ function process_keyboard(evt) } if(evt.window != win_id) return true; - switch (evt.keycode) { - case GF_KEY_B: + switch (sys.keyname(evt.keycode)) { + case 'B': if (evt.keymods & GF_KEY_MOD_SHIFT) speed *= 1.2; else speed *= 2; set_speed(speed); return true; - case GF_KEY_V: + case 'V': if (evt.keymods & GF_KEY_MOD_SHIFT) speed /= 1.2; else speed /= 2; set_speed(speed); return true; - case GF_KEY_N: + case 'N': speed = 1; set_speed(speed); return true; - case GF_KEY_SPACE: + case 'space': paused = !paused; set_speed(paused ? 0 : speed); return true; - case GF_KEY_S: + case 'S': paused = 2; vout.update('step', '1'); if (aout) aout.update('speed', '0'); check_duration(); return true; - case GF_KEY_RIGHT: + case 'Right': if (interactive_scene) return false; do_seek(1, evt.keymods, false); return true; - case GF_KEY_LEFT: + case 'Left': if (interactive_scene) return false; do_seek(-1, evt.keymods, false); return true; - case GF_KEY_UP: + case 'Up': if (interactive_scene) return false; do_seek(1, evt.keymods, true); return true; - case GF_KEY_DOWN: + case 'Down': if (interactive_scene) return false; do_seek(-1, evt.keymods, true); return true; - case GF_KEY_F: + case 'F': if (audio_only) return; fullscreen = !fullscreen; vout.update('fullscreen', ''+fullscreen); return true; - case GF_KEY_H: + case 'H': if (overlay_type==OL_AUTH) break; //hide player if (audio_only && (overlay_type==OL_PLAY)) { @@ -1092,7 +1092,7 @@ function process_keyboard(evt) toggle_overlay(); } return true; - case GF_KEY_I: + case 'I': if (overlay_type==OL_AUTH) break; //hide player if (audio_only && (overlay_type==OL_PLAY)) { @@ -1106,7 +1106,7 @@ function process_keyboard(evt) toggle_overlay(); } return true; - case GF_KEY_P: + case 'P': if (overlay_type==OL_AUTH) break; //do not untoggle for audio only if (audio_only) return; @@ -1114,7 +1114,7 @@ function process_keyboard(evt) if (!ol_visible) init_wnd=true; toggle_overlay(); return true; - case GF_KEY_R: + case 'R': if (audio_only) return; rot = vout.get_arg('vrot'); rot++; @@ -1124,7 +1124,7 @@ function process_keyboard(evt) else if (rot==2) vout.update('vrot', '180'); else vout.update('vrot', '270'); return true; - case GF_KEY_M: + case 'M': if (audio_only) return; flip = vout.get_arg('vflip'); flip++; diff --git a/src/bifs/field_encode.c b/src/bifs/field_encode.c index 1ee5ccd049..db97367b9f 100644 --- a/src/bifs/field_encode.c +++ b/src/bifs/field_encode.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / BIFS codec sub-project @@ -94,7 +94,7 @@ GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *no case GF_SG_VRML_SFSTRING: if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { u32 size, val; - char buf[4096]; + char buf[2048]; char *res_src = NULL; const char *src = ((SFString*)field->far_ptr)->buffer; FILE *f; diff --git a/src/filters/dec_j2k.c b/src/filters/dec_j2k.c index 9fbda374b0..eba65744f3 100644 --- a/src/filters/dec_j2k.c +++ b/src/filters/dec_j2k.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2022 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / openjpeg2k decoder filter @@ -283,7 +283,7 @@ static GF_Err j2kdec_process(GF_Filter *filter) { u32 i, w, wr, h, hr, wh, size, pf; u8 *data, *buffer; - opj_dparameters_t parameters; /* decompression parameters */ + opj_dparameters_t *parameters; /* decompression parameters */ #if OPENJP2 s32 res; opj_codec_t *codec = NULL; @@ -317,8 +317,10 @@ static GF_Err j2kdec_process(GF_Filter *filter) start_offset = 8; } + GF_SAFEALLOC(parameters, opj_dparameters_t); + if (!parameters) return GF_OUT_OF_MEM; /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); + opj_set_default_decoder_parameters(parameters); #if OPENJP2 codec = opj_create_decompress(OPJ_CODEC_J2K); @@ -329,7 +331,7 @@ static GF_Err j2kdec_process(GF_Filter *filter) if (res) res = opj_set_warning_handler(codec, warning_callback, NULL); if (res) res = opj_set_error_handler(codec, error_callback, NULL); - if (res) res = opj_setup_decoder(codec, ¶meters); + if (res) res = opj_setup_decoder(codec, parameters); stream = opj_stream_default_create(OPJ_STREAM_READ); opj_stream_set_read_function(stream, j2kdec_stream_read); @@ -367,13 +369,14 @@ static GF_Err j2kdec_process(GF_Filter *filter) opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); /* setup the decoder decoding parameters using the current image and user parameters */ - opj_setup_decoder(dinfo, ¶meters); + opj_setup_decoder(dinfo, parameters); cio = opj_cio_open((opj_common_ptr)dinfo, data+start_offset, size-start_offset); /* decode the stream and fill the image structure */ image = opj_decode_with_info(dinfo, cio, &cinfo); #endif + gf_free(parameters); if (!image) { #if OPENJP2 opj_stream_destroy(stream); diff --git a/src/filters/dec_ttxt.c b/src/filters/dec_ttxt.c index ba1bad0688..83751cdb8c 100644 --- a/src/filters/dec_ttxt.c +++ b/src/filters/dec_ttxt.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / 3GPP/MPEG4 text renderer filter @@ -601,7 +601,7 @@ typedef struct layout to handle new lines and proper scrolling*/ } TTDTextChunk; -static void ttd_new_text_chunk(GF_TTXTDec *ctx, GF_TextSampleDescriptor *tsd, M_Form *form, u16 *utf16_txt, TTDTextChunk *tc) +static void ttd_new_text_chunk(GF_TTXTDec *ctx, GF_TextSampleDescriptor *tsd, M_Form *form, u16 *utf16_txt, u32 utf_alloc_size, TTDTextChunk *tc) { GF_Node *txt_model, *n2, *txt_material; M_Text *text; @@ -730,9 +730,8 @@ static void ttd_new_text_chunk(GF_TTXTDec *ctx, GF_TextSampleDescriptor *tsd, M_ if (i+1==tc->end_char) i++; if (i!=start_char) { - char szLine[5000]; u32 len; - s16 wsChunk[5000], *sp; + s16 *sp; /*splitting lines, duplicate node*/ @@ -755,17 +754,23 @@ static void ttd_new_text_chunk(GF_TTXTDec *ctx, GF_TextSampleDescriptor *tsd, M_ if (tc->has_blink && txt_material) gf_list_add(ctx->blink_nodes, txt_material); - memcpy(wsChunk, &utf16_txt[start_char], sizeof(s16)*(i-start_char)); - wsChunk[i-start_char] = 0; - sp = &wsChunk[0]; - len = gf_utf8_wcstombs(szLine, 5000, (const unsigned short **) &sp); - if (len == GF_UTF8_FAIL) len = 0; - szLine[len] = 0; - if (len && (szLine[len-1]=='\r')) - szLine[len-1] = 0; - - gf_sg_vrml_mf_append(&text->string, GF_SG_VRML_MFSTRING, (void **) &st); - st->buffer = gf_strdup(szLine); + s16 *wsChunk = gf_malloc(sizeof(s16)*utf_alloc_size); + char *szLine = gf_malloc(utf_alloc_size*2); + if (wsChunk && szLine) { + memcpy(wsChunk, &utf16_txt[start_char], sizeof(s16)*(i-start_char)); + wsChunk[i-start_char] = 0; + sp = &wsChunk[0]; + len = gf_utf8_wcstombs(szLine, utf_alloc_size*2, (const unsigned short **) &sp); + if (len == GF_UTF8_FAIL) len = 0; + szLine[len] = 0; + if (len && (szLine[len-1]=='\r')) + szLine[len-1] = 0; + + gf_sg_vrml_mf_append(&text->string, GF_SG_VRML_MFSTRING, (void **) &st); + st->buffer = gf_strdup(szLine); + } + if (szLine) gf_free(szLine); + if (wsChunk) gf_free(wsChunk); } start_char = i+1; if (new_line) { @@ -856,7 +861,6 @@ static void ttd_apply_sample(GF_TTXTDec *ctx, GF_TextSample *txt, u32 sample_des GF_BoxRecord br; M_Material2D *n; M_Form *form; - u16 utf16_text[5000]; u32 char_offset, char_count; GF_List *chunks; TTDTextChunk *tc; @@ -1020,6 +1024,7 @@ static void ttd_apply_sample(GF_TTXTDec *ctx, GF_TextSample *txt, u32 sample_des ctx->tr_scroll = NULL; } + u16 *utf16_text = gf_malloc(sizeof(u16) * ((txt->len/2)*2 + 2) ); if (is_utf_16) { memcpy((char *) utf16_text, txt->text, sizeof(char) * txt->len); ((char *) utf16_text)[txt->len] = 0; @@ -1027,7 +1032,7 @@ static void ttd_apply_sample(GF_TTXTDec *ctx, GF_TextSample *txt, u32 sample_des char_count = txt->len / 2; } else { char *p = txt->text; - char_count = gf_utf8_mbstowcs(utf16_text, 2500, (const char **) &p); + char_count = gf_utf8_mbstowcs(utf16_text, txt->len+1, (const char **) &p); if (char_count == GF_UTF8_FAIL) char_count = 0; } @@ -1090,10 +1095,11 @@ static void ttd_apply_sample(GF_TTXTDec *ctx, GF_TextSample *txt, u32 sample_des while (gf_list_count(chunks)) { tc = (TTDTextChunk*)gf_list_get(chunks, 0); gf_list_rem(chunks, 0); - ttd_new_text_chunk(ctx, td, form, utf16_text, tc); + ttd_new_text_chunk(ctx, td, form, utf16_text, (u32) sizeof(u16)*(txt->len+1), tc); gf_free(tc); } gf_list_del(chunks); + gf_free(utf16_text); if (form->groupsIndex.count && (form->groupsIndex.vals[form->groupsIndex.count-1] != -1)) ttd_add_line(form); diff --git a/src/filters/dmx_ogg.c b/src/filters/dmx_ogg.c index 99ad36b106..0a59c8fc45 100644 --- a/src/filters/dmx_ogg.c +++ b/src/filters/dmx_ogg.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2022 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / XIPH OGG demux filter @@ -413,7 +413,7 @@ static void oggdmx_check_dur(GF_Filter *filter, GF_OGGDmxCtx *ctx) recompute_ts = 0; max_gran = 0; while (1) { - char buf[10000]; + char buf[2000]; while (ogg_sync_pageout(&oy, &oggpage) != 1 ) { char *buffer; u32 bytes; @@ -421,7 +421,7 @@ static void oggdmx_check_dur(GF_Filter *filter, GF_OGGDmxCtx *ctx) if (gf_feof(stream)) break; - bytes = (u32) gf_fread(buf, 10000, stream); + bytes = (u32) gf_fread(buf, 2000, stream); if (!bytes) break; buffer = ogg_sync_buffer(&oy, bytes); memcpy(buffer, buf, bytes); diff --git a/src/filters/isoffin_load.c b/src/filters/isoffin_load.c index 2f09dfb41c..5ec6e8d80c 100644 --- a/src/filters/isoffin_load.c +++ b/src/filters/isoffin_load.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / ISOBMFF reader filter @@ -139,18 +139,549 @@ static void isor_export_ref(ISOMReader *read, ISOMChannel *ch, u32 rtype, char * } } -static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 stsd_idx, u32 streamtype, Bool use_iod) +static void isor_setup_channel(ISOMReader *read, ISOMChannel *ch, u32 track, u32 streamtype, Bool use_iod, u32 esid, u32 depends_on_id, u32 ocr_es_id) { - u32 w, h, sr, nb_ch, nb_bps, codec_id, depends_on_id, esid, avg_rate, max_rate, buffer_size, sample_count, max_size, base_track, audio_fmt, pix_fmt; - GF_ESD *an_esd; - const char *mime, *encoding, *stxtcfg, *namespace, *schemaloc, *mime_cfg; + u32 base_track; + GF_Language *lang_desc = NULL; + //first setup, creation of PID and channel + Bool use_sidx_dur = GF_FALSE; + Bool external_base = GF_FALSE; + Bool has_scalable_layers = GF_FALSE; + GF_FilterPid *pid; + GF_Err e; + Bool use_lhvc = GF_FALSE; + Bool use_tx3g=GF_FALSE; #if !defined(GPAC_DISABLE_ISOM_WRITE) u8 *tk_template; u32 tk_template_size; #endif + + gf_isom_get_reference(read->mov, track, GF_ISOM_REF_BASE, 1, &base_track); + + //pass on all configs to detect scalability presence and TX3G as we need to export some vars for all configs + for (u32 stsd_idx=0; stsd_idxmov, track); stsd_idx++) { + u32 m_subtype = gf_isom_get_media_subtype(read->mov, track, stsd_idx); + if (m_subtype == GF_ISOM_SUBTYPE_TX3G) use_tx3g = GF_TRUE; + + if (base_track) { + u32 base_subtype=0; + if (read->smode==MP4DMX_SINGLE) + depends_on_id = 0; + + switch (m_subtype) { + case GF_ISOM_SUBTYPE_LHV1: + case GF_ISOM_SUBTYPE_LHE1: + use_lhvc = GF_TRUE; + base_subtype = gf_isom_get_media_subtype(read->mov, base_track, stsd_idx); + switch (base_subtype) { + case GF_ISOM_SUBTYPE_HVC1: + case GF_ISOM_SUBTYPE_HEV1: + case GF_ISOM_SUBTYPE_HVC2: + case GF_ISOM_SUBTYPE_HEV2: + break; + default: + external_base=GF_TRUE; + break; + } + } + if (external_base) { + depends_on_id = gf_isom_get_track_id(read->mov, base_track); + has_scalable_layers = GF_TRUE; + } else { + switch (gf_isom_get_hevc_lhvc_type(read->mov, track, stsd_idx)) { + case GF_ISOM_HEVCTYPE_HEVC_LHVC: + case GF_ISOM_HEVCTYPE_LHVC_ONLY: + has_scalable_layers = GF_TRUE; + break; + //this is likely temporal sublayer of base + case GF_ISOM_HEVCTYPE_HEVC_ONLY: + has_scalable_layers = GF_FALSE; + if (gf_isom_get_reference_count(read->mov, track, GF_ISOM_REF_SCAL)<=0) { + depends_on_id = gf_isom_get_track_id(read->mov, base_track); + } + break; + default: + break; + } + } + } else { + switch (gf_isom_get_hevc_lhvc_type(read->mov, track, stsd_idx)) { + case GF_ISOM_HEVCTYPE_HEVC_LHVC: + case GF_ISOM_HEVCTYPE_LHVC_ONLY: + has_scalable_layers = GF_TRUE; + break; + default: + break; + } + + if (!has_scalable_layers) { + u32 i; + GF_ISOTrackID track_id = gf_isom_get_track_id(read->mov, track); + for (i=0; imov); i++) { + if (gf_isom_get_reference_count(read->mov, i+1, GF_ISOM_REF_BASE)>=0) { + GF_ISOTrackID tkid; + gf_isom_get_reference_ID(read->mov, i+1, GF_ISOM_REF_BASE, 1, &tkid); + if (tkid==track_id) { + has_scalable_layers = GF_TRUE; + break; + } + } + } + } + } + } + + if (base_track && !ocr_es_id) { + ocr_es_id = gf_isom_get_track_id(read->mov, base_track); + } + if (!ocr_es_id) ocr_es_id = esid; + + //OK declare PID + pid = gf_filter_pid_new(read->filter); + if (read->pid) + gf_filter_pid_copy_properties(pid, read->pid); + + gf_filter_pid_set_property(pid, GF_PROP_PID_ID, &PROP_UINT(esid)); + gf_filter_pid_set_property(pid, GF_PROP_PID_CLOCK_ID, &PROP_UINT(ocr_es_id)); + if (depends_on_id && (depends_on_id != esid)) + gf_filter_pid_set_property(pid, GF_PROP_PID_DEPENDENCY_ID, &PROP_UINT(depends_on_id)); + + if (gf_isom_get_track_count(read->mov)>1) { + char szPName[101]; + szPName[100]=0; + const char *szST = gf_stream_type_name(streamtype); + snprintf(szPName, 100, "%c%d", szST[0], esid); + gf_filter_pid_set_name(pid, szPName); + } + + //MPEG-4 systems present + if (use_iod) + gf_filter_pid_set_property(pid, GF_PROP_PID_ESID, &PROP_UINT(esid)); + + if (gf_isom_is_track_in_root_od(read->mov, track) && !read->lightp) { + switch (streamtype) { + case GF_STREAM_SCENE: + case GF_STREAM_OD: + gf_filter_pid_set_property(pid, GF_PROP_PID_IN_IOD, &PROP_BOOL(GF_TRUE)); + break; + } + } + + gf_filter_pid_set_property(pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(streamtype)); + gf_filter_pid_set_property(pid, GF_PROP_PID_TIMESCALE, &PROP_UINT( gf_isom_get_media_timescale(read->mov, track) ) ); + + if (!gf_sys_is_test_mode()) + gf_filter_pid_set_property(pid, GF_PROP_PID_TRACK_NUM, &PROP_UINT(track) ); + + //create our channel + ch = isor_create_channel(read, pid, track, 0, (use_lhvc) ? GF_TRUE : GF_FALSE); + + if (lang_desc) { + char *lang=NULL; + gf_isom_get_media_language(read->mov, track, &lang); + //s32 idx = gf_lang_find(lang); + gf_filter_pid_set_property(pid, GF_PROP_PID_LANGUAGE, &PROP_STRING( lang )); + if (lang) gf_free(lang); + gf_odf_desc_del((GF_Descriptor *)lang_desc); + lang_desc = NULL; + } + + ch->streamType = streamtype; +// ch->clock_id = ocr_es_id; + + if (!read->lightp) { + if (has_scalable_layers) + gf_filter_pid_set_property(pid, GF_PROP_PID_SCALABLE, &PROP_BOOL(GF_TRUE)); + + if (gf_isom_get_reference_count(read->mov, track, GF_ISOM_REF_SABT)>0) { + gf_filter_pid_set_property(pid, GF_PROP_PID_TILE_BASE, &PROP_BOOL(GF_TRUE)); + } + else if (gf_isom_get_reference_count(read->mov, track, GF_ISOM_REF_SUBPIC)>0) { + gf_filter_pid_set_property(pid, GF_PROP_PID_TILE_BASE, &PROP_BOOL(GF_TRUE)); + } + + + if (!use_lhvc) + isor_export_ref(read, ch, GF_ISOM_REF_SCAL, "isom:scal"); + isor_export_ref(read, ch, GF_ISOM_REF_SABT, "isom:sabt"); + isor_export_ref(read, ch, GF_ISOM_REF_TBAS, "isom:tbas"); + isor_export_ref(read, ch, GF_ISOM_REF_SUBPIC, "isom:subp"); + } + + if (read->lightp) { + ch->duration = gf_isom_get_track_duration_orig(read->mov, ch->track); + } else { + ch->duration = gf_isom_get_track_duration(read->mov, ch->track); + } + if (!ch->duration) { + ch->duration = gf_isom_get_duration(read->mov); + } + u32 sample_count = gf_isom_get_sample_count(read->mov, ch->track); + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (read->frag_type && !read->input_loaded) { + u32 ts; + u64 dur; + if (gf_isom_get_sidx_duration(read->mov, &dur, &ts)==GF_OK) { + dur *= read->timescale; + dur /= ts; + ch->duration = dur; + use_sidx_dur = GF_TRUE; + sample_count = 0; + } + } +#endif + + if (!read->mem_load_mode || ch->duration) { + //if no edit list (whether complex or simple TS offset) and no sidx, use media duration + if (!ch->has_edit_list && !use_sidx_dur && !ch->ts_offset) { + //no specific edit list type but edit present, use the duration in the edit + if (gf_isom_get_edits_count(read->mov, ch->track)) { + gf_filter_pid_set_property(pid, GF_PROP_PID_DURATION, &PROP_FRAC64_INT(ch->duration, read->timescale)); + } else { + u64 dur = gf_isom_get_media_duration(read->mov, ch->track); + gf_filter_pid_set_property(pid, GF_PROP_PID_DURATION, &PROP_FRAC64_INT(dur, ch->timescale)); + } + } + //otherwise trust track duration + else { + gf_filter_pid_set_property(pid, GF_PROP_PID_DURATION, &PROP_FRAC64_INT(ch->duration, read->timescale)); + } + gf_filter_pid_set_property(pid, GF_PROP_PID_NB_FRAMES, &PROP_UINT(sample_count)); + } + + if (sample_count && (streamtype==GF_STREAM_VISUAL)) { + u64 mdur = gf_isom_get_media_duration(read->mov, track); + //if ts_offset is negative (skip), update media dur before computing fps + if (!gf_sys_old_arch_compat()) { + u32 sdur = gf_isom_get_avg_sample_delta(read->mov, ch->track); + if (sdur) { + mdur = sdur; + } else { + if (ch->ts_offset<0) + mdur -= (u32) -ch->ts_offset; + mdur /= sample_count; + } + } else { + mdur /= sample_count; + } + gf_filter_pid_set_property(pid, GF_PROP_PID_FPS, &PROP_FRAC_INT(ch->timescale, (u32) mdur)); + } + + Double track_dur = (Double) (s64) ch->duration; + track_dur /= read->timescale; + //move channel duration in media timescale + ch->duration = (u64) (track_dur * ch->timescale); + + + //set stream subtype + u32 mtype = gf_isom_get_media_type(read->mov, track); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_SUBTYPE, &PROP_4CC(mtype) ); + + if (!read->mem_load_mode) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_MEDIA_DATA_SIZE, &PROP_LONGUINT(gf_isom_get_media_data_size(read->mov, track) ) ); + } + //in no cache mode, depending on fetch speed we may have fetched a fragment or not, resulting in has_rap set + //always for HAS_SYNC to false + else if (gf_sys_is_test_mode() && !sample_count) { + gf_filter_pid_set_property(pid, GF_PROP_PID_HAS_SYNC, &PROP_BOOL(GF_FALSE) ); + } + + if (read->lightp) goto props_done; + + u32 cst_size = gf_isom_get_constant_sample_size(read->mov, track); + if (cst_size) + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_FRAME_SIZE, &PROP_UINT(cst_size)); + + //mem mode, cannot read backwards + if (read->mem_load_mode) { + const GF_PropertyValue *p = gf_filter_pid_get_property(read->pid, GF_PROP_PID_PLAYBACK_MODE); + if (!p) + gf_filter_pid_set_property(pid, GF_PROP_PID_PLAYBACK_MODE, &PROP_UINT(GF_PLAYBACK_MODE_FASTFORWARD) ); + } else { + gf_filter_pid_set_property(pid, GF_PROP_PID_PLAYBACK_MODE, &PROP_UINT(GF_PLAYBACK_MODE_REWIND) ); + } + + GF_PropertyValue brands; + brands.type = GF_PROP_4CC_LIST; + u32 major_brand=0; + gf_isom_get_brand_info(read->mov, &major_brand, NULL, &brands.value.uint_list.nb_items); + brands.value.uint_list.vals = (u32 *) gf_isom_get_brands(read->mov); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_BRANDS, &brands); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_MBRAND, &PROP_4CC(major_brand) ); + + //we cannot expose average size/dur in mem mode with fragmented files (sample_count=0) + u32 max_size=0; + if (sample_count) { + max_size = gf_isom_get_max_sample_size(read->mov, ch->track); + if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_MAX_FRAME_SIZE, &PROP_UINT(max_size) ); + + max_size = gf_isom_get_avg_sample_size(read->mov, ch->track); + if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_AVG_FRAME_SIZE, &PROP_UINT(max_size) ); + + max_size = gf_isom_get_max_sample_delta(read->mov, ch->track); + if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_MAX_TS_DELTA, &PROP_UINT(max_size) ); + + max_size = gf_isom_get_max_sample_cts_offset(read->mov, ch->track); + if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_MAX_CTS_OFFSET, &PROP_UINT(max_size) ); + + max_size = gf_isom_get_constant_sample_duration(read->mov, ch->track); + if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_CONSTANT_DURATION, &PROP_UINT(max_size) ); + } + + + u32 media_pl=0; + if (streamtype==GF_STREAM_VISUAL) { + media_pl = gf_isom_get_pl_indication(read->mov, GF_ISOM_PL_VISUAL); + } else if (streamtype==GF_STREAM_AUDIO) { + media_pl = gf_isom_get_pl_indication(read->mov, GF_ISOM_PL_AUDIO); + } + if (media_pl && (media_pl!=0xFF) ) gf_filter_pid_set_property(pid, GF_PROP_PID_PROFILE_LEVEL, &PROP_UINT(media_pl) ); + +#if !defined(GPAC_DISABLE_ISOM_WRITE) + e = gf_isom_get_track_template(read->mov, ch->track, &tk_template, &tk_template_size); + if (e == GF_OK) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_TEMPLATE, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); + } else { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] Failed to serialize track box: %s\n", gf_error_to_string(e) )); + } + + e = gf_isom_get_trex_template(read->mov, ch->track, &tk_template, &tk_template_size); + if (e == GF_OK) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TREX_TEMPLATE, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); + } + + e = gf_isom_get_raw_user_data(read->mov, &tk_template, &tk_template_size); + if (e==GF_OK) { + if (tk_template_size) + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_UDTA, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); + } else { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] Failed to serialize moov UDTA box: %s\n", gf_error_to_string(e) )); + } +#endif + + GF_Fraction64 moov_time; + moov_time.num = gf_isom_get_duration(read->mov); + moov_time.den = gf_isom_get_timescale(read->mov); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_MOVIE_TIME, &PROP_FRAC64(moov_time) ); + + + u32 i, w, h; + s32 tx, ty; + s16 l; + gf_isom_get_track_layout_info(read->mov, ch->track, &w, &h, &tx, &ty, &l); + if (w && h) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_WIDTH, &PROP_UINT(w) ); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_HEIGHT, &PROP_UINT(h) ); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_TRANS_X, &PROP_SINT(tx) ); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_TRANS_Y, &PROP_SINT(ty) ); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ZORDER, &PROP_SINT(l) ); + } + if (use_tx3g) { + u32 m_w = w; + u32 m_h = h; + for (i=0; imov); i++) { + switch (gf_isom_get_media_type(read->mov, i+1)) { + case GF_ISOM_MEDIA_SCENE: + case GF_ISOM_MEDIA_VISUAL: + case GF_ISOM_MEDIA_AUXV: + case GF_ISOM_MEDIA_PICT: + gf_isom_get_track_layout_info(read->mov, i+1, &w, &h, &tx, &ty, &l); + if (w>m_w) m_w = w; + if (h>m_h) m_h = h; + break; + default: + break; + } + } + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_WIDTH_MAX, &PROP_UINT(m_w) ); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_HEIGHT_MAX, &PROP_UINT(m_h) ); + char *tx3g_config_sdp = NULL; + for (i=0; imov, ch->track); i++) { + u8 *tx3g; + u32 l1; + u32 tx3g_len, len; + e = gf_isom_text_get_encoded_tx3g(read->mov, ch->track, i+1, GF_RTP_TX3G_SIDX_OFFSET, &tx3g, &tx3g_len); + if (e==GF_OK) { + char buffer[2000]; + len = gf_base64_encode(tx3g, tx3g_len, buffer, 2000); + gf_free(tx3g); + buffer[len] = 0; + + l1 = tx3g_config_sdp ? (u32) strlen(tx3g_config_sdp) : 0; + tx3g_config_sdp = gf_realloc(tx3g_config_sdp, len+3+l1); + tx3g_config_sdp[l1] = 0; + if (i) strcat(tx3g_config_sdp, ", "); + strcat(tx3g_config_sdp, buffer); + } + } + if (tx3g_config_sdp) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT, &PROP_STRING_NO_COPY(tx3g_config_sdp) ); + } + } + + u32 idx=0; + while (1) { + u32 data_len, int_val2, flags; + u64 int_val; + const char *name; + const u8 *data; + GF_ISOiTunesTag itag; + u32 itype = 0; + s32 tag_idx; + + e = gf_isom_apple_enum_tag(read->mov, idx, &itag, &data, &data_len, &int_val, &int_val2, &flags); + if (e) break; + idx++; + + //do not expose tool + if (!gf_sys_is_test_mode() && (itag == GF_ISOM_ITUNE_TOOL)) + continue; + + tag_idx = gf_itags_find_by_itag(itag); + if (tag_idx>=0) + itype = gf_itags_get_type(tag_idx); + + name = gf_itags_get_name(tag_idx); + switch (itype) { + case GF_ITAG_BOOL: + gf_filter_pid_set_property_str(ch->pid, name, &PROP_BOOL((Bool) int_val ) ); + break; + case GF_ITAG_INT8: + case GF_ITAG_INT16: + case GF_ITAG_INT32: + gf_filter_pid_set_property_str(ch->pid, name, &PROP_UINT((u32) int_val ) ); + break; + case GF_ITAG_INT64: + gf_filter_pid_set_property_str(ch->pid, name, &PROP_LONGUINT(int_val) ); + break; + case GF_ITAG_FRAC8: + case GF_ITAG_FRAC6: + gf_filter_pid_set_property_str(ch->pid, name, &PROP_FRAC_INT((s32) int_val, int_val2) ); + break; + case GF_ITAG_FILE: + if (data && data_len) + gf_filter_pid_set_property_str(ch->pid, name, &PROP_DATA((u8 *)data, data_len) ); + break; + default: + if (data && data_len) { + if (gf_utf8_is_legal(data, data_len)) + gf_filter_pid_set_property_str(ch->pid, name, &PROP_STRING(data) ); + else + gf_filter_pid_set_property_str(ch->pid, name, &PROP_DATA((u8 *)data, data_len) ); + } + break; + } + } + + if (gf_sys_old_arch_compat()) { + Bool gf_isom_has_time_offset_table(GF_ISOFile *the_file, u32 trackNumber); + if (gf_isom_has_time_offset_table(read->mov, ch->track)) + gf_filter_pid_set_property_str(ch->pid, "isom_force_ctts", &PROP_BOOL(GF_TRUE) ); + } + if (read->nodata==2) + gf_filter_pid_set_property_str(ch->pid, "nodata", &PROP_BOOL(GF_TRUE) ); + + if (!gf_sys_is_test_mode()) { + u32 nb_udta, alt_grp=0; + const char *hdlr = NULL; + gf_isom_get_handler_name(read->mov, ch->track, &hdlr); + if (hdlr) + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_HANDLER, &PROP_STRING(hdlr)); + + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_FLAGS, &PROP_UINT( gf_isom_get_track_flags(read->mov, ch->track) )); + + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_FLAGS, &PROP_UINT( gf_isom_get_track_flags(read->mov, ch->track) )); + + gf_isom_get_track_switch_group_count(read->mov, ch->track, &alt_grp, NULL); + if (alt_grp) + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_ALT_GROUP, &PROP_UINT( alt_grp )); + + + if (streamtype==GF_STREAM_VISUAL) { + GF_PropertyValue p; + u32 vals[9]; + memset(vals, 0, sizeof(u32)*9); + memset(&p, 0, sizeof(GF_PropertyValue)); + p.type = GF_PROP_SINT_LIST; + p.value.uint_list.nb_items = 9; + p.value.uint_list.vals = vals; + gf_isom_get_track_matrix(read->mov, ch->track, vals); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_MATRIX, &p); + } + + + nb_udta = gf_isom_get_udta_count(read->mov, ch->track); + if (nb_udta) { + for (i=0; imov, ch->track, i+1, &type, &uuid); + nb_items = gf_isom_get_user_data_count(read->mov, ch->track, type, uuid); + //we only export 4CC udta boxes + if (!type) continue; + + for (j=0; jmov, ch->track, type, uuid, j+1, &udta, &udta_size); + if (!udta || !udta_size) continue; + if (nb_items>1) + snprintf(szName, 30, "udta_%s_%d", gf_4cc_to_str(type), j+1); + else + snprintf(szName, 30, "udta_%s", gf_4cc_to_str(type)); + szName[30]=0; + if (gf_utf8_is_legal(udta, udta_size)) { + if (!udta[udta_size-1]) { + gf_filter_pid_set_property_dyn(ch->pid, szName, &PROP_STRING_NO_COPY(udta)); + } else { + char *data = gf_malloc(udta_size+1); + memcpy(data, udta, udta_size); + data[udta_size]=0; + gf_filter_pid_set_property_dyn(ch->pid, szName, &PROP_STRING_NO_COPY(data)); + gf_free(udta); + } + } else { + gf_filter_pid_set_property_dyn(ch->pid, szName, &PROP_DATA_NO_COPY(udta, udta_size)); + } + } + } + } + + //delcare track groups + u32 idx=0; + while (1) { + char szTK[100]; + u32 track_group_type, track_group_id; + if (!gf_isom_enum_track_group(read->mov, ch->track, &idx, &track_group_type, &track_group_id)) break; + sprintf(szTK, "tkgp_%s", gf_4cc_to_str(track_group_type)); + gf_filter_pid_set_property_dyn(ch->pid, szTK, &PROP_SINT(track_group_id)); + } + } + +props_done: + + if (read->sigfrag) { +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + u64 start, end; + if (gf_isom_get_root_sidx_offsets(read->mov, &start, &end)) { + if (end) + gf_filter_pid_set_property(ch->pid, GF_PROP_PCK_SIDX_RANGE, &PROP_FRAC64_INT(start , end)); + } +#endif + if (!read->frag_type) { + gf_filter_pid_set_property_str(ch->pid, "nofrag", &PROP_BOOL(GF_TRUE)); + } + } +} + +static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 stsd_idx, u32 streamtype, Bool use_iod) +{ + u32 w, h, sr, nb_ch, nb_bps, codec_id, depends_on_id, esid, avg_rate, max_rate, buffer_size, audio_fmt, pix_fmt; + GF_ESD *an_esd; + const char *mime, *encoding, *stxtcfg, *namespace, *schemaloc, *mime_cfg; GF_Language *lang_desc = NULL; - Bool external_base=GF_FALSE; - Bool has_scalable_layers = GF_FALSE; u8 *dsi = NULL, *enh_dsi = NULL; u32 dsi_size = 0, enh_dsi_size = 0; Double track_dur=0; @@ -158,7 +689,7 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 u32 base_tile_track=0; u64 ch_layout=0; Bool srd_full_frame=GF_FALSE; - u32 mtype, m_subtype; + u32 m_subtype; GF_GenericSampleDescription *udesc = NULL; GF_Err e; u32 ocr_es_id; @@ -547,572 +1078,63 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 //first setup, creation of PID and channel if (!ch) { - Bool use_sidx_dur = GF_FALSE; - GF_FilterPid *pid; first_config = GF_TRUE; - - gf_isom_get_reference(read->mov, track, GF_ISOM_REF_BASE, 1, &base_track); - - if (base_track) { - u32 base_subtype=0; - if (read->smode==MP4DMX_SINGLE) - depends_on_id = 0; - - switch (m_subtype) { - case GF_ISOM_SUBTYPE_LHV1: - case GF_ISOM_SUBTYPE_LHE1: - base_subtype = gf_isom_get_media_subtype(read->mov, base_track, stsd_idx); - switch (base_subtype) { - case GF_ISOM_SUBTYPE_HVC1: - case GF_ISOM_SUBTYPE_HEV1: - case GF_ISOM_SUBTYPE_HVC2: - case GF_ISOM_SUBTYPE_HEV2: - break; - default: - external_base=GF_TRUE; - break; - } - } - if (external_base) { - depends_on_id = gf_isom_get_track_id(read->mov, base_track); - has_scalable_layers = GF_TRUE; - } else { - switch (gf_isom_get_hevc_lhvc_type(read->mov, track, stsd_idx)) { - case GF_ISOM_HEVCTYPE_HEVC_LHVC: - case GF_ISOM_HEVCTYPE_LHVC_ONLY: - has_scalable_layers = GF_TRUE; - break; - //this is likely temporal sublayer of base - case GF_ISOM_HEVCTYPE_HEVC_ONLY: - has_scalable_layers = GF_FALSE; - if (gf_isom_get_reference_count(read->mov, track, GF_ISOM_REF_SCAL)<=0) { - depends_on_id = gf_isom_get_track_id(read->mov, base_track); - } - break; - default: - break; - } - } - } else { - switch (gf_isom_get_hevc_lhvc_type(read->mov, track, stsd_idx)) { - case GF_ISOM_HEVCTYPE_HEVC_LHVC: - case GF_ISOM_HEVCTYPE_LHVC_ONLY: - has_scalable_layers = GF_TRUE; - break; - default: - break; - } - - if (!has_scalable_layers) { - u32 i; - GF_ISOTrackID track_id = gf_isom_get_track_id(read->mov, track); - for (i=0; imov); i++) { - if (gf_isom_get_reference_count(read->mov, i+1, GF_ISOM_REF_BASE)>=0) { - GF_ISOTrackID tkid; - gf_isom_get_reference_ID(read->mov, i+1, GF_ISOM_REF_BASE, 1, &tkid); - if (tkid==track_id) { - has_scalable_layers = GF_TRUE; - break; - } - } - } - } - } - - if (base_track && !ocr_es_id) { - ocr_es_id = gf_isom_get_track_id(read->mov, base_track); - } - if (!ocr_es_id) ocr_es_id = esid; - - //OK declare PID - pid = gf_filter_pid_new(read->filter); - if (read->pid) - gf_filter_pid_copy_properties(pid, read->pid); - - gf_filter_pid_set_property(pid, GF_PROP_PID_ID, &PROP_UINT(esid)); - gf_filter_pid_set_property(pid, GF_PROP_PID_CLOCK_ID, &PROP_UINT(ocr_es_id)); - if (depends_on_id && (depends_on_id != esid)) - gf_filter_pid_set_property(pid, GF_PROP_PID_DEPENDENCY_ID, &PROP_UINT(depends_on_id)); - - if (gf_isom_get_track_count(read->mov)>1) { - char szPName[1024]; - const char *szST = gf_stream_type_name(streamtype); - sprintf(szPName, "%c%d", szST[0], esid); - gf_filter_pid_set_name(pid, szPName); - } - - //MPEG-4 systems present - if (use_iod) - gf_filter_pid_set_property(pid, GF_PROP_PID_ESID, &PROP_UINT(esid)); - - if (gf_isom_is_track_in_root_od(read->mov, track) && !read->lightp) { - switch (streamtype) { - case GF_STREAM_SCENE: - case GF_STREAM_OD: - gf_filter_pid_set_property(pid, GF_PROP_PID_IN_IOD, &PROP_BOOL(GF_TRUE)); - break; - } - } - - gf_filter_pid_set_property(pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(streamtype)); - gf_filter_pid_set_property(pid, GF_PROP_PID_TIMESCALE, &PROP_UINT( gf_isom_get_media_timescale(read->mov, track) ) ); - - if (!gf_sys_is_test_mode()) - gf_filter_pid_set_property(pid, GF_PROP_PID_TRACK_NUM, &PROP_UINT(track) ); - - //Dolby Vision - check for any video type - GF_DOVIDecoderConfigurationRecord *dovi = gf_isom_dovi_config_get(read->mov, track, stsd_idx); - if (dovi) { - u8 *data = NULL; - u32 size = 0; - GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_odf_dovi_cfg_write_bs(dovi, bs); - gf_bs_get_content(bs, &data, &size); - gf_filter_pid_set_property(pid, GF_PROP_PID_DOLBY_VISION, &PROP_DATA_NO_COPY(data, size)); - gf_bs_del(bs); - gf_odf_dovi_cfg_del(dovi); - - if (gf_isom_get_reference_count(read->mov, track, GF_4CC('v','d','e','p'))) { - GF_ISOTrackID ref_id=0; - gf_isom_get_reference_ID(read->mov, track, GF_4CC('v','d','e','p'), 1, &ref_id); - if (ref_id) gf_filter_pid_set_property(pid, GF_PROP_PID_DEPENDENCY_ID, &PROP_UINT(ref_id)); - } - } - - //create our channel - ch = isor_create_channel(read, pid, track, 0, (codec_id==GF_CODECID_LHVC) ? GF_TRUE : GF_FALSE); - - if (lang_desc) { - char *lang=NULL; - gf_isom_get_media_language(read->mov, track, &lang); - //s32 idx = gf_lang_find(lang); - gf_filter_pid_set_property(pid, GF_PROP_PID_LANGUAGE, &PROP_STRING( lang )); - if (lang) gf_free(lang); - gf_odf_desc_del((GF_Descriptor *)lang_desc); - lang_desc = NULL; - } - - ch->streamType = streamtype; -// ch->clock_id = ocr_es_id; - - if (!read->lightp) { - if (has_scalable_layers) - gf_filter_pid_set_property(pid, GF_PROP_PID_SCALABLE, &PROP_BOOL(GF_TRUE)); - - if (gf_isom_get_reference_count(read->mov, track, GF_ISOM_REF_SABT)>0) { - gf_filter_pid_set_property(pid, GF_PROP_PID_TILE_BASE, &PROP_BOOL(GF_TRUE)); - } - else if (gf_isom_get_reference_count(read->mov, track, GF_ISOM_REF_SUBPIC)>0) { - gf_filter_pid_set_property(pid, GF_PROP_PID_TILE_BASE, &PROP_BOOL(GF_TRUE)); - } - - if (srd_w && srd_h) { - gf_filter_pid_set_property(pid, GF_PROP_PID_CROP_POS, &PROP_VEC2I_INT(srd_x, srd_y) ); - if (base_tile_track) { - gf_isom_get_visual_info(read->mov, base_tile_track, stsd_idx, &w, &h); - if (w && h) { - gf_filter_pid_set_property(pid, GF_PROP_PID_ORIG_SIZE, &PROP_VEC2I_INT(w, h) ); - } - } - } else { - u8 *srdg=NULL; - u32 srdg_s=0; - gf_isom_get_user_data(read->mov, track, GF_ISOM_UDTA_GPAC_SRD, NULL, 1, &srdg, &srdg_s); - if (srdg && srdg_s>=21) { - GF_BitStream *bs = gf_bs_new(srdg, srdg_s, GF_BITSTREAM_READ); - gf_bs_skip_bytes(bs, 5); - srd_x = (s32) gf_bs_read_u32(bs); - srd_y = (s32) gf_bs_read_u32(bs); - srd_w = gf_bs_read_u32(bs); - srd_h = gf_bs_read_u32(bs); - gf_bs_del(bs); - gf_filter_pid_set_property(pid, GF_PROP_PID_CROP_POS, &PROP_VEC2I_INT(srd_x, srd_y) ); - gf_filter_pid_set_property(pid, GF_PROP_PID_ORIG_SIZE, &PROP_VEC2I_INT(srd_w, srd_h) ); - } - if (srdg) gf_free(srdg); - } + isor_setup_channel(read, ch, track, streamtype, use_iod, esid, depends_on_id, ocr_es_id); + } - if (codec_id !=GF_CODECID_LHVC) - isor_export_ref(read, ch, GF_ISOM_REF_SCAL, "isom:scal"); - isor_export_ref(read, ch, GF_ISOM_REF_SABT, "isom:sabt"); - isor_export_ref(read, ch, GF_ISOM_REF_TBAS, "isom:tbas"); - isor_export_ref(read, ch, GF_ISOM_REF_SUBPIC, "isom:subp"); - } - - if (read->lightp) { - ch->duration = gf_isom_get_track_duration_orig(read->mov, ch->track); - } else { - ch->duration = gf_isom_get_track_duration(read->mov, ch->track); - } - if (!ch->duration) { - ch->duration = gf_isom_get_duration(read->mov); - } - sample_count = gf_isom_get_sample_count(read->mov, ch->track); + if (codec_id==GF_CODECID_TMCD) { + u32 tmcd_flags=0, tmcd_fps_num=0, tmcd_fps_den=0, tmcd_fpt=0; + gf_isom_get_tmcd_config(read->mov, track, stsd_idx, &tmcd_flags, &tmcd_fps_num, &tmcd_fps_den, &tmcd_fpt); + gf_filter_pid_set_property_str(ch->pid, "tmcd:flags", &PROP_UINT(tmcd_flags) ); + gf_filter_pid_set_property_str(ch->pid, "tmcd:framerate", &PROP_FRAC_INT(tmcd_fps_num, tmcd_fps_den) ); + gf_filter_pid_set_property_str(ch->pid, "tmcd:frames_per_tick", &PROP_UINT(tmcd_fpt) ); + } -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - if (read->frag_type && !read->input_loaded) { - u32 ts; - u64 dur; - if (gf_isom_get_sidx_duration(read->mov, &dur, &ts)==GF_OK) { - dur *= read->timescale; - dur /= ts; - ch->duration = dur; - use_sidx_dur = GF_TRUE; - sample_count = 0; - } - } -#endif + //Dolby Vision - check for any video type + GF_DOVIDecoderConfigurationRecord *dovi = gf_isom_dovi_config_get(read->mov, track, stsd_idx); + if (dovi) { + u8 *data = NULL; + u32 size = 0; + GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + gf_odf_dovi_cfg_write_bs(dovi, bs); + gf_bs_get_content(bs, &data, &size); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_DOLBY_VISION, &PROP_DATA_NO_COPY(data, size)); + gf_bs_del(bs); + gf_odf_dovi_cfg_del(dovi); - if (!read->mem_load_mode || ch->duration) { - //if no edit list (whether complex or simple TS offset) and no sidx, use media duration - if (!ch->has_edit_list && !use_sidx_dur && !ch->ts_offset) { - //no specific edit list type but edit present, use the duration in the edit - if (gf_isom_get_edits_count(read->mov, ch->track)) { - gf_filter_pid_set_property(pid, GF_PROP_PID_DURATION, &PROP_FRAC64_INT(ch->duration, read->timescale)); - } else { - u64 dur = gf_isom_get_media_duration(read->mov, ch->track); - gf_filter_pid_set_property(pid, GF_PROP_PID_DURATION, &PROP_FRAC64_INT(dur, ch->timescale)); - } - } - //otherwise trust track duration - else { - gf_filter_pid_set_property(pid, GF_PROP_PID_DURATION, &PROP_FRAC64_INT(ch->duration, read->timescale)); - } - gf_filter_pid_set_property(pid, GF_PROP_PID_NB_FRAMES, &PROP_UINT(sample_count)); + if (gf_isom_get_reference_count(read->mov, track, GF_4CC('v','d','e','p'))) { + GF_ISOTrackID ref_id=0; + gf_isom_get_reference_ID(read->mov, track, GF_4CC('v','d','e','p'), 1, &ref_id); + if (ref_id) gf_filter_pid_set_property(ch->pid, GF_PROP_PID_DEPENDENCY_ID, &PROP_UINT(ref_id)); } + } - if (sample_count && (streamtype==GF_STREAM_VISUAL)) { - u64 mdur = gf_isom_get_media_duration(read->mov, track); - //if ts_offset is negative (skip), update media dur before computing fps - if (!gf_sys_old_arch_compat()) { - u32 sdur = gf_isom_get_avg_sample_delta(read->mov, ch->track); - if (sdur) { - mdur = sdur; - } else { - if (ch->ts_offset<0) - mdur -= (u32) -ch->ts_offset; - mdur /= sample_count; + if (!read->lightp) { + if (srd_w && srd_h) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_CROP_POS, &PROP_VEC2I_INT(srd_x, srd_y) ); + if (base_tile_track) { + gf_isom_get_visual_info(read->mov, base_tile_track, stsd_idx, &w, &h); + if (w && h) { + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ORIG_SIZE, &PROP_VEC2I_INT(w, h) ); } - } else { - mdur /= sample_count; } - gf_filter_pid_set_property(pid, GF_PROP_PID_FPS, &PROP_FRAC_INT(ch->timescale, (u32) mdur)); - } - - track_dur = (Double) (s64) ch->duration; - track_dur /= read->timescale; - //move channel duration in media timescale - ch->duration = (u64) (track_dur * ch->timescale); - - - //set stream subtype - mtype = gf_isom_get_media_type(read->mov, track); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_SUBTYPE, &PROP_4CC(mtype) ); - - if (!read->mem_load_mode) { - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_MEDIA_DATA_SIZE, &PROP_LONGUINT(gf_isom_get_media_data_size(read->mov, track) ) ); - } - //in no cache mode, depending on fetch speed we may have fetched a fragment or not, resulting in has_rap set - //always for HAS_SYNC to false - else if (gf_sys_is_test_mode() && !sample_count) { - gf_filter_pid_set_property(pid, GF_PROP_PID_HAS_SYNC, &PROP_BOOL(GF_FALSE) ); - } - - if (read->lightp) goto props_done; - - w = gf_isom_get_constant_sample_size(read->mov, track); - if (w) - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_FRAME_SIZE, &PROP_UINT(w)); - - //mem mode, cannot read backwards - if (read->mem_load_mode) { - const GF_PropertyValue *p = gf_filter_pid_get_property(read->pid, GF_PROP_PID_PLAYBACK_MODE); - if (!p) - gf_filter_pid_set_property(pid, GF_PROP_PID_PLAYBACK_MODE, &PROP_UINT(GF_PLAYBACK_MODE_FASTFORWARD) ); - } else { - gf_filter_pid_set_property(pid, GF_PROP_PID_PLAYBACK_MODE, &PROP_UINT(GF_PLAYBACK_MODE_REWIND) ); - } - - GF_PropertyValue brands; - brands.type = GF_PROP_4CC_LIST; - u32 major_brand=0; - gf_isom_get_brand_info(read->mov, &major_brand, NULL, &brands.value.uint_list.nb_items); - brands.value.uint_list.vals = (u32 *) gf_isom_get_brands(read->mov); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_BRANDS, &brands); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_MBRAND, &PROP_4CC(major_brand) ); - - //we cannot expose average size/dur in mem mode with fragmented files (sample_count=0) - if (sample_count) { - max_size = gf_isom_get_max_sample_size(read->mov, ch->track); - if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_MAX_FRAME_SIZE, &PROP_UINT(max_size) ); - - max_size = gf_isom_get_avg_sample_size(read->mov, ch->track); - if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_AVG_FRAME_SIZE, &PROP_UINT(max_size) ); - - max_size = gf_isom_get_max_sample_delta(read->mov, ch->track); - if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_MAX_TS_DELTA, &PROP_UINT(max_size) ); - - max_size = gf_isom_get_max_sample_cts_offset(read->mov, ch->track); - if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_MAX_CTS_OFFSET, &PROP_UINT(max_size) ); - - max_size = gf_isom_get_constant_sample_duration(read->mov, ch->track); - if (max_size) gf_filter_pid_set_property(pid, GF_PROP_PID_CONSTANT_DURATION, &PROP_UINT(max_size) ); - } - - - u32 media_pl=0; - if (streamtype==GF_STREAM_VISUAL) { - media_pl = gf_isom_get_pl_indication(read->mov, GF_ISOM_PL_VISUAL); - } else if (streamtype==GF_STREAM_AUDIO) { - media_pl = gf_isom_get_pl_indication(read->mov, GF_ISOM_PL_AUDIO); - } - if (media_pl && (media_pl!=0xFF) ) gf_filter_pid_set_property(pid, GF_PROP_PID_PROFILE_LEVEL, &PROP_UINT(media_pl) ); - -#if !defined(GPAC_DISABLE_ISOM_WRITE) - e = gf_isom_get_track_template(read->mov, ch->track, &tk_template, &tk_template_size); - if (e == GF_OK) { - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_TEMPLATE, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); - } else { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] Failed to serialize track box: %s\n", gf_error_to_string(e) )); - } - - e = gf_isom_get_trex_template(read->mov, ch->track, &tk_template, &tk_template_size); - if (e == GF_OK) { - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TREX_TEMPLATE, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); - } - - e = gf_isom_get_raw_user_data(read->mov, &tk_template, &tk_template_size); - if (e==GF_OK) { - if (tk_template_size) - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_UDTA, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); } else { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] Failed to serialize moov UDTA box: %s\n", gf_error_to_string(e) )); - } -#endif - - GF_Fraction64 moov_time; - moov_time.num = gf_isom_get_duration(read->mov); - moov_time.den = gf_isom_get_timescale(read->mov); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_MOVIE_TIME, &PROP_FRAC64(moov_time) ); - - - u32 i; - s32 tx, ty; - s16 l; - gf_isom_get_track_layout_info(read->mov, ch->track, &w, &h, &tx, &ty, &l); - if (w && h) { - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_WIDTH, &PROP_UINT(w) ); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_HEIGHT, &PROP_UINT(h) ); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_TRANS_X, &PROP_SINT(tx) ); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_TRANS_Y, &PROP_SINT(ty) ); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ZORDER, &PROP_SINT(l) ); - } - if (codec_id==GF_CODECID_TX3G) { - u32 m_w = w; - u32 m_h = h; - for (i=0; imov); i++) { - switch (gf_isom_get_media_type(read->mov, i+1)) { - case GF_ISOM_MEDIA_SCENE: - case GF_ISOM_MEDIA_VISUAL: - case GF_ISOM_MEDIA_AUXV: - case GF_ISOM_MEDIA_PICT: - gf_isom_get_track_layout_info(read->mov, i+1, &w, &h, &tx, &ty, &l); - if (w>m_w) m_w = w; - if (h>m_h) m_h = h; - break; - default: - break; - } - } - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_WIDTH_MAX, &PROP_UINT(m_w) ); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_HEIGHT_MAX, &PROP_UINT(m_h) ); - char *tx3g_config_sdp = NULL; - for (i=0; imov, ch->track); i++) { - u8 *tx3g; - u32 l1; - u32 tx3g_len, len; - e = gf_isom_text_get_encoded_tx3g(read->mov, ch->track, i+1, GF_RTP_TX3G_SIDX_OFFSET, &tx3g, &tx3g_len); - if (e==GF_OK) { - char buffer[2000]; - len = gf_base64_encode(tx3g, tx3g_len, buffer, 2000); - gf_free(tx3g); - buffer[len] = 0; - - l1 = tx3g_config_sdp ? (u32) strlen(tx3g_config_sdp) : 0; - tx3g_config_sdp = gf_realloc(tx3g_config_sdp, len+3+l1); - tx3g_config_sdp[l1] = 0; - if (i) strcat(tx3g_config_sdp, ", "); - strcat(tx3g_config_sdp, buffer); - } - } - if (tx3g_config_sdp) { - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT, &PROP_STRING_NO_COPY(tx3g_config_sdp) ); - } - } - - u32 idx=0; - while (1) { - u32 data_len, int_val2, flags; - u64 int_val; - const char *name; - const u8 *data; - GF_ISOiTunesTag itag; - u32 itype = 0; - s32 tag_idx; - - e = gf_isom_apple_enum_tag(read->mov, idx, &itag, &data, &data_len, &int_val, &int_val2, &flags); - if (e) break; - idx++; - - //do not expose tool - if (!gf_sys_is_test_mode() && (itag == GF_ISOM_ITUNE_TOOL)) - continue; - - tag_idx = gf_itags_find_by_itag(itag); - if (tag_idx>=0) - itype = gf_itags_get_type(tag_idx); - - name = gf_itags_get_name(tag_idx); - switch (itype) { - case GF_ITAG_BOOL: - gf_filter_pid_set_property_str(ch->pid, name, &PROP_BOOL((Bool) int_val ) ); - break; - case GF_ITAG_INT8: - case GF_ITAG_INT16: - case GF_ITAG_INT32: - gf_filter_pid_set_property_str(ch->pid, name, &PROP_UINT((u32) int_val ) ); - break; - case GF_ITAG_INT64: - gf_filter_pid_set_property_str(ch->pid, name, &PROP_LONGUINT(int_val) ); - break; - case GF_ITAG_FRAC8: - case GF_ITAG_FRAC6: - gf_filter_pid_set_property_str(ch->pid, name, &PROP_FRAC_INT((s32) int_val, int_val2) ); - break; - case GF_ITAG_FILE: - if (data && data_len) - gf_filter_pid_set_property_str(ch->pid, name, &PROP_DATA((u8 *)data, data_len) ); - break; - default: - if (data && data_len) { - if (gf_utf8_is_legal(data, data_len)) - gf_filter_pid_set_property_str(ch->pid, name, &PROP_STRING(data) ); - else - gf_filter_pid_set_property_str(ch->pid, name, &PROP_DATA((u8 *)data, data_len) ); - } - break; - } - } - - if (codec_id==GF_CODECID_TMCD) { - u32 tmcd_flags=0, tmcd_fps_num=0, tmcd_fps_den=0, tmcd_fpt=0; - gf_isom_get_tmcd_config(read->mov, track, stsd_idx, &tmcd_flags, &tmcd_fps_num, &tmcd_fps_den, &tmcd_fpt); - gf_filter_pid_set_property_str(ch->pid, "tmcd:flags", &PROP_UINT(tmcd_flags) ); - gf_filter_pid_set_property_str(ch->pid, "tmcd:framerate", &PROP_FRAC_INT(tmcd_fps_num, tmcd_fps_den) ); - gf_filter_pid_set_property_str(ch->pid, "tmcd:frames_per_tick", &PROP_UINT(tmcd_fpt) ); - - } - - if (gf_sys_old_arch_compat()) { - Bool gf_isom_has_time_offset_table(GF_ISOFile *the_file, u32 trackNumber); - if (gf_isom_has_time_offset_table(read->mov, ch->track)) - gf_filter_pid_set_property_str(ch->pid, "isom_force_ctts", &PROP_BOOL(GF_TRUE) ); - } - if (read->nodata==2) - gf_filter_pid_set_property_str(ch->pid, "nodata", &PROP_BOOL(GF_TRUE) ); - - if (!gf_sys_is_test_mode()) { - u32 nb_udta, alt_grp=0; - const char *hdlr = NULL; - gf_isom_get_handler_name(read->mov, ch->track, &hdlr); - if (hdlr) - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_HANDLER, &PROP_STRING(hdlr)); - - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_FLAGS, &PROP_UINT( gf_isom_get_track_flags(read->mov, ch->track) )); - - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_FLAGS, &PROP_UINT( gf_isom_get_track_flags(read->mov, ch->track) )); - - gf_isom_get_track_switch_group_count(read->mov, ch->track, &alt_grp, NULL); - if (alt_grp) - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_ALT_GROUP, &PROP_UINT( alt_grp )); - - - if (streamtype==GF_STREAM_VISUAL) { - GF_PropertyValue p; - u32 vals[9]; - memset(vals, 0, sizeof(u32)*9); - memset(&p, 0, sizeof(GF_PropertyValue)); - p.type = GF_PROP_SINT_LIST; - p.value.uint_list.nb_items = 9; - p.value.uint_list.vals = vals; - gf_isom_get_track_matrix(read->mov, ch->track, vals); - gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_TRACK_MATRIX, &p); - } - - - nb_udta = gf_isom_get_udta_count(read->mov, ch->track); - if (nb_udta) { - for (i=0; imov, ch->track, i+1, &type, &uuid); - nb_items = gf_isom_get_user_data_count(read->mov, ch->track, type, uuid); - //we only export 4CC udta boxes - if (!type) continue; - - for (j=0; jmov, ch->track, type, uuid, j+1, &udta, &udta_size); - if (!udta || !udta_size) continue; - if (nb_items>1) - snprintf(szName, 30, "udta_%s_%d", gf_4cc_to_str(type), j+1); - else - snprintf(szName, 30, "udta_%s", gf_4cc_to_str(type)); - szName[30]=0; - if (gf_utf8_is_legal(udta, udta_size)) { - if (!udta[udta_size-1]) { - gf_filter_pid_set_property_dyn(ch->pid, szName, &PROP_STRING_NO_COPY(udta)); - } else { - char *data = gf_malloc(udta_size+1); - memcpy(data, udta, udta_size); - data[udta_size]=0; - gf_filter_pid_set_property_dyn(ch->pid, szName, &PROP_STRING_NO_COPY(data)); - gf_free(udta); - } - } else { - gf_filter_pid_set_property_dyn(ch->pid, szName, &PROP_DATA_NO_COPY(udta, udta_size)); - } - } - } - } - - //delcare track groups - u32 idx=0; - while (1) { - char szTK[100]; - u32 track_group_type, track_group_id; - if (!gf_isom_enum_track_group(read->mov, ch->track, &idx, &track_group_type, &track_group_id)) break; - sprintf(szTK, "tkgp_%s", gf_4cc_to_str(track_group_type)); - gf_filter_pid_set_property_dyn(ch->pid, szTK, &PROP_SINT(track_group_id)); - } - } - -props_done: - - if (read->sigfrag) { -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - u64 start, end; - if (gf_isom_get_root_sidx_offsets(read->mov, &start, &end)) { - if (end) - gf_filter_pid_set_property(ch->pid, GF_PROP_PCK_SIDX_RANGE, &PROP_FRAC64_INT(start , end)); - } -#endif - if (!read->frag_type) { - gf_filter_pid_set_property_str(ch->pid, "nofrag", &PROP_BOOL(GF_TRUE)); + u8 *srdg=NULL; + u32 srdg_s=0; + gf_isom_get_user_data(read->mov, track, GF_ISOM_UDTA_GPAC_SRD, NULL, 1, &srdg, &srdg_s); + if (srdg && srdg_s>=21) { + GF_BitStream *bs = gf_bs_new(srdg, srdg_s, GF_BITSTREAM_READ); + gf_bs_skip_bytes(bs, 5); + srd_x = (s32) gf_bs_read_u32(bs); + srd_y = (s32) gf_bs_read_u32(bs); + srd_w = gf_bs_read_u32(bs); + srd_h = gf_bs_read_u32(bs); + gf_bs_del(bs); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_CROP_POS, &PROP_VEC2I_INT(srd_x, srd_y) ); + gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ORIG_SIZE, &PROP_VEC2I_INT(srd_w, srd_h) ); } + if (srdg) gf_free(srdg); } } @@ -1430,8 +1452,8 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 #if !defined(GPAC_DISABLE_ISOM_WRITE) - tk_template=NULL; - tk_template_size=0; + u8 *tk_template = NULL; + u32 tk_template_size = 0; e = gf_isom_get_stsd_template(read->mov, ch->track, stsd_idx, &tk_template, &tk_template_size); if (e == GF_OK) { gf_filter_pid_set_property(ch->pid, GF_PROP_PID_ISOM_STSD_TEMPLATE, &PROP_DATA_NO_COPY(tk_template, tk_template_size) ); diff --git a/src/filters/jsfilter.c b/src/filters/jsfilter.c index da2ca68bbb..bf9bfe8ed1 100644 --- a/src/filters/jsfilter.c +++ b/src/filters/jsfilter.c @@ -4468,224 +4468,6 @@ static GF_Err jsfilter_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool #define DEF_CONST( _val ) \ JS_SetPropertyStr(ctx, global_obj, #_val, JS_NewInt32(ctx, _val)); -static void js_load_key_names(JSContext *ctx, JSValue global_obj) -{ - DEF_CONST(GF_KEY_UNIDENTIFIED) - DEF_CONST(GF_KEY_ACCEPT) - DEF_CONST(GF_KEY_AGAIN) - DEF_CONST(GF_KEY_ALLCANDIDATES) - DEF_CONST(GF_KEY_ALPHANUM) - DEF_CONST(GF_KEY_ALT) - DEF_CONST(GF_KEY_ALTGRAPH) - DEF_CONST(GF_KEY_APPS) - DEF_CONST(GF_KEY_ATTN) - DEF_CONST(GF_KEY_BROWSERBACK) - DEF_CONST(GF_KEY_BROWSERFAVORITES) - DEF_CONST(GF_KEY_BROWSERFORWARD) - DEF_CONST(GF_KEY_BROWSERHOME) - DEF_CONST(GF_KEY_BROWSERREFRESH) - DEF_CONST(GF_KEY_BROWSERSEARCH) - DEF_CONST(GF_KEY_BROWSERSTOP) - DEF_CONST(GF_KEY_CAPSLOCK) - DEF_CONST(GF_KEY_CLEAR) - DEF_CONST(GF_KEY_CODEINPUT) - DEF_CONST(GF_KEY_COMPOSE) - DEF_CONST(GF_KEY_CONTROL) - DEF_CONST(GF_KEY_CRSEL) - DEF_CONST(GF_KEY_CONVERT) - DEF_CONST(GF_KEY_COPY) - DEF_CONST(GF_KEY_CUT) - DEF_CONST(GF_KEY_DOWN) - DEF_CONST(GF_KEY_END) - DEF_CONST(GF_KEY_ENTER) - DEF_CONST(GF_KEY_ERASEEOF) - DEF_CONST(GF_KEY_EXECUTE) - DEF_CONST(GF_KEY_EXSEL) - DEF_CONST(GF_KEY_F1) - DEF_CONST(GF_KEY_F2) - DEF_CONST(GF_KEY_F3) - DEF_CONST(GF_KEY_F4) - DEF_CONST(GF_KEY_F5) - DEF_CONST(GF_KEY_F6) - DEF_CONST(GF_KEY_F7) - DEF_CONST(GF_KEY_F8) - DEF_CONST(GF_KEY_F9) - DEF_CONST(GF_KEY_F10) - DEF_CONST(GF_KEY_F11) - DEF_CONST(GF_KEY_F12) - DEF_CONST(GF_KEY_F13) - DEF_CONST(GF_KEY_F14) - DEF_CONST(GF_KEY_F15) - DEF_CONST(GF_KEY_F16) - DEF_CONST(GF_KEY_F17) - DEF_CONST(GF_KEY_F18) - DEF_CONST(GF_KEY_F19) - DEF_CONST(GF_KEY_F20) - DEF_CONST(GF_KEY_F21) - DEF_CONST(GF_KEY_F22) - DEF_CONST(GF_KEY_F23) - DEF_CONST(GF_KEY_F24) - DEF_CONST(GF_KEY_FINALMODE) - DEF_CONST(GF_KEY_FIND) - DEF_CONST(GF_KEY_FULLWIDTH) - DEF_CONST(GF_KEY_HALFWIDTH) - DEF_CONST(GF_KEY_HANGULMODE) - DEF_CONST(GF_KEY_HANJAMODE) - DEF_CONST(GF_KEY_HELP) - DEF_CONST(GF_KEY_HIRAGANA) - DEF_CONST(GF_KEY_HOME) - DEF_CONST(GF_KEY_INSERT) - DEF_CONST(GF_KEY_JAPANESEHIRAGANA) - DEF_CONST(GF_KEY_JAPANESEKATAKANA) - DEF_CONST(GF_KEY_JAPANESEROMAJI) - DEF_CONST(GF_KEY_JUNJAMODE) - DEF_CONST(GF_KEY_KANAMODE) - DEF_CONST(GF_KEY_KANJIMODE) - DEF_CONST(GF_KEY_KATAKANA) - DEF_CONST(GF_KEY_LAUNCHAPPLICATION1) - DEF_CONST(GF_KEY_LAUNCHAPPLICATION2) - DEF_CONST(GF_KEY_LAUNCHMAIL) - DEF_CONST(GF_KEY_LEFT) - DEF_CONST(GF_KEY_META) - DEF_CONST(GF_KEY_MEDIANEXTTRACK) - DEF_CONST(GF_KEY_MEDIAPLAYPAUSE) - DEF_CONST(GF_KEY_MEDIAPREVIOUSTRACK) - DEF_CONST(GF_KEY_MEDIASTOP) - DEF_CONST(GF_KEY_MODECHANGE) - DEF_CONST(GF_KEY_NONCONVERT) - DEF_CONST(GF_KEY_NUMLOCK) - DEF_CONST(GF_KEY_PAGEDOWN) - DEF_CONST(GF_KEY_PAGEUP) - DEF_CONST(GF_KEY_PASTE) - DEF_CONST(GF_KEY_PAUSE) - DEF_CONST(GF_KEY_PLAY) - DEF_CONST(GF_KEY_PREVIOUSCANDIDATE) - DEF_CONST(GF_KEY_PRINTSCREEN) - DEF_CONST(GF_KEY_PROCESS) - DEF_CONST(GF_KEY_PROPS) - DEF_CONST(GF_KEY_RIGHT) - DEF_CONST(GF_KEY_ROMANCHARACTERS) - DEF_CONST(GF_KEY_SCROLL) - DEF_CONST(GF_KEY_SELECT) - DEF_CONST(GF_KEY_SELECTMEDIA) - DEF_CONST(GF_KEY_SHIFT) - DEF_CONST(GF_KEY_STOP) - DEF_CONST(GF_KEY_UP) - DEF_CONST(GF_KEY_UNDO) - DEF_CONST(GF_KEY_VOLUMEDOWN) - DEF_CONST(GF_KEY_VOLUMEMUTE) - DEF_CONST(GF_KEY_VOLUMEUP) - DEF_CONST(GF_KEY_WIN) - DEF_CONST(GF_KEY_ZOOM) - DEF_CONST(GF_KEY_BACKSPACE) - DEF_CONST(GF_KEY_TAB) - DEF_CONST(GF_KEY_CANCEL) - DEF_CONST(GF_KEY_ESCAPE) - DEF_CONST(GF_KEY_SPACE) - DEF_CONST(GF_KEY_EXCLAMATION) - DEF_CONST(GF_KEY_QUOTATION) - DEF_CONST(GF_KEY_NUMBER) - DEF_CONST(GF_KEY_DOLLAR) - DEF_CONST(GF_KEY_AMPERSAND) - DEF_CONST(GF_KEY_APOSTROPHE) - DEF_CONST(GF_KEY_LEFTPARENTHESIS) - DEF_CONST(GF_KEY_RIGHTPARENTHESIS) - DEF_CONST(GF_KEY_STAR) - DEF_CONST(GF_KEY_PLUS) - DEF_CONST(GF_KEY_COMMA) - DEF_CONST(GF_KEY_HYPHEN) - DEF_CONST(GF_KEY_FULLSTOP) - DEF_CONST(GF_KEY_SLASH) - DEF_CONST(GF_KEY_0) - DEF_CONST(GF_KEY_1) - DEF_CONST(GF_KEY_2) - DEF_CONST(GF_KEY_3) - DEF_CONST(GF_KEY_4) - DEF_CONST(GF_KEY_5) - DEF_CONST(GF_KEY_6) - DEF_CONST(GF_KEY_7) - DEF_CONST(GF_KEY_8) - DEF_CONST(GF_KEY_9) - DEF_CONST(GF_KEY_COLON) - DEF_CONST(GF_KEY_SEMICOLON) - DEF_CONST(GF_KEY_LESSTHAN) - DEF_CONST(GF_KEY_EQUALS) - DEF_CONST(GF_KEY_GREATERTHAN) - DEF_CONST(GF_KEY_QUESTION) - DEF_CONST(GF_KEY_AT) - DEF_CONST(GF_KEY_A) - DEF_CONST(GF_KEY_B) - DEF_CONST(GF_KEY_C) - DEF_CONST(GF_KEY_D) - DEF_CONST(GF_KEY_E) - DEF_CONST(GF_KEY_F) - DEF_CONST(GF_KEY_G) - DEF_CONST(GF_KEY_H) - DEF_CONST(GF_KEY_I) - DEF_CONST(GF_KEY_J) - DEF_CONST(GF_KEY_K) - DEF_CONST(GF_KEY_L) - DEF_CONST(GF_KEY_M) - DEF_CONST(GF_KEY_N) - DEF_CONST(GF_KEY_O) - DEF_CONST(GF_KEY_P) - DEF_CONST(GF_KEY_Q) - DEF_CONST(GF_KEY_R) - DEF_CONST(GF_KEY_S) - DEF_CONST(GF_KEY_T) - DEF_CONST(GF_KEY_U) - DEF_CONST(GF_KEY_V) - DEF_CONST(GF_KEY_W) - DEF_CONST(GF_KEY_X) - DEF_CONST(GF_KEY_Y) - DEF_CONST(GF_KEY_Z) - DEF_CONST(GF_KEY_LEFTSQUAREBRACKET) - DEF_CONST(GF_KEY_BACKSLASH) - DEF_CONST(GF_KEY_RIGHTSQUAREBRACKET) - DEF_CONST(GF_KEY_CIRCUM) - DEF_CONST(GF_KEY_UNDERSCORE) - DEF_CONST(GF_KEY_GRAVEACCENT) - DEF_CONST(GF_KEY_LEFTCURLYBRACKET) - DEF_CONST(GF_KEY_PIPE) - DEF_CONST(GF_KEY_RIGHTCURLYBRACKET) - DEF_CONST(GF_KEY_DEL) - DEF_CONST(GF_KEY_INVERTEXCLAMATION) - DEF_CONST(GF_KEY_DEADGRAVE) - DEF_CONST(GF_KEY_DEADEACUTE) - DEF_CONST(GF_KEY_DEADCIRCUM) - DEF_CONST(GF_KEY_DEADTILDE) - DEF_CONST(GF_KEY_DEADMACRON) - DEF_CONST(GF_KEY_DEADBREVE) - DEF_CONST(GF_KEY_DEADABOVEDOT) - DEF_CONST(GF_KEY_DEADDIARESIS) - DEF_CONST(GF_KEY_DEADRINGABOVE) - DEF_CONST(GF_KEY_DEADDOUBLEACUTE) - DEF_CONST(GF_KEY_DEADCARON) - DEF_CONST(GF_KEY_DEADCEDILLA) - DEF_CONST(GF_KEY_DEADOGONEK) - DEF_CONST(GF_KEY_DEADIOTA) - DEF_CONST(GF_KEY_EURO) - DEF_CONST(GF_KEY_DEADVOICESOUND) - DEF_CONST(GF_KEY_DEADSEMIVOICESOUND) - DEF_CONST(GF_KEY_CHANNELUP) - DEF_CONST(GF_KEY_CHANNELDOWN) - DEF_CONST(GF_KEY_TEXT) - DEF_CONST(GF_KEY_INFO) - DEF_CONST(GF_KEY_EPG) - DEF_CONST(GF_KEY_RECORD) - DEF_CONST(GF_KEY_BEGINPAGE) - DEF_CONST(GF_KEY_CELL_SOFT1) - DEF_CONST(GF_KEY_CELL_SOFT2) - DEF_CONST(GF_KEY_JOYSTICK) - - DEF_CONST(GF_KEY_MOD_SHIFT) - DEF_CONST(GF_KEY_MOD_CTRL) - DEF_CONST(GF_KEY_MOD_ALT) - DEF_CONST(GF_KEY_EXT_NUMPAD) - DEF_CONST(GF_KEY_EXT_LEFT) - DEF_CONST(GF_KEY_EXT_RIGHT) -} - void js_load_constants(JSContext *ctx, JSValue global_obj) { JSValue val; @@ -4850,7 +4632,13 @@ void js_load_constants(JSContext *ctx, JSValue global_obj) DEF_CONST(GF_EVENT_CODEC_SLOW) DEF_CONST(GF_EVENT_CODEC_OK) - js_load_key_names(ctx, global_obj); + DEF_CONST(GF_KEY_MOD_SHIFT) + DEF_CONST(GF_KEY_MOD_CTRL) + DEF_CONST(GF_KEY_MOD_ALT) + DEF_CONST(GF_KEY_EXT_NUMPAD) + DEF_CONST(GF_KEY_EXT_LEFT) + DEF_CONST(GF_KEY_EXT_RIGHT) + JS_SetPropertyStr(ctx, global_obj, "print", JS_NewCFunction(ctx, js_print, "print", 1)); JS_SetPropertyStr(ctx, global_obj, "alert", JS_NewCFunction(ctx, js_print, "alert", 1)); diff --git a/src/filters/reframe_latm.c b/src/filters/reframe_latm.c index 3c50204010..5350291471 100644 --- a/src/filters/reframe_latm.c +++ b/src/filters/reframe_latm.c @@ -77,6 +77,8 @@ typedef struct u32 bitrate; GF_Err in_error; Bool copy_props; + + u8 latm_dmx_buffer[LATM_DMX_MAX_SIZE]; } GF_LATMDmxCtx; @@ -528,9 +530,8 @@ GF_Err latm_dmx_process(GF_Filter *filter) while (1) { pos = (u32) gf_bs_get_position(ctx->bs); - u8 latm_buffer[LATM_DMX_MAX_SIZE]; u32 latm_frame_size = LATM_DMX_MAX_SIZE; - if (!latm_dmx_sync_frame_bs(ctx->bs,&ctx->acfg, &latm_frame_size, latm_buffer, NULL)) break; + if (!latm_dmx_sync_frame_bs(ctx->bs,&ctx->acfg, &latm_frame_size, ctx->latm_dmx_buffer, NULL)) break; if (ctx->in_seek) { u64 nb_samples_at_seek = (u64) (ctx->start_range * GF_M4ASampleRates[ctx->sr_idx]); @@ -558,7 +559,7 @@ GF_Err latm_dmx_process(GF_Filter *filter) if (ctx->src_pck) gf_filter_pck_merge_properties(ctx->src_pck, dst_pck); - memcpy(output, latm_buffer, latm_frame_size); + memcpy(output, ctx->latm_dmx_buffer, latm_frame_size); gf_filter_pck_set_cts(dst_pck, ctx->cts); if (ctx->timescale && (ctx->timescale!=ctx->sample_rate)) diff --git a/src/ietf/sdp.c b/src/ietf/sdp.c index f704de48e4..4e3fab70f6 100644 --- a/src/ietf/sdp.c +++ b/src/ietf/sdp.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / IETF RTP/RTSP/SDP sub-project @@ -35,6 +35,8 @@ #define SDP_WRITE_STEPALLOC 2048 +#define SDP_MAX_LINE 1000 + GF_EXPORT GF_SDP_FMTP *gf_sdp_fmtp_new() @@ -76,28 +78,28 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) { s32 pos; u32 PayT; - char comp[3000]; + char comp[SDP_MAX_LINE+1]; GF_X_Attribute *att; - pos = gf_token_get(buffer, 0, " :\t\r\n", comp, 3000); + pos = gf_token_get(buffer, 0, " :\t\r\n", comp, SDP_MAX_LINE); if (!strcmp(comp, "cat")) { if (media) return; - /*pos = */gf_token_get(buffer, pos, ":\t\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\t\r\n", comp, SDP_MAX_LINE); if (sdp->a_cat) return; sdp->a_cat = gf_strdup(comp); return; } if (!strcmp(comp, "keywds")) { if (media) return; - /*pos = */gf_token_get(buffer, pos, ":\t\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\t\r\n", comp, SDP_MAX_LINE); if (sdp->a_keywds) return; sdp->a_keywds = gf_strdup(comp); return; } if (!strcmp(comp, "tool")) { if (media) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); if (sdp->a_tool) return; sdp->a_tool = gf_strdup(comp); return; @@ -105,7 +107,7 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) if (!strcmp(comp, "ptime")) { if (!media) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); media->PacketTime = atoi(comp); return; } @@ -135,27 +137,27 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) } if (!strcmp(comp, "orient")) { if (!media || media->Type) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); if (media->orientation) return; media->orientation = gf_strdup(comp); return; } if (!strcmp(comp, "type")) { if (media) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); if (sdp->a_type) return; sdp->a_type = gf_strdup(comp); return; } if (!strcmp(comp, "charset")) { if (media) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); if (sdp->a_charset) sdp->a_charset = gf_strdup(comp); return; } if (!strcmp(comp, "sdplang")) { - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); if (media) { if (media->sdplang) return; media->sdplang = gf_strdup(comp); @@ -166,7 +168,7 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) return; } if (!strcmp(comp, "lang")) { - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); if (media) { if (media->lang) return; media->lang = gf_strdup(comp); @@ -179,13 +181,13 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) if (!strcmp(comp, "framerate")) { //only for video if (!media || (media->Type != 1)) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); media->FrameRate = atof(comp); return; } if (!strcmp(comp, "quality")) { if (!media) return; - /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(buffer, pos, ":\r\n", comp, SDP_MAX_LINE); media->Quality = atoi(comp); return; } @@ -193,13 +195,13 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) GF_RTPMap *map; if (!media) return; map = (GF_RTPMap*)gf_malloc(sizeof(GF_RTPMap)); - pos = gf_token_get(buffer, pos, ": \r\n", comp, 3000); + pos = gf_token_get(buffer, pos, ": \r\n", comp, SDP_MAX_LINE); map->PayloadType = atoi(comp); - pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000); + pos = gf_token_get(buffer, pos, " /\r\n", comp, SDP_MAX_LINE); map->payload_name = gf_strdup(comp); - pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000); + pos = gf_token_get(buffer, pos, " /\r\n", comp, SDP_MAX_LINE); map->ClockRate = atoi(comp); - pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000); + pos = gf_token_get(buffer, pos, " /\r\n", comp, SDP_MAX_LINE); map->AudioChannels = (pos > 0) ? atoi(comp) : 0; gf_list_add(media->RTPMaps, map); return; @@ -208,7 +210,7 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) if (!strcmp(comp, "fmtp")) { GF_SDP_FMTP *fmtp; if (!media) return; - pos = gf_token_get(buffer, pos, ": \r\n", comp, 3000); + pos = gf_token_get(buffer, pos, ": \r\n", comp, SDP_MAX_LINE); PayT = atoi(comp); fmtp = SDP_GetFMTPForPayload(media, PayT); if (!fmtp) { @@ -217,13 +219,13 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) gf_list_add(media->FMTP, fmtp); } while (1) { - pos = gf_token_get(buffer, pos, "; =\r\n", comp, 3000); + pos = gf_token_get(buffer, pos, "; =\r\n", comp, SDP_MAX_LINE); if (pos <= 0) break; att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); att->Name = gf_strdup(comp); att->Value = NULL; pos ++; - pos = gf_token_get(buffer, pos, ";\r\n", comp, 3000); + pos = gf_token_get(buffer, pos, ";\r\n", comp, SDP_MAX_LINE); if (pos > 0) att->Value = gf_strdup(comp); gf_list_add(fmtp->Attributes, att); } @@ -233,7 +235,7 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) //so keep it. //a= || : //we add in case ... - pos = gf_token_get(buffer, 0, " :\r\n", comp, 3000); + pos = gf_token_get(buffer, 0, " :\r\n", comp, SDP_MAX_LINE); att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); att->Name = gf_strdup(comp); att->Value = NULL; @@ -243,7 +245,7 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) if (buffer[pos] == ' ') pos += 1; } - pos = gf_token_get(buffer, pos, "\r\n", comp, 3000); + pos = gf_token_get(buffer, pos, "\r\n", comp, SDP_MAX_LINE); if (pos > 0) att->Value = gf_strdup(comp); if (media) { @@ -494,7 +496,7 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) GF_SDPTiming *timing; u32 i; s32 pos, LinePos; - char LineBuf[3000], comp[3000]; + char LineBuf[SDP_MAX_LINE+1], comp[SDP_MAX_LINE+1]; media = NULL; timing = NULL; @@ -515,58 +517,58 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) LinePos = 0; while (1) { - LinePos = gf_token_get_line(sdp_text, LinePos, text_size, LineBuf, 3000); + LinePos = gf_token_get_line(sdp_text, LinePos, text_size, LineBuf, SDP_MAX_LINE); if (LinePos <= 0) break; if (!strcmp(LineBuf, "\r\n") || !strcmp(LineBuf, "\n") || !strcmp(LineBuf, "\r")) continue; pos=0; switch (LineBuf[0]) { case 'v': - /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, SDP_MAX_LINE); sdp->Version = atoi(comp); break; case 'o': //only use first one if (sdp->o_username) break; - pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, SDP_MAX_LINE); sdp->o_username = gf_strdup(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); sdp->o_session_id = gf_strdup(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); sdp->o_version = gf_strdup(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); sdp->o_net_type = gf_strdup(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); sdp->o_add_type = gf_strdup(comp); - /*pos = */gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); sdp->o_address = gf_strdup(comp); break; case 's': if (sdp->s_session_name) break; - /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, SDP_MAX_LINE); sdp->s_session_name = gf_strdup(comp); break; case 'i': if (sdp->i_description) break; - /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, SDP_MAX_LINE); sdp->i_description = gf_strdup(comp); break; case 'u': if (sdp->u_uri) break; - /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, SDP_MAX_LINE); sdp->u_uri = gf_strdup(comp); break; case 'e': if (sdp->e_email) break; - /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, SDP_MAX_LINE); sdp->e_email = gf_strdup(comp); break; case 'p': if (sdp->p_phone) break; - /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, 2, "\t\r\n", comp, SDP_MAX_LINE); sdp->p_phone = gf_strdup(comp); break; case 'c': @@ -575,21 +577,21 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) conn = gf_sdp_conn_new(); - pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, SDP_MAX_LINE); conn->net_type = gf_strdup(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); conn->add_type = gf_strdup(comp); - pos = gf_token_get(LineBuf, pos, " /\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " /\r\n", comp, SDP_MAX_LINE); conn->host = gf_strdup(comp); if (gf_sk_is_multicast_address(conn->host)) { //a valid SDP will have TTL if address is multicast - pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, "/\r\n", comp, SDP_MAX_LINE); if (pos > 0) { conn->TTL = atoi(comp); //multiple address indication is only valid for media - pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, "/\r\n", comp, SDP_MAX_LINE); } if (pos > 0) { if (!media) { @@ -606,13 +608,13 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) break; case 'b': - pos = gf_token_get(LineBuf, 2, ":\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, ":\r\n", comp, SDP_MAX_LINE); if (strcmp(comp, "CT") && strcmp(comp, "AS") && (comp[0] != 'X')) break; GF_SAFEALLOC(bw, GF_SDPBandwidth); if (!bw) return GF_OUT_OF_MEM; bw->name = gf_strdup(comp); - /*pos = */gf_token_get(LineBuf, pos, ":\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, pos, ":\r\n", comp, SDP_MAX_LINE); bw->value = atoi(comp); if (media) { gf_list_add(media->Bandwidths, bw); @@ -626,22 +628,22 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) //create a new time structure for each entry GF_SAFEALLOC(timing, GF_SDPTiming); if (!timing) return GF_OUT_OF_MEM; - pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, SDP_MAX_LINE); timing->StartTime = atoi(comp); - /*pos = */gf_token_get(LineBuf, pos, "\r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, pos, "\r\n", comp, SDP_MAX_LINE); timing->StopTime = atoi(comp); gf_list_add(sdp->Timing, timing); break; case 'r': if (media) break; - pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, SDP_MAX_LINE); if (!timing) return GF_NON_COMPLIANT_BITSTREAM; timing->RepeatInterval = SDP_MakeSeconds(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); timing->ActiveDuration = SDP_MakeSeconds(comp); while (pos>=0) { if (timing->NbRepeatOffsets == GF_SDP_MAX_TIMEOFFSET) break; - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); if (pos <= 0) break; timing->OffsetFromStart[timing->NbRepeatOffsets] = SDP_MakeSeconds(comp); timing->NbRepeatOffsets += 1; @@ -652,24 +654,24 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) pos = 2; if (!timing) return GF_NON_COMPLIANT_BITSTREAM; while (1) { - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); if (pos <= 0) break; if (timing->NbZoneOffsets >= GF_SDP_MAX_TIMEOFFSET) break; timing->AdjustmentTime[timing->NbZoneOffsets] = atoi(comp); - pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, SDP_MAX_LINE); timing->AdjustmentOffset[timing->NbZoneOffsets] = SDP_MakeSeconds(comp); timing->NbZoneOffsets += 1; } break; case 'k': if (sdp->k_method) break; - pos = gf_token_get(LineBuf, 2, ":\t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, ":\t\r\n", comp, SDP_MAX_LINE); if (media) { media->k_method = gf_strdup(comp); } else { sdp->k_method = gf_strdup(comp); } - pos = gf_token_get(LineBuf, pos, ":\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, ":\r\n", comp, SDP_MAX_LINE); if (pos > 0) { if (media) { media->k_key = gf_strdup(comp); @@ -682,7 +684,7 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) SDP_ParseAttribute(sdp, LineBuf+2, media); break; case 'm': - pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); + pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, SDP_MAX_LINE); if (strcmp(comp, "audio") && strcmp(comp, "data") && strcmp(comp, "control") @@ -700,21 +702,21 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) else if (!strcmp(comp, "control")) media->Type = 5; else media->Type = 0; //port numbers - gf_token_get(LineBuf, pos, " ", comp, 3000); + gf_token_get(LineBuf, pos, " ", comp, SDP_MAX_LINE); if (!strstr(comp, "/")) { - pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \r\n", comp, SDP_MAX_LINE); media->PortNumber = atoi(comp); media->NumPorts = 0; } else { - pos = gf_token_get(LineBuf, pos, " /\r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " /\r\n", comp, SDP_MAX_LINE); media->PortNumber = atoi(comp); - pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \r\n", comp, SDP_MAX_LINE); media->NumPorts = atoi(comp); } //transport Profile - pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000); + pos = gf_token_get(LineBuf, pos, " \r\n", comp, SDP_MAX_LINE); media->Profile = gf_strdup(comp); - /*pos = */gf_token_get(LineBuf, pos, " \r\n", comp, 3000); + /*pos = */gf_token_get(LineBuf, pos, " \r\n", comp, SDP_MAX_LINE); media->fmt_list = gf_strdup(comp); gf_list_add(sdp->media_desc, media); @@ -733,7 +735,7 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) strcpy(LineBuf, ""); while (1) { if (!media->fmt_list) break; - pos = gf_token_get(media->fmt_list, pos, " ", comp, 3000); + pos = gf_token_get(media->fmt_list, pos, " ", comp, SDP_MAX_LINE); if (pos <= 0) break; if (!SDP_IsDynamicPayload(media, comp)) { if (!LinePos) { diff --git a/src/isomedia/isom_store.c b/src/isomedia/isom_store.c index b4e01dd854..e3cb2c0162 100644 --- a/src/isomedia/isom_store.c +++ b/src/isomedia/isom_store.c @@ -848,6 +848,7 @@ static GF_Err store_meta_item_references(GF_ISOFile *movie, GF_List *writers, GF GF_Err DoWriteMeta(GF_ISOFile *file, GF_MetaBox *meta, GF_BitStream *bs, Bool Emulation, u64 baseOffset, u64 *mdatSize) { + char cache_data[4096]; GF_ItemExtentEntry *entry; u64 maxExtendOffset, maxExtendSize; u32 i, j, count; @@ -926,7 +927,6 @@ GF_Err DoWriteMeta(GF_ISOFile *file, GF_MetaBox *meta, GF_BitStream *bs, Bool Em if (iinf->tk_id && iinf->sample_num) { } else if (src) { - char cache_data[4096]; u64 remain = entry->extent_length; while (remain) { u32 size_cache = (remain>4096) ? 4096 : (u32) remain; @@ -956,7 +956,6 @@ GF_Err DoWriteMeta(GF_ISOFile *file, GF_MetaBox *meta, GF_BitStream *bs, Bool Em /*Reading from the input file*/ if (!Emulation) { - char cache_data[4096]; u64 remain = entry->extent_length; gf_bs_seek(file->movieFileMap->bs, entry->original_extent_offset + iloc->original_base_offset); while (remain) { diff --git a/src/media_tools/isom_hinter.c b/src/media_tools/isom_hinter.c index 00cb858411..7877591af5 100644 --- a/src/media_tools/isom_hinter.c +++ b/src/media_tools/isom_hinter.c @@ -1185,22 +1185,24 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, GF_SDP_IODProfile IOD_Profile, u32 b GF_ISOSample *samp; Bool remove_ocr; u8 *buffer; - char buf64[5000], sdpLine[5100]; + char tmp_buf[201]; +// char buf64[5000], sdpLine[5100]; gf_isom_sdp_clean(file); + tmp_buf[200] = 0; if (bandwidth) { - sprintf(buf64, "b=AS:%d", bandwidth); - gf_isom_sdp_add_line(file, buf64); + snprintf(tmp_buf, 200, "b=AS:%d", bandwidth); + gf_isom_sdp_add_line(file, tmp_buf); } //xtended attribute for copyright if (gf_sys_is_test_mode()) { - sprintf(buf64, "a=x-copyright: %s", "MP4/3GP File hinted with GPAC - (c) Telecom ParisTech (http://gpac.io)"); + snprintf(tmp_buf, 200, "a=x-copyright: %s", "MP4/3GP File hinted with GPAC - (c) Telecom ParisTech (http://gpac.io)"); } else { - sprintf(buf64, "a=x-copyright: MP4/3GP File hinted with GPAC %s - %s", gf_gpac_version(), gf_gpac_copyright() ); + snprintf(tmp_buf, 200, "a=x-copyright: MP4/3GP File hinted with GPAC %s - %s", gf_gpac_version(), gf_gpac_copyright() ); } - gf_isom_sdp_add_line(file, buf64); + gf_isom_sdp_add_line(file, tmp_buf); if (IOD_Profile == GF_SDP_IOD_NONE) return GF_OK; @@ -1256,18 +1258,18 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, GF_SDP_IODProfile IOD_Profile, u32 b //set the SL for future extraction gf_isom_set_extraction_slc(file, odT, 1, &slc); - size64 = gf_base64_encode(samp->data, samp->dataLength, buf64, 2000); - buf64[size64] = 0; - sprintf(sdpLine, "data:application/mpeg4-od-au;base64,%s", buf64); - + u32 len_prfx = (u32) strlen("data:application/mpeg4-od-au;base64,"); + esd->URLString = gf_malloc(1 + len_prfx + samp->dataLength*3); + if (esd->URLString) { + strcpy(esd->URLString, "data:application/mpeg4-od-au;base64,"); + size64 = gf_base64_encode(samp->data, samp->dataLength, esd->URLString+len_prfx, samp->dataLength*3); + esd->URLString[len_prfx + size64] = 0; + } if (esd->decoderConfig) { esd->decoderConfig->avgBitrate = 0; esd->decoderConfig->bufferSizeDB = samp->dataLength; esd->decoderConfig->maxBitrate = 0; } - size64 = (u32) strlen(sdpLine)+1; - esd->URLString = (char*)gf_malloc(sizeof(char) * size64); - strcpy(esd->URLString, sdpLine); } else { GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[rtp hinter] OD sample too large to be embedded in IOD - ISMA disabled\n")); is_ok = 0; @@ -1293,17 +1295,18 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, GF_SDP_IODProfile IOD_Profile, u32 b //set the SL for future extraction gf_isom_set_extraction_slc(file, sceneT, 1, &slc); //encode in Base64 the sample - size64 = gf_base64_encode(samp->data, samp->dataLength, buf64, 2000); - buf64[size64] = 0; - sprintf(sdpLine, "data:application/mpeg4-bifs-au;base64,%s", buf64); - + u32 len_prfx = (u32) strlen("data:application/mpeg4-bifs-au;base64,"); + esd->URLString = gf_malloc(1 + len_prfx + samp->dataLength*3); + if (esd->URLString) { + strcpy(esd->URLString, "data:application/mpeg4-bifs-au;base64,"); + size64 = gf_base64_encode(samp->data, samp->dataLength, esd->URLString+len_prfx, samp->dataLength*3); + esd->URLString[len_prfx + size64] = 0; + } if (esd->decoderConfig) { esd->decoderConfig->avgBitrate = 0; esd->decoderConfig->bufferSizeDB = samp->dataLength; esd->decoderConfig->maxBitrate = 0; } - esd->URLString = (char*)gf_malloc(sizeof(char) * (strlen(sdpLine)+1)); - strcpy(esd->URLString, sdpLine); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[rtp hinter] Scene description sample too large to be embedded in IOD - ISMA disabled\n")); is_ok = 0; @@ -1337,8 +1340,8 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, GF_SDP_IODProfile IOD_Profile, u32 b } /*only 1 MPEG-4 visual max and 1 MPEG-4 audio max for ISMA compliancy*/ if (!has_v && !has_a && (has_i_v<=1) && (has_i_a<=1)) { - sprintf(sdpLine, "a=isma-compliance:1,1.0,1"); - gf_isom_sdp_add_line(file, sdpLine); + snprintf(tmp_buf, 200, "a=isma-compliance:1,1.0,1"); + gf_isom_sdp_add_line(file, tmp_buf); } } } @@ -1350,13 +1353,18 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, GF_SDP_IODProfile IOD_Profile, u32 b gf_odf_desc_del((GF_Descriptor *)iod); //encode in Base64 the iod - size64 = gf_base64_encode(buffer, size, buf64, 2000); - buf64[size64] = 0; + u32 len_prfx = (u32) strlen("a=mpeg4-iod:\"data:application/mpeg4-iod;base64,"); + u8 *buf64 = gf_malloc(size*3+4+len_prfx); + if (buf64) { + strcpy(buf64, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,"); + size64 = gf_base64_encode(buffer, size, buf64+len_prfx, size*3); + buf64[len_prfx + size64] = '"'; + buf64[len_prfx + size64+1] = 0; + gf_isom_sdp_add_line(file, buf64); + gf_free(buf64); + } gf_free(buffer); - sprintf(sdpLine, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"", buf64); - gf_isom_sdp_add_line(file, sdpLine); - return GF_OK; } diff --git a/src/media_tools/isom_tools.c b/src/media_tools/isom_tools.c index 87caf86284..21f2a55e9b 100644 --- a/src/media_tools/isom_tools.c +++ b/src/media_tools/isom_tools.c @@ -1389,11 +1389,16 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) e = gf_isom_get_meta_item_info(mp4, GF_TRUE, 0, item_idx, &item_id, &item_type, &prot_scheme, &prot_scheme_version, &is_self_ref, &name, &mime, &encoding, &url, &urn); if (e != GF_OK) return NULL; - if (item_type == GF_ISOM_SUBTYPE_HVC1) { - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; + GF_ImageItemProperties *props; + GF_SAFEALLOC(props, GF_ImageItemProperties); + if (!props) return NULL; + esd = gf_odf_desc_esd_new(0); + if (!esd) { + gf_free(props); + return NULL; + } + if (item_type == GF_ISOM_SUBTYPE_HVC1) { if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1401,27 +1406,25 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_HEVC; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); - if (e == GF_OK && props.config) { - GF_HEVCConfigurationBox *hvcc = props.config; + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); + if (e == GF_OK && props->config) { + GF_HEVCConfigurationBox *hvcc = props->config; if (hvcc->type==GF_ISOM_BOX_TYPE_HVCC) { gf_odf_hevc_cfg_write(hvcc->config, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); } else { gf_odf_desc_del((GF_Descriptor*)esd); + gf_free(props); return NULL; } } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if (item_type == GF_ISOM_SUBTYPE_AVC_H264) { - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; - if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1429,26 +1432,25 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_AVC; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); - if (e == GF_OK && props.config) { - GF_AVCConfigurationBox *avcc = props.config; + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); + if (e == GF_OK && props->config) { + GF_AVCConfigurationBox *avcc = props->config; if (avcc->type==GF_ISOM_BOX_TYPE_AVCC) { gf_odf_avc_cfg_write(avcc->config, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); } else { gf_odf_desc_del((GF_Descriptor*)esd); + gf_free(props); return NULL; } } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if (item_type == GF_ISOM_SUBTYPE_AV01) { - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1456,27 +1458,25 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_AV1; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); - if (e == GF_OK && props.config) { - GF_AV1ConfigurationBox *av1c = props.config; + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); + if (e == GF_OK && props->config) { + GF_AV1ConfigurationBox *av1c = props->config; if (av1c->type==GF_ISOM_BOX_TYPE_AV1C) { gf_odf_av1_cfg_write(av1c->config, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); } else { gf_odf_desc_del((GF_Descriptor*)esd); + gf_free(props); return NULL; } } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if ((item_type == GF_ISOM_SUBTYPE_JPEG) || (mime && !strcmp(mime, "image/jpeg")) ){ - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; - if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1484,21 +1484,18 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_JPEG; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); - if (e == GF_OK && props.config) { + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); + if (e == GF_OK && props->config) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("JPEG image item decoder config not supported, patch welcome\n")); } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if ((item_type == GF_ISOM_SUBTYPE_PNG) || (mime && !strcmp(mime, "image/png")) ){ - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; - if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1506,21 +1503,18 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_PNG; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); if (e) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Error fetching item properties %s\n", gf_error_to_string(e) )); } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if (item_type == GF_ISOM_SUBTYPE_VVC1) { - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; - if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1528,26 +1522,24 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_VVC; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); - if (e == GF_OK && props.config) { - GF_VVCConfigurationBox *vvcc = props.config; + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); + if (e == GF_OK && props->config) { + GF_VVCConfigurationBox *vvcc = props->config; if (vvcc->type == GF_ISOM_BOX_TYPE_VVCC) { gf_odf_vvc_cfg_write(vvcc->config, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); } else { gf_odf_desc_del((GF_Descriptor*)esd); + gf_free(props); return NULL; } } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if (item_type == GF_4CC('j','2','k','1')) { - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; - if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1555,24 +1547,21 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_J2K; - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, NULL); - if (e == GF_OK && props.config) { + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, NULL); + if (e == GF_OK && props->config) { GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_isom_box_write((GF_Box*)props.config, bs); + gf_isom_box_write((GF_Box*)props->config, bs); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); } esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } if ((item_type == GF_ISOM_SUBTYPE_UNCV) || (item_type == GF_ISOM_ITEM_TYPE_UNCI)) { - GF_ImageItemProperties props; - esd = gf_odf_desc_esd_new(0); - if (!esd) return NULL; - if (item_id > (1 << 16)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Item ID greater than 16 bits, does not fit on ES ID\n")); } @@ -1581,7 +1570,7 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GF_CODECID_RAW; GF_List *other_props = gf_list_new(); - e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, &props, other_props); + e = gf_isom_get_meta_image_props(mp4, GF_TRUE, 0, item_id, props, other_props); #ifndef GPAC_DISABLE_ISOM_WRITE if ((e == GF_OK) && gf_list_count(other_props)) { GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); @@ -1594,10 +1583,12 @@ GF_ESD *gf_media_map_item_esd(GF_ISOFile *mp4, u32 item_id) esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; esd->slConfig->useTimestampsFlag = 1; esd->slConfig->timestampResolution = 1000; + gf_free(props); return esd; } - + gf_odf_desc_del((GF_Descriptor*)esd); + gf_free(props); return NULL; } diff --git a/src/media_tools/media_export.c b/src/media_tools/media_export.c index c75abe2522..6e8e97ee6a 100644 --- a/src/media_tools/media_export.c +++ b/src/media_tools/media_export.c @@ -1099,16 +1099,20 @@ static GF_Err gf_media_export_filters(GF_MediaExporter *dumper) #ifdef GPAC_DISABLE_MEDIA_IMPORT return GF_NOT_SUPPORTED; #else - GF_MediaImporter import; - memset(&import, 0, sizeof(GF_MediaImporter)); - import.flags = GF_IMPORT_PROBE_ONLY; - import.in_name = dumper->in_name; - e = gf_media_import(&import); - if (e) return e; + GF_MediaImporter *import; + GF_SAFEALLOC(import, GF_MediaImporter); + if (!import) return GF_OUT_OF_MEM; + import->flags = GF_IMPORT_PROBE_ONLY; + import->in_name = dumper->in_name; + e = gf_media_import(import); + if (e) { + gf_free(import); + return e; + } Bool found = GF_FALSE; u32 i; - for (i=0; inb_tracks; i++) { + struct __track_import_info *tki = &import->tk_info[i]; if (!tki->codecid) continue; if (dumper->trackID) { if (dumper->trackID != tki->track_num) continue; @@ -1136,6 +1140,7 @@ static GF_Err gf_media_export_filters(GF_MediaExporter *dumper) dumper->track_type = 0; break; } + gf_free(import); if (!found) return GF_NOT_FOUND; #endif } diff --git a/src/media_tools/media_import.c b/src/media_tools/media_import.c index 3c7625210f..64fd453512 100644 --- a/src/media_tools/media_import.c +++ b/src/media_tools/media_import.c @@ -871,6 +871,7 @@ GF_Err gf_media_import_chapters_file(GF_MediaImporter *import) Bool found_chap = GF_FALSE; u32 i, h, m, s, ms, fr, fps; char line[1024]; + char szTemp[1025]; char szTitle[1024]; FILE *f = gf_fopen(import->in_name, "rt"); if (!f) return GF_URL_ERROR; @@ -1022,7 +1023,7 @@ GF_Err gf_media_import_chapters_file(GF_MediaImporter *import) ts = (h*3600 + m*60+s)*1000; } else { - char szTS[1025], *tok; + char *tok, *szTS = szTemp; strncpy(szTS, sL, 1024); szTS[1024]=0; tok = strrchr(szTS, ' '); @@ -1060,7 +1061,7 @@ GF_Err gf_media_import_chapters_file(GF_MediaImporter *import) /*CHAPTERX= and CHAPTERXNAME=*/ else if (!strnicmp(sL, "CHAPTER", 7)) { u32 idx; - char szTemp[1025], *str; + char *str; strncpy(szTemp, sL, 1024); szTemp[1024] = 0; str = strrchr(szTemp, '='); @@ -1130,7 +1131,7 @@ GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, GF_Fraction i { GF_Err e; u32 i; - GF_MediaImporter import; + GF_MediaImporter *import = NULL; //remove all chapter info gf_isom_remove_chapter(file, 0, 0); @@ -1147,17 +1148,18 @@ GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, GF_Fraction i } } - memset(&import, 0, sizeof(GF_MediaImporter)); - import.dest = file; - import.in_name = chap_file; - import.video_fps = import_fps; - import.streamFormat = "CHAP"; - e = gf_media_import(&import); - if (e) return e; - - if (!import.final_trackID) return GF_OK; + GF_SAFEALLOC(import, GF_MediaImporter); + import->dest = file; + import->in_name = chap_file; + import->video_fps = import_fps; + import->streamFormat = "CHAP"; + e = gf_media_import(import); + if (e || !import->final_trackID) { + gf_free(import); + return e; + } if (use_qt) { - u32 chap_track = gf_isom_get_track_by_id(file, import.final_trackID); + u32 chap_track = gf_isom_get_track_by_id(file, import->final_trackID); u32 nb_sdesc = gf_isom_get_sample_description_count(file, chap_track); for (i=0; ifinal_trackID); break; } } + gf_free(import); return GF_OK; } diff --git a/src/media_tools/mpegts.c b/src/media_tools/mpegts.c index a304273a50..d37a62f54f 100644 --- a/src/media_tools/mpegts.c +++ b/src/media_tools/mpegts.c @@ -3198,8 +3198,8 @@ void gf_m2ts_print_info(GF_M2TS_Demuxer *ts) } #endif -//50 packets max -#define M2TS_PROBE_SIZE 188*50 +//20 packets max +#define M2TS_PROBE_SIZE 188*20 static Bool gf_m2ts_probe_buffer(char *buf, u32 size) { GF_Err e; diff --git a/src/quickjs/quickjs.c b/src/quickjs/quickjs.c index f4246937e7..be2eef06a5 100644 --- a/src/quickjs/quickjs.c +++ b/src/quickjs/quickjs.c @@ -16299,7 +16299,7 @@ typedef enum { /* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JSValueConst this_obj, JSValueConst new_target, - int argc, JSValue *argv, int flags) + int argc, JSValue *argv, int in_flags) { JSRuntime *rt = caller_ctx->rt; JSContext *ctx; @@ -16311,6 +16311,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JSValue *local_buf, *stack_buf, *var_buf, *arg_buf, *sp, ret_val, *pval; JSVarRef **var_refs; size_t alloca_size; + JSValue val; + JSAtom atom; + JSValue op1, op2; + int ival; + int iflags; #if !DIRECT_DISPATCH #define SWITCH(pc) switch (opcode = *pc++) @@ -16337,7 +16342,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (js_poll_interrupts(caller_ctx)) return JS_EXCEPTION; if (unlikely(JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT)) { - if (flags & JS_CALL_FLAG_GENERATOR) { + if (in_flags & JS_CALL_FLAG_GENERATOR) { JSAsyncFunctionState *s = JS_VALUE_GET_PTR(func_obj); /* func_obj get contains a pointer to JSFuncAsyncState */ /* the stack frame is already allocated */ @@ -16371,11 +16376,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, return JS_ThrowTypeError(caller_ctx, "not a function"); } return call_func(caller_ctx, func_obj, this_obj, argc, - (JSValueConst *)argv, flags); + (JSValueConst *)argv, in_flags); } b = p->u.func.function_bytecode; - if (unlikely(argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV))) { + if (unlikely(argc < b->arg_count || (in_flags & JS_CALL_FLAG_COPY_ARGV))) { arg_allocated_size = b->arg_count; } else { arg_allocated_size = 0; @@ -16468,8 +16473,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_get_length): { - JSValue val; - val = JS_GetProperty(ctx, sp[-1], JS_ATOM_length); if (unlikely(JS_IsException(val))) goto exception; @@ -16491,7 +16494,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_push_this): /* OP_push_this is only called at the start of a function */ { - JSValue val; if (!(b->js_mode & JS_MODE_STRICT)) { uint32_t tag = JS_VALUE_GET_TAG(this_obj); if (likely(tag == JS_TAG_OBJECT)) @@ -16635,87 +16637,78 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_perm3): /* obj a b -> a obj b (213) */ { - JSValue tmp; - tmp = sp[-2]; + val = sp[-2]; sp[-2] = sp[-3]; - sp[-3] = tmp; + sp[-3] = val; } BREAK; CASE(OP_rot3l): /* x a b -> a b x (231) */ { - JSValue tmp; - tmp = sp[-3]; + val = sp[-3]; sp[-3] = sp[-2]; sp[-2] = sp[-1]; - sp[-1] = tmp; + sp[-1] = val; } BREAK; CASE(OP_rot4l): /* x a b c -> a b c x */ { - JSValue tmp; - tmp = sp[-4]; + val = sp[-4]; sp[-4] = sp[-3]; sp[-3] = sp[-2]; sp[-2] = sp[-1]; - sp[-1] = tmp; + sp[-1] = val; } BREAK; CASE(OP_rot5l): /* x a b c d -> a b c d x */ { - JSValue tmp; - tmp = sp[-5]; + val = sp[-5]; sp[-5] = sp[-4]; sp[-4] = sp[-3]; sp[-3] = sp[-2]; sp[-2] = sp[-1]; - sp[-1] = tmp; + sp[-1] = val; } BREAK; CASE(OP_rot3r): /* a b x -> x a b (312) */ { - JSValue tmp; - tmp = sp[-1]; + val = sp[-1]; sp[-1] = sp[-2]; sp[-2] = sp[-3]; - sp[-3] = tmp; + sp[-3] = val; } BREAK; CASE(OP_perm4): /* obj prop a b -> a obj prop b */ { - JSValue tmp; - tmp = sp[-2]; + val = sp[-2]; sp[-2] = sp[-3]; sp[-3] = sp[-4]; - sp[-4] = tmp; + sp[-4] = val; } BREAK; CASE(OP_perm5): /* this obj prop a b -> a this obj prop b */ { - JSValue tmp; - tmp = sp[-2]; + val = sp[-2]; sp[-2] = sp[-3]; sp[-3] = sp[-4]; sp[-4] = sp[-5]; - sp[-5] = tmp; + sp[-5] = val; } BREAK; CASE(OP_swap): /* a b -> b a */ { - JSValue tmp; - tmp = sp[-2]; + val = sp[-2]; sp[-2] = sp[-1]; - sp[-1] = tmp; + sp[-1] = val; } BREAK; CASE(OP_swap2): /* a b c d -> c d a b */ { - JSValue tmp1, tmp2; - tmp1 = sp[-4]; - tmp2 = sp[-3]; + op1 = sp[-4]; + op2 = sp[-3]; sp[-4] = sp[-2]; sp[-3] = sp[-1]; - sp[-2] = tmp1; - sp[-1] = tmp2; + sp[-2] = op1; + sp[-1] = op2; } BREAK; @@ -16882,7 +16875,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, #define JS_THROW_ERROR_DELETE_SUPER 3 #define JS_THROW_ERROR_ITERATOR_THROW 4 { - JSAtom atom; int type; atom = get_u32(pc); type = pc[4]; @@ -16989,7 +16981,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_import): { - JSValue val; val = js_dynamic_import(ctx, sp[-1]); if (JS_IsException(val)) goto exception; @@ -17001,7 +16992,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_check_var): { int ret; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17015,8 +17005,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_var_undef): CASE(OP_get_var): { - JSValue val; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17031,7 +17019,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_put_var_init): { int ret; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17045,7 +17032,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_put_var_strict): { int ret; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17063,34 +17049,28 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_check_define_var): { - JSAtom atom; - int flags; atom = get_u32(pc); - flags = pc[4]; + iflags = pc[4]; pc += 5; - if (JS_CheckDefineGlobalVar(ctx, atom, flags)) + if (JS_CheckDefineGlobalVar(ctx, atom, iflags)) goto exception; } BREAK; CASE(OP_define_var): { - JSAtom atom; - int flags; atom = get_u32(pc); - flags = pc[4]; + iflags = pc[4]; pc += 5; - if (JS_DefineGlobalVar(ctx, atom, flags)) + if (JS_DefineGlobalVar(ctx, atom, iflags)) goto exception; } BREAK; CASE(OP_define_func): { - JSAtom atom; - int flags; atom = get_u32(pc); - flags = pc[4]; + iflags = pc[4]; pc += 5; - if (JS_DefineGlobalFunction(ctx, atom, sp[-1], flags)) + if (JS_DefineGlobalFunction(ctx, atom, sp[-1], iflags)) goto exception; JS_FreeValue(ctx, sp[-1]); sp--; @@ -17196,7 +17176,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_var_ref): { int idx; - JSValue val; idx = get_u16(pc); pc += 2; val = *var_refs[idx]->pvalue; @@ -17224,7 +17203,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_var_ref_check): { int idx; - JSValue val; idx = get_u16(pc); pc += 2; val = *var_refs[idx]->pvalue; @@ -17324,7 +17302,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, { JSVarRef *var_ref; JSProperty *pr; - JSAtom atom; int idx; atom = get_u32(pc); idx = get_u16(pc + 4); @@ -17352,7 +17329,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_make_var_ref): { - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17382,7 +17358,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_if_true): { int res; - JSValue op1; op1 = sp[-1]; pc += 4; @@ -17402,7 +17377,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_if_false): { int res; - JSValue op1; op1 = sp[-1]; pc += 4; @@ -17423,7 +17397,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_if_true8): { int res; - JSValue op1; op1 = sp[-1]; pc += 1; @@ -17443,7 +17416,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_if_false8): { int res; - JSValue op1; op1 = sp[-1]; pc += 1; @@ -17482,7 +17454,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_ret): { - JSValue op1; uint32_t pos; op1 = sp[-1]; if (unlikely(JS_VALUE_GET_TAG(op1) != JS_TAG_INT)) @@ -17593,16 +17564,15 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, { JSValue method, ret; BOOL ret_flag; - int flags; - flags = *pc++; - method = JS_GetProperty(ctx, sp[-4], (flags & 1) ? + iflags = *pc++; + method = JS_GetProperty(ctx, sp[-4], (iflags & 1) ? JS_ATOM_throw : JS_ATOM_return); if (JS_IsException(method)) goto exception; if (JS_IsUndefined(method) || JS_IsNull(method)) { ret_flag = TRUE; } else { - if (flags & 2) { + if (iflags & 2) { /* no argument */ ret = JS_CallFree(ctx, method, sp[-4], 0, NULL); @@ -17624,7 +17594,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_lnot): { int res; - JSValue op1; op1 = sp[-1]; if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { @@ -17638,8 +17607,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_field): { - JSValue val; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17653,8 +17620,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_field2): { - JSValue val; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17668,7 +17633,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_put_field): { int ret; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17683,9 +17647,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_private_symbol): { - JSAtom atom; - JSValue val; - atom = get_u32(pc); pc += 4; val = JS_NewSymbolFromAtom(ctx, atom, JS_ATOM_TYPE_PRIVATE); @@ -17697,7 +17658,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_private_field): { - JSValue val; val = JS_GetPrivateField(ctx, sp[-2], sp[-1]); JS_FreeValue(ctx, sp[-1]); @@ -17735,7 +17695,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_define_field): { int ret; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17750,7 +17709,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_set_name): { int ret; - JSAtom atom; atom = get_u32(pc); pc += 4; @@ -17787,8 +17745,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, { JSValue getter, setter, value; JSValueConst obj; - JSAtom atom; - int flags, ret, op_flags; + int ret, op_flags; BOOL is_computed; #define OP_DEFINE_METHOD_METHOD 0 #define OP_DEFINE_METHOD_GETTER 1 @@ -17808,28 +17765,28 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, op_flags = *pc++; obj = sp[-2 - is_computed]; - flags = JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE | + iflags = JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE | JS_PROP_THROW; if (op_flags & OP_DEFINE_METHOD_ENUMERABLE) - flags |= JS_PROP_ENUMERABLE; + iflags |= JS_PROP_ENUMERABLE; op_flags &= 3; value = JS_UNDEFINED; getter = JS_UNDEFINED; setter = JS_UNDEFINED; if (op_flags == OP_DEFINE_METHOD_METHOD) { value = sp[-1]; - flags |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE; + iflags |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE; } else if (op_flags == OP_DEFINE_METHOD_GETTER) { getter = sp[-1]; - flags |= JS_PROP_HAS_GET; + iflags |= JS_PROP_HAS_GET; } else { setter = sp[-1]; - flags |= JS_PROP_HAS_SET; + iflags |= JS_PROP_HAS_SET; } - ret = js_method_set_properties(ctx, sp[-1], atom, flags, obj); + ret = js_method_set_properties(ctx, sp[-1], atom, iflags, obj); if (ret >= 0) { ret = JS_DefineProperty(ctx, obj, atom, value, - getter, setter, flags); + getter, setter, iflags); } JS_FreeValue(ctx, sp[-1]); if (is_computed) { @@ -17845,13 +17802,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_define_class): CASE(OP_define_class_computed): { - int class_flags; - JSAtom atom; - atom = get_u32(pc); - class_flags = pc[4]; + iflags = pc[4]; pc += 5; - if (js_op_define_class(ctx, sp, atom, class_flags, + if (js_op_define_class(ctx, sp, atom, iflags, var_refs, sf, (opcode == OP_define_class_computed)) < 0) goto exception; @@ -17860,7 +17814,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_array_el): { - JSValue val; val = JS_GetPropertyValue(ctx, sp[-2], sp[-1]); JS_FreeValue(ctx, sp[-2]); @@ -17873,7 +17826,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_array_el2): { - JSValue val; val = JS_GetPropertyValue(ctx, sp[-2], sp[-1]); sp[-1] = val; @@ -17884,9 +17836,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_ref_value): { - JSValue val; if (unlikely(JS_IsUndefined(sp[-2]))) { - JSAtom atom = JS_ValueToAtom(ctx, sp[-1]); + atom = JS_ValueToAtom(ctx, sp[-1]); if (atom != JS_ATOM_NULL) { JS_ThrowReferenceErrorNotDefined(ctx, atom); JS_FreeAtom(ctx, atom); @@ -17904,8 +17855,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_get_super_value): { - JSValue val; - JSAtom atom; atom = JS_ValueToAtom(ctx, sp[-1]); if (unlikely(atom == JS_ATOM_NULL)) goto exception; @@ -17935,11 +17884,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_put_ref_value): { - int ret, flags; - flags = JS_PROP_THROW_STRICT; + int ret; + iflags = JS_PROP_THROW_STRICT; if (unlikely(JS_IsUndefined(sp[-3]))) { if (is_strict_mode(ctx)) { - JSAtom atom = JS_ValueToAtom(ctx, sp[-2]); + atom = JS_ValueToAtom(ctx, sp[-2]); if (atom != JS_ATOM_NULL) { JS_ThrowReferenceErrorNotDefined(ctx, atom); JS_FreeAtom(ctx, atom); @@ -17950,9 +17899,9 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } } else { if (is_strict_mode(ctx)) - flags |= JS_PROP_NO_ADD; + iflags |= JS_PROP_NO_ADD; } - ret = JS_SetPropertyValue(ctx, sp[-3], sp[-2], sp[-1], flags); + ret = JS_SetPropertyValue(ctx, sp[-3], sp[-2], sp[-1], iflags); JS_FreeValue(ctx, sp[-3]); sp -= 3; if (unlikely(ret < 0)) @@ -17963,7 +17912,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_put_super_value): { int ret; - JSAtom atom; if (JS_VALUE_GET_TAG(sp[-3]) != JS_TAG_OBJECT) { JS_ThrowTypeErrorNotAnObject(ctx); goto exception; @@ -18020,7 +17968,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_add): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18059,7 +18006,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, *pv = JS_NewInt32(ctx, r); sp--; } else if (JS_VALUE_GET_TAG(*pv) == JS_TAG_STRING) { - JSValue op1; op1 = sp[-1]; sp--; op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); @@ -18085,7 +18031,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_sub): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18106,7 +18051,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_mul): { - JSValue op1, op2; double d; op1 = sp[-2]; op2 = sp[-1]; @@ -18148,7 +18092,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_div): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18169,7 +18112,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_math_mod): #endif { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18197,7 +18139,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_plus): { - JSValue op1; uint32_t tag; op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); @@ -18210,24 +18151,22 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_neg): { - JSValue op1; uint32_t tag; - int val; double d; op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); if (tag == JS_TAG_INT) { - val = JS_VALUE_GET_INT(op1); + ival = JS_VALUE_GET_INT(op1); /* Note: -0 cannot be expressed as integer */ - if (unlikely(val == 0)) { + if (unlikely(ival == 0)) { d = -0.0; goto neg_fp_res; } - if (unlikely(val == INT32_MIN)) { - d = -(double)val; + if (unlikely(ival == INT32_MIN)) { + d = -(double)ival; goto neg_fp_res; } - sp[-1] = JS_NewInt32(ctx, -val); + sp[-1] = JS_NewInt32(ctx, -ival); } else if (JS_TAG_IS_FLOAT64(tag)) { d = -JS_VALUE_GET_FLOAT64(op1); neg_fp_res: @@ -18240,14 +18179,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_inc): { - JSValue op1; - int val; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { - val = JS_VALUE_GET_INT(op1); - if (unlikely(val == INT32_MAX)) + ival = JS_VALUE_GET_INT(op1); + if (unlikely(ival == INT32_MAX)) goto inc_slow; - sp[-1] = JS_NewInt32(ctx, val + 1); + sp[-1] = JS_NewInt32(ctx, ival + 1); } else { inc_slow: if (js_unary_arith_slow(ctx, sp, opcode)) @@ -18257,14 +18194,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_dec): { - JSValue op1; - int val; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { - val = JS_VALUE_GET_INT(op1); - if (unlikely(val == INT32_MIN)) + ival = JS_VALUE_GET_INT(op1); + if (unlikely(ival == INT32_MIN)) goto dec_slow; - sp[-1] = JS_NewInt32(ctx, val - 1); + sp[-1] = JS_NewInt32(ctx, ival - 1); } else { dec_slow: if (js_unary_arith_slow(ctx, sp, opcode)) @@ -18280,18 +18215,16 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_inc_loc): { - JSValue op1; - int val; int idx; idx = *pc; pc += 1; op1 = var_buf[idx]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { - val = JS_VALUE_GET_INT(op1); - if (unlikely(val == INT32_MAX)) + ival = JS_VALUE_GET_INT(op1); + if (unlikely(ival == INT32_MAX)) goto inc_loc_slow; - var_buf[idx] = JS_NewInt32(ctx, val + 1); + var_buf[idx] = JS_NewInt32(ctx, ival + 1); } else { inc_loc_slow: /* must duplicate otherwise the variable value may @@ -18305,18 +18238,16 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_dec_loc): { - JSValue op1; - int val; int idx; idx = *pc; pc += 1; op1 = var_buf[idx]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { - val = JS_VALUE_GET_INT(op1); - if (unlikely(val == INT32_MIN)) + ival = JS_VALUE_GET_INT(op1); + if (unlikely(ival == INT32_MIN)) goto dec_loc_slow; - var_buf[idx] = JS_NewInt32(ctx, val - 1); + var_buf[idx] = JS_NewInt32(ctx, ival - 1); } else { dec_loc_slow: /* must duplicate otherwise the variable value may @@ -18330,7 +18261,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_not): { - JSValue op1; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { sp[-1] = JS_NewInt32(ctx, ~JS_VALUE_GET_INT(op1)); @@ -18343,7 +18273,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_shl): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18380,7 +18309,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_shr): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18401,7 +18329,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_sar): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18432,7 +18359,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_and): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18449,7 +18375,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_or): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18466,7 +18391,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_xor): { - JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { @@ -18486,7 +18410,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, #define OP_CMP(opcode, binary_op, slow_call) \ CASE(opcode): \ { \ - JSValue op1, op2; \ op1 = sp[-2]; \ op2 = sp[-1]; \ if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { \ @@ -18528,8 +18451,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_typeof): { - JSValue op1; - JSAtom atom; op1 = sp[-1]; atom = js_operator_typeof(ctx, op1); @@ -18544,7 +18465,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, BREAK; CASE(OP_delete_var): { - JSAtom atom; int ret; atom = get_u32(pc); @@ -18621,9 +18541,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_with_get_ref): CASE(OP_with_get_ref_undef): { - JSAtom atom; int32_t diff; - JSValue obj, val; + JSValue obj; int ret, is_with; atom = get_u32(pc); diff = get_u32(pc + 4); @@ -18774,7 +18693,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } if (!JS_IsUncatchableError(ctx, rt->current_exception)) { while (sp > stack_buf) { - JSValue val = *--sp; + val = *--sp; JS_FreeValue(ctx, val); if (JS_VALUE_GET_TAG(val) == JS_TAG_CATCH_OFFSET) { int pos = JS_VALUE_GET_INT(val); diff --git a/src/scene_manager/encode_isom.c b/src/scene_manager/encode_isom.c index 680d511626..2262d08ca7 100644 --- a/src/scene_manager/encode_isom.c +++ b/src/scene_manager/encode_isom.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2012 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Scene Management sub-project @@ -130,7 +130,6 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD char szName[1024]; char *ext; GF_Descriptor *d; - GF_MediaImporter import; GF_MuxInfo *mux = NULL; if (od_sample_rap && src->ESID && gf_isom_get_track_by_id(mp4, src->ESID) ) { @@ -218,13 +217,15 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD track = gf_isom_get_track_by_id(mp4, src->ESID); if (track) return GF_OK; if (mediaSource) { - memset(&import, 0, sizeof(GF_MediaImporter)); - import.dest = mp4; - import.trackID = src->ESID; - import.orig = gf_isom_open(mediaSource, GF_ISOM_OPEN_READ, NULL); - if (import.orig) { - e = gf_media_import(&import); - gf_isom_delete(import.orig); + GF_MediaImporter *import; + GF_SAFEALLOC(import, GF_MediaImporter); + if (!import) return GF_OUT_OF_MEM; + import->dest = mp4; + import->trackID = src->ESID; + import->orig = gf_isom_open(mediaSource, GF_ISOM_OPEN_READ, NULL); + if (import->orig) { + e = gf_media_import(import); + gf_isom_delete(import->orig); return e; } } @@ -233,7 +234,10 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD if (!mux->file_name) return GF_OK; - memset(&import, 0, sizeof(GF_MediaImporter)); + GF_MediaImporter *import; + GF_SAFEALLOC(import, GF_MediaImporter); + if (!import) return GF_OUT_OF_MEM; + if (mux->src_url) { ext = gf_url_concatenate(mux->src_url, mux->file_name); strcpy(szName, ext ? ext : mux->file_name); @@ -256,8 +260,8 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] missing track specifier for AVI import (file#audio, file#video)\n")); return GF_NOT_SUPPORTED; } - if (isVideo) import.trackID = 1; - else import.trackID = 2; + if (isVideo) import->trackID = 1; + else import->trackID = 2; ext = strchr(ext, '#'); if (ext) ext[0] = 0; } @@ -265,31 +269,35 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD if (ext) { ext = strchr(ext, '#'); if (ext) { - import.trackID = atoi(ext+1); + import->trackID = atoi(ext+1); ext[0] = 0; } } - import.streamFormat = mux->streamFormat; - import.dest = mp4; - import.esd = src; + import->streamFormat = mux->streamFormat; + import->dest = mp4; + import->esd = src; if (mux->duration) { - import.duration.num = mux->duration; - import.duration.den = 1000; + import->duration.num = mux->duration; + import->duration.den = 1000; + } + import->flags = mux->import_flags | GF_IMPORT_FORCE_MPEG4; + import->video_fps.num = (s32) (1000*mux->frame_rate); + import->video_fps.den = 1000; + import->in_name = szName; + import->initial_time_offset = imp_time; + e = gf_media_import(import); + if (e) { + gf_free(import); + return e; } - import.flags = mux->import_flags | GF_IMPORT_FORCE_MPEG4; - import.video_fps.num = (s32) (1000*mux->frame_rate); - import.video_fps.den = 1000; - import.in_name = szName; - import.initial_time_offset = imp_time; - e = gf_media_import(&import); - if (e) return e; - if (src->OCRESID) { - gf_isom_set_track_reference(mp4, gf_isom_get_track_by_id(mp4, import.final_trackID), GF_ISOM_REF_OCR, src->OCRESID); + gf_isom_set_track_reference(mp4, gf_isom_get_track_by_id(mp4, import->final_trackID), GF_ISOM_REF_OCR, src->OCRESID); } - track = gf_isom_get_track_by_id(mp4, import.final_trackID); + track = gf_isom_get_track_by_id(mp4, import->final_trackID); + gf_free(import); + i=0; while ((d = gf_list_enum(src->extensionDescriptors, &i))) { Bool do_del = GF_FALSE; diff --git a/src/scene_manager/loader_bt.c b/src/scene_manager/loader_bt.c index c856557370..817233446a 100644 --- a/src/scene_manager/loader_bt.c +++ b/src/scene_manager/loader_bt.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / Scene Management sub-project @@ -107,6 +107,7 @@ typedef struct u32 def_w, def_h; + unsigned short line_cache[BT_LINE_SIZE]; } GF_BTParser; GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdList); @@ -173,7 +174,7 @@ void gf_bt_check_line(GF_BTParser *parser) if (parser->unicode_type) { u8 c1, c2; unsigned short wchar; - unsigned short l[BT_LINE_SIZE]; + unsigned short *l = parser->line_cache; unsigned short *dst = l; Bool is_ret = 0; u32 last_space_pos, last_space_pos_stream; @@ -3790,34 +3791,42 @@ GF_Err gf_sm_load_init_bt(GF_SceneLoader *load) GF_EXPORT GF_List *gf_sm_load_bt_from_string(GF_SceneGraph *in_scene, char *node_str, Bool force_wrl) { - GF_SceneLoader ctx; - GF_BTParser parser; - memset(&ctx, 0, sizeof(GF_SceneLoader)); - ctx.scene_graph = in_scene; - memset(&parser, 0, sizeof(GF_BTParser)); - parser.line_buffer = node_str; - parser.line_size = (u32) strlen(node_str); - parser.load = &ctx; - parser.top_nodes = gf_list_new(); - parser.undef_nodes = gf_list_new(); - parser.def_nodes = gf_list_new(); - parser.peeked_nodes = gf_list_new(); - parser.is_wrl = force_wrl; - gf_bt_loader_run_intern(&parser, NULL, 1); - gf_list_del(parser.undef_nodes); - gf_list_del(parser.def_nodes); - gf_list_del(parser.peeked_nodes); - while (gf_list_count(parser.def_symbols)) { - BTDefSymbol *d = (BTDefSymbol *)gf_list_get(parser.def_symbols, 0); - gf_list_rem(parser.def_symbols, 0); + GF_SceneLoader *ctx; + GF_BTParser *parser; + GF_SAFEALLOC(ctx, GF_SceneLoader); + if (!ctx) return gf_list_new(); + ctx->scene_graph = in_scene; + GF_SAFEALLOC(parser, GF_BTParser); + if (!parser) { + gf_free(ctx); + return gf_list_new(); + } + parser->line_buffer = node_str; + parser->line_size = (u32) strlen(node_str); + parser->load = ctx; + parser->top_nodes = gf_list_new(); + parser->undef_nodes = gf_list_new(); + parser->def_nodes = gf_list_new(); + parser->peeked_nodes = gf_list_new(); + parser->is_wrl = force_wrl; + gf_bt_loader_run_intern(parser, NULL, 1); + gf_list_del(parser->undef_nodes); + gf_list_del(parser->def_nodes); + gf_list_del(parser->peeked_nodes); + while (gf_list_count(parser->def_symbols)) { + BTDefSymbol *d = (BTDefSymbol *)gf_list_get(parser->def_symbols, 0); + gf_list_rem(parser->def_symbols, 0); gf_free(d->name); gf_free(d->value); gf_free(d); } - gf_list_del(parser.def_symbols); - gf_list_del(parser.scripts); + gf_list_del(parser->def_symbols); + gf_list_del(parser->scripts); + GF_List *result = parser->top_nodes; + gf_free(parser); + gf_free(ctx); - return parser.top_nodes; + return result; } #endif /*GPAC_DISABLE_LOADER_BT*/ diff --git a/src/scene_manager/scene_engine.c b/src/scene_manager/scene_engine.c index b22474ddbb..50aee5e842 100644 --- a/src/scene_manager/scene_engine.c +++ b/src/scene_manager/scene_engine.c @@ -2,7 +2,7 @@ * GPAC Multimedia Framework * * Authors: Jean Le Feuvre, Cyril Concolato - * Copyright (c) Telecom ParisTech 2000-2023 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / ISO Media File Format sub-project @@ -290,8 +290,6 @@ static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *co GF_SceneDumper *dumper = NULL; #endif GF_Err e; - char rad_name[4096]; - char file_name[4096+100]; u32 fsize; u8 *buffer = NULL; GF_BitStream *bs = NULL; @@ -302,23 +300,37 @@ static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *co u32 buffer_len; const char *cache_dir; char *dump_name; + char *base_name = NULL; + char p_sep[2]; if (!data) return GF_BAD_PARAM; if (!seng->dump_path) cache_dir = gf_get_default_cache_directory(); else cache_dir = seng->dump_path; + p_sep[0] = GF_PATH_SEPARATOR; + p_sep[1] = 0; + dump_name = "gpac_scene_engine_dump"; #ifdef DUMP_DIMS_LOG_WITH_TIME start: #endif + if (base_name) { + gf_free(base_name); + base_name=NULL; + } + if (commands && gf_list_count(commands)) { - sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, dump_name, "_update"); + gf_dynstrcat(&base_name, cache_dir, NULL); + gf_dynstrcat(&base_name, dump_name, p_sep); + gf_dynstrcat(&base_name, "_update", NULL); } else { #ifndef DUMP_DIMS_LOG_WITH_TIME - sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, "rap_", dump_name); + gf_dynstrcat(&base_name, cache_dir, NULL); + gf_dynstrcat(&base_name, "rap_", p_sep); + gf_dynstrcat(&base_name, dump_name, NULL); #else char date_str[100], time_str[100]; time_t now; @@ -327,14 +339,18 @@ static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *co tm_tot = localtime(&now); strftime(date_str, 100, "%Yy%mm%dd", tm_tot); strftime(time_str, 100, "%Hh%Mm%Ss", tm_tot); - sprintf(rad_name, "%s%c%s-%s-%s%s", cache_dir, GF_PATH_SEPARATOR, date_str, time_str, "rap_", dump_name); + //format as cache_dir / date_str - time_str -rap_ dump_name); + gf_dynstrcat(&base_name, cache_dir, NULL); + gf_dynstrcat(&base_name, date_str, p_sep); + gf_dynstrcat(&base_name, time_str, "-"); + gf_dynstrcat(&base_name, dump_name, "-rap_"); #endif } #ifndef GPAC_DISABLE_SCENE_DUMP - dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, GF_FALSE, ' ', GF_SM_DUMP_SVG); + dumper = gf_sm_dumper_new(seng->ctx->scene_graph, base_name, GF_FALSE, ' ', GF_SM_DUMP_SVG); if (!dumper) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", base_name)); e = GF_IO_ERR; goto exit; } @@ -350,12 +366,17 @@ static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *co #if 0 //unused if(seng->dump_rap) { GF_SceneDumper *dumper = NULL; + if (base_name) { + gf_free(base_name); + base_name = NULL; + } + gf_dynstrcat(&base_name, cache_dir, NULL); + gf_dynstrcat(&base_name, "rap_", p_sep); + gf_dynstrcat(&base_name, dump_name, NULL); - sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, "rap_", dump_name); - - dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, GF_FALSE, ' ', GF_SM_DUMP_SVG); + dumper = gf_sm_dumper_new(seng->ctx->scene_graph, base_name, GF_FALSE, ' ', GF_SM_DUMP_SVG); if (!dumper) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", base_name)); e = GF_IO_ERR; goto exit; } @@ -377,11 +398,11 @@ static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *co } #endif - sprintf(file_name, "%s.svg", rad_name); + gf_dynstrcat(&base_name, ".svg", NULL); - e = gf_file_load_data(file_name, (u8 **) &buffer, &fsize); + e = gf_file_load_data(base_name, (u8 **) &buffer, &fsize); if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Error loading SVG dump file %s\n", file_name)); + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Error loading SVG dump file %s\n", base_name)); goto exit; } @@ -440,6 +461,7 @@ static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *co gf_bs_del(bs); exit: + if (base_name) gf_free(base_name); if (buffer) gf_free(buffer); return e; } diff --git a/src/utils/base_encoding.c b/src/utils/base_encoding.c index 42617eaf6d..9ba0f661cf 100644 --- a/src/utils/base_encoding.c +++ b/src/utils/base_encoding.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2022 + * Copyright (c) Telecom ParisTech 2000-2024 * All rights reserved * * This file is part of GPAC / common tools sub-project @@ -407,7 +407,8 @@ GF_Err gf_lz_decompress_payload(u8 *data, u32 data_len, u8 **uncompressed_data, u32 block_size = 4096; u32 done = 0; u32 alloc_size = 0; - u8 block[4096]; + u8 *block = gf_malloc(4096); + if (!block) return GF_OUT_OF_MEM; u8 *dst_buffer = NULL; if (*uncompressed_data) { @@ -444,12 +445,14 @@ GF_Err gf_lz_decompress_payload(u8 *data, u32 data_len, u8 **uncompressed_data, if (ret != LZMA_OK) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[LZMA] error decompressing data: %d\n", ret )); if (owns_buffer) gf_free(dst_buffer); + gf_free(block); return GF_IO_ERR; } } *uncompressed_data = dst_buffer; *out_size = done; + gf_free(block); return GF_OK; } #else diff --git a/src/utils/xml_parser.c b/src/utils/xml_parser.c index 93c11bea9d..89606ec14f 100644 --- a/src/utils/xml_parser.c +++ b/src/utils/xml_parser.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2005-2023 + * Copyright (c) Telecom ParisTech 2005-2024 * All rights reserved * * This file is part of GPAC / common tools sub-project @@ -1433,7 +1433,7 @@ char *gf_xml_sax_peek_node(GF_SAXParser *parser, char *att_name, char *att_value #endif Bool from_buffer; Bool dobreak=GF_FALSE; - char szLine1[XML_INPUT_SIZE+2], szLine2[XML_INPUT_SIZE+2], *szLine, *cur_line, *sep, *start, first_c, *result; + char *szLine1, *szLine2, *szLine, *cur_line, *sep, *start, first_c, *result; #define CPYCAT_ALLOC(__str, __is_copy) _len = (u32) strlen(__str);\ @@ -1454,6 +1454,13 @@ char *gf_xml_sax_peek_node(GF_SAXParser *parser, char *att_name, char *att_value result = NULL; + szLine1 = gf_malloc(sizeof(char)*(XML_INPUT_SIZE+2)); + if (!szLine1) return NULL; + szLine2 = gf_malloc(sizeof(char)*(XML_INPUT_SIZE+2)); + if (!szLine2) { + gf_free(szLine1); + return NULL; + } szLine1[0] = szLine2[0] = 0; pos=0; if (!from_buffer) { @@ -1467,6 +1474,11 @@ char *gf_xml_sax_peek_node(GF_SAXParser *parser, char *att_name, char *att_value if (att_len<2*XML_INPUT_SIZE) att_len = 2*XML_INPUT_SIZE; alloc_size = att_len; szLine = (char *) gf_malloc(sizeof(char)*alloc_size); + if (!szLine) { + gf_free(szLine1); + gf_free(szLine2); + return NULL; + } strcpy(szLine, parser->buffer + parser->att_name_start); cur_line = szLine; att_len = (u32) strlen(att_value); @@ -1591,6 +1603,8 @@ char *gf_xml_sax_peek_node(GF_SAXParser *parser, char *att_name, char *att_value } exit: gf_free(szLine); + gf_free(szLine1); + gf_free(szLine2); if (!from_buffer) { #ifdef NO_GZIP From 4b534b03d539b2d42a9beef656c31ec7dee6c81f Mon Sep 17 00:00:00 2001 From: jeanlf Date: Wed, 16 Oct 2024 14:13:34 +0200 Subject: [PATCH 4/5] fixed bug in previous commit --- src/filters/isoffin_load.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/filters/isoffin_load.c b/src/filters/isoffin_load.c index 5ec6e8d80c..c22aca6864 100644 --- a/src/filters/isoffin_load.c +++ b/src/filters/isoffin_load.c @@ -139,10 +139,10 @@ static void isor_export_ref(ISOMReader *read, ISOMChannel *ch, u32 rtype, char * } } -static void isor_setup_channel(ISOMReader *read, ISOMChannel *ch, u32 track, u32 streamtype, Bool use_iod, u32 esid, u32 depends_on_id, u32 ocr_es_id) +static ISOMChannel *isor_setup_channel(ISOMReader *read, u32 track, u32 streamtype, Bool use_iod, u32 esid, u32 depends_on_id, u32 ocr_es_id, Bool set_lang) { + ISOMChannel *ch=NULL; u32 base_track; - GF_Language *lang_desc = NULL; //first setup, creation of PID and channel Bool use_sidx_dur = GF_FALSE; Bool external_base = GF_FALSE; @@ -159,7 +159,7 @@ static void isor_setup_channel(ISOMReader *read, ISOMChannel *ch, u32 track, u32 gf_isom_get_reference(read->mov, track, GF_ISOM_REF_BASE, 1, &base_track); //pass on all configs to detect scalability presence and TX3G as we need to export some vars for all configs - for (u32 stsd_idx=0; stsd_idxmov, track); stsd_idx++) { + for (u32 stsd_idx=1; stsd_idx<=gf_isom_get_sample_description_count(read->mov, track); stsd_idx++) { u32 m_subtype = gf_isom_get_media_subtype(read->mov, track, stsd_idx); if (m_subtype == GF_ISOM_SUBTYPE_TX3G) use_tx3g = GF_TRUE; @@ -276,14 +276,12 @@ static void isor_setup_channel(ISOMReader *read, ISOMChannel *ch, u32 track, u32 //create our channel ch = isor_create_channel(read, pid, track, 0, (use_lhvc) ? GF_TRUE : GF_FALSE); - if (lang_desc) { + if (set_lang) { char *lang=NULL; gf_isom_get_media_language(read->mov, track, &lang); //s32 idx = gf_lang_find(lang); gf_filter_pid_set_property(pid, GF_PROP_PID_LANGUAGE, &PROP_STRING( lang )); if (lang) gf_free(lang); - gf_odf_desc_del((GF_Descriptor *)lang_desc); - lang_desc = NULL; } ch->streamType = streamtype; @@ -674,6 +672,7 @@ static void isor_setup_channel(ISOMReader *read, ISOMChannel *ch, u32 track, u32 gf_filter_pid_set_property_str(ch->pid, "nofrag", &PROP_BOOL(GF_TRUE)); } } + return ch; } static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 stsd_idx, u32 streamtype, Bool use_iod) @@ -684,7 +683,6 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 GF_Language *lang_desc = NULL; u8 *dsi = NULL, *enh_dsi = NULL; u32 dsi_size = 0, enh_dsi_size = 0; - Double track_dur=0; u32 srd_id=0, srd_indep=0, srd_x=0, srd_y=0, srd_w=0, srd_h=0; u32 base_tile_track=0; u64 ch_layout=0; @@ -1079,7 +1077,7 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 //first setup, creation of PID and channel if (!ch) { first_config = GF_TRUE; - isor_setup_channel(read, ch, track, streamtype, use_iod, esid, depends_on_id, ocr_es_id); + ch = isor_setup_channel(read, track, streamtype, use_iod, esid, depends_on_id, ocr_es_id, lang_desc ? GF_TRUE : GF_FALSE); } @@ -1416,6 +1414,8 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 if (!avg_rate) { if (first_config && ch->duration) { + Double track_dur = (Double) (s64) ch->duration; //in media timescale + track_dur /= ch->timescale; u64 avgrate = 8 * gf_isom_get_media_data_size(read->mov, ch->track); avgrate = (u64) (avgrate / track_dur); gf_filter_pid_set_property(ch->pid, GF_PROP_PID_BITRATE, &PROP_UINT((u32) avgrate)); From 3bb379d9d1655f46039ecfbef629e7e412a865a4 Mon Sep 17 00:00:00 2001 From: jeanlf Date: Fri, 18 Oct 2024 08:59:04 +0200 Subject: [PATCH 5/5] fixed wrong sample desc index in SRD fetching --- src/filters/isoffin_load.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/filters/isoffin_load.c b/src/filters/isoffin_load.c index c22aca6864..2f89c5f39e 100644 --- a/src/filters/isoffin_load.c +++ b/src/filters/isoffin_load.c @@ -801,7 +801,7 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 if (base_tile_track) { depends_on_id = gf_isom_get_track_id(read->mov, base_tile_track); } - gf_isom_get_tile_info(read->mov, track, 1, NULL, &srd_id, &srd_indep, &srd_full_frame, &srd_x, &srd_y, &srd_w, &srd_h); + gf_isom_get_tile_info(read->mov, track, stsd_idx, NULL, &srd_id, &srd_indep, &srd_full_frame, &srd_x, &srd_y, &srd_w, &srd_h); break; case GF_ISOM_SUBTYPE_TEXT: case GF_ISOM_SUBTYPE_TX3G: @@ -943,7 +943,7 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 return; } codec_id = GF_CODECID_VVC_SUBPIC; - gf_isom_get_tile_info(read->mov, track, 1, NULL, &srd_id, &srd_indep, &srd_full_frame, &srd_x, &srd_y, &srd_w, &srd_h); + gf_isom_get_tile_info(read->mov, track, stsd_idx, NULL, &srd_id, &srd_indep, &srd_full_frame, &srd_x, &srd_y, &srd_w, &srd_h); break; case GF_ISOM_SUBTYPE_AC3: @@ -1524,7 +1524,7 @@ static void isor_declare_track(ISOMReader *read, ISOMChannel *ch, u32 track, u32 } } else if (codec_id==GF_CODECID_DTS_X) { GF_UDTSConfig cfg; - if (gf_isom_get_udts_config(ch->owner->mov, ch->track, 1, &cfg) == GF_OK) { + if (gf_isom_get_udts_config(ch->owner->mov, ch->track, stsd_idx, &cfg) == GF_OK) { u64 ch_layout = cfg.ChannelMask; gf_filter_pid_set_property(ch->pid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(ch_layout)); }