release
[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 "AS_DCP_system.h"
36 #include "Metadata.h"
37 #include "hex_utils.h"
38
39 using namespace std;
40 using namespace ASDCP;
41 using namespace ASDCP::MXF;
42
43
44
45 namespace ASDCP
46 {
47   // constant values used to calculate KLV and EKLV packet sizes
48
49   static const ui32_t klv_cryptinfo_size =
50     MXF_BER_LENGTH
51     + UUIDlen /* ContextID */
52     + MXF_BER_LENGTH
53     + sizeof(ui64_t) /* PlaintextOffset */
54     + MXF_BER_LENGTH
55     + SMPTE_UL_LENGTH /* SourceKey */
56     + MXF_BER_LENGTH
57     + sizeof(ui64_t) /* SourceLength */
58     + MXF_BER_LENGTH /* ESV length */ ;
59
60   static const ui32_t klv_intpack_size =
61     MXF_BER_LENGTH
62     + UUIDlen /* TrackFileID */
63     + MXF_BER_LENGTH
64     + sizeof(ui64_t) /* SequenceNumber */
65     + MXF_BER_LENGTH
66     + 20; /* HMAC length*/
67
68   // calculate size of encrypted essence with IV, CheckValue, and padding
69   inline ui32_t
70     calc_esv_length(ui32_t source_length, ui32_t plaintext_offset)
71     {
72       ui32_t ct_size = source_length - plaintext_offset;
73       ui32_t diff = ct_size % CBC_BLOCK_SIZE;
74       ui32_t block_size = ct_size - diff;
75       return plaintext_offset + block_size + (CBC_BLOCK_SIZE * 3);
76     }
77
78   // the check value for EKLV packets
79   // CHUKCHUKCHUKCHUK
80   static const byte_t ESV_CheckValue[CBC_BLOCK_SIZE] =
81   { 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b,
82     0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b };
83
84   //------------------------------------------------------------------------------------------
85   //
86
87   Result_t MD_to_WriterInfo(MXF::Identification*, WriterInfo&);
88   Result_t MD_to_CryptoInfo(MXF::CryptographicContext*, WriterInfo&);
89   Result_t EncryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESEncContext*);
90   Result_t DecryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESDecContext*);
91
92   //
93   class h__Reader
94     {
95       ASDCP_NO_COPY_CONSTRUCT(h__Reader);
96
97     public:
98       FileReader         m_File;
99       OPAtomHeader       m_HeaderPart;
100       Partition          m_BodyPart;
101       OPAtomIndexFooter  m_FooterPart;
102       ui64_t             m_EssenceStart;
103       WriterInfo         m_Info;
104       ASDCP::FrameBuffer m_CtFrameBuf;
105       fpos_t             m_LastPosition;
106
107       h__Reader();
108       virtual ~h__Reader();
109
110       Result_t InitInfo();
111       Result_t OpenMXFRead(const char* filename);
112       Result_t InitMXFIndex();
113       Result_t ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
114                               const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
115       void     Close();
116     };
117
118
119   // state machine for mxf writer
120   enum WriterState_t {
121     ST_BEGIN,   // waiting for Open()
122     ST_INIT,    // waiting for SetSourceStream()
123     ST_READY,   // ready to write frames
124     ST_RUNNING, // one or more frames written
125     ST_FINAL,   // index written, file closed
126   };
127
128   // implementation of h__WriterState class Goto_* methods
129 #define Goto_body(s1,s2) if ( m_State != (s1) ) \
130                            return RESULT_STATE; \
131                          m_State = (s2); \
132                          return RESULT_OK
133   //
134   class h__WriterState
135     {
136       ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
137
138     public:
139       WriterState_t m_State;
140       h__WriterState() : m_State(ST_BEGIN) {}
141       ~h__WriterState() {}
142
143       inline bool     Test_BEGIN()   { return m_State == ST_BEGIN; }
144       inline bool     Test_INIT()    { return m_State == ST_INIT; }
145       inline bool     Test_READY()   { return m_State == ST_READY;}
146       inline bool     Test_RUNNING() { return m_State == ST_RUNNING; }
147       inline bool     Test_FINAL()   { return m_State == ST_FINAL; }
148       inline Result_t Goto_INIT()    { Goto_body(ST_BEGIN,   ST_INIT); }
149       inline Result_t Goto_READY()   { Goto_body(ST_INIT,    ST_READY); }
150       inline Result_t Goto_RUNNING() { Goto_body(ST_READY,   ST_RUNNING); }
151       inline Result_t Goto_FINAL()   { Goto_body(ST_RUNNING, ST_FINAL); }
152     };
153
154   //
155   class h__Writer
156     {
157       ASDCP_NO_COPY_CONSTRUCT(h__Writer);
158
159     public:
160       FileWriter         m_File;
161       ui32_t             m_HeaderSize;
162       OPAtomHeader       m_HeaderPart;
163       Partition          m_BodyPart;
164       OPAtomIndexFooter  m_FooterPart;
165       ui64_t             m_EssenceStart;
166
167       MaterialPackage*   m_MaterialPackage;
168       Sequence*          m_MPTCSequence;
169       TimecodeComponent* m_MPTimecode;
170       Sequence*          m_MPClSequence;
171       SourceClip*        m_MPClip;                      //! Material Package SourceClip for each essence stream 
172
173       SourcePackage*     m_FilePackage;
174       Sequence*          m_FPTCSequence;
175       TimecodeComponent* m_FPTimecode;
176       Sequence*          m_FPClSequence;
177       SourceClip*        m_FPClip;                      //! File Package SourceClip for each essence stream 
178
179       FileDescriptor*    m_EssenceDescriptor;
180
181       ui32_t             m_FramesWritten;
182       ui64_t             m_StreamOffset;
183       ASDCP::FrameBuffer m_CtFrameBuf;
184       h__WriterState     m_State;
185       WriterInfo         m_Info;
186
187       h__Writer();
188       virtual ~h__Writer();
189
190       Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
191                               const std::string& TrackName, const UL& DataDefinition,
192                               const MXF::Rational& EditRate,
193                               ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
194
195       Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
196                                const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
197
198       Result_t WriteMXFFooter();
199
200    };
201
202
203   // helper class for calculating Integrity Packs, used by WriteEKLVPacket() below.
204   //
205   class IntegrityPack
206     {
207     public:
208       byte_t Data[klv_intpack_size];
209   
210       IntegrityPack() {
211         memset(Data, 0, klv_intpack_size);
212       }
213
214       ~IntegrityPack() {}
215   
216       Result_t CalcValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
217       Result_t TestValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
218     };
219
220
221 } // namespace ASDCP
222
223 #endif // _AS_DCP_INTERNAL_H__
224
225
226 //
227 // end AS_DCP_internal.h
228 //