Win32 portability fixes
[asdcplib.git] / src / AS_DCP_internal.h
1 /*
2 Copyright (c) 2004-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    AS_DCP_internal.h
28     \version $Id$       
29     \brief   AS-DCP library, non-public common elements
30 */
31
32 #ifndef _AS_DCP_INTERNAL_H_
33 #define _AS_DCP_INTERNAL_H_
34
35 #include <KM_platform.h>
36 #include <KM_util.h>
37 #include <KM_log.h>
38 #include "Metadata.h"
39
40 using Kumu::DefaultLogSink;
41 // using namespace std;
42 using namespace ASDCP;
43 using namespace ASDCP::MXF;
44
45
46
47 namespace ASDCP
48 {
49   // constant values used to calculate KLV and EKLV packet sizes
50   static const ui32_t klv_cryptinfo_size =
51     MXF_BER_LENGTH
52     + UUIDlen /* ContextID */
53     + MXF_BER_LENGTH
54     + sizeof(ui64_t) /* PlaintextOffset */
55     + MXF_BER_LENGTH
56     + SMPTE_UL_LENGTH /* SourceKey */
57     + MXF_BER_LENGTH
58     + sizeof(ui64_t) /* SourceLength */
59     + MXF_BER_LENGTH /* ESV length */ ;
60
61   static const ui32_t klv_intpack_size =
62     MXF_BER_LENGTH
63     + UUIDlen /* TrackFileID */
64     + MXF_BER_LENGTH
65     + sizeof(ui64_t) /* SequenceNumber */
66     + MXF_BER_LENGTH
67     + 20; /* HMAC length*/
68
69   // calculate size of encrypted essence with IV, CheckValue, and padding
70   inline ui32_t
71     calc_esv_length(ui32_t source_length, ui32_t plaintext_offset)
72     {
73       ui32_t ct_size = source_length - plaintext_offset;
74       ui32_t diff = ct_size % CBC_BLOCK_SIZE;
75       ui32_t block_size = ct_size - diff;
76       return plaintext_offset + block_size + (CBC_BLOCK_SIZE * 3);
77     }
78
79   // the check value for EKLV packets
80   // CHUKCHUKCHUKCHUK
81   static const byte_t ESV_CheckValue[CBC_BLOCK_SIZE] =
82   { 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b,
83     0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b };
84
85   //------------------------------------------------------------------------------------------
86   //
87
88   Result_t MD_to_WriterInfo(MXF::Identification*, WriterInfo&);
89   Result_t MD_to_CryptoInfo(MXF::CryptographicContext*, WriterInfo&);
90   Result_t EncryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESEncContext*);
91   Result_t DecryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESDecContext*);
92
93   //
94  class KLReader : public ASDCP::KLVPacket
95     {
96       ASDCP_NO_COPY_CONSTRUCT(KLReader);
97       byte_t m_KeyBuf[SMPTE_UL_LENGTH*2];
98
99     public:
100       KLReader() {}
101       ~KLReader() {}
102
103       inline const byte_t* Key() { return m_KeyBuf; }
104       inline const ui64_t  Length() { return m_ValueLength; }
105       inline const ui64_t  KLLength() { return m_KLLength; }
106       
107       Result_t ReadKLFromFile(Kumu::FileReader& Reader);
108     };
109
110   //
111   class h__Reader
112     {
113       ASDCP_NO_COPY_CONSTRUCT(h__Reader);
114
115     public:
116       Kumu::FileReader   m_File;
117       OPAtomHeader       m_HeaderPart;
118       Partition          m_BodyPart;
119       OPAtomIndexFooter  m_FooterPart;
120       ui64_t             m_EssenceStart;
121       WriterInfo         m_Info;
122       ASDCP::FrameBuffer m_CtFrameBuf;
123       Kumu::fpos_t       m_LastPosition;
124
125       h__Reader();
126       virtual ~h__Reader();
127
128       Result_t InitInfo();
129       Result_t OpenMXFRead(const char* filename);
130       Result_t InitMXFIndex();
131
132       // positions file before reading
133       Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
134                              const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
135
136       // reads from current position
137       Result_t ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
138                               const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
139       void     Close();
140     };
141
142
143   // state machine for mxf writer
144   enum WriterState_t {
145     ST_BEGIN,   // waiting for Open()
146     ST_INIT,    // waiting for SetSourceStream()
147     ST_READY,   // ready to write frames
148     ST_RUNNING, // one or more frames written
149     ST_FINAL,   // index written, file closed
150   };
151
152   // implementation of h__WriterState class Goto_* methods
153 #define Goto_body(s1,s2) if ( m_State != (s1) ) \
154                            return RESULT_STATE; \
155                          m_State = (s2); \
156                          return RESULT_OK
157   //
158   class h__WriterState
159     {
160       ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
161
162     public:
163       WriterState_t m_State;
164       h__WriterState() : m_State(ST_BEGIN) {}
165       ~h__WriterState() {}
166
167       inline bool     Test_BEGIN()   { return m_State == ST_BEGIN; }
168       inline bool     Test_INIT()    { return m_State == ST_INIT; }
169       inline bool     Test_READY()   { return m_State == ST_READY;}
170       inline bool     Test_RUNNING() { return m_State == ST_RUNNING; }
171       inline bool     Test_FINAL()   { return m_State == ST_FINAL; }
172       inline Result_t Goto_INIT()    { Goto_body(ST_BEGIN,   ST_INIT); }
173       inline Result_t Goto_READY()   { Goto_body(ST_INIT,    ST_READY); }
174       inline Result_t Goto_RUNNING() { Goto_body(ST_READY,   ST_RUNNING); }
175       inline Result_t Goto_FINAL()   { Goto_body(ST_RUNNING, ST_FINAL); }
176     };
177
178   typedef std::list<ui64_t*> DurationElementList_t;
179
180   //
181   class h__Writer
182     {
183       ASDCP_NO_COPY_CONSTRUCT(h__Writer);
184
185     public:
186       Kumu::FileWriter   m_File;
187       ui32_t             m_HeaderSize;
188       OPAtomHeader       m_HeaderPart;
189       Partition          m_BodyPart;
190       OPAtomIndexFooter  m_FooterPart;
191       ui64_t             m_EssenceStart;
192
193       MaterialPackage*   m_MaterialPackage;
194       SourcePackage*     m_FilePackage;
195
196       FileDescriptor*    m_EssenceDescriptor;
197       std::list<InterchangeObject*> m_EssenceSubDescriptorList;
198
199       ui32_t             m_FramesWritten;
200       ui64_t             m_StreamOffset;
201       ASDCP::FrameBuffer m_CtFrameBuf;
202       h__WriterState     m_State;
203       WriterInfo         m_Info;
204       DurationElementList_t m_DurationUpdateList;
205
206       h__Writer();
207       virtual ~h__Writer();
208
209       void InitHeader();
210       void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
211                          const std::string& TrackName, const UL& DataDefinition,
212                          const std::string& PackageLabel);
213       void AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
214                          const std::string& TrackName, const UL& DataDefinition,
215                         const std::string& PackageLabel);
216       void AddEssenceDescriptor(const UL& WrappingUL);
217       Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
218
219       // all the above for a single source clip
220       Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
221                               const std::string& TrackName, const UL& DataDefinition,
222                               const MXF::Rational& EditRate,
223                               ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
224
225       Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
226                                const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
227
228       Result_t WriteMXFFooter();
229
230    };
231
232
233   // helper class for calculating Integrity Packs, used by WriteEKLVPacket() below.
234   //
235   class IntegrityPack
236     {
237     public:
238       byte_t Data[klv_intpack_size];
239   
240       IntegrityPack() {
241         memset(Data, 0, klv_intpack_size);
242       }
243
244       ~IntegrityPack() {}
245   
246       Result_t CalcValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
247       Result_t TestValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
248     };
249
250
251 } // namespace ASDCP
252
253 #endif // _AS_DCP_INTERNAL_H_
254
255
256 //
257 // end AS_DCP_internal.h
258 //