1 /*****************************************************************
2 |
3 |    AP4 - Marlin File Format support
4 |
5 |    Copyright 2002-2008 Axiomatic Systems, LLC
6 |
7 |
8 |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 |    Unless you have obtained Bento4 under a difference license,
11 |    this version of Bento4 is Bento4|GPL.
12 |    Bento4|GPL is free software; you can redistribute it and/or modify
13 |    it under the terms of the GNU General Public License as published by
14 |    the Free Software Foundation; either version 2, or (at your option)
15 |    any later version.
16 |
17 |    Bento4|GPL is distributed in the hope that it will be useful,
18 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 |    GNU General Public License for more details.
21 |
22 |    You should have received a copy of the GNU General Public License
23 |    along with Bento4|GPL; see the file COPYING.  If not, write to the
24 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 |    02111-1307, USA.
26 |
27 ****************************************************************/
28 
29 #ifndef _AP4_MARLIN_H_
30 #define _AP4_MARLIN_H_
31 
32 /*----------------------------------------------------------------------
33 |   includes
34 +---------------------------------------------------------------------*/
35 #include "Ap4Types.h"
36 #include "Ap4SampleEntry.h"
37 #include "Ap4Atom.h"
38 #include "Ap4AtomFactory.h"
39 #include "Ap4SampleDescription.h"
40 #include "Ap4Processor.h"
41 #include "Ap4Protection.h"
42 #include "Ap4TrefTypeAtom.h"
43 #include "Ap4ObjectDescriptor.h"
44 #include "Ap4Command.h"
45 #include "Ap4UuidAtom.h"
46 #include "Ap4OmaDcf.h"
47 
48 /*----------------------------------------------------------------------
49 |   constants
50 +---------------------------------------------------------------------*/
51 const AP4_UI32 AP4_MARLIN_BRAND_MGSV       = AP4_ATOM_TYPE('M','G','S','V');
52 const AP4_UI16 AP4_MARLIN_IPMPS_TYPE_MGSV  = 0xA551;
53 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC = AP4_ATOM_TYPE('A','C','B','C');
54 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACGK = AP4_ATOM_TYPE('A','C','G','K');
55 
56 const AP4_Atom::Type AP4_ATOM_TYPE_SATR = AP4_ATOM_TYPE('s','a','t','r');
57 const AP4_Atom::Type AP4_ATOM_TYPE_STYP = AP4_ATOM_TYPE('s','t','y','p');
58 const AP4_Atom::Type AP4_ATOM_TYPE_HMAC = AP4_ATOM_TYPE('h','m','a','c');
59 const AP4_Atom::Type AP4_ATOM_TYPE_GKEY = AP4_ATOM_TYPE('g','k','e','y');
60 
61 const char* const AP4_MARLIN_IPMP_STYP_VIDEO = "urn:marlin:organization:sne:content-type:video";
62 const char* const AP4_MARLIN_IPMP_STYP_AUDIO = "urn:marlin:organization:sne:content-type:audio";
63 
64 const AP4_UI08 AP4_MARLIN_PSSH_SYSTEM_ID[16] = {
65     0x69, 0xF9, 0x08, 0xAF, 0x48, 0x16, 0x46, 0xEA, 0x91, 0x0C, 0xCD, 0x5D, 0xCC, 0xCB, 0x0A, 0x3A
66 };
67 
68 /*----------------------------------------------------------------------
69 |   AP4_MarlinIpmpParser
70 +---------------------------------------------------------------------*/
71 class AP4_MarlinIpmpParser
72 {
73 public:
74     // types
75     struct SinfEntry {
SinfEntrySinfEntry76          SinfEntry(AP4_UI32 track_id, AP4_ContainerAtom* sinf) :
77              m_TrackId(track_id), m_Sinf(sinf) {}
~SinfEntrySinfEntry78         ~SinfEntry() { delete m_Sinf; }
79         AP4_UI32           m_TrackId;
80         AP4_ContainerAtom* m_Sinf;
81     };
82 
83     // methods
84     static AP4_Result Parse(AP4_AtomParent&      top_level,
85                             AP4_ByteStream&      stream,
86                             AP4_List<SinfEntry>& sinf_entries,
87                             bool                 remove_od_data=false);
88 
89 private:
AP4_MarlinIpmpParser()90     AP4_MarlinIpmpParser() {} // this class can't be instantiated
91 };
92 
93 /*----------------------------------------------------------------------
94 |   AP4_MarlinIpmpSampleDecrypter
95 +---------------------------------------------------------------------*/
96 class AP4_MarlinIpmpSampleDecrypter : public AP4_SampleDecrypter
97 {
98 public:
99     /**
100      * Create a sample decrypter given the top-level atoms, the track ID, and the key
101      */
102     static AP4_Result Create(AP4_AtomParent&                 top_level,
103                              const AP4_UI08*                 key,
104                              AP4_Size                        key_size,
105                              AP4_BlockCipherFactory*         block_cipher_factory,
106                              AP4_MarlinIpmpSampleDecrypter*& sample_decrypter);
107 
108     /**
109      * Create a sample decrypter given the key (can't be used with group keys, since the group
110      * key info needs to be parsed from the top level atoms)
111      */
112     static AP4_Result Create(const AP4_UI08*                 key,
113                              AP4_Size                        key_size,
114                              AP4_BlockCipherFactory*         block_cipher_factory,
115                              AP4_MarlinIpmpSampleDecrypter*& sample_decrypter);
116 
117     ~AP4_MarlinIpmpSampleDecrypter();
118 
119     // AP4_SampleDecrypter methods
120     AP4_Size   GetDecryptedSampleSize(AP4_Sample& sample);
121     AP4_Result DecryptSampleData(AP4_DataBuffer&    data_in,
122                                  AP4_DataBuffer&    data_out,
123                                  const AP4_UI08*    iv = NULL);
124 
125 private:
AP4_MarlinIpmpSampleDecrypter(AP4_StreamCipher * cipher)126     AP4_MarlinIpmpSampleDecrypter(AP4_StreamCipher* cipher) : m_Cipher(cipher) {}
127 
128     AP4_StreamCipher* m_Cipher;
129 };
130 
131 /*----------------------------------------------------------------------
132 |   AP4_MarlinIpmpDecryptingProcessor
133 +---------------------------------------------------------------------*/
134 class AP4_MarlinIpmpDecryptingProcessor : public AP4_Processor
135 {
136 public:
137     // constructor and destructor
138     AP4_MarlinIpmpDecryptingProcessor(const AP4_ProtectionKeyMap* key_map = NULL,
139                                       AP4_BlockCipherFactory*     block_cipher_factory = NULL);
140     ~AP4_MarlinIpmpDecryptingProcessor();
141 
142     // accessors
GetKeyMap()143     AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; }
144 
145     // methods
146     virtual AP4_Result Initialize(AP4_AtomParent&   top_level,
147                                   AP4_ByteStream&   stream,
148                                   ProgressListener* listener);
149     virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak);
150 
151 private:
152 
153     // members
154     AP4_BlockCipherFactory*                   m_BlockCipherFactory;
155     AP4_ProtectionKeyMap                      m_KeyMap;
156     AP4_List<AP4_MarlinIpmpParser::SinfEntry> m_SinfEntries;
157 };
158 
159 /*----------------------------------------------------------------------
160 |   AP4_MarlinIpmpTrackDecrypter
161 +---------------------------------------------------------------------*/
162 class AP4_MarlinIpmpTrackDecrypter : public AP4_Processor::TrackHandler
163 {
164 public:
165     // class methods
166     static AP4_Result Create(AP4_BlockCipherFactory&        cipher_factory,
167                              const AP4_UI08*                key,
168                              AP4_Size                       key_size,
169                              AP4_MarlinIpmpTrackDecrypter*& decrypter);
170 
171     // constructor and destructor
AP4_MarlinIpmpTrackDecrypter()172      AP4_MarlinIpmpTrackDecrypter() : m_SampleDecrypter(NULL) {};
173     ~AP4_MarlinIpmpTrackDecrypter();
174 
175     // AP4_Processor::TrackHandler methods
176     virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample);
177     virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in,
178                                      AP4_DataBuffer& data_out);
179 
180 
181 private:
182     // constructor
AP4_MarlinIpmpTrackDecrypter(AP4_SampleDecrypter * sample_decrypter)183     AP4_MarlinIpmpTrackDecrypter(AP4_SampleDecrypter* sample_decrypter) :
184         m_SampleDecrypter(sample_decrypter) {}
185 
186     // members
187     AP4_SampleDecrypter* m_SampleDecrypter;
188 };
189 
190 /*----------------------------------------------------------------------
191 |   AP4_MarlinIpmpEncryptingProcessor
192 +---------------------------------------------------------------------*/
193 class AP4_MarlinIpmpEncryptingProcessor : public AP4_Processor
194 {
195 public:
196     // constructor
197     AP4_MarlinIpmpEncryptingProcessor(bool                        use_group_key = false,
198                                       const AP4_ProtectionKeyMap* key_map = NULL,
199                                       AP4_BlockCipherFactory*     block_cipher_factory = NULL);
200 
201     // accessors
GetKeyMap()202     AP4_ProtectionKeyMap& GetKeyMap()      { return m_KeyMap;      }
GetPropertyMap()203     AP4_TrackPropertyMap& GetPropertyMap() { return m_PropertyMap; }
204 
205     // AP4_Processor methods
206     virtual AP4_Result Initialize(AP4_AtomParent&   top_level,
207                                   AP4_ByteStream&   stream,
208                                   AP4_Processor::ProgressListener* listener = NULL);
209     virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak);
210 
211 private:
212     // members
213     AP4_BlockCipherFactory* m_BlockCipherFactory;
214     bool                    m_UseGroupKey;
215     AP4_ProtectionKeyMap    m_KeyMap;
216     AP4_TrackPropertyMap    m_PropertyMap;
217 };
218 
219 /*----------------------------------------------------------------------
220 |   AP4_MarlinIpmpTrackEncrypter
221 +---------------------------------------------------------------------*/
222 class AP4_MarlinIpmpTrackEncrypter : public AP4_Processor::TrackHandler
223 {
224 public:
225     // class methods
226     static AP4_Result Create(AP4_BlockCipherFactory&        cipher_factory,
227                              const AP4_UI08*                key,
228                              AP4_Size                       key_size,
229                              const AP4_UI08*                iv,
230                              AP4_Size                       iv_size,
231                              AP4_MarlinIpmpTrackEncrypter*& encrypter);
232 
233     // destructor
234     ~AP4_MarlinIpmpTrackEncrypter();
235 
236     // AP4_Processor::TrackHandler methods
237     virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample);
238     virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in,
239                                      AP4_DataBuffer& data_out);
240 
241 
242 private:
243     // constructor
244     AP4_MarlinIpmpTrackEncrypter(AP4_StreamCipher* cipher, const AP4_UI08* iv);
245 
246     // members
247     AP4_UI08          m_IV[16];
248     AP4_StreamCipher* m_Cipher;
249 };
250 
251 /*----------------------------------------------------------------------
252 |   AP4_MkidAtom
253 +---------------------------------------------------------------------*/
254 class AP4_MkidAtom : public AP4_Atom
255 {
256 public:
257     AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MkidAtom, AP4_Atom)
258 
259     // types
260     struct Entry {
261         AP4_UI08   m_KID[16];
262         AP4_String m_ContentId;
263     };
264 
265     // virtual constructor
266     static AP4_MkidAtom* Create(AP4_Size size, AP4_ByteStream& stream);
267 
268     // constructors
269     AP4_MkidAtom();
270 
271     // methods
272     virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
273     virtual AP4_Result WriteFields(AP4_ByteStream& stream);
274 
275     // accessors
GetEntries()276     const AP4_Array<Entry>& GetEntries() { return m_Entries; }
277     AP4_Result              AddEntry(const AP4_UI08* kid, const char* content_id);
278 
279 private:
280     // methods
281     AP4_MkidAtom(AP4_Size        size,
282                  AP4_UI08        version,
283                  AP4_UI32        flags,
284                  AP4_ByteStream& stream);
285 
286     // members
287     AP4_Array<Entry> m_Entries;
288 };
289 
290 
291 #endif // _AP4_MARLIN_H_
292