📄 descriptors.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / MPEG-4 ObjectDescriptor 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/odf_dev.h>#include <gpac/constants.h>s32 gf_odf_size_field_size(u32 size_desc){ if (size_desc < 0x00000080) { return 1 + 1; } else if (size_desc < 0x00004000) { return 2 + 1; } else if (size_desc < 0x00200000) { return 3 + 1; } else if (size_desc < 0x10000000) { return 4 + 1; } else { return -1; }}GF_EXPORTGF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc_size){ u32 val, size, sizeHeader; u8 tag; GF_Err err; GF_Descriptor *newDesc; if (!bs) return GF_BAD_PARAM; *desc_size = 0; //tag tag = (u8) gf_bs_read_int(bs, 8); sizeHeader = 1; //size size = 0; do { val = gf_bs_read_int(bs, 8); sizeHeader++; size <<= 7; size |= val & 0x7F; } while ( val & 0x80); *desc_size = size; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[ODF] Reading descriptor (tag %d size %d)\n", tag, size )); newDesc = gf_odf_create_descriptor(tag); if (! newDesc) { *desc = NULL; *desc_size = sizeHeader; if ( (tag >= GF_ODF_ISO_RES_BEGIN_TAG) && (tag <= GF_ODF_ISO_RES_END_TAG) ) { return GF_ODF_FORBIDDEN_DESCRIPTOR; } else if (!tag || (tag == 0xFF)) { return GF_ODF_INVALID_DESCRIPTOR; } return GF_OUT_OF_MEM; } newDesc->tag = tag; err = gf_odf_read_descriptor(bs, newDesc, *desc_size); /*FFMPEG fix*/ if ((tag==GF_ODF_SLC_TAG) && (((GF_SLConfig*)newDesc)->predefined==2)) { if (*desc_size==3) { *desc_size = 1; err = GF_OK; } } //little trick to handle lazy bitstreams that encode //SizeOfInstance on a fix number of bytes //This nb of bytes is added in Read methods *desc_size += sizeHeader - gf_odf_size_field_size(*desc_size); *desc = newDesc; if (err) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ODF] Error reading descriptor (tag %d size %d): %s\n", tag, size, gf_error_to_string(err) )); gf_odf_delete_descriptor(newDesc); *desc = NULL; } return err;}GF_Err gf_odf_delete_descriptor_list(GF_List *descList){ GF_Err e; GF_Descriptor*tmp; u32 i; //no error if NULL chain... if (! descList) return GF_OK; i=0; while ((tmp = (GF_Descriptor*)gf_list_enum(descList, &i))) { e = gf_odf_delete_descriptor(tmp); if (e) return e; } gf_list_del(descList); return GF_OK;}GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize){ GF_Err e; GF_Descriptor *tmp; u32 tmpSize, count, i; if (! descList) return GF_OK; count = gf_list_count(descList); for ( i = 0; i < count; i++ ) { tmp = (GF_Descriptor*)gf_list_get(descList, i); if (tmp) { e = gf_odf_size_descriptor(tmp, &tmpSize); if (e) return e; if (tmpSize) *outSize += tmpSize + gf_odf_size_field_size(tmpSize); } } return GF_OK;}GF_Err gf_odf_write_base_descriptor(GF_BitStream *bs, u8 tag, u32 size){ u32 length; unsigned char vals[4]; if (!tag ) return GF_BAD_PARAM; length = size; vals[3] = (unsigned char) (length & 0x7f); length >>= 7; vals[2] = (unsigned char) ((length & 0x7f) | 0x80); length >>= 7; vals[1] = (unsigned char) ((length & 0x7f) | 0x80); length >>= 7; vals[0] = (unsigned char) ((length & 0x7f) | 0x80); gf_bs_write_int(bs, tag, 8); if (size < 0x00000080) { gf_bs_write_int(bs, vals[3], 8); } else if (size < 0x00004000) { gf_bs_write_int(bs, vals[2], 8); gf_bs_write_int(bs, vals[3], 8); } else if (size < 0x00200000) { gf_bs_write_int(bs, vals[1], 8); gf_bs_write_int(bs, vals[2], 8); gf_bs_write_int(bs, vals[3], 8); } else if (size < 0x10000000) { gf_bs_write_int(bs, vals[0], 8); gf_bs_write_int(bs, vals[1], 8); gf_bs_write_int(bs, vals[2], 8); gf_bs_write_int(bs, vals[3], 8); } else { return GF_ODF_INVALID_DESCRIPTOR; } return GF_OK;}u32 gf_ipmpx_array_size(GF_BitStream *bs, u32 *array_size){ u32 val, size, io_size; io_size = size = 0; do { val = gf_bs_read_int(bs, 8); io_size ++; size <<= 7; size |= val & 0x7F; } while ( val & 0x80 ); *array_size = size; return io_size;}void gf_ipmpx_write_array(GF_BitStream *bs, char *data, u32 data_len){ u32 length; unsigned char vals[4]; if (!data || !data_len) return; length = data_len; vals[3] = (unsigned char) (length & 0x7f); length >>= 7; vals[2] = (unsigned char) ((length & 0x7f) | 0x80); length >>= 7; vals[1] = (unsigned char) ((length & 0x7f) | 0x80); length >>= 7; vals[0] = (unsigned char) ((length & 0x7f) | 0x80); if (data_len < 0x00000080) { gf_bs_write_int(bs, vals[3], 8); } else if (data_len < 0x00004000) { gf_bs_write_int(bs, vals[2], 8); gf_bs_write_int(bs, vals[3], 8); } else if (data_len < 0x00200000) { gf_bs_write_int(bs, vals[1], 8); gf_bs_write_int(bs, vals[2], 8); gf_bs_write_int(bs, vals[3], 8); } else if (data_len < 0x10000000) { gf_bs_write_int(bs, vals[0], 8); gf_bs_write_int(bs, vals[1], 8); gf_bs_write_int(bs, vals[2], 8); gf_bs_write_int(bs, vals[3], 8); } else { return; } gf_bs_write_data(bs, data, data_len);}GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList){ GF_Err e; u32 count, i; GF_Descriptor *tmp; if (! descList) return GF_OK; count = gf_list_count(descList); for ( i = 0; i < count; i++ ) { tmp = (GF_Descriptor*)gf_list_get(descList, i); if (tmp) { e = gf_odf_write_descriptor(bs, tmp); if (e) return e; } } return GF_OK;}GF_Err gf_odf_write_descriptor_list_filter(GF_BitStream *bs, GF_List *descList, u8 only_tag){ GF_Err e; u32 count, i; GF_Descriptor *tmp; if (! descList) return GF_OK; count = gf_list_count(descList); for ( i = 0; i < count; i++ ) { tmp = (GF_Descriptor*)gf_list_get(descList, i); if (tmp && (tmp->tag==only_tag) ) { e = gf_odf_write_descriptor(bs, tmp); if (e) return e; } } return GF_OK;}static char szStreamText[20];GF_EXPORTconst char *gf_odf_stream_type_name(u32 streamType){ switch (streamType) { case GF_STREAM_OD: return "ObjectDescriptor"; case GF_STREAM_OCR: return "ClockReference"; case GF_STREAM_SCENE: return "SceneDescription"; case GF_STREAM_VISUAL: return "Visual"; case GF_STREAM_AUDIO: return "Audio"; case GF_STREAM_MPEG7: return "MPEG7"; case GF_STREAM_IPMP: return "IPMP"; case GF_STREAM_OCI: return "OCI"; case GF_STREAM_MPEGJ: return "MPEGJ"; case GF_STREAM_INTERACT: return "Interaction"; case GF_STREAM_TEXT: return "Text"; case GF_STREAM_ND_SUBPIC: return "NeroDigital Subpicture"; default: sprintf(szStreamText, "Unknown (0x%02x)", streamType); return szStreamText; }}GF_EXPORTu32 gf_odf_stream_type_by_name(const char *streamType){ if (!streamType) return 0; if (!stricmp(streamType, "ObjectDescriptor")) return GF_STREAM_OD; if (!stricmp(streamType, "ClockReference")) return GF_STREAM_OCR; if (!stricmp(streamType, "SceneDescription")) return GF_STREAM_SCENE; if (!stricmp(streamType, "Visual")) return GF_STREAM_VISUAL; if (!stricmp(streamType, "Audio")) return GF_STREAM_AUDIO; if (!stricmp(streamType, "MPEG7")) return GF_STREAM_MPEG7; if (!stricmp(streamType, "IPMP")) return GF_STREAM_IPMP; if (!stricmp(streamType, "OCI")) return GF_STREAM_OCI; if (!stricmp(streamType, "MPEGJ")) return GF_STREAM_MPEGJ; if (!stricmp(streamType, "Interaction")) return GF_STREAM_INTERACT; if (!stricmp(streamType, "Text")) return GF_STREAM_TEXT; return 0;}/*special authoring functions*/GF_EXPORTGF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u8 oti){ Bool hasSize, cmd_stream; GF_Err e; GF_BitStream *bs; GF_BIFSConfig *cfg; if (!dsi || !dsi->data || !dsi->dataLength ) return NULL; bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ); cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); e = GF_OK; if (oti==2) { /*3D Mesh Coding*/ gf_bs_read_int(bs, 1); /*PMF*/ gf_bs_read_int(bs, 1); } cfg->nodeIDbits = gf_bs_read_int(bs, 5); cfg->routeIDbits = gf_bs_read_int(bs, 5); if (oti==2) cfg->protoIDbits = gf_bs_read_int(bs, 5); cmd_stream = gf_bs_read_int(bs, 1); if (!cmd_stream) { cfg->elementaryMasks = gf_list_new(); while (1) { GF_ElementaryMask* em = (GF_ElementaryMask* ) gf_odf_New_ElemMask(); em->node_id = gf_bs_read_int(bs, cfg->nodeIDbits); gf_list_add(cfg->elementaryMasks, em); /*this assumes only FDP, BDP and IFS2D (no elem mask)*/ if (gf_bs_read_int(bs, 1) == 0) break; } gf_bs_align(bs); if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) e = GF_NOT_SUPPORTED; } else { cfg->pixelMetrics = gf_bs_read_int(bs, 1); hasSize = gf_bs_read_int(bs, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -