doc: libvlc: add drag and drop support to the basic set_hwnd sample app
[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     string      s_edit_rate;
202     int         i_intrisic_duration;
203     int         i_entry_point;
204     int         i_duration;
205     /* encryption attribute */
206     string      s_key_id;
207     /* Picture attributes */
208     string      s_frame_rate;
209     string      s_screen_aspect_ratio;
210     /* sound and subtitle */
211     string      s_language;
212
213     demux_t     *p_demux;
214     std::vector<Chunk> chunk_vec;
215
216
217     int parseChunkList( xml_reader_t *p_xmlReader, string p_node, int p_type);
218
219 };
220
221
222
223 class Reel
224 {
225 public:
226     Reel(demux_t * demux, AssetList *asset_list, xml_reader_t *xmlReader)
227         : p_asset_list(asset_list), p_xmlReader(xmlReader), p_demux(demux), p_picture_track(NULL), p_sound_track(NULL), p_subtitle_track(NULL)
228          {};
229     int Parse(string p_node, int p_type);
230     Asset * getTrack(TrackType_t e_track);
231
232 private:
233     AssetList *p_asset_list;
234     xml_reader_t *p_xmlReader;
235     demux_t      *p_demux;
236
237     string s_id;
238     string s_annotation;
239     Asset  *p_picture_track;
240     Asset  *p_sound_track;
241     Asset  *p_subtitle_track;
242
243     int ParseAssetList(string p_node, int p_type);
244     int ParseAsset(string p_node, int p_type, TrackType_t e_track);
245 };
246
247 class CPL : public XmlFile
248 {
249 public:
250     CPL(demux_t * p_demux, string s_path, AssetList *_asset_list)
251         : XmlFile(p_demux, s_path), asset_list( _asset_list)
252         {};
253     ~CPL();
254     virtual int Parse();
255
256     Reel *getReel(int pos) { return this->vec_reel[pos]; } ;
257     std::vector<Reel *> getReelList() { return this->vec_reel; } ;
258
259 private :
260     AssetList *asset_list;
261
262     string s_id;
263     string s_annotation;
264     string s_icon_id;
265     string s_issue_date;
266     string s_issuer;
267     string s_creator;
268     string s_content_title;
269     string s_content_kind;
270     /* TODO:  ContentVersion, RatingList, signer and signature */
271
272     std::vector<Reel *>   vec_reel;
273     int DummyParse(string p_node, int p_type);
274     int ParseReelList(string p_node, int p_type);
275 };
276
277
278 class PKL : public XmlFile
279 {
280 public:
281     PKL( demux_t * p_demux, string s_path, AssetList *_asset_list, string s )
282         : XmlFile( p_demux, s_path ), asset_list( _asset_list ), s_dcp_path( s )
283         {};
284     ~PKL();
285     virtual int Parse();
286
287     int FindCPLs();
288     CPL *getCPL(int pos) { return this->vec_cpl[pos]; };
289
290 private:
291     AssetList *asset_list;
292
293     string s_id;
294     string s_annotation;
295     string s_issue_date;
296     string s_issuer;
297     string s_creator;
298     string s_icon_id;
299     string s_group_id;
300     string s_dcp_path;
301     std::vector<CPL *> vec_cpl;
302
303     int ParseAssetList(string p_node, int p_type);
304     int ParseAsset(string p_node, int p_type);
305     int ParseSigner(string p_node, int p_type);
306     int ParseSignature(string p_node, int p_type);
307
308 };
309
310 class AssetMap : public XmlFile {
311
312 public:
313     AssetMap( demux_t * p_demux, string s_path, dcp_t *_p_dcp)
314         : XmlFile( p_demux, s_path ), p_dcp( _p_dcp) {};
315     ~AssetMap();
316
317     static Asset * getAssetById(AssetList*, const string p_id);
318
319     virtual int Parse();
320 private:
321     dcp_t *p_dcp;
322
323     int ParseAssetList (xml_reader_t *p_xmlReader, const string p_node, int p_type);
324 };
325
326 class KDM : public XmlFile {
327
328 public:
329     KDM( demux_t * p_demux, string s_path, dcp_t *_p_dcp )
330         : XmlFile( p_demux, s_path ), p_dcp(_p_dcp) {}
331
332     virtual int Parse();
333
334 private:
335     dcp_t *p_dcp;
336
337     int ParsePrivate( const string s_node, int i_type );
338 };
339
340 class AESKey
341 {
342 public:
343     AESKey( demux_t *demux ): p_demux( demux ) { }
344     virtual ~AESKey() {};
345
346     const string getKeyId() { return this->s_key_id; };
347     const unsigned char * getKey() { return this->ps_key; };
348
349     int Parse( xml_reader_t *p_xml_reader, string s_node, int i_type );
350
351 private:
352     demux_t *p_demux;
353     string s_key_id;
354     unsigned char ps_key[16];
355
356     int decryptRSA( string s_cipher_text_b64 );
357     int extractInfo( unsigned char * ps_plain_text, bool smpte );
358 };
359
360 class RSAKey
361 {
362 public:
363     RSAKey( demux_t *demux ):
364         priv_key( NULL ), p_demux( demux ) { }
365     virtual ~RSAKey() { gcry_sexp_release( priv_key ); }
366
367     /* some ASN.1 tags.  */
368     enum
369     {
370       TAG_INTEGER = 2,
371       TAG_SEQUENCE = 16,
372     };
373
374     /* ASN.1 Parser object.  */
375     struct tag_info
376     {
377         int class_;            /* Object class.  */
378         unsigned long tag;     /* The tag of the object.  */
379         unsigned long length;  /* Length of the values.  */
380         int nhdr;              /* Length of the header (TL).  */
381         unsigned int ndef:1;   /* The object has an indefinite length.  */
382         unsigned int cons:1;   /* This is a constructed object.  */
383     };
384
385     int setPath();
386     int readPEM();
387     int readDER( unsigned char const *ps_data_der, size_t length );
388     int parseTag( unsigned char const **buffer, size_t *buflen, struct tag_info *ti);
389
390     gcry_sexp_t priv_key;
391
392 private:
393     demux_t *p_demux;
394     string s_path;
395 };
396
397 #endif /* include-guard */