This source file includes following definitions.
- gf_odf_qos_new
- gf_odf_qos_del
- gf_odf_qos_add_qualif
- gf_odf_delete_qos_qual
- gf_odf_size_qos_qual
- gf_odf_write_qos_qual
- gf_odf_parse_qos
- NewQoS
- gf_odf_new_qos
- gf_odf_del_qos
- gf_odf_read_qos
- gf_odf_size_qos
- gf_odf_write_qos
#include <gpac/internal/odf_dev.h>
#ifndef GPAC_MINIMAL_ODF
GF_EXPORT
GF_QoS_Default *gf_odf_qos_new(u8 tag)
{
GF_QoS_Default *NewQoS(u8 tag);
GF_QoS_Default *qos;
qos = NewQoS(tag);
return qos;
}
GF_EXPORT
GF_Err gf_odf_qos_del(GF_QoS_Default **qos)
{
if (*qos) gf_odf_delete_qos_qual(*qos);
*qos = NULL;
return GF_OK;
}
GF_EXPORT
GF_Err gf_odf_qos_add_qualif(GF_QoS_Descriptor *desc, GF_QoS_Default *qualif)
{
u32 i;
GF_QoS_Default *def;
if (desc->tag != GF_ODF_QOS_TAG) return GF_BAD_PARAM;
if (desc->predefined) return GF_ODF_FORBIDDEN_DESCRIPTOR;
i=0;
while ((def = (GF_QoS_Default *)gf_list_enum(desc->QoS_Qualifiers, &i))) {
if (def->tag == qualif->tag) return GF_ODF_FORBIDDEN_DESCRIPTOR;
}
return gf_list_add(desc->QoS_Qualifiers, qualif);
}
void gf_odf_delete_qos_qual(GF_QoS_Default *qos)
{
switch (qos->tag) {
case QoSMaxDelayTag :
case QoSPrefMaxDelayTag:
case QoSLossProbTag:
case QoSMaxGapLossTag:
case QoSMaxAUSizeTag:
case QoSAvgAUSizeTag:
case QoSMaxAURateTag:
gf_free(qos);
return;
default:
if ( ((GF_QoS_Private *)qos)->DataLength)
gf_free(((GF_QoS_Private *)qos)->Data);
gf_free( (GF_QoS_Private *) qos);
return;
}
}
GF_Err gf_odf_size_qos_qual(GF_QoS_Default *qos)
{
if (! qos) return GF_BAD_PARAM;
qos->size = 0;
switch (qos->tag) {
case QoSMaxDelayTag:
case QoSPrefMaxDelayTag:
case QoSLossProbTag:
case QoSMaxGapLossTag:
case QoSMaxAUSizeTag:
case QoSAvgAUSizeTag:
case QoSMaxAURateTag:
qos->size += 4;
return GF_OK;
case 0x00:
case 0xFF:
return GF_ODF_FORBIDDEN_DESCRIPTOR;
default :
qos->size += ((GF_QoS_Private *)qos)->DataLength;
}
return GF_OK;
}
GF_Err gf_odf_write_qos_qual(GF_BitStream *bs, GF_QoS_Default *qos)
{
GF_Err e;
if (!bs || !qos) return GF_BAD_PARAM;
e = gf_odf_size_qos_qual(qos);
if (e) return e;
e = gf_odf_write_base_descriptor(bs, qos->tag, qos->size);
if (e) return e;
switch (qos->tag) {
case QoSMaxDelayTag:
gf_bs_write_int(bs, ((GF_QoS_MaxDelay *)qos)->MaxDelay, 32);
break;
case QoSPrefMaxDelayTag:
gf_bs_write_int(bs, ((GF_QoS_PrefMaxDelay *)qos)->PrefMaxDelay, 32);
break;
case QoSLossProbTag:
gf_bs_write_float(bs, ((GF_QoS_LossProb *)qos)->LossProb);
break;
case QoSMaxGapLossTag:
gf_bs_write_int(bs, ((GF_QoS_MaxGapLoss *)qos)->MaxGapLoss, 32);
break;
case QoSMaxAUSizeTag:
gf_bs_write_int(bs, ((GF_QoS_MaxAUSize *)qos)->MaxAUSize, 32);
break;
case QoSAvgAUSizeTag:
gf_bs_write_int(bs, ((GF_QoS_AvgAUSize *)qos)->AvgAUSize, 32);
break;
case QoSMaxAURateTag:
gf_bs_write_int(bs, ((GF_QoS_MaxAURate *)qos)->MaxAURate, 32);
break;
case 0x00:
case 0xFF:
return GF_ODF_FORBIDDEN_DESCRIPTOR;
default:
gf_bs_write_data(bs, ((GF_QoS_Private *)qos)->Data, ((GF_QoS_Private *)qos)->DataLength);
break;
}
return GF_OK;
}
GF_Err gf_odf_parse_qos(GF_BitStream *bs, GF_QoS_Default **qos_qual, u32 *qual_size)
{
u32 tag, qos_size, val, bytesParsed, sizeHeader;
GF_QoS_Default *newQoS;
tag = gf_bs_read_int(bs, 8);
bytesParsed = 1;
qos_size = 0;
sizeHeader = 0;
do {
val = gf_bs_read_int(bs, 8);
sizeHeader++;
if (sizeHeader > 5) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Descriptor size on more than 4 bytes\n"));
return GF_ODF_INVALID_DESCRIPTOR;
}
qos_size <<= 7;
qos_size |= val & 0x7F;
} while ( val & 0x80 );
if (gf_bs_available(bs) < qos_size) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Not enough bytes (%d) to read descriptor (size=%d)\n", gf_bs_available(bs), qos_size));
return GF_ODF_INVALID_DESCRIPTOR;
}
bytesParsed += sizeHeader;
switch (tag) {
case QoSMaxDelayTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxDelay));
((GF_QoS_MaxDelay *)newQoS)->MaxDelay = gf_bs_read_int(bs, 32);
bytesParsed += 4;
break;
case QoSPrefMaxDelayTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_PrefMaxDelay));
((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = gf_bs_read_int(bs, 32);
bytesParsed += 4;
break;
case QoSLossProbTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_LossProb));
((GF_QoS_LossProb *)newQoS)->LossProb = gf_bs_read_float(bs);
bytesParsed += 4;
break;
case QoSMaxGapLossTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxGapLoss));
((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = gf_bs_read_int(bs, 32);
bytesParsed += 4;
break;
case QoSMaxAUSizeTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAUSize));
((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = gf_bs_read_int(bs, 32);
bytesParsed += 4;
break;
case QoSAvgAUSizeTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_AvgAUSize));
((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = gf_bs_read_int(bs, 32);
bytesParsed += 4;
break;
case QoSMaxAURateTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAURate));
((GF_QoS_MaxAURate *)newQoS)->MaxAURate = gf_bs_read_int(bs, 32);
bytesParsed += 4;
break;
case 0x00:
case 0xFF:
return GF_ODF_FORBIDDEN_DESCRIPTOR;
default:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_Private));
((GF_QoS_Private *)newQoS)->DataLength = qos_size;
gf_bs_read_data(bs, ((GF_QoS_Private *)newQoS)->Data, ((GF_QoS_Private *)newQoS)->DataLength);
bytesParsed += ((GF_QoS_Private *)newQoS)->DataLength;
break;
}
newQoS->size = qos_size;
newQoS->tag = tag;
if (bytesParsed != 1 + qos_size + sizeHeader) {
gf_odf_delete_qos_qual(newQoS);
return GF_ODF_INVALID_DESCRIPTOR;
}
*qos_qual = newQoS;
*qual_size = bytesParsed;
return GF_OK;
}
GF_QoS_Default *NewQoS(u8 tag)
{
GF_QoS_Default *newQoS;
switch (tag) {
case QoSMaxDelayTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxDelay));
((GF_QoS_MaxDelay *)newQoS)->MaxDelay = 0;
((GF_QoS_MaxDelay *)newQoS)->size = 4;
break;
case QoSPrefMaxDelayTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_PrefMaxDelay));
((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = 0;
((GF_QoS_PrefMaxDelay *)newQoS)->size = 4;
break;
case QoSLossProbTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_LossProb));
((GF_QoS_LossProb *)newQoS)->LossProb = 0;
((GF_QoS_LossProb *)newQoS)->size = 4;
break;
case QoSMaxGapLossTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxGapLoss));
((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = 0;
((GF_QoS_MaxGapLoss *)newQoS)->size = 4;
break;
case QoSMaxAUSizeTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAUSize));
((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = 0;
((GF_QoS_MaxAUSize *)newQoS)->size = 0;
break;
case QoSAvgAUSizeTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_AvgAUSize));
((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = 0;
((GF_QoS_AvgAUSize *)newQoS)->size = 4;
break;
case QoSMaxAURateTag:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAURate));
((GF_QoS_MaxAURate *)newQoS)->MaxAURate = 0;
((GF_QoS_MaxAURate *)newQoS)->size = 4;
break;
case 0x00:
case 0xFF:
return NULL;
default:
newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_Private));
((GF_QoS_Private *)newQoS)->DataLength = 0;
((GF_QoS_Private *)newQoS)->Data = NULL;
break;
}
newQoS->tag = tag;
return newQoS;
}
GF_Descriptor *gf_odf_new_qos()
{
GF_QoS_Descriptor *newDesc = (GF_QoS_Descriptor *) gf_malloc(sizeof(GF_QoS_Descriptor));
if (!newDesc) return NULL;
newDesc->QoS_Qualifiers = gf_list_new();
newDesc->predefined = 0;
newDesc->tag = GF_ODF_QOS_TAG;
return (GF_Descriptor *) newDesc;
}
GF_Err gf_odf_del_qos(GF_QoS_Descriptor *qos)
{
if (!qos) return GF_BAD_PARAM;
while (gf_list_count(qos->QoS_Qualifiers)) {
GF_QoS_Default *tmp = (GF_QoS_Default*)gf_list_get(qos->QoS_Qualifiers, 0);
gf_odf_delete_qos_qual(tmp);
gf_list_rem(qos->QoS_Qualifiers, 0);
}
gf_list_del(qos->QoS_Qualifiers);
return GF_OK;
}
GF_Err gf_odf_read_qos(GF_BitStream *bs, GF_QoS_Descriptor *qos, u32 DescSize)
{
GF_Err e;
GF_QoS_Default *tmp;
u32 tmp_size, nbBytes = 0;
if (!qos) return GF_BAD_PARAM;
qos->predefined = gf_bs_read_int(bs, 8);
nbBytes += 1;
if (qos->predefined) {
if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
return GF_OK;
}
while (nbBytes < DescSize) {
tmp = NULL;
e = gf_odf_parse_qos(bs, &tmp, &tmp_size);
if (e) return e;
if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
e = gf_list_add(qos->QoS_Qualifiers, tmp);
if (e) return e;
nbBytes += tmp_size;
}
if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
return GF_OK;
}
GF_Err gf_odf_size_qos(GF_QoS_Descriptor *qos, u32 *outSize)
{
GF_Err e;
u32 i;
GF_QoS_Default *tmp;
if (!qos) return GF_BAD_PARAM;
*outSize = 1;
i=0;
while ((tmp = (GF_QoS_Default *)gf_list_enum(qos->QoS_Qualifiers, &i))) {
e = gf_odf_size_qos_qual(tmp);
if (e) return e;
*outSize += tmp->size + gf_odf_size_field_size(tmp->size);
}
return GF_OK;
}
GF_Err gf_odf_write_qos(GF_BitStream *bs, GF_QoS_Descriptor *qos)
{
GF_Err e;
u32 size, i;
GF_QoS_Default *tmp;
if (!qos) return GF_BAD_PARAM;
e = gf_odf_size_descriptor((GF_Descriptor *)qos, &size);
if (e) return e;
e = gf_odf_write_base_descriptor(bs, qos->tag, size);
if (e) return e;
gf_bs_write_int(bs, qos->predefined, 8);
if (! qos->predefined) {
i=0;
while ((tmp = (GF_QoS_Default *)gf_list_enum(qos->QoS_Qualifiers, &i))) {
e = gf_odf_write_qos_qual(bs, tmp);
if (e) return e;
}
}
return GF_OK;
}
#endif