DCP: fixed include-guards
[vlc.git] / modules / access / dcp / dcp.cpp
1 /*****************************************************************************
2  * Copyright (C) 2012-2013 VLC authors and VideoLAN
3  *
4  * Authors:
5  *          Nicolas Bertrand <nico@isf.cc>
6  *          Simona-Marinela Prodea <simona dot marinela dot prodea at gmail dot com>
7  *          Jean-Baptiste Kempf <jb@videolan.org>
8  *          Guillaume Gonnaud
9  *          Valentin Vetter <vvetter@outlook.com>
10  *          Anthony Giniers
11  *          Ludovic Hoareau
12  *          Loukmane Dessai
13  *          Pierre Villard <pierre dot villard dot fr at gmail dot com>
14  *          Claire Etienne
15  *          Aurélie Sbinné
16  *          Samuel Kerjose
17  *          Julien Puyobro
18  *
19  * This program is free software; you can redistribute it and/or modify it
20  * under the terms of the GNU Lesser General Public License as published by
21  * the Free Software Foundation; either version 2.1 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU Lesser General Public License
30  * along with this program; if not, write to the Free Software Foundation,
31  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
32  *****************************************************************************/
33
34 /**
35  * @file dcp.cpp
36  * @brief DCP access-demux module for Digital Cinema Packages using asdcp library
37  */
38
39 #ifdef HAVE_CONFIG_H
40 # include "config.h"
41 #endif
42
43 #define KDM_HELP_TEXT          "KDM file"
44 #define KDM_HELP_LONG_TEXT     "Path to Key Delivery Message XML file"
45
46 /* VLC core API headers */
47 #include <vlc_common.h>
48 #include <vlc_demux.h>
49 #include <vlc_plugin.h>
50 #include <vlc_xml.h>
51 #include <vlc_url.h>
52 #include <vlc_aout.h>
53
54 /* ASDCP headers */
55 #include <AS_DCP.h>
56
57 #include <vector>
58
59 #include "dcpparser.h"
60
61 using namespace ASDCP;
62
63 #define FRAME_BUFFER_SIZE 1302083 /* maximum frame length, in bytes, after
64                                      "Digital Cinema System Specification Version 1.2
65                                      with Errata as of 30 August 2012" */
66
67 /* Forward declarations */
68 static int Open( vlc_object_t * );
69 static void Close( vlc_object_t * );
70
71 /* Module descriptor */
72 vlc_module_begin()
73     set_shortname( N_( "DCP" ) )
74     add_shortcut( "dcp" )
75     add_loadfile( "kdm", "", KDM_HELP_TEXT, KDM_HELP_LONG_TEXT, false )
76     set_description( N_( "Digital Cinema Package module" ) )
77     set_capability( "access_demux", 0 )
78     set_category( CAT_INPUT )
79     set_subcategory( SUBCAT_INPUT_ACCESS )
80     set_callbacks( Open, Close )
81 vlc_module_end()
82
83 //! Kind of MXF MEDIA TYPE
84 typedef enum MxfMedia_t {
85     MXF_UNKNOWN = 0,
86     MXF_PICTURE,
87     MXF_AUDIO,
88 } MxfMedia_t;
89
90 union videoReader_t
91 {
92    /* JPEG2000 essence type */
93    ASDCP::JP2K::MXFReader *p_PicMXFReader;
94
95    /* JPEG2000 stereoscopic essence type */
96    ASDCP::JP2K::MXFSReader *p_PicMXFSReader;
97
98    /* MPEG2 essence type */
99    ASDCP::MPEG2::MXFReader *p_VideoMXFReader;
100 };
101
102 struct audioReader_t
103 {
104     PCM::MXFReader *p_AudioMXFReader;
105 };
106
107 /* ASDCP library (version 1.10.48) can handle files having one of the following Essence Types, as defined in AS_DCP.h:
108     ESS_UNKNOWN,     // the file is not a supported AS-DCP essence container
109     ESS_MPEG2_VES,   // the file contains an MPEG video elementary stream
110     ESS_JPEG_2000,   // the file contains one or more JPEG 2000 codestreams
111     ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
112     ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
113     ESS_TIMED_TEXT,  // the file contains an XML timed text document and one or more resources
114     ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic).
115
116     The classes for handling these essence types are defined in AS_DCP.h and are different for each essence type, respectively. The demux_sys_t structure contains members for handling each of these essence types.
117 */
118
119 class demux_sys_t
120 {
121  public:
122     /* ASDCP Picture Essence Type */
123     EssenceType_t PictureEssType;
124
125     /* ASDCP Video MXF Reader */
126     std::vector<videoReader_t> v_videoReader;
127
128     /* ASDCP Audio MXF Reader */
129     std::vector<audioReader_t> v_audioReader;
130
131     /* audio buffer size */
132     uint32_t i_audio_buffer;
133
134     /* elementary streams */
135     es_out_id_t *p_video_es;
136     es_out_id_t *p_audio_es;
137
138     /* DCP object */
139     dcp_t *p_dcp;
140
141     /* current absolute frame number */
142     uint32_t frame_no;
143
144     /* frame rate */
145     int frame_rate_num;
146     int frame_rate_denom;
147
148     /* total number of frames */
149     uint32_t frames_total;
150
151     /* current video reel */
152     unsigned int i_video_reel;
153
154     /* current audio reel */
155     unsigned int i_audio_reel;
156
157     uint8_t i_chans_to_reorder;            /* do we need channel reordering */
158     uint8_t pi_chan_table[AOUT_CHAN_MAX];
159     uint8_t i_channels;
160
161     mtime_t i_pts;
162
163     demux_sys_t():
164         PictureEssType ( ESS_UNKNOWN ),
165         v_videoReader(),
166         v_audioReader(),
167         p_video_es( NULL ),
168         p_audio_es( NULL ),
169         p_dcp( NULL ),
170         frame_no( 0 ),
171         frames_total( 0 ),
172         i_video_reel( 0 ),
173         i_audio_reel( 0 ) {};
174
175     ~demux_sys_t()
176     {
177         switch ( PictureEssType )
178         {
179             case ESS_UNKNOWN:
180                 break;
181             case ESS_JPEG_2000:
182                 for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
183                 {
184                     delete v_videoReader[i].p_PicMXFReader;
185                 }
186                 break;
187             case ESS_JPEG_2000_S:
188                 for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
189                 {
190                     delete v_videoReader[i].p_PicMXFSReader;
191                 }
192                 break;
193             case ESS_MPEG2_VES:
194                 for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
195                 {
196                     delete v_videoReader[i].p_VideoMXFReader;
197                 }
198                 break;
199             default:
200                 break;
201         }
202
203         for ( unsigned int i = 0; i < v_audioReader.size(); i++ )
204         {
205             delete v_audioReader[i].p_AudioMXFReader;
206         }
207
208         delete p_dcp;
209     }
210 };
211
212 /*TODO: basic correlation between SMPTE S428-3/S429-2
213  * Real sound is more complex with case of left/right surround, ...
214  * and hearing impaired/Narration channels */
215
216 /* 1 channel: mono */
217 static const uint32_t i_channels_1[] =
218 { AOUT_CHAN_LEFT, 0 };
219
220 /* 2 channels: stereo */
221 static const uint32_t i_channels_2[]=
222 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 };
223
224 /* 4 channels */
225 static const uint32_t i_channels_4[] =
226 {   AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
227     AOUT_CHAN_LFE, 0  };
228
229 /* 6 channels: 5.1 */
230 static const uint32_t i_channels_6[] =
231 {   AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,      AOUT_CHAN_CENTER,
232     AOUT_CHAN_LFE,  AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,
233     0 };
234
235 /* 7 channels: 6.1 */
236 static const uint32_t i_channels_7[] =
237 {   AOUT_CHAN_LEFT,       AOUT_CHAN_RIGHT,    AOUT_CHAN_CENTER,
238     AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
239     AOUT_CHAN_REARCENTER, 0  };
240
241 /* 8 channels:  7.1 */
242 static const uint32_t i_channels_8[] =
243 {   AOUT_CHAN_LEFT,        AOUT_CHAN_RIGHT,      AOUT_CHAN_CENTER,
244     AOUT_CHAN_LFE,         AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,
245     AOUT_CHAN_MIDDLELEFT,  AOUT_CHAN_MIDDLERIGHT, 0 };
246
247 /* 9 channels; 8.1 */
248 static const uint32_t i_channels_9[] =
249 {   AOUT_CHAN_LEFT,        AOUT_CHAN_RIGHT,      AOUT_CHAN_CENTER,
250     AOUT_CHAN_LFE,         AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,
251     AOUT_CHAN_MIDDLELEFT,  AOUT_CHAN_MIDDLERIGHT, AOUT_CHAN_REARCENTER, 0 };
252
253 static const uint32_t *pi_channels_aout [] =
254 {   NULL,
255     i_channels_1,
256     i_channels_2,
257     NULL,
258     i_channels_4,
259     NULL,
260     i_channels_6,
261     i_channels_7,
262     i_channels_8,
263     i_channels_9 };
264
265 static const unsigned i_channel_mask[] =
266 {    0,
267     AOUT_CHAN_LEFT,
268     AOUT_CHANS_STEREO,
269     0,
270     AOUT_CHANS_3_1,
271     0,
272     AOUT_CHANS_5_1,
273     AOUT_CHANS_6_1_MIDDLE,
274     AOUT_CHANS_7_1,
275     AOUT_CHANS_8_1 };
276
277 /*****************************************************************************
278  * Local prototypes
279  *****************************************************************************/
280
281 static int Demux( demux_t * );
282 static int Control( demux_t *, int, va_list );
283
284 int dcpInit ( demux_t *p_demux );
285 int parseXML ( demux_t * p_demux );
286 static inline void fillVideoFmt(
287         video_format_t * fmt, unsigned int width, unsigned int height,
288         unsigned int frame_rate_num, unsigned int frame_rate_denom );
289 void CloseDcpAndMxf( demux_t *p_demux );
290
291
292
293 /*****************************************************************************
294  * Open: module init function
295  *****************************************************************************/
296 static int Open( vlc_object_t *obj )
297 {
298     demux_t *p_demux = ( demux_t* ) obj;
299     demux_sys_t *p_sys;
300     es_format_t video_format, audio_format;
301     int retval;
302
303     if( !p_demux->psz_file )
304         return VLC_EGENERIC;
305
306     p_sys = new ( nothrow ) demux_sys_t();
307     if( unlikely( p_sys == NULL ) ) {
308         return VLC_ENOMEM;
309     }
310     p_demux->p_sys = p_sys;
311
312     /* Allocate DCP object */
313     dcp_t *p_dcp = new ( nothrow ) dcp_t;
314     if( unlikely( p_dcp == NULL ) ) {
315         delete  p_sys;
316         return VLC_ENOMEM;
317     }
318     p_sys->p_dcp = p_dcp;
319
320
321     /* handle the DCP directory, saving the paths for audio and video file, returning error if unsuccessful */
322     if( ( retval = dcpInit( p_demux ) ) )
323         goto error;
324
325     /* Open video file */
326     EssenceType_t essInter;
327     for ( size_t i = 0; i < ( p_sys->p_dcp->video_reels.size() ); i++ )
328     {
329         EssenceType( p_sys->p_dcp->video_reels[i].filename.c_str(), essInter );
330         if ( i == 0 )
331         {
332             p_sys->PictureEssType = essInter;
333         }
334         else
335         {
336             if ( essInter != p_sys->PictureEssType )
337             {
338                 msg_Err( p_demux, "Integrity check failed : different essence containers" );
339                 retval = VLC_EGENERIC;
340                 goto error;
341             }
342         }
343
344         switch( essInter )
345         {
346             case ESS_UNKNOWN:
347                 msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container", p_sys->p_dcp->video_reels[i].filename.c_str() );
348                 retval = VLC_EGENERIC;
349                 goto error;
350
351             case ESS_JPEG_2000:
352             case ESS_JPEG_2000_S: {
353                 JP2K::PictureDescriptor PicDesc;
354                 if (p_sys->PictureEssType == ESS_JPEG_2000_S) {     /* 3D JPEG2000 */
355                     JP2K::MXFSReader * p_PicMXFSReader = new ( nothrow ) JP2K::MXFSReader();
356
357                     if( !p_PicMXFSReader) {
358                         retval = VLC_ENOMEM;
359                         goto error;
360                     }
361                     if( !ASDCP_SUCCESS( p_PicMXFSReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
362                         msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->video_reels[i].filename.c_str() );
363                         retval = VLC_EGENERIC;
364                         delete p_PicMXFSReader;
365                         goto error;
366                     }
367
368                     p_PicMXFSReader->FillPictureDescriptor( PicDesc );
369                     videoReader_t videoReader;
370                     videoReader.p_PicMXFSReader = p_PicMXFSReader;
371                     p_sys->v_videoReader.push_back(videoReader);
372                 } else {                                            /* 2D JPEG2000 */
373                     JP2K::MXFReader *p_PicMXFReader = new ( nothrow ) JP2K::MXFReader();
374                     if( !p_PicMXFReader ) {
375                         retval = VLC_ENOMEM;
376                         goto error;
377                     }
378                     if( !ASDCP_SUCCESS( p_PicMXFReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
379                         msg_Err( p_demux, "File %s could not be opened with ASDCP",
380                                         p_sys->p_dcp->video_reels[i].filename.c_str() );
381                         retval = VLC_EGENERIC;
382                         delete p_PicMXFReader;
383                         goto error;
384                     }
385
386                     p_PicMXFReader->FillPictureDescriptor( PicDesc );
387                     videoReader_t videoReader;
388                     videoReader.p_PicMXFReader = p_PicMXFReader;
389                     p_sys->v_videoReader.push_back(videoReader);
390                 }
391                 es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_JPEG2000 );
392                 fillVideoFmt( &video_format.video, PicDesc.StoredWidth, PicDesc.StoredHeight,
393                                 PicDesc.EditRate.Numerator, PicDesc.EditRate.Denominator );
394
395
396                 if ( i > 0 ) {
397                     if ( p_sys->frame_rate_num != PicDesc.EditRate.Numerator ||
398                             p_sys->frame_rate_denom != PicDesc.EditRate.Denominator )
399                     {
400                         msg_Err( p_demux, "Integrity check failed : different frame rates" );
401                         retval = VLC_EGENERIC;
402                         goto error;
403                     }
404                 }
405                 else
406                 {
407                     p_sys->frame_rate_num   = PicDesc.EditRate.Numerator;
408                     p_sys->frame_rate_denom = PicDesc.EditRate.Denominator;
409                 }
410
411                 p_sys->frames_total += p_sys->p_dcp->video_reels[i].i_duration;
412                 break;
413             }
414             case ESS_MPEG2_VES: {
415
416                 MPEG2::MXFReader *p_VideoMXFReader = new ( nothrow ) MPEG2::MXFReader();
417
418                 videoReader_t videoReader;
419                 videoReader.p_VideoMXFReader = p_VideoMXFReader;
420                 p_sys->v_videoReader.push_back(videoReader);
421
422                 MPEG2::VideoDescriptor  VideoDesc;
423
424                 if( !p_VideoMXFReader ) {
425                     retval = VLC_ENOMEM;
426                     goto error;
427                 }
428
429                 if( !ASDCP_SUCCESS( p_VideoMXFReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
430                     msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->video_reels[i].filename.c_str() );
431                     retval = VLC_EGENERIC;
432                     goto error;
433                 }
434
435                 p_VideoMXFReader->FillVideoDescriptor( VideoDesc );
436
437                 es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_MPGV );
438                 fillVideoFmt( &video_format.video, VideoDesc.StoredWidth, VideoDesc.StoredHeight,
439                               VideoDesc.EditRate.Numerator, VideoDesc.EditRate.Denominator );
440
441
442                 if ( i > 0 ) {
443                     if ( p_sys->frame_rate_num != VideoDesc.EditRate.Numerator ||
444                             p_sys->frame_rate_denom != VideoDesc.EditRate.Denominator)
445                     {
446                         msg_Err( p_demux, "Integrity check failed : different frame rates" );
447                         retval = VLC_EGENERIC;
448                         goto error;
449                     }
450                 }
451                 else
452                 {
453                     p_sys->frame_rate_num   = VideoDesc.EditRate.Numerator;
454                     p_sys->frame_rate_denom = VideoDesc.EditRate.Denominator;
455                 }
456
457                 p_sys->frames_total += p_sys->p_dcp->video_reels[i].i_duration;
458                 break;
459             }
460             default:
461                 msg_Err( p_demux, "Unrecognized video format" );
462                 retval = VLC_EGENERIC;
463                 goto error;
464         }
465     }
466
467     if ( (p_sys->frame_rate_num == 0) || (p_sys->frame_rate_denom == 0) ) {
468         msg_Err(p_demux, "Invalid frame rate (%i/%i)",
469                 p_sys->frame_rate_num, p_sys->frame_rate_denom);
470         retval = VLC_EGENERIC;
471         goto error;
472     }
473
474     if( ( p_sys->p_video_es = es_out_Add( p_demux->out, &video_format ) ) == NULL ) {
475         msg_Err( p_demux, "Failed to add video es" );
476         retval = VLC_EGENERIC;
477         goto error;
478     }
479
480     /* Open audio file */
481     EssenceType_t AudioEssType;
482     EssenceType_t AudioEssTypeCompare;
483
484     if( !p_sys->p_dcp->audio_reels.empty() )
485     {
486         EssenceType( p_sys->p_dcp->audio_reels[0].filename.c_str(), AudioEssType );
487
488         if ( (AudioEssType == ESS_PCM_24b_48k) || (AudioEssType == ESS_PCM_24b_96k) ) {
489             PCM::AudioDescriptor AudioDesc;
490
491             for ( size_t i = 0; i < ( p_sys->p_dcp->audio_reels.size() ); i++)
492             {
493                 if ( i != 0 )
494                 {
495                     EssenceType( p_sys->p_dcp->audio_reels[i].filename.c_str(), AudioEssTypeCompare );
496                     if ( AudioEssTypeCompare != AudioEssType )
497                     {
498                         msg_Err( p_demux, "Integrity check failed : different audio essence types in %s",
499                         p_sys->p_dcp->audio_reels[i].filename.c_str() );
500                         retval = VLC_EGENERIC;
501                         goto error;
502                     }
503                 }
504                 PCM::MXFReader *p_AudioMXFReader = new ( nothrow ) PCM::MXFReader();
505
506                 if( !p_AudioMXFReader ) {
507                     retval = VLC_ENOMEM;
508                     goto error;
509                 }
510
511                 if( !ASDCP_SUCCESS( p_AudioMXFReader->OpenRead( p_sys->p_dcp->audio_reels[i].filename.c_str() ) ) ) {
512                     msg_Err( p_demux, "File %s could not be opened with ASDCP",
513                                     p_sys->p_dcp->audio_reels[i].filename.c_str() );
514                     retval = VLC_EGENERIC;
515                     delete p_AudioMXFReader;
516                     goto error;
517                 }
518
519                 p_AudioMXFReader->FillAudioDescriptor( AudioDesc );
520
521                 if (  (AudioDesc.ChannelCount >= sizeof(pi_channels_aout)/sizeof(uint32_t *))
522                         || (pi_channels_aout[AudioDesc.ChannelCount] == NULL) )
523                 {
524                     msg_Err(p_demux, " DCP module does not support %i channels", AudioDesc.ChannelCount);
525                     retval = VLC_EGENERIC;
526                     delete p_AudioMXFReader;
527                     goto error;
528                 }
529                 audioReader_t audioReader;
530                 audioReader.p_AudioMXFReader = p_AudioMXFReader;
531                 p_sys->v_audioReader.push_back( audioReader );
532
533             }
534             es_format_Init( &audio_format, AUDIO_ES, VLC_CODEC_S24L );
535             if( AudioDesc.AudioSamplingRate.Denominator != 0 )
536                 audio_format.audio.i_rate =
537                     AudioDesc.AudioSamplingRate.Numerator
538                     / AudioDesc.AudioSamplingRate.Denominator;
539             else if ( AudioEssType == ESS_PCM_24b_96k )
540                 audio_format.audio.i_rate = 96000;
541             else
542                 audio_format.audio.i_rate = 48000;
543
544             p_sys->i_audio_buffer = PCM::CalcFrameBufferSize( AudioDesc );
545             if (p_sys->i_audio_buffer == 0) {
546                 msg_Err( p_demux, "Failed to get audio buffer size" );
547                 retval = VLC_EGENERIC;
548                 goto error;
549             }
550
551             audio_format.audio.i_bitspersample = AudioDesc.QuantizationBits;
552             audio_format.audio.i_blockalign    = AudioDesc.BlockAlign;
553             audio_format.audio.i_channels      =
554             p_sys->i_channels                  = AudioDesc.ChannelCount;
555
556             /* Manage channel orders */
557             p_sys->i_chans_to_reorder =  aout_CheckChannelReorder(
558                     pi_channels_aout[AudioDesc.ChannelCount], NULL,
559                     i_channel_mask[AudioDesc.ChannelCount],   p_sys->pi_chan_table );
560
561             if( ( p_sys->p_audio_es = es_out_Add( p_demux->out, &audio_format ) ) == NULL ) {
562                 msg_Err( p_demux, "Failed to add audio es" );
563                 retval = VLC_EGENERIC;
564                 goto error;
565             }
566         } else {
567             msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container",
568                     p_sys->p_dcp->audio_reels[0].filename.c_str() );
569             retval = VLC_EGENERIC;
570             goto error;
571         }
572     }
573     p_demux->pf_demux = Demux;
574     p_demux->pf_control = Control;
575     p_sys->frame_no = p_sys->p_dcp->video_reels[0].i_entrypoint;
576
577     return VLC_SUCCESS;
578 error:
579     CloseDcpAndMxf( p_demux );
580     return retval;
581 }
582
583
584 /*****************************************************************************
585  * Close: module destroy function
586  *****************************************************************************/
587 static inline void Close( vlc_object_t *obj )
588 {
589     demux_t *p_demux = ( demux_t* ) obj;
590     CloseDcpAndMxf( p_demux );
591 }
592
593
594
595 /*****************************************************************************
596  * Demux: DCP Demuxing function
597  *****************************************************************************/
598 static int Demux( demux_t *p_demux )
599 {
600     demux_sys_t *p_sys = p_demux->p_sys;
601     block_t *p_video_frame = NULL, *p_audio_frame = NULL;
602
603     PCM::FrameBuffer   AudioFrameBuff( p_sys->i_audio_buffer);
604     AESDecContext video_aes_ctx, audio_aes_ctx;
605
606     /* swaping video reels */
607     if  ( p_sys->frame_no == p_sys->p_dcp->video_reels[p_sys->i_video_reel].i_absolute_end )
608     {
609         if ( p_sys->i_video_reel + 1 == p_sys->v_videoReader.size() )
610         {
611             return 0;
612         }
613         else
614         {
615             p_sys->i_video_reel++;
616         }
617     }
618
619     /* swaping audio reels */
620     if  ( !p_sys->p_dcp->audio_reels.empty() && p_sys->frame_no == p_sys->p_dcp->audio_reels[p_sys->i_audio_reel].i_absolute_end )
621      {
622          if ( p_sys->i_audio_reel + 1 == p_sys->v_audioReader.size() )
623          {
624              return 0;//should never go there
625          }
626          else
627          {
628              p_sys->i_audio_reel++;
629          }
630      }
631
632     /* video frame */
633
634     /* initialize AES context, if reel is encrypted */
635     if( p_sys &&
636             p_sys->p_dcp &&
637             p_sys->p_dcp->video_reels.size() > p_sys->i_video_reel &&
638             p_sys->p_dcp->video_reels[p_sys->i_video_reel].p_key )
639     {
640         if( ! ASDCP_SUCCESS( video_aes_ctx.InitKey( p_sys->p_dcp->video_reels[p_sys->i_video_reel].p_key->getKey() ) ) )
641         {
642             msg_Err( p_demux, "ASDCP failed to initialize AES key" );
643             goto error;
644         }
645     }
646
647     switch( p_sys->PictureEssType )
648     {
649         case ESS_JPEG_2000:
650         case ESS_JPEG_2000_S:{
651             JP2K::FrameBuffer  PicFrameBuff(FRAME_BUFFER_SIZE);
652             int nextFrame = p_sys->frame_no + p_sys->p_dcp->video_reels[p_sys->i_video_reel].i_correction;
653             if ( ( p_video_frame = block_Alloc( FRAME_BUFFER_SIZE )) == NULL )
654                 goto error;
655
656             if ( ! ASDCP_SUCCESS(
657                     PicFrameBuff.SetData(p_video_frame->p_buffer, FRAME_BUFFER_SIZE)) )
658                 goto error_asdcp;
659             if ( p_sys->PictureEssType == ESS_JPEG_2000_S ) {
660                 if ( ! ASDCP_SUCCESS(
661                         p_sys->v_videoReader[p_sys->i_video_reel].p_PicMXFSReader->ReadFrame(nextFrame, JP2K::SP_LEFT, PicFrameBuff, &video_aes_ctx, 0)) ) {
662                     PicFrameBuff.SetData(0,0);
663                     goto error_asdcp;
664                 }
665              } else {
666                 if ( ! ASDCP_SUCCESS(
667                         p_sys->v_videoReader[p_sys->i_video_reel].p_PicMXFReader->ReadFrame(nextFrame, PicFrameBuff, &video_aes_ctx, 0)) ) {
668                     PicFrameBuff.SetData(0,0);
669                     goto error_asdcp;
670                 }
671             }
672             p_video_frame->i_buffer = PicFrameBuff.Size();
673             break;
674         }
675         case ESS_MPEG2_VES: {
676             MPEG2::FrameBuffer VideoFrameBuff(FRAME_BUFFER_SIZE);
677             if ( ( p_video_frame = block_Alloc( FRAME_BUFFER_SIZE )) == NULL )
678                 goto error;
679
680             if ( ! ASDCP_SUCCESS(
681                     VideoFrameBuff.SetData(p_video_frame->p_buffer, FRAME_BUFFER_SIZE)) )
682                 goto error_asdcp;
683
684             if ( ! ASDCP_SUCCESS(
685                     p_sys->v_videoReader[p_sys->i_video_reel].p_VideoMXFReader->ReadFrame(p_sys->frame_no + p_sys->p_dcp->video_reels[p_sys->i_video_reel].i_correction, VideoFrameBuff, &video_aes_ctx, 0)) ) {
686                 VideoFrameBuff.SetData(0,0);
687                 goto error_asdcp;
688             }
689
690             p_video_frame->i_buffer = VideoFrameBuff.Size();
691             break;
692         }
693         default:
694             msg_Err( p_demux, "Unrecognized video format" );
695             goto error;
696     }
697
698     p_video_frame->i_length = CLOCK_FREQ * p_sys->frame_rate_denom / p_sys->frame_rate_num;
699     p_video_frame->i_pts = CLOCK_FREQ * p_sys->frame_no * p_sys->frame_rate_denom / p_sys->frame_rate_num;
700
701     if( !p_sys->p_dcp->audio_reels.empty() )
702     {
703         /* audio frame */
704         if ( ( p_audio_frame = block_Alloc( p_sys->i_audio_buffer )) == NULL ) {
705             goto error;
706         }
707
708         /* initialize AES context, if reel is encrypted */
709         if( p_sys &&
710                 p_sys->p_dcp &&
711                 p_sys->p_dcp->audio_reels.size() > p_sys->i_audio_reel &&
712                 p_sys->p_dcp->audio_reels[p_sys->i_audio_reel].p_key )
713         {
714             if( ! ASDCP_SUCCESS( audio_aes_ctx.InitKey( p_sys->p_dcp->audio_reels[p_sys->i_audio_reel].p_key->getKey() ) ) )
715             {
716                 msg_Err( p_demux, "ASDCP failed to initialize AES key" );
717                 goto error;
718             }
719         }
720
721         if ( ! ASDCP_SUCCESS(
722                 AudioFrameBuff.SetData(p_audio_frame->p_buffer, p_sys->i_audio_buffer)) ) {
723             goto error_asdcp;
724         }
725
726         if ( ! ASDCP_SUCCESS(
727                 p_sys->v_audioReader[p_sys->i_audio_reel].p_AudioMXFReader->ReadFrame(p_sys->frame_no + p_sys->p_dcp->audio_reels[p_sys->i_audio_reel].i_correction, AudioFrameBuff, &audio_aes_ctx, 0)) ) {
728             AudioFrameBuff.SetData(0,0);
729             goto error_asdcp;
730         }
731
732         if( p_sys->i_chans_to_reorder )
733             aout_ChannelReorder( p_audio_frame->p_buffer, p_audio_frame->i_buffer,
734                     p_sys->i_channels,
735                     p_sys->pi_chan_table, VLC_CODEC_S24L );
736
737         p_audio_frame->i_buffer = AudioFrameBuff.Size();
738         p_audio_frame->i_length = CLOCK_FREQ * p_sys->frame_rate_denom / p_sys->frame_rate_num;
739         p_audio_frame->i_pts = CLOCK_FREQ * p_sys->frame_no * p_sys->frame_rate_denom / p_sys->frame_rate_num;
740         /* Video is the main pts */
741         if ( p_audio_frame->i_pts != p_video_frame->i_pts ) {
742             msg_Err( p_demux, "Audio and video frame pts are not in sync" );
743         }
744     }
745
746     p_sys->i_pts = p_video_frame->i_pts;
747     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts );
748     if(p_video_frame)
749         es_out_Send( p_demux->out, p_sys->p_video_es, p_video_frame );
750     if(p_audio_frame)
751         es_out_Send( p_demux->out, p_sys->p_audio_es, p_audio_frame );
752
753     p_sys->frame_no++;
754
755     return 1;
756
757 error_asdcp:
758     msg_Err( p_demux, "Couldn't read frame with ASDCP");
759 error:
760     if (p_video_frame)
761         block_Release(p_video_frame);
762     if (p_audio_frame)
763         block_Release(p_audio_frame);
764     return -1;
765 }
766
767 /*****************************************************************************
768  * Control: handle the controls
769  *****************************************************************************/
770 static int Control( demux_t *p_demux, int query, va_list args )
771 {
772     double f,*pf;
773     bool *pb;
774     int64_t *pi64, i64;
775     demux_sys_t *p_sys = p_demux->p_sys;
776
777     switch ( query )
778     {
779         case DEMUX_CAN_PAUSE:
780         case DEMUX_CAN_CONTROL_PACE:
781             pb = ( bool* ) va_arg ( args, bool* );
782             *pb = true;
783             break;
784
785         case DEMUX_CAN_SEEK:
786             pb = (bool *)va_arg( args, bool * );
787             if( p_sys->PictureEssType != ESS_MPEG2_VES )
788                 *pb = true;
789             else
790                 *pb = false;
791             break;
792
793         case DEMUX_SET_PAUSE_STATE:
794             return VLC_SUCCESS;
795
796         case DEMUX_GET_POSITION:
797             pf = ( double* ) va_arg ( args, double* );
798             if( p_sys->frames_total != 0 )
799                 *pf = (double) p_sys->frame_no / (double) p_sys->frames_total;
800             else {
801                 msg_Warn( p_demux, "Total number of frames is 0" );
802                 *pf = 0.0;
803             }
804             break;
805
806         case DEMUX_SET_POSITION:
807             f = ( double ) va_arg ( args, double );
808             p_sys->frame_no = (int) ( f * p_sys->frames_total );
809             break;
810
811         case DEMUX_GET_LENGTH:
812             pi64 = ( int64_t* ) va_arg ( args, int64_t* );
813             *pi64 =  ( p_sys->frames_total * p_sys->frame_rate_denom / p_sys->frame_rate_num ) * CLOCK_FREQ;
814             break;
815
816         case DEMUX_GET_TIME:
817             pi64 = ( int64_t* ) va_arg ( args, int64_t* );
818             *pi64 = p_sys->i_pts >= 0 ? p_sys->i_pts : 0;
819             break;
820
821         case DEMUX_SET_TIME:
822             i64 = ( int64_t ) va_arg ( args, int64_t );
823             msg_Warn( p_demux, "DEMUX_SET_TIME"  );
824             p_sys->frame_no = i64 * p_sys->frame_rate_num / ( CLOCK_FREQ * p_sys->frame_rate_denom );
825             p_sys->i_pts= i64;
826             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts);
827             es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, ( mtime_t ) i64 );
828             break;
829         case DEMUX_GET_PTS_DELAY:
830             pi64 = (int64_t*)va_arg( args, int64_t * );
831             *pi64 =
832                 INT64_C(1000) * var_InheritInteger( p_demux, "file-caching" );
833             return VLC_SUCCESS;
834
835
836         default:
837             msg_Warn( p_demux, "Unknown query %d in DCP Control", query );
838             return VLC_EGENERIC;
839     }
840
841     return VLC_SUCCESS;
842 }
843
844
845 /*****************************************************************************
846  * Low-level functions : string manipulation, free function, etc
847  *****************************************************************************/
848 /**
849  * Function to fill video_format_t fields for an elementary stream
850  * @param fmt video format structure
851  * @param width picture width
852  * @param height picture height
853  * @param frame_rate_num video frame rate numerator
854  * @param frame_rate_denom video frame rate denominator
855  */
856 static inline void fillVideoFmt( video_format_t * fmt, unsigned int width, unsigned int height, unsigned int frame_rate_num, unsigned int frame_rate_denom )
857 {
858     fmt->i_width = width;
859     fmt->i_height = height;
860     /* As input are square pixels let VLC  or decoder fix SAR, origin,
861      * and visible area */
862     fmt->i_frame_rate = frame_rate_num;
863     fmt->i_frame_rate_base = frame_rate_denom;
864 }
865
866 /**
867  * Function to free memory in case of error or when closing the module
868  * @param p_demux DCP access-demux
869  */
870
871
872 void CloseDcpAndMxf( demux_t *p_demux )
873 {
874     demux_sys_t *p_sys = p_demux->p_sys;
875     /* close the files */
876     switch( p_sys->PictureEssType )
877     {
878         case ESS_UNKNOWN:
879             break;
880         case ESS_JPEG_2000:
881             for ( size_t i = 0; i < p_sys->v_videoReader.size(); i++ )
882             {
883                 if( p_sys->v_videoReader[i].p_PicMXFReader )
884                     p_sys->v_videoReader[i].p_PicMXFReader->Close();
885             }
886             break;
887         case ESS_JPEG_2000_S:
888             for ( size_t i = 0; i < p_sys->v_videoReader.size(); i++ )
889             {
890                 if( p_sys->v_videoReader[i].p_PicMXFSReader )
891                     p_sys->v_videoReader[i].p_PicMXFSReader->Close();
892             }
893             break;
894         case ESS_MPEG2_VES:
895             for ( size_t i = 0; i < p_sys->v_videoReader.size(); i++ )
896             {
897                 if( p_sys->v_videoReader[i].p_VideoMXFReader )
898                     p_sys->v_videoReader[i].p_VideoMXFReader->Close();
899             }
900             break;
901         default:
902             break;
903     }
904
905     for ( size_t i = 0; i < p_sys->v_audioReader.size(); i++ )
906     {
907         if( p_sys->v_audioReader[i].p_AudioMXFReader )
908             p_sys->v_audioReader[i].p_AudioMXFReader->Close();
909     }
910
911     delete( p_demux->p_sys );
912 }
913
914
915 /*****************************************************************************
916  * DCP init
917  *****************************************************************************/
918
919 /**
920  * Function to handle the operations with the DCP directory.
921  * @param p_demux Demux pointer.
922  * @return Integer according to the success or not of the process.
923  */
924 int dcpInit ( demux_t *p_demux )
925 {
926     int retval;
927
928     demux_sys_t *p_sys = p_demux->p_sys;
929     dcp_t *p_dcp = p_sys->p_dcp;
930
931     p_dcp->path = p_demux->psz_file;
932     /* Add a '/' in end of path if needed */
933     if ( *(p_dcp->path).rbegin() != '/')
934         p_dcp->path.append( "/" );
935
936     /* Parsing XML files to get audio and video files */
937     msg_Dbg( p_demux, "parsing XML files..." );
938     if( ( retval = parseXML( p_demux ) ) )
939         return retval;
940
941     msg_Dbg(p_demux, "parsing XML files done");
942
943     return VLC_SUCCESS;
944 }
945
946
947 /*****************************************************************************
948  * functions for XML parsing
949  *****************************************************************************/
950
951 /**
952  * Function to retrieve the path to the ASSETMAP file.
953  * @param p_demux DCP access_demux.
954  */
955 static std::string assetmapPath( demux_t * p_demux )
956 {
957     DIR *dir = NULL;
958     struct dirent *ent = NULL;
959     dcp_t *p_dcp = p_demux->p_sys->p_dcp;
960     std::string result;
961
962     if( ( dir = opendir (p_dcp->path.c_str() ) ) != NULL )
963     {
964         /* print all the files and directories within directory */
965         while( ( ent = readdir ( dir ) ) != NULL )
966         {
967             if( strcasecmp( "assetmap", ent->d_name ) == 0 || strcasecmp( "assetmap.xml", ent->d_name ) == 0 )
968             {
969                 /* copy of "path" in "res" */
970                 result = p_dcp->path;
971                 result.append( ent->d_name );
972                 break;
973             }
974         }
975         closedir( dir );
976     }
977     else
978         msg_Err( p_demux, "Could not open the directory: %s", p_dcp->path.c_str() );
979
980     /* if no assetmap file */
981     if( result.empty() )
982         msg_Err( p_demux, "No ASSETMAP found in the directory: %s", p_dcp->path.c_str() );
983
984     return result;
985 }
986
987
988 /**
989  * Function which parses XML files in DCP directory in order to get video and audio files
990  * @param p_demux Demux pointer.
991  * @return Integer according to the success or not of the operation
992  */
993 int parseXML ( demux_t * p_demux )
994 {
995     int retval;
996
997     std::string assetmap_path = assetmapPath( p_demux );
998     /* We get the ASSETMAP file path */
999     if( assetmap_path.empty() )
1000         return VLC_EGENERIC;
1001
1002     /* We parse the ASSETMAP File in order to get CPL File path, PKL File path
1003      and to store UID/Path of all files in DCP directory (except ASSETMAP file) */
1004     AssetMap *assetmap = new (nothrow) AssetMap( p_demux, assetmap_path, p_demux->p_sys->p_dcp );
1005     if( ( retval = assetmap->Parse() ) )
1006         return retval;
1007
1008     delete assetmap;
1009     return VLC_SUCCESS; /* TODO : perform checking on XML parsing */
1010 }