DCP: fixed include-guards
[vlc.git] / modules / access / dcp / dcpparser.h
1 /*****************************************************************************
2  * Copyright (C) 2013 VLC authors and VideoLAN
3  *
4  * Authors: Nicolas Bertrand <nico@isf.cc>
5  *          Jean-Baptiste Kempf <jb@videolan.org>
6  *          Guillaume Gonnaud
7  *          Valentin Vetter <vvetter@outlook.com>
8  *          Anthony Giniers
9  *          Ludovic Hoareau
10  *          Loukmane Dessai
11  *          Simona-Marinela Prodea <simona dot marinela dot prodea at gmail dot com>
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation; either version 2.1 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 /**
29  * @file dcpparser.h
30  * @brief Parse DCP XML files
31  */
32
33
34 #ifndef VLC_DCP_DCPPARSER_H_
35 #define VLC_DCP_DCPPARSER_H_
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 /* VLC core API headers */
42 #include <vlc_common.h>
43 #include <vlc_demux.h>
44 #include <vlc_plugin.h>
45
46 /* gcrypt headers */
47 #include <gcrypt.h>
48 #include <vlc_gcrypt.h>
49
50 #include <iostream>
51 #include <string>
52 #include <list>
53 #include <vector>
54
55 using namespace std;
56 typedef enum {
57     TRACK_UNKNOWN = 0,
58     TRACK_PICTURE,
59     TRACK_SOUND,
60     TRACK_SUBTITLE
61 } TrackType_t;
62
63 class Asset;
64 class AssetList: public std::list<Asset *> {};
65 class PKL;
66 class AESKey;
67 class AESKeyList: public std::list<AESKey *> {};
68
69 /* This struct stores useful information about an MXF for demux() */
70 struct info_reel
71 {
72     string filename;
73     int i_entrypoint;
74     int i_duration;
75     int i_correction;       /* entrypoint - sum of previous durations */
76     uint32_t i_absolute_end;     /* correction + duration */
77     AESKey * p_key;
78 };
79
80 /* This struct stores the most important information about the DCP */
81 struct dcp_t
82 {
83     string path;                    /* Path to DCP directory */
84
85     vector<PKL *> pkls;
86     AssetList *p_asset_list;
87     AESKeyList *p_key_list;
88
89     vector<info_reel> audio_reels;
90     vector<info_reel> video_reels;
91
92     dcp_t():
93         p_asset_list(NULL), p_key_list(NULL) {};
94
95     ~dcp_t( ) {
96         vlc_delete_all(pkls);
97         if ( p_asset_list != NULL ) {
98             vlc_delete_all(*p_asset_list);
99             delete(p_asset_list);
100
101         }
102         if ( p_key_list != NULL ) {
103             vlc_delete_all(*p_key_list);
104             delete(p_key_list);
105         }
106     }
107 };
108
109 class XmlFile
110 {
111 public:
112     XmlFile( demux_t * p_demux, string s_path):
113     p_demux(p_demux), s_path(s_path),
114     p_stream(NULL),
115     p_xmlReader(NULL) {}
116
117     virtual ~XmlFile( );
118
119     virtual int Parse() = 0;
120
121     static int ReadNextNode( demux_t *p_demux, xml_reader_t *p_xmlReader, string& s_node );
122     static int ReadEndNode( demux_t *p_demux, xml_reader_t *p_xmlReader, string s_node, int i_type, string &s_value );
123
124     int isCPL();
125 protected:
126     demux_t      *p_demux;
127     string       s_path;
128     stream_t     *p_stream;
129
130     xml_reader_t *p_xmlReader;
131
132     int OpenXml();
133     void CloseXml();
134 };
135
136 class Chunk {
137 public:
138     Chunk(demux_t * demux):
139         i_vol_index(1), i_offset(0), i_length(0),
140         p_demux(demux) {};
141     int Parse(xml_reader_t *p_xmlReader, string p_node, int p_type);
142     string getPath() { return this->s_path; };
143 private:
144     string s_path;
145     int i_vol_index;
146     int i_offset;
147     int i_length;
148     demux_t      *p_demux;
149 };
150
151 class Asset {
152 public:
153     /* Constructor */
154     Asset (demux_t * demux):
155         b_is_packing_list(false),  ui_size(0),
156         i_intrisic_duration(0), i_entry_point(0), i_duration(0),
157         p_demux(demux) {}
158     virtual ~Asset() ;
159
160     void setId(string p_string ) { this->s_id = p_string; };
161     void setPath(string p_string) { this->s_path = p_string; };
162     void setAnnotation(string p_string) {
163         if (this->s_annotation.empty())
164             this->s_annotation = p_string;
165         else
166             this->s_annotation = this->s_annotation + "--" + p_string;
167     };
168     void setKeyId(string p_string) { this->s_key_id = p_string; };
169     void setPackingList(bool p_bool) { this->s_path = p_bool; };
170     void setEntryPoint(int i_val) { this->i_entry_point = i_val; };
171     void setDuration (int i_val) { this->i_duration = i_val; };
172     void setIntrinsicDuration (int i_val) { this->i_intrisic_duration = i_val; };
173     string getId() const { return this->s_id; } ;
174     string getPath() const { return this->s_path; };
175     string getType() const { return this->s_type; };
176     string getOriginalFilename() const { return this->s_original_filename; };
177     string getKeyId() const { return this->s_key_id; }
178     int getEntryPoint() const { return this->i_entry_point; };
179     int getDuration() const { return this->i_duration; };
180     int getIntrinsicDuration() const { return this->i_intrisic_duration; };
181
182     bool isPackingList() const { return this->b_is_packing_list; };
183
184     int Parse( xml_reader_t *p_xmlReader, string node, int type);
185     int ParsePKL( xml_reader_t *p_xmlReader);
186
187     static AESKey * getAESKeyById( AESKeyList* , const string s_id );
188
189     // TODO: remove
190     void Dump();
191
192 private:
193     string      s_id;
194     string      s_path;
195     string      s_annotation;
196     bool        b_is_packing_list;
197     string      s_hash;
198     uint32_t    ui_size;
199     string      s_type;
200     string      s_original_filename;
201     TrackType_t e_track_type;
202     string      s_edit_rate;
203     int         i_intrisic_duration;
204     int         i_entry_point;
205     int         i_duration;
206     /* encryption attribute */
207     string      s_key_id;
208     /* Picture attributes */
209     string      s_frame_rate;
210     string      s_screen_aspect_ratio;
211     /* sound and subtitle */
212     string      s_language;
213
214     demux_t     *p_demux;
215     std::vector<Chunk> chunk_vec;
216
217
218     int parseChunkList( xml_reader_t *p_xmlReader, string p_node, int p_type);
219
220 };
221
222
223
224 class Reel
225 {
226 public:
227     Reel(demux_t * demux, AssetList *asset_list, xml_reader_t *xmlReader)
228         : p_asset_list(asset_list), p_xmlReader(xmlReader), p_demux(demux), p_picture_track(NULL), p_sound_track(NULL), p_subtitle_track(NULL)
229          {};
230     int Parse(string p_node, int p_type);
231     Asset * getTrack(TrackType_t e_track);
232
233 private:
234     AssetList *p_asset_list;
235     xml_reader_t *p_xmlReader;
236     demux_t      *p_demux;
237
238     string s_id;
239     string s_annotation;
240     Asset  *p_picture_track;
241     Asset  *p_sound_track;
242     Asset  *p_subtitle_track;
243
244     int ParseAssetList(string p_node, int p_type);
245     int ParseAsset(string p_node, int p_type, TrackType_t e_track);
246 };
247
248 class CPL : public XmlFile
249 {
250 public:
251     CPL(demux_t * p_demux, string s_path, AssetList *_asset_list)
252         : XmlFile(p_demux, s_path), asset_list( _asset_list)
253         {};
254     ~CPL();
255     virtual int Parse();
256
257     Reel *getReel(int pos) { return this->vec_reel[pos]; } ;
258     std::vector<Reel *> getReelList() { return this->vec_reel; } ;
259
260 private :
261     AssetList *asset_list;
262
263     string s_id;
264     string s_annotation;
265     string s_icon_id;
266     string s_issue_date;
267     string s_issuer;
268     string s_creator;
269     string s_content_title;
270     string s_content_kind;
271     /* TODO:  ContentVersion, RatingList, signer and signature */
272
273     std::vector<Reel *>   vec_reel;
274     int DummyParse(string p_node, int p_type);
275     int ParseReelList(string p_node, int p_type);
276 };
277
278
279 class PKL : public XmlFile
280 {
281 public:
282     PKL( demux_t * p_demux, string s_path, AssetList *_asset_list, string s )
283         : XmlFile( p_demux, s_path ), asset_list( _asset_list ), s_dcp_path( s )
284         {};
285     ~PKL();
286     virtual int Parse();
287
288     int FindCPLs();
289     CPL *getCPL(int pos) { return this->vec_cpl[pos]; };
290
291 private:
292     AssetList *asset_list;
293
294     string s_id;
295     string s_annotation;
296     string s_issue_date;
297     string s_issuer;
298     string s_creator;
299     string s_icon_id;
300     string s_group_id;
301     string s_dcp_path;
302     std::vector<CPL *> vec_cpl;
303
304     int ParseAssetList(string p_node, int p_type);
305     int ParseAsset(string p_node, int p_type);
306     int ParseSigner(string p_node, int p_type);
307     int ParseSignature(string p_node, int p_type);
308
309 };
310
311 class AssetMap : public XmlFile {
312
313 public:
314     AssetMap( demux_t * p_demux, string s_path, dcp_t *_p_dcp)
315         : XmlFile( p_demux, s_path ), p_dcp( _p_dcp) {};
316     ~AssetMap();
317
318     static Asset * getAssetById(AssetList*, const string p_id);
319
320     virtual int Parse();
321 private:
322     dcp_t *p_dcp;
323
324     int ParseAssetList (xml_reader_t *p_xmlReader, const string p_node, int p_type);
325 };
326
327 class KDM : public XmlFile {
328
329 public:
330     KDM( demux_t * p_demux, string s_path, dcp_t *_p_dcp )
331         : XmlFile( p_demux, s_path ), p_dcp(_p_dcp) {}
332
333     virtual int Parse();
334
335 private:
336     dcp_t *p_dcp;
337
338     int ParsePrivate( const string s_node, int i_type );
339 };
340
341 class AESKey
342 {
343 public:
344     AESKey( demux_t *demux ): p_demux( demux ) { }
345     virtual ~AESKey() {};
346
347     const string getKeyId() { return this->s_key_id; };
348     const unsigned char * getKey() { return this->ps_key; };
349
350     int Parse( xml_reader_t *p_xml_reader, string s_node, int i_type );
351
352 private:
353     demux_t *p_demux;
354     string s_key_id;
355     unsigned char ps_key[16];
356
357     int decryptRSA( string s_cipher_text_b64 );
358     int extractInfo( unsigned char * ps_plain_text, bool smpte );
359 };
360
361 class RSAKey
362 {
363 public:
364     RSAKey( demux_t *demux ):
365         priv_key( NULL ), p_demux( demux ) { }
366     virtual ~RSAKey() { gcry_sexp_release( priv_key ); }
367
368     /* some ASN.1 tags.  */
369     enum
370     {
371       TAG_INTEGER = 2,
372       TAG_SEQUENCE = 16,
373     };
374
375     /* ASN.1 Parser object.  */
376     struct tag_info
377     {
378         int class_;            /* Object class.  */
379         unsigned long tag;     /* The tag of the object.  */
380         unsigned long length;  /* Length of the values.  */
381         int nhdr;              /* Length of the header (TL).  */
382         unsigned int ndef:1;   /* The object has an indefinite length.  */
383         unsigned int cons:1;   /* This is a constructed object.  */
384     };
385
386     int setPath();
387     int readPEM();
388     int readDER( unsigned char const *ps_data_der, size_t length );
389     int parseTag( unsigned char const **buffer, size_t *buflen, struct tag_info *ti);
390
391     gcry_sexp_t priv_key;
392
393 private:
394     demux_t *p_demux;
395     string s_path;
396 };
397
398 #endif /* include-guard */