Ejemplo n.º 1
0
void V4SceneGraph::GetSceneSize(wxSize &size) 
{
	gf_sg_get_scene_size_info(m_pSg, (u32 *)&(size.x), (u32 *)&(size.y));	
}
Ejemplo n.º 2
0
GF_EXPORT
GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, GF_MediaInfo *info)
{
    GF_Channel *ch;

    if (!term || !odm || !odm->OD || !info) return GF_BAD_PARAM;
    if (!gf_term_check_odm(term, odm)) return GF_BAD_PARAM;

    memset(info, 0, sizeof(GF_MediaInfo));
    info->od = odm->OD;

    info->duration = (Double) (s64)odm->duration;
    info->duration /= 1000;
    if (odm->codec) {
        /*since we don't remove ODs that failed setup, check for clock*/
        if (odm->codec->ck) info->current_time = odm->codec->CB ? odm->current_time : gf_clock_time(odm->codec->ck);
        info->current_time /= 1000;
        info->nb_droped = odm->codec->nb_droped;
    } else if (odm->subscene) {
        if (odm->subscene->scene_codec) {
            if (odm->subscene->scene_codec->ck) {
                info->current_time = gf_clock_time(odm->subscene->scene_codec->ck);
                info->current_time /= 1000;
            }
            info->duration = (Double) (s64)odm->subscene->duration;
            info->duration /= 1000;
            info->nb_droped = odm->subscene->scene_codec->nb_droped;
        } else if (odm->subscene->is_dynamic_scene && odm->subscene->dyn_ck) {
            info->current_time = gf_clock_time(odm->subscene->dyn_ck);
            info->current_time /= 1000;
        }
    }

    info->buffer = -2;
    info->db_unit_count = 0;

    /*Warning: is_open==2 means object setup, don't check then*/
    if (odm->state==GF_ODM_STATE_IN_SETUP) {
        info->status = 3;
    } else if (odm->state==GF_ODM_STATE_BLOCKED) {
        info->status = 0;
        info->protection = 2;
    } else if (odm->state) {
        u32 i, buf;
        GF_Clock *ck;

        ck = gf_odm_get_media_clock(odm);
        /*no clock means setup failed*/
        if (!ck) {
            info->status = 4;
        } else {
            info->status = gf_clock_is_started(ck) ? 1 : 2;
            info->clock_drift = ck->drift;

            info->buffer = -1;
            buf = 0;
            i=0;
            while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) {
                info->db_unit_count += ch->AU_Count;
                if (!ch->is_pulling) {
                    if (ch->MaxBuffer) info->buffer = 0;
                    buf += ch->BufferTime;
                }
                if (ch->is_protected) info->protection = ch->ipmp_tool ? 1 : 2;

            }
            if (buf) info->buffer = (s32) buf;
        }
    }

    info->has_profiles = (odm->flags & GF_ODM_HAS_PROFILES) ? 1 : 0;
    if (info->has_profiles) {
        info->inline_pl = (odm->flags & GF_ODM_INLINE_PROFILES) ? 1 : 0;
        info->OD_pl = odm->OD_PL;
        info->scene_pl = odm->Scene_PL;
        info->audio_pl = odm->Audio_PL;
        info->visual_pl = odm->Visual_PL;
        info->graphics_pl = odm->Graphics_PL;
    }

    if (odm->net_service) {
        info->service_handler = odm->net_service->ifce->module_name;
        info->service_url = odm->net_service->url;
        if (odm->net_service->owner == odm) info->owns_service = 1;
    } else if ((odm->subscene && odm->subscene->graph_attached) || (odm->codec)) {
        info->service_url = "No associated network Service";
    } else {
        info->service_url = "Service not found or error";
    }

    if (odm->codec && odm->codec->decio) {
        if (!odm->codec->decio->GetName) {
            info->codec_name = odm->codec->decio->module_name;
        } else {
            info->codec_name = odm->codec->decio->GetName(odm->codec->decio);
        }
        info->od_type = odm->codec->type;
        if (odm->codec->CB) {
            info->cb_max_count = odm->codec->CB->Capacity;
            info->cb_unit_count = odm->codec->CB->UnitCount;
        }
    }

    if (odm->subscene && odm->subscene->scene_codec) {
        GF_BaseDecoder *dec = odm->subscene->scene_codec->decio;
        assert(odm->subscene->root_od==odm) ;
        info->od_type = odm->subscene->scene_codec->type;
        if (!dec->GetName) {
            info->codec_name = dec->module_name;
        } else {
            info->codec_name = dec->GetName(dec);
        }
        gf_sg_get_scene_size_info(odm->subscene->graph, &info->width, &info->height);
    } else if (odm->mo) {
        switch (info->od_type) {
        case GF_STREAM_VISUAL:
            gf_mo_get_visual_info(odm->mo, &info->width, &info->height, NULL, &info->par, &info->pixelFormat, NULL);
            break;
        case GF_STREAM_AUDIO:
            gf_mo_get_audio_info(odm->mo, &info->sample_rate, &info->bits_per_sample, &info->num_channels, NULL);
            info->clock_drift = 0;
            break;
        case GF_STREAM_TEXT:
            gf_mo_get_visual_info(odm->mo, &info->width, &info->height, NULL, NULL, NULL, NULL);
            break;
        }
    }
    if (odm->subscene && odm->subscene->scene_codec) get_codec_stats(odm->subscene->scene_codec, info);
    else if (odm->codec) get_codec_stats(odm->codec, info);

    ch = (GF_Channel*)gf_list_get(odm->channels, 0);
    if (ch && ch->esd->langDesc) info->lang = ch->esd->langDesc->langCode;

    if (odm->mo && odm->mo->URLs.count)
        info->media_url = odm->mo->URLs.vals[0].url;
    return GF_OK;
}
Ejemplo n.º 3
0
void V4SceneManager::GetSceneSize(wxSize &size) 
{
	gf_sg_get_scene_size_info(m_pIs->graph, (u32 *)&(size.x), (u32 *)&(size.y));	
}
Ejemplo n.º 4
0
Archivo: main.c Proyecto: Bevara/GPAC
void bifs_to_vid(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, char *rad_name, u32 dump_type, char *out_dir, Double fps, s32 frameID, s32 dump_time)
{
	GF_User user;
	BIFSVID b2v;
	u16 es_id;
	Bool first_dump, needs_raw;
	u32 i, j, di, count, timescale, frameNum;
	u32 duration, cur_time;
	GF_VideoSurface fb;
	GF_Err e;
	char old_driv[1024];
	const char *test;
	char config_path[GF_MAX_PATH];
	avi_t *avi_out;
	Bool reset_fps;
	GF_ESD *esd;
	char comp[5];
	char *conv_buf;

	memset(&user, 0, sizeof(GF_User));
	if (szConfigFile && strlen(szConfigFile)) {
		user.config = gf_cfg_init(config_path, NULL);
	} else {
		user.config = gf_cfg_init(NULL, NULL);
	}

	if (!user.config) {
		fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path);
		return;
	}
	avi_out = NULL;
	conv_buf = NULL;
	esd = NULL;
	needs_raw = 0;
	test = gf_cfg_get_key(user.config, "General", "ModulesDirectory");
	user.modules = gf_modules_new((const unsigned char *) test, user.config);
	strcpy(old_driv, "raw_out");
	if (!gf_modules_get_count(user.modules)) {
		printf("Error: no modules found\n");
		goto err_exit;
	}

	/*switch driver to raw_driver*/
	test = gf_cfg_get_key(user.config, "Video", "DriverName");
	if (test) strcpy(old_driv, test);

	test = gf_cfg_get_key(user.config, "Compositor", "RendererName");
	/*since we only support RGB24 for MP42AVI force using RAW out with 2D driver*/
	if (test && strstr(test, "2D")) {
		gf_cfg_set_key(user.config, "Video", "DriverName", "Raw Video Output");
		needs_raw = 1;
	}

	needs_raw = 0;
	user.init_flags = GF_TERM_NO_AUDIO | GF_TERM_FORCE_3D;
	b2v.sr = gf_sc_new(&user, 0, NULL);
	gf_sc_set_option(b2v.sr, GF_OPT_VISIBLE, 0);

	b2v.sg = gf_sg_new();
	gf_sg_set_scene_time_callback(b2v.sg, get_scene_time, &b2v);
	gf_sg_set_init_callback(b2v.sg, node_init, &b2v);
	gf_sg_set_modified_callback(b2v.sg, node_modif, &b2v);

	/*load config*/
	gf_sc_set_option(b2v.sr, GF_OPT_RELOAD_CONFIG, 1);

	b2v.bifs = gf_bifs_decoder_new(b2v.sg, 0);

	if (needs_raw) {
		test = gf_cfg_get_key(user.config, "Video", "DriverName");
		if (stricmp(test, "raw_out") && stricmp(test, "Raw Video Output")) {
			printf("couldn't load raw output driver (%s used)\n", test);
			goto err_exit;
		}
	}

	strcpy(config_path, "");
	if (out_dir) {
		strcat(config_path, out_dir);
		if (config_path[strlen(config_path)-1] != '\\') strcat(config_path, "\\");
	}
	strcat(config_path, rad_name);
	strcat(config_path, "_bifs");
	if (!dump_type) {
		strcat(config_path, ".avi");
		avi_out = AVI_open_output_file(config_path);
		comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0;
		if (!avi_out) goto err_exit;
	}


	for (i=0; i<gf_isom_get_track_count(file); i++) {
		esd = gf_isom_get_esd(file, i+1, 1);
		if (!esd) continue;
		if (!esd->dependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break;
		gf_odf_desc_del((GF_Descriptor *) esd);
		esd = NULL;
	}
	if (!esd) {
		printf("no bifs track found\n");
		goto err_exit;
	}

	b2v.duration = gf_isom_get_media_duration(file, i+1);
	timescale = gf_isom_get_media_timescale(file, i+1);
	es_id = (u16) gf_isom_get_track_id(file, i+1);
	e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication);
	if (e) {
		printf("BIFS init error %s\n", gf_error_to_string(e));
		gf_odf_desc_del((GF_Descriptor *) esd);
		esd = NULL;
		goto err_exit;
	}
	if (dump_time>=0) dump_time = dump_time *1000 / timescale;

	gf_sc_set_scene(b2v.sr, b2v.sg);
	count = gf_isom_get_sample_count(file, i+1);

	reset_fps = 0;
	if (!fps) {
		fps = (Float) (count * timescale);
		fps /= (Double) (s64) b2v.duration;
		printf("Estimated BIFS FrameRate %g\n", fps);
		reset_fps = 1;
	}

	if (!width || !height) {
		gf_sg_get_scene_size_info(b2v.sg, &width, &height);
	}
	/*we work in RGB24, and we must make sure the pitch is %4*/
	if ((width*3)%4) {
		printf("Adjusting width (%d) to have a stride multiple of 4\n", width);
		while ((width*3)%4) width--;
	}

	gf_sc_set_size(b2v.sr, width, height);
	gf_sc_draw_frame(b2v.sr);

	gf_sc_get_screen_buffer(b2v.sr, &fb);
	width = fb.width;
	height = fb.height;
	if (avi_out) {
		AVI_set_video(avi_out, width, height, fps, comp);
		conv_buf = gf_malloc(sizeof(char) * width * height * 3);
	}
	printf("Dumping at BIFS resolution %d x %d\n\n", width, height);
	gf_sc_release_screen_buffer(b2v.sr, &fb);

	cur_time = 0;

	duration = (u32)(timescale / fps);
	if (reset_fps) fps = 0;

	frameNum = 1;
	first_dump = 1;
	for (j=0; j<count; j++) {
		GF_ISOSample *samp = gf_isom_get_sample(file, i+1, j+1, &di);

		b2v.cts = samp->DTS + samp->CTS_Offset;
		/*apply command*/
		gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0);
		gf_isom_sample_del(&samp);

		if ((frameID>=0) && (j<(u32)frameID)) continue;
		if ((dump_time>=0) && ((u32) dump_time>b2v.cts)) continue;
		/*render frame*/
		gf_sc_draw_frame(b2v.sr);
		/*needed for background2D !!*/
		if (first_dump) {
			gf_sc_draw_frame(b2v.sr);
			first_dump = 0;
		}

		if (fps) {
			if (cur_time > b2v.cts) continue;

			while (1) {
				printf("dumped frame time %f (frame %d - sample %d)\r", ((Float)cur_time)/timescale, frameNum, j+1);
				dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, frameNum);
				frameNum++;
				cur_time += duration;
				if (cur_time > b2v.cts) break;
			}
		} else {
			dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, (frameID>=0) ? frameID : frameNum);
			if (frameID>=0 || dump_time>=0) break;
			frameNum++;
			printf("dumped frame %d / %d\r", j+1, count);
		}

	}
	gf_odf_desc_del((GF_Descriptor *) esd);

	/*destroy everything*/
	gf_bifs_decoder_del(b2v.bifs);
	gf_sg_del(b2v.sg);
	gf_sc_set_scene(b2v.sr, NULL);
	gf_sc_del(b2v.sr);

err_exit:
	if (avi_out) AVI_close(avi_out);
	if (conv_buf) gf_free(conv_buf);
	if (user.modules) gf_modules_del(user.modules);
	if (needs_raw) gf_cfg_set_key(user.config, "Video", "DriverName", old_driv);
	gf_cfg_del(user.config);
}
Ejemplo n.º 5
0
Archivo: main.c Proyecto: Bevara/GPAC
/*generates an intertwined bmp from a scene file with 5 different viewpoints*/
void bifs3d_viewpoints_merger(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, char *rad_name, u32 dump_type, char *out_dir, Double fps, s32 frameID, s32 dump_time)
{
	GF_User user;
	char out_path[GF_MAX_PATH];
	char old_driv[1024];
	BIFSVID b2v;
	Bool needs_raw;
	GF_Err e;
	GF_VideoSurface fb;
	unsigned char **rendered_frames;
	u32 nb_viewpoints = 5;
	u32 viewpoint_index;


	/* Configuration of the Rendering Capabilities */
	{
		const char *test;
		char config_path[GF_MAX_PATH];
		memset(&user, 0, sizeof(GF_User));
		user.config = gf_cfg_init(szConfigFile, NULL);

		if (!user.config) {
			fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path);
			return;
		}

		test = gf_cfg_get_key(user.config, "General", "ModulesDirectory");
		user.modules = gf_modules_new((const unsigned char *) test, user.config);
		strcpy(old_driv, "raw_out");
		if (!gf_modules_get_count(user.modules)) {
			printf("Error: no modules found\n");
			goto err_exit;
		}

		/*switch driver to raw_driver*/
		test = gf_cfg_get_key(user.config, "Video", "DriverName");
		if (test) strcpy(old_driv, test);

		needs_raw = 0;
		test = gf_cfg_get_key(user.config, "Compositor", "RendererName");
		/*since we only support RGB24 for MP42AVI force using RAW out with 2D driver*/
		if (test && strstr(test, "2D")) {
			gf_cfg_set_key(user.config, "Video", "DriverName", "Raw Video Output");
			needs_raw = 1;
		}
		if (needs_raw) {
			test = gf_cfg_get_key(user.config, "Video", "DriverName");
			if (stricmp(test, "raw_out") && stricmp(test, "Raw Video Output")) {
				printf("couldn't load raw output driver (%s used)\n", test);
				goto err_exit;
			}
		}
	}

	memset(&b2v, 0, sizeof(BIFSVID));
	user.init_flags = GF_TERM_NO_AUDIO;
	/* Initialization of the compositor */
	b2v.sr = gf_sc_new(&user, 0, NULL);
	gf_sc_set_option(b2v.sr, GF_OPT_VISIBLE, 0);

	/* Initialization of the scene graph */
	b2v.sg = gf_sg_new();
	gf_sg_set_scene_time_callback(b2v.sg, get_scene_time, &b2v);
	gf_sg_set_init_callback(b2v.sg, node_init, &b2v);
	gf_sg_set_modified_callback(b2v.sg, node_modif, &b2v);

	/*load config*/
	gf_sc_set_option(b2v.sr, GF_OPT_RELOAD_CONFIG, 1);

	{
		u32 di;
		u32 track_number;
		GF_ESD *esd;
		u16 es_id;
		b2v.bifs = gf_bifs_decoder_new(b2v.sg, 0);

		for (track_number=0; track_number<gf_isom_get_track_count(file); track_number++) {
			esd = gf_isom_get_esd(file, track_number+1, 1);
			if (!esd) continue;
			if (!esd->dependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break;
			gf_odf_desc_del((GF_Descriptor *) esd);
			esd = NULL;
		}
		if (!esd) {
			printf("no bifs track found\n");
			goto err_exit;
		}

		es_id = (u16) gf_isom_get_track_id(file, track_number+1);
		e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication);
		if (e) {
			printf("BIFS init error %s\n", gf_error_to_string(e));
			gf_odf_desc_del((GF_Descriptor *) esd);
			esd = NULL;
			goto err_exit;
		}

		{
			GF_ISOSample *samp = gf_isom_get_sample(file, track_number+1, 1, &di);
			b2v.cts = samp->DTS + samp->CTS_Offset;
			/*apply command*/
			gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0);
			gf_isom_sample_del(&samp);
		}

		b2v.duration = gf_isom_get_media_duration(file, track_number+1);

		gf_odf_desc_del((GF_Descriptor *) esd);

	}
	gf_sc_set_scene(b2v.sr, b2v.sg);

	if (!width || !height) {
		gf_sg_get_scene_size_info(b2v.sg, &width, &height);
	}
	/*we work in RGB24, and we must make sure the pitch is %4*/
	if ((width*3)%4) {
		printf("Adjusting width (%d) to have a stride multiple of 4\n", width);
		while ((width*3)%4) width--;
	}
	gf_sc_set_size(b2v.sr, width, height);
	gf_sc_get_screen_buffer(b2v.sr, &fb);
	width = fb.width;
	height = fb.height;
	gf_sc_release_screen_buffer(b2v.sr, &fb);

	GF_SAFEALLOC(rendered_frames, nb_viewpoints*sizeof(char *));
	for (viewpoint_index = 1; viewpoint_index <= nb_viewpoints; viewpoint_index++) {
		GF_SAFEALLOC(rendered_frames[viewpoint_index-1], fb.width*fb.height*3);
		gf_sc_set_viewpoint(b2v.sr, viewpoint_index, NULL);
		gf_sc_draw_frame(b2v.sr);
		/*needed for background2D !!*/
		gf_sc_draw_frame(b2v.sr);
		strcpy(out_path, "");
		if (out_dir) {
			strcat(out_path, out_dir);
			if (out_path[strlen(out_path)-1] != '\\') strcat(out_path, "\\");
		}
		strcat(out_path, rad_name);
		strcat(out_path, "_view");
		gf_sc_get_screen_buffer(b2v.sr, &fb);
		write_bmp(&fb, out_path, viewpoint_index);
		memcpy(rendered_frames[viewpoint_index-1], fb.video_buffer, fb.width*fb.height*3);
		gf_sc_release_screen_buffer(b2v.sr, &fb);
	}

	if (width != 800 || height != 480) {
		printf("Wrong scene dimension, cannot produce output\n");
		goto err_exit;
	} else {
		u32 x, y;
		GF_VideoSurface out_fb;
		u32 bpp = 3;
		out_fb.width = 800;
		out_fb.height = 480;
		out_fb.pitch = 800*bpp;
		out_fb.pixel_format = GF_PIXEL_RGB_24;
		out_fb.is_hardware_memory = 0;
		GF_SAFEALLOC(out_fb.video_buffer, out_fb.pitch*out_fb.height)
#if 1
		for (y=0; y<out_fb.height; y++) {
			/*starting red pixel is R1, R5, R4, R3, R2, R1, R5, ... when increasing line num*/
			u32 line_shift = (5-y) % 5;
			for (x=0; x<out_fb.width; x++) {
				u32 view_shift = (line_shift+bpp*x)%5;
				u32 offset = out_fb.pitch*y + x*bpp;
				/* red */
				out_fb.video_buffer[offset] = rendered_frames[view_shift][offset];
				/* green */
				out_fb.video_buffer[offset+1] = rendered_frames[(view_shift+1)%5][offset+1];
				/* blue */
				out_fb.video_buffer[offset+2] = rendered_frames[(view_shift+2)%5][offset+2];
			}
		}
#else
		/*calibration*/
		for (y=0; y<out_fb.height; y++) {
			u32 line_shift = (5- y%5) % 5;
			for (x=0; x<out_fb.width; x++) {
				u32 view_shift = (line_shift+bpp*x)%5;
				u32 offset = out_fb.pitch*y + x*bpp;
				out_fb.video_buffer[offset] = ((view_shift)%5 == 2) ? 0xFF : 0;
				out_fb.video_buffer[offset+1] = ((view_shift+1)%5 == 2) ? 0xFF : 0;
				out_fb.video_buffer[offset+2] = ((view_shift+2)%5 == 2) ? 0xFF : 0;
			}
		}
#endif
		write_bmp(&out_fb, "output", 0);
	}

	/*destroy everything*/
	gf_bifs_decoder_del(b2v.bifs);
	gf_sg_del(b2v.sg);
	gf_sc_set_scene(b2v.sr, NULL);
	gf_sc_del(b2v.sr);



err_exit:
	/*	if (rendered_frames) {
			for (viewpoint_index = 1; viewpoint_index <= nb_viewpoints; viewpoint_index++) {
				if (rendered_frames[viewpoint_index-1]) gf_free(rendered_frames[viewpoint_index-1]);
			}
			gf_free(rendered_frames);
		}
		if (output_merged_frame) gf_free(output_merged_frame);
	*/
	if (user.modules) gf_modules_del(user.modules);
	if (needs_raw) gf_cfg_set_key(user.config, "Video", "DriverName", old_driv);
	gf_cfg_del(user.config);
}
Ejemplo n.º 6
0
/*the WORST thing about 3GP in MPEG4 is positioning of the text track...*/
static void TTD_UpdateSizeInfo(TTDPriv *priv)
{
	u32 w, h;
	Bool has_size;
	s32 offset, thw, thh, vw, vh;

	has_size = gf_sg_get_scene_size_info(priv->inlineScene->graph, &w, &h);
	/*no size info is given in main scene, override by associated video size if any, or by text track size*/
	if (!has_size) {
		if (priv->cfg->has_vid_info && priv->cfg->video_width && priv->cfg->video_height) {
			gf_sg_set_scene_size_info(priv->sg, priv->cfg->video_width, priv->cfg->video_height, 1);
		} else {
			gf_sg_set_scene_size_info(priv->sg, priv->cfg->text_width, priv->cfg->text_height, 1);
		}
		gf_sg_get_scene_size_info(priv->sg, &w, &h);
		if (!w || !h) return;
		gf_scene_force_size(priv->inlineScene, w, h);
	}

	if (!w || !h) return;
	/*apply*/
	gf_sg_set_scene_size_info(priv->sg, w, h, 1);
	/*make sure the scene size is big enough to contain the text track after positioning. RESULTS ARE UNDEFINED
	if offsets are negative: since MPEG-4 uses centered coord system, we must assume video is aligned to top-left*/
	if (priv->cfg->has_vid_info) {
		Bool set_size = 0;
		vw = priv->cfg->horiz_offset; if (vw<0) vw = 0;
		vh = priv->cfg->vert_offset; if (vh<0) vh = 0;
		if (priv->cfg->text_width + (u32) vw > w) {
			w = priv->cfg->text_width+vw;
			set_size = 1;
		}
		if (priv->cfg->text_height + (u32) vh > h) {
			h = priv->cfg->text_height+vh;
			set_size = 1;
		}
		if (set_size) {
			gf_sg_set_scene_size_info(priv->sg, w, h, 1);
			gf_scene_force_size(priv->inlineScene, w, h);
		}
	} else {
		/*otherwise override (mainly used for SRT & TTXT file direct loading*/
		priv->cfg->text_width = w;
		priv->cfg->text_height = h;
	}

	/*ok override video size with main scene size*/
	priv->cfg->video_width = w;
	priv->cfg->video_height = h;

	vw = (s32) w;
	vh = (s32) h;
	thw = priv->cfg->text_width / 2;
	thh = priv->cfg->text_height / 2;
	/*check translation, we must not get out of scene size - not supported in GPAC*/
	offset = priv->cfg->horiz_offset - vw/2 + thw;
	/*safety checks ?
	if (offset + thw < - vw/2) offset = - vw/2 + thw;
	else if (offset - thw > vw/2) offset = vw/2 - thw;
	*/
	priv->tr_track->translation.x = INT2FIX(offset);

	offset = vh/2 - priv->cfg->vert_offset - thh;
	/*safety checks ?
	if (offset + thh > vh/2) offset = vh/2 - thh;
	else if (offset - thh < -vh/2) offset = -vh/2 + thh;
	*/
	priv->tr_track->translation.y = INT2FIX(offset);

	gf_node_changed((GF_Node *)priv->tr_track, NULL);
}
Ejemplo n.º 7
0
GF_Err gf_sr_set_scene(GF_Renderer *sr, GF_SceneGraph *scene_graph)
{
	u32 width, height;
	Bool do_notif;

	if (!sr) return GF_BAD_PARAM;

	gf_sr_lock(sr, 1);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, (scene_graph ? "[Render] Attaching new scene\n" : "[Render] Detaching scene\n"));

	if (sr->audio_renderer && (sr->scene != scene_graph)) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting audio render\n"));
		gf_sr_ar_reset(sr->audio_renderer);
	}

#ifdef GF_SR_EVENT_QUEUE
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting event queue\n"));
	gf_mx_p(sr->ev_mx);
	while (gf_list_count(sr->events)) {
		GF_Event *ev = (GF_Event*)gf_list_get(sr->events, 0);
		gf_list_rem(sr->events, 0);
		free(ev);
	}
#endif
	
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting render module\n"));
	/*reset main surface*/
	sr->visual_renderer->SceneReset(sr->visual_renderer);

	/*set current graph*/
	sr->scene = scene_graph;
	do_notif = 0;
	if (scene_graph) {
#ifndef GPAC_DISABLE_SVG
		SVG_Length *w, *h;
#endif
		const char *opt;
		Bool is_svg = 0;
		u32 tag;
		GF_Node *top_node;
		Bool had_size_info = sr->has_size_info;
		/*get pixel size if any*/
		gf_sg_get_scene_size_info(sr->scene, &width, &height);
		sr->has_size_info = (width && height) ? 1 : 0;
		if (sr->has_size_info != had_size_info) sr->scene_width = sr->scene_height = 0;

		/*default back color is black*/
		if (! (sr->user->init_flags & GF_TERM_WINDOWLESS)) sr->back_color = 0xFF000000;

		top_node = gf_sg_get_root_node(sr->scene);
		tag = 0;
		if (top_node) tag = gf_node_get_tag(top_node);

#ifndef GPAC_DISABLE_SVG
		w = h = NULL;
		if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {
			GF_FieldInfo info;
			is_svg = 1;
			if (gf_svg_get_attribute_by_tag(top_node, TAG_SVG_ATT_width, 0, 0, &info)==GF_OK) 
				w = info.far_ptr;
			if (gf_svg_get_attribute_by_tag(top_node, TAG_SVG_ATT_height, 0, 0, &info)==GF_OK) 
				h = info.far_ptr;
		}
#ifdef GPAC_ENABLE_SVG_SA
		else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) {
			SVG_SA_svgElement *root = (SVG_SA_svgElement *) top_node;
			is_svg = 1;
			w = &root->width;
			h = &root->height;
		}
#endif
#ifdef GPAC_ENABLE_SVG_SANI
		else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) {
			SVG_SANI_svgElement *root = (SVG_SANI_svgElement*) top_node;
			is_svg = 1;
			w = &root->width;
			h = &root->height;
		}
#endif
		/*default back color is white*/
		if (is_svg && ! (sr->user->init_flags & GF_TERM_WINDOWLESS)) sr->back_color = 0xFFFFFFFF;

		/*hack for SVG where size is set in %*/
		if (!sr->has_size_info && w && h) {
			sr->has_size_info = 1;
			sr->aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN;
			if (w->type!=SVG_NUMBER_PERCENTAGE) {
				width = FIX2INT(convert_svg_length_to_user(sr, w) );
			} else {
				width = 320; //FIX2INT(root->viewBox.width);
			}
			if (h->type!=SVG_NUMBER_PERCENTAGE) {
				height = FIX2INT(convert_svg_length_to_user(sr, h) );
			} else {
				height = 240; //FIX2INT(root->viewBox.height);
			}
		}
#endif
		/*default back color is key color*/
		if (sr->user->init_flags & GF_TERM_WINDOWLESS) {
			opt = gf_cfg_get_key(sr->user->config, "Rendering", "ColorKey");
			if (opt) {
				u32 r, g, b, a;
				sscanf(opt, "%02X%02X%02X%02X", &a, &r, &g, &b);
				sr->back_color = GF_COL_ARGB(0xFF, r, g, b);
			}
		}

		/*set scene size only if different, otherwise keep scaling/FS*/
		if ( !width || (sr->scene_width!=width) || !height || (sr->scene_height!=height)) {
			do_notif = sr->has_size_info || (!sr->scene_width && !sr->scene_height);
			SR_SetSceneSize(sr, width, height);

			/*get actual size in pixels*/
			width = sr->scene_width;
			height = sr->scene_height;

			if (!sr->user->os_window_handler) {
				/*only notify user if we are attached to a window*/
				do_notif = 0;
				if (sr->video_out->max_screen_width && (width > sr->video_out->max_screen_width))
					width = sr->video_out->max_screen_width;
				if (sr->video_out->max_screen_height && (height > sr->video_out->max_screen_height))
					height = sr->video_out->max_screen_height;

				gf_sr_set_size(sr,width, height);
			}
		}
	}

	SR_ResetFrameRate(sr);	
#ifdef GF_SR_EVENT_QUEUE
	gf_mx_v(sr->ev_mx);
#endif
	
	gf_sr_lock(sr, 0);
	/*here's a nasty trick: the app may respond to this by calling a gf_sr_set_size from a different
	thread, but in an atomic way (typically happen on Win32 when changing the window size). WE MUST
	NOTIFY THE SIZE CHANGE AFTER RELEASING THE RENDERER MUTEX*/
	if (do_notif && sr->user->EventProc) {
		GF_Event evt;
		evt.type = GF_EVENT_SCENE_SIZE;
		evt.size.width = width;
		evt.size.height = height;
		sr->user->EventProc(sr->user->opaque, &evt);
	}
	if (scene_graph)
		sr->draw_next_frame = 1;
	return GF_OK;
}