[vlc-devel] [PATCH/RFC] dcp: Read multiple reels
Valentin Vetter
vvetter at outlook.com
Wed Feb 19 03:56:09 CET 2014
Allow to read more than one reel
---
modules/access/dcp/dcp.cpp | 456 +++++++++++++++++++++++++-------------
modules/access/dcp/dcpparser.cpp | 66 ++++--
modules/access/dcp/dcpparser.h | 24 +-
3 files changed, 366 insertions(+), 180 deletions(-)
diff --git a/modules/access/dcp/dcp.cpp b/modules/access/dcp/dcp.cpp
index 36516eb..06ad48a 100644
--- a/modules/access/dcp/dcp.cpp
+++ b/modules/access/dcp/dcp.cpp
@@ -48,6 +48,8 @@
/* ASDCP headers */
#include <AS_DCP.h>
+#include <vector>
+
#include "dcpparser.h"
using namespace ASDCP;
@@ -79,6 +81,23 @@ typedef enum MxfMedia_t {
MXF_AUDIO,
} MxfMedia_t;
+union videoReader_t
+{
+ /* JPEG2000 essence type */
+ ASDCP::JP2K::MXFReader *p_PicMXFReader;
+
+ /* JPEG2000 stereoscopic essence type */
+ ASDCP::JP2K::MXFSReader *p_PicMXFSReader;
+
+ /* MPEG2 essence type */
+ ASDCP::MPEG2::MXFReader *p_VideoMXFReader;
+};
+
+struct audioReader_t
+{
+ PCM::MXFReader *p_AudioMXFReader;
+};
+
/* ASDCP library (version 1.10.48) can handle files having one of the following Essence Types, as defined in AS_DCP.h:
ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
@@ -98,20 +117,10 @@ class demux_sys_t
EssenceType_t PictureEssType;
/* ASDCP Video MXF Reader */
- union
- {
- /* JPEG2000 essence type */
- JP2K::MXFReader *p_PicMXFReader;
-
- /* JPEG2000 stereoscopic essence type */
- JP2K::MXFSReader *p_PicMXFSReader;
-
- /* MPEG2 essence type */
- MPEG2::MXFReader *p_VideoMXFReader;
- };
+ vector<videoReader_t> v_videoReader;
/* ASDCP Audio MXF Reader */
- PCM::MXFReader *p_AudioMXFReader;
+ vector<audioReader_t> v_audioReader;
/* audio buffer size */
uint32_t i_audio_buffer;
@@ -123,7 +132,7 @@ class demux_sys_t
/* DCP object */
dcp_t *p_dcp;
- /* current frame number */
+ /* current absolute frame number */
uint32_t frame_no;
/* frame rate */
@@ -133,6 +142,12 @@ class demux_sys_t
/* total number of frames */
uint32_t frames_total;
+ /* current video reel */
+ int i_video_reel;
+
+ /* current audio reel */
+ int i_audio_reel;
+
uint8_t i_chans_to_reorder; /* do we need channel reordering */
uint8_t pi_chan_table[AOUT_CHAN_MAX];
uint8_t i_channels;
@@ -141,12 +156,15 @@ class demux_sys_t
demux_sys_t():
PictureEssType ( ESS_UNKNOWN ),
- p_PicMXFReader( NULL ),
- p_AudioMXFReader( NULL ),
+ v_videoReader( NULL ),
+ v_audioReader( NULL ),
p_video_es( NULL ),
p_audio_es( NULL ),
p_dcp( NULL ),
- frame_no( 0 ) {};
+ frame_no( 0 ),
+ frames_total( 0 ),
+ i_video_reel( 0 ),
+ i_audio_reel( 0 ) {};
~demux_sys_t()
{
@@ -155,18 +173,32 @@ class demux_sys_t
case ESS_UNKNOWN:
break;
case ESS_JPEG_2000:
- delete p_PicMXFReader;
+ for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
+ {
+ delete v_videoReader[i].p_PicMXFReader;
+ }
break;
case ESS_JPEG_2000_S:
- delete p_PicMXFSReader;
+ for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
+ {
+ delete v_videoReader[i].p_PicMXFSReader;
+ }
break;
case ESS_MPEG2_VES:
- delete p_VideoMXFReader;
+ for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
+ {
+ delete v_videoReader[i].p_VideoMXFReader;
+ }
break;
default:
break;
}
- delete p_AudioMXFReader;
+
+ for ( unsigned int i = 0; i < v_audioReader.size(); i++ )
+ {
+ delete v_audioReader[i].p_AudioMXFReader;
+ }
+
delete p_dcp;
}
};
@@ -284,93 +316,146 @@ static int Open( vlc_object_t *obj )
if( ( retval = dcpInit( p_demux ) ) )
goto error;
-
/* Open video file */
- EssenceType( p_sys->p_dcp->videofile.c_str(), p_sys->PictureEssType );
-
- switch( p_sys->PictureEssType )
+ EssenceType_t essInter;
+ for ( int i = 0; i < ( p_sys->p_dcp->video_reels.size() ); i++ )
{
- case ESS_UNKNOWN:
- msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container", p_sys->p_dcp->videofile.c_str() );
- retval = VLC_EGENERIC;
- goto error;
+ EssenceType( p_sys->p_dcp->video_reels[i].filename.c_str(), essInter );
+ if ( i == 0 )
+ {
+ p_sys->PictureEssType = essInter;
+ }
+ else
+ {
+ if ( essInter != p_sys->PictureEssType )
+ {
+ msg_Err( p_demux, "Integrity check failed : different essence containers" );
+ retval = VLC_EGENERIC;
+ goto error;
+ }
+ }
- case ESS_JPEG_2000:
- case ESS_JPEG_2000_S: {
- JP2K::PictureDescriptor PicDesc;
- if (p_sys->PictureEssType == ESS_JPEG_2000_S) { /* 3D JPEG2000 */
- JP2K::MXFSReader * p_PicMXFSReader = new ( nothrow ) JP2K::MXFSReader();
+ switch( essInter )
+ {
+ case ESS_UNKNOWN:
+ 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() );
+ retval = VLC_EGENERIC;
+ goto error;
- if( !p_PicMXFSReader) {
- retval = VLC_ENOMEM;
- goto error;
+ case ESS_JPEG_2000:
+ case ESS_JPEG_2000_S: {
+ JP2K::PictureDescriptor PicDesc;
+ if (p_sys->PictureEssType == ESS_JPEG_2000_S) { /* 3D JPEG2000 */
+ JP2K::MXFSReader * p_PicMXFSReader = new ( nothrow ) JP2K::MXFSReader();
+
+ if( !p_PicMXFSReader) {
+ retval = VLC_ENOMEM;
+ goto error;
+ }
+ if( !ASDCP_SUCCESS( p_PicMXFSReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
+ msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->video_reels[i].filename.c_str() );
+ retval = VLC_EGENERIC;
+ delete p_PicMXFSReader;
+ goto error;
+ }
+
+ p_PicMXFSReader->FillPictureDescriptor( PicDesc );
+ videoReader_t videoReader;
+ videoReader.p_PicMXFSReader = p_PicMXFSReader;
+ p_sys->v_videoReader.push_back(videoReader);
+ } else { /* 2D JPEG2000 */
+ JP2K::MXFReader *p_PicMXFReader = new ( nothrow ) JP2K::MXFReader();
+ if( !p_PicMXFReader ) {
+ retval = VLC_ENOMEM;
+ goto error;
+ }
+ if( !ASDCP_SUCCESS( p_PicMXFReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
+ msg_Err( p_demux, "File %s could not be opened with ASDCP",
+ p_sys->p_dcp->video_reels[i].filename.c_str() );
+ retval = VLC_EGENERIC;
+ delete p_PicMXFReader;
+ goto error;
+ }
+
+ p_PicMXFReader->FillPictureDescriptor( PicDesc );
+ videoReader_t videoReader;
+ videoReader.p_PicMXFReader = p_PicMXFReader;
+ p_sys->v_videoReader.push_back(videoReader);
}
- if( !ASDCP_SUCCESS( p_PicMXFSReader->OpenRead( p_sys->p_dcp->videofile.c_str() ) ) ) {
- msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->videofile.c_str() );
- retval = VLC_EGENERIC;
- delete p_PicMXFSReader;
- goto error;
+ es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_JPEG2000 );
+ fillVideoFmt( &video_format.video, PicDesc.StoredWidth, PicDesc.StoredHeight,
+ PicDesc.EditRate.Numerator, PicDesc.EditRate.Denominator );
+
+
+ if ( i > 0 ) {
+ if ( p_sys->frame_rate_num != PicDesc.EditRate.Numerator ||
+ p_sys->frame_rate_denom != PicDesc.EditRate.Denominator )
+ {
+ msg_Err( p_demux, "Integrity check failed : different frame rates" );
+ retval = VLC_EGENERIC;
+ goto error;
+ }
}
+ else
+ {
+ p_sys->frame_rate_num = PicDesc.EditRate.Numerator;
+ p_sys->frame_rate_denom = PicDesc.EditRate.Denominator;
+ }
+
+ p_sys->frames_total += p_sys->p_dcp->video_reels[i].i_duration;
+ break;
+ }
+ case ESS_MPEG2_VES: {
- p_PicMXFSReader->FillPictureDescriptor( PicDesc );
- p_sys->p_PicMXFSReader = p_PicMXFSReader;
- } else { /* 2D JPEG2000 */
- JP2K::MXFReader *p_PicMXFReader = new ( nothrow ) JP2K::MXFReader();
- if( !p_PicMXFReader ) {
+ MPEG2::MXFReader *p_VideoMXFReader = new ( nothrow ) MPEG2::MXFReader();
+
+ videoReader_t videoReader;
+ videoReader.p_VideoMXFReader = p_VideoMXFReader;
+ p_sys->v_videoReader.push_back(videoReader);
+
+ MPEG2::VideoDescriptor VideoDesc;
+
+ if( !p_VideoMXFReader ) {
retval = VLC_ENOMEM;
goto error;
}
- if( !ASDCP_SUCCESS( p_PicMXFReader->OpenRead( p_sys->p_dcp->videofile.c_str() ) ) ) {
- msg_Err( p_demux, "File %s could not be opened with ASDCP",
- p_sys->p_dcp->videofile.c_str() );
+
+ if( !ASDCP_SUCCESS( p_VideoMXFReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
+ msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->video_reels[i].filename.c_str() );
retval = VLC_EGENERIC;
- delete p_PicMXFReader;
goto error;
}
- p_PicMXFReader->FillPictureDescriptor( PicDesc );
- p_sys->p_PicMXFReader = p_PicMXFReader;
- }
- es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_JPEG2000 );
- fillVideoFmt( &video_format.video, PicDesc.StoredWidth, PicDesc.StoredHeight,
- PicDesc.EditRate.Numerator, PicDesc.EditRate.Denominator );
+ p_VideoMXFReader->FillVideoDescriptor( VideoDesc );
- p_sys->frame_rate_num = PicDesc.EditRate.Numerator;
- p_sys->frame_rate_denom = PicDesc.EditRate.Denominator;
- p_sys->frames_total = PicDesc.ContainerDuration;
- break;
- }
- case ESS_MPEG2_VES: {
+ es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_MPGV );
+ fillVideoFmt( &video_format.video, VideoDesc.StoredWidth, VideoDesc.StoredHeight,
+ VideoDesc.EditRate.Numerator, VideoDesc.EditRate.Denominator );
- MPEG2::MXFReader *p_VideoMXFReader = p_sys->p_VideoMXFReader = new ( nothrow ) MPEG2::MXFReader();
- MPEG2::VideoDescriptor VideoDesc;
- if( !p_VideoMXFReader ) {
- retval = VLC_ENOMEM;
- goto error;
- }
+ if ( i > 0 ) {
+ if ( p_sys->frame_rate_num != VideoDesc.EditRate.Numerator ||
+ p_sys->frame_rate_denom != VideoDesc.EditRate.Denominator)
+ {
+ msg_Err( p_demux, "Integrity check failed : different frame rates" );
+ retval = VLC_EGENERIC;
+ goto error;
+ }
+ }
+ else
+ {
+ p_sys->frame_rate_num = VideoDesc.EditRate.Numerator;
+ p_sys->frame_rate_denom = VideoDesc.EditRate.Denominator;
+ }
- if( !ASDCP_SUCCESS( p_VideoMXFReader->OpenRead( p_sys->p_dcp->videofile.c_str() ) ) ) {
- msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->videofile.c_str() );
+ p_sys->frames_total += p_sys->p_dcp->video_reels[i].i_duration;
+ break;
+ }
+ default:
+ msg_Err( p_demux, "Unrecognized video format" );
retval = VLC_EGENERIC;
goto error;
- }
-
- p_VideoMXFReader->FillVideoDescriptor( VideoDesc );
-
- es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_MPGV );
- fillVideoFmt( &video_format.video, VideoDesc.StoredWidth, VideoDesc.StoredHeight,
- VideoDesc.EditRate.Numerator, VideoDesc.EditRate.Denominator );
-
- p_sys->frame_rate_num = VideoDesc.EditRate.Numerator;
- p_sys->frame_rate_denom = VideoDesc.EditRate.Denominator;
- p_sys->frames_total = VideoDesc.ContainerDuration;
- break;
}
- default:
- msg_Err( p_demux, "Unrecognized video format" );
- retval = VLC_EGENERIC;
- goto error;
}
if ( (p_sys->frame_rate_num == 0) || (p_sys->frame_rate_denom == 0) ) {
@@ -388,78 +473,104 @@ static int Open( vlc_object_t *obj )
/* Open audio file */
EssenceType_t AudioEssType;
- EssenceType( p_sys->p_dcp->audiofile.c_str(), AudioEssType );
- if ( (AudioEssType == ESS_PCM_24b_48k) || (AudioEssType == ESS_PCM_24b_96k) ) {
- PCM::MXFReader *p_AudioMXFReader = new ( nothrow ) PCM::MXFReader();
- PCM::AudioDescriptor AudioDesc;
+ EssenceType_t AudioEssTypeCompare;
- if( !p_AudioMXFReader ) {
- retval = VLC_ENOMEM;
- goto error;
- }
+ if( p_sys->p_dcp->audio_reels.size() == 0 )
+ {
+ msg_Err( p_demux, "No audio reel found" );
+ retval = VLC_EGENERIC;
+ goto error;
+ }
- if( !ASDCP_SUCCESS( p_AudioMXFReader->OpenRead( p_sys->p_dcp->audiofile.c_str() ) ) ) {
- msg_Err( p_demux, "File %s could not be opened with ASDCP",
- p_sys->p_dcp->audiofile.c_str() );
- retval = VLC_EGENERIC;
- delete p_AudioMXFReader;
- goto error;
- }
+ EssenceType( p_sys->p_dcp->audio_reels[0].filename.c_str(), AudioEssType );
- p_AudioMXFReader->FillAudioDescriptor( AudioDesc );
+ if ( (AudioEssType == ESS_PCM_24b_48k) || (AudioEssType == ESS_PCM_24b_96k) ) {
+ PCM::AudioDescriptor AudioDesc;
- if ( (AudioDesc.ChannelCount >= sizeof(pi_channels_aout)/sizeof(uint32_t *))
- || (pi_channels_aout[AudioDesc.ChannelCount] == NULL) ){
- msg_Err(p_demux, " DCP module does not support %i channels",
- AudioDesc.ChannelCount);
- retval = VLC_EGENERIC;
- delete p_AudioMXFReader;
- goto error;
- } else {
- es_format_Init( &audio_format, AUDIO_ES, VLC_CODEC_S24L );
- if( AudioDesc.AudioSamplingRate.Denominator != 0 )
- audio_format.audio.i_rate =
- AudioDesc.AudioSamplingRate.Numerator
- / AudioDesc.AudioSamplingRate.Denominator;
- else if ( AudioEssType == ESS_PCM_24b_96k )
- audio_format.audio.i_rate = 96000;
- else
- audio_format.audio.i_rate = 48000;
+ for ( int i=0; i < ( p_sys->p_dcp->audio_reels.size() ); i++)
+ {
+ if ( i != 0 )
+ {
+ EssenceType( p_sys->p_dcp->audio_reels[i].filename.c_str(), AudioEssTypeCompare );
+ if ( AudioEssTypeCompare != AudioEssType )
+ {
+ msg_Err( p_demux, "Integrity check failed : different audio essence types",
+ p_sys->p_dcp->audio_reels[i].filename.c_str() );
+ retval = VLC_EGENERIC;
+ goto error;
+ }
+ }
+ PCM::MXFReader *p_AudioMXFReader = new ( nothrow ) PCM::MXFReader();
+
+ if( !p_AudioMXFReader ) {
+ retval = VLC_ENOMEM;
+ goto error;
+ }
- p_sys->i_audio_buffer = PCM::CalcFrameBufferSize(AudioDesc);
- if (p_sys->i_audio_buffer == 0) {
- msg_Err( p_demux, "Failed to get audio buffer size" );
+ if( !ASDCP_SUCCESS( p_AudioMXFReader->OpenRead( p_sys->p_dcp->audio_reels[i].filename.c_str() ) ) ) {
+ msg_Err( p_demux, "File %s could not be opened with ASDCP",
+ p_sys->p_dcp->audio_reels[i].filename.c_str() );
retval = VLC_EGENERIC;
delete p_AudioMXFReader;
goto error;
}
- audio_format.audio.i_bitspersample = AudioDesc.QuantizationBits;
- audio_format.audio.i_blockalign = AudioDesc.BlockAlign;
- audio_format.audio.i_channels =
- p_sys->i_channels = AudioDesc.ChannelCount;
+ p_AudioMXFReader->FillAudioDescriptor( AudioDesc );
- /* Manage channel orders */
- p_sys->i_chans_to_reorder = aout_CheckChannelReorder(
- pi_channels_aout[AudioDesc.ChannelCount], NULL,
- i_channel_mask[AudioDesc.ChannelCount], p_sys->pi_chan_table );
-
- if( ( p_sys->p_audio_es = es_out_Add( p_demux->out, &audio_format ) ) == NULL ) {
- msg_Err( p_demux, "Failed to add audio es" );
+ if ( (AudioDesc.ChannelCount >= sizeof(pi_channels_aout)/sizeof(uint32_t *))
+ || (pi_channels_aout[AudioDesc.ChannelCount] == NULL) )
+ {
+ msg_Err(p_demux, " DCP module does not support %i channels", AudioDesc.ChannelCount);
retval = VLC_EGENERIC;
delete p_AudioMXFReader;
goto error;
}
- p_sys->p_AudioMXFReader = p_AudioMXFReader;
+ audioReader_t audioReader;
+ audioReader.p_AudioMXFReader = p_AudioMXFReader;
+ p_sys->v_audioReader.push_back( audioReader );
+
+ }
+ es_format_Init( &audio_format, AUDIO_ES, VLC_CODEC_S24L );
+ if( AudioDesc.AudioSamplingRate.Denominator != 0 )
+ audio_format.audio.i_rate =
+ AudioDesc.AudioSamplingRate.Numerator
+ / AudioDesc.AudioSamplingRate.Denominator;
+ else if ( AudioEssType == ESS_PCM_24b_96k )
+ audio_format.audio.i_rate = 96000;
+ else
+ audio_format.audio.i_rate = 48000;
+
+ p_sys->i_audio_buffer = PCM::CalcFrameBufferSize( AudioDesc );
+ if (p_sys->i_audio_buffer == 0) {
+ msg_Err( p_demux, "Failed to get audio buffer size" );
+ retval = VLC_EGENERIC;
+ goto error;
+ }
+
+ audio_format.audio.i_bitspersample = AudioDesc.QuantizationBits;
+ audio_format.audio.i_blockalign = AudioDesc.BlockAlign;
+ audio_format.audio.i_channels =
+ p_sys->i_channels = AudioDesc.ChannelCount;
+
+ /* Manage channel orders */
+ p_sys->i_chans_to_reorder = aout_CheckChannelReorder(
+ pi_channels_aout[AudioDesc.ChannelCount], NULL,
+ i_channel_mask[AudioDesc.ChannelCount], p_sys->pi_chan_table );
+
+ if( ( p_sys->p_audio_es = es_out_Add( p_demux->out, &audio_format ) ) == NULL ) {
+ msg_Err( p_demux, "Failed to add audio es" );
+ retval = VLC_EGENERIC;
+ goto error;
}
} else {
msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container",
- p_sys->p_dcp->audiofile.c_str() );
+ p_sys->p_dcp->audio_reels[0].filename.c_str() );
retval = VLC_EGENERIC;
goto error;
}
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
+ p_sys->frame_no = p_sys->p_dcp->video_reels[0].i_entrypoint;
return VLC_SUCCESS;
error:
@@ -486,11 +597,34 @@ static int Demux( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_video_frame = NULL, *p_audio_frame = NULL;
- uint32_t i = p_sys->frame_no;
+
PCM::FrameBuffer AudioFrameBuff( p_sys->i_audio_buffer);
- if( i == p_sys->frames_total )
- return 0;
+ /* swaping video reels */
+ if ( p_sys->frame_no == p_sys->p_dcp->video_reels[p_sys->i_video_reel].i_absolute_end )
+ {
+ if ( p_sys->i_video_reel + 1 == p_sys->v_videoReader.size() )
+ {
+ return 0;
+ }
+ else
+ {
+ p_sys->i_video_reel++;
+ }
+ }
+
+ /* swaping audio reels */
+ if ( p_sys->frame_no == p_sys->p_dcp->audio_reels[p_sys->i_audio_reel].i_absolute_end )
+ {
+ if ( p_sys->i_audio_reel + 1 == p_sys->v_audioReader.size() )
+ {
+ return 0;//should never go there
+ }
+ else
+ {
+ p_sys->i_audio_reel++;
+ }
+ }
/* video frame */
switch( p_sys->PictureEssType )
@@ -498,6 +632,7 @@ static int Demux( demux_t *p_demux )
case ESS_JPEG_2000:
case ESS_JPEG_2000_S:{
JP2K::FrameBuffer PicFrameBuff(FRAME_BUFFER_SIZE);
+ int nextFrame = p_sys->frame_no + p_sys->p_dcp->video_reels[p_sys->i_video_reel].i_correction;
if ( ( p_video_frame = block_Alloc( FRAME_BUFFER_SIZE )) == NULL )
goto error;
@@ -506,13 +641,13 @@ static int Demux( demux_t *p_demux )
goto error_asdcp;
if ( p_sys->PictureEssType == ESS_JPEG_2000_S ) {
if ( ! ASDCP_SUCCESS(
- p_sys->p_PicMXFSReader->ReadFrame(i + p_sys->p_dcp->i_video_entry, JP2K::SP_LEFT, PicFrameBuff, 0, 0)) ) {
+ p_sys->v_videoReader[p_sys->i_video_reel].p_PicMXFSReader->ReadFrame(nextFrame, JP2K::SP_LEFT, PicFrameBuff, 0, 0)) ) {
PicFrameBuff.SetData(0,0);
goto error_asdcp;
}
} else {
if ( ! ASDCP_SUCCESS(
- p_sys->p_PicMXFReader->ReadFrame(i + p_sys->p_dcp->i_video_entry, PicFrameBuff, 0, 0)) ) {
+ p_sys->v_videoReader[p_sys->i_video_reel].p_PicMXFReader->ReadFrame(nextFrame, PicFrameBuff, 0, 0)) ) {
PicFrameBuff.SetData(0,0);
goto error_asdcp;
}
@@ -530,7 +665,7 @@ static int Demux( demux_t *p_demux )
goto error_asdcp;
if ( ! ASDCP_SUCCESS(
- p_sys->p_VideoMXFReader->ReadFrame(i + p_sys->p_dcp->i_video_entry, VideoFrameBuff, 0, 0)) ) {
+ 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, 0, 0)) ) {
VideoFrameBuff.SetData(0,0);
goto error_asdcp;
}
@@ -556,7 +691,7 @@ static int Demux( demux_t *p_demux )
}
if ( ! ASDCP_SUCCESS(
- p_sys->p_AudioMXFReader->ReadFrame(i + p_sys->p_dcp->i_audio_entry, AudioFrameBuff, 0, 0)) ) {
+ 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, 0, 0)) ) {
AudioFrameBuff.SetData(0,0);
goto error_asdcp;
}
@@ -686,6 +821,8 @@ static inline void fillVideoFmt( video_format_t * fmt, unsigned int width, unsig
* Function to free memory in case of error or when closing the module
* @param p_demux DCP access-demux
*/
+
+
void CloseDcpAndMxf( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
@@ -695,22 +832,35 @@ void CloseDcpAndMxf( demux_t *p_demux )
case ESS_UNKNOWN:
break;
case ESS_JPEG_2000:
- if( p_sys->p_PicMXFReader )
- p_sys->p_PicMXFReader->Close();
+ for ( int i = 0; i < p_sys->v_videoReader.size(); i++ )
+ {
+ if( p_sys->v_videoReader[i].p_PicMXFReader )
+ p_sys->v_videoReader[i].p_PicMXFReader->Close();
+ }
break;
case ESS_JPEG_2000_S:
- if( p_sys->p_PicMXFSReader )
- p_sys->p_PicMXFSReader->Close();
+ for ( int i = 0; i < p_sys->v_videoReader.size(); i++ )
+ {
+ if( p_sys->v_videoReader[i].p_PicMXFSReader )
+ p_sys->v_videoReader[i].p_PicMXFSReader->Close();
+ }
break;
case ESS_MPEG2_VES:
- if( p_sys->p_VideoMXFReader )
- p_sys->p_VideoMXFReader->Close();
+ for ( int i = 0; i < p_sys->v_videoReader.size(); i++ )
+ {
+ if( p_sys->v_videoReader[i].p_VideoMXFReader )
+ p_sys->v_videoReader[i].p_VideoMXFReader->Close();
+ }
break;
default:
break;
}
- if( p_sys->p_AudioMXFReader )
- p_sys->p_AudioMXFReader->Close();
+
+ for ( int i = 0; i < p_sys->v_audioReader.size(); i++ )
+ {
+ if( p_sys->v_audioReader[i].p_AudioMXFReader )
+ p_sys->v_audioReader[i].p_AudioMXFReader->Close();
+ }
delete( p_demux->p_sys );
}
@@ -744,12 +894,6 @@ int dcpInit ( demux_t *p_demux )
msg_Dbg(p_demux, "parsing XML files done");
-#ifndef NDEBUG
- msg_Dbg( p_demux, "path = %s", p_sys->p_dcp->path.c_str() );
- msg_Dbg( p_demux, "video = %s", p_sys->p_dcp->videofile.c_str() );
- msg_Dbg( p_demux, "audio = %s", p_sys->p_dcp->audiofile.c_str() );
-#endif
-
return VLC_SUCCESS;
}
diff --git a/modules/access/dcp/dcpparser.cpp b/modules/access/dcp/dcpparser.cpp
index 4dc1cda..a0e24da 100644
--- a/modules/access/dcp/dcpparser.cpp
+++ b/modules/access/dcp/dcpparser.cpp
@@ -225,6 +225,10 @@ AssetMap::~AssetMap() { }
int AssetMap::Parse ( )
{
int type = 0;
+ int reel_nbr = 0;
+ int index = 0;
+ int sum_duration_vid = 0;
+ int sum_duration_aud = 0;
string node;
CPL *cpl;
@@ -327,23 +331,53 @@ int AssetMap::Parse ( )
this->CloseXml();
return -1;
}
- /*TODO : case of 1st reel only managed */
- reel = cpl->getReel(0);
-
- Asset *asset;
- /* Get picture */
- asset = reel->getTrack(TRACK_PICTURE);
- msg_Dbg( this->p_demux, "Video Track: %s",asset->getPath().c_str());
- msg_Dbg( this->p_demux, "Entry point: %i",asset->getEntryPoint());
- p_dcp->videofile = p_dcp->path + asset->getPath();
- p_dcp->i_video_entry = asset->getEntryPoint();
- /* Get audio */
- asset = reel->getTrack(TRACK_SOUND);
- msg_Dbg( this->p_demux, "Audio Track: %s",asset->getPath().c_str());
- msg_Dbg( this->p_demux, "Entry point: %i",asset->getEntryPoint());
- p_dcp->audiofile = p_dcp->path + asset->getPath();
- p_dcp->i_audio_entry = asset->getEntryPoint();
+ reel_nbr = cpl->getReelList().size();
+ for(index = 0; index != reel_nbr; ++index)
+ {
+ reel = cpl->getReel(index);
+
+ Asset *asset;
+ struct info_reel video;
+ struct info_reel audio;
+
+ /* Get picture */
+ asset = reel->getTrack(TRACK_PICTURE);
+ if (asset != NULL)
+ {
+ sum_duration_vid += asset->getDuration();
+ video.filename = p_dcp->path + asset->getPath();
+ video.i_entrypoint = asset->getEntryPoint();
+ video.i_duration = asset->getDuration();
+ video.i_correction = video.i_entrypoint - sum_duration_vid + video.i_duration;
+ video.i_absolute_end = sum_duration_vid;
+ p_dcp->video_reels.push_back(video);
+ msg_Dbg( this->p_demux, "Video Track: %s",asset->getPath().c_str());
+ msg_Dbg( this->p_demux, "Entry point: %i",asset->getEntryPoint());
+ }
+ /* Get audio */
+ asset = reel->getTrack(TRACK_SOUND);
+ if (asset != NULL)
+ {
+ /*if (!p_dcp->audio_reels.empty())
+ {
+ sum_duration_aud = 0;
+ for (int i = 0; i != p_dcp->audio_reels.size(); ++i)
+ {
+ sum_duration_aud += p_dcp->audio_reels(i).i_duration;
+ }
+ }*/
+ sum_duration_aud += asset->getDuration();
+ audio.filename = p_dcp->path + asset->getPath();
+ audio.i_entrypoint = asset->getEntryPoint();
+ audio.i_duration = asset->getDuration();
+ audio.i_correction = audio.i_entrypoint - sum_duration_aud + audio.i_duration;
+ audio.i_absolute_end = sum_duration_aud;
+ p_dcp->audio_reels.push_back(audio);
+ msg_Dbg( this->p_demux, "Audio Track: %s",asset->getPath().c_str());
+ msg_Dbg( this->p_demux, "Entry point: %i",asset->getEntryPoint());
+ }
+ }
/* free memory */
this->CloseXml();
return VLC_SUCCESS;
diff --git a/modules/access/dcp/dcpparser.h b/modules/access/dcp/dcpparser.h
index e3a6a6a..e7f19cb 100644
--- a/modules/access/dcp/dcpparser.h
+++ b/modules/access/dcp/dcpparser.h
@@ -63,6 +63,17 @@ class Asset;
class AssetList: public std::list<Asset *> {};
class PKL;
+
+/* This struct stores useful information about an MXF for demux() */
+struct info_reel
+{
+ string filename;
+ int i_entrypoint;
+ int i_duration;
+ int i_correction; /* entrypoint - sum of previous durations */
+ int i_absolute_end; /* correction + duration */
+};
+
/* This struct stores the most important information about the DCP */
struct dcp_t
{
@@ -71,16 +82,11 @@ struct dcp_t
vector<PKL *> pkls;
AssetList *p_asset_list;
- string videofile; /* Picture file name */
- string audiofile; /* Sound file name */
-
- int i_video_entry; /* Picture entry point */
- int i_audio_entry; /* Sound entry point */
+ vector<info_reel> audio_reels;
+ vector<info_reel> video_reels;
dcp_t():
- p_asset_list(NULL),
- i_video_entry(0),
- i_audio_entry(0) {};
+ p_asset_list(NULL) {};
~dcp_t( ) {
vlc_delete_all(pkls);
@@ -160,6 +166,7 @@ public:
string getId() const { return this->s_id; } ;
string getPath() const { return this->s_path; };
string getType() const { return this->s_type; };
+ string getOriginalFilename() const { return this->s_original_filename; };
int getEntryPoint() const { return this->i_entry_point; };
int getDuration() const { return this->i_duration; };
int getIntrinsicDuration() const { return this->i_intrisic_duration; };
@@ -236,6 +243,7 @@ public:
virtual int Parse();
Reel *getReel(int pos) { return this->vec_reel[pos]; } ;
+ std::vector<Reel *> getReelList() { return this->vec_reel; } ;
private :
AssetList *asset_list;
--
1.7.9.5
More information about the vlc-devel
mailing list