working multi-dict
[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(IndexTableSegmentBase, 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(IndexTableSegmentBase, 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   m_Typeinfo = &(m_Dict->Type(MDD_IndexTableSegment));
90   return InterchangeObject::InitFromBuffer(p, l);
91 }
92
93 //
94 ASDCP::Result_t
95 ASDCP::MXF::IndexTableSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
96 {
97   m_Typeinfo = &(m_Dict->Type(MDD_IndexTableSegment));
98   return InterchangeObject::WriteToBuffer(Buffer);
99 }
100
101 //
102 void
103 ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
104 {
105   char identbuf[IdentBufferLen];
106
107   if ( stream == 0 )
108     stream = stderr;
109
110   InterchangeObject::Dump(stream);
111   fprintf(stream, "  IndexEditRate      = %s\n",  IndexEditRate.EncodeString(identbuf, IdentBufferLen));
112   fprintf(stream, "  IndexStartPosition = %s\n",  i64sz(IndexStartPosition, identbuf));
113   fprintf(stream, "  IndexDuration      = %s\n",  i64sz(IndexDuration, identbuf));
114   fprintf(stream, "  EditUnitByteCount  = %u\n",  EditUnitByteCount);
115   fprintf(stream, "  IndexSID           = %u\n",  IndexSID);
116   fprintf(stream, "  BodySID            = %u\n",  BodySID);
117   fprintf(stream, "  SliceCount         = %hu\n", SliceCount);
118   fprintf(stream, "  PosTableCount      = %hu\n", PosTableCount);
119
120   fprintf(stream, "  DeltaEntryArray:\n");  DeltaEntryArray.Dump(stream);
121
122   if ( IndexEntryArray.size() < 100 )
123     {
124       fprintf(stream, "  IndexEntryArray:\n");
125       IndexEntryArray.Dump(stream);
126     }
127   else
128     {
129       fprintf(stream, "  IndexEntryArray: %du entries\n", IndexEntryArray.size());
130     }
131 }
132
133 //------------------------------------------------------------------------------------------
134 //
135
136 //
137 const char*
138 ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const
139 {
140   snprintf(str_buf, buf_len, "%3d %-3hu %-3u", PosTableIndex, Slice, ElementData);
141   return str_buf;
142 }
143
144 //
145 bool
146 ASDCP::MXF::IndexTableSegment::DeltaEntry::Unarchive(Kumu::MemIOReader* Reader)
147 {
148   if ( ! Reader->ReadUi8((ui8_t*)&PosTableIndex) ) return false;
149   if ( ! Reader->ReadUi8(&Slice) ) return false;
150   if ( ! Reader->ReadUi32BE(&ElementData) ) return false;
151   return true;
152 }
153
154 //
155 bool
156 ASDCP::MXF::IndexTableSegment::DeltaEntry::Archive(Kumu::MemIOWriter* Writer) const
157 {
158   if ( ! Writer->WriteUi8((ui8_t)PosTableIndex) ) return false;
159   if ( ! Writer->WriteUi8(Slice) ) return false;
160   if ( ! Writer->WriteUi32BE(ElementData) ) return false;
161   return true;
162 }
163
164 //------------------------------------------------------------------------------------------
165 //
166
167 // Flags:
168 // Bit 7: Random Access
169 // Bit 6: Sequence Header
170 // Bit 5: forward prediction flag
171 // Bit 4: backward prediction flag 
172 //   e.g.
173 //   00== I frame (no prediction)
174 //   10== P frame(forward prediction from previous  frame)
175 //   01== B frame (backward prediction from future  frame)
176 //   11== B frame (forward & backward prediction)
177 // Bits 0-3: reserved  [RP210 Flags to indicate coding of elements in this  edit unit]
178
179 //
180 const char*
181 ASDCP::MXF::IndexTableSegment::IndexEntry::EncodeString(char* str_buf, ui32_t buf_len) const
182 {
183   char intbuf[IntBufferLen];
184   char txt_flags[6];
185
186   txt_flags[0] = ( (Flags & 0x80) != 0 ) ? 'r' : ' ';
187   txt_flags[1] = ( (Flags & 0x40) != 0 ) ? 's' : ' ';
188   txt_flags[2] = ( (Flags & 0x20) != 0 ) ? 'f' : ' ';
189   txt_flags[3] = ( (Flags & 0x10) != 0 ) ? 'b' : ' ';
190   txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
191   txt_flags[5] = 0;
192
193   snprintf(str_buf, buf_len, "%3i %-3hu %s %s",
194            TemporalOffset, KeyFrameOffset, txt_flags,
195            i64sz(StreamOffset, intbuf));
196
197   return str_buf;
198 }
199
200 //
201 bool
202 ASDCP::MXF::IndexTableSegment::IndexEntry::Unarchive(Kumu::MemIOReader* Reader)
203 {
204   if ( ! Reader->ReadUi8((ui8_t*)&TemporalOffset) ) return false;
205   if ( ! Reader->ReadUi8((ui8_t*)&KeyFrameOffset) ) return false;
206   if ( ! Reader->ReadUi8(&Flags) ) return false;
207   if ( ! Reader->ReadUi64BE(&StreamOffset) ) return false;
208   return true;
209 }
210
211 //
212 bool
213 ASDCP::MXF::IndexTableSegment::IndexEntry::Archive(Kumu::MemIOWriter* Writer) const
214 {
215   if ( ! Writer->WriteUi8((ui8_t)TemporalOffset) ) return false;
216   if ( ! Writer->WriteUi8((ui8_t)KeyFrameOffset) ) return false;
217   if ( ! Writer->WriteUi8(Flags) ) return false;
218   if ( ! Writer->WriteUi64BE(StreamOffset) ) return false;
219   return true;
220 }
221
222
223 //
224 // end Index.cpp
225 //
226