📄 odf_codec.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>/************************************************************ Object GF_Descriptor Codec Functions************************************************************/GF_EXPORTGF_ODCodec *gf_odf_codec_new(){ GF_ODCodec *codec; GF_List *comList; comList = gf_list_new(); if (!comList) return NULL; codec = (GF_ODCodec *) malloc(sizeof(GF_ODCodec)); if (!codec) { gf_list_del(comList); return NULL; } //the bitstream is always NULL. It is created on the fly for access unit processing only codec->bs = NULL; codec->CommandList = comList; return codec;}GF_EXPORTvoid gf_odf_codec_del(GF_ODCodec *codec){ if (!codec) return; while (gf_list_count(codec->CommandList)) { GF_ODCom *com = (GF_ODCom *)gf_list_get(codec->CommandList, 0); gf_odf_delete_command(com); gf_list_rem(codec->CommandList, 0); } gf_list_del(codec->CommandList); if (codec->bs) gf_bs_del(codec->bs); free(codec);}/************************************************************ Codec Encoder Functions************************************************************/GF_EXPORTGF_Err gf_odf_codec_add_com(GF_ODCodec *codec, GF_ODCom *command){ if (!codec || !command) return GF_BAD_PARAM; return gf_list_add(codec->CommandList, command);}GF_EXPORTGF_Err gf_odf_codec_encode(GF_ODCodec *codec, Bool delete_content){ GF_ODCom *com; GF_Err e = GF_OK; u32 i; if (!codec) return GF_BAD_PARAM; //check our bitstream: if existing, this means the previous encoded AU was not retrieved //we DON'T allow that if (codec->bs) return GF_BAD_PARAM; codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (!codec->bs) return GF_OUT_OF_MEM; /*encode each command*/ i = 0; while ((com = (GF_ODCom *)gf_list_enum(codec->CommandList, &i))) { e = gf_odf_write_command(codec->bs, com); if (e) goto err_exit; //don't forget OD Commands are aligned... gf_bs_align(codec->bs); }//if an error occurs, delete the GF_BitStream and empty the codecerr_exit: if (e) { gf_bs_del(codec->bs); codec->bs = NULL; } if (delete_content) { while (gf_list_count(codec->CommandList)) { com = (GF_ODCom *)gf_list_get(codec->CommandList, 0); gf_odf_delete_command(com); gf_list_rem(codec->CommandList, 0); } } return e;}GF_EXPORTGF_Err gf_odf_codec_get_au(GF_ODCodec *codec, char **outAU, u32 *au_length){ if (!codec || !codec->bs || !outAU || *outAU) return GF_BAD_PARAM; gf_bs_get_content(codec->bs, outAU, au_length); gf_bs_del(codec->bs); codec->bs = NULL; return GF_OK;}/************************************************************ Codec Decoder Functions************************************************************/GF_EXPORTGF_Err gf_odf_codec_set_au(GF_ODCodec *codec, char *au, u32 au_length){ if (!codec ) return GF_BAD_PARAM; if (!au || !au_length) return GF_OK; //if the command list is not empty, this is an error if (gf_list_count(codec->CommandList)) return GF_BAD_PARAM; //the bitStream should not be here if (codec->bs) return GF_BAD_PARAM; codec->bs = gf_bs_new(au, (u64) au_length, (unsigned char)GF_BITSTREAM_READ); if (!codec->bs) return GF_OUT_OF_MEM; return GF_OK; }GF_EXPORTGF_Err gf_odf_codec_decode(GF_ODCodec *codec){ GF_Err e = GF_OK; u32 size = 0, comSize, bufSize; GF_ODCom *com; if (!codec || !codec->bs) return GF_BAD_PARAM; bufSize = (u32) gf_bs_available(codec->bs); while (size < bufSize) { e = gf_odf_parse_command(codec->bs, &com, &comSize); if (e) goto err_exit; gf_list_add(codec->CommandList, com); size += comSize + gf_odf_size_field_size(comSize); //OD Commands are aligned gf_bs_align(codec->bs); } //then delete our bitstream gf_bs_del(codec->bs); codec->bs = NULL; if (size != bufSize) { e = GF_ODF_INVALID_COMMAND; goto err_exit; } return e;err_exit: if (codec->bs) { gf_bs_del(codec->bs); codec->bs = NULL; } while (gf_list_count(codec->CommandList)) { com = (GF_ODCom*)gf_list_get(codec->CommandList, 0); gf_odf_delete_command(com); gf_list_rem(codec->CommandList, 0); } return e;}//get the first command in the codec and remove the entryGF_EXPORTGF_ODCom *gf_odf_codec_get_com(GF_ODCodec *codec){ GF_ODCom *com; if (!codec || codec->bs) return NULL; com = (GF_ODCom*)gf_list_get(codec->CommandList, 0); if (com) gf_list_rem(codec->CommandList, 0); return com;}/************************************************************ OD Commands Functions************************************************************///some easy way to get an OD GF_ODCom...GF_EXPORTGF_ODCom *gf_odf_com_new(u8 tag){ GF_ODCom *newcom; newcom = gf_odf_create_command(tag); newcom->tag = tag; return (GF_ODCom *)newcom;}// ... and to delete itGF_EXPORTGF_Err gf_odf_com_del(GF_ODCom **com){ GF_Err e; e = gf_odf_delete_command(*com); *com = NULL; return e;}/************************************************************ Object Descriptors Functions************************************************************///some easy way to get an mpeg4 descriptor ...GF_EXPORTGF_Descriptor *gf_odf_desc_new(u8 tag){ GF_Descriptor *newdesc; newdesc = gf_odf_create_descriptor(tag); newdesc->tag = tag; return (GF_Descriptor *)newdesc;}// ... and to delete itGF_EXPORTvoid gf_odf_desc_del(GF_Descriptor *desc){ if (desc) gf_odf_delete_descriptor(desc);}//use this function to decode a standalone descriptor//the desc MUST be formatted with tag and size field!!!GF_EXPORTGF_Err gf_odf_desc_read(char *raw_desc, u32 descSize, GF_Descriptor * *outDesc){ GF_Err e; u32 size; GF_BitStream *bs; if (!raw_desc || !descSize) return GF_BAD_PARAM; bs = gf_bs_new(raw_desc, (u64) descSize, GF_BITSTREAM_READ); if (!bs) return GF_OUT_OF_MEM; size = 0; e = gf_odf_parse_descriptor(bs, outDesc, &size); //the size dosn't have the header in it size += gf_odf_size_field_size(size);/* if (size != descSize) { if (*outDesc) gf_odf_delete_descriptor(*outDesc); *outDesc = NULL; e = GF_ODF_INVALID_DESCRIPTOR; }*/ gf_bs_del(bs); return e;}//use this function to encode a standalone descriptor//the desc will be formatted with tag and size fieldGF_EXPORTGF_Err gf_odf_desc_write(GF_Descriptor *desc, char **outEncDesc, u32 *outSize){ GF_Err e; GF_BitStream *bs; if (!desc || !outEncDesc || !outSize) return GF_BAD_PARAM; *outEncDesc = NULL; *outSize = 0; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (!bs) return GF_OUT_OF_MEM; //then encode our desc... e = gf_odf_write_descriptor(bs, desc); if (e) { gf_bs_del(bs); return e; } //then get the content from our bitstream gf_bs_get_content(bs, outEncDesc, outSize); gf_bs_del(bs); return GF_OK;}//use this function to get the size of a standalone descriptorGF_EXPORTu32 gf_odf_desc_size(GF_Descriptor *desc){ u32 descSize; GF_Err e; if (!desc) return GF_BAD_PARAM; //get the descriptor length e = gf_odf_size_descriptor(desc, &descSize); if (e) return 0; //add the header length descSize += gf_odf_size_field_size(descSize); return descSize;}//this is usefull to duplicate on the fly a descriptor (mainly for authoring purposes) GF_EXPORTGF_Err gf_odf_desc_copy(GF_Descriptor *inDesc, GF_Descriptor **outDesc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -