static void setup_texture_object(GF_TextureHandler *txh, Bool private_media) { if (!txh->tx_io) { gf_sc_texture_allocate(txh); if (!txh->tx_io) return; gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat, &txh->is_flipped); if (private_media) { txh->transparent = 1; txh->pixelformat = GF_PIXEL_ARGB; txh->flags |= GF_SR_TEXTURE_PRIVATE_MEDIA; } else { txh->transparent = 0; switch (txh->pixelformat) { case GF_PIXEL_ALPHAGREY: case GF_PIXEL_ARGB: case GF_PIXEL_RGBA: case GF_PIXEL_YUVA: case GF_PIXEL_RGBDS: txh->transparent = 1; break; } } gf_mo_set_flag(txh->stream, GF_MO_IS_INIT, 1); } }
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; }
void visual_2d_texture_path_extended(GF_VisualManager *visual, GF_Path *path, GF_TextureHandler *txh, struct _drawable_context *ctx, GF_Rect *orig_bounds, GF_Matrix2D *ext_mx, GF_TraverseState *tr_state) { Fixed sS, sT; u32 tx_tile; GF_STENCIL tx_raster; GF_Matrix2D mx_texture; GF_Rect orig_rc; GF_Raster2D *raster; if (! visual->CheckAttached(visual) ) return; raster = visual->compositor->rasterizer; if (!txh) txh = ctx->aspect.fill_texture; if (!txh) return; if (!txh->tx_io) { gf_node_dirty_set(txh->owner, 0, 1); txh->needs_refresh=1; return; } /*this is gradient draw*/ if (txh->compute_gradient_matrix) { visual_2d_draw_gradient(visual, path, txh, ctx, tr_state, ext_mx, orig_bounds); return; } #ifndef GPAC_DISABLE_3D if (visual->compositor->hybrid_opengl) { visual_2d_texture_path_opengl_auto(visual, path, txh, ctx, orig_bounds, ext_mx, tr_state); return; } #endif if (txh->flags & GF_SR_TEXTURE_PRIVATE_MEDIA) { GF_Window src, dst; visual_2d_fill_path(visual, ctx, NULL, tr_state, 0); /*if texture not ready, update the size before computing output rectangles */ if (!txh->width || !txh->height) { gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat, &txh->is_flipped); /*in case the node is an MPEG-4 bitmap, force stack rebuild at next frame */ gf_node_dirty_set(ctx->drawable->node, GF_SG_NODE_DIRTY, 1); } if (compositor_texture_rectangles(visual, txh, &ctx->bi->clip, &ctx->bi->unclip, &src, &dst, NULL, NULL)) { if (txh->stream && gf_mo_set_position(txh->stream, &src, &dst)) { gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat, &txh->is_flipped); /*force dirty flag to get called again*/ gf_node_dirty_set(ctx->drawable->node, GF_SG_NODE_DIRTY, 1); gf_sc_next_frame_state(visual->compositor, GF_SC_DRAW_FRAME); } } return; } if (!gf_sc_texture_push_image(txh, 0, 1)) return; tx_raster = gf_sc_texture_get_stencil(txh); /*setup quality even for background (since quality concerns images)*/ visual_2d_set_options(visual->compositor, visual->raster_surface, ctx->flags & CTX_IS_TEXT, ctx->flags & CTX_NO_ANTIALIAS); /*get original bounds*/ if (orig_bounds) { orig_rc = *orig_bounds; } else { gf_path_get_bounds(path, &orig_rc); } /*get scaling ratio so that active texture view is stretched to original bounds (std 2D shape texture mapping in MPEG4)*/ sS = orig_rc.width / txh->width; sT = orig_rc.height / txh->height; gf_mx2d_init(mx_texture); gf_mx2d_add_scale(&mx_texture, sS, sT); #ifndef GPAC_DISABLE_VRML /*apply texture transform*/ if (ctx->flags & CTX_HAS_APPEARANCE) { GF_Matrix2D tex_trans; visual_2d_get_texture_transform(ctx->appear, txh, &tex_trans, (txh == ctx->aspect.fill_texture) ? 0 : 1, txh->width * sS, txh->height * sT); gf_mx2d_add_matrix(&mx_texture, &tex_trans); } #endif /*move to bottom-left corner of bounds */ gf_mx2d_add_translation(&mx_texture, (orig_rc.x), (orig_rc.y - orig_rc.height)); if (ext_mx) gf_mx2d_add_matrix(&mx_texture, ext_mx); /*move to final coordinate system (except background which is built directly in final coord system)*/ if (!(ctx->flags & CTX_IS_BACKGROUND) ) gf_mx2d_add_matrix(&mx_texture, &ctx->transform); /*set path transform*/ raster->stencil_set_matrix(tx_raster, &mx_texture); tx_tile = 0; if (txh->flags & GF_SR_TEXTURE_REPEAT_S) tx_tile |= GF_TEXTURE_REPEAT_S; if (txh->flags & GF_SR_TEXTURE_REPEAT_T) tx_tile |= GF_TEXTURE_REPEAT_T; if (ctx->flags & CTX_FLIPED_COORDS) tx_tile |= GF_TEXTURE_FLIP; raster->stencil_set_tiling(tx_raster, (GF_TextureTiling) tx_tile); if (!(ctx->flags & CTX_IS_BACKGROUND) ) { u8 a = GF_COL_A(ctx->aspect.fill_color); if (!a) a = GF_COL_A(ctx->aspect.line_color); /*texture alpha scale is the original material transparency, NOT the one after color transform*/ raster->stencil_set_alpha(tx_raster, a ); raster->stencil_set_color_matrix(tx_raster, ctx->col_mat); raster->surface_set_matrix(visual->raster_surface, &ctx->transform); } else { raster->surface_set_matrix(visual->raster_surface, NULL); } txh->flags |= GF_SR_TEXTURE_USED; /*push path & draw*/ raster->surface_set_path(visual->raster_surface, path); visual_2d_fill_path(visual, ctx, tx_raster, tr_state, 0); raster->surface_set_path(visual->raster_surface, NULL); ctx->flags |= CTX_PATH_FILLED; }