Commit 0c01d856 authored by Valentin Vetter's avatar Valentin Vetter Committed by Jean-Baptiste Kempf

DCP: Read multiple reels

Allow to read more than one reel
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 366a9aa8
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
/* ASDCP headers */ /* ASDCP headers */
#include <AS_DCP.h> #include <AS_DCP.h>
#include <vector>
#include "dcpparser.h" #include "dcpparser.h"
using namespace ASDCP; using namespace ASDCP;
...@@ -79,6 +81,23 @@ typedef enum MxfMedia_t { ...@@ -79,6 +81,23 @@ typedef enum MxfMedia_t {
MXF_AUDIO, MXF_AUDIO,
} MxfMedia_t; } 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: /* 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_UNKNOWN, // the file is not a supported AS-DCP essence container
ESS_MPEG2_VES, // the file contains an MPEG video elementary stream ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
...@@ -98,20 +117,10 @@ class demux_sys_t ...@@ -98,20 +117,10 @@ class demux_sys_t
EssenceType_t PictureEssType; EssenceType_t PictureEssType;
/* ASDCP Video MXF Reader */ /* ASDCP Video MXF Reader */
union vector<videoReader_t> v_videoReader;
{
/* JPEG2000 essence type */
JP2K::MXFReader *p_PicMXFReader;
/* JPEG2000 stereoscopic essence type */
JP2K::MXFSReader *p_PicMXFSReader;
/* MPEG2 essence type */
MPEG2::MXFReader *p_VideoMXFReader;
};
/* ASDCP Audio MXF Reader */ /* ASDCP Audio MXF Reader */
PCM::MXFReader *p_AudioMXFReader; vector<audioReader_t> v_audioReader;
/* audio buffer size */ /* audio buffer size */
uint32_t i_audio_buffer; uint32_t i_audio_buffer;
...@@ -123,7 +132,7 @@ class demux_sys_t ...@@ -123,7 +132,7 @@ class demux_sys_t
/* DCP object */ /* DCP object */
dcp_t *p_dcp; dcp_t *p_dcp;
/* current frame number */ /* current absolute frame number */
uint32_t frame_no; uint32_t frame_no;
/* frame rate */ /* frame rate */
...@@ -133,6 +142,12 @@ class demux_sys_t ...@@ -133,6 +142,12 @@ class demux_sys_t
/* total number of frames */ /* total number of frames */
uint32_t frames_total; 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 i_chans_to_reorder; /* do we need channel reordering */
uint8_t pi_chan_table[AOUT_CHAN_MAX]; uint8_t pi_chan_table[AOUT_CHAN_MAX];
uint8_t i_channels; uint8_t i_channels;
...@@ -141,12 +156,15 @@ class demux_sys_t ...@@ -141,12 +156,15 @@ class demux_sys_t
demux_sys_t(): demux_sys_t():
PictureEssType ( ESS_UNKNOWN ), PictureEssType ( ESS_UNKNOWN ),
p_PicMXFReader( NULL ), v_videoReader( NULL ),
p_AudioMXFReader( NULL ), v_audioReader( NULL ),
p_video_es( NULL ), p_video_es( NULL ),
p_audio_es( NULL ), p_audio_es( NULL ),
p_dcp( NULL ), p_dcp( NULL ),
frame_no( 0 ) {}; frame_no( 0 ),
frames_total( 0 ),
i_video_reel( 0 ),
i_audio_reel( 0 ) {};
~demux_sys_t() ~demux_sys_t()
{ {
...@@ -155,18 +173,32 @@ class demux_sys_t ...@@ -155,18 +173,32 @@ class demux_sys_t
case ESS_UNKNOWN: case ESS_UNKNOWN:
break; break;
case ESS_JPEG_2000: case ESS_JPEG_2000:
delete p_PicMXFReader; for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
{
delete v_videoReader[i].p_PicMXFReader;
}
break; break;
case ESS_JPEG_2000_S: 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; break;
case ESS_MPEG2_VES: case ESS_MPEG2_VES:
delete p_VideoMXFReader; for ( unsigned int i = 0; i < v_videoReader.size(); i++ )
{
delete v_videoReader[i].p_VideoMXFReader;
}
break; break;
default: default:
break; break;
} }
delete p_AudioMXFReader;
for ( unsigned int i = 0; i < v_audioReader.size(); i++ )
{
delete v_audioReader[i].p_AudioMXFReader;
}
delete p_dcp; delete p_dcp;
} }
}; };
...@@ -284,93 +316,146 @@ static int Open( vlc_object_t *obj ) ...@@ -284,93 +316,146 @@ static int Open( vlc_object_t *obj )
if( ( retval = dcpInit( p_demux ) ) ) if( ( retval = dcpInit( p_demux ) ) )
goto error; goto error;
/* Open video file */ /* Open video file */
EssenceType( p_sys->p_dcp->videofile.c_str(), p_sys->PictureEssType ); EssenceType_t essInter;
for ( int i = 0; i < ( p_sys->p_dcp->video_reels.size() ); i++ )
switch( p_sys->PictureEssType )
{ {
case ESS_UNKNOWN: EssenceType( p_sys->p_dcp->video_reels[i].filename.c_str(), essInter );
msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container", p_sys->p_dcp->videofile.c_str() ); if ( i == 0 )
retval = VLC_EGENERIC; {
goto error; 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: switch( essInter )
case ESS_JPEG_2000_S: { {
JP2K::PictureDescriptor PicDesc; case ESS_UNKNOWN:
if (p_sys->PictureEssType == ESS_JPEG_2000_S) { /* 3D JPEG2000 */ 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() );
JP2K::MXFSReader * p_PicMXFSReader = new ( nothrow ) JP2K::MXFSReader(); retval = VLC_EGENERIC;
goto error;
if( !p_PicMXFSReader) { case ESS_JPEG_2000:
retval = VLC_ENOMEM; case ESS_JPEG_2000_S: {
goto error; 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() ) ) ) { es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_JPEG2000 );
msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->videofile.c_str() ); fillVideoFmt( &video_format.video, PicDesc.StoredWidth, PicDesc.StoredHeight,
retval = VLC_EGENERIC; PicDesc.EditRate.Numerator, PicDesc.EditRate.Denominator );
delete p_PicMXFSReader;
goto error;
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 ); MPEG2::MXFReader *p_VideoMXFReader = new ( nothrow ) MPEG2::MXFReader();
p_sys->p_PicMXFSReader = p_PicMXFSReader;
} else { /* 2D JPEG2000 */ videoReader_t videoReader;
JP2K::MXFReader *p_PicMXFReader = new ( nothrow ) JP2K::MXFReader(); videoReader.p_VideoMXFReader = p_VideoMXFReader;
if( !p_PicMXFReader ) { p_sys->v_videoReader.push_back(videoReader);
MPEG2::VideoDescriptor VideoDesc;
if( !p_VideoMXFReader ) {
retval = VLC_ENOMEM; retval = VLC_ENOMEM;
goto error; 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", if( !ASDCP_SUCCESS( p_VideoMXFReader->OpenRead( p_sys->p_dcp->video_reels[i].filename.c_str() ) ) ) {
p_sys->p_dcp->videofile.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; retval = VLC_EGENERIC;
delete p_PicMXFReader;
goto error; goto error;
} }
p_PicMXFReader->FillPictureDescriptor( PicDesc ); p_VideoMXFReader->FillVideoDescriptor( VideoDesc );
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_sys->frame_rate_num = PicDesc.EditRate.Numerator; es_format_Init( &video_format, VIDEO_ES, VLC_CODEC_MPGV );
p_sys->frame_rate_denom = PicDesc.EditRate.Denominator; fillVideoFmt( &video_format.video, VideoDesc.StoredWidth, VideoDesc.StoredHeight,
p_sys->frames_total = PicDesc.ContainerDuration; VideoDesc.EditRate.Numerator, VideoDesc.EditRate.Denominator );
break;
}
case ESS_MPEG2_VES: {
MPEG2::MXFReader *p_VideoMXFReader = p_sys->p_VideoMXFReader = new ( nothrow ) MPEG2::MXFReader();
MPEG2::VideoDescriptor VideoDesc;
if( !p_VideoMXFReader ) { if ( i > 0 ) {
retval = VLC_ENOMEM; if ( p_sys->frame_rate_num != VideoDesc.EditRate.Numerator ||
goto error; 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() ) ) ) { p_sys->frames_total += p_sys->p_dcp->video_reels[i].i_duration;
msg_Err( p_demux, "File %s could not be opened with ASDCP", p_sys->p_dcp->videofile.c_str() ); break;
}
default:
msg_Err( p_demux, "Unrecognized video format" );
retval = VLC_EGENERIC; retval = VLC_EGENERIC;
goto error; 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) ) { if ( (p_sys->frame_rate_num == 0) || (p_sys->frame_rate_denom == 0) ) {
...@@ -388,78 +473,104 @@ static int Open( vlc_object_t *obj ) ...@@ -388,78 +473,104 @@ static int Open( vlc_object_t *obj )
/* Open audio file */ /* Open audio file */
EssenceType_t AudioEssType; EssenceType_t AudioEssType;
EssenceType( p_sys->p_dcp->audiofile.c_str(), AudioEssType ); EssenceType_t AudioEssTypeCompare;
if ( (AudioEssType == ESS_PCM_24b_48k) || (AudioEssType == ESS_PCM_24b_96k) ) {
PCM::MXFReader *p_AudioMXFReader = new ( nothrow ) PCM::MXFReader();
PCM::AudioDescriptor AudioDesc;
if( !p_AudioMXFReader ) { if( p_sys->p_dcp->audio_reels.size() == 0 )
retval = VLC_ENOMEM; {
goto error; 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() ) ) ) { EssenceType( p_sys->p_dcp->audio_reels[0].filename.c_str(), AudioEssType );
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;
}
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 *)) for ( int i=0; i < ( p_sys->p_dcp->audio_reels.size() ); i++)
|| (pi_channels_aout[AudioDesc.ChannelCount] == NULL) ){ {
msg_Err(p_demux, " DCP module does not support %i channels", if ( i != 0 )
AudioDesc.ChannelCount); {
retval = VLC_EGENERIC; EssenceType( p_sys->p_dcp->audio_reels[i].filename.c_str(), AudioEssTypeCompare );
delete p_AudioMXFReader; if ( AudioEssTypeCompare != AudioEssType )
goto error; {
} else { msg_Err( p_demux, "Integrity check failed : different audio essence types",
es_format_Init( &audio_format, AUDIO_ES, VLC_CODEC_S24L ); p_sys->p_dcp->audio_reels[i].filename.c_str() );
if( AudioDesc.AudioSamplingRate.Denominator != 0 ) retval = VLC_EGENERIC;
audio_format.audio.i_rate = goto error;
AudioDesc.AudioSamplingRate.Numerator }
/ AudioDesc.AudioSamplingRate.Denominator; }
else if ( AudioEssType == ESS_PCM_24b_96k ) PCM::MXFReader *p_AudioMXFReader = new ( nothrow ) PCM::MXFReader();
audio_format.audio.i_rate = 96000;
else if( !p_AudioMXFReader ) {
audio_format.audio.i_rate = 48000; retval = VLC_ENOMEM;
goto error;
}
p_sys->i_audio_buffer = PCM::CalcFrameBufferSize(AudioDesc); if( !ASDCP_SUCCESS( p_AudioMXFReader->OpenRead( p_sys->p_dcp->audio_reels[i].filename.c_str() ) ) ) {
if (p_sys->i_audio_buffer == 0) { msg_Err( p_demux, "File %s could not be opened with ASDCP",
msg_Err( p_demux, "Failed to get audio buffer size" ); p_sys->p_dcp->audio_reels[i].filename.c_str() );
retval = VLC_EGENERIC; retval = VLC_EGENERIC;
delete p_AudioMXFReader; delete p_AudioMXFReader;
goto error; goto error;
} }
audio_format.audio.i_bitspersample = AudioDesc.QuantizationBits; p_AudioMXFReader->FillAudioDescriptor( AudioDesc );
audio_format.audio.i_blockalign = AudioDesc.BlockAlign;
audio_format.audio.i_channels =
p_sys->i_channels = AudioDesc.ChannelCount;
/* Manage channel orders */ if ( (AudioDesc.ChannelCount >= sizeof(pi_channels_aout)/sizeof(uint32_t *))
p_sys->i_chans_to_reorder = aout_CheckChannelReorder( || (pi_channels_aout[AudioDesc.ChannelCount] == NULL) )
pi_channels_aout[AudioDesc.ChannelCount], NULL, {
i_channel_mask[AudioDesc.ChannelCount], p_sys->pi_chan_table ); msg_Err(p_demux, " DCP module does not support %i channels", AudioDesc.ChannelCount);
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; retval = VLC_EGENERIC;
delete p_AudioMXFReader; delete p_AudioMXFReader;
goto error; 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 { } else {
msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container", 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; retval = VLC_EGENERIC;
goto error; goto error;
} }
p_demux->pf_demux = Demux; p_demux->pf_demux = Demux;
p_demux->pf_control = Control; p_demux->pf_control = Control;
p_sys->frame_no = p_sys->p_dcp->video_reels[0].i_entrypoint;
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
...@@ -486,11 +597,34 @@ static int Demux( demux_t *p_demux ) ...@@ -486,11 +597,34 @@ static int Demux( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_video_frame = NULL, *p_audio_frame = NULL; 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); PCM::FrameBuffer AudioFrameBuff( p_sys->i_audio_buffer);
if( i == p_sys->frames_total ) /* swaping video reels */
return 0; 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 */ /* video frame */
switch( p_sys->PictureEssType ) switch( p_sys->PictureEssType )
...@@ -498,6 +632,7 @@ static int Demux( demux_t *p_demux ) ...@@ -498,6 +632,7 @@ static int Demux( demux_t *p_demux )
case ESS_JPEG_2000: case ESS_JPEG_2000:
case ESS_JPEG_2000_S:{ case ESS_JPEG_2000_S:{
JP2K::FrameBuffer PicFrameBuff(FRAME_BUFFER_SIZE); 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 ) if ( ( p_video_frame = block_Alloc( FRAME_BUFFER_SIZE )) == NULL )
goto error; goto error;
...@@ -506,13 +641,13 @@ static int Demux( demux_t *p_demux ) ...@@ -506,13 +641,13 @@ static int Demux( demux_t *p_demux )
goto error_asdcp; goto error_asdcp;
if ( p_sys->PictureEssType == ESS_JPEG_2000_S ) { if ( p_sys->PictureEssType == ESS_JPEG_2000_S ) {
if ( ! ASDCP_SUCCESS( 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); PicFrameBuff.SetData(0,0);
goto error_asdcp; goto error_asdcp;
} }
} else { } else {
if ( ! ASDCP_SUCCESS( 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); PicFrameBuff.SetData(0,0);
goto error_asdcp; goto error_asdcp;
} }
...@@ -530,7 +665,7 @@ static int Demux( demux_t *p_demux ) ...@@ -530,7 +665,7 @@ static int Demux( demux_t *p_demux )
goto error_asdcp; goto error_asdcp;
if ( ! ASDCP_SUCCESS( 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); VideoFrameBuff.SetData(0,0);
goto error_asdcp; goto error_asdcp;
} }
...@@ -556,7 +691,7 @@ static int Demux( demux_t *p_demux ) ...@@ -556,7 +691,7 @@ static int Demux( demux_t *p_demux )
} }
if ( ! ASDCP_SUCCESS( 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); AudioFrameBuff.SetData(0,0);
goto error_asdcp; goto error_asdcp;
} }
...@@ -686,6 +821,8 @@ static inline void fillVideoFmt( video_format_t * fmt, unsigned int width, unsig ...@@ -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 * Function to free memory in case of error or when closing the module
* @param p_demux DCP access-demux * @param p_demux DCP access-demux
*/ */
void CloseDcpAndMxf( demux_t *p_demux ) void CloseDcpAndMxf( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
...@@ -695,22 +832,35 @@ void CloseDcpAndMxf( demux_t *p_demux ) ...@@ -695,22 +832,35 @@ void CloseDcpAndMxf( demux_t *p_demux )
case ESS_UNKNOWN: case ESS_UNKNOWN:
break; break;
case ESS_JPEG_2000: case ESS_JPEG_2000:
if( p_sys->p_PicMXFReader ) for ( int i = 0; i < p_sys->v_videoReader.size(); i++ )
p_sys->p_PicMXFReader->Close(); {
if( p_sys->v_videoReader[i].p_PicMXFReader )
p_sys->v_videoReader[i].p_PicMXFReader->Close();
}
break; break;
case ESS_JPEG_2000_S: case ESS_JPEG_2000_S:
if( p_sys->p_PicMXFSReader ) for ( int i = 0; i < p_sys->v_videoReader.size(); i++ )
p_sys->p_PicMXFSReader->Close(); {
if( p_sys->v_videoReader[i].p_PicMXFSReader )
p_sys->v_videoReader[i].p_PicMXFSReader->Close();
}
break; break;
case ESS_MPEG2_VES: case ESS_MPEG2_VES:
if( p_sys->p_VideoMXFReader ) for ( int i = 0; i < p_sys->v_videoReader.size(); i++ )
p_sys->p_VideoMXFReader->Close(); {
if( p_sys->v_videoReader[i].p_VideoMXFReader )
p_sys->v_videoReader[i].p_VideoMXFReader->Close();
}
break; break;
default: default:
break; 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 ); delete( p_demux->p_sys );
} }
...@@ -744,12 +894,6 @@ int dcpInit ( demux_t *p_demux ) ...@@ -744,12 +894,6 @@ int dcpInit ( demux_t *p_demux )
msg_Dbg(p_demux, "parsing XML files done"); 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; return VLC_SUCCESS;
} }
......
...@@ -225,6 +225,10 @@ AssetMap::~AssetMap() { } ...@@ -225,6 +225,10 @@ AssetMap::~AssetMap() { }
int AssetMap::Parse ( ) int AssetMap::Parse ( )
{ {
int type = 0; int type = 0;
int reel_nbr = 0;
int index = 0;
int sum_duration_vid = 0;
int sum_duration_aud = 0;
string node; string node;
CPL *cpl; CPL *cpl;
...@@ -327,23 +331,53 @@ int AssetMap::Parse ( ) ...@@ -327,23 +331,53 @@ int AssetMap::Parse ( )
this->CloseXml(); this->CloseXml();
return -1; 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 */ /* free memory */
this->CloseXml(); this->CloseXml();
return VLC_SUCCESS; return VLC_SUCCESS;
......
...@@ -63,6 +63,17 @@ class Asset; ...@@ -63,6 +63,17 @@ class Asset;
class AssetList: public std::list<Asset *> {}; class AssetList: public std::list<Asset *> {};
class PKL; 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 */ /* This struct stores the most important information about the DCP */
struct dcp_t struct dcp_t
{ {
...@@ -71,16 +82,11 @@ struct dcp_t ...@@ -71,16 +82,11 @@ struct dcp_t
vector<PKL *> pkls; vector<PKL *> pkls;
AssetList *p_asset_list; AssetList *p_asset_list;
string videofile; /* Picture file name */ vector<info_reel> audio_reels;
string audiofile; /* Sound file name */ vector<info_reel> video_reels;
int i_video_entry; /* Picture entry point */
int i_audio_entry; /* Sound entry point */
dcp_t(): dcp_t():
p_asset_list(NULL), p_asset_list(NULL) {};
i_video_entry(0),
i_audio_entry(0) {};
~dcp_t( ) { ~dcp_t( ) {
vlc_delete_all(pkls); vlc_delete_all(pkls);
...@@ -160,6 +166,7 @@ public: ...@@ -160,6 +166,7 @@ public:
string getId() const { return this->s_id; } ; string getId() const { return this->s_id; } ;
string getPath() const { return this->s_path; }; string getPath() const { return this->s_path; };
string getType() const { return this->s_type; }; string getType() const { return this->s_type; };
string getOriginalFilename() const { return this->s_original_filename; };
int getEntryPoint() const { return this->i_entry_point; }; int getEntryPoint() const { return this->i_entry_point; };
int getDuration() const { return this->i_duration; }; int getDuration() const { return this->i_duration; };
int getIntrinsicDuration() const { return this->i_intrisic_duration; }; int getIntrinsicDuration() const { return this->i_intrisic_duration; };
...@@ -236,6 +243,7 @@ public: ...@@ -236,6 +243,7 @@ public:
virtual int Parse(); virtual int Parse();
Reel *getReel(int pos) { return this->vec_reel[pos]; } ; Reel *getReel(int pos) { return this->vec_reel[pos]; } ;
std::vector<Reel *> getReelList() { return this->vec_reel; } ;
private : private :
AssetList *asset_list; AssetList *asset_list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment