📄 avc_ext.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>#include <gpac/constants.h>void AVC_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *avc){ if (avc->emul_esd) gf_odf_desc_del((GF_Descriptor *)avc->emul_esd); avc->emul_esd = gf_odf_desc_esd_new(2); avc->emul_esd->decoderConfig->streamType = GF_STREAM_VISUAL; /*AVC OTI is 0x21, AVC parameter set stream OTI (not supported in gpac) is 0x22*/ avc->emul_esd->decoderConfig->objectTypeIndication = 0x21; if (avc->bitrate) { avc->emul_esd->decoderConfig->bufferSizeDB = avc->bitrate->bufferSizeDB; avc->emul_esd->decoderConfig->avgBitrate = avc->bitrate->avgBitrate; avc->emul_esd->decoderConfig->maxBitrate = avc->bitrate->maxBitrate; } if (avc->descr) { u32 i=0; GF_Descriptor *desc,*clone; i=0; while ((desc = (GF_Descriptor *)gf_list_enum(avc->descr->descriptors, &i))) { clone = NULL; gf_odf_desc_copy(desc, &clone); if (gf_odf_desc_add_desc((GF_Descriptor *)avc->emul_esd, clone) != GF_OK) gf_odf_desc_del(clone); } } if (avc->avc_config && avc->avc_config->config) { gf_odf_avc_cfg_write(avc->avc_config->config, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); }}GF_Err AVC_UpdateESD(GF_MPEGVisualSampleEntryBox *avc, GF_ESD *esd){ if (!avc->bitrate) avc->bitrate = (GF_MPEG4BitRateBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_BTRT); if (avc->descr) gf_isom_box_del((GF_Box *) avc->descr); avc->descr = NULL; avc->bitrate->avgBitrate = esd->decoderConfig->avgBitrate; avc->bitrate->maxBitrate = esd->decoderConfig->maxBitrate; avc->bitrate->bufferSizeDB = esd->decoderConfig->bufferSizeDB; if (gf_list_count(esd->IPIDataSet) || gf_list_count(esd->IPMPDescriptorPointers) || esd->langDesc || gf_list_count(esd->extensionDescriptors) || esd->ipiPtr || esd->qos || esd->RegDescriptor) { avc->descr = (GF_MPEG4ExtensionDescriptorsBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_M4DS); if (esd->RegDescriptor) { gf_list_add(avc->descr->descriptors, esd->RegDescriptor); esd->RegDescriptor = NULL; } if (esd->qos) { gf_list_add(avc->descr->descriptors, esd->qos); esd->qos = NULL; } if (esd->ipiPtr) { gf_list_add(avc->descr->descriptors, esd->ipiPtr); esd->ipiPtr= NULL; } while (gf_list_count(esd->IPIDataSet)) { GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPIDataSet, 0); gf_list_rem(esd->IPIDataSet, 0); gf_list_add(avc->descr->descriptors, desc); } while (gf_list_count(esd->IPMPDescriptorPointers)) { GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPMPDescriptorPointers, 0); gf_list_rem(esd->IPMPDescriptorPointers, 0); gf_list_add(avc->descr->descriptors, desc); } if (esd->langDesc) { gf_list_add(avc->descr->descriptors, esd->langDesc); esd->langDesc = NULL; } while (gf_list_count(esd->extensionDescriptors)) { GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->extensionDescriptors, 0); gf_list_rem(esd->extensionDescriptors, 0); gf_list_add(avc->descr->descriptors, desc); } } /*update GF_AVCConfig*/ if (!avc->avc_config) avc->avc_config = (GF_AVCConfigurationBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_AVCC); if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { if (avc->avc_config->config) gf_odf_avc_cfg_del(avc->avc_config->config); avc->avc_config->config = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); } gf_odf_desc_del((GF_Descriptor *)esd); AVC_RewriteESDescriptor(avc); return GF_OK;}static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg){ u32 i, count; GF_AVCConfigSlot *p1, *p2; GF_AVCConfig *cfg_new = gf_odf_avc_cfg_new(); cfg_new->AVCLevelIndication = cfg->AVCLevelIndication; cfg_new->AVCProfileIndication = cfg->AVCProfileIndication; cfg_new->configurationVersion = cfg->configurationVersion; cfg_new->nal_unit_size = cfg->nal_unit_size; cfg_new->profile_compatibility = cfg->profile_compatibility; count = gf_list_count(cfg->sequenceParameterSets); for (i=0; i<count; i++) { p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->sequenceParameterSets, i); p2 = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); p2->size = p1->size; p2->data = (char *)malloc(sizeof(char)*p1->size); memcpy(p2->data, p1->data, sizeof(char)*p1->size); gf_list_add(cfg_new->sequenceParameterSets, p2); } count = gf_list_count(cfg->pictureParameterSets); for (i=0; i<count; i++) { p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->pictureParameterSets, i); p2 = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); p2->size = p1->size; p2->data = (char*)malloc(sizeof(char)*p1->size); memcpy(p2->data, p1->data, sizeof(char)*p1->size); gf_list_add(cfg_new->pictureParameterSets, p2); } return cfg_new; }#ifndef GPAC_READ_ONLYGF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex){ GF_TrackBox *trak; GF_Err e; u32 dataRefIndex; GF_TrackReferenceTypeBox *dpnd; GF_TrackReferenceBox *tref; GF_MPEGVisualSampleEntryBox *entry; e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; dpnd = NULL; tref = NULL; //get or create the data ref e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); if (e) return e; if (!dataRefIndex) { e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); if (e) return e; } trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); //create a new entry entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_AVC1); if (!entry) return GF_OUT_OF_MEM; entry->avc_config = (GF_AVCConfigurationBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_AVCC); entry->avc_config->config = AVC_DuplicateConfig(cfg); entry->dataReferenceIndex = dataRefIndex; e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->boxList, entry); *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList); AVC_RewriteESDescriptor(entry); return e;}GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg){ GF_TrackBox *trak; GF_Err e; GF_MPEGVisualSampleEntryBox *entry; e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !trak->Media || !cfg || !DescriptionIndex) return GF_BAD_PARAM; entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1); if (!entry) return GF_BAD_PARAM; if (entry->type != GF_ISOM_BOX_TYPE_AVC1) return GF_BAD_PARAM; if (entry->avc_config->config) gf_odf_avc_cfg_del(entry->avc_config->config); entry->avc_config->config = AVC_DuplicateConfig(cfg); AVC_RewriteESDescriptor(entry); return GF_OK;}GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber){ static u8 ipod_ext[][16] = { { 0x6B, 0x68, 0x40, 0xF2, 0x5F, 0x24, 0x4F, 0xC5, 0xBA, 0x39, 0xA5, 0x1B, 0xCF, 0x03, 0x23, 0xF3} }; GF_TrackBox *trak; GF_Err e; GF_MPEGVisualSampleEntryBox *entry; e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !trak->Media) return GF_BAD_PARAM; entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0); if (!entry) return GF_OK; if (entry->type != GF_ISOM_BOX_TYPE_AVC1) return GF_OK; if (!entry->ipod_ext) entry->ipod_ext = (GF_UnknownUUIDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_UUID); memcpy(entry->ipod_ext->uuid, ipod_ext, sizeof(u8)*16); entry->ipod_ext->dataSize = 0; return GF_OK;}#endifGF_EXPORTGF_AVCConfig *gf_isom_avc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex){ GF_TrackBox *trak;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -