📄 hinting.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / ISO Media File Format 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/isomedia_dev.h>GF_Box *ghnt_New(){ GF_HintSampleEntryBox *tmp = (GF_HintSampleEntryBox *) malloc(sizeof(GF_HintSampleEntryBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_HintSampleEntryBox)); tmp->HintDataTable = gf_list_new(); if (!tmp->HintDataTable) { free(tmp); return NULL; } //this type is used internally for protocols that share the same base entry //currently only RTP uses this, but a flexMux could use this entry too... tmp->type = GF_ISOM_BOX_TYPE_GHNT; tmp->HintTrackVersion = 1; tmp->LastCompatibleVersion = 1; return (GF_Box *)tmp;}void ghnt_del(GF_Box *s){ GF_HintSampleEntryBox *ptr; ptr = (GF_HintSampleEntryBox *)s; gf_isom_box_array_del(ptr->HintDataTable); if (ptr->hint_sample) gf_isom_hint_sample_del(ptr->hint_sample); free(ptr);}GF_Err ghnt_Read(GF_Box *s, GF_BitStream *bs){ GF_Box *a; GF_Err e; GF_HintSampleEntryBox *ptr = (GF_HintSampleEntryBox *)s; if (ptr == NULL) return GF_BAD_PARAM; if (ptr->size < 16) return GF_ISOM_INVALID_FILE; gf_bs_read_data(bs, ptr->reserved, 6); ptr->dataReferenceIndex = gf_bs_read_u16(bs); ptr->HintTrackVersion = gf_bs_read_u16(bs); ptr->LastCompatibleVersion = gf_bs_read_u16(bs); ptr->MaxPacketSize = gf_bs_read_u32(bs); ptr->size -= 16; while (ptr->size) { e = gf_isom_parse_box(&a, bs); if (e) return e; e = gf_list_add(ptr->HintDataTable, a); if (e) return e; ptr->size -= a->size; } return GF_OK;}#ifndef GPAC_READ_ONLYGF_Err ghnt_Write(GF_Box *s, GF_BitStream *bs){ GF_Err e; GF_HintSampleEntryBox *ptr = (GF_HintSampleEntryBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_data(bs, ptr->reserved, 6); gf_bs_write_u16(bs, ptr->dataReferenceIndex); gf_bs_write_u16(bs, ptr->HintTrackVersion); gf_bs_write_u16(bs, ptr->LastCompatibleVersion); gf_bs_write_u32(bs, ptr->MaxPacketSize); return gf_isom_box_array_write(s, ptr->HintDataTable, bs);}GF_Err ghnt_Size(GF_Box *s){ GF_Err e; GF_HintSampleEntryBox *ptr = (GF_HintSampleEntryBox *)s; e = gf_isom_box_get_size(s); if (e) return e; ptr->size += 16; e = gf_isom_box_array_size(s, ptr->HintDataTable); if (e) return e; return GF_OK;}#endif //GPAC_READ_ONLYGF_HintSample *gf_isom_hint_sample_new(u32 ProtocolType){ GF_HintSample *tmp; u8 type; switch (ProtocolType) { case GF_ISOM_BOX_TYPE_RTP_STSD: type = GF_ISMO_HINT_RTP; break; default: return NULL; } GF_SAFEALLOC(tmp, GF_HintSample); tmp->packetTable = gf_list_new(); tmp->HintType = type; return tmp;}void gf_isom_hint_sample_del(GF_HintSample *ptr){ GF_HintPacket *pck; while (gf_list_count(ptr->packetTable)) { pck = (GF_HintPacket *)gf_list_get(ptr->packetTable, 0); gf_isom_hint_pck_del(ptr->HintType, pck); gf_list_rem(ptr->packetTable, 0); } gf_list_del(ptr->packetTable); if (ptr->AdditionalData) free(ptr->AdditionalData); if (ptr->sample_cache) { while (gf_list_count(ptr->sample_cache)) { GF_HintDataCache *hdc = (GF_HintDataCache *)gf_list_get(ptr->sample_cache, 0); gf_list_rem(ptr->sample_cache, 0); if (hdc->samp) gf_isom_sample_del(&hdc->samp); free(hdc); } gf_list_del(ptr->sample_cache); } free(ptr);}GF_Err gf_isom_hint_sample_read(GF_HintSample *ptr, GF_BitStream *bs, u32 sampleSize){ u16 entryCount, i; GF_HintPacket *pck; GF_Err e; u64 sizeIn, sizeOut; sizeIn = gf_bs_available(bs); entryCount = gf_bs_read_u16(bs); ptr->reserved = gf_bs_read_u16(bs); for (i = 0; i < entryCount; i++) { pck = gf_isom_hint_pck_new(ptr->HintType); e = gf_isom_hint_pck_read(ptr->HintType, pck, bs); if (e) return e; gf_list_add(ptr->packetTable, pck); } sizeOut = gf_bs_available(bs) - sizeIn; //do we have some more data after the packets ?? if ((u32)sizeOut < sampleSize) { ptr->dataLength = sampleSize - (u32)sizeOut; ptr->AdditionalData = (char*)malloc(sizeof(char) * ptr->dataLength); gf_bs_read_data(bs, ptr->AdditionalData, ptr->dataLength); } return GF_OK;}#ifndef GPAC_READ_ONLYGF_Err gf_isom_hint_sample_write(GF_HintSample *ptr, GF_BitStream *bs){ u32 count, i; GF_HintPacket *pck; GF_Err e; count = gf_list_count(ptr->packetTable); gf_bs_write_u16(bs, count); gf_bs_write_u16(bs, ptr->reserved); //write the packet table for (i=0; i<count; i++) { pck = (GF_HintPacket *)gf_list_get(ptr->packetTable, i); e = gf_isom_hint_pck_write(ptr->HintType, pck, bs); if (e) return e; } //write additional data if (ptr->AdditionalData) { gf_bs_write_data(bs, ptr->AdditionalData, ptr->dataLength); } return GF_OK;}u32 gf_isom_hint_sample_size(GF_HintSample *ptr){ u32 size, count, i; GF_HintPacket *pck; size = 4; count = gf_list_count(ptr->packetTable); for (i=0; i<count; i++) { pck = (GF_HintPacket *)gf_list_get(ptr->packetTable, i); size += gf_isom_hint_pck_size(ptr->HintType, pck); } size += ptr->dataLength; return size;}#endifGF_HintPacket *gf_isom_hint_pck_new(u8 HintType){ switch (HintType) { case GF_ISMO_HINT_RTP: return (GF_HintPacket *) gf_isom_hint_rtp_new(); default: return NULL; }}void gf_isom_hint_pck_del(u8 HintType, GF_HintPacket *ptr){ switch (HintType) { case GF_ISMO_HINT_RTP: gf_isom_hint_rtp_del((GF_RTPPacket *)ptr); break; default: break; }}GF_Err gf_isom_hint_pck_read(u8 HintType, GF_HintPacket *ptr, GF_BitStream *bs){ switch (HintType) { case GF_ISMO_HINT_RTP: return gf_isom_hint_rtp_read((GF_RTPPacket *)ptr, bs); default: return GF_NOT_SUPPORTED; }}#ifndef GPAC_READ_ONLYGF_Err gf_isom_hint_pck_write(u8 HintType, GF_HintPacket *ptr, GF_BitStream *bs){ switch (HintType) { case GF_ISMO_HINT_RTP: return gf_isom_hint_rtp_write((GF_RTPPacket *)ptr, bs); default: return GF_NOT_SUPPORTED; }}u32 gf_isom_hint_pck_size(u8 HintType, GF_HintPacket *ptr){ switch (HintType) { case GF_ISMO_HINT_RTP: return gf_isom_hint_rtp_size((GF_RTPPacket *)ptr); default: return 0; }}GF_Err gf_isom_hint_pck_offset(u8 HintType, GF_HintPacket *ptr, u32 offset, u32 HintSampleNumber){ switch (HintType) { case GF_ISMO_HINT_RTP: return gf_isom_hint_rtp_offset((GF_RTPPacket *)ptr, offset, HintSampleNumber); default: return GF_NOT_SUPPORTED; }}GF_Err gf_isom_hint_pck_add_dte(u8 HintType, GF_HintPacket *ptr, GF_GenericDTE *dte, u8 AtBegin){ switch (HintType) { case GF_ISMO_HINT_RTP: if (AtBegin) return gf_list_insert( ((GF_RTPPacket *)ptr)->DataTable, dte, 0); else return gf_list_add( ((GF_RTPPacket *)ptr)->DataTable, dte); default: return GF_NOT_SUPPORTED; }}u32 gf_isom_hint_pck_length(u8 HintType, GF_HintPacket *ptr){ switch (HintType) { case GF_ISMO_HINT_RTP: return gf_isom_hint_rtp_length((GF_RTPPacket *)ptr); default: return 0; }}#endif/******************************************************************** Creation of DataTable entries in the RTP sample********************************************************************/GF_GenericDTE *New_EmptyDTE(){ GF_EmptyDTE *dte = (GF_EmptyDTE *)malloc(sizeof(GF_EmptyDTE)); dte->source = 0; return (GF_GenericDTE *)dte;}GF_GenericDTE *New_ImmediateDTE(){ GF_ImmediateDTE *dte = (GF_ImmediateDTE *)malloc(sizeof(GF_ImmediateDTE)); dte->source = 1; memset(dte->data, 0, 14); dte->dataLength = 0; return (GF_GenericDTE *)dte;}GF_GenericDTE *New_SampleDTE(){ GF_SampleDTE *dte = (GF_SampleDTE *)malloc(sizeof(GF_SampleDTE)); dte->source = 2; //can be -1 in QT , so init at -2 dte->trackRefIndex = (s8) -2; dte->dataLength = 0; dte->sampleNumber = 0; dte->samplesPerComp = 1; dte->byteOffset = 0; dte->bytesPerComp = 1; return (GF_GenericDTE *)dte;}GF_GenericDTE *New_StreamDescDTE(){ GF_StreamDescDTE *dte = (GF_StreamDescDTE *)malloc(sizeof(GF_StreamDescDTE)); dte->source = 3; dte->byteOffset = 0; dte->dataLength = 0; dte->reserved = 0; dte->streamDescIndex = 0; //can be -1 in QT , so init at -2 dte->trackRefIndex = (s8) -2; return (GF_GenericDTE *)dte;}//creation of DTEsGF_GenericDTE *NewDTE(u8 type){ switch (type) { case 0: return New_EmptyDTE(); case 1: return New_ImmediateDTE(); case 2: return New_SampleDTE(); case 3: return New_StreamDescDTE(); default: return NULL; }}/******************************************************************** Deletion of DataTable entries in the RTP sample********************************************************************/void Del_EmptyDTE(GF_EmptyDTE *dte){ free(dte); }void Del_ImmediateDTE(GF_ImmediateDTE *dte){ free(dte); }void Del_SampleDTE(GF_SampleDTE *dte){ free(dte); }void Del_StreamDescDTE(GF_StreamDescDTE *dte){ free(dte); }//deletion of DTEsvoid DelDTE(GF_GenericDTE *dte){ switch (dte->source) { case 0: Del_EmptyDTE((GF_EmptyDTE *)dte); break; case 1: Del_ImmediateDTE((GF_ImmediateDTE *)dte); break; case 2: Del_SampleDTE((GF_SampleDTE *)dte); break; case 3: Del_StreamDescDTE((GF_StreamDescDTE *)dte); break; default: return; }}/******************************************************************** Reading of DataTable entries in the RTP sample********************************************************************/GF_Err Read_EmptyDTE(GF_EmptyDTE *dte, GF_BitStream *bs){ char empty[15]; //empty but always 15 bytes !!! gf_bs_read_data(bs, empty, 15); return GF_OK;}GF_Err Read_ImmediateDTE(GF_ImmediateDTE *dte, GF_BitStream *bs){ dte->dataLength = gf_bs_read_u8(bs); if (dte->dataLength > 14) return GF_ISOM_INVALID_FILE; gf_bs_read_data(bs, dte->data, dte->dataLength); if (dte->dataLength < 14) gf_bs_skip_bytes(bs, 14 - dte->dataLength); return GF_OK;}GF_Err Read_SampleDTE(GF_SampleDTE *dte, GF_BitStream *bs){ dte->trackRefIndex = gf_bs_read_u8(bs); dte->dataLength = gf_bs_read_u16(bs); dte->sampleNumber = gf_bs_read_u32(bs); dte->byteOffset = gf_bs_read_u32(bs); dte->bytesPerComp = gf_bs_read_u16(bs); dte->samplesPerComp = gf_bs_read_u16(bs); return GF_OK;}GF_Err Read_StreamDescDTE(GF_StreamDescDTE *dte, GF_BitStream *bs){ dte->trackRefIndex = gf_bs_read_u8(bs); dte->dataLength = gf_bs_read_u16(bs); dte->streamDescIndex = gf_bs_read_u32(bs); dte->byteOffset = gf_bs_read_u32(bs); dte->reserved = gf_bs_read_u32(bs); return GF_OK;}GF_Err ReadDTE(GF_GenericDTE *dte, GF_BitStream *bs){ switch (dte->source) { case 0: //nothing to o, it is an empty entry return Read_EmptyDTE((GF_EmptyDTE *)dte, bs); case 1: return Read_ImmediateDTE((GF_ImmediateDTE *)dte, bs); case 2: return Read_SampleDTE((GF_SampleDTE *)dte, bs); case 3: return Read_StreamDescDTE((GF_StreamDescDTE *)dte, bs); default: return GF_ISOM_INVALID_FILE; }}/******************************************************************** Writing of DataTable entries in the RTP sample********************************************************************/GF_Err Write_EmptyDTE(GF_EmptyDTE *dte, GF_BitStream *bs){ gf_bs_write_u8(bs, dte->source); //empty but always 15 bytes !!! gf_bs_write_data(bs, "empty hint DTE", 15);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -