📄 lsr_dec.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Authors: Jean le Feuvre * Copyright (c) 2005-200X ENST * All rights reserved * * This file is part of GPAC / LASeR codec sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <gpac/internal/laser_dev.h>#include <gpac/internal/scenegraph_dev.h>#include <gpac/bitstream.h>#include <gpac/math.h>#include <gpac/events.h>#define GF_LSR_READ_INT(_codec, _val, _nbBits, _str) {\ (_val) = gf_bs_read_int(_codec->bs, _nbBits); \ GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", _str, _nbBits, _val)); \ }\static void lsr_read_group_content(GF_LASeRCodec *lsr, GF_Node *elt, Bool skip_object_content);static void lsr_read_group_content_post_init(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_init);static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *comList, SVG_Element *cond, Bool first_imp);static GF_Err lsr_decode_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list);static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_PathData *path, const char *name);static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char *name);static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Element *anim_parent);GF_EXPORTGF_LASeRCodec *gf_laser_decoder_new(GF_SceneGraph *graph){ GF_LASeRCodec *tmp; GF_SAFEALLOC(tmp, GF_LASeRCodec); if (!tmp) return NULL; tmp->streamInfo = gf_list_new(); tmp->font_table = gf_list_new(); tmp->defered_hrefs = gf_list_new(); tmp->defered_listeners = gf_list_new(); tmp->defered_anims = gf_list_new(); tmp->unresolved_commands = gf_list_new(); tmp->sg = graph; return tmp;}GF_EXPORTvoid gf_laser_decoder_del(GF_LASeRCodec *codec){ /*destroy all config*/ while (gf_list_count(codec->streamInfo)) { LASeRStreamInfo *p = (LASeRStreamInfo *)gf_list_last(codec->streamInfo); free(p); gf_list_rem_last(codec->streamInfo); } gf_list_del(codec->streamInfo); if (codec->col_table) free(codec->col_table); while (gf_list_count(codec->font_table)) { char *ft = (char *)gf_list_last(codec->font_table); free(ft); gf_list_rem_last(codec->font_table); } gf_list_del(codec->font_table);#if 0 while (gf_list_count(codec->defered_hrefs)) { XMLRI *iri = (XMLRI *)gf_list_last(codec->defered_hrefs); gf_list_rem_last(codec->defered_hrefs); if (iri->string) free(iri->string); iri->string = NULL; }#endif gf_list_del(codec->defered_hrefs); gf_list_del(codec->defered_anims); gf_list_del(codec->defered_listeners); gf_list_del(codec->unresolved_commands); free(codec);}static LASeRStreamInfo *lsr_get_stream(GF_LASeRCodec *codec, u16 ESID){ u32 i=0; LASeRStreamInfo *ptr; while ((ptr = (LASeRStreamInfo *)gf_list_enum(codec->streamInfo, &i))) { if (!ESID || (ptr->ESID==ESID)) return ptr; } return NULL;}GF_EXPORTGF_Err gf_laser_decoder_configure_stream(GF_LASeRCodec *codec, u16 ESID, char *dsi, u32 dsi_len){ LASeRStreamInfo *info; GF_BitStream *bs; if (lsr_get_stream(codec, ESID) != NULL) return GF_BAD_PARAM; GF_SAFEALLOC(info, LASeRStreamInfo); info->ESID = ESID; bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ); info->cfg.profile = gf_bs_read_int(bs, 8); info->cfg.level = gf_bs_read_int(bs, 8); /*info->cfg.reserved = */ gf_bs_read_int(bs, 3); info->cfg.pointsCodec = gf_bs_read_int(bs, 2); info->cfg.pathComponents = gf_bs_read_int(bs, 4); info->cfg.fullRequestHost = gf_bs_read_int(bs, 1); if (gf_bs_read_int(bs, 1)) { info->cfg.time_resolution = gf_bs_read_int(bs, 16); } else { info->cfg.time_resolution = 1000; } info->cfg.colorComponentBits = gf_bs_read_int(bs, 4); info->cfg.colorComponentBits += 1; info->cfg.resolution = gf_bs_read_int(bs, 4); if (info->cfg.resolution>7) info->cfg.resolution -= 16; info->cfg.coord_bits = gf_bs_read_int(bs, 5); info->cfg.scale_bits_minus_coord_bits = gf_bs_read_int(bs, 4); info->cfg.newSceneIndicator = gf_bs_read_int(bs, 1); /*reserved*/ gf_bs_read_int(bs, 3); info->cfg.extensionIDBits = gf_bs_read_int(bs, 4); /*we ignore the rest*/ gf_list_add(codec->streamInfo, info); gf_bs_del(bs); return GF_OK;}GF_EXPORTGF_Err gf_laser_decoder_remove_stream(GF_LASeRCodec *codec, u16 ESID){ u32 i, count; count = gf_list_count(codec->streamInfo); for (i=0;i<count;i++) { LASeRStreamInfo *ptr = (LASeRStreamInfo *) gf_list_get(codec->streamInfo, i); if (ptr->ESID==ESID) { free(ptr); gf_list_rem(codec->streamInfo, i); return GF_OK; } } return GF_BAD_PARAM;}GF_EXPORTGF_Err gf_laser_decode_au(GF_LASeRCodec *codec, u16 ESID, char *data, u32 data_len){ GF_Err e; if (!codec || !data || !data_len) return GF_BAD_PARAM; codec->info = lsr_get_stream(codec, ESID); if (!codec->info) return GF_BAD_PARAM; codec->coord_bits = codec->info->cfg.coord_bits; codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits; codec->time_resolution = codec->info->cfg.time_resolution; codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution >= 0) codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution); else codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) ); codec->bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ); codec->memory_dec = 0; e = lsr_decode_laser_unit(codec, NULL); gf_bs_del(codec->bs); codec->bs = NULL; return e;}GF_Err gf_laser_decode_command_list(GF_LASeRCodec *codec, u16 ESID, char *data, u32 data_len, GF_List *com_list){ GF_Err e; u32 i; if (!codec || !data || !data_len) return GF_BAD_PARAM; codec->info = lsr_get_stream(codec, ESID); if (!codec->info) return GF_BAD_PARAM; codec->coord_bits = codec->info->cfg.coord_bits; codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits; codec->time_resolution = codec->info->cfg.time_resolution; codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution >= 0) codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution); else codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) ); codec->bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ); codec->memory_dec = 1; e = lsr_decode_laser_unit(codec, com_list); gf_bs_del(codec->bs); codec->bs = NULL; if (e) return e; for (i=0; i<gf_list_count(codec->unresolved_commands); i++) { GF_Command *com = (GF_Command *)gf_list_get(codec->unresolved_commands, i); assert(!com->node); com->node = gf_sg_find_node(codec->sg, com->RouteID); if (com->node) { gf_node_register(com->node, NULL); com->RouteID = 0; gf_list_rem(codec->unresolved_commands, i); i--; } } return GF_OK;}GF_EXPORTvoid gf_laser_decoder_set_clock(GF_LASeRCodec *codec, Double (*GetSceneTime)(void *st_cbk), void *st_cbk ){ codec->GetSceneTime = GetSceneTime; codec->cbk = st_cbk;}static u32 lsr_read_vluimsbf5(GF_LASeRCodec *lsr, const char *name){ u32 nb_words = 0; u32 nb_tot, nb_bits, val; while (gf_bs_read_int(lsr->bs, 1)) nb_words++; nb_words++; nb_tot = nb_words; nb_bits = nb_words*4; nb_tot += nb_bits; val = gf_bs_read_int(lsr->bs, nb_bits); if (name) GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val)); return val;}static u32 lsr_read_vluimsbf8(GF_LASeRCodec *lsr, const char *name){ u32 nb_words = 0; u32 nb_tot, nb_bits, val; while (gf_bs_read_int(lsr->bs, 1)) nb_words++; nb_words++; nb_tot = nb_words; nb_bits = nb_words*7; nb_tot += nb_bits; val = gf_bs_read_int(lsr->bs, nb_bits); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val)); return val;}static void lsr_read_extension(GF_LASeRCodec *lsr, const char *name){ u32 len = lsr_read_vluimsbf5(lsr, name);#if 0 *out_data = malloc(sizeof(char)*len); gf_bs_read_data(lsr->bs, *out_data, len); *out_len = len;#else while (len) { gf_bs_read_int(lsr->bs, 8); len--; }#endif}static void lsr_read_extend_class(GF_LASeRCodec *lsr, char **out_data, u32 *out_len, const char *name){ u32 len; GF_LSR_READ_INT(lsr, len, lsr->info->cfg.extensionIDBits, "reserved"); len = lsr_read_vluimsbf5(lsr, "len");// while (len) gf_bs_read_int(lsr->bs, 1); gf_bs_read_long_int(lsr->bs, len); if (out_data) *out_data = NULL; if (out_len) *out_len = 0;}static void lsr_read_private_element_container(GF_LASeRCodec *lsr){ u32 val, len; GF_LSR_READ_INT(lsr, val, 4, "ch4"); switch (val) { /*privateAnyXMLElement*/ case 0: len = lsr_read_vluimsbf5(lsr, "len"); gf_bs_skip_bytes(lsr->bs, len); break; /*privateOpaqueElement*/ case 1: len = lsr_read_vluimsbf5(lsr, "len"); gf_bs_skip_bytes(lsr->bs, len); break; /*element_any*/ case 2: lsr_read_extend_class(lsr, NULL, 0, "reserved"); break; /*attr_custom_extension*/ default: len = lsr_read_vluimsbf5(lsr, "len"); gf_bs_skip_bytes(lsr->bs, len); break; }}static void lsr_read_private_attribute_container(GF_LASeRCodec *lsr){ u32 val; do { u32 skip_len; GF_LSR_READ_INT(lsr, val, 2, "privateDataType"); skip_len = lsr_read_vluimsbf5(lsr, "skipLen"); gf_bs_align(lsr->bs); /*just skip data*/#if 1 if (skip_len>gf_bs_available(lsr->bs)) { lsr->last_error = GF_NON_COMPLIANT_BITSTREAM; return; } gf_bs_skip_bytes(lsr->bs, skip_len);#else switch (val) { /*private data of type "anyXML"*/ case 0: count = lsr_read_vluimsbf5(lsr, "count"); for (i=0; i<count; i++) { privateAttribute(0) attr[i]; } break; case 1: /*TODO FIXME - nameSpaceIndexBits is not defined in the spec*/ uint(nameSpaceIndexBits) nameSpaceIndex; gf_bs_align(lsr->bs); byte[skipLen - ((nameSpaceIndexBits+7)%8)] data; break; default: /*TODO - spec is wrong here (typo, "len" instead of "skipLen" )*/ gf_bs_skip_bytes(skipLen); break; }#endif gf_bs_align(lsr->bs); GF_LSR_READ_INT(lsr, val, 1, "hasMorePrivateData"); } while (val);}static void lsr_read_any_attribute(GF_LASeRCodec *lsr, GF_Node *node, Bool skippable){ u32 val = 1; if (skippable) GF_LSR_READ_INT(lsr, val, 1, "has_attrs"); if (val) { do { GF_LSR_READ_INT(lsr, val, lsr->info->cfg.extensionIDBits, "reserved"); val = lsr_read_vluimsbf5(lsr, "len");//len in BITS GF_LSR_READ_INT(lsr, val, val, "reserved_val"); GF_LSR_READ_INT(lsr, val, 1, "hasNextExtension"); } while (val); }}static void lsr_read_object_content(GF_LASeRCodec *lsr, SVG_Element *elt){ u32 val; GF_LSR_READ_INT(lsr, val, 1, "has_private_attr"); if (val) lsr_read_private_attribute_container(lsr);}static void lsr_read_codec_IDREF(GF_LASeRCodec *lsr, XMLRI *href, const char *name){ GF_Node *n; u32 flag; u32 nID = 1+lsr_read_vluimsbf5(lsr, name); GF_LSR_READ_INT(lsr, flag, 1, "reserved"); if (flag) { u32 len = lsr_read_vluimsbf5(lsr, "len"); GF_LSR_READ_INT(lsr, flag, len, "reserved"); } n = gf_sg_find_node(lsr->sg, nID); if (!n) { char NodeID[1024]; sprintf(NodeID, "N%d", nID-1); href->string = strdup(NodeID); if (href->type!=0xFF) gf_list_add(lsr->defered_hrefs, href); href->type = XMLRI_ELEMENTID; return; } href->target = (SVG_Element *)n; href->type = XMLRI_ELEMENTID; gf_svg_register_iri(lsr->sg, href);}static u32 lsr_read_codec_IDREF_command(GF_LASeRCodec *lsr, const char *name){ u32 flag; u32 nID = 1+lsr_read_vluimsbf5(lsr, name); GF_LSR_READ_INT(lsr, flag, 1, "reserved"); if (flag) { u32 len = lsr_read_vluimsbf5(lsr, "len"); GF_LSR_READ_INT(lsr, flag, len, "reserved"); } return nID;}static Fixed lsr_read_fixed_16_8(GF_LASeRCodec *lsr, const char *name){ u32 val; GF_LSR_READ_INT(lsr, val, 24, name); if (val & (1<<23)) { s32 res = val - (1<<24);#ifdef GPAC_FIXED_POINT return res*256;#else return INT2FIX(res) / 256;#endif } else {#ifdef GPAC_FIXED_POINT return val*256;#else return INT2FIX(val) / 256;#endif }}static void lsr_read_fixed_16_8i(GF_LASeRCodec *lsr, SVG_Number *n, const char *name){ s32 val; GF_LSR_READ_INT(lsr, val, 1, name); if (val) { n->type=SVG_NUMBER_INHERIT; } else { n->type=SVG_NUMBER_VALUE; n->value = lsr_read_fixed_16_8(lsr, name); }}static void lsr_get_color(GF_LASeRCodec *lsr, u32 idx, SVG_Color *color){ LSRCol *c; if (idx>=lsr->nb_cols) return; c = &lsr->col_table[idx]; color->red = INT2FIX(c->r) / lsr->color_scale; color->green = INT2FIX(c->g) / lsr->color_scale; color->blue = INT2FIX(c->b) / lsr->color_scale;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -