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