Imported Upstream version 0.5.0+svn5324~dfsg1
authorAlessio Treglia <alessio@debian.org>
Thu, 31 Jul 2014 13:11:44 +0000 (14:11 +0100)
committerAlessio Treglia <alessio@debian.org>
Thu, 31 Jul 2014 13:11:44 +0000 (14:11 +0100)
72 files changed:
applications/mp4box/filedump.c
applications/mp4box/fileimport.c
applications/mp4box/main.c
applications/mp4client/main.c
applications/testapps/hevcbench/main.c
applications/testapps/loadcompare/loadcompare.c
applications/testapps/svg2bifs/main.c
gui/gui.js
include/gpac/color.h
include/gpac/events.h
include/gpac/events_constants.h
include/gpac/internal/compositor_dev.h
include/gpac/internal/scenegraph_dev.h
include/gpac/media_tools.h
include/gpac/scenegraph_svg.h
include/gpac/tools.h
include/gpac/version.h
modules/dx_hw/copy_pixels.c
modules/dx_hw/dx_window.c
modules/ffmpeg_in/ffmpeg_decode.c
modules/ft_font/ft_font.c
modules/gpac_js/gpac_js.c
modules/mpd_in/mpd_in.c
modules/openhevc_dec/openhevc_dec.c
modules/widgetman/widgetman.c
src/bifs/conditional.c
src/compositor/compositor.c
src/compositor/compositor_2d.c
src/compositor/drawable.c
src/compositor/events.c
src/compositor/hardcoded_protos.c
src/compositor/mpeg4_animstream.c
src/compositor/mpeg4_audio.c
src/compositor/mpeg4_background2d.c
src/compositor/mpeg4_composite.c
src/compositor/mpeg4_grouping_3d.c
src/compositor/mpeg4_layer_2d.c
src/compositor/mpeg4_layer_3d.c
src/compositor/mpeg4_layout.c
src/compositor/mpeg4_sensors.c
src/compositor/mpeg4_textures.c
src/compositor/svg_grouping.c
src/compositor/texturing.c
src/compositor/visual_manager.h
src/compositor/visual_manager_2d.c
src/compositor/visual_manager_2d.h
src/compositor/visual_manager_2d_draw.c
src/isomedia/isom_write.c
src/media_tools/dash_client.c
src/media_tools/dash_segmenter.c
src/media_tools/isom_tools.c
src/media_tools/media_import.c
src/media_tools/mpegts.c
src/scenegraph/base_scenegraph.c
src/scenegraph/mpeg4_animators.c
src/scenegraph/svg_attributes.c
src/scenegraph/vrml_interpolators.c
src/scenegraph/vrml_proto.c
src/scenegraph/vrml_route.c
src/scenegraph/vrml_smjs.c
src/terminal/media_control.c
src/terminal/network_service.c
src/terminal/object_manager.c
src/terminal/scene.c
src/terminal/terminal.c
src/utils/cache.c
src/utils/color.c
src/utils/os_config_init.c
src/utils/os_divers.c
src/utils/os_module.c
src/utils/symbian_os.cpp
src/utils/xml_parser.c

index feea5e1950d10791994402e506825e27894279ed..1966b5eed054ba897b1e86b3d76dc1c2c20cbfc5 100644 (file)
@@ -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);
index b97bdf739b4ca54504f8873174d6abadc42fc7ca..39fd3bae4711e121860a293354a8e2ed613a88a5 100644 (file)
@@ -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; i<import.nb_tracks; i++) {
@@ -1939,7 +1939,7 @@ typedef struct
        Bool force_cat, align_timelines, allow_add_in_command;
 } CATEnum;
 
-Bool cat_enumerate(void *cbk, char *szName, char *szPath)
+Bool cat_enumerate(void *cbk, char *szName, char *szPath, GF_FileEnumInfo *file_info)
 {
        GF_Err e;
        u32 len_rad1;
@@ -2421,7 +2421,7 @@ void sax_node_start(void *sax_cbck, const char *node_name, const char *name_spac
        }
 }
 
-static Bool wgt_enum_files(void *cbck, char *file_name, char *file_path)
+static Bool wgt_enum_files(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info)
 {
        WGTEnum *wgt = (WGTEnum *)cbck;
 
@@ -2431,7 +2431,7 @@ static Bool wgt_enum_files(void *cbck, char *file_name, char *file_path)
        gf_list_add(wgt->imports, 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);
index 2ab062bc0c5d7679c563a3f2110bf6bc1dc82c99..f62b655aa7fb98b8e5618079e5a7619ffb3d8b19 100644 (file)
@@ -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"));
index a8b9060634f049aed3ce3cc068f2feec438bebaa..4cb1f882b37a7efc5240d92d11c5d42bf23aee97 100644 (file)
@@ -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();
                }
        }
 }
index 96cb43da5913aa4e7bdf46f5dec95009cc79df7c..034e2217c438812b1c3b6018d1131a896bc74999 100644 (file)
@@ -42,8 +42,8 @@ GLint memory_format=GL_UNSIGNED_BYTE;
 GLint pixel_format=GL_LUMINANCE;\r
 GLint texture_type=GL_TEXTURE_RECTANGLE_EXT;\r
 u32 gl_nb_frames = 1;\r
-u32 gl_upload_time = 0;\r
-u32 gl_draw_time = 0;\r
+u64 gl_upload_time = 0;\r
+u64 gl_draw_time = 0;\r
 Bool pbo_mode = GF_TRUE;\r
 Bool first_tx_load = GF_FALSE;\r
 Bool use_vsync=0;\r
@@ -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)\r
 {\r
        u32 needs_stride = 0;\r
-       u32 now, end;\r
+       u64 now, end;\r
 \r
        if (stride != w) {\r
                if (bit_depth==10) {\r
                        if (stride != 2*w) {\r
-                               needs_stride = stride;\r
+                               needs_stride = stride / 2;\r
                        }\r
                } else {\r
                        needs_stride = stride;\r
@@ -395,7 +395,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str
 \r
        glEnable(texture_type);\r
 \r
-       now = gf_sys_clock();\r
+       now = gf_sys_clock_high_res();\r
 \r
 \r
        if (first_tx_load) {\r
@@ -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)\r
 #else\r
                linesize = width*Bpp;\r
-               p_stride = stride*Bpp;\r
+               p_stride = stride;\r
                count = h;\r
 #if (COPY_TYPE==2)\r
                c2 = linesize/4;\r
@@ -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)\r
 #else\r
                linesize = width*Bpp/2;\r
-               p_stride = stride*Bpp/2;\r
+               p_stride = stride/2;\r
                count/=2;\r
 #if (COPY_TYPE==2)\r
                c2 /= 2;\r
@@ -570,7 +570,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str
 \r
                if (needs_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);\r
        }\r
-       end = gf_sys_clock() - now;\r
+       end = gf_sys_clock_high_res() - now;\r
 \r
        if (!first_tx_load) {\r
                gl_nb_frames ++;\r
@@ -601,7 +601,7 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str
 \r
        SDL_GL_SwapWindow(window);\r
 \r
-       gl_draw_time += gf_sys_clock() - now;\r
+       gl_draw_time += gf_sys_clock_high_res() - now;\r
        return;\r
 }\r
 \r
@@ -610,19 +610,19 @@ void sdl_bench()
 {\r
        Double rate;\r
        u32 i, count;\r
-       u32 start = gf_sys_clock();\r
+       u64 start = gf_sys_clock_high_res();\r
 \r
        count = 600;\r
        for (i=0; i<count; i++) {\r
-               sdl_draw_frame(pY, pU, pV, width, height, 8, width);\r
+               sdl_draw_frame(pY, pU, pV, width, height, bpp, width);\r
        }\r
 \r
-       start = gf_sys_clock() - start;\r
+       start = gf_sys_clock_high_res() - start;\r
        rate = 3*size/2;\r
-       rate *= count;\r
+       rate *= count*1000;\r
        rate /= start; //in ms\r
        rate /= 1000; //==*1000 (in s) / 1000 * 1000 in MB /s\r
-       fprintf(stdout, "gltext pushed %d frames in %d ms - FPS %g - data rate %g MB/s\n", count, start, 1000.0*count/start, rate);\r
+       fprintf(stdout, "gltext pushed %d frames in %d ms - FPS %g - data rate %g MB/s\n", count, start/1000, 1000000.0*count/start, rate);\r
 }\r
 \r
 void PrintUsage()\r
@@ -639,14 +639,17 @@ void PrintUsage()
               );\r
 }\r
 \r
+\r
+\r
 int main(int argc, char **argv)\r
 {\r
        Bool sdl_bench_yuv = GF_FALSE;\r
        Bool no_display = GF_FALSE;\r
-       u32 start, now, check_prompt;\r
+       u64 start, now;\r
+       u32 check_prompt;\r
        Bool sdl_is_init=GF_FALSE, run;\r
        Bool paused = GF_FALSE;\r
-       u32 pause_time = 0;\r
+       u64 pause_time = 0;\r
        GF_ISOFile *isom;\r
        u32 i, count, track = 0;\r
        u32 nb_frames_at_start = 0;\r
@@ -671,6 +674,7 @@ int main(int argc, char **argv)
                        continue;\r
                }\r
                if (!strcmp(arg, "-bench-yuv")) sdl_bench_yuv=1;\r
+               else if (!strcmp(arg, "-bench-yuv10")) sdl_bench_yuv=2;\r
                else if (!strcmp(arg, "-sys-mem")) use_raw_memory = 0;\r
                else if (!strcmp(arg, "-vsync")) use_vsync = 1;\r
                else if (!strcmp(arg, "-use-pbo")) use_pbo = 1;\r
@@ -702,7 +706,7 @@ int main(int argc, char **argv)
        gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);\r
 \r
        if (sdl_bench_yuv) {\r
-               sdl_init(3840, 2160, 8, 3840, use_pbo);\r
+               sdl_init(3840, 2160, (sdl_bench_yuv==2) ? 10 : 8, 3840, use_pbo);\r
                sdl_bench();\r
                sdl_close();\r
                gf_sys_close();\r
@@ -737,13 +741,17 @@ int main(int argc, char **argv)
        }\r
 \r
        count = gf_isom_get_sample_count(isom, track);\r
-       start = gf_sys_clock();\r
+       start = gf_sys_clock_high_res();\r
 \r
        esd = gf_isom_get_esd(isom, track, 1);\r
        ohevc = libOpenHevcInit(nb_threads, mode);\r
        if (esd->decoderConfig && esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) {\r
                libOpenHevcCopyExtraData(ohevc, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength+8);\r
        }\r
+\r
+       libOpenHevcSetActiveDecoders(ohevc, 1);\r
+       libOpenHevcSetViewLayers(ohevc, 1);\r
+\r
        libOpenHevcStartDecoder(ohevc);\r
        gf_odf_desc_del((GF_Descriptor *)esd);\r
        gf_isom_set_sample_padding(isom, track, 8);\r
@@ -756,16 +764,6 @@ int main(int argc, char **argv)
                        GF_ISOSample *sample = gf_isom_get_sample(isom, track, i+1, &di);\r
 \r
                        if ( libOpenHevcDecode(ohevc, sample->data, sample->dataLength, sample->DTS+sample->CTS_Offset) ) {\r
-                               OpenHevc_Frame_cpy HVCFrame;\r
-\r
-                               libOpenHevcGetPictureInfo(ohevc, &HVCFrame.frameInfo);\r
-                               if (!sdl_is_init && !no_display) {\r
-                                       sdl_init(HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch+32, use_pbo);\r
-                                       sdl_is_init=1;\r
-                                       start = gf_sys_clock();\r
-                                       nb_frames_at_start = i+1;\r
-                               }\r
-\r
                                if (no_display) {\r
                                        OpenHevc_Frame HVCFrame_ptr;\r
                                        libOpenHevcGetOutput(ohevc, 1, &HVCFrame_ptr);\r
@@ -773,21 +771,42 @@ int main(int argc, char **argv)
                                        OpenHevc_Frame HVCFrame_ptr;\r
                                        libOpenHevcGetOutput(ohevc, 1, &HVCFrame_ptr);\r
 \r
-                                       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);\r
+\r
+                                       if (!sdl_is_init && !no_display) {\r
+                                               sdl_init(HVCFrame_ptr.frameInfo.nWidth, HVCFrame_ptr.frameInfo.nHeight, HVCFrame_ptr.frameInfo.nBitDepth, HVCFrame_ptr.frameInfo.nYPitch, use_pbo);\r
+                                               sdl_is_init=1;\r
+                                               start = gf_sys_clock_high_res();\r
+                                               nb_frames_at_start = i+1;\r
+                                       }\r
+\r
+                                       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);\r
                                } else {\r
-                                       memset(&HVCFrame, 0, sizeof(OpenHevc_Frame) );\r
+                                       OpenHevc_Frame_cpy HVCFrame;\r
+                                       memset(&HVCFrame, 0, sizeof(OpenHevc_Frame_cpy) );\r
+\r
+                                       libOpenHevcGetPictureInfoCpy(ohevc, &HVCFrame.frameInfo);\r
+\r
+                                       if (!sdl_is_init && !no_display) {\r
+                                               sdl_init(HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch, use_pbo);\r
+                                               sdl_is_init=1;\r
+                                               start = gf_sys_clock_high_res();\r
+                                               nb_frames_at_start = i+1;\r
+                                       }\r
+\r
                                        HVCFrame.pvY = (void*) pY;\r
                                        HVCFrame.pvU = (void*) pU;\r
                                        HVCFrame.pvV = (void*) pV;\r
+\r
                                        libOpenHevcGetOutputCpy(ohevc, 1, &HVCFrame);\r
+\r
                                        sdl_draw_frame(pY, pU, pV, HVCFrame.frameInfo.nWidth, HVCFrame.frameInfo.nHeight, HVCFrame.frameInfo.nBitDepth, HVCFrame.frameInfo.nYPitch);\r
                                }\r
                        }\r
 \r
                        gf_isom_sample_del(&sample);\r
 \r
-                       now = gf_sys_clock();\r
-                       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 );\r
+                       now = gf_sys_clock_high_res();\r
+                       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 );\r
                } else {\r
                        gf_sleep(10);\r
                        i--;\r
@@ -805,14 +824,14 @@ int main(int argc, char **argv)
                                case 'p':\r
                                        if (paused) {\r
                                                paused=0;\r
-                                               start += gf_sys_clock()-pause_time;\r
+                                               start += gf_sys_clock_high_res()-pause_time;\r
                                        } else {\r
                                                paused = 1;\r
-                                               pause_time=gf_sys_clock();\r
+                                               pause_time=gf_sys_clock_high_res();\r
                                        }\r
                                        break;\r
                                case 'r':\r
-                                       start = gf_sys_clock();\r
+                                       start = gf_sys_clock_high_res();\r
                                        nb_frames_at_start = i+1;\r
                                        gl_upload_time = gl_draw_time = 0;\r
                                        gl_nb_frames=1;\r
@@ -823,8 +842,8 @@ int main(int argc, char **argv)
                        check_prompt=0;\r
                }\r
        }\r
-       now = gf_sys_clock();\r
-       fprintf(stderr, "Decoded %d frames in %d ms - FPS %g\n", i+1, now-start, 1000.0 * (i+1) / (now-start) );\r
+       now = gf_sys_clock_high_res();\r
+       fprintf(stderr, "\nDecoded %d frames in %d ms - FPS %g\n", i+1, (now-start)/1000, 1000000.0 * (i+1) / (now-start) );\r
 \r
        libOpenHevcClose(ohevc);\r
        gf_isom_close(isom);\r
index 828dc5baddca83079aa2e433dc1c07571d1bbe00..877428179cd285879e802854dd291f358a148206 100644 (file)
@@ -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;
index f5a462defe4b479d0643f3246f188c2a1eebb20e..d13ed2fdd6492b1de7941362d0e81219da21506f 100644 (file)
@@ -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);
index ebea4be70876571cfa4650173e5c776daaf43a75..f047984494dad795ccc51bb21a42686f555068ed 100644 (file)
@@ -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) {
index d2540196cad2a7e1de11b8caaaa6a530dff9a182..1820200b5d691d526d2c4dc7e56febedd7658fe2 100644 (file)
@@ -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);
 
 /*! @} */
 
index ecf06d641964b72cf167839ae37b93b7a58b4d7e..372e3fdfdb72e61136f82344719646bdc16767ca 100644 (file)
@@ -274,7 +274,7 @@ typedef struct {
 
 
 typedef struct {
-       /* GF_EVENT_OPENFILE*/
+       /* GF_EVENT_DROPFILE*/
        u8 type;
        u32 nb_files;
        char **files;
index a8eeb64a974772cc5f70ce680507a8b75482b591..e8da544c1fe7cca6abcbbc967f4bbebc4ac8b5e2 100644 (file)
@@ -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,
index 61580bc28174216a2cbc86172e2dbe0e4e9666fc..fab6bdc47aad96cdf4bc30450b7de13d48256222 100644 (file)
@@ -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);
index 9d380c8a61b34618e8efcdb6d4f07e16c9fffdea..c063304bdb5d73b29ae74be854255b52abd89392 100644 (file)
@@ -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
index d65557af579d1f60b316707d183f4b4e0ac2ecba..5175a6980804f981c811fc99684248514fffc523 100644 (file)
@@ -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;
 
index 22dd7e79bc16b0f7b62aaa7cb177a7cb77b54710..1021950d18b000f6236ff5919b1cba094a7d06e1 100644 (file)
@@ -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;
index 8802ec7a87aced9c791adb628f9fb337123f04e9..c68e35606e362b1e047d943fa1d0001960c64f2f 100644 (file)
@@ -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
index d0066221196de2776079127042f2f9917348740e..3a8a8c2fafcf8da30ef38b8402e38153cc02ec02 100644 (file)
@@ -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 <gpac/revision.h>
index 328ce6365fd24459dd15258a26be96a3c9805f75..aa3def9a7e89f66b71d7150a6a8d0805e91a649b 100644 (file)
@@ -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)) {
index a2ff70e4e03e9b66bffd41025d1b513564a659eb..bcb20ef60f18e8f00e7f1cf97e4b4b4ea8755f91 100644 (file)
@@ -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; i<evt.open_file.nb_files; i++) {
index 80a278bf1176eecd01efa2f15f45572893671bc8..16c4fbbc3d9884f3aabfc1de3629255ac1f954ed 100644 (file)
@@ -1073,7 +1073,7 @@ redecode:
                dst.video_buffer = ffd->direct_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;
        }
index dbaa2c43a59301006502098ba0dc2b3048b34777..e88fa8af4dff490a179ab8618153c1268036d01f 100644 (file)
@@ -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");
index 9ba3a8a828b3c16557d55063e6ae5f368bbb03f1..0d1ded3ab4779d53ec4c2f3a2e822f447602f5bb 100644 (file)
@@ -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; i<evt->open_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; i<evt->open_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);
index 55e746954d95cfbbb8246f6ee816f8768fa6dc75..09c48cf019f8a814f767e575f9f81731c8cbc5bf 100644 (file)
@@ -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, &timescale);
                                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, &timescale);
-                                               offset = pto;
+                                               offset = (Double) pto;
                                                offset /= timescale;
                                                com->play.start_range -= offset;
                                                if (com->play.start_range < 0) com->play.start_range = 0;
index bf9f2f19fdaccb0139711c7ee9fb70d12c643967..ea223cb223e5e1e5304144834ad09dc40cba312a 100644 (file)
@@ -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; i<ctx->height; i++) {
-                                       memcpy(pY,  (u8 *) openHFrame.pvY + i*s_stride, d_stride);
-                                       pY += dd_stride;
+                       for (i=0; i<ctx->height; 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;
 }
index c74a2f8c88cab5708a1318d7f477e1490e3641df..0949240c8c9398785c311da2497065ad6ae307c8 100644 (file)
@@ -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;
 }
index 50b19a890f3443f1213288af0226050698c6c620..95f19e50a6438fa699fa8b2acbcfa5bfffa7a3d3 100644 (file)
@@ -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*/
index a0552a60bfbefc0683a7d29dbdb39fb852535b7a..85e1ca83e53835cb75d8ef2fbaf78b94a40a4cd4 100644 (file)
@@ -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; i<count; i++) {
-                               SVG_SA_listenerElement *l = gf_dom_listener_get(root, i);
-                               if (l->event.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; i<count; i++) {
                GF_TextureHandler *txh = (GF_TextureHandler *)gf_list_get(compositor->textures, 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))
index b097df87bc4b9b45530b6c945010bbfa292f67d4..f0830e1ff8f614ae16cb268ccff24683fd071d16 100644 (file)
@@ -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;
index b5207b8c95abc019c2e9690ef937b62151b4f4a2..23bf49de467412ddded60088b8a5af3d6fbb78db 100644 (file)
@@ -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;
 
index 2535b134dcbc2bed064d62ca3efadb42ed4e3d6d..7b16c470210cd42d21ee3a1fd0b69a98f5eed760 100644 (file)
@@ -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;
index 984309a17f6343281d87bbc307888041c79dba76..72ab6735ecade94bc7c53f9f3fe51f2036ee12a2 100644 (file)
@@ -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) {
index 9bcff37f95813f40e0c14ccedacbfdda7010f56d..acac8a32f4aea817923dc7734ce2ae71d84259bd 100644 (file)
@@ -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))
index e44cae805201049c10f93872aa6cbe979925b4d1..72156bb3fa1699cc5769d9e41a07ed8fe0c0c8d1 100644 (file)
@@ -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;
 }
 
index edf359505a97101f123ae0abe7f3e5f3be6eef65..b0ec70503871c168886262a88ea9e904a12e2f2a 100644 (file)
@@ -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);
                        }
                }
        }
index 2739c7a32270ad72dd315bece0a2406c19b31ef7..2e96aa7e8d784380a809ce9ddc3fcec69b5802aa 100644 (file)
@@ -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;
                }
 
index ae525a31b1cef86c42fe153e0eb9bf397f947db8..1ebf79c8cecf966ee73ccf3d8238b9d6d0e7dc58 100644 (file)
@@ -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_dist<tr_state->camera->collide_dist)) {
                                tr_state->camera->collide_flags = collide_flags;
index 19e31e70517ad8b724e0bf52f4b55fa4c1262dcb..9f60b47c64a8b4f8caacd1c653f938cc33596e8f 100644 (file)
@@ -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"*/);
        }
 }
 
index 3e86362904cf2cb6ba7f0f564e115734d9ea4e75..f5d16791003fe3f8d09827508c7f9776b6a71031 100644 (file)
@@ -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;
 }
index 2b997bd3bff23f8a2b5c5f9057e172f7212254fb..990df3f4932dfb01a4476a4df8e427b7610224f4 100644 (file)
@@ -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;
index 96f498ab1d18eb3562a8e1877fc71066768f5ea8..21682443374d2a77a9f584b65188ca24a6b9d250 100644 (file)
@@ -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)
index f3e46ce7f439090ae458ba5f9c837e9a8fb04374..d7d3b7782fe984b14b5f05df66b65f3978b1c881 100644 (file)
@@ -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);
index e0f5a25348d0466efe02ee0876593c9b1ae19105..55cb2f849985685c68a91b77644e6aaa3718ef19 100644 (file)
@@ -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;
index ecf751944e403e1d6255562caa847506d522ea8a..3bebb9f59969eaa95afaac78426395e24f8fc8a3 100644 (file)
@@ -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;
 }
 
index 14eb1aefb5345db0f49cc5957c83a70512dad00e..ee70873d52ada71f8ce574c88b4028ce21fc3ff1 100644 (file)
@@ -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);
 
index 8de00e8cf56644d40cfa070ecc7bcad1ee6d532a..b9a8ac7ac3892f51eeea73b31c6c905196b5e964 100644 (file)
@@ -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; i<ra->count; i++) {
                for (j=i+1; j<ra->count; 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
        }
index f8c5438f94e521175b1e10f7fdccb800597467e3..77a3c728c21523a410a3a45a0f8271edf84d50fa 100644 (file)
@@ -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);
index 21dc81d1235d6469344f2e4d31f1ea659df85155..024614b339495797cdf49cff8be1b5e86161e1d2 100644 (file)
@@ -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;
index dd72ec894e497bdc084807044810cfda8ba81d15..5f20f22c407eb93b92503a3a19cb830694883c71 100644 (file)
@@ -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;
index 9e008b0371d64c8fd79dfcf543391617158b5a80..d1a04787502e11e9d7bac7947a1be8e1cf837cfe 100644 (file)
@@ -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;
                                        }
                                }
index 3ef541fb4e70c8fdd56e5a6a573b4c6c44926bd0..3fa3631a19c354fbc444a06e83b26581af8c27b5 100644 (file)
@@ -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; i<dash_input->nb_rep_descs; i++) {
+                       fprintf(dash_cfg->mpd, "    %s\n", dash_input->rep_descs[i]);
+               }
+       }
+
        if (nb_channels && !is_bs_switching)
                fprintf(dash_cfg->mpd, "    <AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\"/>\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; i<nb_dash_inputs; i++) {
+               Bool has_same_desc = GF_TRUE;
                Bool valid_in_adaptation_set = 1;
                Bool assign_to_group = 1;
                GF_ISOFile *in;
@@ -2001,6 +2018,18 @@ static GF_Err dasher_isom_classify_input(GF_DashSegInput *dash_inputs, u32 nb_da
                if (strcmp(dash_inputs[input_idx].role, dash_inputs[i].role))
                        continue;
 
+               /* if two inputs don't have the same (number and value) as_desc they don't belong to the same AdaptationSet
+                  (use c_as_desc for AdaptationSet descriptors common to all inputs in an AS) */
+               if (dash_inputs[input_idx].nb_as_descs != dash_inputs[i].nb_as_descs)
+                       continue;               
+               for (j = 0; j < dash_inputs[input_idx].nb_as_descs; j++) {
+                       if (strcmp(dash_inputs[input_idx].as_descs[j], dash_inputs[i].as_descs[j])) {
+                               has_same_desc= GF_FALSE;
+                               break;
+                       }
+               }
+               if (!has_same_desc) continue;
+
                if (dash_inputs[input_idx].x != dash_inputs[i].x) continue;
                if (dash_inputs[input_idx].y != dash_inputs[i].y) continue;
                if (dash_inputs[input_idx].w != dash_inputs[i].w) continue;
@@ -3285,6 +3314,12 @@ static GF_Err dasher_mp2t_segment_file(GF_DashSegInput *dash_input, const char *
        fprintf(dash_cfg->mpd, " bandwidth=\"%d\"", bandwidth);
        fprintf(dash_cfg->mpd, ">\n");
 
+       /* writing Representation level descriptors */
+       if (dash_input->nb_rep_descs) {
+               for (i=0; i<dash_input->nb_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, "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\" minBufferTime=\"PT%fS\" type=\"%s\"", min_buffer, dash_dynamic ? "dynamic" : "static");
        if (dash_dynamic) {
-               //we only support profiles for which AST has to be the same
-               const char *opt = gf_cfg_get_key(dash_ctx, "DASH", "GenerationNTP");
-               sscanf(opt, "%u", &sec);
-               sec += ast_shift_sec;
+               if (dash_ctx) {
+                       //we only support profiles for which AST has to be the same
+                       const char *opt = gf_cfg_get_key(dash_ctx, "DASH", "GenerationNTP");
+                       sscanf(opt, "%u", &sec);
+                       sec += ast_shift_sec;
+               }
 
 #ifdef _WIN32_WCE
                *(LONGLONG *) &filet = (sec - GF_NTP_SEC_1900_TO_1970) * 10000000 + TIMESPEC_TO_FILETIME_OFFSET;
@@ -3802,13 +3839,16 @@ static GF_Err write_mpd_header(FILE *mpd, const char *mpd_name, GF_Config *dash_
        return GF_OK;
 }
 
-static GF_Err write_period_header(FILE *mpd, const char *szID, Double period_start, Double period_duration, Bool dash_dynamic, const char *xlink)
+static GF_Err write_period_header(FILE *mpd, const char *szID, Double period_start, Double period_duration, 
+                                                                 Bool dash_dynamic, const char *xlink, 
+                                                                 GF_DashSegInput *dash_inputs, u32 nb_dash_inputs, u32 period_num)
 {
        u32 h, m;
        Double s;
+       u32 i,j;
 
        fprintf(mpd, " <Period");
-       if (szID)
+       if (szID && strlen(szID))
                fprintf(mpd, " id=\"%s\"", szID);
 
        if (period_start || dash_dynamic) {
@@ -3827,11 +3867,25 @@ static GF_Err write_period_header(FILE *mpd, const char *szID, Double period_sta
                fprintf(mpd, " xlink:href=\"%s\"", xlink);
        }
        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, "  <AdaptationSet segmentAlignment=\"true\"");
        if (bitstream_switching_mode) {
                fprintf(mpd, " bitstreamSwitching=\"true\"");
@@ -3846,7 +3900,7 @@ static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool us
                gf_media_reduce_aspect_ratio(&max_width, &max_height);
                fprintf(mpd, " par=\"%d:%d\"", max_width, max_height);
        }
-       if (szLang && szLang[0]) {
+       if (szLang && szLang[0] && strcmp(szLang, "und")) {
                fprintf(mpd, " lang=\"%s\"", szLang);
        }
        /*this should be fixed to use info collected during segmentation process*/
@@ -3858,8 +3912,21 @@ static GF_Err write_adaptation_header(FILE *mpd, GF_DashProfile profile, Bool us
 
        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; i<first_rep->nb_as_descs; i++) {
+                       fprintf(mpd, "   %s\n", first_rep->as_descs[i]);
+               }
 
                if (bitstream_switching_mode) {
                        for (i=0; i<first_rep->nb_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; i<first_rep->nb_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, "</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;
 }
index e40a69bc871cc9530b45c6cc30c6025b78ac5fd3..56c4f29166a9ce52ff97f54419fc8e79ca9cc17c 100644 (file)
@@ -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);
index beda643f066bbcabf82fa4c2be08295aaaa39eb1..0181bd21b2a43a6b6819c6ab59349e2f608565c4 100644 (file)
@@ -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; i<GF_M2TS_MAX_STREAMS; i++) {
+               if (ts->ess[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");
index 4b0b309019d3fd3f86b167037387d03b06850f1e..15002de48284f0a448d2e5726cbe3c11b3580064 100644 (file)
@@ -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;
 
index 0b5d84bd528b19e04a84bc7ffc35918ded5f8a89..10fc8389f9ab6094b50c90ae7ad9540033a48c3d 100644 (file)
@@ -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)
 {
index 412dab0bc1528dd8ceb85a973936b4ad05312992..525630ca597d085bc54d6ba83869e6de2a9156ff 100644 (file)
@@ -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)
index 7fc914c73e4dc48602dd5038763820b51adddba8..67ac4176ff0be15b415828a678bc04bb4bbb4d35 100644 (file)
@@ -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;
index a3ab53c0fbe81313c62976888fc881b6dabbfa67..60f2947580acbb5515ec6c1c5d08b55798336655 100644 (file)
@@ -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)
 {
index 197030e5147ba12e9e750e0ade065fc2edd9497e..97536011042efce08d472a52b048e60bbadff3b3 100644 (file)
@@ -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*/
index 6beb960ae2d1943591607a617f51f0e902554636..98938e13e37c1da26fa419cd5f1a2997a9a1fe61 100644 (file)
@@ -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;
 }
 
index d258a7ddf5b504b6e77f2bbe606b97d1bcc94f18..41978710662a9efd2ab633a961187314b1145af4 100644 (file)
@@ -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 (len<ind) {
-               jsval a_val;
-               switch (ptr->field.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 (len<ind) {
+                       jsval a_val;
+                       switch (ptr->field.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; i<len; i++) {
-       jsval a_val;
-       if (the_sf_class) {
-               JSObject *an_obj = SMJS_CONSTRUCT_OBJECT(c, the_sf_class, obj);
-               a_val = OBJECT_TO_JSVAL(an_obj );
-       } else {
-               switch (sftype) {
-               case GF_SG_VRML_SFBOOL:
-                       a_val = BOOLEAN_TO_JSVAL(0);
-                       break;
-               case GF_SG_VRML_SFINT32:
-                       a_val = INT_TO_JSVAL(0);
-                       break;
-               case GF_SG_VRML_SFFLOAT:
-               case GF_SG_VRML_SFTIME:
-                       a_val = JS_MAKE_DOUBLE(c, 0);
-                       break;
-               case GF_SG_VRML_SFSTRING:
-               case GF_SG_VRML_SFURL:
-                       a_val = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") );
-                       break;
-               default:
-                       a_val = INT_TO_JSVAL(0);
-                       break;
+
+       sftype = gf_sg_vrml_get_sf_type(ptr->field.fieldType);
+       for (i=0; i<len; i++) {
+               jsval a_val;
+               if (the_sf_class) {
+                       JSObject *an_obj = SMJS_CONSTRUCT_OBJECT(c, the_sf_class, obj);
+                       a_val = OBJECT_TO_JSVAL(an_obj );
+               } else {
+                       switch (sftype) {
+                       case GF_SG_VRML_SFBOOL:
+                               a_val = BOOLEAN_TO_JSVAL(0);
+                               break;
+                       case GF_SG_VRML_SFINT32:
+                               a_val = INT_TO_JSVAL(0);
+                               break;
+                       case GF_SG_VRML_SFFLOAT:
+                       case GF_SG_VRML_SFTIME:
+                               a_val = JS_MAKE_DOUBLE(c, 0);
+                               break;
+                       case GF_SG_VRML_SFSTRING:
+                       case GF_SG_VRML_SFURL:
+                               a_val = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") );
+                               break;
+                       default:
+                               a_val = INT_TO_JSVAL(0);
+                               break;
+                       }
                }
+               JS_SetElement(c, ptr->js_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)
index fb1b87d83ddc0edaf88aaa624e0556c5f9bee707..8bb7b5b54ae200fdb5ca3fbf02a19457a64d9bce 100644 (file)
@@ -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;
        }
index e596bbb4be239ba582a4279b5fb9a2af0dc59424..1122d474b8331ab9563ab6f4f8434a7a5e2d3d92 100644 (file)
@@ -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;
                        }
                }
index 5b98ac94a70c4500b9d0b4b44dda30766829c657..600398760b03bbf0dc3739a632bd292693ab7ed3 100644 (file)
@@ -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
index e0d932b66ac69c3c6583eb5814632779bea6b7f1..9d9399dce6b5bded69dd243c0fa20b83e60c7e3a 100644 (file)
@@ -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;
index 5c9325697685f818d12fef865e06b800c22192aa..cdbe8370579669a84a72570763ba9f945890b975 100644 (file)
@@ -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)
index 927dee30c384c8e070ba4fe4e49a30ea96a59af9..d0022c0f14d905b2b3dfb232eab603261ee37b36 100644 (file)
@@ -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 );
index f7d91f873683fb931884c4ba9047df2984fdd9de..b7254dc8be2fbb201fe2b239afaec6ab6125d29b 100644 (file)
@@ -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; i<h; i++) {
@@ -1566,7 +1573,7 @@ static GF_Err gf_color_write_yv12_10_to_yuv_intrin(GF_VideoSurface *vs_dst,  uns
 
 
 GF_EXPORT
-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)
 {
        u32 i, j, w, h;
 
@@ -1593,7 +1600,7 @@ GF_Err gf_color_write_yv12_10_to_yuv(GF_VideoSurface *vs_dst,  unsigned char *pY
                && (GFINTCAST (pU + src_stride/2)%8 == 0)
                && (GFINTCAST (pV + src_stride/2)%8 == 0)
           ) {
-               return gf_color_write_yv12_10_to_yuv_intrin(vs_dst, pY, pU, pV, src_stride, src_width, src_height, _src_wnd);
+               return gf_color_write_yv12_10_to_yuv_intrin(vs_dst, pY, pU, pV, src_stride, src_width, src_height, _src_wnd, swap_uv);
        }
 #endif
 
@@ -1609,6 +1616,12 @@ GF_Err gf_color_write_yv12_10_to_yuv(GF_VideoSurface *vs_dst,  unsigned char *pY
                pU = pU + (src_stride * (_src_wnd->y / 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; i<h; i++) {
index 9c074094a4567c697fe24580bce1c6b3d4478a73..517b6c29dbb7894816704db8c3ca9494b0436580 100644 (file)
@@ -64,7 +64,7 @@
 
 
 #ifdef GPAC_STATIC_MODULES
-static Bool enum_mod_dir(void *cbck, char *item_name, char *item_path)
+static Bool enum_mod_dir(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info)
 {
        if (!strnicmp(item_name, "gm_", 3)) {
                printf("Found %s\n", item_name);
index 51033f4e5d97070dfb49f7d8241ec4a7f76f01dd..09d01c5b00c8607542e5d905740d6f8634c102f8 100644 (file)
@@ -201,7 +201,7 @@ GF_Err gf_mkdir(char* DirPathName)
        return GF_OK;
 }
 
-static Bool delete_dir(void *cbck, char *item_name, char *item_path)
+static Bool delete_dir(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info)
 {
        Bool directory_clean_mode = *(Bool*)cbck;
 
@@ -588,6 +588,7 @@ GF_EXPORT
 GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item enum_dir_fct, void *cbck, const char *filter)
 {
        char item_path[GF_MAX_PATH];
+       GF_FileEnumInfo file_info;
 
 #if defined(_WIN32_WCE)
        char _path[GF_MAX_PATH];
@@ -611,6 +612,8 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
 
        if (filter && (!strcmp(filter, "*") || !filter[0])) filter=NULL;
 
+       memset(&file_info, 0, sizeof(GF_FileEnumInfo) );
+
        if (!strcmp(dir, "/")) {
 #if defined(WIN32) && !defined(_WIN32_WCE)
                u32 len;
@@ -621,8 +624,10 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
                GetLogicalDriveStrings(len, drives);
                len = (u32) strlen(drives);
                volume = drives;
+               file_info.directory = GF_TRUE;
+               file_info.drive = GF_TRUE;
                while (len) {
-                       enum_dir_fct(cbck, volume, "");
+                       enum_dir_fct(cbck, volume, "", &file_info);
                        volume += len+1;
                        len = (u32) strlen(volume);
                }
@@ -639,7 +644,7 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
                                TChar aDrive;
                                iFs.DriveToChar(i, aDrive);
                                sprintf(szDrive, "%c:", (TUint)aDrive);
-                               enum_dir_fct(cbck, szDrive, "");
+                               enum_dir_fct(cbck, szDrive, "", &file_info);
                        }
                }
                iFs.Close();
@@ -700,6 +705,9 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
 
 #endif
 
+               memset(&file_info, 0, sizeof(GF_FileEnumInfo) );
+
+
 #if defined (_WIN32_WCE)
                if (!wcscmp(FindData.cFileName, _T(".") )) goto next;
                if (!wcscmp(FindData.cFileName, _T("..") )) goto next;
@@ -712,8 +720,9 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
 #endif
 
 #ifdef WIN32
-               if (!enum_directory && (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) goto next;
-               if (enum_directory && !(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) goto next;
+               file_info.directory = (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? GF_TRUE : GF_FALSE;
+               if (!enum_directory && file_info.directory) goto next;
+               if (enum_directory && !file_info.directory) goto next;
 #endif
 
                if (filter) {
@@ -741,6 +750,16 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
 #endif
                }
 
+#if defined(WIN32)
+               file_info.hidden = (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? 1 : 0;
+               file_info.system = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? 1 : 0;
+               file_info.size = MAXDWORD;
+               file_info.size += 1;
+               file_info.size *= FindData.nFileSizeHigh;
+               file_info.size += FindData.nFileSizeLow;
+               file_info.last_modified = (u64) ((*(LONGLONG *) &FindData.ftLastWriteTime - TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
+#endif
+
 #if defined (_WIN32_WCE)
                CE_WideToChar(FindData.cFileName, file);
                strcpy(item_path, _path);
@@ -755,11 +774,37 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item
                GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Checking file %s for enum\n", item_path));
 
                if (stat( item_path, &st ) != 0) goto next;
-               if (enum_directory && ( (st.st_mode & S_IFMT) != S_IFDIR)) goto next;
-               if (!enum_directory && ((st.st_mode & S_IFMT) == S_IFDIR)) goto next;
+
+               file_info.directory = ((st.st_mode & S_IFMT) == S_IFDIR) ? GF_TRUE : GF_FALSE;
+               if (enum_directory && !file_info.directory) goto next;
+               if (!enum_directory && file_info.directory) goto next;
+
+               file_info.size = st.st_size;
+
+               {
+                       struct tm _t = * gmtime(& st.st_mtime);
+                       file_info.last_modified = mktime(&_t);
+               }
                file = the_file->d_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) {
index 1cecf5327083d363c36b583a9b4842941c0af936..e81bf55830695625e160828594d3a92bd97f8ded 100644 (file)
@@ -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
index afcefda0787803930e227fa6ada2f4c63c9114df..91878acdeebbc7415c772ef07094c95399567245 100644 (file)
@@ -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;
 
index 750db8e072db952499e1a97b9b2d41c59871cc2f..e0ce1a68db3cd3290446cbe3a0f7734767804d7b 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
  *                     GPAC - Multimedia Framework C SDK
  *
  *                     Authors: Jean Le Feuvre