From 65b9745cb7fed21a273e0223a30c214cd0c0b051 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 31 Jul 2014 14:11:44 +0100 Subject: [PATCH] Imported Upstream version 0.5.0+svn5324~dfsg1 --- applications/mp4box/filedump.c | 4 +- applications/mp4box/fileimport.c | 8 +- applications/mp4box/main.c | 71 ++- applications/mp4client/main.c | 10 +- applications/testapps/hevcbench/main.c | 93 +-- .../testapps/loadcompare/loadcompare.c | 2 +- applications/testapps/svg2bifs/main.c | 4 +- gui/gui.js | 2 +- include/gpac/color.h | 2 +- include/gpac/events.h | 2 +- include/gpac/events_constants.h | 2 +- include/gpac/internal/compositor_dev.h | 6 +- include/gpac/internal/scenegraph_dev.h | 3 + include/gpac/media_tools.h | 8 + include/gpac/scenegraph_svg.h | 2 + include/gpac/tools.h | 26 +- include/gpac/version.h | 2 +- modules/dx_hw/copy_pixels.c | 2 +- modules/dx_hw/dx_window.c | 2 +- modules/ffmpeg_in/ffmpeg_decode.c | 2 +- modules/ft_font/ft_font.c | 4 +- modules/gpac_js/gpac_js.c | 530 ++++++++------- modules/mpd_in/mpd_in.c | 6 +- modules/openhevc_dec/openhevc_dec.c | 122 ++-- modules/widgetman/widgetman.c | 4 +- src/bifs/conditional.c | 2 +- src/compositor/compositor.c | 99 +-- src/compositor/compositor_2d.c | 13 +- src/compositor/drawable.c | 33 +- src/compositor/events.c | 10 +- src/compositor/hardcoded_protos.c | 87 +++ src/compositor/mpeg4_animstream.c | 4 +- src/compositor/mpeg4_audio.c | 10 +- src/compositor/mpeg4_background2d.c | 8 +- src/compositor/mpeg4_composite.c | 12 +- src/compositor/mpeg4_grouping_3d.c | 2 +- src/compositor/mpeg4_layer_2d.c | 4 +- src/compositor/mpeg4_layer_3d.c | 8 +- src/compositor/mpeg4_layout.c | 13 + src/compositor/mpeg4_sensors.c | 126 ++-- src/compositor/mpeg4_textures.c | 6 +- src/compositor/svg_grouping.c | 2 +- src/compositor/texturing.c | 4 +- src/compositor/visual_manager.h | 3 +- src/compositor/visual_manager_2d.c | 14 +- src/compositor/visual_manager_2d.h | 2 +- src/compositor/visual_manager_2d_draw.c | 2 +- src/isomedia/isom_write.c | 2 + src/media_tools/dash_client.c | 5 +- src/media_tools/dash_segmenter.c | 159 ++++- src/media_tools/isom_tools.c | 13 + src/media_tools/media_import.c | 109 +++- src/media_tools/mpegts.c | 64 +- src/scenegraph/base_scenegraph.c | 28 + src/scenegraph/mpeg4_animators.c | 6 +- src/scenegraph/svg_attributes.c | 34 +- src/scenegraph/vrml_interpolators.c | 14 +- src/scenegraph/vrml_proto.c | 2 +- src/scenegraph/vrml_route.c | 15 +- src/scenegraph/vrml_smjs.c | 601 +++++++++--------- src/terminal/media_control.c | 6 +- src/terminal/network_service.c | 3 +- src/terminal/object_manager.c | 13 +- src/terminal/scene.c | 5 +- src/terminal/terminal.c | 36 +- src/utils/cache.c | 2 +- src/utils/color.c | 19 +- src/utils/os_config_init.c | 2 +- src/utils/os_divers.c | 61 +- src/utils/os_module.c | 2 +- src/utils/symbian_os.cpp | 2 +- src/utils/xml_parser.c | 2 +- 72 files changed, 1581 insertions(+), 1007 deletions(-) diff --git a/applications/mp4box/filedump.c b/applications/mp4box/filedump.c index feea5e1..1966b5e 100644 --- a/applications/mp4box/filedump.c +++ b/applications/mp4box/filedump.c @@ -2128,7 +2128,9 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } else { fprintf(stderr, "Unknown media type\n"); } - fprintf(stderr, "\tVendor code \"%s\" - Version %d - revision %d\n", gf_4cc_to_str(udesc->vendor_code), udesc->version, udesc->revision); + if (udesc->vendor_code) + fprintf(stderr, "\tVendor code \"%s\" - Version %d - revision %d\n", gf_4cc_to_str(udesc->vendor_code), udesc->version, udesc->revision); + if (udesc->extension_buf) { fprintf(stderr, "\tCodec configuration data size: %d bytes\n", udesc->extension_buf_size); gf_free(udesc->extension_buf); diff --git a/applications/mp4box/fileimport.c b/applications/mp4box/fileimport.c index b97bdf7..39fd3ba 100644 --- a/applications/mp4box/fileimport.c +++ b/applications/mp4box/fileimport.c @@ -89,7 +89,7 @@ void convert_file_info(char *inName, u32 trackID) fprintf(stderr, "File has %d tracks\n", import.nb_tracks); } if (import.probe_duration) { - fprintf(stderr, "Duration: %g ms\n", (Double) (import.probe_duration/1000.0)); + fprintf(stderr, "Duration: %g s\n", (Double) (import.probe_duration/1000.0)); } found = 0; for (i=0; iimports, gf_strdup(file_path) ); return 0; } -static Bool wgt_enum_dir(void *cbck, char *file_name, char *file_path) +static Bool wgt_enum_dir(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info) { if (!stricmp(file_name, "cvs") || !stricmp(file_name, ".svn")) return 0; gf_enum_directory(file_path, 0, wgt_enum_files, cbck, NULL); diff --git a/applications/mp4box/main.c b/applications/mp4box/main.c index 2ab062b..f62b655 100644 --- a/applications/mp4box/main.c +++ b/applications/mp4box/main.c @@ -302,6 +302,13 @@ void PrintDASHUsage() " only the xlink declared on the first rep of a period will be used\n" " \":role=VALUE\" sets the role of this representation (cf DASH spec).\n" " media with different roles belong to different adaptation sets.\n" + " \":desc_p=VALUE\" adds a descriptor at the Period level.\n" + " \":desc_as=VALUE\" adds a descriptor at the AdaptationSet level \n" + " two input files with different values will be in different AdaptationSet elements.\n" + " \":desc_as_c=VALUE\" adds a descriptor at the AdaptationSet level \n" + " value is ignored to created AdaptationSet elements.\n" + " \":desc_rep=VALUE\" adds a descriptor at the Representation level.\n" + " value is ignored to created AdaptationSet elements.\n" "\n" " -rap segments begin with random access points\n" " Note: segment duration may not be exactly what asked by\n" @@ -1365,7 +1372,26 @@ enum if (tsel_acts) gf_free(tsel_acts); \ if (brand_add) gf_free(brand_add); \ if (brand_rem) gf_free(brand_rem); \ - if (dash_inputs) gf_free(dash_inputs); \ + if (dash_inputs) { \ + u32 input_index; \ + for (input_index = 0; input_index < dash_inputs->nb_rep_descs; input_index++) { \ + gf_free(dash_inputs->rep_descs[input_index]); \ + } \ + gf_free(dash_inputs->rep_descs); \ + for (input_index = 0; input_index < dash_inputs->nb_as_descs; input_index++) { \ + gf_free(dash_inputs->as_descs[input_index]); \ + } \ + gf_free(dash_inputs->as_descs); \ + for (input_index = 0; input_index < dash_inputs->nb_as_c_descs; input_index++) { \ + gf_free(dash_inputs->as_c_descs[input_index]); \ + } \ + gf_free(dash_inputs->as_c_descs); \ + for (input_index = 0; input_index < dash_inputs->nb_p_descs; input_index++) { \ + gf_free(dash_inputs->p_descs[input_index]); \ + } \ + gf_free(dash_inputs->p_descs); \ + gf_free(dash_inputs); \ + } \ gf_sys_close(); \ return __ret_code; \ @@ -1386,6 +1412,19 @@ GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char * sep[0] = 0; while (opts) { sep = strchr(opts, ':'); + while (sep) { + /* this is a real separator if it is followed by a keyword we are looking for */ + if (!strnicmp(sep, ":id=", 4) || + !strnicmp(sep, ":period=", 8) || + !strnicmp(sep, ":bandwidth=", 11) || + !strnicmp(sep, ":role=", 6) || + !strnicmp(sep, ":desc", 5) || + !strnicmp(sep, ":xlink=", 7)) { + break; + } else { + sep = strchr(sep+1, ':'); + } + } if (sep && !strncmp(sep, "://", 3)) sep = strchr(sep+3, ':'); if (sep) sep[0] = 0; @@ -1408,6 +1447,36 @@ GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char * } else if (!strnicmp(opts, "bandwidth=", 10)) di->bandwidth = atoi(opts+10); else if (!strnicmp(opts, "role=", 5)) strncpy(di->role, opts+5, 99); + else if (!strnicmp(opts, "desc", 4)) { + u32 *nb_descs; + char ***descs; + u32 opt_offset; + u32 len; + if (!strnicmp(opts, "desc_p=", 7)) { + nb_descs = &di->nb_p_descs; + descs = &di->p_descs; + opt_offset = 7; + } else if (!strnicmp(opts, "desc_as=", 8)) { + nb_descs = &di->nb_as_descs; + descs = &di->as_descs; + opt_offset = 8; + } else if (!strnicmp(opts, "desc_as_c=", 8)) { + nb_descs = &di->nb_as_c_descs; + descs = &di->as_c_descs; + opt_offset = 10; + } else if (!strnicmp(opts, "desc_rep=", 8)) { + nb_descs = &di->nb_rep_descs; + descs = &di->rep_descs; + opt_offset = 9; + } + (*nb_descs)++; + opts += opt_offset; + len = (u32) strlen(opts); + (*descs) = (char **)gf_realloc((*descs), (*nb_descs)*sizeof(char *)); + (*descs)[(*nb_descs)-1] = (char *)gf_malloc((len+1)*sizeof(char)); + strncpy((*descs)[(*nb_descs)-1], opts, len); + (*descs)[(*nb_descs)-1][len] = 0; + } else if (!strnicmp(opts, "xlink=", 6)) { if (strlen(opts+6) > 199) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] XLink cannot exceed 99 characters in MP4Box, truncating ...\n")); diff --git a/applications/mp4client/main.c b/applications/mp4client/main.c index a8b9060..4cb1f88 100644 --- a/applications/mp4client/main.c +++ b/applications/mp4client/main.c @@ -100,7 +100,7 @@ static char the_url[GF_MAX_PATH]; static char pl_path[GF_MAX_PATH]; static Bool no_mime_check = GF_TRUE; static Bool be_quiet = GF_FALSE; -static u32 log_time_start = 0; +static u64 log_time_start = 0; static Bool log_utc_time = GF_FALSE; static Bool loop_at_end = GF_FALSE; static u32 forced_width=0; @@ -182,7 +182,7 @@ void PrintUsage() "\t \"mutex\" : mutex\n" "\t \"all\" : all tools logged - other tools can be specified afterwards.\n" "\n" - "\t-log-clock or -lc : logs time in ms since start time of GPAC before each log line.\n" + "\t-log-clock or -lc : logs time in micro sec since start time of GPAC before each log line.\n" "\t-log-utc or -lu : logs UTC time in ms before each log line.\n" "\t-ifce IPIFCE : Sets default Multicast interface\n" "\t-size WxH: specifies visual size (default: scene size)\n" @@ -753,7 +753,7 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) ResetCaption(); break; - case GF_EVENT_OPENFILE: + case GF_EVENT_DROPFILE: { u32 i, pos; /*todo - force playlist mode*/ @@ -936,7 +936,7 @@ static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list vsprintf(szMsg, fmt, list); UpdateRTInfo(szMsg + 6 /*"[RTI] "*/); } else { - if (log_time_start) fprintf(logs, "[At %d]", gf_sys_clock() - log_time_start); + if (log_time_start) fprintf(logs, "[At "LLD"]", gf_sys_clock_high_res() - log_time_start); if (log_utc_time) { u64 utc_clock = gf_net_get_utc() ; time_t secs = utc_clock/1000; @@ -966,7 +966,7 @@ static void init_rti_logs(char *rti_file, char *url, Bool use_rtix) GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n")); } else if (log_time_start) { - log_time_start = gf_sys_clock(); + log_time_start = gf_sys_clock_high_res(); } } } diff --git a/applications/testapps/hevcbench/main.c b/applications/testapps/hevcbench/main.c index 96cb43d..034e221 100644 --- a/applications/testapps/hevcbench/main.c +++ b/applications/testapps/hevcbench/main.c @@ -42,8 +42,8 @@ GLint memory_format=GL_UNSIGNED_BYTE; GLint pixel_format=GL_LUMINANCE; GLint texture_type=GL_TEXTURE_RECTANGLE_EXT; u32 gl_nb_frames = 1; -u32 gl_upload_time = 0; -u32 gl_draw_time = 0; +u64 gl_upload_time = 0; +u64 gl_draw_time = 0; Bool pbo_mode = GF_TRUE; Bool first_tx_load = GF_FALSE; Bool use_vsync=0; @@ -381,12 +381,12 @@ void sdl_draw_quad() void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 stride) { u32 needs_stride = 0; - u32 now, end; + u64 now, end; if (stride != w) { if (bit_depth==10) { if (stride != 2*w) { - needs_stride = stride; + needs_stride = stride / 2; } } else { needs_stride = stride; @@ -395,7 +395,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str glEnable(texture_type); - now = gf_sys_clock(); + now = gf_sys_clock_high_res(); if (first_tx_load) { @@ -432,7 +432,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str #elif (COPY_TYPE==4) #else linesize = width*Bpp; - p_stride = stride*Bpp; + p_stride = stride; count = h; #if (COPY_TYPE==2) c2 = linesize/4; @@ -467,7 +467,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str #elif (COPY_TYPE==4) #else linesize = width*Bpp/2; - p_stride = stride*Bpp/2; + p_stride = stride/2; count/=2; #if (COPY_TYPE==2) c2 /= 2; @@ -570,7 +570,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str if (needs_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } - end = gf_sys_clock() - now; + end = gf_sys_clock_high_res() - now; if (!first_tx_load) { gl_nb_frames ++; @@ -601,7 +601,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str SDL_GL_SwapWindow(window); - gl_draw_time += gf_sys_clock() - now; + gl_draw_time += gf_sys_clock_high_res() - now; return; } @@ -610,19 +610,19 @@ void sdl_bench() { Double rate; u32 i, count; - u32 start = gf_sys_clock(); + u64 start = gf_sys_clock_high_res(); count = 600; for (i=0; idecoderConfig && esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { libOpenHevcCopyExtraData(ohevc, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength+8); } + + libOpenHevcSetActiveDecoders(ohevc, 1); + libOpenHevcSetViewLayers(ohevc, 1); + libOpenHevcStartDecoder(ohevc); gf_odf_desc_del((GF_Descriptor *)esd); gf_isom_set_sample_padding(isom, track, 8); @@ -756,16 +764,6 @@ int main(int argc, char **argv) GF_ISOSample *sample = gf_isom_get_sample(isom, track, i+1, &di); if ( libOpenHevcDecode(ohevc, sample->data, sample->dataLength, sample->DTS+sample->CTS_Offset) ) { - OpenHevc_Frame_cpy HVCFrame; - - libOpenHevcGetPictureInfo(ohevc, &HVCFrame.frameInfo); - if (!sdl_is_init && !no_display) { - sdl_init(HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch+32, use_pbo); - sdl_is_init=1; - start = gf_sys_clock(); - nb_frames_at_start = i+1; - } - if (no_display) { OpenHevc_Frame HVCFrame_ptr; libOpenHevcGetOutput(ohevc, 1, &HVCFrame_ptr); @@ -773,21 +771,42 @@ int main(int argc, char **argv) OpenHevc_Frame HVCFrame_ptr; libOpenHevcGetOutput(ohevc, 1, &HVCFrame_ptr); - sdl_draw_frame((u8 *) HVCFrame_ptr.pvY, (u8 *) HVCFrame_ptr.pvU, (u8 *) HVCFrame_ptr.pvV, HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch+32); + + if (!sdl_is_init && !no_display) { + sdl_init(HVCFrame_ptr.frameInfo.nWidth, HVCFrame_ptr.frameInfo.nHeight, HVCFrame_ptr.frameInfo.nBitDepth, HVCFrame_ptr.frameInfo.nYPitch, use_pbo); + sdl_is_init=1; + start = gf_sys_clock_high_res(); + nb_frames_at_start = i+1; + } + + sdl_draw_frame((u8 *) HVCFrame_ptr.pvY, (u8 *) HVCFrame_ptr.pvU, (u8 *) HVCFrame_ptr.pvV, HVCFrame_ptr.frameInfo.nWidth, HVCFrame_ptr.frameInfo.nHeight, HVCFrame_ptr.frameInfo.nBitDepth, HVCFrame_ptr.frameInfo.nYPitch); } else { - memset(&HVCFrame, 0, sizeof(OpenHevc_Frame) ); + OpenHevc_Frame_cpy HVCFrame; + memset(&HVCFrame, 0, sizeof(OpenHevc_Frame_cpy) ); + + libOpenHevcGetPictureInfoCpy(ohevc, &HVCFrame.frameInfo); + + if (!sdl_is_init && !no_display) { + sdl_init(HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch, use_pbo); + sdl_is_init=1; + start = gf_sys_clock_high_res(); + nb_frames_at_start = i+1; + } + HVCFrame.pvY = (void*) pY; HVCFrame.pvU = (void*) pU; HVCFrame.pvV = (void*) pV; + libOpenHevcGetOutputCpy(ohevc, 1, &HVCFrame); + sdl_draw_frame(pY, pU, pV, HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch); } } gf_isom_sample_del(&sample); - now = gf_sys_clock(); - fprintf(stderr, "%d %% %d frames in %d ms - FPS %02.2g - push time %d ms - draw %d ms\r", 100*(i+1-nb_frames_at_start)/count, i+1-nb_frames_at_start, now-start, 1000.0 * (i+1-nb_frames_at_start) / (now-start), gl_upload_time / gl_nb_frames , (gl_draw_time - gl_upload_time) / gl_nb_frames ); + now = gf_sys_clock_high_res(); + fprintf(stderr, "%d %% %d frames in %d ms - FPS %03.2f - push time "LLD" ms - draw "LLD" ms\r", 100*(i+1-nb_frames_at_start)/count, i+1-nb_frames_at_start, (now-start)/1000, 1000000.0 * (i+1-nb_frames_at_start) / (now-start), gl_upload_time / gl_nb_frames/1000 , (gl_draw_time - gl_upload_time) / gl_nb_frames/1000 ); } else { gf_sleep(10); i--; @@ -805,14 +824,14 @@ int main(int argc, char **argv) case 'p': if (paused) { paused=0; - start += gf_sys_clock()-pause_time; + start += gf_sys_clock_high_res()-pause_time; } else { paused = 1; - pause_time=gf_sys_clock(); + pause_time=gf_sys_clock_high_res(); } break; case 'r': - start = gf_sys_clock(); + start = gf_sys_clock_high_res(); nb_frames_at_start = i+1; gl_upload_time = gl_draw_time = 0; gl_nb_frames=1; @@ -823,8 +842,8 @@ int main(int argc, char **argv) check_prompt=0; } } - now = gf_sys_clock(); - fprintf(stderr, "Decoded %d frames in %d ms - FPS %g\n", i+1, now-start, 1000.0 * (i+1) / (now-start) ); + now = gf_sys_clock_high_res(); + fprintf(stderr, "\nDecoded %d frames in %d ms - FPS %g\n", i+1, (now-start)/1000, 1000000.0 * (i+1) / (now-start) ); libOpenHevcClose(ohevc); gf_isom_close(isom); diff --git a/applications/testapps/loadcompare/loadcompare.c b/applications/testapps/loadcompare/loadcompare.c index 828dc5b..8774281 100644 --- a/applications/testapps/loadcompare/loadcompare.c +++ b/applications/testapps/loadcompare/loadcompare.c @@ -514,7 +514,7 @@ void print_load_data(GF_LoadCompare *lc, LoadData *ld) fflush(lc->out); } -Bool loadcompare_one(void *cbck, char *item_name, char *item_path) +Bool loadcompare_one(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) { GF_Err e; GF_LoadCompare *lc = cbck; diff --git a/applications/testapps/svg2bifs/main.c b/applications/testapps/svg2bifs/main.c index f5a462d..d13ed2f 100644 --- a/applications/testapps/svg2bifs/main.c +++ b/applications/testapps/svg2bifs/main.c @@ -1012,7 +1012,7 @@ int main(int argc, char **argv) GF_SceneDumper *dump; char *tmp; - gf_sys_init(); + gf_sys_init(0); GF_SAFEALLOC(converter, SVG2BIFS_Converter); @@ -1030,7 +1030,7 @@ int main(int argc, char **argv) fprintf(stdout, "Dumping BIFS scenegraph\n"); tmp = strchr(argv[1], '.'); tmp[0] = 0; - dump = gf_sm_dumper_new(converter->bifs_sg, argv[1], ' ', GF_SM_DUMP_XMTA); + dump = gf_sm_dumper_new(converter->bifs_sg, argv[1], ' ', GF_SM_DUMP_BT); tmp[0] = '.'; gf_sm_dump_graph(dump, 1, 0); diff --git a/gui/gui.js b/gui/gui.js index ebea4be..f047984 100644 --- a/gui/gui.js +++ b/gui/gui.js @@ -103,7 +103,7 @@ function filter_event(evt) } return false; - case GF_EVENT_OPENFILE: + case GF_EVENT_DROPFILE: var files = evt.files; /*todo - handle playlist*/ if (files.length) { diff --git a/include/gpac/color.h b/include/gpac/color.h index d254019..1820200 100644 --- a/include/gpac/color.h +++ b/include/gpac/color.h @@ -257,7 +257,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds *\param src_wnd source rectangle. If null the entire source surface is used *\return error code if any */ -GF_Err gf_color_write_yv12_10_to_yuv(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *src_wnd); +GF_Err gf_color_write_yv12_10_to_yuv(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *src_wnd, Bool swap_uv); /*! @} */ diff --git a/include/gpac/events.h b/include/gpac/events.h index ecf06d6..372e3fd 100644 --- a/include/gpac/events.h +++ b/include/gpac/events.h @@ -274,7 +274,7 @@ typedef struct { typedef struct { - /* GF_EVENT_OPENFILE*/ + /* GF_EVENT_DROPFILE*/ u8 type; u32 nb_files; char **files; diff --git a/include/gpac/events_constants.h b/include/gpac/events_constants.h index a8eeb64..e8da544 100644 --- a/include/gpac/events_constants.h +++ b/include/gpac/events_constants.h @@ -224,7 +224,7 @@ typedef enum { GF_EVENT_MIGRATE, /*indicates a session migration request*/ GF_EVENT_DISCONNECT, /*indicates the current url should be disconnected*/ GF_EVENT_RESOLUTION, /*indicates the screen resolution has changed*/ - GF_EVENT_OPENFILE, + GF_EVENT_DROPFILE, /* Events for Keyboad */ GF_EVENT_TEXT_EDITING_START, GF_EVENT_TEXT_EDITING_END, diff --git a/include/gpac/internal/compositor_dev.h b/include/gpac/internal/compositor_dev.h index 61580bc..fab6bdc 100644 --- a/include/gpac/internal/compositor_dev.h +++ b/include/gpac/internal/compositor_dev.h @@ -187,6 +187,7 @@ struct __tag_compositor GF_List *time_nodes; /*all textures (texture handlers)*/ GF_List *textures; + Bool texture_inserted; /*all textures to be destroyed (needed for openGL context ...)*/ GF_List *textures_gc; @@ -809,6 +810,9 @@ struct _traversing_state /*parent group for composition: can be Form, Layout or Layer2D*/ struct _parent_node_2d *parent; + /*override appearance of all nodes with this one*/ + GF_Node *override_appearance; + /*group/object bounds in local coordinate system*/ GF_Rect bounds; @@ -1161,7 +1165,7 @@ GF_Rect compositor_2d_update_clipper(GF_TraverseState *tr_state, GF_Rect this_cl #ifndef GPAC_DISABLE_3D void compositor_2d_reset_gl_auto(GF_Compositor *compositor); void compositor_2d_hybgl_flush_video(GF_Compositor *compositor, GF_IRect *area); -void compositor_2d_hybgl_clear_surface_ex(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool is_offscreen_clear); +void compositor_2d_hybgl_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool is_offscreen_clear); #endif Bool compositor_texture_rectangles(GF_VisualManager *visual, GF_TextureHandler *txh, GF_IRect *clip, GF_Rect *unclip, GF_Window *src, GF_Window *dst, Bool *disable_blit, Bool *has_scale); diff --git a/include/gpac/internal/scenegraph_dev.h b/include/gpac/internal/scenegraph_dev.h index 9d380c8..c063304 100644 --- a/include/gpac/internal/scenegraph_dev.h +++ b/include/gpac/internal/scenegraph_dev.h @@ -300,6 +300,8 @@ struct __tag_scene_graph struct JSObject *document; Bool dcci_doc; + + Bool trigger_gc; #endif }; @@ -508,6 +510,7 @@ enum { GF_SG_PROTO_LOADED = 1, GF_SG_PROTO_IS_GROUPING = 2, + GF_SG_PROTO_HARDCODED = 4, }; typedef struct _proto_instance diff --git a/include/gpac/media_tools.h b/include/gpac/media_tools.h index d65557a..5175a69 100644 --- a/include/gpac/media_tools.h +++ b/include/gpac/media_tools.h @@ -286,6 +286,14 @@ typedef struct char periodID[100]; char xlink[100]; char role[100]; + u32 nb_rep_descs; + char **rep_descs; + u32 nb_p_descs; + char **p_descs; + u32 nb_as_descs; + char **as_descs; + u32 nb_as_c_descs; + char **as_c_descs; u32 bandwidth; } GF_DashSegmenterInput; diff --git a/include/gpac/scenegraph_svg.h b/include/gpac/scenegraph_svg.h index 22dd7e7..1021950 100644 --- a/include/gpac/scenegraph_svg.h +++ b/include/gpac/scenegraph_svg.h @@ -419,6 +419,8 @@ typedef enum /*HTML Media Source events*/ GF_DOM_EVENT_MEDIASOURCE = 1<<11, + /*Internal GPAC events*/ + GF_DOM_EVENT_GPAC = 1<<30, /*fake events - these events are NEVER fired*/ GF_DOM_EVENT_FAKE = 1<<31, } GF_DOMEventCategory; diff --git a/include/gpac/tools.h b/include/gpac/tools.h index 8802ec7..c68e356 100644 --- a/include/gpac/tools.h +++ b/include/gpac/tools.h @@ -518,6 +518,27 @@ u32 gf_rand(); */ void gf_get_user_name(char *buf, u32 buf_size); + +/*!\brief FileEnum info object + * + *The FileEnumInfo object is used to get file attributes upon enumeration of a directory. +*/ +typedef struct +{ + /*!File is marked as hidden*/ + Bool hidden; + /*!File is a directory*/ + Bool directory; + /*!File is a drive mountpoint*/ + Bool drive; + /*!File is a system file*/ + Bool system; + /*!File size in bytes*/ + u64 size; + /*!File last modif time in UTC seconds*/ + u64 last_modified; +} GF_FileEnumInfo; + /*! * \brief Directory Enumeration Callback * @@ -525,10 +546,11 @@ void gf_get_user_name(char *buf, u32 buf_size); * \param cbck Opaque user data. * \param item_name File or directory name. * \param item_path File or directory full path and name from filesystem root. + * \param file_info information for the file or directory. * \return 1 to abort enumeration, 0 to continue enumeration. * */ -typedef Bool (*gf_enum_dir_item)(void *cbck, char *item_name, char *item_path); +typedef Bool (*gf_enum_dir_item)(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info); /*! * \brief Directory enumeration * @@ -720,7 +742,7 @@ GF_Err gf_cleanup_dir(char* DirPathName); */ u32 gf_crc_32(const char *data, u32 size); -#ifdef _WIN32_WCE +#ifdef WIN32 /*! * \brief WINCE time constant * \hideinitializer diff --git a/include/gpac/version.h b/include/gpac/version.h index d006622..3a8a8c2 100644 --- a/include/gpac/version.h +++ b/include/gpac/version.h @@ -37,7 +37,7 @@ */ #define GPAC_VERSION "0.5.1-DEV" #define GPAC_VERSION_MAJOR 3 -#define GPAC_VERSION_MINOR 0 +#define GPAC_VERSION_MINOR 1 #define GPAC_VERSION_MICRO 0 #include diff --git a/modules/dx_hw/copy_pixels.c b/modules/dx_hw/copy_pixels.c index 328ce63..aa3def9 100644 --- a/modules/dx_hw/copy_pixels.c +++ b/modules/dx_hw/copy_pixels.c @@ -560,7 +560,7 @@ void dx_copy_pixels(GF_VideoSurface *dst_s, const GF_VideoSurface *src_s, const } else if (get_yuv_base(src_s->pixel_format)==GF_PIXEL_YV12_10) { if (format_is_yuv(dst_s->pixel_format)) { /*generic YV planar to YUV (planar or not) */ - gf_color_write_yv12_10_to_yuv(dst_s, src_s->video_buffer, src_s->u_ptr, src_s->v_ptr, src_s->pitch_y, src_s->width, src_s->height, src_wnd); + gf_color_write_yv12_10_to_yuv(dst_s, src_s->video_buffer, src_s->u_ptr, src_s->v_ptr, src_s->pitch_y, src_s->width, src_s->height, src_wnd, 1); return; } } else if (format_is_yuv(src_s->pixel_format)) { diff --git a/modules/dx_hw/dx_window.c b/modules/dx_hw/dx_window.c index a2ff70e..bcb20ef 100644 --- a/modules/dx_hw/dx_window.c +++ b/modules/dx_hw/dx_window.c @@ -579,7 +579,7 @@ LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam u32 i; HDROP hDrop = (HDROP) wParam; - evt.type = GF_EVENT_OPENFILE; + evt.type = GF_EVENT_DROPFILE; evt.open_file.nb_files = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); evt.open_file.files = gf_malloc(sizeof(char *)*evt.open_file.nb_files); for (i=0; idirect_output ? ffd->conv_buffer : outBuffer; dst.pixel_format = GF_PIXEL_YV12; - gf_color_write_yv12_10_to_yuv(&dst, (u8 *) frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], ctx->width, ctx->height, NULL); + gf_color_write_yv12_10_to_yuv(&dst, (u8 *) frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], ctx->width, ctx->height, NULL, 0); *outBufferLength = ffd->out_size; return GF_OK; } diff --git a/modules/ft_font/ft_font.c b/modules/ft_font/ft_font.c index dbaa2c4..e88fa8a 100644 --- a/modules/ft_font/ft_font.c +++ b/modules/ft_font/ft_font.c @@ -114,7 +114,7 @@ void setBestFont(const char * listOfFonts[], char ** currentBestFont, const char } } -static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path) +static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info) { char *szfont; FT_Face face; @@ -195,7 +195,7 @@ static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path) return 0; } -static Bool ft_enum_fonts_dir(void *cbck, char *file_name, char *file_path) +static Bool ft_enum_fonts_dir(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info) { GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Scanning directory %s (%s)\n", file_name, file_path)); gf_enum_directory(file_path, 0, ft_enum_fonts, cbck, "ttf;ttc"); diff --git a/modules/gpac_js/gpac_js.c b/modules/gpac_js/gpac_js.c index 9ba3a8a..0d1ded3 100644 --- a/modules/gpac_js/gpac_js.c +++ b/modules/gpac_js/gpac_js.c @@ -94,210 +94,213 @@ static GF_Terminal *gpac_get_term(JSContext *c, JSObject *obj) static SMJS_FUNC_PROP_GET( gpac_getProperty) -const char *res; -char *prop_name; -GF_Terminal *term = gpac_get_term(c, obj); -if (!term) return JS_FALSE; - -if (!SMJS_ID_IS_STRING(id)) return JS_TRUE; -prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id)); -if (!prop_name) return JS_FALSE; - -if (!strcmp(prop_name, "last_working_directory")) { - res = gf_cfg_get_key(term->user->config, "General", "LastWorkingDir"); - if (!res) res = gf_cfg_get_key(term->user->config, "General", "ModulesDirectory"); - *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, res)); -} -else if (!strcmp(prop_name, "scale_x")) { - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->scale_x)) ); -} -else if (!strcmp(prop_name, "scale_y")) { - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->scale_y)) ); -} -else if (!strcmp(prop_name, "translation_x")) { - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->trans_x)) ); -} -else if (!strcmp(prop_name, "translation_y")) { - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->trans_y)) ); -} -else if (!strcmp(prop_name, "rectangular_textures")) { - Bool any_size = GF_FALSE; -#ifndef GPAC_DISABLE_3D - if (term->compositor->gl_caps.npot_texture || term->compositor->gl_caps.rect_texture) - any_size = GF_TRUE; -#endif - *vp = BOOLEAN_TO_JSVAL( any_size ? JS_TRUE : JS_FALSE ); -} -else if (!strcmp(prop_name, "batteryOn")) { - Bool on_battery = GF_FALSE; - gf_sys_get_battery_state(&on_battery, NULL, NULL, NULL, NULL); - *vp = BOOLEAN_TO_JSVAL( on_battery ? JS_TRUE : JS_FALSE ); -} -else if (!strcmp(prop_name, "batteryCharging")) { - u32 on_charge = 0; - gf_sys_get_battery_state(NULL, &on_charge, NULL, NULL, NULL); - *vp = BOOLEAN_TO_JSVAL( on_charge ? JS_TRUE : JS_FALSE ); -} -else if (!strcmp(prop_name, "batteryPercent")) { - u32 level = 0; - gf_sys_get_battery_state(NULL, NULL, &level, NULL, NULL); - *vp = INT_TO_JSVAL( level ); -} -else if (!strcmp(prop_name, "batteryLifeTime")) { - u32 level = 0; - gf_sys_get_battery_state(NULL, NULL, NULL, &level, NULL); - *vp = INT_TO_JSVAL( level ); -} -else if (!strcmp(prop_name, "batteryFullLifeTime")) { - u32 level = 0; - gf_sys_get_battery_state(NULL, NULL, NULL, NULL, &level); - *vp = INT_TO_JSVAL( level ); -} -else if (!strcmp(prop_name, "hostname")) { - char hostname[100]; - gf_sk_get_host_name((char*)hostname); - *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, hostname)); -} -else if (!strcmp(prop_name, "fullscreen")) { - *vp = BOOLEAN_TO_JSVAL( term->compositor->fullscreen ? JS_TRUE : JS_FALSE); -} -else if (!strcmp(prop_name, "current_path")) { - char *url = gf_url_concatenate(term->root_scene->root_od->net_service->url, ""); - if (!url) url = gf_strdup(""); - *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, url)); - gf_free(url); -} -else if (!strcmp(prop_name, "volume")) { - *vp = INT_TO_JSVAL( gf_term_get_option(term, GF_OPT_AUDIO_VOLUME)); -} -else if (!strcmp(prop_name, "navigation")) { - *vp = INT_TO_JSVAL( gf_term_get_option(term, GF_OPT_NAVIGATION)); -} -else if (!strcmp(prop_name, "navigation_type")) { - *vp = INT_TO_JSVAL( gf_term_get_option(term, GF_OPT_NAVIGATION_TYPE) ); -} -else if (!strcmp(prop_name, "hardware_yuv")) { - *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_YUV) ? 1 : 0 ); -} -else if (!strcmp(prop_name, "hardware_rgb")) { - *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_RGB) ? 1 : 0 ); -} -else if (!strcmp(prop_name, "hardware_rgba")) { - u32 has_rgba = (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_RGBA) ? 1 : 0; -#ifndef GPAC_DISABLE_3D - if (term->compositor->hybrid_opengl || term->compositor->is_opengl) has_rgba = 1; -#endif - *vp = INT_TO_JSVAL( has_rgba ); -} -else if (!strcmp(prop_name, "hardware_stretch")) { - *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_STRETCH) ? 1 : 0 ); -} -else if (!strcmp(prop_name, "screen_width")) { - *vp = INT_TO_JSVAL( term->compositor->video_out->max_screen_width); -} -else if (!strcmp(prop_name, "screen_height")) { - *vp = INT_TO_JSVAL( term->compositor->video_out->max_screen_height); -} -else if (!strcmp(prop_name, "http_bitrate")) { - *vp = INT_TO_JSVAL( gf_dm_get_data_rate(term->downloader)*8/1024); -} -else if (!strcmp(prop_name, "fps")) { - Double fps = gf_sc_get_fps(term->compositor, 0); - *vp = DOUBLE_TO_JSVAL(JS_NewDouble(c, fps) ); -} -else if (!strcmp(prop_name, "cpu_load")) { - GF_GPACJSExt *ext = (GF_GPACJSExt *)SMJS_GET_PRIVATE(c, obj); - gf_sys_get_rti(ext->rti_refresh_rate, &ext->rti, 0); - *vp = INT_TO_JSVAL(ext->rti.process_cpu_usage); -} -else if (!strcmp(prop_name, "memory")) { - GF_GPACJSExt *ext = (GF_GPACJSExt *)SMJS_GET_PRIVATE(c, obj); - gf_sys_get_rti(ext->rti_refresh_rate, &ext->rti, 0); - *vp = INT_TO_JSVAL(ext->rti.process_memory); -} + const char *res; + char *prop_name; + GF_Terminal *term = gpac_get_term(c, obj); + if (!term) return JS_FALSE; + + if (!SMJS_ID_IS_STRING(id)) return JS_TRUE; + prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + if (!strcmp(prop_name, "last_working_directory")) { + res = gf_cfg_get_key(term->user->config, "General", "LastWorkingDir"); + if (!res) res = gf_cfg_get_key(term->user->config, "General", "ModulesDirectory"); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, res)); + } + else if (!strcmp(prop_name, "scale_x")) { + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->scale_x)) ); + } + else if (!strcmp(prop_name, "scale_y")) { + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->scale_y)) ); + } + else if (!strcmp(prop_name, "translation_x")) { + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->trans_x)) ); + } + else if (!strcmp(prop_name, "translation_y")) { + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->trans_y)) ); + } + else if (!strcmp(prop_name, "rectangular_textures")) { + Bool any_size = GF_FALSE; + #ifndef GPAC_DISABLE_3D + if (term->compositor->gl_caps.npot_texture || term->compositor->gl_caps.rect_texture) + any_size = GF_TRUE; + #endif + *vp = BOOLEAN_TO_JSVAL( any_size ? JS_TRUE : JS_FALSE ); + } + else if (!strcmp(prop_name, "batteryOn")) { + Bool on_battery = GF_FALSE; + gf_sys_get_battery_state(&on_battery, NULL, NULL, NULL, NULL); + *vp = BOOLEAN_TO_JSVAL( on_battery ? JS_TRUE : JS_FALSE ); + } + else if (!strcmp(prop_name, "batteryCharging")) { + u32 on_charge = 0; + gf_sys_get_battery_state(NULL, &on_charge, NULL, NULL, NULL); + *vp = BOOLEAN_TO_JSVAL( on_charge ? JS_TRUE : JS_FALSE ); + } + else if (!strcmp(prop_name, "batteryPercent")) { + u32 level = 0; + gf_sys_get_battery_state(NULL, NULL, &level, NULL, NULL); + *vp = INT_TO_JSVAL( level ); + } + else if (!strcmp(prop_name, "batteryLifeTime")) { + u32 level = 0; + gf_sys_get_battery_state(NULL, NULL, NULL, &level, NULL); + *vp = INT_TO_JSVAL( level ); + } + else if (!strcmp(prop_name, "batteryFullLifeTime")) { + u32 level = 0; + gf_sys_get_battery_state(NULL, NULL, NULL, NULL, &level); + *vp = INT_TO_JSVAL( level ); + } + else if (!strcmp(prop_name, "hostname")) { + char hostname[100]; + gf_sk_get_host_name((char*)hostname); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, hostname)); + } + else if (!strcmp(prop_name, "fullscreen")) { + *vp = BOOLEAN_TO_JSVAL( term->compositor->fullscreen ? JS_TRUE : JS_FALSE); + } + else if (!strcmp(prop_name, "current_path")) { + char *url = gf_url_concatenate(term->root_scene->root_od->net_service->url, ""); + if (!url) url = gf_strdup(""); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, url)); + gf_free(url); + } + else if (!strcmp(prop_name, "volume")) { + *vp = INT_TO_JSVAL( gf_term_get_option(term, GF_OPT_AUDIO_VOLUME)); + } + else if (!strcmp(prop_name, "navigation")) { + *vp = INT_TO_JSVAL( gf_term_get_option(term, GF_OPT_NAVIGATION)); + } + else if (!strcmp(prop_name, "navigation_type")) { + *vp = INT_TO_JSVAL( gf_term_get_option(term, GF_OPT_NAVIGATION_TYPE) ); + } + else if (!strcmp(prop_name, "hardware_yuv")) { + *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_YUV) ? 1 : 0 ); + } + else if (!strcmp(prop_name, "hardware_rgb")) { + *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_RGB) ? 1 : 0 ); + } + else if (!strcmp(prop_name, "hardware_rgba")) { + u32 has_rgba = (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_RGBA) ? 1 : 0; + #ifndef GPAC_DISABLE_3D + if (term->compositor->hybrid_opengl || term->compositor->is_opengl) has_rgba = 1; + #endif + *vp = INT_TO_JSVAL( has_rgba ); + } + else if (!strcmp(prop_name, "hardware_stretch")) { + *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_STRETCH) ? 1 : 0 ); + } + else if (!strcmp(prop_name, "screen_width")) { + *vp = INT_TO_JSVAL( term->compositor->video_out->max_screen_width); + } + else if (!strcmp(prop_name, "screen_height")) { + *vp = INT_TO_JSVAL( term->compositor->video_out->max_screen_height); + } + else if (!strcmp(prop_name, "http_bitrate")) { + *vp = INT_TO_JSVAL( gf_dm_get_data_rate(term->downloader)*8/1024); + } + else if (!strcmp(prop_name, "fps")) { + Double fps = gf_sc_get_fps(term->compositor, 0); + *vp = DOUBLE_TO_JSVAL(JS_NewDouble(c, fps) ); + } + else if (!strcmp(prop_name, "cpu_load")) { + GF_GPACJSExt *ext = (GF_GPACJSExt *)SMJS_GET_PRIVATE(c, obj); + gf_sys_get_rti(ext->rti_refresh_rate, &ext->rti, 0); + *vp = INT_TO_JSVAL(ext->rti.process_cpu_usage); + } + else if (!strcmp(prop_name, "memory")) { + GF_GPACJSExt *ext = (GF_GPACJSExt *)SMJS_GET_PRIVATE(c, obj); + gf_sys_get_rti(ext->rti_refresh_rate, &ext->rti, 0); + *vp = INT_TO_JSVAL(ext->rti.process_memory); + } -SMJS_FREE(c, prop_name); -return JS_TRUE; + + SMJS_FREE(c, prop_name); + return JS_TRUE; } + + static SMJS_FUNC_PROP_SET( gpac_setProperty) -char *prop_name, *prop_val; -GF_Terminal *term = gpac_get_term(c, obj); -if (!term) return JS_FALSE; + char *prop_name, *prop_val; + GF_Terminal *term = gpac_get_term(c, obj); + if (!term) return JS_FALSE; -if (!SMJS_ID_IS_STRING(id)) return JS_TRUE; -prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id)); + if (!SMJS_ID_IS_STRING(id)) return JS_TRUE; + prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id)); -if (!strcmp(prop_name, "last_working_directory")) { - if (!JSVAL_IS_STRING(*vp)) { - SMJS_FREE(c, prop_name); - return JS_FALSE; + if (!strcmp(prop_name, "last_working_directory")) { + if (!JSVAL_IS_STRING(*vp)) { + SMJS_FREE(c, prop_name); + return JS_FALSE; + } + prop_val = SMJS_CHARS(c, *vp); + gf_cfg_set_key(term->user->config, "General", "LastWorkingDir", prop_val); + SMJS_FREE(c, prop_val); } - prop_val = SMJS_CHARS(c, *vp); - gf_cfg_set_key(term->user->config, "General", "LastWorkingDir", prop_val); - SMJS_FREE(c, prop_val); -} -else if (!strcmp(prop_name, "caption")) { - GF_Event evt; - if (!JSVAL_IS_STRING(*vp)) { - SMJS_FREE(c, prop_name); - return JS_FALSE; - } - evt.type = GF_EVENT_SET_CAPTION; - evt.caption.caption = SMJS_CHARS(c, *vp); - gf_term_user_event(term, &evt); - SMJS_FREE(c, (char*)evt.caption.caption); -} -else if (!strcmp(prop_name, "fullscreen")) { - /*no fullscreen for iOS (always on)*/ -#ifndef GPAC_IPHONE - Bool res = (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? 1 : 0; - if (term->compositor->fullscreen != res) { - gf_term_set_option(term, GF_OPT_FULLSCREEN, res); + else if (!strcmp(prop_name, "caption")) { + GF_Event evt; + if (!JSVAL_IS_STRING(*vp)) { + SMJS_FREE(c, prop_name); + return JS_FALSE; + } + evt.type = GF_EVENT_SET_CAPTION; + evt.caption.caption = SMJS_CHARS(c, *vp); + gf_term_user_event(term, &evt); + SMJS_FREE(c, (char*)evt.caption.caption); } -#endif -} -else if (!strcmp(prop_name, "volume")) { - if (JSVAL_IS_NUMBER(*vp)) { - jsdouble d; - JS_ValueToNumber(c, *vp, &d); - gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, (u32) d); - } else if (JSVAL_IS_INT(*vp)) { - gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, JSVAL_TO_INT(*vp)); + else if (!strcmp(prop_name, "fullscreen")) { + /*no fullscreen for iOS (always on)*/ + #ifndef GPAC_IPHONE + Bool res = (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? 1 : 0; + if (term->compositor->fullscreen != res) { + gf_term_set_option(term, GF_OPT_FULLSCREEN, res); + } + #endif } -} -else if (!strcmp(prop_name, "navigation")) { - gf_term_set_option(term, GF_OPT_NAVIGATION, JSVAL_TO_INT(*vp) ); -} -else if (!strcmp(prop_name, "navigation_type")) { - gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0); -} -else if (!strcmp(prop_name, "disable_hardware_blit")) { - term->compositor->disable_hardware_blit = JSVAL_TO_INT(*vp) ? 1 : 0; - gf_sc_set_option(term->compositor, GF_OPT_REFRESH, 0); -} -else if (!strcmp(prop_name, "disable_composite_blit")) { - Bool new_val = JSVAL_TO_INT(*vp) ? 1 : 0; - if (new_val != term->compositor->disable_composite_blit) { - term->compositor->disable_composite_blit = new_val; - term->compositor->rebuild_offscreen_textures = 1; + else if (!strcmp(prop_name, "volume")) { + if (JSVAL_IS_NUMBER(*vp)) { + jsdouble d; + JS_ValueToNumber(c, *vp, &d); + gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, (u32) d); + } else if (JSVAL_IS_INT(*vp)) { + gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, JSVAL_TO_INT(*vp)); + } + } + else if (!strcmp(prop_name, "navigation")) { + gf_term_set_option(term, GF_OPT_NAVIGATION, JSVAL_TO_INT(*vp) ); + } + else if (!strcmp(prop_name, "navigation_type")) { + gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0); + } + else if (!strcmp(prop_name, "disable_hardware_blit")) { + term->compositor->disable_hardware_blit = JSVAL_TO_INT(*vp) ? 1 : 0; gf_sc_set_option(term->compositor, GF_OPT_REFRESH, 0); } -} -else if (!strcmp(prop_name, "http_bitrate")) { - u32 new_rate = JSVAL_TO_INT(*vp); - gf_dm_set_data_rate(term->downloader, new_rate); -} + else if (!strcmp(prop_name, "disable_composite_blit")) { + Bool new_val = JSVAL_TO_INT(*vp) ? 1 : 0; + if (new_val != term->compositor->disable_composite_blit) { + term->compositor->disable_composite_blit = new_val; + term->compositor->rebuild_offscreen_textures = 1; + gf_sc_set_option(term->compositor, GF_OPT_REFRESH, 0); + } + } + else if (!strcmp(prop_name, "http_bitrate")) { + u32 new_rate = JSVAL_TO_INT(*vp); + gf_dm_set_data_rate(term->downloader, new_rate); + } -SMJS_FREE(c, prop_name); -return JS_TRUE; + SMJS_FREE(c, prop_name); + return JS_TRUE; } static JSBool SMJS_FUNCTION(gpac_getOption) { const char *opt; char *sec_name, *key_name; + s32 idx = -1; JSString *s; SMJS_OBJ SMJS_ARGS @@ -307,10 +310,15 @@ static JSBool SMJS_FUNCTION(gpac_getOption) if (argc < 2) return JS_FALSE; if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE; - if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; + if (!JSVAL_IS_STRING(argv[1]) && !JSVAL_IS_INT(argv[1])) return JS_FALSE; sec_name = SMJS_CHARS(c, argv[0]); - key_name = SMJS_CHARS(c, argv[1]); + key_name = NULL; + if (JSVAL_IS_INT(argv[1])) { + idx = JSVAL_TO_INT(argv[1]); + } else if (JSVAL_IS_STRING(argv[1]) ) { + key_name = SMJS_CHARS(c, argv[1]); + } if (!stricmp(sec_name, "audiofilters")) { if (!term->compositor->audio_renderer->filter_chain.enable_filters @@ -320,15 +328,22 @@ static JSBool SMJS_FUNCTION(gpac_getOption) return JS_TRUE; } opt = term->compositor->audio_renderer->filter_chain.filters->filter->GetOption(term->compositor->audio_renderer->filter_chain.filters->filter, key_name); - } else { + } else if (key_name) { opt = gf_cfg_get_key(term->user->config, sec_name, key_name); + } else if (idx>=0) { + opt = gf_cfg_get_key_name(term->user->config, sec_name, idx); + } + if (key_name) { + SMJS_FREE(c, key_name); } - SMJS_FREE(c, key_name); SMJS_FREE(c, sec_name); - s = JS_NewStringCopyZ(c, opt ? opt : ""); - if (!s) return JS_FALSE; - SMJS_SET_RVAL( STRING_TO_JSVAL(s) ); + if (opt) { + s = JS_NewStringCopyZ(c, opt); + SMJS_SET_RVAL( STRING_TO_JSVAL(s) ); + } else { + SMJS_SET_RVAL( JSVAL_NULL ); + } return JS_TRUE; } @@ -373,7 +388,7 @@ typedef struct Bool is_dir; } enum_dir_cbk; -static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path) +static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info) { u32 i, len; char *sep; @@ -407,6 +422,12 @@ static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path) } JS_DefineProperty(cbk->c, obj, "path", STRING_TO_JSVAL(s), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineProperty(cbk->c, obj, "directory", BOOLEAN_TO_JSVAL(cbk->is_dir ? JS_TRUE : JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(cbk->c, obj, "drive", BOOLEAN_TO_JSVAL(file_info->drive ? JS_TRUE : JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(cbk->c, obj, "hidden", BOOLEAN_TO_JSVAL(file_info->hidden ? JS_TRUE : JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(cbk->c, obj, "system", BOOLEAN_TO_JSVAL(file_info->system ? JS_TRUE : JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(cbk->c, obj, "size", INT_TO_JSVAL(file_info->size), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(cbk->c, obj, "last_modified", INT_TO_JSVAL(file_info->last_modified), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_GetArrayLength(cbk->c, cbk->array, &idx); v = OBJECT_TO_JSVAL(obj); @@ -449,6 +470,7 @@ static JSBool SMJS_FUNCTION(gpac_enum_directory) if ((dir[1]==':') && ((dir[2]=='/') || (dir[2]=='\\')) ) browse_root = 1; else if (!strcmp(dir, "/")) browse_root = 1; } + if (!strcmp(url, "/")) browse_root = 1; } } @@ -652,6 +674,18 @@ static JSBool SMJS_FUNCTION(gpac_get_scene_time) return JS_TRUE; } +static JSBool SMJS_FUNCTION(gpac_trigger_gc) +{ + SMJS_OBJ + SMJS_ARGS + GF_SceneGraph *sg = NULL; + GF_Terminal *term = gpac_get_term(c, obj); + + sg = term->root_scene->graph; + sg->trigger_gc = GF_TRUE; + return JS_TRUE; +} + static JSBool SMJS_FUNCTION(gpac_migrate_url) { char *url; @@ -687,61 +721,66 @@ static JSBool SMJS_FUNCTION(gpac_migrate_url) static SMJS_FUNC_PROP_GET( gpacevt_getProperty) -GF_GPACJSExt *gjs = SMJS_GET_PRIVATE(c, obj); -GF_Event *evt = gjs->evt; -if (!evt) return 0; + GF_GPACJSExt *gjs = SMJS_GET_PRIVATE(c, obj); + GF_Event *evt = gjs->evt; + if (!evt) return 0; -if (SMJS_ID_IS_INT(id)) { - switch (SMJS_ID_TO_INT(id)) { - case -1: + if (SMJS_ID_IS_INT(id)) { + switch (SMJS_ID_TO_INT(id)) { + case -1: #ifndef GPAC_DISABLE_SVG - *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, gf_dom_get_key_name(evt->key.key_code) )); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, gf_dom_get_key_name(evt->key.key_code) )); #endif - break; - case -2: - *vp = INT_TO_JSVAL(evt->mouse.x); - break; - case -3: - *vp = INT_TO_JSVAL(evt->mouse.y); - break; - case -4: - if (gjs->term->compositor->hit_appear) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); - else if (gf_list_count(gjs->term->compositor->previous_sensors) ) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); - else if (gjs->term->compositor->text_selection) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); - else *vp = BOOLEAN_TO_JSVAL(JS_FALSE); - break; - case -5: - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->mouse.wheel_pos)) ); - break; - case -6: - *vp = INT_TO_JSVAL( evt->mouse.button); - break; - case -7: - *vp = INT_TO_JSVAL(evt->type); - break; - } -} else if (SMJS_ID_IS_STRING(id)) { - char *name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id)); - if (!strcmp(name, "target_url")) { - *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, evt->navigate.to_url) ); - } - else if (!strcmp(name, "files")) { - u32 i, idx; - jsval v; - JSObject *files_array = JS_NewArrayObject(c, 0, NULL); - for (i=0; iopen_file.nb_files; i++) { - if (evt->open_file.files[i]) { - JS_GetArrayLength(c, files_array, &idx); - v = STRING_TO_JSVAL( JS_NewStringCopyZ(c, evt->open_file.files[i]) ); - JS_SetElement(c, files_array, idx, &v); + break; + case -2: + *vp = INT_TO_JSVAL(evt->mouse.x); + break; + case -3: + *vp = INT_TO_JSVAL(evt->mouse.y); + break; + case -4: + if (gjs->term->compositor->hit_appear) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); + else if (gf_list_count(gjs->term->compositor->previous_sensors) ) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); + else if (gjs->term->compositor->text_selection) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); + else *vp = BOOLEAN_TO_JSVAL(JS_FALSE); + break; + case -5: + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->mouse.wheel_pos)) ); + break; + case -6: + *vp = INT_TO_JSVAL( evt->mouse.button); + break; + case -7: + *vp = INT_TO_JSVAL(evt->type); + break; + case -8: +#ifndef GPAC_DISABLE_SVG + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, gf_dom_event_get_name(evt->type) )); +#endif + break; + } + } else if (SMJS_ID_IS_STRING(id)) { + char *name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id)); + if (!strcmp(name, "target_url")) { + *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, evt->navigate.to_url) ); + } + else if (!strcmp(name, "files")) { + u32 i, idx; + jsval v; + JSObject *files_array = JS_NewArrayObject(c, 0, NULL); + for (i=0; iopen_file.nb_files; i++) { + if (evt->open_file.files[i]) { + JS_GetArrayLength(c, files_array, &idx); + v = STRING_TO_JSVAL( JS_NewStringCopyZ(c, evt->open_file.files[i]) ); + JS_SetElement(c, files_array, idx, &v); + } } + *vp = OBJECT_TO_JSVAL(files_array); } - *vp = OBJECT_TO_JSVAL(files_array); + SMJS_FREE(c, name); } - SMJS_FREE(c, name); -} -return JS_TRUE; + return JS_TRUE; } static Bool gjs_event_filter(void *udta, GF_Event *evt, Bool consumed_by_compositor) @@ -805,6 +844,11 @@ static JSBool SMJS_FUNCTION(gpac_set_focus) GF_Terminal *term = gpac_get_term(c, obj); if (!argc) return JS_FALSE; + if (JSVAL_IS_NULL(argv[0])) { + gf_sc_focus_switch_ring(term->compositor, 0, NULL, 0); + return JS_TRUE; + } + if (JSVAL_IS_STRING(argv[0])) { char *focus_type = SMJS_CHARS(c, argv[0]); if (!stricmp(focus_type, "previous")) { @@ -897,6 +941,7 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext SMJS_PROPERTY_SPEC("wheel", -5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0), SMJS_PROPERTY_SPEC("button", -6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0), SMJS_PROPERTY_SPEC("type", -7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0), + SMJS_PROPERTY_SPEC("name", -8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, 0, 0), SMJS_PROPERTY_SPEC(0, 0, 0, 0, 0) }; JSFunctionSpec gpacEvtClassFuncs[] = { @@ -927,6 +972,7 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext SMJS_FUNCTION_SPEC("get_scene", gpac_get_scene, 1), SMJS_FUNCTION_SPEC("error_string", gpac_error_string, 1), SMJS_FUNCTION_SPEC("show_keyboard", gpac_show_keyboard, 1), + SMJS_FUNCTION_SPEC("trigger_gc", gpac_trigger_gc, 1), SMJS_FUNCTION_SPEC(0, 0, 0) @@ -983,7 +1029,7 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext DECLARE_GPAC_CONST(GF_EVENT_CONNECT); DECLARE_GPAC_CONST(GF_EVENT_NAVIGATE_INFO); DECLARE_GPAC_CONST(GF_EVENT_NAVIGATE); - DECLARE_GPAC_CONST(GF_EVENT_OPENFILE); + DECLARE_GPAC_CONST(GF_EVENT_DROPFILE); DECLARE_GPAC_CONST(GF_NAVIGATE_NONE); DECLARE_GPAC_CONST(GF_NAVIGATE_WALK); diff --git a/modules/mpd_in/mpd_in.c b/modules/mpd_in/mpd_in.c index 55e7469..09c48cf 100644 --- a/modules/mpd_in/mpd_in.c +++ b/modules/mpd_in/mpd_in.c @@ -144,7 +144,7 @@ void mpdin_data_packet(GF_ClientService *service, LPNETCHANNEL ns, char *data, u if (group->segment_ifce == ifce) { //if sync is based on timestamps do not adjust the timestamps back if (! group->is_timestamp_based) { - u32 idx, timescale; + u32 timescale; u64 pto=0; gf_dash_group_get_presentation_time_offset(mpdin->dash, i, &pto, ×cale); if (timescale && (timescale != ch->esd->slConfig->timestampResolution)) { @@ -845,8 +845,6 @@ GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const c com.base.command_type = GF_NET_SERVICE_MEDIA_CAP_QUERY; gf_service_command(serv, &com, GF_OK); - com.mcaps.width = 1920; - com.mcaps.height = 1080; if (com.mcaps.width && com.mcaps.height) { gf_dash_set_max_resolution(mpdin->dash, com.mcaps.width, com.mcaps.height, com.mcaps.display_bit_depth); } @@ -1033,7 +1031,7 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) u64 pto; Double offset; gf_dash_group_get_presentation_time_offset(mpdin->dash, idx, &pto, ×cale); - offset = pto; + offset = (Double) pto; offset /= timescale; com->play.start_range -= offset; if (com->play.start_range < 0) com->play.start_range = 0; diff --git a/modules/openhevc_dec/openhevc_dec.c b/modules/openhevc_dec/openhevc_dec.c index bf9f2f1..ea223cb 100644 --- a/modules/openhevc_dec/openhevc_dec.c +++ b/modules/openhevc_dec/openhevc_dec.c @@ -413,76 +413,82 @@ static GF_Err HEVC_flush_picture(HEVCDec *ctx, char *outBuffer, u32 *outBufferLe if (!ctx->conv_to_8bit && ctx->direct_output) { *outBufferLength = ctx->out_size; ctx->has_pic = GF_TRUE; - } else { - if (ctx->conv_to_8bit) { - OpenHevc_Frame openHevcFramePtr; - if (libOpenHevcGetOutput(ctx->openHevcHandle, 1, &openHevcFramePtr)) { - GF_VideoSurface dst; - memset(&dst, 0, sizeof(GF_VideoSurface)); - dst.width = ctx->width; - dst.height = ctx->height; - dst.pitch_y = ctx->width; - dst.video_buffer = ctx->direct_output ? ctx->conv_buffer : outBuffer; - dst.pixel_format = GF_PIXEL_YV12; - - gf_color_write_yv12_10_to_yuv(&dst, (u8 *) openHevcFramePtr.pvY, (u8 *) openHevcFramePtr.pvU, (u8 *) openHevcFramePtr.pvV, openHevcFramePtr.frameInfo.nYPitch, ctx->width, ctx->height, NULL); - *outBufferLength = ctx->out_size; - - if (ctx->direct_output ) - ctx->has_pic = GF_TRUE; - } - } else if (ctx->pack_mode) { - OpenHevc_Frame openHFrame; - u8 *pY, *pU, *pV; + return GF_OK; + } + + if (ctx->conv_to_8bit) { + OpenHevc_Frame openHevcFramePtr; + if (libOpenHevcGetOutput(ctx->openHevcHandle, 1, &openHevcFramePtr)) { + GF_VideoSurface dst; + memset(&dst, 0, sizeof(GF_VideoSurface)); + dst.width = ctx->width; + dst.height = ctx->height; + dst.pitch_y = ctx->width; + dst.video_buffer = ctx->direct_output ? ctx->conv_buffer : outBuffer; + dst.pixel_format = GF_PIXEL_YV12; + + gf_color_write_yv12_10_to_yuv(&dst, (u8 *) openHevcFramePtr.pvY, (u8 *) openHevcFramePtr.pvU, (u8 *) openHevcFramePtr.pvV, openHevcFramePtr.frameInfo.nYPitch, ctx->width, ctx->height, NULL, 0); + *outBufferLength = ctx->out_size; + + if (ctx->direct_output ) + ctx->has_pic = GF_TRUE; + } + return GF_OK; + } + + if (ctx->pack_mode) { + OpenHevc_Frame openHFrame; + u8 *pY, *pU, *pV; - u32 idx_w, idx_h; - idx_w = ((ctx->frame_idx==0) || (ctx->frame_idx==2)) ? 0 : ctx->width; - idx_h = ((ctx->frame_idx==0) || (ctx->frame_idx==1)) ? 0 : ctx->height*2*ctx->stride; + u32 idx_w, idx_h; + idx_w = ((ctx->frame_idx==0) || (ctx->frame_idx==2)) ? 0 : ctx->width; + idx_h = ((ctx->frame_idx==0) || (ctx->frame_idx==1)) ? 0 : ctx->height*2*ctx->stride; - pY = (void*) ( outBuffer + idx_h + idx_w ); - pU = (void*) (outBuffer + 2*ctx->stride*2*ctx->height + idx_w/2 + idx_h/4); - pV = (void*) (outBuffer + 2*ctx->stride*2*ctx->height + ctx->stride*ctx->height + idx_w/2 + idx_h/4); + pY = (void*) ( outBuffer + idx_h + idx_w ); + pU = (void*) (outBuffer + 2*ctx->stride*2*ctx->height + idx_w/2 + idx_h/4); + pV = (void*) (outBuffer + 2*ctx->stride*2*ctx->height + ctx->stride*ctx->height + idx_w/2 + idx_h/4); - *outBufferLength = 0; - if (libOpenHevcGetOutput(ctx->openHevcHandle, 1, &openHFrame)) { - u32 i, s_stride, qs_stride, d_stride, dd_stride, hd_stride; + *outBufferLength = 0; + if (libOpenHevcGetOutput(ctx->openHevcHandle, 1, &openHFrame)) { + u32 i, s_stride, qs_stride, d_stride, dd_stride, hd_stride; - s_stride = openHFrame.frameInfo.nYPitch; - qs_stride = s_stride / 4; + s_stride = openHFrame.frameInfo.nYPitch; + qs_stride = s_stride / 4; - d_stride = ctx->stride; - dd_stride = 2*ctx->stride; - hd_stride = ctx->stride/2; + d_stride = ctx->stride; + dd_stride = 2*ctx->stride; + hd_stride = ctx->stride/2; - for (i=0; iheight; i++) { - memcpy(pY, (u8 *) openHFrame.pvY + i*s_stride, d_stride); - pY += dd_stride; + for (i=0; iheight; i++) { + memcpy(pY, (u8 *) openHFrame.pvY + i*s_stride, d_stride); + pY += dd_stride; - if (! (i%2) ) { - memcpy(pU, (u8 *) openHFrame.pvU + i*qs_stride, hd_stride); - pU += d_stride; + if (! (i%2) ) { + memcpy(pU, (u8 *) openHFrame.pvU + i*qs_stride, hd_stride); + pU += d_stride; - memcpy(pV, (u8 *) openHFrame.pvV + i*qs_stride, hd_stride); - pV += d_stride; - } + memcpy(pV, (u8 *) openHFrame.pvV + i*qs_stride, hd_stride); + pV += d_stride; } - - ctx->frame_idx++; - if (ctx->frame_idx==4) { - *outBufferLength = 4 * ctx->out_size; - ctx->frame_idx = 0; - } - } - } else { - openHevcFrame.pvY = (void*) outBuffer; - openHevcFrame.pvU = (void*) (outBuffer + ctx->stride * ctx->height); - openHevcFrame.pvV = (void*) (outBuffer + 5*ctx->stride * ctx->height/4); - *outBufferLength = 0; - if (libOpenHevcGetOutputCpy(ctx->openHevcHandle, 1, &openHevcFrame)) { - *outBufferLength = ctx->out_size; } + + ctx->frame_idx++; + if (ctx->frame_idx==4) { + *outBufferLength = 4 * ctx->out_size; + ctx->frame_idx = 0; + } } + return GF_OK; + } + + + openHevcFrame.pvY = (void*) outBuffer; + openHevcFrame.pvU = (void*) (outBuffer + ctx->stride * ctx->height); + openHevcFrame.pvV = (void*) (outBuffer + 5*ctx->stride * ctx->height/4); + *outBufferLength = 0; + if (libOpenHevcGetOutputCpy(ctx->openHevcHandle, 1, &openHevcFrame)) { + *outBufferLength = ctx->out_size; } return GF_OK; } diff --git a/modules/widgetman/widgetman.c b/modules/widgetman/widgetman.c index c74a2f8..0949240 100644 --- a/modules/widgetman/widgetman.c +++ b/modules/widgetman/widgetman.c @@ -3445,7 +3445,7 @@ exit: } -static Bool wm_enum_widget(void *cbk, char *file_name, char *file_path) +static Bool wm_enum_widget(void *cbk, char *file_name, char *file_path, GF_FileEnumInfo *file_info) { GF_WidgetInstance *wid; GF_WidgetManager *wm = (GF_WidgetManager *)cbk; @@ -3459,7 +3459,7 @@ static Bool wm_enum_widget(void *cbk, char *file_name, char *file_path) return 0; } -static Bool wm_enum_dir(void *cbk, char *file_name, char *file_path) +static Bool wm_enum_dir(void *cbk, char *file_name, char *file_path, GF_FileEnumInfo *file_info) { return (gf_enum_directory(file_path, 0, wm_enum_widget, cbk, "mgt")==GF_OK) ? GF_FALSE : GF_TRUE; } diff --git a/src/bifs/conditional.c b/src/bifs/conditional.c index 50b19a8..95f19e5 100644 --- a/src/bifs/conditional.c +++ b/src/bifs/conditional.c @@ -77,7 +77,7 @@ static void Conditional_execute(M_Conditional *node) /*set isActive - to clarify in the specs*/ node->isActive = 1; - gf_node_event_out_str((GF_Node *)node, "isActive"); + gf_node_event_out((GF_Node *)node, 3/*"isActive"*/); if (!node->buffer.bufferSize) return; /*we may replace ourselves*/ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index a0552a6..85e1ca8 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -2177,16 +2177,17 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) GF_SceneGraph *sg; #endif GF_List *temp_queue; - u32 in_time, end_time, i, count; + u32 in_time, end_time, i, count, frame_duration; Bool frame_drawn, has_timed_nodes=GF_FALSE, all_tx_done=GF_TRUE; #ifndef GPAC_DISABLE_LOG s32 event_time, route_time, smil_timing_time=0, time_node_time, texture_time, traverse_time, flush_time, txtime; #endif - in_time = gf_sys_clock(); /*lock compositor for the whole cycle*/ gf_sc_lock(compositor, 1); + in_time = gf_sys_clock(); + gf_sc_texture_cleanup_hw(compositor); /*first thing to do, let the video output handle user event if it is not threaded*/ @@ -2269,6 +2270,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) //first update all natural textures to figure out timing compositor->frame_delay = (u32) -1; compositor->next_frame_delay = (u32) -1; + frame_duration = compositor->frame_duration; #ifndef GPAC_DISABLE_LOG texture_time = gf_sys_clock(); @@ -2285,7 +2287,12 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) if (compositor->reset_graphics && txh->tx_io) gf_sc_texture_reset(txh); txh->update_texture_fcnt(txh); - if (!txh->stream_finished) all_tx_done=0; + if (!txh->stream_finished) { + u32 d = gf_mo_get_min_frame_dur(txh->stream); + if (d && (d < frame_duration)) frame_duration = d; + + all_tx_done=0; + } } //it may happen that we have a reconfigure request at this stage, especially if updating one of the textures @@ -2300,57 +2307,6 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) texture_time = gf_sys_clock() - texture_time; #endif - //this is correct but doesn't bring much and we may actually waste time while sleeping that could be used for texture upload - we prefer sleeping at the end of the pass -#if 0 - //if next video frame is due in this render cycle, wait until it matures - if ((compositor->frame_delay > 0) && (compositor->frame_delay != (u32) -1)) { - u32 diff=0; - compositor->frame_delay = MIN(compositor->frame_delay, (s32) compositor->frame_duration); - while (!compositor->video_frame_pending) { - gf_sleep(0); - diff = gf_sys_clock() - in_time; - if (diff >= (u32) compositor->frame_delay) - break; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Compositor] Waited %d ms for next frame and %d ms was required\n", diff, compositor->frame_delay)); - if (compositor->next_frame_delay != (u32) -1) { - if (diff < compositor->next_frame_delay) compositor->next_frame_delay -= diff; - else compositor->next_frame_delay = 1; - } - } -#endif - - - -#ifndef GPAC_DISABLE_SVG -#if SVG_FIXME - { /* Experimental (Not SVG compliant system events (i.e. battery, cpu ...) triggered to the root node)*/ - GF_Node *root = gf_sg_get_root_node(compositor->scene); - GF_DOM_Event evt; - if (gf_dom_listener_count(root)) { - u32 i, count; - count = gf_dom_listener_count(root); - for (i=0; ievent.type == GF_EVENT_CPU) { - GF_SystemRTInfo sys_rti; - if (gf_sys_get_rti(500, &sys_rti, GF_RTI_ALL_PROCESSES_TIMES)) { - evt.type = GF_EVENT_CPU; - evt.cpu_percentage = sys_rti.total_cpu_usage; - //fprintf(stderr, "%d\n",sys_rti.total_cpu_usage); - gf_dom_event_fire(root, NULL, &evt); - } - } else if (l->event.type == GF_EVENT_BATTERY) { //&& l->observer.target == (SVG_SA_Element *)node) { - evt.type = GF_EVENT_BATTERY; - gf_sys_get_battery_state(&evt.onBattery, &evt.batteryState, &evt.batteryLevel, NULL, NULL); - gf_dom_event_fire(root, NULL, &evt); - } - } - } - } -#endif -#endif //GPAC_DISABLE_SVG - #ifndef GPAC_DISABLE_SVG @@ -2436,7 +2392,6 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) #endif /*GPAC_DISABLE_VRML*/ - /*setup root visual BEFORE updating the composite textures (since they may depend on root setup)*/ gf_sc_setup_root_visual(compositor, gf_sg_get_root_node(compositor->scene)); @@ -2447,6 +2402,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) txtime = gf_sys_clock(); #endif /*update all composite textures*/ + compositor->texture_inserted = GF_FALSE; count = gf_list_count(compositor->textures); for (i=0; itextures, i); @@ -2456,11 +2412,18 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) /*signal graphics reset before updating*/ if (compositor->reset_graphics && txh->tx_io) gf_sc_texture_reset(txh); txh->update_texture_fcnt(txh); + if (compositor->texture_inserted) { + compositor->texture_inserted = GF_FALSE; + count = gf_list_count(compositor->textures); + i = gf_list_find(compositor->textures, txh); + } } //it may happen that we have a reconfigure request at this stage, especially if updating one of the textures update //forced a relayout - do it right away if (compositor->msg_type) { + //reset AR recompute flag, it will be reset when msg is handled + compositor->recompute_ar = 0; gf_sc_lock(compositor, 0); return; } @@ -2477,14 +2440,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) } if (compositor->is_hidden) { -#if 0 - gf_sc_lock(compositor, 0); - if (compositor->no_regulation) return; - gf_sleep(compositor->frame_duration); - return; -#else compositor->frame_draw_type = 0; -#endif } frame_drawn = (compositor->frame_draw_type==GF_SC_DRAW_FRAME) ? 1 : 0; @@ -2616,7 +2572,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) } if (compositor->bench_mode && (frame_drawn || (has_timed_nodes&&all_tx_done) )) { //in bench mode we always increase the clock of the fixed target simulation rate - this needs refinement if video is used ... - compositor->scene_sampled_clock += compositor->frame_duration; + compositor->scene_sampled_clock += frame_duration; } compositor->video_frame_pending=0; gf_sc_lock(compositor, 0); @@ -2638,7 +2594,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) if (compositor->next_frame_delay>end_time) compositor->next_frame_delay-=end_time; else compositor->next_frame_delay=0; - compositor->next_frame_delay = MIN(compositor->next_frame_delay, 2*compositor->frame_duration); + compositor->next_frame_delay = MIN(compositor->next_frame_delay, 2*frame_duration); if (compositor->next_frame_delay>2) { u32 diff=0; while (! compositor->msg_type && ! compositor->video_frame_pending) { @@ -2654,15 +2610,15 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) return; } - if (end_time > compositor->frame_duration) { + if (end_time > frame_duration) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Compositor did not go to sleep\n")); return; } /*compute sleep time till next frame*/ - end_time %= compositor->frame_duration; - gf_sleep(compositor->frame_duration - end_time); - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Compositor slept for %d ms\n", compositor->frame_duration - end_time)); + end_time %= frame_duration; + gf_sleep(frame_duration - end_time); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Compositor slept for %d ms\n", frame_duration - end_time)); } Bool gf_sc_visual_is_registered(GF_Compositor *compositor, GF_VisualManager *visual) @@ -2942,8 +2898,7 @@ static Bool gf_sc_on_event_ex(GF_Compositor *compositor , GF_Event *event, Bool if (from_user) compositor->msg_type &= ~GF_SR_CFG_WINDOWSIZE_NOTIF; } else { /*remove pending resize notif*/ - if (!compositor->new_width) - compositor->msg_type = 0; + compositor->msg_type &= ~GF_SR_CFG_SET_SIZE; } if (lock_ok) gf_sc_lock(compositor, GF_FALSE); } @@ -3425,12 +3380,12 @@ static void sc_cleanup_event_queue(GF_List *evq, GF_Node *node, GF_SceneGraph *s Bool del = 0; GF_QueuedEvent *qev = gf_list_get(evq, i); if (qev->node) { - if (node && qev->node) + if (node == qev->node) del = 1; if (sg && (gf_node_get_graph(qev->node)==sg)) del = 1; } - if (qev->sg==sg) + if (qev->sg && (qev->sg==sg)) del = 1; else if (qev->target && (qev->target->ptr_type == GF_DOM_EVENT_TARGET_NODE)) { if (node && ((GF_Node *)qev->target->ptr==node)) diff --git a/src/compositor/compositor_2d.c b/src/compositor/compositor_2d.c index b097df8..f0830e1 100644 --- a/src/compositor/compositor_2d.c +++ b/src/compositor/compositor_2d.c @@ -138,9 +138,10 @@ static void c2d_gl_fill_rect(void *cbk, u32 x, u32 y, u32 width, u32 height, GF_ #ifndef GPAC_DISABLE_3D -void compositor_2d_hybgl_clear_surface_ex(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool is_offscreen_clear) +void compositor_2d_hybgl_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool is_offscreen_clear) { SFColor rgb; + Fixed alpha = INT2FIX( GF_COL_A(BackColor) )/255; if (!visual->is_attached) return; if (!BackColor && !visual->offscreen) { @@ -155,18 +156,12 @@ void compositor_2d_hybgl_clear_surface_ex(GF_VisualManager *visual, GF_IRect *rc ra_union_rect(&visual->hybgl_drawn, rc); } } else { - Fixed a; rgb.red = INT2FIX( GF_COL_R(BackColor) ) / 255; rgb.green = INT2FIX( GF_COL_G(BackColor) )/255; rgb.blue = INT2FIX( GF_COL_B(BackColor) )/255; - a = INT2FIX( GF_COL_A(BackColor) )/255; - visual_3d_clear(visual, rgb , a); + visual_3d_clear(visual, rgb , alpha); } } -void compositor_2d_hybgl_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor) -{ - compositor_2d_hybgl_clear_surface_ex(visual, rc, BackColor, 1); -} void compositor_2d_hybgl_flush_video(GF_Compositor *compositor, GF_IRect *area) @@ -876,7 +871,7 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan o_rc.width = dst_wnd.w; o_rc.height = dst_wnd.h; - visual->ClearSurface(visual, &o_rc, visual->compositor->video_out->overlay_color_key); + visual->ClearSurface(visual, &o_rc, visual->compositor->video_out->overlay_color_key, 0); visual->has_overlays = GF_TRUE; /*mark drawable as overlay*/ ctx->drawable->flags |= DRAWABLE_IS_OVERLAY; diff --git a/src/compositor/drawable.c b/src/compositor/drawable.c index b5207b8..23bf49d 100644 --- a/src/compositor/drawable.c +++ b/src/compositor/drawable.c @@ -45,6 +45,7 @@ void vrml_drawable_pick(Drawable *drawable, GF_TraverseState *tr_state) StrikeInfo2D *si; Fixed x, y; u32 i, count; + GF_Node *appear = tr_state->override_appearance ? tr_state->override_appearance : tr_state->appear; GF_Compositor *compositor = tr_state->visual->compositor; #ifndef GPAC_DISABLE_3D @@ -73,7 +74,7 @@ void vrml_drawable_pick(Drawable *drawable, GF_TraverseState *tr_state) } if (asp.pen_props.width || asp.line_texture ) { - si = drawable_get_strikeinfo(tr_state->visual->compositor, drawable, &asp, tr_state->appear, NULL, 0, NULL); + si = drawable_get_strikeinfo(tr_state->visual->compositor, drawable, &asp, appear, NULL, 0, NULL); if (si && si->outline && gf_path_point_over(si->outline, x, y)) { goto picked; } @@ -97,8 +98,8 @@ picked: compositor->hit_texcoords.y = FIX_ONE - gf_divfix(drawable->path->bbox.y - y, drawable->path->bbox.height); #ifndef GPAC_DISABLE_VRML - if (compositor_is_composite_texture(tr_state->appear)) { - compositor->hit_appear = tr_state->appear; + if (compositor_is_composite_texture(appear)) { + compositor->hit_appear = appear; } else #endif { @@ -506,6 +507,7 @@ u32 drawable_get_aspect_2d_mpeg4(GF_Node *node, DrawAspect2D *asp, GF_TraverseSt M_Material2D *m = NULL; M_LineProperties *LP; M_XLineProperties *XLP; + GF_Node *appear = tr_state->override_appearance ? tr_state->override_appearance : tr_state->appear; u32 ret = 0; asp->pen_props.cap = GF_LINE_CAP_FLAT; @@ -515,14 +517,14 @@ u32 drawable_get_aspect_2d_mpeg4(GF_Node *node, DrawAspect2D *asp, GF_TraverseSt asp->line_color = 0xFFCCCCCC; asp->pen_props.width = 0; - if (tr_state->appear == NULL) goto check_default; + if (appear == NULL) goto check_default; - if ( ((M_Appearance *) tr_state->appear)->texture ) { - asp->fill_texture = gf_sc_texture_get_handler( ((M_Appearance *) tr_state->appear)->texture ); + if ( ((M_Appearance *) appear)->texture ) { + asp->fill_texture = gf_sc_texture_get_handler( ((M_Appearance *) appear)->texture ); } - m = (M_Material2D *) ((M_Appearance *)tr_state->appear)->material; + m = (M_Material2D *) ((M_Appearance *)appear)->material; if ( m == NULL) { asp->fill_color &= 0x00FFFFFF; goto check_default; @@ -649,6 +651,7 @@ DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseStat { DrawableContext *ctx; Bool skipFill; + GF_Node *appear; #ifndef GPAC_DISABLE_3D Bool texture_ready=0; #endif @@ -666,14 +669,16 @@ DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseStat ctx->drawable = drawable; + appear = tr_state->override_appearance ? tr_state->override_appearance : tr_state->appear; + /*usually set by colorTransform or changes in OrderedGroup*/ if (tr_state->invalidate_all) ctx->flags |= CTX_APP_DIRTY; ctx->aspect.fill_texture = NULL; - if (tr_state->appear) { - ctx->appear = tr_state->appear; - if (gf_node_dirty_get(tr_state->appear)) + if (appear) { + ctx->appear = appear; + if (gf_node_dirty_get(appear)) ctx->flags |= CTX_APP_DIRTY; } /*todo cliper*/ @@ -867,6 +872,7 @@ void drawable_finalize_sort_ex(DrawableContext *ctx, GF_TraverseState *tr_state, #endif Fixed pw; GF_Rect unclip, store_orig_bounds; + GF_Node *appear = tr_state->override_appearance ? tr_state->override_appearance : tr_state->appear; drawable_check_bounds(ctx, tr_state->visual); @@ -898,7 +904,7 @@ void drawable_finalize_sort_ex(DrawableContext *ctx, GF_TraverseState *tr_state, #endif /*get strike info & outline for exact bounds compute. If failure use default offset*/ - si = drawable_get_strikeinfo(tr_state->visual->compositor, ctx->drawable, &ctx->aspect, tr_state->appear, ctx->drawable->path, ctx->flags, NULL); + si = drawable_get_strikeinfo(tr_state->visual->compositor, ctx->drawable, &ctx->aspect, appear, ctx->drawable->path, ctx->flags, NULL); if (si && si->outline) { gf_path_get_bounds(si->outline, &ctx->bi->unclip); gf_mx2d_apply_rect(&tr_state->transform, &ctx->bi->unclip); @@ -1442,6 +1448,11 @@ DrawableContext *drawable_init_context_svg(Drawable *drawable, GF_TraverseState DrawableContext *ctx; assert(tr_state->visual); + /*setup SVG based on override appearance node */ + if (tr_state->override_appearance) { + return drawable_init_context_mpeg4(drawable, tr_state); + } + /*switched-off geometry nodes are not drawn*/ if (tr_state->switched_off) return NULL; diff --git a/src/compositor/events.c b/src/compositor/events.c index 2535b13..7b16c47 100644 --- a/src/compositor/events.c +++ b/src/compositor/events.c @@ -117,7 +117,7 @@ static void flush_text_node_edit(GF_Compositor *compositor, Bool final_flush) compositor->sel_buffer_len = compositor->sel_buffer_alloc = 0; compositor->edited_text = NULL; - if (signal) { + if (compositor->focus_node && signal) { memset(&info, 0, sizeof(GF_FieldInfo)); info.fieldIndex = (u32) -1; if (compositor->focus_text_type>=3) { @@ -249,7 +249,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) } else #endif /*GPAC_DISABLE_VRML*/ - { + if (compositor->focus_node) { #ifndef GPAC_DISABLE_SVG GF_ChildNodeItem *child = ((GF_ParentNode *) compositor->focus_node)->children; @@ -374,7 +374,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) flush_text_node_edit(compositor, 1); } - if (*res) { + if (res && *res) { const char *src = *res; compositor->sel_buffer_alloc = 2 + (u32) strlen(src); compositor->sel_buffer = gf_realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); @@ -2035,13 +2035,13 @@ void gf_sc_change_key_navigator(GF_Compositor *sr, GF_Node *n) if (sr->keynav_node) { kn = (M_KeyNavigator*)sr->keynav_node; kn->focusSet = 0; - gf_node_event_out_str(sr->keynav_node, "focusSet"); + gf_node_event_out(sr->keynav_node, 9/*"focusSet"*/); } sr->keynav_node = n; kn = (M_KeyNavigator*)n; if (n) { kn->focusSet = 1; - gf_node_event_out_str(sr->keynav_node, "focusSet"); + gf_node_event_out(sr->keynav_node, 9/*"focusSet"*/); } par = n ? kn->sensor : NULL; diff --git a/src/compositor/hardcoded_protos.c b/src/compositor/hardcoded_protos.c index 984309a..72ab673 100644 --- a/src/compositor/hardcoded_protos.c +++ b/src/compositor/hardcoded_protos.c @@ -968,6 +968,89 @@ void compositor_init_untransform(GF_Compositor *compositor, GF_Node *node) } } + + +/*StyleGroup: overrides appearance of all children*/ +typedef struct +{ + BASE_NODE + CHILDREN + + GF_Node *appearance; +} StyleGroup; + +typedef struct +{ + GROUPING_MPEG4_STACK_2D + StyleGroup sg; +} StyleGroupStack; + +static Bool StyleGroup_GetNode(GF_Node *node, StyleGroup *sg) +{ + GF_FieldInfo field; + memset(sg, 0, sizeof(StyleGroup)); + sg->sgprivate = node->sgprivate; + + if (gf_node_get_field(node, 0, &field) != GF_OK) return 0; + if (field.fieldType != GF_SG_VRML_MFNODE) return 0; + sg->children = *(GF_ChildNodeItem **) field.far_ptr; + + if (gf_node_get_field(node, 1, &field) != GF_OK) return 0; + if (field.fieldType != GF_SG_VRML_SFNODE) return 0; + sg->appearance = *(GF_Node **)field.far_ptr; + + return 1; +} + + +static void TraverseStyleGroup(GF_Node *node, void *rs, Bool is_destroy) +{ + Bool set = 0; + StyleGroupStack *stack = (StyleGroupStack *)gf_node_get_private(node); + GF_TraverseState *tr_state = (GF_TraverseState *) rs; + + if (is_destroy) { + gf_free(stack); + return; + } + + if (tr_state->traversing_mode==TRAVERSE_SORT) { + if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { + + gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); + /*flag is not set for PROTO*/ + gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0); + } + } + StyleGroup_GetNode(node, &stack->sg); + + if (!tr_state->override_appearance) { + set = 1; + tr_state->override_appearance = stack->sg.appearance; + } + group_2d_traverse((GF_Node *)&stack->sg, (GroupingNode2D*)stack, tr_state); + + if (set) { + tr_state->override_appearance = NULL; + } +} + +void compositor_init_style_group(GF_Compositor *compositor, GF_Node *node) +{ + StyleGroup sg; + if (StyleGroup_GetNode(node, &sg)) { + StyleGroupStack *stack; + GF_SAFEALLOC(stack, StyleGroupStack); + gf_node_set_private(node, stack); + gf_node_set_callback_function(node, TraverseStyleGroup); + stack->sg = sg; + gf_node_proto_set_grouping(node); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor2D] Unable to initialize style group\n")); + } +} + + /*hardcoded proto loading - this is mainly used for module development and testing...*/ void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node) { @@ -1024,6 +1107,10 @@ void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node) compositor_init_hc_flashshape(compositor, node); return; } + if (!strcmp(url, "urn:inet:gpac:builtin:StyleGroup")) { + compositor_init_style_group(compositor, node); + return; + } /*check proto modules*/ if (compositor->proto_modules) { diff --git a/src/compositor/mpeg4_animstream.c b/src/compositor/mpeg4_animstream.c index 9bcff37..acac8a3 100644 --- a/src/compositor/mpeg4_animstream.c +++ b/src/compositor/mpeg4_animstream.c @@ -106,7 +106,7 @@ static void animationstream_activate(AnimationStreamStack *stack, M_AnimationStr { animationstream_check_url(stack, as); as->isActive = 1; - gf_node_event_out_str((GF_Node*)as, "isActive"); + gf_node_event_out((GF_Node*)as, 6/*"isActive"*/); gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); @@ -116,7 +116,7 @@ static void animationstream_deactivate(AnimationStreamStack *stack, M_AnimationS { if (as->isActive) { as->isActive = 0; - gf_node_event_out_str((GF_Node*)as, "isActive"); + gf_node_event_out((GF_Node*)as, 6/*"isActive"*/); } if (stack->stream) { if (gf_mo_url_changed(stack->stream, &as->url)) diff --git a/src/compositor/mpeg4_audio.c b/src/compositor/mpeg4_audio.c index e44cae8..72156bb 100644 --- a/src/compositor/mpeg4_audio.c +++ b/src/compositor/mpeg4_audio.c @@ -44,7 +44,7 @@ static void audioclip_activate(AudioClipStack *st, M_AudioClip *ac) return; } ac->isActive = 1; - gf_node_event_out_str((GF_Node *)ac, "isActive"); + gf_node_event_out((GF_Node *)ac, 7/*"isActive"*/); gf_mo_set_speed(st->input.stream, st->input.speed); /*traverse all graph to get parent audio group*/ @@ -55,7 +55,7 @@ static void audioclip_deactivate(AudioClipStack *st, M_AudioClip *ac) { gf_sc_audio_stop(&st->input); ac->isActive = 0; - gf_node_event_out_str((GF_Node *)ac, "isActive"); + gf_node_event_out((GF_Node *)ac, 7/*"isActive"*/); st->time_handle.needs_unregister = 1; } @@ -90,7 +90,7 @@ static void audioclip_traverse(GF_Node *node, void *rs, Bool is_destroy) } if (st->set_duration && st->input.stream) { ac->duration_changed = gf_mo_get_duration(st->input.stream); - gf_node_event_out_str(node, "duration_changed"); + gf_node_event_out(node, 6/*"duration_changed"*/); st->set_duration = 0; } @@ -398,7 +398,7 @@ static void audiobuffer_traverse(GF_Node *node, void *rs, Bool is_destroy) static void audiobuffer_activate(AudioBufferStack *st, M_AudioBuffer *ab) { ab->isActive = 1; - gf_node_event_out_str((GF_Node *)ab, "isActive"); + gf_node_event_out((GF_Node *)ab, 17/*"isActive"*/); /*rerender all graph to get parent audio group*/ gf_sc_invalidate(st->output.compositor, NULL); st->done = 0; @@ -408,7 +408,7 @@ static void audiobuffer_activate(AudioBufferStack *st, M_AudioBuffer *ab) static void audiobuffer_deactivate(AudioBufferStack *st, M_AudioBuffer *ab) { ab->isActive = 0; - gf_node_event_out_str((GF_Node *)ab, "isActive"); + gf_node_event_out((GF_Node *)ab, 17/*"isActive"*/); st->time_handle.needs_unregister = 1; } diff --git a/src/compositor/mpeg4_background2d.c b/src/compositor/mpeg4_background2d.c index edf3595..b0ec705 100644 --- a/src/compositor/mpeg4_background2d.c +++ b/src/compositor/mpeg4_background2d.c @@ -104,6 +104,7 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state { Bool clear_all = GF_TRUE; u32 color; + Bool is_offscreen = GF_FALSE; Background2DStack *stack; if (!ctx || !ctx->drawable || !ctx->drawable->node) return; stack = (Background2DStack *) gf_node_get_private(ctx->drawable->node); @@ -132,6 +133,7 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state //in opengl auto mode we still have to clear the canvas if (!tr_state->immediate_draw && !tr_state->visual->offscreen && tr_state->visual->compositor->hybrid_opengl) { clear_all = GF_FALSE; + is_offscreen = GF_TRUE; color &= 0x00FFFFFF; } else #endif @@ -143,7 +145,7 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state if (clear_all && !tr_state->visual->offscreen && tr_state->visual->compositor->hybrid_opengl) { if (ctx->flags & CTX_BACKROUND_NOT_LAYER) { color &= 0x00FFFFFF; - compositor_2d_hybgl_clear_surface_ex(tr_state->visual, NULL, color, GF_FALSE); + compositor_2d_hybgl_clear_surface(tr_state->visual, NULL, color, GF_FALSE); clear_all = GF_FALSE; } } @@ -153,7 +155,7 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state ) { /*directly clear with specified color*/ if (clear_all) - tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, color); + tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, color, is_offscreen); } else { u32 i; GF_IRect clip; @@ -165,7 +167,7 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state clip = ctx->bi->clip; gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i].rect); if (clip.width && clip.height) { - tr_state->visual->ClearSurface(tr_state->visual, &clip, color); + tr_state->visual->ClearSurface(tr_state->visual, &clip, color, is_offscreen); } } } diff --git a/src/compositor/mpeg4_composite.c b/src/compositor/mpeg4_composite.c index 2739c7a..2e96aa7 100644 --- a/src/compositor/mpeg4_composite.c +++ b/src/compositor/mpeg4_composite.c @@ -166,7 +166,7 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f gf_node_unregister(c3d->background, n); gf_node_register(btop, n); c3d->background = btop; - gf_node_event_out_str(n, "background"); + gf_node_event_out(n, 5/*"background"*/); ret = 1; } if (force_check || gf_node_dirty_get(c3d->viewpoint)) { @@ -178,7 +178,7 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f gf_node_unregister(c3d->viewpoint, n); gf_node_register(btop, n); c3d->viewpoint = btop; - gf_node_event_out_str(n, "viewpoint"); + gf_node_event_out(n, 8/*"viewpoint"*/); ret = 1; } @@ -191,7 +191,7 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f gf_node_unregister(c3d->fog, n); gf_node_register(btop, n); c3d->fog = btop; - gf_node_event_out_str(n, "fog"); + gf_node_event_out(n, 6/*"fog"*/); ret = 1; } @@ -204,7 +204,7 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f gf_node_unregister(c3d->navigationInfo, n); gf_node_register(btop, n); c3d->navigationInfo = btop; - gf_node_event_out_str(n, "navigationInfo"); + gf_node_event_out(n, 7/*"navigationInfo"*/); ret = 1; } return ret; @@ -222,7 +222,7 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f gf_node_unregister(c2d->background, n); gf_node_register(btop, n); c2d->background = btop; - gf_node_event_out_str(n, "background"); + gf_node_event_out(n, 5/*"background"*/); ret = 1; } @@ -235,7 +235,7 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f gf_node_unregister(c2d->viewport, n); gf_node_register(btop, n); c2d->viewport = btop; - gf_node_event_out_str(n, "viewport"); + gf_node_event_out(n, 6/*"viewport"*/); ret = 1; } diff --git a/src/compositor/mpeg4_grouping_3d.c b/src/compositor/mpeg4_grouping_3d.c index ae525a3..1ebf79c 100644 --- a/src/compositor/mpeg4_grouping_3d.c +++ b/src/compositor/mpeg4_grouping_3d.c @@ -128,7 +128,7 @@ void TraverseCollision(GF_Node *node, void *rs, Bool is_destroy) } if (tr_state->camera->collide_flags & CF_COLLISION) { col->collideTime = gf_node_get_scene_time(node); - gf_node_event_out_str(node, "collideTime"); + gf_node_event_out(node, 5/*"collideTime"*/); /*if not closer restore*/ if (collide_flags && (last_distcamera->collide_dist)) { tr_state->camera->collide_flags = collide_flags; diff --git a/src/compositor/mpeg4_layer_2d.c b/src/compositor/mpeg4_layer_2d.c index 19e31e7..9f60b47 100644 --- a/src/compositor/mpeg4_layer_2d.c +++ b/src/compositor/mpeg4_layer_2d.c @@ -54,7 +54,7 @@ static void l2d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc gf_node_unregister(l2d->background, n); gf_node_register(btop, n); l2d->background = btop; - gf_node_event_out_str(n, "background"); + gf_node_event_out(n, 4/*"background"*/); } if (force_traverse) gf_node_traverse(l2d->viewport, tr_state); btop = (GF_Node*)gf_list_get(tr_state->viewpoints, 0); @@ -62,7 +62,7 @@ static void l2d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc gf_node_unregister(l2d->viewport, n); gf_node_register(btop, n); l2d->viewport = btop; - gf_node_event_out_str(n, "viewport"); + gf_node_event_out(n, 5/*"viewport"*/); } } diff --git a/src/compositor/mpeg4_layer_3d.c b/src/compositor/mpeg4_layer_3d.c index 3e86362..f5d1679 100644 --- a/src/compositor/mpeg4_layer_3d.c +++ b/src/compositor/mpeg4_layer_3d.c @@ -101,7 +101,7 @@ static void l3d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc gf_node_unregister(l3d->background, n); gf_node_register(btop, n); l3d->background = btop; - gf_node_event_out_str(n, "background"); + gf_node_event_out(n, 4/*"background"*/); } if (force_traverse) gf_node_traverse(l3d->viewpoint, tr_state); btop = (GF_Node*)gf_list_get(tr_state->viewpoints, 0); @@ -109,7 +109,7 @@ static void l3d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc gf_node_unregister(l3d->viewpoint, n); gf_node_register(btop, n); l3d->viewpoint = btop; - gf_node_event_out_str(n, "viewpoint"); + gf_node_event_out(n, 7/*"viewpoint"*/); } if (force_traverse) gf_node_traverse(l3d->navigationInfo, tr_state); btop = (GF_Node*)gf_list_get(tr_state->navigations, 0); @@ -117,7 +117,7 @@ static void l3d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc gf_node_unregister(l3d->navigationInfo, n); gf_node_register(btop, n); l3d->navigationInfo = btop; - gf_node_event_out_str(n, "navigationInfo"); + gf_node_event_out(n, 6/*"navigationInfo"*/); } if (force_traverse) gf_node_traverse(l3d->fog, tr_state); btop = (GF_Node*)gf_list_get(tr_state->fogs, 0); @@ -125,7 +125,7 @@ static void l3d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc gf_node_unregister(l3d->fog, n); gf_node_register(btop, n); l3d->fog = btop; - gf_node_event_out_str(n, "fog"); + gf_node_event_out(n, 5/*"fog"*/); } tr_state->traversing_mode = mode; } diff --git a/src/compositor/mpeg4_layout.c b/src/compositor/mpeg4_layout.c index 2b997bd..990df3f 100644 --- a/src/compositor/mpeg4_layout.c +++ b/src/compositor/mpeg4_layout.c @@ -43,6 +43,7 @@ typedef struct /*for keyboard navigation*/ GF_SensorHandler hdl; s32 key_scroll; + Bool keys_active; } LayoutStack; typedef struct @@ -200,6 +201,7 @@ static void layout_justify(LayoutStack *st, M_Layout *l) /*set major alignment (X) */ cg = (ChildGroup *)gf_list_get(st->groups, first); + if (!cg) continue; switch (major) { case L_END: cg->final.x = st->clip.x + st->clip.width - li->width; @@ -766,21 +768,32 @@ static Bool OnLayout(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF_Even switch (ev->key.key_code) { case GF_KEY_LEFT: + if (!st->keys_active) return 0; + if (vertical) return 0; st->key_scroll = -1; break; case GF_KEY_RIGHT: + if (!st->keys_active) return 0; + if (vertical) return 0; st->key_scroll = +1; break; case GF_KEY_UP: + if (!st->keys_active) return 0; + if (!vertical) return 0; st->key_scroll = +1; break; case GF_KEY_DOWN: + if (!st->keys_active) return 0; + if (!vertical) return 0; st->key_scroll = -1; break; + case GF_KEY_ENTER: + st->keys_active = !st->keys_active; + break; default: st->key_scroll = 0; return 0; diff --git a/src/compositor/mpeg4_sensors.c b/src/compositor/mpeg4_sensors.c index 96f498a..2168244 100644 --- a/src/compositor/mpeg4_sensors.c +++ b/src/compositor/mpeg4_sensors.c @@ -271,10 +271,10 @@ static Bool OnDiscSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF_ if (ds->autoOffset) { ds->offset = ds->rotation_changed; /*that's an exposedField*/ - if (!is_cancel) gf_node_event_out_str(sh->sensor, "offset"); + if (!is_cancel) gf_node_event_out(sh->sensor, 4/*"offset"*/); } ds->isActive = 0; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isActive"); + if (!is_cancel) gf_node_event_out(sh->sensor, 5/*"isActive"*/); sh->grabbed = 0; return is_cancel ? 0 : 1; } else if (is_mouse) { @@ -283,7 +283,7 @@ static Bool OnDiscSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF_ gf_mx_copy(stack->initial_matrix, compositor->hit_local_to_world); stack->start_angle = gf_atan2(compositor->hit_local_point.y, compositor->hit_local_point.x); ds->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 5/*"isActive"*/); sh->grabbed = 1; return 1; } @@ -302,17 +302,17 @@ static Bool OnDiscSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF_ if (rot > ds->maxAngle) rot = ds->maxAngle; } ds->rotation_changed = rot; - gf_node_event_out_str(sh->sensor, "rotation_changed"); + gf_node_event_out(sh->sensor, 6/*"rotation_changed"*/); ds->trackPoint_changed.x = res.x; ds->trackPoint_changed.y = res.y; - gf_node_event_out_str(sh->sensor, "trackPoint_changed"); + gf_node_event_out(sh->sensor, 7/*"trackPoint_changed"*/); return 1; } } else { if (!ds->isActive && is_over && (ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) { ds->isActive = 1; stack->start_angle = ds->offset; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 5/*"isActive"*/); return 1; } else if (ds->isActive && (ev->type==GF_EVENT_KEYDOWN)) { @@ -341,7 +341,7 @@ static Bool OnDiscSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF_ } stack->start_angle = res; ds->rotation_changed = res; - gf_node_event_out_str(sh->sensor, "rotation_changed"); + gf_node_event_out(sh->sensor, 6/*"rotation_changed"*/); return 1; } } @@ -406,11 +406,11 @@ static Bool OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, ) ) { if (ps->autoOffset) { ps->offset = ps->translation_changed; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "offset"); + if (!is_cancel) gf_node_event_out(sh->sensor, 4/*"offset"*/); } ps->isActive = 0; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isActive"); + if (!is_cancel) gf_node_event_out(sh->sensor, 5/*"isActive"*/); sh->grabbed = 0; return is_cancel ? 0 : 1; } else if (is_mouse) { @@ -419,7 +419,7 @@ static Bool OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, stack->start_drag.x = compositor->hit_local_point.x - ps->offset.x; stack->start_drag.y = compositor->hit_local_point.y - ps->offset.y; ps->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 5/*"isActive"*/); sh->grabbed = 1; /*fallthrough to fire mouse coords*/ //return 1; @@ -434,7 +434,7 @@ static Bool OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, ps->trackPoint_changed.x = res.x; ps->trackPoint_changed.y = res.y; - gf_node_event_out_str(sh->sensor, "trackPoint_changed"); + gf_node_event_out(sh->sensor, 6/*"trackPoint_changed"*/); res.x -= stack->start_drag.x; res.y -= stack->start_drag.y; @@ -451,14 +451,14 @@ static Bool OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, } ps->translation_changed.x = res.x; ps->translation_changed.y = res.y; - gf_node_event_out_str(sh->sensor, "translation_changed"); + gf_node_event_out(sh->sensor, 7/*"translation_changed"*/); return 1; } } else { if (!ps->isActive && is_over && (ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) { ps->isActive = 1; stack->start_drag = ps->offset; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 5/*"isActive"*/); return 1; } else if (ps->isActive && (ev->type==GF_EVENT_KEYDOWN)) { @@ -496,10 +496,10 @@ static Bool OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, if (res.y > ps->maxPosition.y) res.y = ps->maxPosition.y; } ps->translation_changed = res; - gf_node_event_out_str(sh->sensor, "translation_changed"); + gf_node_event_out(sh->sensor, 7/*"translation_changed"*/); ps->trackPoint_changed.x = res.x + stack->start_drag.x; ps->trackPoint_changed.y = res.y + stack->start_drag.y; - gf_node_event_out_str(sh->sensor, "trackPoint_changed"); + gf_node_event_out(sh->sensor, 6/*"trackPoint_changed"*/); stack->start_drag = res; return 1; } @@ -571,13 +571,13 @@ static Bool OnProximitySensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_canc if (prox2D_is_in_sensor(stack, ps, compositor->hit_local_point.x, compositor->hit_local_point.y)) { ps->position_changed.x = compositor->hit_local_point.x; ps->position_changed.y = compositor->hit_local_point.y; - gf_node_event_out_str(sh->sensor, "position_changed"); + gf_node_event_out(sh->sensor, 4/*"position_changed"*/); if (!ps->isActive) { ps->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 3/*"isActive"*/); ps->enterTime = stack->last_time; - gf_node_event_out_str(sh->sensor, "enterTime"); + gf_node_event_out(sh->sensor, 6/*"enterTime"*/); } return 1; } @@ -585,9 +585,9 @@ static Bool OnProximitySensor2D(GF_SensorHandler *sh, Bool is_over, Bool is_canc /*either we're not over the shape or we're not in sensor*/ if (ps->isActive) { ps->exitTime = stack->last_time; - gf_node_event_out_str(sh->sensor, "exitTime"); + gf_node_event_out(sh->sensor, 7/*"exitTime"*/); ps->isActive = 0; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 3/*"isActive"*/); return 1; } return 0; @@ -655,16 +655,16 @@ static Bool OnTouchSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF || /*keyboard*/ ((ev->type==GF_EVENT_KEYUP) && (ev->key.key_code==GF_KEY_ENTER) ) ) { ts->touchTime = gf_node_get_scene_time(sh->sensor); - if (!is_cancel) gf_node_event_out_str(sh->sensor, "touchTime"); + if (!is_cancel) gf_node_event_out(sh->sensor, 6/*"touchTime"*/); ts->isActive = 0; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isActive"); + if (!is_cancel) gf_node_event_out(sh->sensor, 4/*"isActive"*/); sh->grabbed = 0; return is_cancel ? 0 : 1; } } if (is_over != ts->isOver) { ts->isOver = is_over; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isOver"); + if (!is_cancel) gf_node_event_out(sh->sensor, 5/*"isOver"*/); return is_cancel ? 0 : 1; } if (!ts->isActive && is_over) { @@ -672,21 +672,21 @@ static Bool OnTouchSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF || /*keyboard*/ ((ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) ) { ts->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 4/*"isActive"*/); sh->grabbed = 1; return 1; } if (ev->type==GF_EVENT_MOUSEUP) return 0; } - if (is_over && is_mouse) { + if (is_over && is_mouse && (ev->type==GF_EVENT_MOUSEMOVE) ) { /*THIS IS NOT CONFORMANT, the hitpoint should be in the touchsensor coordinate system, eg we should store the matrix from TS -> shape and apply that ...*/ ts->hitPoint_changed = compositor->hit_local_point; - gf_node_event_out_str(sh->sensor, "hitPoint_changed"); + gf_node_event_out(sh->sensor, 1/*"hitPoint_changed"*/); ts->hitNormal_changed = compositor->hit_normal; - gf_node_event_out_str(sh->sensor, "hitNormal_changed"); + gf_node_event_out(sh->sensor, 2/*"hitNormal_changed"*/); ts->hitTexCoord_changed = compositor->hit_texcoords; - gf_node_event_out_str(sh->sensor, "hitTexCoord_changed"); + gf_node_event_out(sh->sensor, 3/*"hitTexCoord_changed"*/); return 1; } return 0; @@ -750,16 +750,16 @@ void TraverseProximitySensor(GF_Node *node, void *rs, Bool is_destroy) if (!ps->isActive) { ps->isActive = 1; - gf_node_event_out_str(node, "isActive"); + gf_node_event_out(node, 3/*"isActive"*/); ps->enterTime = gf_node_get_scene_time(node); - gf_node_event_out_str(node, "enterTime"); + gf_node_event_out(node, 6/*"enterTime"*/); } if ((ps->position_changed.x != user_pos.x) || (ps->position_changed.y != user_pos.y) || (ps->position_changed.z != user_pos.z) ) { ps->position_changed = user_pos; - gf_node_event_out_str(node, "position_changed"); + gf_node_event_out(node, 4/*"position_changed"*/); } dist = tr_state->camera->target; gf_mx_apply_vec(&mx, &dist); @@ -771,13 +771,13 @@ void TraverseProximitySensor(GF_Node *node, void *rs, Bool is_destroy) || (ori.y != ps->orientation_changed.y) || (ori.z != ps->orientation_changed.z) ) { ps->orientation_changed = ori; - gf_node_event_out_str(node, "orientation_changed"); + gf_node_event_out(node, 5/*"orientation_changed"*/); } } else if (ps->isActive) { ps->isActive = 0; - gf_node_event_out_str(node, "isActive"); + gf_node_event_out(node, 3/*"isActive"*/); ps->exitTime = gf_node_get_scene_time(node); - gf_node_event_out_str(node, "exitTime"); + gf_node_event_out(node, 7/*"exitTime"*/); } } @@ -824,10 +824,10 @@ static Bool OnPlaneSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF ) ) { if (ps->autoOffset) { ps->offset = ps->translation_changed; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "offset"); + if (!is_cancel) gf_node_event_out(sh->sensor, 4/*"offset"*/); } ps->isActive = 0; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isActive"); + if (!is_cancel) gf_node_event_out(sh->sensor, 5/*"isActive"*/); sh->grabbed = 0; return is_cancel ? 0 : 1; } @@ -840,7 +840,7 @@ static Bool OnPlaneSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF stack->tracker.normal.z = FIX_ONE; stack->tracker.d = - gf_vec_dot(stack->start_drag, stack->tracker.normal); ps->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 5/*"isActive"*/); sh->grabbed = 1; return 1; } @@ -851,7 +851,7 @@ static Bool OnPlaneSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF gf_mx_apply_ray(&stack->initial_matrix, &loc_ray); gf_plane_intersect_line(&stack->tracker, &loc_ray.orig, &loc_ray.dir, &res); ps->trackPoint_changed = res; - gf_node_event_out_str(sh->sensor, "trackPoint_changed"); + gf_node_event_out(sh->sensor, 6/*"trackPoint_changed"*/); gf_vec_diff(res, res, stack->start_drag); /*clip*/ @@ -864,14 +864,14 @@ static Bool OnPlaneSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF if (res.y > ps->maxPosition.y) res.y = ps->maxPosition.y; } ps->translation_changed = res; - gf_node_event_out_str(sh->sensor, "translation_changed"); + gf_node_event_out(sh->sensor, 7/*"translation_changed"*/); return 1; } } else { if (!ps->isActive && is_over && (ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) { ps->isActive = 1; stack->start_drag = ps->offset; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 5/*"isActive"*/); return 1; } else if (ps->isActive && (ev->type==GF_EVENT_KEYDOWN)) { @@ -911,7 +911,7 @@ static Bool OnPlaneSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF } stack->start_drag = res; ps->translation_changed = res; - gf_node_event_out_str(sh->sensor, "translation_changed"); + gf_node_event_out(sh->sensor, 7/*"translation_changed"*/); return 1; } } @@ -975,10 +975,10 @@ static Bool OnCylinderSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, ) ) { if (cs->autoOffset) { cs->offset = cs->rotation_changed.q; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "offset"); + if (!is_cancel) gf_node_event_out(sh->sensor, 5/*"offset"*/); } cs->isActive = 0; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isActive"); + if (!is_cancel) gf_node_event_out(sh->sensor, 6/*"isActive"*/); sh->grabbed = 0; return is_cancel ? 0 : 1; } @@ -1021,7 +1021,7 @@ static Bool OnCylinderSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, cs->rotation_changed.z = 0; cs->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 6/*"isActive"*/); sh->grabbed = 1; return 1; } @@ -1032,7 +1032,7 @@ static Bool OnCylinderSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, if (is_over) { cs->trackPoint_changed = compositor->hit_local_point; - gf_node_event_out_str(sh->sensor, "trackPoint_changed"); + gf_node_event_out(sh->sensor, 8/*"trackPoint_changed"*/); } else { GF_Plane project_to; r = compositor->hit_world_ray; @@ -1074,7 +1074,7 @@ static Bool OnCylinderSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, else if (rot > cs->maxAngle) rot = cs->maxAngle; } cs->rotation_changed.q = rot; - gf_node_event_out_str(sh->sensor, "rotation_changed"); + gf_node_event_out(sh->sensor, 7/*"rotation_changed"*/); return 1; } } else { @@ -1083,7 +1083,7 @@ static Bool OnCylinderSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, cs->rotation_changed.q = cs->offset; cs->rotation_changed.x = cs->rotation_changed.z = 0; cs->rotation_changed.y = FIX_ONE; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 6/*"isActive"*/); return 1; } else if (cs->isActive && (ev->type==GF_EVENT_KEYDOWN)) { @@ -1110,7 +1110,7 @@ static Bool OnCylinderSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, if (res > cs->maxAngle) res = cs->maxAngle; } cs->rotation_changed.q = res; - gf_node_event_out_str(sh->sensor, "rotation_changed"); + gf_node_event_out(sh->sensor, 7/*"rotation_changed"*/); return 1; } } @@ -1175,10 +1175,10 @@ static Bool OnSphereSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, G ) ) { if (sphere->autoOffset) { sphere->offset = sphere->rotation_changed; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "offset"); + if (!is_cancel) gf_node_event_out(sh->sensor, 2/*"offset"*/); } sphere->isActive = 0; - if (!is_cancel) gf_node_event_out_str(sh->sensor, "isActive"); + if (!is_cancel) gf_node_event_out(sh->sensor, 3/*"isActive"*/); sh->grabbed = 0; return is_cancel ? 0 : 1; } @@ -1191,7 +1191,7 @@ static Bool OnSphereSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, G st->grab_vec = gf_vec_scale(compositor->hit_local_point, gf_invfix(st->radius)); sphere->isActive = 1; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 3/*"isActive"*/); sh->grabbed = 1; return 1; } @@ -1202,7 +1202,7 @@ static Bool OnSphereSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, G Fixed cl; if (is_over) { sphere->trackPoint_changed = compositor->hit_local_point; - gf_node_event_out_str(sh->sensor, "trackPoint_changed"); + gf_node_event_out(sh->sensor, 5/*"trackPoint_changed"*/); } else { GF_Ray r; r = compositor->hit_world_ray; @@ -1233,14 +1233,14 @@ static Bool OnSphereSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, G q1 = gf_quat_multiply(&q1, &q2); } sphere->rotation_changed = gf_quat_to_rotation(&q1); - gf_node_event_out_str(sh->sensor, "rotation_changed"); + gf_node_event_out(sh->sensor, 4/*"rotation_changed"*/); return 1; } } else { if (!sphere->isActive && is_over && (ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) { sphere->isActive = 1; sphere->rotation_changed = sphere->offset; - gf_node_event_out_str(sh->sensor, "isActive"); + gf_node_event_out(sh->sensor, 3/*"isActive"*/); return 1; } else if (sphere->isActive && (ev->type==GF_EVENT_KEYDOWN)) { @@ -1285,7 +1285,7 @@ static Bool OnSphereSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, G return 0; } sphere->rotation_changed = res; - gf_node_event_out_str(sh->sensor, "rotation_changed"); + gf_node_event_out(sh->sensor, 4/*"rotation_changed"*/); return 1; } } @@ -1342,15 +1342,15 @@ void TraverseVisibilitySensor(GF_Node *node, void *rs, Bool is_destroy) if (visible && !vs->isActive) { vs->isActive = 1; - gf_node_event_out_str(node, "isActive"); + gf_node_event_out(node, 5/*"isActive"*/); vs->enterTime = gf_node_get_scene_time(node); - gf_node_event_out_str(node, "enterTime"); + gf_node_event_out(node, 3/*"enterTime"*/); } else if (!visible && vs->isActive) { vs->isActive = 0; - gf_node_event_out_str(node, "isActive"); + gf_node_event_out(node, 5/*"isActive"*/); vs->exitTime = gf_node_get_scene_time(node); - gf_node_event_out_str(node, "exitTime"); + gf_node_event_out(node, 4/*"exitTime"*/); } } } @@ -1543,18 +1543,18 @@ void envtest_evaluate(GF_Node *node, GF_Route *_route) if (equal) { envtest->valueEqual=(equal==1) ? 1 : 0; - gf_node_event_out_str(node, "valueEqual"); + gf_node_event_out(node, 6/*"valueEqual"*/); } else if (smaller) { envtest->valueSmaller=1; - gf_node_event_out_str(node, "valueSmaller"); + gf_node_event_out(node, 7/*"valueSmaller"*/); } else if (larger) { envtest->valueLarger=1; - gf_node_event_out_str(node, "valueLarger"); + gf_node_event_out(node, 5/*"valueLarger"*/); } envtest->parameterValue.buffer = gf_strdup(par_value); - gf_node_event_out_str(node, "parameterValue"); + gf_node_event_out(node, 8/*"parameterValue"*/); } void compositor_evaluate_envtests(GF_Compositor *compositor, u32 param_type) diff --git a/src/compositor/mpeg4_textures.c b/src/compositor/mpeg4_textures.c index f3e46ce..d7d3b77 100644 --- a/src/compositor/mpeg4_textures.c +++ b/src/compositor/mpeg4_textures.c @@ -69,7 +69,7 @@ static Bool movietexture_get_loop(MovieTextureStack *stack, M_MovieTexture *mt) static void movietexture_activate(MovieTextureStack *stack, M_MovieTexture *mt, Double scene_time) { mt->isActive = 1; - gf_node_event_out_str((GF_Node*)mt, "isActive"); + gf_node_event_out((GF_Node*)mt, 8/*"isActive"*/); if (!stack->txh.is_open) { scene_time -= mt->startTime; gf_sc_texture_play_from_to(&stack->txh, &mt->url, scene_time, -1, gf_mo_get_loop(stack->txh.stream, mt->loop), 0); @@ -81,7 +81,7 @@ static void movietexture_activate(MovieTextureStack *stack, M_MovieTexture *mt, static void movietexture_deactivate(MovieTextureStack *stack, M_MovieTexture *mt) { mt->isActive = 0; - gf_node_event_out_str((GF_Node*)mt, "isActive"); + gf_node_event_out((GF_Node*)mt, 8/*"isActive"*/); stack->time_handle.needs_unregister = 1; if (stack->txh.is_open) { @@ -113,7 +113,7 @@ static void movietexture_update(GF_TextureHandler *txh) if (!st->first_frame_fetched && (txh->needs_refresh) ) { st->first_frame_fetched = 1; txnode->duration_changed = gf_mo_get_duration(txh->stream); - gf_node_event_out_str(txh->owner, "duration_changed"); + gf_node_event_out(txh->owner, 7/*"duration_changed"*/); /*stop stream if needed*/ if (!txnode->isActive && txh->is_open) { gf_mo_pause(txh->stream); diff --git a/src/compositor/svg_grouping.c b/src/compositor/svg_grouping.c index e0f5a25..55cb2f8 100644 --- a/src/compositor/svg_grouping.c +++ b/src/compositor/svg_grouping.c @@ -609,7 +609,7 @@ static void svg_traverse_g(GF_Node *node, void *rs, Bool is_destroy) tr_state->depth_gain = gf_mulfix(scale, dscale); #endif - if (opacity < FIX_ONE) { + if (!tr_state->override_appearance && (opacity < FIX_ONE)) { if (!group->cache) { group->cache = group_cache_new(tr_state->visual->compositor, node); group->cache->force_recompute = 1; diff --git a/src/compositor/texturing.c b/src/compositor/texturing.c index ecf7519..3bebb9f 100644 --- a/src/compositor/texturing.c +++ b/src/compositor/texturing.c @@ -40,8 +40,10 @@ void gf_sc_texture_setup(GF_TextureHandler *txh, GF_Compositor *compositor, GF_N txh->owner = owner; txh->compositor = compositor; /*insert texture in reverse order, so that textures in sub documents/scenes are updated before parent ones*/ - if (gf_list_find(compositor->textures, txh)<0) + if (gf_list_find(compositor->textures, txh)<0) { gf_list_insert(compositor->textures, txh, 0); + compositor->texture_inserted = GF_TRUE; + } if (!txh->update_texture_fcnt) txh->update_texture_fcnt = update_texture_void; } diff --git a/src/compositor/visual_manager.h b/src/compositor/visual_manager.h index 14eb1ae..ee70873 100644 --- a/src/compositor/visual_manager.h +++ b/src/compositor/visual_manager.h @@ -126,8 +126,9 @@ struct _visual_manager BackColor for background nodes 0x00000000 for composite, compositor clear color otherwise + offscreen_clear is set to 1 when the clear targets the canvas buffer in hybrid GL mode */ - void (*ClearSurface)(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor); + void (*ClearSurface)(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool offscreen_clear); /*draws specified texture as flat bitmap*/ Bool (*DrawBitmap)(GF_VisualManager *visual, GF_TraverseState *tr_state, DrawableContext *ctx, GF_ColorKey *col_key); diff --git a/src/compositor/visual_manager_2d.c b/src/compositor/visual_manager_2d.c index 8de00e8..b9a8ac7 100644 --- a/src/compositor/visual_manager_2d.c +++ b/src/compositor/visual_manager_2d.c @@ -327,12 +327,12 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) tr_state->traversing_mode = TRAVERSE_SORT; ctx->flags &= ~CTX_BACKROUND_NOT_LAYER; } else { - visual->ClearSurface(visual, NULL, 0); + visual->ClearSurface(visual, NULL, 0, 0); } } else #endif { - visual->ClearSurface(visual, NULL, 0); + visual->ClearSurface(visual, NULL, 0, 0); } return GF_OK; } @@ -416,6 +416,7 @@ static u32 gf_irect_relation(GF_IRect *rc1, GF_IRect *rc2) void ra_refresh(GF_RectArray *ra) { u32 i, j, k; +restart: for (i=0; icount; i++) { for (j=i+1; jcount; j++) { switch (gf_irect_relation(&ra->list[j].rect, &ra->list[i].rect)) { @@ -437,7 +438,7 @@ void ra_refresh(GF_RectArray *ra) } ra->count--; if (ra->count>=2) - ra_refresh(ra); + goto restart; return; default: break; @@ -684,7 +685,7 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta ra_refresh(&visual->to_redraw); if (visual->compositor->debug_defer) { - visual->ClearSurface(visual, &visual->top_clipper, 0); + visual->ClearSurface(visual, &visual->top_clipper, 0, 0); } } @@ -710,6 +711,7 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta if (bck_ctx) { drawable_check_bounds(bck_ctx, visual); tr_state->ctx = bck_ctx; + tr_state->appear = NULL; visual->draw_node_index = 0; /*force clearing entire zone, not just viewport, when using color. If texture, we MUST @@ -735,11 +737,11 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta if (visual->to_redraw.list[k].opaque_node_index > 0) continue; #endif rc = visual->to_redraw.list[k].rect; - visual->ClearSurface(visual, &rc, 0); + visual->ClearSurface(visual, &rc, 0, 0); } #ifndef GPAC_DISABLE_3D if (!count && hyb_force_redraw) { - compositor_2d_hybgl_clear_surface_ex(tr_state->visual, NULL, 0, GF_FALSE); + compositor_2d_hybgl_clear_surface(tr_state->visual, NULL, 0, GF_FALSE); } #endif } diff --git a/src/compositor/visual_manager_2d.h b/src/compositor/visual_manager_2d.h index f8c5438..77a3c72 100644 --- a/src/compositor/visual_manager_2d.h +++ b/src/compositor/visual_manager_2d.h @@ -94,7 +94,7 @@ Bool visual_2d_node_cull(GF_TraverseState *tr_state, GF_Rect *bounds); void visual_2d_pick_node(GF_VisualManager *visual, GF_TraverseState *tr_state, GF_Event *ev, GF_ChildNodeItem *children); -void visual_2d_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor); +void visual_2d_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool is_offscreen); /*gets a drawable context on this visual*/ DrawableContext *visual_2d_get_drawable_context(GF_VisualManager *visual); diff --git a/src/compositor/visual_manager_2d_draw.c b/src/compositor/visual_manager_2d_draw.c index 21dc81d..024614b 100644 --- a/src/compositor/visual_manager_2d_draw.c +++ b/src/compositor/visual_manager_2d_draw.c @@ -52,7 +52,7 @@ void visual_2d_release_raster(GF_VisualManager *visual) } -void visual_2d_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor) +void visual_2d_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor, Bool is_offscreen) { #ifdef SKIP_DRAW return; diff --git a/src/isomedia/isom_write.c b/src/isomedia/isom_write.c index dd72ec8..5f20f22 100644 --- a/src/isomedia/isom_write.c +++ b/src/isomedia/isom_write.c @@ -895,6 +895,7 @@ GF_Err gf_isom_set_last_sample_duration(GF_ISOFile *movie, u32 trackNumber, u32 } //update a sample data in the media. Note that the sample MUST exists +GF_EXPORT GF_Err gf_isom_update_sample(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber, GF_ISOSample *sample, Bool data_only) { GF_Err e; @@ -929,6 +930,7 @@ GF_Err gf_isom_update_sample(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumbe //update a sample data in the media. Note that the sample MUST exists, //that sample->data MUST be NULL and sample->dataLength must be NON NULL; +GF_EXPORT GF_Err gf_isom_update_sample_reference(GF_ISOFile *movie, u32 trackNumber, u32 sampleNumber, GF_ISOSample *sample, u64 data_offset) { GF_Err e; diff --git a/src/media_tools/dash_client.c b/src/media_tools/dash_client.c index 9e008b0..d1a0478 100644 --- a/src/media_tools/dash_client.c +++ b/src/media_tools/dash_client.c @@ -2770,11 +2770,12 @@ GF_Err gf_dash_setup_groups(GF_DashClient *dash) if (dash->max_width && dash->max_height) { if ((rep->width>dash->max_width) || (rep->height>dash->max_height)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Representation size %dx%d exceeds max display size allowed %dx%d - ignoring\n", rep->width, rep->height, dash->max_width, dash->max_height)); rep->playback.disabled = 1; continue; } } - if (rep->codecs && dash->max_bit_per_pixel) { + if (rep->codecs && (dash->max_bit_per_pixel > 8) ) { char *vid_type = strstr(rep->codecs, "hvc"); if (!vid_type) vid_type = strstr(rep->codecs, "hev"); if (!vid_type) vid_type = strstr(rep->codecs, "avc"); @@ -2787,6 +2788,7 @@ GF_Err gf_dash_setup_groups(GF_DashClient *dash) //Main 10 !! if (!strncmp(pidc, "2.", 2)) { rep->playback.disabled = 1; + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Representation bit depth higher than max display bit depth - ignoring\n")); continue; } } @@ -2800,6 +2802,7 @@ GF_Err gf_dash_setup_groups(GF_DashClient *dash) //Main 10 if (prof==0x6E) { rep->playback.disabled = 1; + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] Representation bit depth higher than max display bit depth - ignoring\n")); continue; } } diff --git a/src/media_tools/dash_segmenter.c b/src/media_tools/dash_segmenter.c index 3ef541f..3fa3631 100644 --- a/src/media_tools/dash_segmenter.c +++ b/src/media_tools/dash_segmenter.c @@ -101,6 +101,14 @@ struct _dash_segment_input char periodID[100]; char xlink[100]; char role[100]; + u32 nb_rep_descs; + char **rep_descs; + u32 nb_as_descs; + char **as_descs; + u32 nb_as_c_descs; + char **as_c_descs; + u32 nb_p_descs; + char **p_descs; u32 bandwidth; u32 dependency_bandwidth; char dependencyID[100]; @@ -479,26 +487,27 @@ typedef struct { u32 nb_segment; u64 segment_duration; -} GF_DASHSementDuration; +} GF_DASHSegmentDuration; -static void store_segment_duration(GF_List *segment_duration, u64 SegmentDuration) +static void store_segment_duration(GF_List **segment_duration, u64 SegmentDuration) { u32 k; - GF_DASHSementDuration *entry; + GF_DASHSegmentDuration *entry; - for (k = 0; k < gf_list_count(segment_duration); k++) { - entry = (GF_DASHSementDuration *)gf_list_get(segment_duration, k); + if (! *segment_duration) *segment_duration = gf_list_new(); + + for (k = 0; k < gf_list_count(*segment_duration); k++) { + entry = (GF_DASHSegmentDuration *)gf_list_get(*segment_duration, k); if (SegmentDuration == entry->segment_duration) { entry->nb_segment++; return; } } - GF_SAFEALLOC(entry, GF_DASHSementDuration); + GF_SAFEALLOC(entry, GF_DASHSegmentDuration); entry->segment_duration = SegmentDuration; entry->nb_segment = 1; - if (!segment_duration) segment_duration = gf_list_new(); - gf_list_add(segment_duration, entry); + gf_list_add(*segment_duration, entry); } @@ -1352,7 +1361,7 @@ restart_fragmentation_pass: if (next_sap_time) { u32 scaler; /*this is the fragment duration from last sample added to next SAP*/ - frag_dur += (u32) (next_sap_time - tf->next_sample_dts - next_dur) * dash_cfg->dash_scale / tf->TimeScale; + frag_dur += (s64) (next_sap_time - tf->next_sample_dts - next_dur) * dash_cfg->dash_scale / tf->TimeScale; /*if media segment about to be produced is longer than max segment length, force segment split*/ if (SegmentDuration + frag_dur > MaxSegmentDuration) { split_at_rap = GF_TRUE; @@ -1440,7 +1449,7 @@ restart_fragmentation_pass: if (force_switch_segment || ((SegmentDuration >= MaxSegmentDuration) && (!split_seg_at_rap || next_sample_rap))) { - store_segment_duration(segment_duration, SegmentDuration); + store_segment_duration(&segment_duration, SegmentDuration); if (mpd_timeline_bs) { if (previous_segment_duration == SegmentDuration) { @@ -1483,7 +1492,6 @@ restart_fragmentation_pass: if (!simulation_pass) { u64 idx_start_range, idx_end_range; - gf_isom_close_segment(output, dash_cfg->subsegs_per_sidx, ref_track_id, ref_track_first_dts, tfref ? tfref->media_time_to_pres_time_shift : tf->media_time_to_pres_time_shift, ref_track_next_cts, dash_cfg->daisy_chain_sidx, flush_all_samples ? GF_TRUE : GF_FALSE, dash_cfg->segment_marker_4cc, &idx_start_range, &idx_end_range); //take care of scalable reps @@ -1552,7 +1560,7 @@ restart_fragmentation_pass: if (!switch_segment) { u64 idx_start_range, idx_end_range; - store_segment_duration(segment_duration, SegmentDuration); + store_segment_duration(&segment_duration, SegmentDuration); /*do not update on last segment, we're likely to have a different last GOP*/ #if 0 @@ -1623,10 +1631,11 @@ restart_fragmentation_pass: u32 most_frequent_duration = 0; for (k = 0; k < gf_list_count(segment_duration); k++) { - GF_DASHSementDuration *entry; - entry = (GF_DASHSementDuration *)gf_list_get(segment_duration, k); + GF_DASHSegmentDuration *entry; + entry = (GF_DASHSegmentDuration *)gf_list_get(segment_duration, k); if (entry->nb_segment > most_frequent_duration) { - max_segment_duration = (Double) ( entry->segment_duration / dash_cfg->dash_scale ); + max_segment_duration = (Double) entry->segment_duration; + max_segment_duration /= dash_cfg->dash_scale; most_frequent_duration = entry->nb_segment; } } @@ -1742,6 +1751,13 @@ restart_fragmentation_pass: fprintf(dash_cfg->mpd, " dependencyId=\"%s\"", dash_input->dependencyID); fprintf(dash_cfg->mpd, ">\n"); + /* writing Representation level descriptors */ + if (dash_input->nb_rep_descs) { + for (i=0; inb_rep_descs; i++) { + fprintf(dash_cfg->mpd, " %s\n", dash_input->rep_descs[i]); + } + } + if (nb_channels && !is_bs_switching) fprintf(dash_cfg->mpd, " \n", nb_channels); @@ -1914,7 +1930,7 @@ err_exit: if (mpd_timeline_bs) gf_bs_del(mpd_timeline_bs); if (segment_duration) { while (gf_list_count(segment_duration)) { - GF_DASHSementDuration *entry = (GF_DASHSementDuration *)gf_list_last(segment_duration); + GF_DASHSegmentDuration *entry = (GF_DASHSegmentDuration *)gf_list_last(segment_duration); gf_free(entry); gf_list_rem_last(segment_duration); } @@ -1988,6 +2004,7 @@ static GF_Err dasher_isom_classify_input(GF_DashSegInput *dash_inputs, u32 nb_da set_file = gf_isom_open(dash_inputs[input_idx].file_name, GF_ISOM_OPEN_READ, NULL); for (i=input_idx+1; impd, " bandwidth=\"%d\"", bandwidth); fprintf(dash_cfg->mpd, ">\n"); + /* writing Representation level descriptors */ + if (dash_input->nb_rep_descs) { + for (i=0; inb_rep_descs; i++) { + fprintf(dash_cfg->mpd, " %s\n", dash_input->rep_descs[i]); + } + } if (dash_cfg->single_file_mode==1) { gf_media_mpd_format_segment_name(GF_DASH_TEMPLATE_SEGMENT, 1, SegName, basename, dash_input->representationID, gf_url_get_resource_name(dash_cfg->seg_rad_name), "ts", 0, bandwidth, segment_index, dash_cfg->use_segment_timeline); @@ -3722,10 +3757,12 @@ static GF_Err write_mpd_header(FILE *mpd, const char *mpd_name, GF_Config *dash_ /*TODO what should we put for minBufferTime */ fprintf(mpd, "\n"); + + /* writing Period level descriptors */ + for (i=0; i< nb_dash_inputs; i++) { + if (dash_inputs[i].adaptation_set && (dash_inputs[i].period==period_num)) { + for (j = 0; j < dash_inputs[i].nb_p_descs; j++) { + fprintf(mpd, " %s\n", dash_inputs[i].p_descs[j]); + } + } + } + return GF_OK; } -static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool use_url_template, u32 single_file_mode, GF_DashSegInput *first_rep, Bool bitstream_switching_mode, u32 max_width, u32 max_height, char *szMaxFPS, char *szLang, const char *szInitSegment) +static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool use_url_template, u32 single_file_mode, + GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 period_num, u32 adaptation_set_num, u32 first_rep_in_set, + Bool bitstream_switching_mode, u32 max_width, u32 max_height, char *szMaxFPS, char *szLang, const char *szInitSegment) { + u32 i, j; + GF_DashSegInput *first_rep = &dash_inputs[first_rep_in_set]; fprintf(mpd, " \n"); + /* writing AdaptationSet level descriptors specified only on one input (non discriminating during classification)*/ + for (i=0; i< nb_dash_inputs; i++) { + if (dash_inputs[i].adaptation_set == adaptation_set_num && dash_inputs[i].period == period_num) { + for (j = 0; j < dash_inputs[i].nb_as_c_descs; j++) { + fprintf(mpd, " %s\n", dash_inputs[i].as_c_descs[j]); + } + } + } + if (first_rep) { - u32 i; + + /* writing AdaptationSet level descriptors specified only all inputs for that AdaptationSet*/ + for (i=0; inb_as_descs; i++) { + fprintf(mpd, " %s\n", first_rep->as_descs[i]); + } if (bitstream_switching_mode) { for (i=0; inb_components; i++) { @@ -3882,7 +3949,6 @@ static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool us } } - if (first_rep->nb_components>1) { for (i=0; inb_components; i++) { struct _dash_component *comp = &first_rep->components[i]; @@ -3905,7 +3971,7 @@ static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool us break; } /*if lang not specified at adaptationSet level, put it here*/ - if ((!szLang || !szLang[0]) && comp->szLang[0]) { + if ((!szLang || !szLang[0]) && (comp->szLang[0] && strcmp(comp->szLang, "und"))) { fprintf(mpd, " lang=\"%s\"", comp->szLang); } fprintf(mpd, "/>\n"); @@ -4210,7 +4276,7 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input GF_Config *dash_ctx, u32 dash_dynamic, u32 mpd_update_time, u32 time_shift_depth, Double subduration, Double min_buffer, u32 ast_shift_sec, u32 dash_scale, Bool fragments_in_memory, u32 initial_moof_sn, u64 initial_tfdt, Bool no_fragments_defaults, Bool pssh_moof, Bool samplegroups_in_traf) { - u32 i, j, segment_mode; + u32 i, j, k, segment_mode; char *sep, szSegName[GF_MAX_PATH], szSolvedSegName[GF_MAX_PATH], szTempMPD[GF_MAX_PATH], szOpt[GF_MAX_PATH]; char szPeriodXML[GF_MAX_PATH]; const char *opt; @@ -4279,6 +4345,26 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input strcpy(dash_inputs[j].xlink, inputs[i].xlink); if (strlen(dash_inputs[j].xlink)) uses_xlink = GF_TRUE; strcpy(dash_inputs[j].role, inputs[i].role); + dash_inputs[j].nb_rep_descs = inputs[i].nb_rep_descs; + dash_inputs[j].rep_descs = (char **)gf_malloc(dash_inputs[j].nb_rep_descs*sizeof(char *)); + for (k = 0; k < dash_inputs[j].nb_rep_descs; k++) { + dash_inputs[j].rep_descs[k] = inputs[i].rep_descs[k]; + } + dash_inputs[j].nb_as_descs = inputs[i].nb_as_descs; + dash_inputs[j].as_descs = (char **)gf_malloc(dash_inputs[j].nb_as_descs*sizeof(char *)); + for (k = 0; k < dash_inputs[j].nb_as_descs; k++) { + dash_inputs[j].as_descs[k] = inputs[i].as_descs[k]; + } + dash_inputs[j].nb_as_c_descs = inputs[i].nb_as_c_descs; + dash_inputs[j].as_c_descs = (char **)gf_malloc(dash_inputs[j].nb_as_c_descs*sizeof(char *)); + for (k = 0; k < dash_inputs[j].nb_as_c_descs; k++) { + dash_inputs[j].as_c_descs[k] = inputs[i].as_c_descs[k]; + } + dash_inputs[j].nb_p_descs = inputs[i].nb_p_descs; + dash_inputs[j].p_descs = (char **)gf_malloc(dash_inputs[j].nb_p_descs*sizeof(char *)); + for (k = 0; k < dash_inputs[j].nb_p_descs; k++) { + dash_inputs[j].p_descs[k] = inputs[i].p_descs[k]; + } dash_inputs[j].bandwidth = inputs[i].bandwidth; if (strlen(inputs[i].role) && strcmp(inputs[i].role, "main")) @@ -4631,7 +4717,7 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input const char *id=NULL; const char *xlink = NULL; - /*for each identified adaptationSets, write MPD and perform segmentation of input files*/ + /* Find period information for this period */ for (i=0; i< nb_dash_inputs; i++) { if (dash_inputs[i].adaptation_set && (dash_inputs[i].period==cur_period+1)) { period_duration = dash_inputs[i].period_duration; @@ -4652,7 +4738,7 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input period_mpd = gf_f64_open(szPeriodXML, "wb"); dash_opts.mpd = period_mpd; - e = write_period_header(period_mpd, id, 0.0, period_duration, dash_dynamic, NULL); + e = write_period_header(period_mpd, id, 0.0, period_duration, dash_dynamic, NULL, dash_inputs, nb_dash_inputs, cur_period+1); if (e) goto exit; @@ -4760,7 +4846,7 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input sprintf(szFPS, "%d", fps_num); } - e = write_adaptation_header(period_mpd, dash_profile, use_url_template, segment_mode, &dash_inputs[first_rep_in_set], use_bs_switching, max_width, max_height, szFPS, szLang, szInit); + e = write_adaptation_header(period_mpd, dash_profile, use_url_template, segment_mode, dash_inputs, nb_dash_inputs, cur_period+1, cur_adaptation_set+1, first_rep_in_set, use_bs_switching, max_width, max_height, szFPS, szLang, szInit); if (e) goto exit; is_first_rep = 1; @@ -4834,7 +4920,7 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input fclose(period_mpd); if (xlink) { - write_period_header(mpd, id, 0.0, period_duration, dash_dynamic, xlink); + write_period_header(mpd, id, 0.0, period_duration, dash_dynamic, xlink, dash_inputs, nb_dash_inputs, cur_period+1); } else { dash_insert_period_xml(mpd, szPeriodXML); } @@ -4855,7 +4941,7 @@ GF_Err gf_dasher_segment_files(const char *mpdfile, GF_DashSegmenterInput *input sprintf(szOpt, "%g", active_period_start); gf_cfg_set_key(dash_ctx, "DASH", "LastActivePeriodStart", szOpt); - purge_dash_context(dash_ctx); + if (dash_ctx) purge_dash_context(dash_ctx); } } fprintf(mpd, ""); @@ -4871,6 +4957,13 @@ exit: } } } + /* TODO free descriptors */ + for (i=0; i < nb_dash_inputs; i++) { + if (dash_inputs[i].as_descs) gf_free(dash_inputs[i].as_descs); + if (dash_inputs[i].as_c_descs) gf_free(dash_inputs[i].as_c_descs); + if (dash_inputs[i].p_descs) gf_free(dash_inputs[i].p_descs); + if (dash_inputs[i].rep_descs) gf_free(dash_inputs[i].rep_descs); + } gf_free(dash_inputs); return e; } diff --git a/src/media_tools/isom_tools.c b/src/media_tools/isom_tools.c index e40a69b..56c4f29 100644 --- a/src/media_tools/isom_tools.c +++ b/src/media_tools/isom_tools.c @@ -880,6 +880,19 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track) return esd; } + + if ( (subtype == GF_4CC('j','p','e','g')) || (subtype == GF_4CC('p','n','g',' ')) ) { + esd = gf_odf_desc_esd_new(0); + esd->slConfig->timestampResolution = gf_isom_get_media_timescale(mp4, track); + esd->ESID = gf_isom_get_track_id(mp4, track); + esd->OCRESID = esd->ESID; + esd->decoderConfig->streamType = GF_STREAM_VISUAL; + esd->decoderConfig->objectTypeIndication = (subtype == GF_4CC('j','p','e','g')) ? GPAC_OTI_IMAGE_JPEG : GPAC_OTI_IMAGE_PNG; + gf_odf_desc_del((GF_Descriptor*)esd->decoderConfig->decoderSpecificInfo); + esd->decoderConfig->decoderSpecificInfo = NULL; + return esd; + } + if (subtype == GF_ISOM_SUBTYPE_3GP_DIMS) { GF_DIMSDescription dims; esd = gf_odf_desc_esd_new(0); diff --git a/src/media_tools/media_import.c b/src/media_tools/media_import.c index beda643..0181bd2 100644 --- a/src/media_tools/media_import.c +++ b/src/media_tools/media_import.c @@ -176,12 +176,15 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import, Bool mult_desc_all GF_BitStream *bs; GF_Err e; Bool destroy_esd; - u32 size, track, di, w, h, dsi_len, mtype; + u32 size, track, di, w, h, dsi_len, mtype, id; GF_ISOSample *samp; u8 OTI; char *dsi, *data; FILE *src; + Bool import_mpeg4 = 0; + if (import->flags & GF_IMPORT_FORCE_MPEG4) import_mpeg4 = 1; + else if (import->esd) import_mpeg4 = 1; src = gf_f64_open(import->in_name, "rb"); if (!src) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); @@ -195,7 +198,8 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import, Bool mult_desc_all /*get image size*/ bs = gf_bs_new(data, size, GF_BITSTREAM_READ); - gf_img_parse(bs, &OTI, &mtype, &w, &h, &dsi, &dsi_len); + dsi = NULL; + gf_img_parse(bs, &OTI, &mtype, &w, &h, import_mpeg4 ? &dsi : NULL, import_mpeg4 ? &dsi_len : NULL); gf_bs_del(bs); if (!OTI) { @@ -225,43 +229,76 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import, Bool mult_desc_all e = GF_OK; destroy_esd = 0; - if (!import->esd) { - import->esd = gf_odf_desc_esd_new(2); - destroy_esd = 1; - } - /*update stream type/oti*/ - if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); - if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); - import->esd->decoderConfig->streamType = GF_STREAM_VISUAL; - import->esd->decoderConfig->objectTypeIndication = OTI; - import->esd->decoderConfig->bufferSizeDB = size; - import->esd->decoderConfig->avgBitrate = 8*size; - import->esd->decoderConfig->maxBitrate = 8*size; - import->esd->slConfig->timestampResolution = 1000; - if (dsi) { - if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (import->esd->decoderConfig->decoderSpecificInfo->data) gf_free(import->esd->decoderConfig->decoderSpecificInfo->data); - import->esd->decoderConfig->decoderSpecificInfo->data = dsi; - import->esd->decoderConfig->decoderSpecificInfo->dataLength = dsi_len; + id = 0; + if (import_mpeg4) { + + if (!import->esd) { + import->esd = gf_odf_desc_esd_new(2); + destroy_esd = 1; + } + /*update stream type/oti*/ + if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); + if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); + import->esd->decoderConfig->streamType = GF_STREAM_VISUAL; + import->esd->decoderConfig->objectTypeIndication = OTI; + import->esd->decoderConfig->bufferSizeDB = size; + import->esd->decoderConfig->avgBitrate = 8*size; + import->esd->decoderConfig->maxBitrate = 8*size; + import->esd->slConfig->timestampResolution = 1000; + + if (dsi) { + if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + if (import->esd->decoderConfig->decoderSpecificInfo->data) gf_free(import->esd->decoderConfig->decoderSpecificInfo->data); + import->esd->decoderConfig->decoderSpecificInfo->data = dsi; + import->esd->decoderConfig->decoderSpecificInfo->dataLength = dsi_len; + } + id = import->esd->ESID; } track = 0; if (mult_desc_allowed) - track = gf_isom_get_track_by_id(import->dest, import->esd->ESID); + track = gf_isom_get_track_by_id(import->dest, id); if (!track) - track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_VISUAL, 1000); + track = gf_isom_new_track(import->dest, id, GF_ISOM_MEDIA_VISUAL, 1000); if (!track) { e = gf_isom_last_error(import->dest); goto exit; } gf_isom_set_track_enabled(import->dest, track, 1); - if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); - import->final_trackID = import->esd->ESID; - e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); - if (e) goto exit; + if (import_mpeg4) { + if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); + import->final_trackID = import->esd->ESID; + + e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); + if (e) goto exit; + } else { + GF_GenericSampleDescription udesc; + memset(&udesc, 0, sizeof(GF_GenericSampleDescription)); + switch (OTI) { + case GPAC_OTI_IMAGE_JPEG: + udesc.codec_tag = GF_4CC('j', 'p', 'e', 'g'); + break; + case GPAC_OTI_IMAGE_PNG: + udesc.codec_tag = GF_4CC('p', 'n', 'g', ' '); + break; + case GPAC_OTI_IMAGE_JPEG_2000: + udesc.codec_tag = GF_4CC('j', 'p', '2', 'k'); + break; + } + udesc.width = w; + udesc.height = h; + udesc.v_res = 72; + udesc.h_res = 72; + udesc.depth = 24; + memcpy(udesc.compressor_name, "\4JPEG", 5); + + gf_isom_new_generic_sample_description(import->dest, track, NULL, NULL, &udesc, &di); + import->final_trackID = gf_isom_get_track_id(import->dest, track); + } + gf_isom_set_visual_info(import->dest, track, di, w, h); samp = gf_isom_sample_new(); samp->IsRAP = 1; @@ -287,6 +324,9 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import, Bool mult_desc_all gf_set_progress("Importing Image", 1, 1); gf_isom_sample_del(&samp); + if (import->duration) { + gf_isom_set_last_sample_duration(import->dest, track, import->duration); + } exit: gf_free(data); @@ -7904,6 +7944,9 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) break; } } + +extern void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes); + /* Warning: we start importing only after finding the PMT */ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) { @@ -7912,7 +7955,7 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) char data[188]; GF_TSImport tsimp; u64 fsize, done; - u32 size; + u32 size, i; Bool do_import = 1; FILE *mts; char progress[1000]; @@ -7965,6 +8008,16 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) fclose(mts); return e; } + + for (i=0; iess[i]) { + if (ts->ess[i]->flags & GF_M2TS_ES_IS_PES) { + gf_m2ts_flush_pes(ts, (GF_M2TS_PES *) ts->ess[i]); + ts->on_event(ts, GF_M2TS_EVT_EOS, (GF_M2TS_PES *) ts->ess[i]); + } + } + } + import->esd = NULL; if (do_import) gf_set_progress(progress, (u32) (fsize/1024), (u32) (fsize/1024)); @@ -8324,7 +8377,7 @@ GF_Err gf_import_ac3(GF_MediaImporter *import) if (!in) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); bs = gf_bs_from_file(in, GF_BITSTREAM_READ); - if (!gf_ac3_parser_bs(bs, &hdr, 1)) { + if (!gf_ac3_parser_bs(bs, &hdr, GF_TRUE)) { gf_bs_del(bs); fclose(in); return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Audio isn't AC3 audio"); diff --git a/src/media_tools/mpegts.c b/src/media_tools/mpegts.c index 4b0b309..15002de 100644 --- a/src/media_tools/mpegts.c +++ b/src/media_tools/mpegts.c @@ -147,7 +147,7 @@ static void gf_m2ts_estimate_duration(GF_M2TS_Demuxer *ts, u64 PCR, u16 pcr_pid) ts->pcr_pid = pcr_pid; ts->nb_pck_at_pcr = ts->nb_pck; - GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] Estimated duration based on instant bitrate: %g\n", ts->duration)); + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] Estimated duration based on instant bitrate: %g sec\n", ts->duration)); if (ts->on_event && changed) { GF_M2TS_PES_PCK pck; @@ -1409,36 +1409,40 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter } if (has_syntax_indicator) { - /*remove crc32*/ - sec->length -= 4; - if (gf_m2ts_crc32_check((char *)data, sec->length)) { - s32 cur_sec_num; - t->version_number = (data[5] >> 1) & 0x1f; - if (t->last_section_number && t->section_number && (t->version_number != t->last_version_number)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] table transmission interrupted: previous table (v=%d) %d/%d sections - new table (v=%d) %d/%d sections\n", t->last_version_number, t->section_number, t->last_section_number, t->version_number, data[6] + 1, data[7] + 1) ); - gf_m2ts_reset_sections(t->sections); - t->section_number = 0; - } + if (sec->length < 4) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted section length %d less than CRC \n", sec->length)); + } else { + /*remove crc32*/ + sec->length -= 4; + if (gf_m2ts_crc32_check((char *)data, sec->length)) { + s32 cur_sec_num; + t->version_number = (data[5] >> 1) & 0x1f; + if (t->last_section_number && t->section_number && (t->version_number != t->last_version_number)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] table transmission interrupted: previous table (v=%d) %d/%d sections - new table (v=%d) %d/%d sections\n", t->last_version_number, t->section_number, t->last_section_number, t->version_number, data[6] + 1, data[7] + 1) ); + gf_m2ts_reset_sections(t->sections); + t->section_number = 0; + } - t->current_next_indicator = (data[5] & 0x1) ? 1 : 0; - /*add one to section numbers to detect if we missed or not the first section in the table*/ - cur_sec_num = data[6] + 1; - t->last_section_number = data[7] + 1; - section_start = 8; - /*we missed something*/ - if (!sec->process_individual && t->section_number + 1 != cur_sec_num) { - /* TODO - Check how to handle sections when the first complete section does - not have its sec num 0 */ - section_valid = 0; - if (t->is_init) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted table (lost section %d)\n", cur_sec_num ? cur_sec_num-1 : 31) ); + t->current_next_indicator = (data[5] & 0x1) ? 1 : 0; + /*add one to section numbers to detect if we missed or not the first section in the table*/ + cur_sec_num = data[6] + 1; + t->last_section_number = data[7] + 1; + section_start = 8; + /*we missed something*/ + if (!sec->process_individual && t->section_number + 1 != cur_sec_num) { + /* TODO - Check how to handle sections when the first complete section does + not have its sec num 0 */ + section_valid = 0; + if (t->is_init) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted table (lost section %d)\n", cur_sec_num ? cur_sec_num-1 : 31) ); + } + } else { + section_valid = 1; + t->section_number = cur_sec_num; } } else { - section_valid = 1; - t->section_number = cur_sec_num; - } - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted section (CRC32 failed)\n")); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted section (CRC32 failed)\n")); + } } } else { section_valid = 1; @@ -2291,7 +2295,7 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF data += len+2; pos += len+2; if (desc_len < len+2) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PMT es descriptor size for PID %d\n", pes->pid ) ); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PMT es descriptor size for PID %d\n", es->pid ) ); break; } desc_len-=len+2; @@ -2565,7 +2569,7 @@ static void gf_m2ts_flush_temi(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes) ts->on_event(ts, GF_M2TS_EVT_TEMI_TIMECODE, &temi_tc); } -static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes) +void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes) { GF_M2TS_PESHeader pesh; diff --git a/src/scenegraph/base_scenegraph.c b/src/scenegraph/base_scenegraph.c index 0b5d84b..10fc838 100644 --- a/src/scenegraph/base_scenegraph.c +++ b/src/scenegraph/base_scenegraph.c @@ -1355,6 +1355,34 @@ GF_Err gf_node_list_insert_child(GF_ChildNodeItem **list, GF_Node *n, u32 pos) return GF_OK; } +GF_EXPORT +GF_Err gf_node_list_append_child(GF_ChildNodeItem **list, GF_ChildNodeItem **last_child, GF_Node *n) +{ + GF_ChildNodeItem *child, *cur; + + child = *list; + + cur = (GF_ChildNodeItem*) gf_malloc(sizeof(GF_ChildNodeItem)); + if (!cur) return GF_OUT_OF_MEM; + cur->node = n; + cur->next = NULL; + + if (!child) { + *list = cur; + *last_child = cur; + } else { + if (! *last_child) { + while (child->next) { + child = child->next; + } + *last_child = child; + } + (*last_child)->next = cur; + *last_child = cur; + } + return GF_OK; +} + GF_EXPORT GF_Node *gf_node_list_get_child(GF_ChildNodeItem *list, s32 pos) { diff --git a/src/scenegraph/mpeg4_animators.c b/src/scenegraph/mpeg4_animators.c index 412dab0..525630c 100644 --- a/src/scenegraph/mpeg4_animators.c +++ b/src/scenegraph/mpeg4_animators.c @@ -460,7 +460,7 @@ static void PA_SetFraction(GF_Node *node, GF_Route *route) pa->value_changed.x += pa->offset.x; pa->value_changed.y += pa->offset.y; pa->value_changed.z += pa->offset.z; - gf_node_event_out_str(node, "value_changed"); + gf_node_event_out(node, 12/*"value_changed"*/); } void PA_Modified(GF_Node *node, GF_FieldInfo *field) @@ -623,7 +623,7 @@ static void PA2D_SetFraction(GF_Node *node, GF_Route *route) pa->value_changed.x += pa->offset.x; pa->value_changed.y += pa->offset.y; - gf_node_event_out_str(node, "value_changed"); + gf_node_event_out(node, 12/*"value_changed"*/); } void PA2D_Modified(GF_Node *node, GF_FieldInfo *field) @@ -780,7 +780,7 @@ void SA_SetFraction(GF_Node *node, GF_Route *route) } sa->value_changed += sa->offset; - gf_node_event_out_str(node, "value_changed"); + gf_node_event_out(node, 10/*"value_changed"*/); } void SA_Modified(GF_Node *node, GF_FieldInfo *field) diff --git a/src/scenegraph/svg_attributes.c b/src/scenegraph/svg_attributes.c index 7fc914c..67ac417 100644 --- a/src/scenegraph/svg_attributes.c +++ b/src/scenegraph/svg_attributes.c @@ -165,8 +165,37 @@ static const struct dom_event_def { { GF_EVENT_HTML_MSE_REMOVE_SOURCE_BUFFER, "removesourcebuffer", GF_DOM_EVENT_MEDIASOURCE }, /*GPAC internals*/ - { GF_EVENT_SCENE_ATTACHED, "gpac_scene_attached", GF_DOM_EVENT_DOM }, - { GF_EVENT_VP_RESIZE, "gpac_vp_changed", GF_DOM_EVENT_DOM }, + { GF_EVENT_SCENE_ATTACHED, "gpac_scene_attached", GF_DOM_EVENT_GPAC}, + { GF_EVENT_VP_RESIZE, "gpac_vp_changed", GF_DOM_EVENT_GPAC}, + { GF_EVENT_DBLCLICK, "gpac_dbl_click", GF_DOM_EVENT_GPAC}, + { GF_EVENT_SIZE, "gpac_size_changed", GF_DOM_EVENT_GPAC}, + { GF_EVENT_SCENE_SIZE, "gpac_scene_size", GF_DOM_EVENT_GPAC}, + { GF_EVENT_SHOWHIDE, "gpac_show_hide", GF_DOM_EVENT_GPAC}, + { GF_EVENT_SET_CURSOR, "gpac_set_cursor", GF_DOM_EVENT_GPAC}, + { GF_EVENT_SET_CAPTION, "gpac_set_caption", GF_DOM_EVENT_GPAC}, + { GF_EVENT_MOVE, "gpac_move", GF_DOM_EVENT_GPAC}, + { GF_EVENT_REFRESH, "gpac_move", GF_DOM_EVENT_GPAC}, + { GF_EVENT_QUIT, "gpac_quit", GF_DOM_EVENT_GPAC}, + { GF_EVENT_PASTE_TEXT, "gpac_paste", GF_DOM_EVENT_GPAC}, + { GF_EVENT_COPY_TEXT, "gpac_paste", GF_DOM_EVENT_GPAC}, + { GF_EVENT_CONNECT, "gpac_on_connect", GF_DOM_EVENT_GPAC}, + { GF_EVENT_DURATION, "gpac_on_duration", GF_DOM_EVENT_GPAC}, + { GF_EVENT_EOS, "gpac_eos", GF_DOM_EVENT_GPAC}, + { GF_EVENT_AUTHORIZATION, "gpac_authorization", GF_DOM_EVENT_GPAC}, + { GF_EVENT_NAVIGATE, "gpac_navigate", GF_DOM_EVENT_GPAC}, + { GF_EVENT_NAVIGATE_INFO, "gpac_navigate_info", GF_DOM_EVENT_GPAC}, + { GF_EVENT_MESSAGE, "gpac_on_message", GF_DOM_EVENT_GPAC}, + { GF_EVENT_PROGRESS, "gpac_on_progress", GF_DOM_EVENT_GPAC}, + { GF_EVENT_VIEWPOINTS, "gpac_viewpoints_changed", GF_DOM_EVENT_GPAC}, + { GF_EVENT_STREAMLIST, "gpac_streamlist_changed", GF_DOM_EVENT_GPAC}, + { GF_EVENT_METADATA, "gpac_metadata_changed", GF_DOM_EVENT_GPAC}, + { GF_EVENT_MIGRATE, "gpac_session_migrate", GF_DOM_EVENT_GPAC}, + { GF_EVENT_DISCONNECT, "gpac_request_disconnect", GF_DOM_EVENT_GPAC}, + { GF_EVENT_RESOLUTION, "gpac_resolution_changed", GF_DOM_EVENT_GPAC}, + { GF_EVENT_DROPFILE, "gpac_dropfile", GF_DOM_EVENT_GPAC}, + { GF_EVENT_TEXT_EDITING_START, "gpac_textedit_start", GF_DOM_EVENT_GPAC}, + { GF_EVENT_TEXT_EDITING_END, "gpac_textedit_end", GF_DOM_EVENT_GPAC}, + { GF_EVENT_ADDON_DETECTED, "gpac_addon_found", GF_DOM_EVENT_GPAC} }; GF_EXPORT @@ -183,6 +212,7 @@ GF_EventType gf_dom_event_type_by_name(const char *name) return GF_EVENT_UNKNOWN; } +GF_EXPORT const char *gf_dom_event_get_name(GF_EventType type) { u32 i, count; diff --git a/src/scenegraph/vrml_interpolators.c b/src/scenegraph/vrml_interpolators.c index a3ab53c..60f2947 100644 --- a/src/scenegraph/vrml_interpolators.c +++ b/src/scenegraph/vrml_interpolators.c @@ -511,14 +511,14 @@ static void BooleanFilter_setValue(GF_Node *n, GF_Route *route) X_BooleanFilter *bf = (X_BooleanFilter *)n; if (!bf->set_boolean) { bf->inputFalse = 1; - gf_node_event_out_str(n, "inputFalse"); + gf_node_event_out(n, 1/*"inputFalse"*/); } if (bf->set_boolean) { bf->inputTrue = 1; - gf_node_event_out_str(n, "inputTrue"); + gf_node_event_out(n, 3/*"inputTrue"*/); } bf->inputNegate = bf->set_boolean ? 0 : 1; - gf_node_event_out_str(n, "inputNegate"); + gf_node_event_out(n, 2/*"inputNegate"*/); } void InitBooleanFilter(GF_Node *n) @@ -599,7 +599,7 @@ static void BooleanToggle_setValue(GF_Node *n, GF_Route *route) X_BooleanToggle *bt = (X_BooleanToggle *)n; if (bt->set_boolean) { bt->toggle = !bt->toggle; - gf_node_event_out_str(n, "toggle"); + gf_node_event_out(n, 1/*"toggle"*/); } } void InitBooleanToggle(GF_Node *n) @@ -612,7 +612,7 @@ static void BooleanTrigger_setTime(GF_Node *n, GF_Route *route) { X_BooleanTrigger *bt = (X_BooleanTrigger *)n; bt->triggerTrue = 1; - gf_node_event_out_str(n, "triggerTrue"); + gf_node_event_out(n, 1/*"triggerTrue"*/); } void InitBooleanTrigger(GF_Node *n) { @@ -692,7 +692,7 @@ static void IntegerTrigger_setTrigger(GF_Node *n, GF_Route *route) X_IntegerTrigger *it = (X_IntegerTrigger *)n; if (it->set_boolean) { it->triggerValue = it->integerKey; - gf_node_event_out_str(n, "triggerValue"); + gf_node_event_out(n, 2/*"triggerValue"*/); } } void InitIntegerTrigger(GF_Node *n) @@ -705,7 +705,7 @@ static void TimeTrigger_setTrigger(GF_Node *n, GF_Route *route) { X_TimeTrigger *tt = (X_TimeTrigger *)n; tt->triggerTime = gf_node_get_scene_time(n); - gf_node_event_out_str(n, "triggerTime"); + gf_node_event_out(n, 1/*"triggerTime"*/); } void InitTimeTrigger(GF_Node *n) { diff --git a/src/scenegraph/vrml_proto.c b/src/scenegraph/vrml_proto.c index 197030e..9753601 100644 --- a/src/scenegraph/vrml_proto.c +++ b/src/scenegraph/vrml_proto.c @@ -585,7 +585,7 @@ void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node) } } owner->parent_graph->NodeCallback(owner->parent_graph->userpriv, GF_SG_CALLBACK_INIT, (GF_Node *) proto_node, NULL); - proto_node->flags |= GF_SG_PROTO_LOADED; + proto_node->flags |= GF_SG_PROTO_LOADED | GF_SG_PROTO_HARDCODED; return; } /*not loaded yet*/ diff --git a/src/scenegraph/vrml_route.c b/src/scenegraph/vrml_route.c index 6beb960..98938e1 100644 --- a/src/scenegraph/vrml_route.c +++ b/src/scenegraph/vrml_route.c @@ -285,7 +285,7 @@ Bool gf_sg_route_activate(GF_Route *r) } } #ifndef GPAC_DISABLE_LOG - if (gf_log_tool_level_on(GF_LOG_DEBUG, GF_LOG_INTERACT)) { + if (gf_log_tool_level_on(GF_LOG_INTERACT, GF_LOG_DEBUG)) { if (r->IS_route) { GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Event] executing %s.%s IS %s.%s", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name)); } else { @@ -349,6 +349,12 @@ Bool gf_sg_route_activate(GF_Route *r) break; } +#ifndef GPAC_DISABLE_LOG + if (gf_log_tool_level_on(GF_LOG_INTERACT, GF_LOG_DEBUG)) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Route] field copy/casted\n")); + } +#endif + //if this is a supported eventIn call watcher if (r->ToField.on_event_in) { r->ToField.on_event_in(r->ToNode, r); @@ -379,6 +385,13 @@ Bool gf_sg_route_activate(GF_Route *r) else gf_node_event_out(r->ToNode, r->ToField.fieldIndex); } + +#ifndef GPAC_DISABLE_LOG + if (gf_log_tool_level_on(GF_LOG_INTERACT, GF_LOG_DEBUG)) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Route] done executing (res %d)\n", ret)); + } +#endif + return ret; } diff --git a/src/scenegraph/vrml_smjs.c b/src/scenegraph/vrml_smjs.c index d258a7d..4197871 100644 --- a/src/scenegraph/vrml_smjs.c +++ b/src/scenegraph/vrml_smjs.c @@ -114,10 +114,12 @@ JSObject *gf_sg_js_global_object(JSContext *cx, GF_JSClass *__class) on latest SM, GC will crash if called from a different thread than the thread creating the contex, no clue why for iOS don't force GC (better performances according to Ivica) + +NOTE - this is currently disabled, as performing the GC at each root with complex scenes (lots of objects) really decreases performances */ #if !defined(GPAC_IPHONE) # if (JS_VERSION<180) -# define FORCE_GC +//# define FORCE_GC # endif #endif @@ -440,7 +442,7 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No static void JSScript_NodeModified(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo *info, GF_Node *script); -Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain); +Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain, jsval *rval); void gf_sg_js_call_gc(JSContext *c) { @@ -453,13 +455,17 @@ void gf_sg_js_call_gc(JSContext *c) gf_sg_lock_javascript(c, 0); } -#ifdef FORCE_GC -void MyJSGC(JSContext *c) +void do_js_gc(JSContext *c, GF_Node *node) { - gf_sg_js_call_gc(c); +#ifdef FORCE_GC + node->sgprivate->scenegraph->trigger_gc = GF_TRUE; +#endif + if (node->sgprivate->scenegraph->trigger_gc) { + node->sgprivate->scenegraph->trigger_gc = GF_FALSE; + gf_sg_js_call_gc(c); + } } -#endif void SFColor_fromHSV(SFColor *col) @@ -686,17 +692,15 @@ static JSBool SMJS_FUNCTION(loadScript) char *url; GF_Node *node = JS_GetContextPrivate(c); SMJS_ARGS + jsval aval; if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; if ((argc>1) && JSVAL_IS_BOOLEAN(argv[1])) no_complain = (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ? 1 : 0; url = SMJS_CHARS(c, argv[0]); if (url) { - if ( JSScriptFromFile(node, url, no_complain) == 1) { - SMJS_SET_RVAL( BOOLEAN_TO_JSVAL(JS_TRUE) ); - } else { - SMJS_SET_RVAL( BOOLEAN_TO_JSVAL(JS_FALSE) ); - } + JSScriptFromFile(node, url, no_complain, &aval); + SMJS_SET_RVAL(aval); } SMJS_FREE(c, url); return JS_TRUE; @@ -834,9 +838,7 @@ static void on_route_to_object(GF_Node *node, GF_Route *_r) gf_sg_lock_javascript(priv->js_ctx, 0); -#ifdef FORCE_GC - MyJSGC(priv->js_ctx); -#endif + do_js_gc(priv->js_ctx, node); } static JSBool SMJS_FUNCTION(addRoute) @@ -1225,9 +1227,16 @@ void Script_FieldChanged(JSContext *c, GF_Node *parent, GF_JSField *parent_owner } /*field has changed, set routes...*/ if (parent->sgprivate->tag == TAG_ProtoNode) { + GF_ProtoInstance *inst = (GF_ProtoInstance *)parent; gf_sg_proto_propagate_event(parent, field->fieldIndex, (GF_Node*)JS_GetScript(c)); /* Node exposedField can also be routed to another field */ gf_node_event_out_proto(parent, field->fieldIndex); + + //hardcoded protos be implemented in ways not inspecting the node_dirty propagation scheme (eg defining an SFNode in their interface, not linked with the graph). + //in this case handle the node as a regular one + if (inst->flags & GF_SG_PROTO_HARDCODED) { + gf_node_changed_internal(parent, field, 0); + } } else { gf_node_event_out(parent, field->fieldIndex); gf_node_changed_internal(parent, field, 0); @@ -1928,7 +1937,12 @@ if (!ptr) { } if (SMJS_ID_IS_INT(id)) { + if (! JSVAL_IS_NUMBER(*vp)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML JS] Value is not a number while assigning SFVec2f\n")); + return JS_FALSE; + } JS_ValueToNumber(c, *vp, &d); + switch (SMJS_ID_TO_INT(id)) { case 0: v = FLT2FIX( d); @@ -2123,6 +2137,11 @@ if (!ptr) { return JS_TRUE; } + if (! JSVAL_IS_NUMBER(*vp)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML JS] Value is not a number while assigning SFVec3f\n")); + return JS_FALSE; + } + if (SMJS_ID_IS_INT(id) && SMJS_ID_TO_INT(id) >= 0 && SMJS_ID_TO_INT(id) < 3 && JS_ValueToNumber(c, *vp, &d)) { switch (SMJS_ID_TO_INT(id)) { case 0: @@ -2380,6 +2399,10 @@ if (!ptr) { return JS_TRUE; } + if (! JSVAL_IS_NUMBER(*vp)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML JS] Value is not a number while assigning SFVec3f\n")); + return JS_FALSE; + } if (SMJS_ID_IS_INT(id) && SMJS_ID_TO_INT(id) >= 0 && SMJS_ID_TO_INT(id) < 4 && JS_ValueToNumber(c, *vp, &d)) { switch (SMJS_ID_TO_INT(id)) { case 0: @@ -2586,6 +2609,10 @@ if (!ptr) { return JS_TRUE; } + if (! JSVAL_IS_NUMBER(*vp)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML JS] Value is not a number while assigning SFVec3f\n")); + return JS_FALSE; + } if (SMJS_ID_IS_INT(id) && SMJS_ID_TO_INT(id) >= 0 && SMJS_ID_TO_INT(id) < 3 && JS_ValueToNumber(c, *vp, &d)) { switch (SMJS_ID_TO_INT(id)) { case 0: @@ -2651,13 +2678,15 @@ static JSBool SMJS_FUNCTION(color_getHSV) static void setup_js_array(JSContext *c, JSObject *obj, GF_JSField *ptr, uintN argc, jsval *argv) { - GF_ScriptPriv *priv = JS_GetScriptStack(c); +// GF_ScriptPriv *priv = JS_GetScriptStack(c); ptr->obj = obj; ptr->js_list = JS_NewArrayObject(c, (jsint) argc, argv); +/* gf_js_add_root(c, &ptr->js_list, GF_JSGC_OBJECT); ptr->is_rooted = 1; gf_list_add(priv->js_cache, obj); +*/ } #define MFARRAY_CONSTRUCTOR(__classp, _fieldType) \ @@ -2753,307 +2782,300 @@ return JS_TRUE; //this could be overloaded for each MF type... static SMJS_FUNC_PROP_SET(array_setElement) -u32 ind; -jsuint len; -jsdouble d; -GF_JSField *from; -JSBool ret; -GF_JSClass *the_sf_class = NULL; -JSString *str; -char *str_val; -void *sf_slot; -GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj); -ind = SMJS_ID_TO_INT(id); + u32 ind; + jsuint len; + jsdouble d; + GF_JSField *from; + JSBool ret; + GF_JSClass *the_sf_class = NULL; + JSString *str; + char *str_val; + void *sf_slot; + Bool is_append = 0; + GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj); + ind = SMJS_ID_TO_INT(id); -ret = JS_GetArrayLength(c, ptr->js_list, &len); -if (ret==JS_FALSE) return JS_FALSE; + ret = JS_GetArrayLength(c, ptr->js_list, &len); + if (ret==JS_FALSE) return JS_FALSE; -if (gf_sg_vrml_is_sf_field(ptr->field.fieldType)) return JS_FALSE; + if (gf_sg_vrml_is_sf_field(ptr->field.fieldType)) return JS_FALSE; -switch (ptr->field.fieldType) { -case GF_SG_VRML_MFVEC2F: - the_sf_class = &js_rt->SFVec2fClass; - break; -case GF_SG_VRML_MFVEC3F: - the_sf_class = &js_rt->SFVec3fClass; - break; -case GF_SG_VRML_MFCOLOR: - the_sf_class = &js_rt->SFColorClass; - break; -case GF_SG_VRML_MFROTATION: - the_sf_class = &js_rt->SFRotationClass; - break; -} -/*dynamic expend*/ -if (ind>=len) { - ret = JS_SetArrayLength(c, ptr->js_list, len+1); - if (ret==JS_FALSE) return JS_FALSE; - while (lenfield.fieldType) { - case GF_SG_VRML_MFBOOL: - a_val = BOOLEAN_TO_JSVAL(0); - break; - case GF_SG_VRML_MFINT32: - a_val = INT_TO_JSVAL(0); - break; - case GF_SG_VRML_MFFLOAT: - case GF_SG_VRML_MFTIME: - a_val = JS_MAKE_DOUBLE(c, 0); - break; - case GF_SG_VRML_MFSTRING: - case GF_SG_VRML_MFURL: - a_val = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") ); - break; - case GF_SG_VRML_MFVEC2F: - case GF_SG_VRML_MFVEC3F: - case GF_SG_VRML_MFCOLOR: - case GF_SG_VRML_MFROTATION: - a_val = OBJECT_TO_JSVAL( SMJS_CONSTRUCT_OBJECT(c, the_sf_class, obj) ); - break; - default: - a_val = INT_TO_JSVAL(0); - break; - } + switch (ptr->field.fieldType) { + case GF_SG_VRML_MFVEC2F: + the_sf_class = &js_rt->SFVec2fClass; + break; + case GF_SG_VRML_MFVEC3F: + the_sf_class = &js_rt->SFVec3fClass; + break; + case GF_SG_VRML_MFCOLOR: + the_sf_class = &js_rt->SFColorClass; + break; + case GF_SG_VRML_MFROTATION: + the_sf_class = &js_rt->SFRotationClass; + break; + } + /*dynamic expend*/ + if (ind>=len) { + is_append = 1; + ret = JS_SetArrayLength(c, ptr->js_list, len+1); + if (ret==JS_FALSE) return JS_FALSE; + while (lenfield.fieldType) { + case GF_SG_VRML_MFBOOL: + a_val = BOOLEAN_TO_JSVAL(0); + break; + case GF_SG_VRML_MFINT32: + a_val = INT_TO_JSVAL(0); + break; + case GF_SG_VRML_MFFLOAT: + case GF_SG_VRML_MFTIME: + a_val = JS_MAKE_DOUBLE(c, 0); + break; + case GF_SG_VRML_MFSTRING: + case GF_SG_VRML_MFURL: + a_val = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") ); + break; + case GF_SG_VRML_MFVEC2F: + case GF_SG_VRML_MFVEC3F: + case GF_SG_VRML_MFCOLOR: + case GF_SG_VRML_MFROTATION: + a_val = OBJECT_TO_JSVAL( SMJS_CONSTRUCT_OBJECT(c, the_sf_class, obj) ); + break; + default: + a_val = INT_TO_JSVAL(0); + break; + } - if (ptr->field.fieldType!=GF_SG_VRML_MFNODE) { - gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, len); - JS_SetElement(c, ptr->js_list, len, &a_val); + if (ptr->field.fieldType!=GF_SG_VRML_MFNODE) { + gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, len); + JS_SetElement(c, ptr->js_list, len, &a_val); + } + len++; } - len++; + if (ptr->field.far_ptr && (ptr->field.fieldType!=GF_SG_VRML_MFNODE)) + gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, ind); } - if (ptr->field.far_ptr && (ptr->field.fieldType!=GF_SG_VRML_MFNODE)) - gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, ind); -} -if (ptr->field.far_ptr && (ptr->field.fieldType!=GF_SG_VRML_MFNODE)) { - u32 items = ((GenMFField *)ptr->field.far_ptr)->count; - while (ind>=items) { - gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, ind); - items++; + if (ptr->field.far_ptr && (ptr->field.fieldType!=GF_SG_VRML_MFNODE)) { + u32 items = ((GenMFField *)ptr->field.far_ptr)->count; + while (ind>=items) { + gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, ind); + items++; + } } -} -/*assign object*/ -if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { - if (JSVAL_IS_VOID(*vp) || JSVAL_IS_NULL(*vp) || !GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), &js_rt->SFNodeClass, NULL) ) return JS_FALSE; -} else if (the_sf_class) { - if (JSVAL_IS_VOID(*vp)) return JS_FALSE; - if (!GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), the_sf_class, NULL) ) return JS_FALSE; -} else if (ptr->field.fieldType==GF_SG_VRML_MFBOOL) { - if (!JSVAL_IS_BOOLEAN(*vp)) return JS_FALSE; -} else if (ptr->field.fieldType==GF_SG_VRML_MFINT32) { - if (!JSVAL_IS_INT(*vp)) return JS_FALSE; -} else if (ptr->field.fieldType==GF_SG_VRML_MFFLOAT) { - if (!JSVAL_IS_NUMBER(*vp)) return JS_FALSE; -} else if (ptr->field.fieldType==GF_SG_VRML_MFTIME) { - if (!JSVAL_IS_NUMBER(*vp)) return JS_FALSE; -} else if (ptr->field.fieldType==GF_SG_VRML_MFSTRING) { - if (!JSVAL_IS_STRING(*vp)) return JS_FALSE; -} else if (ptr->field.fieldType==GF_SG_VRML_MFURL) { - if (!JSVAL_IS_STRING(*vp)) return JS_FALSE; -} - - -/*rewrite MFNode entry*/ -if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { - GF_Node *prev_n, *new_n; - - if (!ptr->owner) return JS_TRUE; + /*assign object*/ + if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { + JSObject *o; + if (JSVAL_IS_VOID(*vp)) return JS_FALSE; + if (JSVAL_IS_NULL(*vp) ) return JS_FALSE; + o = JSVAL_TO_OBJECT(*vp); + if (!GF_JS_InstanceOf(c, o, &js_rt->SFNodeClass, NULL) ) return JS_FALSE; + } else if (the_sf_class) { + if (JSVAL_IS_VOID(*vp)) return JS_FALSE; + if (!GF_JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), the_sf_class, NULL) ) return JS_FALSE; + } else if (ptr->field.fieldType==GF_SG_VRML_MFBOOL) { + if (!JSVAL_IS_BOOLEAN(*vp)) return JS_FALSE; + } else if (ptr->field.fieldType==GF_SG_VRML_MFINT32) { + if (!JSVAL_IS_INT(*vp)) return JS_FALSE; + } else if (ptr->field.fieldType==GF_SG_VRML_MFFLOAT) { + if (!JSVAL_IS_NUMBER(*vp)) return JS_FALSE; + } else if (ptr->field.fieldType==GF_SG_VRML_MFTIME) { + if (!JSVAL_IS_NUMBER(*vp)) return JS_FALSE; + } else if (ptr->field.fieldType==GF_SG_VRML_MFSTRING) { + if (!JSVAL_IS_STRING(*vp)) return JS_FALSE; + } else if (ptr->field.fieldType==GF_SG_VRML_MFURL) { + if (!JSVAL_IS_STRING(*vp)) return JS_FALSE; + } + + + /*rewrite MFNode entry*/ + if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { + GF_Node *prev_n, *new_n; - /*get new node*/ - from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); - new_n = *(GF_Node**)from->field.far_ptr; + if (!ptr->owner) return JS_TRUE; -#if 0 - anobj = node_get_binding(JS_GetScriptStack(c), from->node, 0); + /*get new node*/ + from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); + new_n = *(GF_Node**)from->field.far_ptr; + prev_n = NULL; - /*add it to the new object if needed*/ - ret = JS_SetElement(c, ptr->js_list, ind, vp); -#endif + if (!is_append) { + /*get and delete previous node if any, but unregister later*/ + prev_n = gf_node_list_del_child_idx( (GF_ChildNodeItem **)ptr->field.far_ptr, ind); + } - /*get and delete previous node if any, but unregister later*/ - prev_n = gf_node_list_del_child_idx( (GF_ChildNodeItem **)ptr->field.far_ptr, ind); + if (new_n) { + gf_node_list_insert_child( (GF_ChildNodeItem **)ptr->field.far_ptr , new_n, ind); + gf_node_register(new_n, ptr->owner); - if (new_n) { - gf_node_list_insert_child( (GF_ChildNodeItem **)ptr->field.far_ptr , new_n, ind); - gf_node_register(new_n, ptr->owner); + /*node created from script and inserted in the tree, root it*/ + if (!from->is_rooted) + node_get_binding(JS_GetScriptStack(c), new_n, 0); + } + /*unregister previous node*/ + if (prev_n) gf_node_unregister(prev_n, ptr->owner); - /*node created from script and inserted in the tree, root it*/ - if (!from->is_rooted) - node_get_binding(JS_GetScriptStack(c), new_n, 0); + Script_FieldChanged(c, NULL, ptr, NULL); + return JS_TRUE; } - /*unregister previous node*/ - if (prev_n) gf_node_unregister(prev_n, ptr->owner); - Script_FieldChanged(c, NULL, ptr, NULL); - return JS_TRUE; -} + ret = JS_SetElement(c, ptr->js_list, ind, vp); + if (ret==JS_FALSE) return JS_FALSE; -ret = JS_SetElement(c, ptr->js_list, ind, vp); -if (ret==JS_FALSE) return JS_FALSE; + if (!ptr->owner) return JS_TRUE; -if (!ptr->owner) return JS_TRUE; + /*rewrite MF slot*/ + switch (ptr->field.fieldType) { + case GF_SG_VRML_MFBOOL: + ((MFBool *)ptr->field.far_ptr)->vals[ind] = (Bool) JSVAL_TO_BOOLEAN(*vp); + break; + case GF_SG_VRML_MFINT32: + ((MFInt32 *)ptr->field.far_ptr)->vals[ind] = (s32) JSVAL_TO_INT(*vp); + break; + case GF_SG_VRML_MFFLOAT: + JS_ValueToNumber(c, *vp, &d); + ((MFFloat *)ptr->field.far_ptr)->vals[ind] = FLT2FIX(d); + break; + case GF_SG_VRML_MFTIME: + JS_ValueToNumber(c, *vp, &d); + ((MFTime *)ptr->field.far_ptr)->vals[ind] = d; + break; + case GF_SG_VRML_MFSTRING: + if (((MFString *)ptr->field.far_ptr)->vals[ind]) { + gf_free(((MFString *)ptr->field.far_ptr)->vals[ind]); + ((MFString *)ptr->field.far_ptr)->vals[ind] = NULL; + } + str = JSVAL_IS_STRING(*vp) ? JSVAL_TO_STRING(*vp) : JS_ValueToString(c, *vp); + str_val = SMJS_CHARS_FROM_STRING(c, str); + ((MFString *)ptr->field.far_ptr)->vals[ind] = gf_strdup(str_val); + SMJS_FREE(c, str_val); + break; -/*rewrite MF slot*/ -switch (ptr->field.fieldType) { -case GF_SG_VRML_MFBOOL: - ((MFBool *)ptr->field.far_ptr)->vals[ind] = (Bool) JSVAL_TO_BOOLEAN(*vp); - break; -case GF_SG_VRML_MFINT32: - ((MFInt32 *)ptr->field.far_ptr)->vals[ind] = (s32) JSVAL_TO_INT(*vp); - break; -case GF_SG_VRML_MFFLOAT: - JS_ValueToNumber(c, *vp, &d); - ((MFFloat *)ptr->field.far_ptr)->vals[ind] = FLT2FIX(d); - break; -case GF_SG_VRML_MFTIME: - JS_ValueToNumber(c, *vp, &d); - ((MFTime *)ptr->field.far_ptr)->vals[ind] = d; - break; -case GF_SG_VRML_MFSTRING: - if (((MFString *)ptr->field.far_ptr)->vals[ind]) { - gf_free(((MFString *)ptr->field.far_ptr)->vals[ind]); - ((MFString *)ptr->field.far_ptr)->vals[ind] = NULL; - } - str = JSVAL_IS_STRING(*vp) ? JSVAL_TO_STRING(*vp) : JS_ValueToString(c, *vp); - str_val = SMJS_CHARS_FROM_STRING(c, str); - ((MFString *)ptr->field.far_ptr)->vals[ind] = gf_strdup(str_val); - SMJS_FREE(c, str_val); - break; + case GF_SG_VRML_MFURL: + if (((MFURL *)ptr->field.far_ptr)->vals[ind].url) { + gf_free(((MFURL *)ptr->field.far_ptr)->vals[ind].url); + ((MFURL *)ptr->field.far_ptr)->vals[ind].url = NULL; + } + str = JSVAL_IS_STRING(*vp) ? JSVAL_TO_STRING(*vp) : JS_ValueToString(c, *vp); + str_val = SMJS_CHARS_FROM_STRING(c, str); + ((MFURL *)ptr->field.far_ptr)->vals[ind].url = gf_strdup(str_val); + ((MFURL *)ptr->field.far_ptr)->vals[ind].OD_ID = 0; + SMJS_FREE(c, str_val); + break; -case GF_SG_VRML_MFURL: - if (((MFURL *)ptr->field.far_ptr)->vals[ind].url) { - gf_free(((MFURL *)ptr->field.far_ptr)->vals[ind].url); - ((MFURL *)ptr->field.far_ptr)->vals[ind].url = NULL; + case GF_SG_VRML_MFVEC2F: + from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); + gf_sg_vrml_field_copy(& ((MFVec2f *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); + break; + case GF_SG_VRML_MFVEC3F: + from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); + gf_sg_vrml_field_copy(& ((MFVec3f *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); + break; + case GF_SG_VRML_MFROTATION: + from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); + gf_sg_vrml_field_copy(& ((MFRotation *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); + break; + case GF_SG_VRML_MFCOLOR: + from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); + gf_sg_vrml_field_copy(& ((MFColor *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); + break; } - str = JSVAL_IS_STRING(*vp) ? JSVAL_TO_STRING(*vp) : JS_ValueToString(c, *vp); - str_val = SMJS_CHARS_FROM_STRING(c, str); - ((MFURL *)ptr->field.far_ptr)->vals[ind].url = gf_strdup(str_val); - ((MFURL *)ptr->field.far_ptr)->vals[ind].OD_ID = 0; - SMJS_FREE(c, str_val); - break; - -case GF_SG_VRML_MFVEC2F: - from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); - gf_sg_vrml_field_copy(& ((MFVec2f *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); - break; -case GF_SG_VRML_MFVEC3F: - from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); - gf_sg_vrml_field_copy(& ((MFVec3f *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); - break; -case GF_SG_VRML_MFROTATION: - from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); - gf_sg_vrml_field_copy(& ((MFRotation *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); - break; -case GF_SG_VRML_MFCOLOR: - from = (GF_JSField *) SMJS_GET_PRIVATE(c, JSVAL_TO_OBJECT(*vp)); - gf_sg_vrml_field_copy(& ((MFColor *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); - break; -} -Script_FieldChanged(c, NULL, ptr, NULL); -return JS_TRUE; + Script_FieldChanged(c, NULL, ptr, NULL); + return JS_TRUE; } static SMJS_FUNC_PROP_SET( array_setLength) -u32 len, i, sftype; -JSBool ret; -GF_JSClass *the_sf_class; -GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj); -if (!JSVAL_IS_INT(*vp) || JSVAL_TO_INT(*vp) < 0) return JS_FALSE; + u32 len, i, sftype; + JSBool ret; + GF_JSClass *the_sf_class; + GF_JSField *ptr = (GF_JSField *) SMJS_GET_PRIVATE(c, obj); + if (!JSVAL_IS_INT(*vp) || JSVAL_TO_INT(*vp) < 0) return JS_FALSE; /*avoids gcc warning*/ #ifndef GPAC_CONFIG_DARWIN if (!id) id=0; #endif -len = JSVAL_TO_INT(*vp); + len = JSVAL_TO_INT(*vp); -if (!len) { - if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { - gf_node_unregister_children(ptr->owner, *(GF_ChildNodeItem**)ptr->field.far_ptr); - *(GF_ChildNodeItem**)ptr->field.far_ptr = NULL; - } else { - gf_sg_vrml_mf_reset(ptr->field.far_ptr, ptr->field.fieldType); + if (!len) { + if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { + gf_node_unregister_children(ptr->owner, *(GF_ChildNodeItem**)ptr->field.far_ptr); + *(GF_ChildNodeItem**)ptr->field.far_ptr = NULL; + } else { + gf_sg_vrml_mf_reset(ptr->field.far_ptr, ptr->field.fieldType); + } + JS_SetArrayLength(c, ptr->js_list, 0); + Script_FieldChanged(c, NULL, ptr, NULL); + return JS_TRUE; } - JS_SetArrayLength(c, ptr->js_list, 0); - Script_FieldChanged(c, NULL, ptr, NULL); - return JS_TRUE; -} -ret = JS_SetArrayLength(c, ptr->js_list, len); -if (ret==JS_FALSE) return ret; + ret = JS_SetArrayLength(c, ptr->js_list, len); + if (ret==JS_FALSE) return ret; -#if 0 -/*insert till index if needed*/ -if (ptr->field.fieldType != GF_SG_VRML_MFNODE) { - if (!ptr->field.far_ptr) ptr->field_ptr = ptr->field.far_ptr = gf_sg_vrml_field_pointer_new(ptr->field.fieldType); - gf_sg_vrml_mf_reset(ptr->field.far_ptr, ptr->field.fieldType); - gf_sg_vrml_mf_alloc(ptr->field.far_ptr, ptr->field.fieldType, len); - if (ptr->field_ptr) ptr->field_ptr = ptr->field.far_ptr; -} -#endif - -the_sf_class = NULL; -switch (ptr->field.fieldType) { -case GF_SG_VRML_MFVEC2F: - the_sf_class = &js_rt->SFVec2fClass; - break; -case GF_SG_VRML_MFVEC3F: - the_sf_class = &js_rt->SFVec3fClass; - break; -case GF_SG_VRML_MFCOLOR: - the_sf_class = &js_rt->SFColorClass; - break; -case GF_SG_VRML_MFROTATION: - the_sf_class = &js_rt->SFRotationClass; - break; -case GF_SG_VRML_MFNODE: -{ - u32 c = gf_node_list_get_count(*(GF_ChildNodeItem**)ptr->field.far_ptr); - while (len < c) { - GF_Node *n = gf_node_list_del_child_idx((GF_ChildNodeItem**)ptr->field.far_ptr, c-1); - if (n) gf_node_unregister(n, ptr->owner); - c--; + the_sf_class = NULL; + switch (ptr->field.fieldType) { + case GF_SG_VRML_MFVEC2F: + the_sf_class = &js_rt->SFVec2fClass; + break; + case GF_SG_VRML_MFVEC3F: + the_sf_class = &js_rt->SFVec3fClass; + break; + case GF_SG_VRML_MFCOLOR: + the_sf_class = &js_rt->SFColorClass; + break; + case GF_SG_VRML_MFROTATION: + the_sf_class = &js_rt->SFRotationClass; + break; + case GF_SG_VRML_MFNODE: + { + u32 c = gf_node_list_get_count(*(GF_ChildNodeItem**)ptr->field.far_ptr); + while (len < c) { + GF_Node *n = gf_node_list_del_child_idx((GF_ChildNodeItem**)ptr->field.far_ptr, c-1); + if (n) gf_node_unregister(n, ptr->owner); + c--; + } + if (len>c) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML] MFARRAY EXPANSION NOT SUPPORTED!!!\n")); + } } - if (len>c) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[VRML] MFARRAY EXPANSION NOT SUPPORTED!!!\n")); + return JS_TRUE; } -} -return JS_TRUE; -} -sftype = gf_sg_vrml_get_sf_type(ptr->field.fieldType); -for (i=0; ifield.fieldType); + for (i=0; ijs_list, i, &a_val); } - JS_SetElement(c, ptr->js_list, i, &a_val); -} -return JS_TRUE; + return JS_TRUE; } static SMJS_FUNC_PROP_GET( array_getLength) @@ -4511,20 +4533,18 @@ static void JS_EventIn(GF_Node *node, GF_FieldInfo *in_field) gf_js_vrml_flush_event_out(node, priv); -#ifdef FORCE_GC - MyJSGC(priv->js_ctx); -#endif + do_js_gc(priv->js_ctx, node); } -static Bool vrml_js_load_script(M_Script *script, char *file, Bool primary_script) +static Bool vrml_js_load_script(M_Script *script, char *file, Bool primary_script, jsval *rval) { FILE *jsf; char *jsscript; u64 fsize; Bool success = 1; JSBool ret; - jsval rval, fval; + jsval fval; GF_ScriptPriv *priv = (GF_ScriptPriv *) script->sgprivate->UserPrivate; uintN attr; JSBool found; @@ -4540,14 +4560,15 @@ static Bool vrml_js_load_script(M_Script *script, char *file, Bool primary_scrip fclose(jsf); jsscript[fsize] = 0; - ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, jsscript, (u32) (sizeof(char)*fsize), 0, 0, &rval); + *rval = JSVAL_NULL; + ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, jsscript, (u32) (sizeof(char)*fsize), 0, 0, rval); if (ret==JS_FALSE) success = 0; if (success && primary_script && JS_LookupProperty(priv->js_ctx, priv->js_obj, "initialize", &fval) && !JSVAL_IS_VOID(fval) && JS_GetPropertyAttributes(priv->js_ctx, priv->js_obj, "initialize", &attr, &found) && found == JS_TRUE) { - JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, &rval); + JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, rval); gf_js_vrml_flush_event_out((GF_Node *)script, priv); } gf_free(jsscript); @@ -4555,7 +4576,7 @@ static Bool vrml_js_load_script(M_Script *script, char *file, Bool primary_scrip } /*fetches each listed URL and attempts to load the script - this is SYNCHRONOUS*/ -Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain) +Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain, jsval *rval) { GF_JSAPIParam par; u32 i; @@ -4563,10 +4584,10 @@ Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain) char *url; GF_Err e; const char *ext; - M_Script *script = (M_Script *)node; e = GF_SCRIPT_ERROR; + *rval = JSVAL_NULL; par.dnld_man = NULL; ScriptAction(NULL, node->sgprivate->scenegraph, GF_JSAPI_OP_GET_DOWNLOAD_MANAGER, NULL, &par); @@ -4595,7 +4616,7 @@ Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain) } if (!strstr(url, "://") || !strnicmp(url, "file://", 7)) { - Bool res = vrml_js_load_script(script, url, opt_file ? 0 : 1); + Bool res = vrml_js_load_script(script, url, opt_file ? 0 : 1, rval); gf_free(url); if (res) return 1; if (no_complain) return 0; @@ -4605,7 +4626,7 @@ Bool JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain) e = gf_dm_sess_process(sess); if (e==GF_OK) { const char *szCache = gf_dm_sess_get_cache_name(sess); - if (!vrml_js_load_script(script, (char *) szCache, opt_file ? 0 : 1)) + if (!vrml_js_load_script(script, (char *) szCache, opt_file ? 0 : 1, rval)) e = GF_SCRIPT_ERROR; } gf_dm_sess_del(sess); @@ -4687,14 +4708,13 @@ static void JSScript_LoadVRML(GF_Node *node) priv->JS_EventIn = JS_EventIn; if (!local_script) { - JSScriptFromFile(node, NULL, 0); + JSScriptFromFile(node, NULL, 0, &rval); gf_sg_lock_javascript(priv->js_ctx, 0); return; } GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] Evaluating script %s\n", str)); -#if 1 ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, str, (u32) strlen(str), 0, 0, &rval); if (ret==JS_TRUE) { /*call initialize if present*/ @@ -4704,13 +4724,10 @@ static void JSScript_LoadVRML(GF_Node *node) JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, &rval); gf_js_vrml_flush_event_out(node, priv); } -#endif gf_sg_lock_javascript(priv->js_ctx, 0); -#ifdef FORCE_GC - MyJSGC(priv->js_ctx); -#endif + do_js_gc(priv->js_ctx, node); } static void JSScript_Load(GF_Node *node) diff --git a/src/terminal/media_control.c b/src/terminal/media_control.c index fb1b87d..8bb7b5b 100644 --- a/src/terminal/media_control.c +++ b/src/terminal/media_control.c @@ -506,7 +506,7 @@ void gf_odm_set_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl) /*deactivate current control*/ if (ctrl && odm->subscene->dyn_ck->mc) { odm->subscene->dyn_ck->mc->control->enabled = 0; - gf_node_event_out_str((GF_Node *)odm->subscene->dyn_ck->mc->control, "enabled"); + gf_node_event_out((GF_Node *)odm->subscene->dyn_ck->mc->control, 7/*"enabled"*/); } odm->subscene->dyn_ck->mc = ctrl; } @@ -518,7 +518,7 @@ void gf_odm_set_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl) /*deactivate current control*/ if (ctrl && ch->clock->mc) { ch->clock->mc->control->enabled = 0; - gf_node_event_out_str((GF_Node *)ch->clock->mc->control, "enabled"); + gf_node_event_out((GF_Node *)ch->clock->mc->control, 7/*"enabled"*/); } /*and attach this control to the clock*/ ch->clock->mc = ctrl; @@ -564,7 +564,7 @@ Bool gf_odm_switch_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl) if (st2 == ctrl) continue; if (st2->control->enabled) { st2->control->enabled = 0; - gf_node_event_out_str((GF_Node *) st2->control, "enabled"); + gf_node_event_out((GF_Node *) st2->control, 7/*"enabled"*/); } st2->enabled = 0; } diff --git a/src/terminal/network_service.c b/src/terminal/network_service.c index e596bbb..1122d47 100644 --- a/src/terminal/network_service.c +++ b/src/terminal/network_service.c @@ -78,6 +78,8 @@ static void term_on_connect(GF_ClientService *service, LPNETCHANNEL netch, GF_Er gf_list_add(term->net_services_to_remove, service); } + gf_term_lock_media_queue(term, 0); + if (!root->parentscene) { GF_Event evt; evt.type = GF_EVENT_CONNECT; @@ -92,7 +94,6 @@ static void term_on_connect(GF_ClientService *service, LPNETCHANNEL netch, GF_Er gf_scene_remove_object(root->parentscene, root, 0); gf_odm_disconnect(root, 1); } - gf_term_lock_media_queue(term, 0); return; } } diff --git a/src/terminal/object_manager.c b/src/terminal/object_manager.c index 5b98ac9..6003987 100644 --- a/src/terminal/object_manager.c +++ b/src/terminal/object_manager.c @@ -59,23 +59,22 @@ GF_ObjectManager *gf_odm_new() void gf_odm_reset_media_control(GF_ObjectManager *odm, Bool signal_reset) { #ifndef GPAC_DISABLE_VRML - u32 i; MediaSensorStack *media_sens; MediaControlStack *media_ctrl; - i=0; - while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i))) { + while ((media_sens = (MediaSensorStack *)gf_list_last(odm->ms_stack))) { MS_Stop(media_sens); /*and detach from stream object*/ media_sens->stream = NULL; + gf_list_rem_last(odm->ms_stack); } - i=0; - while ((media_ctrl = (MediaControlStack *)gf_list_enum(odm->mc_stack, &i))) { + while ((media_ctrl = (MediaControlStack *)gf_list_last(odm->mc_stack))) { if (signal_reset) gf_odm_remove_mediacontrol(odm, media_ctrl); media_ctrl->stream = NULL; media_ctrl->ck = NULL; + gf_list_rem_last(odm->mc_stack); } #endif } @@ -1956,7 +1955,7 @@ void gf_odm_pause(GF_ObjectManager *odm) while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i)) ) { if (media_sens && media_sens->sensor->isActive) { media_sens->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); } } #endif @@ -2017,7 +2016,7 @@ void gf_odm_resume(GF_ObjectManager *odm) while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i)) ) { if (media_sens && !media_sens->sensor->isActive) { media_sens->sensor->isActive = 1; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); } } #endif diff --git a/src/terminal/scene.c b/src/terminal/scene.c index e0d932b..9d9399d 100644 --- a/src/terminal/scene.c +++ b/src/terminal/scene.c @@ -908,7 +908,7 @@ void gf_scene_set_duration(GF_Scene *scene) while ((media_sens = (MediaSensorStack*)gf_list_enum(scene->root_od->ms_stack, &i))) { if (media_sens->sensor->isActive) { media_sens->sensor->mediaDuration = dur; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaDuration"); + gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/); } } #endif @@ -1840,7 +1840,7 @@ static void load_associated_media(GF_Scene *scene, GF_AddonMedia *addon) //we force the timeline of the addon to be locked with the main scene mo = gf_scene_get_media_object(scene, &url, GF_MEDIA_OBJECT_SCENE, GF_TRUE); - if (!mo) return; + if (!mo || !mo->odm) return; addon->root_od = mo->odm; mo->odm->addon = addon; @@ -1933,6 +1933,7 @@ void gf_scene_notify_associated_media_timeline(GF_Scene *scene, GF_AssociatedCon load_associated_media(scene, addon); } } + if (!scene->active_addon->root_od) return; gf_mx_p(scene->active_addon->root_od->mx); prev_time = (Double) scene->active_addon->media_timestamp; diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 5c93256..cdbe837 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -67,13 +67,36 @@ static Bool check_user(GF_User *user) return 1; } +void gf_term_message_ex(GF_Terminal *term, const char *service, const char *message, GF_Err error, Bool no_filtering) +{ + GF_Event evt; + if (!term || !term->user) return; + memset(&evt, 0, sizeof(GF_Event)); + evt.type = GF_EVENT_MESSAGE; + evt.message.service = service; + evt.message.message = message; + evt.message.error = error; + + if (no_filtering) { + if (term->user->EventProc) + term->user->EventProc(term->user->opaque, &evt); + } else { + gf_term_send_event(term, &evt); + } +} + +void gf_term_message(GF_Terminal *term, const char *service, const char *message, GF_Err error) +{ + gf_term_message_ex(term, service, message, error, 0); +} + static Bool term_script_action(void *opaque, u32 type, GF_Node *n, GF_JSAPIParam *param) { Bool ret; GF_Terminal *term = (GF_Terminal *) opaque; if (type==GF_JSAPI_OP_MESSAGE) { - gf_term_message(term, term->root_scene->root_od->net_service->url, param->info.msg, param->info.e); + gf_term_message_ex(term, term->root_scene->root_od->net_service->url, param->info.msg, param->info.e, 1); return 1; } if (type==GF_JSAPI_OP_GET_TERM) { @@ -801,17 +824,6 @@ GF_Err gf_term_del(GF_Terminal * term) } -void gf_term_message(GF_Terminal *term, const char *service, const char *message, GF_Err error) -{ - GF_Event evt; - if (!term || !term->user) return; - memset(&evt, 0, sizeof(GF_Event)); - evt.type = GF_EVENT_MESSAGE; - evt.message.service = service; - evt.message.message = message; - evt.message.error = error; - gf_term_send_event(term, &evt); -} GF_EXPORT GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff) diff --git a/src/utils/cache.c b/src/utils/cache.c index 927dee3..d0022c0 100644 --- a/src/utils/cache.c +++ b/src/utils/cache.c @@ -171,7 +171,7 @@ struct __DownloadedCacheEntryStruct u8 *mem_storage; }; -Bool delete_cache_files(void *cbck, char *item_name, char *item_path) { +Bool delete_cache_files(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) { const char * startPattern; int sz; assert( cbck ); diff --git a/src/utils/color.c b/src/utils/color.c index f7d91f8..b7254dc 100644 --- a/src/utils/color.c +++ b/src/utils/color.c @@ -1491,7 +1491,7 @@ void gf_cmx_apply_fixed(GF_ColorMatrix *_this, Fixed *a, Fixed *r, Fixed *g, Fix #ifdef GPAC_HAS_SSE2 -static GF_Err gf_color_write_yv12_10_to_yuv_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd) +static GF_Err gf_color_write_yv12_10_to_yuv_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd, Bool swap_uv) { u32 i, j, w, h; if (!pU) { @@ -1512,6 +1512,13 @@ static GF_Err gf_color_write_yv12_10_to_yuv_intrin(GF_VideoSurface *vs_dst, uns h = src_height; } + if (swap_uv) { + u8 *t = pV; + pV = pU; + pU = t; + } + + if (vs_dst->pixel_format == GF_PIXEL_YV12) { __m128i val1, val2, val_dst, *src1, *src2, *dst; for (i=0; iy / 2) + _src_wnd->x) / 2; pV = pV + (src_stride * (_src_wnd->y / 2) + _src_wnd->x) / 2; } + + if (swap_uv) { + u8 *t = pV; + pV = pU; + pU = t; + } if (vs_dst->pixel_format == GF_PIXEL_YV12) { for (i=0; id_name; + if (file && file[0]=='.') file_info.hidden = 1; + + if (file_info.directory) { + char * parent_name = strrchr(item_path, '/'); + if (!parent_name) { + file_info.drive = GF_TRUE; + } else { + struct stat st_parent; + parent_name[0] = 0; + if (stat(item_path, &st_parent) == 0) { + if ((st.st_dev != st_parent.st_dev) || ((st.st_dev == st_parent.st_dev) && (st.st_ino == st_parent.st_ino))) { + file_info.drive = GF_TRUE; + } + } + parent_name[0] = '/'; + } + } #endif - if (enum_dir_fct(cbck, file, item_path)) { + if (enum_dir_fct(cbck, file, item_path, &file_info)) { #ifdef WIN32 BOOL ret = FindClose(SearchH); if (!ret) { diff --git a/src/utils/os_module.c b/src/utils/os_module.c index 1cecf53..e81bf55 100644 --- a/src/utils/os_module.c +++ b/src/utils/os_module.c @@ -178,7 +178,7 @@ void gf_modules_unload_library(ModuleInstance *inst) } -Bool enum_modules(void *cbck, char *item_name, char *item_path) +static Bool enum_modules(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) { ModuleInstance *inst; #if CHECK_MODULE diff --git a/src/utils/symbian_os.cpp b/src/utils/symbian_os.cpp index afcefda..91878ac 100644 --- a/src/utils/symbian_os.cpp +++ b/src/utils/symbian_os.cpp @@ -795,7 +795,7 @@ void gf_modules_unload_library(ModuleInstance *inst) } -static Bool enum_modules(void *cbck, char *item_name, char *item_path) +static Bool enum_modules(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) { ModuleInstance *inst; diff --git a/src/utils/xml_parser.c b/src/utils/xml_parser.c index 750db8e..e0ce1a6 100644 --- a/src/utils/xml_parser.c +++ b/src/utils/xml_parser.c @@ -1,4 +1,4 @@ -/* +/* * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre -- 2.30.2