void Rat_to_extended(ASDCP::Rational rate, byte_t* buf) { memset(buf, 0, 10); ui32_t value = (ui32_t)ceil(rate.Quotient()); ui32_t exp = value; exp >>= 1; ui8_t i = 0; for ( ; i < 32; i++ ) { exp >>= 1; if ( ! exp ) break; } *(buf+1) = i; for ( i = 32; i != 0 ; i-- ) { if ( value & 0x80000000 ) break; value <<= 1; } *(ui32_t*)(buf+2) = KM_i32_BE(value); }
// all the above for a single source clip Result_t AS_02::PHDR::MXFWriter::h__Writer::WritePHDRHeader(const std::string& PackageLabel, const ASDCP::UL& WrappingUL, const std::string& TrackName, const ASDCP::UL& EssenceUL, const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate, const ui32_t& TCFrameRate) { if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 ) { DefaultLogSink().Error("Non-zero edit-rate reqired.\n"); return RESULT_PARAM; } InitHeader(); AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel); // add metadata track TrackSet<SourceClip> metdata_track = CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage, MD_DEF_LABEL, EditRate, UL(m_Dict->ul(MDD_PHDRImageMetadataItem)), 3 /* track id */, m_Dict); metdata_track.Sequence->Duration.set_has_value(); m_DurationUpdateList.push_back(&(metdata_track.Sequence->Duration.get())); // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from. metdata_track.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((UL(m_MetadataUL).Value() + 12))); metdata_track.Clip = new SourceClip(m_Dict); m_HeaderPart.AddChildObject(metdata_track.Clip); metdata_track.Sequence->StructuralComponents.push_back(metdata_track.Clip->InstanceUID); metdata_track.Clip->DataDefinition = UL(m_Dict->ul(MDD_PHDRImageMetadataWrappingFrame)); // for now we do not allow setting this value, so all files will be 'original' metdata_track.Clip->SourceTrackID = 0; metdata_track.Clip->SourcePackageID = NilUMID; metdata_track.Clip->Duration.set_has_value(); m_DurationUpdateList.push_back(&(metdata_track.Clip->Duration.get())); // add PHDR subdescriptor m_MetadataTrackSubDescriptor = new PHDRMetadataTrackSubDescriptor(m_Dict); m_EssenceSubDescriptorList.push_back(m_MetadataTrackSubDescriptor); GenRandomValue(m_MetadataTrackSubDescriptor->InstanceUID); m_EssenceDescriptor->SubDescriptors.push_back(m_MetadataTrackSubDescriptor->InstanceUID); m_MetadataTrackSubDescriptor->DataDefinition = UL(m_Dict->ul(MDD_PHDRImageMetadataWrappingFrame)); m_MetadataTrackSubDescriptor->SourceTrackID = 3; m_MetadataTrackSubDescriptor->SimplePayloadSID = 0; AddEssenceDescriptor(WrappingUL); m_IndexWriter.SetPrimerLookup(&m_HeaderPart.m_Primer); m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry m_IndexWriter.OperationalPattern = m_HeaderPart.OperationalPattern; m_IndexWriter.EssenceContainers = m_HeaderPart.EssenceContainers; Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); if ( KM_SUCCESS(result) ) { m_PartitionSpace *= floor( EditRate.Quotient() + 0.5 ); // convert seconds to edit units m_ECStart = m_File.Tell(); m_IndexWriter.IndexSID = 129; UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); Partition body_part(m_Dict); body_part.BodySID = 1; body_part.OperationalPattern = m_HeaderPart.OperationalPattern; body_part.EssenceContainers = m_HeaderPart.EssenceContainers; body_part.ThisPartition = m_ECStart; result = body_part.WriteToFile(m_File, body_ul); m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); // Second RIP Entry } return result; }