oops
[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 h__Reader
95     {
96       ASDCP_NO_COPY_CONSTRUCT(h__Reader);
97
98     public:
99       Kumu::FileReader   m_File;
100       OPAtomHeader       m_HeaderPart;
101       Partition          m_BodyPart;
102       OPAtomIndexFooter  m_FooterPart;
103       ui64_t             m_EssenceStart;
104       WriterInfo         m_Info;
105       ASDCP::FrameBuffer m_CtFrameBuf;
106       Kumu::fpos_t       m_LastPosition;
107
108       h__Reader();
109       virtual ~h__Reader();
110
111       Result_t InitInfo();
112       Result_t OpenMXFRead(const char* filename);
113       Result_t InitMXFIndex();
114       Result_t ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
115                               const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
116       void     Close();
117     };
118
119
120   // state machine for mxf writer
121   enum WriterState_t {
122     ST_BEGIN,   // waiting for Open()
123     ST_INIT,    // waiting for SetSourceStream()
124     ST_READY,   // ready to write frames
125     ST_RUNNING, // one or more frames written
126     ST_FINAL,   // index written, file closed
127   };
128
129   // implementation of h__WriterState class Goto_* methods
130 #define Goto_body(s1,s2) if ( m_State != (s1) ) \
131                            return RESULT_STATE; \
132                          m_State = (s2); \
133                          return RESULT_OK
134   //
135   class h__WriterState
136     {
137       ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
138
139     public:
140       WriterState_t m_State;
141       h__WriterState() : m_State(ST_BEGIN) {}
142       ~h__WriterState() {}
143
144       inline bool     Test_BEGIN()   { return m_State == ST_BEGIN; }
145       inline bool     Test_INIT()    { return m_State == ST_INIT; }
146       inline bool     Test_READY()   { return m_State == ST_READY;}
147       inline bool     Test_RUNNING() { return m_State == ST_RUNNING; }
148       inline bool     Test_FINAL()   { return m_State == ST_FINAL; }
149       inline Result_t Goto_INIT()    { Goto_body(ST_BEGIN,   ST_INIT); }
150       inline Result_t Goto_READY()   { Goto_body(ST_INIT,    ST_READY); }
151       inline Result_t Goto_RUNNING() { Goto_body(ST_READY,   ST_RUNNING); }
152       inline Result_t Goto_FINAL()   { Goto_body(ST_RUNNING, ST_FINAL); }
153     };
154
155   //
156   class h__Writer
157     {
158       ASDCP_NO_COPY_CONSTRUCT(h__Writer);
159
160     public:
161       Kumu::FileWriter   m_File;
162       ui32_t             m_HeaderSize;
163       OPAtomHeader       m_HeaderPart;
164       Partition          m_BodyPart;
165       OPAtomIndexFooter  m_FooterPart;
166       ui64_t             m_EssenceStart;
167
168       MaterialPackage*   m_MaterialPackage;
169       Sequence*          m_MPTCSequence;
170       TimecodeComponent* m_MPTimecode;
171       Sequence*          m_MPClSequence;
172       SourceClip*        m_MPClip;                      //! Material Package SourceClip for each essence stream 
173
174       SourcePackage*     m_FilePackage;
175       Sequence*          m_FPTCSequence;
176       TimecodeComponent* m_FPTimecode;
177       Sequence*          m_FPClSequence;
178       SourceClip*        m_FPClip;                      //! File Package SourceClip for each essence stream 
179
180       FileDescriptor*    m_EssenceDescriptor;
181       std::list<FileDescriptor*> m_EssenceSubDescriptorList;
182
183       ui32_t             m_FramesWritten;
184       ui64_t             m_StreamOffset;
185       ASDCP::FrameBuffer m_CtFrameBuf;
186       h__WriterState     m_State;
187       WriterInfo         m_Info;
188
189       h__Writer();
190       virtual ~h__Writer();
191
192       Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
193                               const std::string& TrackName, const UL& DataDefinition,
194                               const MXF::Rational& EditRate,
195                               ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
196
197       Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
198                                const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
199
200       Result_t WriteMXFFooter();
201
202    };
203
204
205   // helper class for calculating Integrity Packs, used by WriteEKLVPacket() below.
206   //
207   class IntegrityPack
208     {
209     public:
210       byte_t Data[klv_intpack_size];
211   
212       IntegrityPack() {
213         memset(Data, 0, klv_intpack_size);
214       }
215
216       ~IntegrityPack() {}
217   
218       Result_t CalcValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
219       Result_t TestValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
220     };
221
222
223 } // namespace ASDCP
224
225 #endif // _AS_DCP_INTERNAL_H_
226
227
228 //
229 // end AS_DCP_internal.h
230 //