[vlc-devel] [PATCH] DCP: allow to read subtitles

Denis Charmet typx at dinauz.org
Mon Mar 3 18:13:42 CET 2014


Hi,

Le samedi 01 mars 2014 à 05:20:12, Valentin Vetter a écrit :
> +typedef struct
> +{
> +    int64_t i_start;
> +    int64_t i_stop;
> +
> +    char    *psz_text;
> +} subtitle_t;
why not use block_t?
> +
> +typedef struct
> +{
> +    xml_t        *xml;
> +    xml_reader_t *xml_reader;
> +    int          count;
> +} sub_xml_t;
> +
> +struct demux_sub_sys_t
> +{
> +    int         i_type;
> +    sub_xml_t   sub_xml;
> +    es_out_id_t *es;
> +
> +    int64_t     i_next_demux_date;
> +    int64_t     i_microsecperframe;
> +
> +    char        *psz_header;
> +    int         i_subtitle;
> +    int         i_subtitles;
> +    subtitle_t  *subtitle;
I assume those will be allocated shouldn't you have a destructor?
> +
> +    int64_t     i_length;
> +
> +    struct
> +    {
> +        bool b_inited;
> +
> +        int i_comment;
> +        int i_time_resolution;
> +        int i_time_shift;
> +    } jss;
> +    struct
> +    {
> +        bool  b_inited;
> +
> +        float f_total;
> +        float f_factor;
> +    } mpsub;
> +};
> +
>  class demux_sys_t
>  {
>   public:
> @@ -127,12 +182,20 @@ class demux_sys_t
>      /* ASDCP Audio MXF Reader */
>      vector<audioReader_t> v_audioReader;
>  
> +    /* Subtitles information */
> +    vector<demux_sub_sys_t*> v_sub_sys;
> +
>      /* audio buffer size */
>      uint32_t i_audio_buffer;
>  
>      /* elementary streams */
>      es_out_id_t *p_video_es;
>      es_out_id_t *p_audio_es;
> +    es_out_id_t *p_sub_es;
isn't that somehow redundant with es inside demux_sub_sys_t?
> +
> +    /* subtitle parser */
> +    stream_t    *p_subtitle_parser;
> +    stream_t    *p_subtitle_stream;
>  
>      /* DCP object */
>      dcp_t *p_dcp;
> @@ -153,6 +216,9 @@ class demux_sys_t
>      /* current audio reel */
>      unsigned int i_audio_reel;
>  
> +    /* current subtitle reel */
> +    unsigned int i_sub_reel;
> +
>      uint8_t i_chans_to_reorder;            /* do we need channel reordering */
>      uint8_t pi_chan_table[AOUT_CHAN_MAX];
>      uint8_t i_channels;
> @@ -163,13 +229,16 @@ class demux_sys_t
>          PictureEssType ( ESS_UNKNOWN ),
>          v_videoReader(),
>          v_audioReader(),
> +        v_sub_sys(),
>          p_video_es( NULL ),
>          p_audio_es( NULL ),
> +        p_sub_es( NULL ),
>          p_dcp( NULL ),
>          frame_no( 0 ),
>          frames_total( 0 ),
>          i_video_reel( 0 ),
> -        i_audio_reel( 0 ) {};
> +        i_audio_reel( 0 ),
> +        i_sub_reel( 0 ) {};
>  
>      ~demux_sys_t()
>      {
> @@ -281,6 +350,9 @@ static int Demux( demux_t * );
>  static int Control( demux_t *, int, va_list );
>  
>  int dcpInit ( demux_t *p_demux );
> +int OpenSubtitle( demux_t *p_demux, const char *filePath, int );
> +int SubtitleDemux( demux_t *, int );
> +static int ParseDCSubtitle ( demux_t *, subtitle_t *, int, int );
>  int parseXML ( demux_t * p_demux );
>  static inline void fillVideoFmt(
>          video_format_t * fmt, unsigned int width, unsigned int height,
> @@ -411,7 +483,6 @@ static int Open( vlc_object_t *obj )
>                  break;
>              }
>              case ESS_MPEG2_VES: {
> -
>                  MPEG2::MXFReader *p_VideoMXFReader = new ( nothrow ) MPEG2::MXFReader();
>  
>                  videoReader_t videoReader;
> @@ -533,7 +604,6 @@ static int Open( vlc_object_t *obj )
>              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 )
> @@ -573,9 +643,33 @@ static int Open( vlc_object_t *obj )
>          retval = VLC_EGENERIC;
>          goto error;
>      }
> +
> +    /* Open subtitle file */
> +    if( p_sys->p_dcp->sub_reels.size() > 0 )
> +    {
> +        for ( uint8_t i = 0; i < ( p_sys->p_dcp->sub_reels.size() ); i++)
> +        {
> +        if ( retval = OpenSubtitle( p_demux, p_sys->p_dcp->sub_reels[i].filename.c_str(), i ) )
> +            return retval;
leak
> +        }
> +    }
> +
> +    es_format_t fmt;
> +    es_format_Init( &fmt, SPU_ES, VLC_CODEC_SUBT );
> +    fmt.subs.psz_encoding = strdup( "UTF-8" );
> +
> +    if( ( p_demux->p_sys->p_sub_es = es_out_Add( p_demux->out, &fmt ) ) == NULL )
> +    {
> +        msg_Err( p_demux, "Failed to add subtitle es" );
If you don't use a program in the format, the only reason for it to fail
is a lack of memory so avoid traces.

> +        free( p_sys );
> +        return VLC_EGENERIC;
> +    }
> +
> +    es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, p_demux->p_sys->p_sub_es );
> +    es_format_Clean( &fmt );
I think that you can just free(fmt.subs.psz_encoding) instead of that.
> +
>      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:
> @@ -631,6 +725,21 @@ static int Demux( demux_t *p_demux )
>           }
>       }
>  
> +    /* swaping subtitle reels */
> +    if  ( p_sys->frame_no == p_sys->p_dcp->sub_reels[p_sys->i_sub_reel].i_absolute_end )
> +    {
> +        if ( p_sys->i_sub_reel + 1 == p_sys->p_dcp->sub_reels.size() )
> +        {
> +            return 0;
This will cause an end of file, do you really want that?
> +        }
> +        else
> +        {
> +            p_sys->i_sub_reel++;
> +            es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, p_demux->p_sys->p_sub_es );
> +        }
> +     }
> +
> +
>      /* video frame */
>      switch( p_sys->PictureEssType )
>      {
> @@ -719,6 +828,9 @@ static int Demux( demux_t *p_demux )
>      es_out_Send( p_demux->out, p_sys->p_video_es, p_video_frame );
>      es_out_Send( p_demux->out, p_sys->p_audio_es, p_audio_frame );
>  
> +    if ( p_sys->v_sub_sys[p_sys->i_sub_reel] )
> +        SubtitleDemux( p_demux, p_sys->i_sub_reel );
> +
>      p_sys->frame_no++;
>  
>      return 1;
> @@ -743,6 +855,9 @@ static int Control( demux_t *p_demux, int query, va_list args )
>      int64_t *pi64, i64;
>      demux_sys_t *p_sys = p_demux->p_sys;
>  
> +    int i_reel = 0;
> +    bool b_correct_reel = false;
> +
Why declare it if you don't use it?
>      switch ( query )
>      {
>          case DEMUX_CAN_PAUSE:
> @@ -970,3 +1085,241 @@ int parseXML ( demux_t * p_demux )
>      delete assetmap;
>      return VLC_SUCCESS; /* TODO : perform checking on XML parsing */
>  }
> +
> +
> +/*****************************************************************************
> + * functions for subtitles
> + *****************************************************************************/
> +
> +static int XmlLoad( demux_t * p_demux, stream_t *s, int sub_nb )
> +{
> +    demux_sub_sys_t *p_sys = p_demux->p_sys->v_sub_sys[sub_nb];
> +    sub_xml_t *p_sub_xml = &p_sys->sub_xml;
> +    xml_t *p_xml;
> +    xml_reader_t *p_xml_reader;
> +
> +    /* Create XML parser */
> +    p_xml = xml_Create( p_demux );
> +    if( ! p_xml )
> +        return VLC_EGENERIC;
> +
> +    /* Initialize XML reader */
> +    p_xml_reader = xml_ReaderCreate( p_xml, s );
> +    if( ! p_xml_reader )
> +        return VLC_EGENERIC;
leak p_xml
> +    p_sub_xml->xml = p_xml;
> +    p_sub_xml->xml_reader = p_xml_reader;
> +    return VLC_SUCCESS;
> +
> +}
> +
> +static void XmlUnLoad ( demux_t *p_demux, int sub_nb )
> +{
> +    demux_sub_sys_t *p_sys = p_demux->p_sys->v_sub_sys[sub_nb];
> +    sub_xml_t *p_sub_xml = &p_sys->sub_xml;
> +    xml_ReaderDelete( p_sub_xml->xml_reader );
> +    xml_Delete( p_sub_xml->xml );
> +
> +}
> +
> +static int  ParseDCSubtitle( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx, int sub_nb )
> +{
> +    demux_sub_sys_t *p_sys = p_demux->p_sys->v_sub_sys[sub_nb];
> +    sub_xml_t *p_sub_xml = &p_sys->sub_xml;
> +    xml_reader_t * p_xml_reader = p_sub_xml->xml_reader;
> +    const char *node = NULL;
> +    int type = 0;
> +    bool b_subtitle_tag = false;
> +    bool b_quit = false;
> +    char *psz_text = NULL;
> +    int i_len = 0;
> +    while( ( b_quit == false ) && ( type = xml_ReaderNextNode( p_xml_reader, &node ) ) > 0 )
> +    {
> +        switch (type)
> +        {
> +            case XML_READER_STARTELEM:
> +                if( strcmp( node, "Subtitle" ) == 0 ) {
> +                    const char *val, *attr;
> +                    int h1, m1, s1, d1;
> +                    b_subtitle_tag = true;
> +                    i_len = 0;
> +                    while( ( attr = xml_ReaderNextAttr( p_xml_reader, &val ) ) )  {
> +                        if( ( strcmp( attr, "TimeIn" ) == 0 ) ) {
> +                            if( sscanf( val, "%d:%d:%d:%d", &h1, &m1, &s1, &d1 ) ==4 ) {
> +                                p_subtitle->i_start = ( (int64_t)h1 * 3600*1000 +
> +                                                        (int64_t)m1 * 60*1000 +
> +                                                        (int64_t)s1 * 1000 +
> +                                                        (int64_t)d1 ) * 1000;
> +                            }
> +                        }
> +                        if( ( strcmp(attr, "TimeOut" ) == 0 ) ) {
> +                            if( sscanf(val, "%d:%d:%d:%d", &h1, &m1, &s1, &d1) ==4 ) {
> +                                p_subtitle->i_stop = ( (int64_t)h1 * 3600*1000 +
> +                                                        (int64_t)m1 * 60*1000 +
> +                                                        (int64_t)s1 * 1000 +
> +                                                        (int64_t)d1 ) * 1000;
> +                            }
> +                        }
Beware if your sscanf fail for some reason you'll have garbage i_start,
i_stop
> +                    }
> +                }
> +                break;
> +
> +            case XML_READER_TEXT:
> +                if( b_subtitle_tag ) {
> +                    if( i_len == 0 ) {
> +                        psz_text = strdup(node);
> +                        i_len = strlen(psz_text);
> +                    } else {
> +                        int i_old = i_len;
> +                        i_len = strlen(node);
> +                        psz_text = (char *) realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
> +                        strcat( psz_text, "\n" );
crash if realloc_or_free freed the data.
> +                        strcat( psz_text, node );
> +                        i_len = strlen(psz_text);
why not using i_old + i_len + 1?
> +                    }
> +                }
> +                break;
> +
> +            case XML_READER_ENDELEM:
> +                if( strcmp( node, "Subtitle" ) == 0 ) {
> +                    p_subtitle->psz_text = psz_text;
> +                        b_subtitle_tag = false ;
> +                        b_quit = true;
> +                    }
else
> +                 if( strcmp(node, "DCSubtitle") == 0 ) {
> +                    if( psz_text ) free(psz_text);
> +                    return VLC_EGENERIC;
> +                    }
> +                break;
> +
> +            default:
> +                break;
> +        }
> +    }
> +
> +    return VLC_SUCCESS;
> +}
> +
> +int OpenSubtitle( demux_t *p_demux, const char *filePath, int sub_nb )
> +{
> +    demux_sub_sys_t *p_sys ;
> +    const char * s_url = vlc_path2uri( filePath, "file" );
> +    stream_t *p_stream;
> +    int ret;
> +    int i_max;
> +
> +    /*TODO: Where put the free */
> +    p_sys = new demux_sub_sys_t();
no check
> +    p_demux->p_sys->v_sub_sys.push_back( p_sys );
> +    p_demux->p_sys->v_sub_sys[sub_nb] = p_sys = (demux_sub_sys_t *) malloc( sizeof( *p_sys ) );
Uh?? smells like memleak.
> +
> +    if( p_sys == NULL )
> +        return VLC_ENOMEM;
> +
> +    p_sys->psz_header         = NULL;
> +    p_sys->i_subtitle         = 0;
> +    p_sys->i_subtitles        = 0;
> +    p_sys->subtitle           = NULL;
> +    p_sys->i_microsecperframe = 40000;
> +
> +    p_sys->jss.b_inited       = false;
> +    p_sys->mpsub.b_inited     = false;
> +
> +    /* HARD fix fps to 24 fps */
> +    p_sys->i_microsecperframe = (int64_t)(1000000 / 24 );
> +
> +    p_sys->i_type = SUB_TYPE_DCSUBTITLE;
Shouldn't all that belong to a constructor?
> +
> +    /* Load the whole file */
> +    p_stream = stream_UrlNew( p_demux, s_url );
> +    if( ! p_stream )
> +        return VLC_EGENERIC;
> +    if ( ret = XmlLoad( p_demux, p_stream, sub_nb ) ) {
> +        msg_Warn( p_demux, "Failure on loading XML subfile" );
> +        free( p_sys );
here you free p_sys but not before isn't it dangerous with it already in
the vector?
> +        stream_Delete( p_stream );
> +        return ret;
> +    }
> +
> +    /* Parse it */
> +    for( i_max = 0; ; )
> +    {
> +        if( p_sys->i_subtitles >= i_max )
> +        {
> +            i_max += 500;
> +            if( !( p_sys->subtitle = (subtitle_t *)realloc_or_free( p_sys->subtitle,
> +                                              sizeof(subtitle_t) * i_max ) ) )
> +            {
> +                XmlUnLoad( p_demux, sub_nb );
> +                stream_Delete( p_stream );
> +                free( p_sys );
same
> +                return VLC_ENOMEM;
> +            }
> +        }
> +
> +        if( ParseDCSubtitle( p_demux, &p_sys->subtitle[p_sys->i_subtitles],
> +                     p_sys->i_subtitles, sub_nb ) )
> +            break;
> +
> +        p_sys->i_subtitles++;
> +    }
> +
> +    XmlUnLoad( p_demux, sub_nb );
> +    stream_Delete(p_stream);
> +
> +    return VLC_SUCCESS;
> +}
> +
> +int SubtitleDemux( demux_t *p_demux, int sub_nb )
> +{
> +    demux_sub_sys_t *p_sys = p_demux->p_sys->v_sub_sys[sub_nb];
> +    int64_t i_maxdate;
> +
> +
> +    if( p_sys->i_subtitle >= p_sys->i_subtitles )
> +        return 0;
> +
> +    i_maxdate = p_sys->i_next_demux_date;
> +
> +    if( i_maxdate <= 0 && p_sys->i_subtitle < p_sys->i_subtitles )
> +    {
> +        /* Should not happen */
> +        i_maxdate = p_sys->subtitle[p_sys->i_subtitle].i_start + 1;
> +    }
> +
> +    while( p_sys->i_subtitle < p_sys->i_subtitles &&
> +           p_sys->subtitle[p_sys->i_subtitle].i_start < i_maxdate )
> +    {
> +        const subtitle_t *p_subtitle = &p_sys->subtitle[p_sys->i_subtitle];
> +
> +        block_t *p_block;
> +        int i_len = strlen( p_subtitle->psz_text ) + 1;
> +
> +        if( i_len <= 1 || p_subtitle->i_start < 0 )
> +        {
> +            p_sys->i_subtitle++;
> +            continue;
> +        }
> +
> +        if( ( p_block = block_Alloc( i_len ) ) == NULL )
> +        {
> +            p_sys->i_subtitle++;
> +            continue;
> +        }
> +
> +        p_block->i_dts =
> +        p_block->i_pts = VLC_TS_0 + p_subtitle->i_start + p_demux->p_sys->p_dcp->sub_reels[sub_nb].i_correction;
> +
> +        if( p_subtitle->i_stop >= 0 && p_subtitle->i_stop >= p_subtitle->i_start )
> +            p_block->i_length = p_subtitle->i_stop - p_subtitle->i_start;
> +
> +        memcpy( p_block->p_buffer, p_subtitle->psz_text, i_len );
> +
> +        es_out_Send( p_demux->out, p_demux->p_sys->p_sub_es, p_block );
> +
> +        p_sys->i_subtitle++;
> +    }
> +
> +    p_sys->i_next_demux_date = 0;
> +    return 1;
> +}
> diff --git a/modules/access/dcp/dcpparser.cpp b/modules/access/dcp/dcpparser.cpp
> index cd42922..e68bc46 100644
> --- a/modules/access/dcp/dcpparser.cpp
> +++ b/modules/access/dcp/dcpparser.cpp
> @@ -234,6 +234,8 @@ int AssetMap::Parse ( )
>      int index = 0;
>      int sum_duration_vid = 0;
>      int sum_duration_aud = 0;
> +    int sum_duration_sub = 0;
> +    int64_t i_conversion = (int64_t)(1000000 / 24);
>      string node;
>  
>      CPL  *cpl;
> @@ -268,7 +270,6 @@ int AssetMap::Parse ( )
>          }
>      }
>  
> -
>      /* Look for PKLs path */
>      if ( (_p_asset_list == NULL) ||  (_p_asset_list->size() == 0) ) {
>          msg_Err( p_demux, "Asset list empty" );
> @@ -345,6 +346,7 @@ int AssetMap::Parse ( )
>          Asset *asset;
>          struct info_reel video;
>          struct info_reel audio;
> +        struct info_reel subtitles;
>  
>          /* Get picture */
>          asset = reel->getTrack(TRACK_PICTURE);
> @@ -356,32 +358,51 @@ int AssetMap::Parse ( )
>              video.i_duration = asset->getDuration();
>              video.i_correction = video.i_entrypoint - sum_duration_vid + video.i_duration;
>              video.i_absolute_end = sum_duration_vid;
> +            video.i_nb_reel = index;
>              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;
> +            audio.i_nb_reel = index;
>              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());
>          }
> +
> +        /* Get subtitle */
> +        asset = reel->getTrack(TRACK_SUBTITLE);
> +        if (asset != NULL)
> +        {
> +            sum_duration_sub += asset->getDuration();
> +            subtitles.filename = p_dcp->path + asset->getPath();
> +            subtitles.i_entrypoint = asset->getEntryPoint();
> +            subtitles.i_duration = asset->getDuration();
> +            /* Subtitle correction, not the same as for audio and video, unit is 10^(-6)*s */
> +            if (index > 0 )
> +            {
> +                subtitles.i_correction = (p_dcp->video_reels[index-1].i_absolute_end + subtitles.i_entrypoint) * i_conversion;
> +            }
> +            else
> +            {
> +                subtitles.i_correction = (subtitles.i_entrypoint) * i_conversion;
> +            }
> +            subtitles.i_absolute_end = sum_duration_sub;
> +            subtitles.i_nb_reel = index;
> +            p_dcp->sub_reels.push_back(subtitles);
> +            msg_Dbg( this->p_demux, "Subtitle Track: %s",asset->getPath().c_str());
> +            msg_Dbg( this->p_demux, "Entry point: %i",asset->getEntryPoint());
> +        }
>      }
>      /* free memory */
>      this->CloseXml();
> @@ -448,7 +469,7 @@ int Asset::Parse( xml_reader_t *p_xmlReader, string p_node, int p_type)
>                                      /* Asset tags not in AssetMap */
>                                      break;
>                                  default:
> -                                    msg_Warn(this->p_demux, "Unknow ASSET_TAG: %i", _tag );
> +                                    msg_Warn( this->p_demux, "Unknow ASSET_TAG: %i", _tag );
>                                      break;
>                              }
>                              /* break the for loop as a tag is found*/
> @@ -482,6 +503,7 @@ int Asset::Parse( xml_reader_t *p_xmlReader, string p_node, int p_type)
>          }
>      }
>      return -1;
> +
>  }
>  
>  
> @@ -536,7 +558,7 @@ int Asset::ParsePKL( xml_reader_t *p_xmlReader)
>                                      /* Asset tags not in PKL */
>                                      break;
>                                  default:
> -                                    msg_Warn(this->p_demux, "Unknow ASSET_TAG: %i", _tag );
> +                                    msg_Warn( this->p_demux, "Unknow ASSET_TAG: %i", _tag );
>                                      break;
>                              }
>                              /* break the for loop as a tag is found*/
> @@ -634,7 +656,6 @@ int AssetMap::ParseAssetList (xml_reader_t *p_xmlReader, const string p_node, in
>      string node;
>      int type;
>      Asset *asset;
> -
>      if (p_type != XML_READER_STARTELEM)
>          return -1;
>      if( p_node != "AssetList" )
> @@ -666,6 +687,7 @@ int AssetMap::ParseAssetList (xml_reader_t *p_xmlReader, const string p_node, in
>          }
>      }
>      return -1;
> +
>  }
>  
>  Asset * AssetMap::getAssetById(AssetList *asset_list, const string p_id)
> @@ -819,7 +841,7 @@ int PKL::Parse()
>                                  this->s_group_id = s_value;
>                                  break;
>                              default:
> -                                msg_Warn(this->p_demux, "Unknow PKG_TAG: %i", _tag );
> +                                msg_Warn( this->p_demux, "Unknow PKG_TAG: %i", _tag );
>                                  break;
>                          }
>                          /* break the for loop as a tag is found*/
> @@ -992,6 +1014,10 @@ int Reel::Parse(string p_node, int p_type) {
>      int type;
>      string s_value;
>  
> +    this->p_picture_track = NULL;
> +    this->p_sound_track = NULL;
> +    this->p_subtitle_track = NULL;
> +
>      if (p_type != XML_READER_STARTELEM)
>          return -1;
>      if( p_node != "Reel")
> @@ -1126,19 +1152,19 @@ int Reel::ParseAsset(string p_node, int p_type, TrackType_t e_track) {
>                  } else if (node == "AnnotationText") {
>                      if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
>                          return -1;
> -                        asset->setAnnotation(s_value);
> +                    asset->setAnnotation(s_value);
>                  } else if (node == "IntrinsicDuration") {
>                      if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
>                          return -1;
> -                        asset->setIntrinsicDuration(atoi(s_value.c_str()));
> +                    asset->setIntrinsicDuration(atoi(s_value.c_str()));
>                  } else if (node == "EntryPoint") {
>                      if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
>                          return -1;
> -                        asset->setEntryPoint(atoi(s_value.c_str()));
> +                    asset->setEntryPoint(atoi(s_value.c_str()));
>                  } else if (node == "Duration") {
>                      if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
>                          return -1;
> -                        asset->setDuration(atoi(s_value.c_str()));
> +                    asset->setDuration(atoi(s_value.c_str()));
>                  } else if (node == "KeyId") {
>                      if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
>                          return -1;
> @@ -1187,6 +1213,7 @@ int Reel::ParseAsset(string p_node, int p_type, TrackType_t e_track) {
>          default:
>              break;
>      }
> +
>      return 0;
>  }
>  
> @@ -1316,7 +1343,7 @@ int CPL::Parse()
>                                  this->s_content_kind = s_value;
>                                  break;
>                              default:
> -                                msg_Warn(this->p_demux, "Unknow CPL_TAG: %i", _tag );
> +                                msg_Warn( this->p_demux, "Unknow CPL_TAG: %i", _tag );
>                                  break;
>                          }
>  
> @@ -1386,6 +1413,7 @@ int CPL::ParseReelList(string p_node, int p_type) {
>                  break;
>              }
>      }
> +
>      return -1;
>  }
>  
> diff --git a/modules/access/dcp/dcpparser.h b/modules/access/dcp/dcpparser.h
> index 32059f5..f02a520 100644
> --- a/modules/access/dcp/dcpparser.h
> +++ b/modules/access/dcp/dcpparser.h
> @@ -72,11 +72,12 @@ class PKL;
>  /* This struct stores useful information about an MXF for demux() */
>  struct info_reel
>  {
> +    int64_t i_correction;           /* entrypoint - sum of previous durations */
>      string filename;
>      int i_entrypoint;
>      int i_duration;
> -    int i_correction;       /* entrypoint - sum of previous durations */
> -    uint32_t i_absolute_end;     /* correction + duration */
> +    uint32_t i_absolute_end;    /* correction + duration */
> +    int i_nb_reel;              /* number of the reel in the cpl reel list, start at 0 */
>  };
>  
>  /* This struct stores the most important information about the DCP */
> @@ -89,6 +90,7 @@ struct dcp_t
>  
>      vector<info_reel> audio_reels;
>      vector<info_reel> video_reels;
> +    vector<info_reel> sub_reels;
>  
>      dcp_t():
>          p_asset_list(NULL) {};
> -- 
> 1.7.9.5
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel

Regards,

-- 
Denis Charmet - TypX
Le mauvais esprit est un art de vivre



More information about the vlc-devel mailing list