📄 qos.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>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: free(qos); return; default: if ( ((GF_QoS_Private *)qos)->DataLength) free(((GF_QoS_Private *)qos)->Data); 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: //FLOAT (double on 4 bytes) 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: //we defined the private qos... 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 tag = gf_bs_read_int(bs, 8); bytesParsed = 1; //size of instance qos_size = 0; sizeHeader = 0; do { val = gf_bs_read_int(bs, 8); sizeHeader++; qos_size <<= 7; qos_size |= val & 0x7F; } while ( val & 0x80 ); bytesParsed += sizeHeader; //Payload switch (tag) { case QoSMaxDelayTag: newQoS = (GF_QoS_Default *) 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 *) 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 *) malloc(sizeof(GF_QoS_LossProb)); ((GF_QoS_LossProb *)newQoS)->LossProb = gf_bs_read_float(bs); bytesParsed += 4; break; case QoSMaxGapLossTag: newQoS = (GF_QoS_Default *) 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 *) 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 *) 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 *) 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: //we defined the private qos... newQoS = (GF_QoS_Default *) 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 *) malloc(sizeof(GF_QoS_MaxDelay)); ((GF_QoS_MaxDelay *)newQoS)->MaxDelay = 0; ((GF_QoS_MaxDelay *)newQoS)->size = 4; break; case QoSPrefMaxDelayTag: newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_PrefMaxDelay)); ((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = 0; ((GF_QoS_PrefMaxDelay *)newQoS)->size = 4; break; case QoSLossProbTag: newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_LossProb)); ((GF_QoS_LossProb *)newQoS)->LossProb = 0; ((GF_QoS_LossProb *)newQoS)->size = 4; break; case QoSMaxGapLossTag: newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxGapLoss)); ((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = 0; ((GF_QoS_MaxGapLoss *)newQoS)->size = 4; break; case QoSMaxAUSizeTag: newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxAUSize)); ((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = 0; ((GF_QoS_MaxAUSize *)newQoS)->size = 0; break; case QoSAvgAUSizeTag: newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_AvgAUSize)); ((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = 0; ((GF_QoS_AvgAUSize *)newQoS)->size = 4; break; case QoSMaxAURateTag: newQoS = (GF_QoS_Default *) 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: //we defined the private qos... newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_Private)); ((GF_QoS_Private *)newQoS)->DataLength = 0; ((GF_QoS_Private *)newQoS)->Data = NULL; break; } newQoS->tag = tag; return newQoS;}//// Constructor//GF_Descriptor *gf_odf_new_qos(){ GF_QoS_Descriptor *newDesc = (GF_QoS_Descriptor *) 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;}//// Desctructor//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;}//// Reader//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 (!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;}//// Size//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;}//// Writer//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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -