📄 lsr_enc.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_WRITE_INT(_codec, _val, _nbBits, _str) {\ gf_bs_write_int(_codec->bs, _val, _nbBits); \ GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", _str, _nbBits, _val)); \ }\static void lsr_write_group_content(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_object_content);static GF_Err lsr_write_command_list(GF_LASeRCodec *lsr, GF_List *comList, SVG_Element *script, Bool first_implicit);static GF_Err lsr_write_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list, Bool reset_encoding_context);static void lsr_write_point_sequence(GF_LASeRCodec *lsr, GF_List **pts, const char *name);static void lsr_write_path_type(GF_LASeRCodec *lsr, SVG_PathData *path, const char *name);GF_LASeRCodec *gf_laser_encoder_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->sg = graph; return tmp;}void gf_laser_encoder_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); free(codec);}static LASeRStreamInfo *lsr_get_stream(GF_LASeRCodec *codec, u16 ESID){ LASeRStreamInfo *ptr; u32 i = 0; while ((ptr = (LASeRStreamInfo *)gf_list_enum(codec->streamInfo, &i))) { if(ptr->ESID==ESID) return ptr; } return NULL;}GF_Err gf_laser_encoder_new_stream(GF_LASeRCodec *codec, u16 ESID, GF_LASERConfig *cfg){ LASeRStreamInfo *pInfo; if (lsr_get_stream(codec, ESID) != NULL) return GF_BAD_PARAM; GF_SAFEALLOC(pInfo, LASeRStreamInfo); pInfo->ESID = ESID; memcpy(&pInfo->cfg, cfg, sizeof(GF_LASERConfig)); if (!pInfo->cfg.time_resolution) pInfo->cfg.time_resolution = 1000; if (!pInfo->cfg.colorComponentBits) pInfo->cfg.colorComponentBits = 8; if (!pInfo->cfg.coord_bits) pInfo->cfg.coord_bits = 12; if (pInfo->cfg.resolution<-8) pInfo->cfg.resolution = (s8) -8; else if (pInfo->cfg.resolution>7) pInfo->cfg.resolution=7; gf_list_add(codec->streamInfo, pInfo); return GF_OK;}GF_Err gf_laser_encoder_get_config(GF_LASeRCodec *codec, u16 ESID, char **out_data, u32 *out_data_length){ GF_BitStream *bs; if (!codec || !out_data || !out_data_length) return GF_BAD_PARAM; codec->info = lsr_get_stream(codec, ESID); if (!codec->info) return GF_BAD_PARAM; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, codec->info->cfg.profile, 8); gf_bs_write_int(bs, codec->info->cfg.level, 8); gf_bs_write_int(bs, 0 /*codec->info->cfg.reserved*/, 3); gf_bs_write_int(bs, codec->info->cfg.pointsCodec, 2); gf_bs_write_int(bs, codec->info->cfg.pathComponents, 4); gf_bs_write_int(bs, codec->info->cfg.fullRequestHost, 1); if (codec->info->cfg.time_resolution != 1000) { gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, codec->info->cfg.time_resolution , 16); } else { gf_bs_write_int(bs, 0, 1); } gf_bs_write_int(bs, codec->info->cfg.colorComponentBits - 1, 4); if (codec->info->cfg.resolution<0) gf_bs_write_int(bs, 16 + codec->info->cfg.resolution, 4); else gf_bs_write_int(bs, codec->info->cfg.resolution, 4); gf_bs_write_int(bs, codec->info->cfg.coord_bits, 5); gf_bs_write_int(bs, codec->info->cfg.scale_bits_minus_coord_bits, 4); gf_bs_write_int(bs, codec->info->cfg.newSceneIndicator ? 1 : 0, 1); gf_bs_write_int(bs, 0, 3); gf_bs_write_int(bs, codec->info->cfg.extensionIDBits, 4); /*no extConfig*/ gf_bs_write_int(bs, 0, 1); /*no extensions*/ gf_bs_write_int(bs, 0, 1); gf_bs_align(bs); gf_bs_get_content(bs, out_data, out_data_length); gf_bs_del(bs); return GF_OK;}GF_Err gf_laser_encode_au(GF_LASeRCodec *codec, u16 ESID, GF_List *command_list, Bool reset_context, char **out_data, u32 *out_data_length){ GF_Err e; if (!codec || !command_list || !out_data || !out_data_length) 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 = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) ); else codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution)); codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); e = lsr_write_laser_unit(codec, command_list, reset_context); if (!e) { gf_bs_align(codec->bs); gf_bs_get_content(codec->bs, out_data, out_data_length); } gf_bs_del(codec->bs); codec->bs = NULL; return e;}GF_Err gf_laser_encoder_get_rap(GF_LASeRCodec *codec, char **out_data, u32 *out_data_length){ GF_Err e; if (!codec->info) codec->info = (LASeRStreamInfo*)gf_list_get(codec->streamInfo, 0); 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 = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) ); else codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution)); codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); e = lsr_write_laser_unit(codec, NULL, 0); if (e == GF_OK) gf_bs_get_content(codec->bs, out_data, out_data_length); gf_bs_del(codec->bs); codec->bs = NULL; return e;}static void lsr_write_vluimsbf5(GF_LASeRCodec *lsr, u32 val, const char *name){ u32 nb_words; u32 nb_bits = val ? gf_get_bit_size(val) : 1; nb_words = nb_bits / 4; if (nb_bits%4) nb_words++; assert(nb_words * 4 >= nb_bits); nb_bits = 4*nb_words; while (nb_words) { nb_words--; gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1); } gf_bs_write_int(lsr->bs, val, nb_bits); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_bits + (nb_bits/4), val));}static void lsr_write_vluimsbf5_ex(GF_LASeRCodec *lsr, u32 val, u32 extra_words, const char *name){ u32 nb_words; u32 nb_bits = val ? gf_get_bit_size(val) : 1; nb_words = nb_bits / 4; if (nb_bits%4) nb_words++; nb_words += extra_words; assert(nb_words * 4 >= nb_bits); nb_bits = 4*nb_words; while (nb_words) { nb_words--; gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1); } gf_bs_write_int(lsr->bs, val, nb_bits); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_bits + (nb_bits/4), val));}static u32 lsr_get_vluimsbf5_size(u32 val, u32 extra_words){ u32 nb_words; u32 nb_bits = val ? gf_get_bit_size(val) : 1; nb_words = nb_bits / 4; if (nb_bits%4) nb_words++; nb_words += extra_words; return 4*nb_words + nb_words;}static void lsr_write_vluimsbf8(GF_LASeRCodec *lsr, u32 val, const char *name){ u32 nb_words; u32 nb_tot, nb_bits = val ? gf_get_bit_size(val) : 1; nb_words = nb_bits / 7; if (nb_bits%7) nb_words++; assert(nb_words * 7 >= nb_bits); nb_bits = nb_words * 7; nb_tot = nb_words+nb_bits; while (nb_words) { nb_words--; gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1); } gf_bs_write_int(lsr->bs, val, nb_bits); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val));}static void lsr_write_extension(GF_LASeRCodec *lsr, char *data, u32 len, const char *name){ if (!len) len = strlen(name); lsr_write_vluimsbf5(lsr, len, name); gf_bs_write_data(lsr->bs, data, len);}static void lsr_write_extend_class(GF_LASeRCodec *lsr, char *data, u32 len, const char *name){ u32 i=0; GF_LSR_WRITE_INT(lsr, 0, lsr->info->cfg.extensionIDBits, "reserved"); lsr_write_vluimsbf5(lsr, len, "len"); while (i<len) { gf_bs_write_int(lsr->bs, data[i], 8); i++; }}static void lsr_write_codec_IDREF(GF_LASeRCodec *lsr, XMLRI *href, const char *name){ u32 nID = 0; if (href && href->target) nID = gf_node_get_id((GF_Node *)href->target); else if (name[0]=='#') { GF_Node *n = gf_sg_find_node_by_name(lsr->sg, (char *) name + 1); if (n) nID = gf_node_get_id((GF_Node *)href->target); } else nID = 1+href->lsr_stream_id; assert(nID); lsr_write_vluimsbf5(lsr, nID-1, name); GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");}static void lsr_write_codec_IDREF_Node(GF_LASeRCodec *lsr, GF_Node *href, const char *name){ u32 nID = gf_node_get_id(href); assert(nID); lsr_write_vluimsbf5(lsr, nID-1, name); GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");}static u32 lsr_get_IDREF_nb_bits(GF_LASeRCodec *lsr, GF_Node *href){ u32 nb_bits, nb_words, nID; nID = gf_node_get_id(href); assert(nID); nb_bits = nID ? gf_get_bit_size(nID) : 1; nb_words = nb_bits / 4; if (nb_bits%4) nb_words++; assert(nb_words * 4 >= nb_bits); nb_bits = nb_words * 4; return nb_words+nb_bits /*IDREF part*/ + 1 /*reserevd bit*/;}static void lsr_write_fixed_16_8(GF_LASeRCodec *lsr, Fixed fix, const char *name){ u32 val; if (fix<0) {#ifdef GPAC_FIXED_POINT val = (1<<24) + fix / 256;#else val = (1<<24) + FIX2INT(fix * 256);#endif } else {#ifdef GPAC_FIXED_POINT val = fix/256;#else val = FIX2INT(fix*256);#endif } val &= 0x00FFFFFF; GF_LSR_WRITE_INT(lsr, val, 24, name);}static void lsr_write_fixed_16_8i(GF_LASeRCodec *lsr, SVG_Number *n, const char *name){ if (n->type==SVG_NUMBER_INHERIT) { GF_LSR_WRITE_INT(lsr, 1, 1, name); } else { GF_LSR_WRITE_INT(lsr, 0, 1, name); lsr_write_fixed_16_8(lsr, n->value, name); }}static s32 lsr_get_font_index(GF_LASeRCodec *lsr, SVG_FontFamily *font){ u32 i, count; if ((font->type!=SVG_FONTFAMILY_VALUE) || !font->value) return -1; count = gf_list_count(lsr->font_table); for (i=0; i<count; i++) { char *n = (char *)gf_list_get(lsr->font_table, i); if (!strcmp(n, font->value)) return (s32) i; } return -2;}static s32 lsr_get_col_index(GF_LASeRCodec *lsr, SVG_Color *color){ u16 r, g, b; u32 i; if (color->type!=SVG_COLOR_RGBCOLOR) return -1; r = FIX2INT(color->red*lsr->color_scale); g = FIX2INT(color->green*lsr->color_scale); b = FIX2INT(color->blue*lsr->color_scale); for (i=0; i<lsr->nb_cols; i++) { LSRCol *c = &lsr->col_table[i]; if ((c->r == r) && (c->g == g) && (c->b == b)) return (s32) i; } return -2;}static void lsr_write_line_increment_type(GF_LASeRCodec *lsr, SVG_Number *li, const char *name){ if (li->type==SVG_NUMBER_INHERIT) { GF_LSR_WRITE_INT(lsr, 1, 1, "choice"); GF_LSR_WRITE_INT(lsr, 1, 1, "inherit"); } else if (li->type==SVG_NUMBER_AUTO) { GF_LSR_WRITE_INT(lsr, 1, 1, "choice"); GF_LSR_WRITE_INT(lsr, 0, 1, "auto"); } else { GF_LSR_WRITE_INT(lsr, 0, 1, "choice"); lsr_write_fixed_16_8(lsr, li->value, "line-increment-value"); }}static void lsr_write_byte_align_string(GF_LASeRCodec *lsr, char *str, const char *name){ u32 len = str ? strlen(str) : 0; gf_bs_align(lsr->bs); lsr_write_vluimsbf8(lsr, len, "len");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -