removed extraneous assert(), added multi-/ test to path-test.cpp
[asdcplib.git] / src / Index.cpp
1 /*
2 Copyright (c) 2005-2006, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
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.
15
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.
26 */
27 /*! \file    Index.cpp
28     \version $Id$
29     \brief   MXF index segment objects
30 */
31
32 #include "MXF.h"
33 const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH;
34
35
36 //
37 ASDCP::MXF::IndexTableSegment::IndexTableSegment() :
38   IndexStartPosition(0), IndexDuration(0), EditUnitByteCount(0),
39   IndexSID(129), BodySID(1), SliceCount(0), PosTableCount(0)
40 {
41 }
42
43 //
44 ASDCP::MXF::IndexTableSegment::~IndexTableSegment()
45 {
46 }
47
48 //
49 ASDCP::Result_t
50 ASDCP::MXF::IndexTableSegment::InitFromTLVSet(TLVReader& TLVSet)
51 {
52   Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
53   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
54   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
55   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
56   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
57   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
58   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
59   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
60   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
61   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
62   if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
63   return result;
64 }
65
66 //
67 ASDCP::Result_t
68 ASDCP::MXF::IndexTableSegment::WriteToTLVSet(TLVWriter& TLVSet)
69 {
70   Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
71   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexEditRate));
72   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexStartPosition));
73   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexDuration));
74   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(IndexTableSegmentBase, EditUnitByteCount));
75   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexSID));
76   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(IndexTableSegmentBase, BodySID));
77   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(IndexTableSegmentBase, SliceCount));
78   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(IndexTableSegmentBase, PosTableCount));
79   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IndexTableSegment, DeltaEntryArray));
80   if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IndexTableSegment, IndexEntryArray));
81   return result;
82 }
83
84 //
85 ASDCP::Result_t
86 ASDCP::MXF::IndexTableSegment::InitFromBuffer(const byte_t* p, ui32_t l)
87 {
88   m_Typeinfo = &Dict::Type(MDD_IndexTableSegment);
89   return InterchangeObject::InitFromBuffer(p, l);
90 }
91
92 //
93 ASDCP::Result_t
94 ASDCP::MXF::IndexTableSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
95 {
96   m_Typeinfo = &Dict::Type(MDD_IndexTableSegment);
97   return InterchangeObject::WriteToBuffer(Buffer);
98 }
99
100 //
101 void
102 ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
103 {
104   char identbuf[IdentBufferLen];
105
106   if ( stream == 0 )
107     stream = stderr;
108
109   InterchangeObject::Dump(stream);
110   fprintf(stream, "  IndexEditRate      = %s\n",  IndexEditRate.EncodeString(identbuf, IdentBufferLen));
111   fprintf(stream, "  IndexStartPosition = %s\n",  i64sz(IndexStartPosition, identbuf));
112   fprintf(stream, "  IndexDuration      = %s\n",  i64sz(IndexDuration, identbuf));
113   fprintf(stream, "  EditUnitByteCount  = %u\n",  EditUnitByteCount);
114   fprintf(stream, "  IndexSID           = %u\n",  IndexSID);
115   fprintf(stream, "  BodySID            = %u\n",  BodySID);
116   fprintf(stream, "  SliceCount         = %hu\n", SliceCount);
117   fprintf(stream, "  PosTableCount      = %hu\n", PosTableCount);
118
119   fprintf(stream, "  DeltaEntryArray:\n");  DeltaEntryArray.Dump(stream);
120
121   if ( IndexEntryArray.size() < 100 )
122     {
123       fprintf(stream, "  IndexEntryArray:\n");
124       IndexEntryArray.Dump(stream);
125     }
126   else
127     {
128       fprintf(stream, "  IndexEntryArray: %du entries\n", IndexEntryArray.size());
129     }
130 }
131
132 //------------------------------------------------------------------------------------------
133 //
134
135 //
136 const char*
137 ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const
138 {
139   snprintf(str_buf, buf_len, "%3d %-3hu %-3u", PosTableIndex, Slice, ElementData);
140   return str_buf;
141 }
142
143 //
144 bool
145 ASDCP::MXF::IndexTableSegment::DeltaEntry::Unarchive(Kumu::MemIOReader* Reader)
146 {
147   if ( ! Reader->ReadUi8((ui8_t*)&PosTableIndex) ) return false;
148   if ( ! Reader->ReadUi8(&Slice) ) return false;
149   if ( ! Reader->ReadUi32BE(&ElementData) ) return false;
150   return true;
151 }
152
153 //
154 bool
155 ASDCP::MXF::IndexTableSegment::DeltaEntry::Archive(Kumu::MemIOWriter* Writer) const
156 {
157   if ( ! Writer->WriteUi8((ui8_t)PosTableIndex) ) return false;
158   if ( ! Writer->WriteUi8(Slice) ) return false;
159   if ( ! Writer->WriteUi32BE(ElementData) ) return false;
160   return true;
161 }
162
163 //------------------------------------------------------------------------------------------
164 //
165
166 // Flags:
167 // Bit 7: Random Access
168 // Bit 6: Sequence Header
169 // Bit 5: forward prediction flag
170 // Bit 4: backward prediction flag 
171 //   e.g.
172 //   00== I frame (no prediction)
173 //   10== P frame(forward prediction from previous  frame)
174 //   01== B frame (backward prediction from future  frame)
175 //   11== B frame (forward & backward prediction)
176 // Bits 0-3: reserved  [RP210 Flags to indicate coding of elements in this  edit unit]
177
178 //
179 const char*
180 ASDCP::MXF::IndexTableSegment::IndexEntry::EncodeString(char* str_buf, ui32_t buf_len) const
181 {
182   char intbuf[IntBufferLen];
183   char txt_flags[6];
184
185   txt_flags[0] = ( (Flags & 0x80) != 0 ) ? 'r' : ' ';
186   txt_flags[1] = ( (Flags & 0x40) != 0 ) ? 's' : ' ';
187   txt_flags[2] = ( (Flags & 0x20) != 0 ) ? 'f' : ' ';
188   txt_flags[3] = ( (Flags & 0x10) != 0 ) ? 'b' : ' ';
189   txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
190   txt_flags[5] = 0;
191
192   snprintf(str_buf, buf_len, "%3i %-3hu %s %s",
193            TemporalOffset, KeyFrameOffset, txt_flags,
194            i64sz(StreamOffset, intbuf));
195
196   return str_buf;
197 }
198
199 //
200 bool
201 ASDCP::MXF::IndexTableSegment::IndexEntry::Unarchive(Kumu::MemIOReader* Reader)
202 {
203   if ( ! Reader->ReadUi8((ui8_t*)&TemporalOffset) ) return false;
204   if ( ! Reader->ReadUi8((ui8_t*)&KeyFrameOffset) ) return false;
205   if ( ! Reader->ReadUi8(&Flags) ) return false;
206   if ( ! Reader->ReadUi64BE(&StreamOffset) ) return false;
207   return true;
208 }
209
210 //
211 bool
212 ASDCP::MXF::IndexTableSegment::IndexEntry::Archive(Kumu::MemIOWriter* Writer) const
213 {
214   if ( ! Writer->WriteUi8((ui8_t)TemporalOffset) ) return false;
215   if ( ! Writer->WriteUi8((ui8_t)KeyFrameOffset) ) return false;
216   if ( ! Writer->WriteUi8(Flags) ) return false;
217   if ( ! Writer->WriteUi64BE(StreamOffset) ) return false;
218   return true;
219 }
220
221
222 //
223 // end Index.cpp
224 //
225