2 Copyright (c) 2005-2006, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \brief MXF index segment objects
36 ASDCP::MXF::IndexTableSegment::IndexTableSegment() :
37 IndexStartPosition(0), IndexDuration(0), EditUnitByteCount(0),
38 IndexSID(0), BodySID(0), SliceCount(0), PosTableCount(0)
43 ASDCP::MXF::IndexTableSegment::~IndexTableSegment()
49 ASDCP::MXF::IndexTableSegment::InitFromBuffer(const byte_t* p, ui32_t l)
53 Result_t result = KLVPacket::InitFromBuffer(p, l, s_MDD_Table[MDDindex_IndexTableSegment].ul);
55 if ( ASDCP_SUCCESS(result) )
57 TLVReader MemRDR(m_ValueStart, m_ValueLength, m_Lookup);
59 result = MemRDR.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID));
60 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
61 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
62 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
63 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
64 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
65 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
66 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
67 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
68 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
69 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
72 if ( ASDCP_SUCCESS(result) )
74 Batch<IndexEntry>::iterator i;
76 for ( i = IndexEntryArray.begin(); i != IndexEntryArray.end(); i++ )
78 if ( (*i).Flags == 0x40 )
81 (*i).KeyFrameOffset = offset++;
90 ASDCP::MXF::IndexTableSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
92 return WriteKLToBuffer(Buffer, s_MDD_Table[MDDindex_IndexTableSegment].ul, 0);
94 Result_t result = KLVPacket::InitFromBuffer(p, l, s_MDD_Table[MDDindex_IndexTableSegment].ul);
96 if ( ASDCP_SUCCESS(result) )
98 TLVWriter MemRDR(m_ValueStart, m_ValueLength, m_Lookup);
100 result = MemRDR.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID));
101 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
102 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
103 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
104 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
105 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
106 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
107 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
108 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
109 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
110 if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
119 ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
121 char identbuf[IdentBufferLen];
126 KLVPacket::Dump(stream, false);
127 fprintf(stream, " InstanceUID = %s\n", InstanceUID.ToString(identbuf));
128 fprintf(stream, " IndexEditRate = %s\n", IndexEditRate.ToString(identbuf));
129 fprintf(stream, " IndexStartPosition = %s\n", i64sz(IndexStartPosition, identbuf));
130 fprintf(stream, " IndexDuration = %s\n", i64sz(IndexDuration, identbuf));
131 fprintf(stream, " EditUnitByteCount = %lu\n", EditUnitByteCount);
132 fprintf(stream, " IndexSID = %lu\n", IndexSID);
133 fprintf(stream, " BodySID = %lu\n", BodySID);
134 fprintf(stream, " SliceCount = %hu\n", SliceCount);
135 fprintf(stream, " PosTableCount = %hu\n", PosTableCount);
137 fprintf(stream, " DeltaEntryArray:\n"); DeltaEntryArray.Dump(stream);
139 if ( IndexEntryArray.size() < 100 )
141 fprintf(stream, " IndexEntryArray:\n");
142 IndexEntryArray.Dump(stream);
146 fprintf(stream, " IndexEntryArray: %lu entries\n", IndexEntryArray.size());
149 fputs("==========================================================================\n", stream);
154 ASDCP::MXF::IndexTableSegment::DeltaEntry::ToString(char* str_buf) const
156 sprintf(str_buf, "%3i %-3hu %-3lu", PosTableIndex, Slice, ElementData);
162 ASDCP::MXF::IndexTableSegment::DeltaEntry::ReadFrom(ASDCP::MemIOReader& Reader)
164 Result_t result = Reader.ReadUi8((ui8_t*)&PosTableIndex);
165 if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Slice);
166 if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi32BE(&ElementData);
172 ASDCP::MXF::IndexTableSegment::DeltaEntry::WriteTo(ASDCP::MemIOWriter& Writer)
174 Result_t result = Writer.WriteUi8((ui8_t)PosTableIndex);
175 if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Slice);
176 if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi32BE(ElementData);
181 // Bit 7: Random Access
182 // Bit 6: Sequence Header
183 // Bit 5: forward prediction flag
184 // Bit 4: backward prediction flag
186 // 00== I frame (no prediction)
187 // 10== P frame(forward prediction from previous frame)
188 // 01== B frame (backward prediction from future frame)
189 // 11== B frame (forward & backward prediction)
190 // Bits 0-3: reserved [RP210 Flags to indicate coding of elements in this edit unit]
194 ASDCP::MXF::IndexTableSegment::IndexEntry::ToString(char* str_buf) const
196 char intbuf[IntBufferLen];
200 txt_flags[0] = ( (Flags & 0x80) != 0 ) ? 'r' : ' ';
201 txt_flags[1] = ( (Flags & 0x40) != 0 ) ? 's' : ' ';
202 txt_flags[2] = ( (Flags & 0x20) != 0 ) ? 'f' : ' ';
203 txt_flags[3] = ( (Flags & 0x10) != 0 ) ? 'b' : ' ';
204 txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
206 sprintf(str_buf, "%3i %-3hu %s %s",
207 TemporalOffset, KeyFrameOffset, txt_flags,
208 i64sz(StreamOffset, intbuf));
215 ASDCP::MXF::IndexTableSegment::IndexEntry::ReadFrom(ASDCP::MemIOReader& Reader)
217 Result_t result = Reader.ReadUi8((ui8_t*)&TemporalOffset);
218 if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8((ui8_t*)&KeyFrameOffset);
219 if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Flags);
220 if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi64BE(&StreamOffset);
226 ASDCP::MXF::IndexTableSegment::IndexEntry::WriteTo(ASDCP::MemIOWriter& Writer)
228 Result_t result = Writer.WriteUi8((ui8_t)TemporalOffset);
229 if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8((ui8_t)KeyFrameOffset);
230 if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Flags);
231 if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi64BE(StreamOffset);