This source file includes following definitions.
- gf_odf_codec_new
- gf_odf_codec_del
- gf_odf_codec_add_com
- gf_odf_codec_encode
- gf_odf_codec_get_au
- gf_odf_codec_set_au
- gf_odf_codec_decode
- gf_odf_codec_get_com
- gf_odf_com_new
- gf_odf_com_del
- gf_odf_desc_new
- gf_odf_desc_del
- gf_odf_desc_list_del
- gf_odf_desc_esd_new
- gf_odf_desc_read
- gf_odf_desc_write_bs
- gf_odf_desc_write
- gf_odf_desc_size
- gf_odf_desc_copy
- gf_odf_desc_add_desc
- gf_odf_desc_list_read
- gf_odf_desc_list_write
- gf_odf_desc_list_size
- gf_odf_codec_apply_com
#include <gpac/internal/odf_dev.h>
GF_EXPORT
GF_ODCodec *gf_odf_codec_new()
{
GF_ODCodec *codec;
GF_List *comList;
comList = gf_list_new();
if (!comList) return NULL;
codec = (GF_ODCodec *) gf_malloc(sizeof(GF_ODCodec));
if (!codec) {
gf_list_del(comList);
return NULL;
}
codec->bs = NULL;
codec->CommandList = comList;
return codec;
}
GF_EXPORT
void 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);
gf_free(codec);
}
GF_EXPORT
GF_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_EXPORT
GF_Err gf_odf_codec_encode(GF_ODCodec *codec, u32 cleanup_type)
{
GF_ODCom *com;
GF_Err e = GF_OK;
u32 i;
if (!codec) return GF_BAD_PARAM;
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;
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;
gf_bs_align(codec->bs);
}
err_exit:
if (e) {
gf_bs_del(codec->bs);
codec->bs = NULL;
}
if (cleanup_type==1) {
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);
}
}
if (cleanup_type==0) {
gf_list_reset(codec->CommandList);
}
return e;
}
GF_EXPORT
GF_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;
}
GF_EXPORT
GF_Err gf_odf_codec_set_au(GF_ODCodec *codec, const char *au, u32 au_length)
{
if (!codec ) return GF_BAD_PARAM;
if (!au || !au_length) return GF_OK;
if (gf_list_count(codec->CommandList)) return GF_BAD_PARAM;
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_EXPORT
GF_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);
gf_bs_align(codec->bs);
}
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;
}
GF_EXPORT
GF_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;
}
GF_EXPORT
GF_ODCom *gf_odf_com_new(u8 tag)
{
GF_ODCom *newcom;
newcom = gf_odf_create_command(tag);
newcom->tag = tag;
return (GF_ODCom *)newcom;
}
GF_EXPORT
GF_Err gf_odf_com_del(GF_ODCom **com)
{
GF_Err e;
e = gf_odf_delete_command(*com);
*com = NULL;
return e;
}
GF_EXPORT
GF_Descriptor *gf_odf_desc_new(u8 tag)
{
GF_Descriptor *newdesc;
newdesc = gf_odf_create_descriptor(tag);
newdesc->tag = tag;
return (GF_Descriptor *)newdesc;
}
GF_EXPORT
void gf_odf_desc_del(GF_Descriptor *desc)
{
if (desc) gf_odf_delete_descriptor(desc);
}
GF_EXPORT
GF_Err gf_odf_desc_list_del(GF_List *descList)
{
GF_Err e;
GF_Descriptor *tmp;
if (! descList) return GF_BAD_PARAM;
while (gf_list_count(descList)) {
tmp = (GF_Descriptor*)gf_list_get(descList, 0);
gf_list_rem(descList, 0);
e = gf_odf_delete_descriptor(tmp);
if (e) return e;
}
return GF_OK;
}
GF_EXPORT
GF_ESD *gf_odf_desc_esd_new(u32 sl_predefined)
{
GF_ESD *esd;
esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG);
esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG);
esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);
esd->slConfig = (GF_SLConfig *) gf_odf_new_slc((u8) sl_predefined);
return esd;
}
GF_EXPORT
GF_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);
size += gf_odf_size_field_size(size);
gf_bs_del(bs);
return e;
}
GF_EXPORT
GF_Err gf_odf_desc_write_bs(GF_Descriptor *desc, GF_BitStream *bs)
{
GF_Err e;
if (!desc || !bs) return GF_BAD_PARAM;
e = gf_odf_write_descriptor(bs, desc);
if (e) {
gf_bs_del(bs);
return e;
}
return GF_OK;
}
GF_EXPORT
GF_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;
e = gf_odf_desc_write_bs(desc, bs);
gf_bs_get_content(bs, outEncDesc, outSize);
gf_bs_del(bs);
return e;
}
GF_EXPORT
u32 gf_odf_desc_size(GF_Descriptor *desc)
{
u32 descSize;
GF_Err e;
if (!desc) return GF_BAD_PARAM;
e = gf_odf_size_descriptor(desc, &descSize);
if (e) return 0;
descSize += gf_odf_size_field_size(descSize);
return descSize;
}
GF_EXPORT
GF_Err gf_odf_desc_copy(GF_Descriptor *inDesc, GF_Descriptor **outDesc)
{
GF_Err e;
char *desc;
u32 size;
e = gf_odf_desc_write(inDesc, &desc, &size);
if (e) return e;
e = gf_odf_desc_read(desc, size, outDesc);
gf_free(desc);
return e;
}
GF_EXPORT
GF_Err gf_odf_desc_add_desc(GF_Descriptor *parentDesc, GF_Descriptor *newDesc)
{
GF_DecoderConfig *dcd;
GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc);
GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc);
GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc);
GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc);
GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc);
if (!parentDesc || !newDesc) return GF_BAD_PARAM;
switch (parentDesc->tag) {
case GF_ODF_OD_TAG:
return AddDescriptorToOD((GF_ObjectDescriptor *)parentDesc, newDesc);
case GF_ODF_IOD_TAG:
return AddDescriptorToIOD((GF_InitialObjectDescriptor *)parentDesc, newDesc);
case GF_ODF_ESD_TAG:
return AddDescriptorToESD((GF_ESD *)parentDesc, newDesc);
case GF_ODF_DCD_TAG:
dcd = (GF_DecoderConfig *)parentDesc;
if ((newDesc->tag == GF_ODF_DSI_TAG)
|| (newDesc->tag == GF_ODF_BIFS_CFG_TAG)
|| (newDesc->tag == GF_ODF_UI_CFG_TAG)
|| (newDesc->tag == GF_ODF_TEXT_CFG_TAG)
) {
if (dcd->decoderSpecificInfo) return GF_ODF_FORBIDDEN_DESCRIPTOR;
dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) newDesc;
return GF_OK;
} else if (newDesc->tag == GF_ODF_EXT_PL_TAG) {
return gf_list_add(dcd->profileLevelIndicationIndexDescriptor, newDesc);
}
return GF_ODF_FORBIDDEN_DESCRIPTOR;
case GF_ODF_TEXT_CFG_TAG:
if (newDesc->tag != GF_ODF_TX3G_TAG) return GF_ODF_FORBIDDEN_DESCRIPTOR;
return gf_list_add(((GF_TextConfig *)parentDesc)->sample_descriptions, newDesc);
case GF_ODF_QOS_TAG:
return GF_BAD_PARAM;
case GF_ODF_ISOM_IOD_TAG:
return AddDescriptorToIsomIOD((GF_IsomInitialObjectDescriptor *)parentDesc, newDesc);
case GF_ODF_ISOM_OD_TAG:
return AddDescriptorToIsomOD((GF_IsomObjectDescriptor *)parentDesc, newDesc);
case GF_ODF_IPMP_TL_TAG:
if (newDesc->tag!=GF_ODF_IPMP_TOOL_TAG) return GF_BAD_PARAM;
return gf_list_add(((GF_IPMP_ToolList *)parentDesc)->ipmp_tools, newDesc);
case GF_ODF_BIFS_CFG_TAG:
{
GF_BIFSConfig *cfg = (GF_BIFSConfig *)parentDesc;
if (newDesc->tag!=GF_ODF_ELEM_MASK_TAG) return GF_BAD_PARAM;
if (!cfg->elementaryMasks) cfg->elementaryMasks = gf_list_new();
return gf_list_add(cfg->elementaryMasks, newDesc);
}
default:
return GF_ODF_FORBIDDEN_DESCRIPTOR;
}
}
GF_EXPORT
GF_Err gf_odf_desc_list_read(char *raw_list, u32 raw_size, GF_List *descList)
{
GF_BitStream *bs;
u32 size, desc_size;
GF_Descriptor *desc;
GF_Err e = GF_OK;
if (!descList || !raw_list || !raw_size) return GF_BAD_PARAM;
bs = gf_bs_new(raw_list, raw_size, GF_BITSTREAM_READ);
if (!bs) return GF_OUT_OF_MEM;
size = 0;
while (size < raw_size) {
e = gf_odf_parse_descriptor(bs, &desc, &desc_size);
if (e) goto exit;
gf_list_add(descList, desc);
size += desc_size + gf_odf_size_field_size(desc_size);
}
exit:
gf_bs_del(bs);
if (size != raw_size) e = GF_ODF_INVALID_DESCRIPTOR;
return e;
}
GF_EXPORT
GF_Err gf_odf_desc_list_write(GF_List *descList, char **outEncList, u32 *outSize)
{
GF_BitStream *bs;
GF_Err e;
if (!descList || !outEncList || *outEncList || !outSize) return GF_BAD_PARAM;
*outSize = 0;
bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
if (!bs) return GF_OUT_OF_MEM;
e = gf_odf_write_descriptor_list(bs, descList);
if (e) {
gf_bs_del(bs);
return e;
}
gf_bs_get_content(bs, outEncList, outSize);
gf_bs_del(bs);
return GF_OK;
}
GF_EXPORT
GF_Err gf_odf_desc_list_size(GF_List *descList, u32 *outSize)
{
return gf_odf_size_descriptor_list(descList, outSize);
}
GF_Err gf_odf_codec_apply_com(GF_ODCodec *codec, GF_ODCom *command)
{
GF_ODCom *com;
GF_ODUpdate *odU, *odU_o;
u32 i, count;
count = gf_list_count(codec->CommandList);
switch (command->tag) {
case GF_ODF_OD_REMOVE_TAG:
for (i=0; i<count; i++) {
com = (GF_ODCom *)gf_list_get(codec->CommandList, i);
if (com->tag==GF_ODF_OD_UPDATE_TAG) {
u32 count, j, k;
GF_ODRemove *odR = (GF_ODRemove *) command;
odU = (GF_ODUpdate *)com;
count = gf_list_count(odU->objectDescriptors);
for (k=0; k<count; k++) {
GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, k);
for (j=0; j<odR->NbODs; j++) {
if (od->objectDescriptorID==odR->OD_ID[j]) {
gf_list_rem(odU->objectDescriptors, k);
k--;
count--;
gf_odf_desc_del((GF_Descriptor *)od);
break;
}
}
}
if (!gf_list_count(odU->objectDescriptors)) {
gf_list_rem(codec->CommandList, i);
i--;
count--;
}
}
else if (com->tag==GF_ODF_ESD_UPDATE_TAG) {
u32 j;
GF_ODRemove *odR = (GF_ODRemove *) command;
GF_ESDUpdate *esdU = (GF_ESDUpdate*)com;
for (j=0; j<odR->NbODs; j++) {
if (esdU->ODID==odR->OD_ID[j]) {
gf_list_rem(codec->CommandList, i);
i--;
count--;
gf_odf_com_del((GF_ODCom**)&esdU);
break;
}
}
}
}
return GF_OK;
case GF_ODF_OD_UPDATE_TAG:
odU_o = NULL;
for (i=0; i<count; i++) {
odU_o = (GF_ODUpdate*)gf_list_get(codec->CommandList, i);
if (odU_o->tag==GF_ODF_OD_UPDATE_TAG) break;
odU_o = NULL;
}
if (!odU_o) {
odU_o = (GF_ODUpdate *)gf_odf_com_new(GF_ODF_OD_UPDATE_TAG);
gf_list_add(codec->CommandList, odU_o);
}
odU = (GF_ODUpdate*)command;
count = gf_list_count(odU->objectDescriptors);
for (i=0; i<count; i++) {
Bool found = GF_FALSE;
GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, i);
u32 j, count2 = gf_list_count(odU_o->objectDescriptors);
for (j=0; j<count2; j++) {
GF_ObjectDescriptor *od2 = (GF_ObjectDescriptor *)gf_list_get(odU_o->objectDescriptors, j);
if (od2->objectDescriptorID==od->objectDescriptorID) {
found = GF_TRUE;
break;
}
}
if (!found) {
GF_ObjectDescriptor *od_new;
GF_Err e = gf_odf_desc_copy((GF_Descriptor*)od, (GF_Descriptor**)&od_new);
if (e==GF_OK)
gf_list_add(odU_o->objectDescriptors, od_new);
}
}
return GF_OK;
}
return GF_NOT_SUPPORTED;
}