MP4AvspAtom::MP4AvspAtom() : MP4Atom("avsp") { AddReserved("reserved1", 6); /* 0 */ AddProperty( /* 1 */ new MP4Integer16Property("dataReferenceIndex")); AddReserved("reserved2", 16); /* 2 */ AddProperty( /* 3 */ new MP4Integer16Property("width")); AddProperty( /* 4 */ new MP4Integer16Property("height")); AddReserved("reserved3", 14); /* 5 */ MP4StringProperty* pProp = new MP4StringProperty("compressorName"); pProp->SetFixedLength(32); pProp->SetValue("AVS-M Parameters"); AddProperty(pProp); /* 6 */ AddReserved("reserved4", 4); /* 7 */ ExpectChildAtom("avsc", Required, OnlyOne); ExpectChildAtom("btrt", Optional, OnlyOne); // for now ExpectChildAtom("m4ds", Optional, OnlyOne); }
MP4EncvAtom::MP4EncvAtom() : MP4Atom("encv") { AddReserved("reserved1", 6); /* 0 */ AddProperty( /* 1 */ new MP4Integer16Property("dataReferenceIndex")); AddReserved("reserved2", 16); /* 2 */ AddProperty( /* 3 */ new MP4Integer16Property("width")); AddProperty( /* 4 */ new MP4Integer16Property("height")); AddReserved("reserved3", 14); /* 5 */ MP4StringProperty* pProp = new MP4StringProperty("compressorName"); pProp->SetFixedLength(32); pProp->SetValue(""); AddProperty(pProp); /* 6 */ AddReserved("reserved4", 4); /* 7 */ ExpectChildAtom("esds", Required, OnlyOne); ExpectChildAtom("sinf", Required, OnlyOne); ExpectChildAtom("avcC", Optional, OnlyOne); }
MP4Mp4vAtom::MP4Mp4vAtom(MP4File &file) : MP4Atom(file, "mp4v") { AddReserved(*this, "reserved1", 6); /* 0 */ AddProperty( /* 1 */ new MP4Integer16Property(*this, "dataReferenceIndex")); AddReserved(*this, "reserved2", 16); /* 2 */ AddProperty( /* 3 */ new MP4Integer16Property(*this, "width")); AddProperty( /* 4 */ new MP4Integer16Property(*this, "height")); AddReserved(*this, "reserved3", 14); /* 5 */ MP4StringProperty* pProp = new MP4StringProperty(*this, "compressorName"); pProp->SetFixedLength(32); pProp->SetCountedFormat(true); pProp->SetValue(""); AddProperty(pProp); /* 6 */ AddReserved(*this, "reserved4", 4); /* 7 */ ExpectChildAtom("colr", Optional, OnlyOne); ExpectChildAtom("esds", Required, OnlyOne); ExpectChildAtom("pasp", Optional, OnlyOne); }
MP4VideoAtom::MP4VideoAtom (const char *type) : MP4Atom(type) { AddReserved("reserved1", 6); /* 0 */ AddProperty( /* 1 */ new MP4Integer16Property("dataReferenceIndex")); AddReserved("reserved2", 16); /* 2 */ AddProperty( /* 3 */ new MP4Integer16Property("width")); AddProperty( /* 4 */ new MP4Integer16Property("height")); AddReserved("reserved3", 14); /* 5 */ MP4StringProperty* pProp = new MP4StringProperty("compressorName"); pProp->SetFixedLength(32); pProp->SetCountedFormat(true); pProp->SetValue(""); AddProperty(pProp); /* 6 */ AddProperty(/* 7 */ new MP4Integer16Property("depth")); AddProperty(/* 8 */ new MP4Integer16Property("colorTableId")); ExpectChildAtom("smi ", Optional, OnlyOne); }
void MP4File::MakeFtypAtom(char* majorBrand, u_int32_t minorVersion, char** supportedBrands, u_int32_t supportedBrandsCount) { bool rewriteNeeded = false; u_int32_t currentSupportedBrandsCount; u_int32_t i; MP4Atom* ftypAtom = m_pRootAtom->FindAtom("ftyp"); if (ftypAtom == NULL) { ftypAtom = InsertChildAtom(m_pRootAtom, "ftyp", 0); } if (majorBrand == NULL) return; MP4StringProperty* pMajorBrandProperty; if (!ftypAtom->FindProperty( "ftyp.majorBrand", (MP4Property**)&pMajorBrandProperty)) return; pMajorBrandProperty->SetValue(majorBrand); MP4Integer32Property* pMinorVersionProperty; if (!ftypAtom->FindProperty( "ftype.minorVersion", (MP4Property**)&pMinorVersionProperty)) return; pMinorVersionProperty->SetValue(minorVersion); MP4Integer32Property* pCompatibleBrandsCountProperty; if (!ftypAtom->FindProperty( "ftyp.compatibleBrandsCount", (MP4Property**)&pCompatibleBrandsCountProperty)) return; currentSupportedBrandsCount = pCompatibleBrandsCountProperty->GetValue(); MP4TableProperty* pCompatibleBrandsProperty; if (!ftypAtom->FindProperty( "ftyp.compatibleBrands", (MP4Property**)&pCompatibleBrandsProperty)) return; MP4StringProperty* pBrandProperty = (MP4StringProperty*) pCompatibleBrandsProperty->GetProperty(0); ASSERT(pBrandProperty); for (i = 0 ; i < ((currentSupportedBrandsCount > supportedBrandsCount) ? supportedBrandsCount : currentSupportedBrandsCount) ; i++) { pBrandProperty->SetValue(supportedBrands[i], i); } if (i < supportedBrandsCount) { for ( ; i < supportedBrandsCount ; i++) { pBrandProperty->AddValue(supportedBrands[i]); } } if (currentSupportedBrandsCount != supportedBrandsCount) { rewriteNeeded = true; pBrandProperty->SetCount(supportedBrandsCount); pCompatibleBrandsCountProperty->SetReadOnly(false); pCompatibleBrandsCountProperty->SetValue(supportedBrandsCount); pCompatibleBrandsCountProperty->SetReadOnly(true); } }
MP4Descriptor* MP4File::CreateESD( MP4DescriptorProperty* pEsProperty, u_int32_t esid, u_int8_t objectType, u_int8_t streamType, u_int32_t bufferSize, u_int32_t bitrate, u_int8_t* pConfig, u_int32_t configLength, char* url) { MP4IntegerProperty* pInt; MP4StringProperty* pString; MP4BytesProperty* pBytes; MP4BitfieldProperty* pBits; MP4Descriptor* pEsd = pEsProperty->AddDescriptor(MP4ESDescrTag); pEsd->Generate(); pEsd->FindProperty("ESID", (MP4Property**)&pInt); pInt->SetValue(esid); pEsd->FindProperty("decConfigDescr.objectTypeId", (MP4Property**)&pInt); pInt->SetValue(objectType); pEsd->FindProperty("decConfigDescr.streamType", (MP4Property**)&pInt); pInt->SetValue(streamType); pEsd->FindProperty("decConfigDescr.bufferSizeDB", (MP4Property**)&pInt); pInt->SetValue(bufferSize); pEsd->FindProperty("decConfigDescr.maxBitrate", (MP4Property**)&pInt); pInt->SetValue(bitrate); pEsd->FindProperty("decConfigDescr.avgBitrate", (MP4Property**)&pInt); pInt->SetValue(bitrate); MP4DescriptorProperty* pConfigDescrProperty; pEsd->FindProperty("decConfigDescr.decSpecificInfo", (MP4Property**)&pConfigDescrProperty); MP4Descriptor* pConfigDescr = pConfigDescrProperty->AddDescriptor(MP4DecSpecificDescrTag); pConfigDescr->Generate(); pConfigDescrProperty->FindProperty("decSpecificInfo[0].info", (MP4Property**)&pBytes); pBytes->SetValue(pConfig, configLength); pEsd->FindProperty("slConfigDescr.predefined", (MP4Property**)&pInt); // changed 12/5/02 from plugfest to value 0 pInt->SetValue(0); pEsd->FindProperty("slConfig.useAccessUnitEndFlag", (MP4Property **)&pBits); pBits->SetValue(1); if (url) { pEsd->FindProperty("URLFlag", (MP4Property**)&pInt); pInt->SetValue(1); pEsd->FindProperty("URL", (MP4Property**)&pString); pString->SetValue(url); } return pEsd; }
void MP4File::CreateIsmaIodFromFile( MP4TrackId odTrackId, MP4TrackId sceneTrackId, MP4TrackId audioTrackId, MP4TrackId videoTrackId, u_int8_t** ppBytes, u_int64_t* pNumBytes) { MP4Descriptor* pIod = new MP4IODescriptor(); pIod->SetTag(MP4IODescrTag); pIod->Generate(); MP4Atom* pIodsAtom = FindAtom("moov.iods"); ASSERT(pIodsAtom); MP4DescriptorProperty* pSrcIod = (MP4DescriptorProperty*)pIodsAtom->GetProperty(2); CloneIntegerProperty(pIod, pSrcIod, "objectDescriptorId"); CloneIntegerProperty(pIod, pSrcIod, "ODProfileLevelId"); CloneIntegerProperty(pIod, pSrcIod, "sceneProfileLevelId"); CloneIntegerProperty(pIod, pSrcIod, "audioProfileLevelId"); CloneIntegerProperty(pIod, pSrcIod, "visualProfileLevelId"); CloneIntegerProperty(pIod, pSrcIod, "graphicsProfileLevelId"); // mutate esIds from MP4ESIDIncDescrTag to MP4ESDescrTag MP4DescriptorProperty* pEsProperty; pIod->FindProperty("esIds", (MP4Property**)&pEsProperty); pEsProperty->SetTags(MP4ESDescrTag); MP4IntegerProperty* pSetProperty; MP4IntegerProperty* pSceneESID; MP4IntegerProperty* pOdESID; // OD MP4Descriptor* pOdEsd = pEsProperty->AddDescriptor(MP4ESDescrTag); pOdEsd->Generate(); pOdEsd->FindProperty("ESID", (MP4Property**)&pOdESID); // we set the OD ESID to a non-zero unique value pOdESID->SetValue(m_odTrackId); pOdEsd->FindProperty("URLFlag", (MP4Property**)&pSetProperty); pSetProperty->SetValue(1); u_int8_t* pBytes; u_int64_t numBytes; CreateIsmaODUpdateCommandFromFileForStream( audioTrackId, videoTrackId, &pBytes, &numBytes); VERBOSE_ISMA(GetVerbosity(), printf("OD data =\n"); MP4HexDump(pBytes, numBytes)); char* odCmdBase64 = MP4ToBase64(pBytes, numBytes); char* urlBuf = (char*)MP4Malloc(strlen(odCmdBase64) + 64); sprintf(urlBuf, "data:application/mpeg4-od-au;base64,%s", odCmdBase64); MP4StringProperty* pUrlProperty; pOdEsd->FindProperty("URL", (MP4Property**)&pUrlProperty); pUrlProperty->SetValue(urlBuf); VERBOSE_ISMA(GetVerbosity(), printf("OD data URL = \042%s\042\n", urlBuf)); MP4Free(odCmdBase64); odCmdBase64 = NULL; MP4Free(pBytes); pBytes = NULL; MP4Free(urlBuf); urlBuf = NULL; MP4DescriptorProperty* pSrcDcd = NULL; // HACK temporarily point to scene decoder config FindProperty(MakeTrackName(odTrackId, "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"), (MP4Property**)&pSrcDcd); ASSERT(pSrcDcd); MP4Property* pOrgOdEsdProperty = pOdEsd->GetProperty(8); pOdEsd->SetProperty(8, pSrcDcd); // bufferSizeDB needs to be set appropriately MP4BitfieldProperty* pBufferSizeProperty = NULL; pOdEsd->FindProperty("decConfigDescr.bufferSizeDB", (MP4Property**)&pBufferSizeProperty); ASSERT(pBufferSizeProperty); pBufferSizeProperty->SetValue(numBytes); // SL config needs to change from 2 (file) to 1 (null) pOdEsd->FindProperty("slConfigDescr.predefined", (MP4Property**)&pSetProperty); pSetProperty->SetValue(1); // Scene MP4Descriptor* pSceneEsd = pEsProperty->AddDescriptor(MP4ESDescrTag); pSceneEsd->Generate(); pSceneEsd->FindProperty("ESID", (MP4Property**)&pSceneESID); // we set the Scene ESID to a non-zero unique value pSceneESID->SetValue(sceneTrackId); pSceneEsd->FindProperty("URLFlag", (MP4Property**)&pSetProperty); pSetProperty->SetValue(1); CreateIsmaSceneCommand( MP4_IS_VALID_TRACK_ID(audioTrackId), MP4_IS_VALID_TRACK_ID(videoTrackId), &pBytes, &numBytes); VERBOSE_ISMA(GetVerbosity(), printf("Scene data =\n"); MP4HexDump(pBytes, numBytes)); char *sceneCmdBase64 = MP4ToBase64(pBytes, numBytes); urlBuf = (char*)MP4Malloc(strlen(sceneCmdBase64) + 64); sprintf(urlBuf, "data:application/mpeg4-bifs-au;base64,%s", sceneCmdBase64); pSceneEsd->FindProperty("URL", (MP4Property**)&pUrlProperty); pUrlProperty->SetValue(urlBuf); VERBOSE_ISMA(GetVerbosity(), printf("Scene data URL = \042%s\042\n", urlBuf)); MP4Free(sceneCmdBase64); sceneCmdBase64 = NULL; MP4Free(urlBuf); urlBuf = NULL; MP4Free(pBytes); pBytes = NULL; // HACK temporarily point to scene decoder config FindProperty(MakeTrackName(sceneTrackId, "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"), (MP4Property**)&pSrcDcd); ASSERT(pSrcDcd); MP4Property* pOrgSceneEsdProperty = pSceneEsd->GetProperty(8); pSceneEsd->SetProperty(8, pSrcDcd); // bufferSizeDB needs to be set pBufferSizeProperty = NULL; pSceneEsd->FindProperty("decConfigDescr.bufferSizeDB", (MP4Property**)&pBufferSizeProperty); ASSERT(pBufferSizeProperty); pBufferSizeProperty->SetValue(numBytes); // SL config needs to change from 2 (file) to 1 (null) pSceneEsd->FindProperty("slConfigDescr.predefined", (MP4Property**)&pSetProperty); pSetProperty->SetValue(1); // finally get the whole thing written to a memory pIod->WriteToMemory(this, ppBytes, pNumBytes); // now carefully replace esd properties before destroying pOdEsd->SetProperty(8, pOrgOdEsdProperty); pSceneEsd->SetProperty(8, pOrgSceneEsdProperty); pSceneESID->SetValue(0); // restore 0 value pOdESID->SetValue(0); delete pIod; VERBOSE_ISMA(GetVerbosity(), printf("IOD data =\n"); MP4HexDump(*ppBytes, *pNumBytes)); }