9d1791ad68944074b23baacc753a78b531ea5e6d
[asdcplib.git] / src / Index.cpp
1 //
2 // Index.cpp
3 //
4
5 #include "MDD.h"
6 #include "MXF.h"
7
8 //
9 ASDCP::MXF::IndexTableSegment::IndexTableSegment() :
10   IndexStartPosition(0), IndexDuration(0), EditUnitByteCount(0),
11   IndexSID(0), BodySID(0), SliceCount(0), PosTableCount(0)
12 {
13 }
14
15 //
16 ASDCP::MXF::IndexTableSegment::~IndexTableSegment()
17 {
18 }
19
20 //
21 ASDCP::Result_t
22 ASDCP::MXF::IndexTableSegment::InitFromBuffer(const byte_t* p, ui32_t l)
23 {
24   ASDCP_TEST_NULL(p);
25
26   Result_t result = KLVPacket::InitFromBuffer(p, l, s_MDD_Table[MDDindex_IndexTableSegment].ul);
27
28   if ( ASDCP_SUCCESS(result) )
29     {
30       TLVReader MemRDR(m_ValueStart, m_ValueLength, m_Lookup);
31
32       result = MemRDR.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID));
33       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
34       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
35       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
36       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
37       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
38       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
39       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
40       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
41       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
42       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
43     }
44
45   if ( ASDCP_SUCCESS(result) )
46     {
47       Batch<IndexEntry>::iterator i;
48       ui32_t offset = 0;
49       for ( i = IndexEntryArray.begin(); i != IndexEntryArray.end(); i++ )
50         {
51           if ( (*i).Flags == 0x40 )
52             offset = 0;
53
54           (*i).KeyFrameOffset = offset++;
55         }
56     }
57
58   return result;
59 }
60
61 //
62 ASDCP::Result_t
63 ASDCP::MXF::IndexTableSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
64 {
65   return WriteKLToBuffer(Buffer, s_MDD_Table[MDDindex_IndexTableSegment].ul, 0);
66 #if 0
67   Result_t result = KLVPacket::InitFromBuffer(p, l, s_MDD_Table[MDDindex_IndexTableSegment].ul);
68
69   if ( ASDCP_SUCCESS(result) )
70     {
71       TLVWriter MemRDR(m_ValueStart, m_ValueLength, m_Lookup);
72
73       result = MemRDR.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID));
74       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
75       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
76       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
77       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
78       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
79       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
80       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
81       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
82       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
83       if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
84     }
85
86   return result;
87 #endif
88 }
89
90 //
91 void
92 ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
93 {
94   char identbuf[IdentBufferLen];
95
96   if ( stream == 0 )
97     stream = stderr;
98
99   KLVPacket::Dump(stream, false);
100   fprintf(stream, "  InstanceUID        = %s\n",  InstanceUID.ToString(identbuf));
101   fprintf(stream, "  IndexEditRate      = %s\n",  IndexEditRate.ToString(identbuf));
102   fprintf(stream, "  IndexStartPosition = %s\n",  i64sz(IndexStartPosition, identbuf));
103   fprintf(stream, "  IndexDuration      = %s\n",  i64sz(IndexDuration, identbuf));
104   fprintf(stream, "  EditUnitByteCount  = %lu\n", EditUnitByteCount);
105   fprintf(stream, "  IndexSID           = %lu\n", IndexSID);
106   fprintf(stream, "  BodySID            = %lu\n", BodySID);
107   fprintf(stream, "  SliceCount         = %hu\n", SliceCount);
108   fprintf(stream, "  PosTableCount      = %hu\n", PosTableCount);
109
110   fprintf(stream, "  DeltaEntryArray:\n");  DeltaEntryArray.Dump(stream);
111   fprintf(stream, "  IndexEntryArray:\n");  IndexEntryArray.Dump(stream);
112
113   fputs("==========================================================================\n", stream);
114 }
115
116 //
117 const char*
118 ASDCP::MXF::IndexTableSegment::DeltaEntry::ToString(char* str_buf) const
119 {
120   sprintf(str_buf, "%3i %-3hu %-3lu", PosTableIndex, Slice, ElementData);
121   return str_buf;
122 }
123
124 //
125 ASDCP::Result_t
126 ASDCP::MXF::IndexTableSegment::DeltaEntry::ReadFrom(ASDCP::MemIOReader& Reader)
127 {
128   Result_t result = Reader.ReadUi8((ui8_t*)&PosTableIndex);
129   if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Slice);
130   if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi32BE(&ElementData);
131   return result;
132 }
133
134 //
135 ASDCP::Result_t
136 ASDCP::MXF::IndexTableSegment::DeltaEntry::WriteTo(ASDCP::MemIOWriter& Writer)
137 {
138   Result_t result = Writer.WriteUi8((ui8_t)PosTableIndex);
139   if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Slice);
140   if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi32BE(ElementData);
141   return result;
142 }
143
144 // Flags:
145 // Bit 7: Random Access
146 // Bit 6: Sequence Header
147 // Bit 5: forward prediction flag
148 // Bit 4: backward prediction flag 
149 //   e.g.
150 //   00== I frame (no prediction)
151 //   10== P frame(forward prediction from previous  frame)
152 //   01== B frame (backward prediction from future  frame)
153 //   11== B frame (forward & backward prediction)
154 // Bits 0-3: reserved  [RP210 Flags to indicate coding of elements in this  edit unit]
155
156 //
157 const char*
158 ASDCP::MXF::IndexTableSegment::IndexEntry::ToString(char* str_buf) const
159 {
160   char intbuf[IntBufferLen];
161   char txt_flags[6];
162   txt_flags[5] = 0;
163
164   txt_flags[0] = ( (Flags & 0x80) != 0 ) ? 'r' : ' ';
165   txt_flags[1] = ( (Flags & 0x40) != 0 ) ? 's' : ' ';
166   txt_flags[2] = ( (Flags & 0x20) != 0 ) ? 'f' : ' ';
167   txt_flags[3] = ( (Flags & 0x10) != 0 ) ? 'b' : ' ';
168   txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
169
170   sprintf(str_buf, "%3i %-3hu %s %s",
171           TemporalOffset, KeyFrameOffset, txt_flags,
172           i64sz(StreamOffset, intbuf));
173
174   return str_buf;
175 }
176
177 //
178 ASDCP::Result_t
179 ASDCP::MXF::IndexTableSegment::IndexEntry::ReadFrom(ASDCP::MemIOReader& Reader)
180 {
181   Result_t result = Reader.ReadUi8((ui8_t*)&TemporalOffset);
182   if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8((ui8_t*)&KeyFrameOffset);
183   if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Flags);
184   if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi64BE(&StreamOffset);
185   return result;
186 }
187
188 //
189 ASDCP::Result_t
190 ASDCP::MXF::IndexTableSegment::IndexEntry::WriteTo(ASDCP::MemIOWriter& Writer)
191 {
192   Result_t result = Writer.WriteUi8((ui8_t)TemporalOffset);
193   if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8((ui8_t)KeyFrameOffset);
194   if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Flags);
195   if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi64BE(StreamOffset);
196   return result;
197 }
198
199
200 //
201 // end Index.cpp
202 //
203