[vlc-devel] [PATCHv6] dcp: Creation of access-demux module for DCP
Denis Charmet
typx at dinauz.org
Mon Nov 25 23:14:16 CET 2013
Hi again,
First some general remarks:
* You should declare and initialize variables when you need them not at
the beginning of the function.
* Most of the "this->" are not mandatory
* Most of the gotos and b_stop_parse should be return
More details inlined
Le vendredi 22 novembre 2013 à 07:29:46, Nicolas Bertrand a écrit :
diff --git a/modules/access/dcp/dcpparser.cpp b/modules/access/dcp/dcpparser.cpp
> new file mode 100644
> index 0000000..0b3ca65
> --- /dev/null
> +++ b/modules/access/dcp/dcpparser.cpp
> @@ -0,0 +1,1462 @@
> +/*****************************************************************************
> + * Copyright (C) 2013 VLC authors and VideoLAN
> + *
> + * Authors:
> + * Nicolas Bertrand <nico at isf.cc>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +/**
> + * @file dcp.cpp
Bad filename
> + * @brief DCP access-demux module for Digital Cinema Packages using asdcp library
> + */
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +/* VLC core API headers */
> +#include <vlc_common.h>
> +//#include <vlc_demux.h>
> +#include <vlc_plugin.h>
> +#include <vlc_xml.h>
> +#include <vlc_url.h>
> +
> +#include <iostream>
> +#include <string>
> +#include <list>
> +#include <vector>
> +
> +#include "dcpparser.h"
> +
> +using namespace std;
> +
> +static int ReadNextNode(xml_reader_t *p_xmlReader, string& p_node) {
> + const char * c_node;
> + int i;
> + i = xml_ReaderNextNode( p_xmlReader, &c_node );
> + p_node = c_node;
> + return i;
> +}
> +
> +static int ReadEndNode(xml_reader_t *p_xmlReader, string p_node, int p_type, string &s_value) {
> + string node;
> + int type;
> +
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> +
> + if (( type = ReadNextNode( p_xmlReader, node ) ) > 0) {
> + if ( type == XML_READER_TEXT ) {
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + } else
> + goto error;
> + } else
> + goto error;
> +
> + if (( type = ReadNextNode( p_xmlReader, node ) ) > 0) {
> + if ( type == XML_READER_ENDELEM ) {
> + if (node != p_node)
> + goto error;
> + } else
> + goto error;
> + } else
> + goto error;
This is overly complicated... Don't use goto if your only action is a
return... In any case, your goal seems just to do something like:
if (ReadNextNode(p_xmlReader, node) == XML_READER_TEXT)
{
s_value = node;
if((ReadNextNode(p_xmlReader, node) == XML_READER_ENDELEM) &&
node == p_node)
return 0;
}
return -1;
> +
> + return 0;
> +error:
> + return -1;
> +}
> +
> +typedef enum {
> + CHUNK_UNKNOWN = 0,
> + CHUNK_PATH,
> + CHUNK_VOL_INDEX,
> + CHUNK_OFFSET,
> + CHUNK_LENGTH
> +} ChunkTag_t;
> +
> +
> +typedef enum {
> + ASSET_UNKNOWN = 0,
> + ASSET_ID,
> + ASSET_ANNOTATION_TEXT,
> + ASSET_PACKING_LIST,
> + ASSET_CHUNK_LIST,
> + ASSET_HASH,
> + ASSET_SIZE,
> + ASSET_TYPE,
> + ASSET_ORIGINAL_FILENAME
> +} AssetTag_t;
> +
> +
> +typedef enum {
> + PKL_UNKNOWN = 0,
> + PKL_ID,
> + PKL_ISSUE_DATE,
> + PKL_ISSUER,
> + PKL_CREATOR,
> + PKL_ASSET_LIST,
> + PKL_ANNOTATION_TEXT, /* start of optional tags */
> + PKL_ICON_ID,
> + PKL_GROUP_ID,
> + PKL_SIGNER,
> + PKL_SIGNATURE,
> +
> +} PKLTag_t;
> +
> +typedef enum {
> + CPL_UNKNOWN = 0,
> + CPL_ID,
> + CPL_ANNOTATION_TEXT, /* optional */
> + CPL_ICON_ID, /* optional */
> + CPL_ISSUE_DATE,
> + CPL_ISSUER, /* optional */
> + CPL_CREATOR, /* optional */
> + CPL_CONTENT_TITLE,
> + CPL_CONTENT_KIND,
> + CPL_CONTENT_VERSION, /* not optional, but not always present*/
> + CPL_RATING_LIST, /* not handled */
> + CPL_REEL_LIST,
> + CPL_SIGNER, /* optional - not handled */
> + CPL_SIGNATURE /* optional - not handled */
> +} CPLTag_t;
> +
> +
> +class ChunkList: public std::list<Chunk> {
> +public :
> + ChunkList();
> + ~ChunkList();
> +};
> +
> +/*
> + * Chunk Class
> + */
> +
> +Chunk::Chunk():
i_vol_index(1), i_offset(0), i_length(0) {}
No need to pull a this->foo.
> + {
> + this->i_vol_index = 1;
> + this->i_offset = 0;
> + this->i_length = 0;
> +
> +}
> +int Chunk::Parse( xml_reader_t *p_xmlReader, string p_node, int p_type){
> + string node;
> + int type;
> + string s_value;
> + ChunkTag_t chunk_tag = CHUNK_UNKNOWN;
> +
> + cout << "Chunk::Parse Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
Once again don't use goto if your only goal is to return an error, just
return it. (I'll skip this part now).
> + if( p_node != "Chunk")
> + goto error;
> + /* loop on Chunks Node */
> + while( ( type = ReadNextNode( p_xmlReader, node ) ) > 0 ) {
> + cout << "Chunk::Parse node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
<nitpicking> this could be done in a more compact way with something like
static const string names[] = {"Path", "VolumeIndex", "Offset",
"Length"};
chunk_tag = CHUNK_UNKNOWN;
for(ChunkTag_t i = 0; i < CHUNK_LENGTH; i++)
if( node == names[i])
{
chunk_tag = i+1;
break;
}
if(chunk_tag == CHUNK_UNKNOWN)
return -1;
> + if( node =="Path")
> + chunk_tag = CHUNK_PATH;
> + else if( node =="VolumeIndex")
> + chunk_tag = CHUNK_VOL_INDEX;
> + else if( node =="Offset")
> + chunk_tag = CHUNK_OFFSET;
> + else if( node =="Length")
> + chunk_tag = CHUNK_LENGTH;
> + else {
> + chunk_tag = CHUNK_UNKNOWN;
> + goto error;
> + }
> + break;
> + case XML_READER_TEXT:
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + break;
> + case XML_READER_ENDELEM:
> + /* Verify if we reach Chuk endelem */
> + if ( node == p_node) {
> + /* verify path */
> + if ( this->s_path.empty() ) {
> + cout << "Chunk::Parse No path found" <<endl;
> + goto error;
> + }
> + if ( this->i_vol_index != 1 ) {
> + cout << "Chunk::Parse Only TODO: Only one VOLINDEX suported. Patch welcome." <<endl;
> + goto error;
> + }
> + /* end of Chnuk tag parse */
> + goto end;
> + }
> + switch (chunk_tag) {
then you could reuse the table here (mind
the +/-1 if you want to keep unknown at the zero position.
> + case CHUNK_PATH:
> + if( node != "Path" )
> + goto error;
> + this->s_path = s_value;
IMO, you can drop the "this".
> + break;
> + case CHUNK_VOL_INDEX:
> + if( node != "VolumeIndex" )
> + goto error;
> + this->i_vol_index = atoi(s_value.c_str());
> + break;
> + case CHUNK_OFFSET:
> + if( node != "Offset" )
> + goto error;
> + this->i_offset = atoi(s_value.c_str());
> + break;
> + case CHUNK_LENGTH:
> + if( node != "Length" )
> + goto error;
> + this->i_length = atoi(s_value.c_str());
> + break;
> + case CHUNK_UNKNOWN:
> + default:
> + cout << "Chunk::Parse Unknow chunk tag" <<endl;
> + break;
> + }
> + break;
> + }
> + }
> +
> +end:
> + return 0;
> +
> +error:
> + return -1;
> +
> +
> +}
> +
> +int AssetMap::Parse ( )
> +{
> + int type = 0;
> + const char* node = NULL;
> +
> + CPL *cpl;
> + Reel *reel;
> + PKL *pkl;
> + Asset *test_asset;
> +
> + AssetList *p_asset_list;
> + AssetList::iterator iter;
> +
> + vector<string> pklfiles;
> + string p_filepath;
> +
> + /* init XML parser */
> + if( OpenXml() )
> + {
> + msg_Err( p_demux, "Failed to initialize XML parser" );
> + goto error;
> + }
> +
> + /* reading ASSETMAP file to get the asset_list */
> + msg_Dbg( p_demux, "reading ASSETMAP file..." );
> + while( ( type = xml_ReaderNextNode( p_xmlReader, &node ) ) > 0 ) {
> + /* This condition determines if we are in AssetList part or not */
> + if( ( type == XML_READER_STARTELEM ) && ( strcasecmp( node, "AssetList" ) == 0 ) )
> + {
> + p_asset_list = new AssetList();
Beware of exceptions coming with new
> + p_dcp->p_asset_list = p_asset_list;
> + ParseAssetList(p_xmlReader, node, type );
leaks if you have several asset lists, maybe a break?
> + }
> + }
> + if (p_asset_list == NULL) {
> + msg_Err( p_demux, "Could not find AssetList tag in ASSETMAP" );
> + goto error;
> + }
> +
> + /* Look for PKLs path */
> + for (iter = p_asset_list->begin(); iter != p_asset_list->end() ; ++iter) {
> + p_filepath = (*iter)->getPath();
> + if (p_filepath.empty()) {
> + msg_Err( p_demux, "No path element for asset" );
> + continue;
> + }
> + /* set an absolute file path */
> + p_filepath = p_dcp->path + p_filepath;
> +
> + /* case of packing list */
> + if ((*iter)->isPackingList()) {
> + pklfiles.push_back( p_filepath );
if you only need one why bother staying in the loop and using a vector?
> + }
> + }
> +
> + if( pklfiles[0].empty() )
test pklfiles.size() before trying the first element.
> + {
> + msg_Err( p_demux, "Could not find PKL file in ASSETMAP" );
> + goto error;
> + }
> +
> + /* Create the first PKL */
> + pkl = new PKL(p_demux, pklfiles[0], p_asset_list, p_dcp->path);
possible exception
> + if (pkl->Parse())
> + goto error;
> + p_dcp->pkls.push_back( pkl );
> +
> + /* Now, CPL */
> + if ( pkl->FindCPLs() <= 0 ) {
> + msg_Err(p_demux, " No CPL found");
> + goto error;
> + }
> + cpl = pkl->getCPL(0);
> + if( cpl == NULL ) {
> + msg_Err(p_demux, " No CPL found");
> + goto error;
> + }
> + cpl->Parse();
> + reel = cpl->getReel(0);
> +
> + /* test picture */
> + test_asset = reel->getTrack(TRACK_PICTURE);
> + cout << "Video Track: "<< test_asset->getPath() << endl;
> + p_dcp->videofile = p_dcp->path + test_asset->getPath();
> + test_asset = reel->getTrack(TRACK_SOUND);
> + p_dcp->audiofile = p_dcp->path + test_asset->getPath();
> +
> + /* free memory */
> + CloseXml();
> + delete pkl;
smells like double free since you pushed it in p_dcp->pkls
> + std::cout << "parseAssetmapXML OK "<< std::endl;
> + return VLC_SUCCESS;
> +
> +error:
> + std::cout << "Error in parseAssetmapXML"<< std::endl;
> + CloseXml();
> + return VLC_EGENERIC;
> +}
> +
> +
> +
> +/*
> + * Asset Class
> + */
> +
> +Asset::Asset()
: b_is_packing_list(false),...
> +{
> + this->b_is_packing_list = false;
> + this->s_path = "toto";
really? That's a waste of memory.
> + this->ui_size = 0;
> +}
> +
> +int Asset::Parse( xml_reader_t *p_xmlReader, string p_node, int p_type)
> +{
> + string node;
> + int type;
> + string s_value;
> + AssetTag_t asset_tag = ASSET_UNKNOWN;
> +
> + cout << "Asset::Parse Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "Asset")
> + goto error;
> + /* loop on Assets Node */
> + while( ( type = ReadNextNode( p_xmlReader, node ) ) > 0 ) {
> + cout << "Asset::Parse node = "<< node << "("<< type<<")"<< endl;
> + if (xml_ReaderIsEmptyElement( p_xmlReader)) {
> + cout << node << "is an empty element" <<endl;
> + }
> + switch (type) {
> + case XML_READER_STARTELEM:
maybe the table trick can come in handy.
> + if( node =="Id")
> + asset_tag = ASSET_ID;
> + else if( node =="AnnotationText")
> + asset_tag = ASSET_ANNOTATION_TEXT;
> + else if( node =="PackingList") {
> + asset_tag = ASSET_PACKING_LIST;
> + /* case of <PackinkList/> tag, bur not compliant with SMPTE-429-9 2007*/
> + if (xml_ReaderIsEmptyElement( p_xmlReader))
> + this->b_is_packing_list = true;
> + }
> + else if( node =="ChunkList") {
> + asset_tag = ASSET_CHUNK_LIST;
> + if ( this->parseChunkList(p_xmlReader, node, type ) )
> + goto error;
> + this->s_path = this->chunk_vec[0].getPath();
> + } else {
> + asset_tag = ASSET_UNKNOWN;
> + goto error;
> + }
> + break;
> + case XML_READER_TEXT:
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + break;
> + case XML_READER_ENDELEM:
> + /*Check Presence of Id and Chunklist, when its present */
> + if ( node == p_node) {
> + if ( this->s_id.empty() ) {
> + //msg_Err(this->p_demux, " No Id element found in Asset");
> + goto error;
> + }
> + /* TODO: verification of Chunklist */
> + goto end;
> + }
> + switch (asset_tag) {
> + case ASSET_ID:
> + if( node != "Id" )
> + goto error;
> + this->s_id = s_value;
> + break;
> + case ASSET_PACKING_LIST:
> + if( node != "PackingList" )
> + goto error;
> + if ( s_value == "true" )
> + this->b_is_packing_list = true;
> + break;
> + case ASSET_ANNOTATION_TEXT:
> + if( node != "AnnotationText" )
> + goto error;
> + this->s_annotation = s_value;
> + break;
> + default:
> + //msg_Err(this->p_demux,"Unknow end attribute %s",s_value.c_str());
> + break;
> + }
> + }
> + }
> +end:
> + return 0;
> +
> +error:
> + return -1;
> +}
> +
> +int Asset::ParsePKL( xml_reader_t *p_xmlReader)
> +{
> + string node;
> + int type;
> + string s_value;
> + AssetTag_t i_tag = ASSET_UNKNOWN;
> +
> + while( ( type = ReadNextNode( p_xmlReader, node ) ) > 0 ) {
> + cout << "Asset::ParsePKL node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
same thing.
> + if( node =="AnnotationText")
> + i_tag = ASSET_ANNOTATION_TEXT;
> + else if( node =="Hash")
> + i_tag = ASSET_HASH;
> + else if( node =="Size")
> + i_tag = ASSET_SIZE;
> + else if( node =="Type")
> + i_tag = ASSET_TYPE;
> + else if( node =="OriginalFileName")
> + i_tag = ASSET_ORIGINAL_FILENAME;
> + else {
> + i_tag = ASSET_UNKNOWN;
> + goto error;
> + }
> + break;
> + case XML_READER_TEXT:
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + break;
> + case XML_READER_ENDELEM:
> + if (node == "Asset") {
> + /* Reach end node of asset */
> + if (this->s_hash.empty()) {
> + cout << " Hash tag invalid " <<endl;
> + goto error;
> + }
> + if (this->ui_size == 0) {
> + cout << " Size tag invalid " <<endl;
> + goto error;
> + }
> + if (this->s_type.empty()) {
> + cout << " Type tag invalid " <<endl;
> + goto error;
> + }
> + goto end;
> + }
> +
> + switch (i_tag) {
> + case ASSET_ANNOTATION_TEXT:
> + if ( this->s_annotation.empty() )
> + this->s_annotation = s_value;
> + else
> + this->s_annotation = this->s_annotation + "--" + s_value;
> + break;
> + case ASSET_HASH:
> + this->s_hash = s_value;
> + break;
> + case ASSET_SIZE:
> + this->ui_size = atol(s_value.c_str());
> + break;
> + case ASSET_TYPE:
> + this->s_type = s_value;
> + break;
> + case ASSET_ORIGINAL_FILENAME:
> + this->s_original_filename = s_value;
> + break;
> + case ASSET_UNKNOWN:
> + default:
> + cout << __LINE__ << " Unknown asset" <<endl;
> + break;
> + }
> + break;
> + }
> + }
> +end:
> + return 0;
> +
> +error:
> + return -1;
> +}
> +
> +void Asset::Dump()
> +{
> +string s_str;
> +
> +cout << "Id = " << this->s_id << endl;
> +cout << "Path = " << this->s_path << endl;
> +s_str = this->b_is_packing_list ? "True" : "False";
> +cout << "Is PKL = " << s_str << endl;
> +cout << "Hash = " << this->s_hash << endl;
> +cout << "Size = " << this->ui_size << endl;
> +cout << "Type = " << this->s_type << endl;
> +cout << "OrignalFileName = " << this->s_original_filename << endl;
> +cout << "AnnotationText = " << this->s_annotation << endl;
> +
> +}
> +
> +int Asset::parseChunkList( xml_reader_t *p_xmlReader, string p_node, int p_type)
> +{
> + string node;
> + int type;
> + string s_value;
> + std::vector<Chunk> chunk_vec;
> + //Chunk chunk;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "ChunkList" )
> + goto error;
> + /* loop on Assets Node */
> + while( ( type = ReadNextNode( p_xmlReader, node ) ) > 0 ) {
> + cout << "Asset::parseChunkList node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
> + {
indentation
> + Chunk chunk;
> + if (node != "Chunk" )
> + goto error;
> + if ( chunk.Parse(p_xmlReader, node, type) )
> + goto error;
> + chunk_vec.push_back(chunk);
> + break;
> + }
> + case XML_READER_TEXT:
> + break;
useless
> + case XML_READER_ENDELEM:
> + if ( node == p_node) {
> + if (chunk_vec.size() != 1 ) {
> + cout << "chunklist of size greater than one not supported" << endl;
> + goto error;
> + }
> + this->chunk_vec = chunk_vec;
> + goto end;
> + }
> + break;
> + }
> + }
> +end:
> + return 0;
> +
> +error:
> + return -1;
> +}
> +
> +#if 0
> +list<Asset *> AssetList;
> +int main()
> +{
> + list<Asset *>::iterator itor;
> + std::cout << "# creating Asset list :" << std::endl;
> + Asset *_Asset1 = new Asset();
> + _Asset1->setId("1234");
> + AssetList.push_back(_Asset1);
> + Asset *_Asset2 = new Asset();
> + _Asset2->setId("5678");
> + AssetList.push_back(_Asset2);
> + cout << "Size of asset list = "<<AssetList.size()<<endl;
> + for (itor=AssetList.begin(); itor != AssetList.end() ; ++itor) {
> + std::cout << "Id=" << (*itor)->getId() << std::endl;
> + }
> +}
> +#endif
Maybe remove dead code.
> +
> +
> +int AssetMap::ParseAssetList (xml_reader_t *p_xmlReader, string p_node, int p_type)
> +{
> + string node;
> + int type;
> + Asset *asset;
> +
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "AssetList" )
> + goto error;
> + /* loop on AssetList nodes */
> + while( ( type = ReadNextNode( p_xmlReader, node ) ) > 0 ) {
> + cout << "AssetList::Parse node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
> + if (node != "Asset" )
> + goto error;
> + asset = new Asset;
> + if (asset->Parse(p_xmlReader, node, type)){
> + delete asset;
> + goto error;
> + }
> + p_dcp->p_asset_list->push_back(asset);
> + break;
> +
> + case XML_READER_ENDELEM:
> + if (node == "AssetList" )
> + goto end;
> + break;
> + }
> + }
> +
> +end :
> + return 0;
> +error:
> + return -1;
> +}
> +
> +Asset * AssetMap::getAssetById(AssetList *asset_list, const string p_id)
> +{
> + cout << "AssetList::getAssetById Enter Id=" << p_id <<endl;
meh cout :(
> + AssetList::iterator index = asset_list->begin() ;
> + cout << " size ="<< asset_list->size() <<endl;
> + while (index != asset_list->end()) {
why not a for?
> + if ((*index)->getId() == p_id )
> + return *index;
> + index++;
> + }
> + cout << "No matching asset found with Id" << p_id <<endl;
> + return NULL;
> +}
> +
> +/*
> + * XmlFile Class
> + */
> +
> +XmlFile::XmlFile(demux_t * p_demux, string s_path)
s_path(s_path)...
> +{
> + this->s_path = s_path;
> + this->p_demux = p_demux;
> + this->p_stream = NULL;
> + this->p_xml = NULL;
> + this->p_xmlReader = NULL;
> +
> + this->type = XML_UNKNOWN;
> + /* convert path to uri */
> +}
> +
> +XmlFile::~XmlFile()
> +{
> + cout << "destructor in Xml::File" << endl;
> +}
> +
> +int XmlFile::OpenXml()
> +{
> + char *psz_uri;
> +
> + this->p_xml = xml_Create( this->p_demux );
> + if (! this->p_xml) {
> + return -1;
> + }
> + psz_uri = vlc_path2uri( this->s_path.c_str(), "file" );
> + this->p_stream = stream_UrlNew(this->p_demux, psz_uri );
> + if( ! this->p_stream ) {
> + xml_Delete(this->p_xml );
> + free(psz_uri);
> + return -1;
> + }
> +
> + this->p_xmlReader = xml_ReaderCreate( this->p_xml, this->p_stream);
> + if( ! this->p_xmlReader ) {
> + stream_Delete( this->p_stream );
> + xml_Delete(this->p_xml );
> + free(psz_uri);
> + return -1;
> + }
> + free(psz_uri);
> + return 0;
> +}
> +
> +void XmlFile::CloseXml() {
> + if( this->p_stream )
> + stream_Delete( this->p_stream );
> + if( this->p_xmlReader )
> + xml_ReaderDelete( this->p_xmlReader );
> + if( this->p_xml )
> + xml_Delete( this->p_xml );
> +
> +}
> +
> +/*
> + * PKL Class
> + */
> +
> +PKL::PKL(demux_t * p_demux, string s_path, AssetList *_asset_list, string s):
> + XmlFile(p_demux, s_path), asset_list(_asset_list), s_dcp_path(s)
,type(XML_PKL)
> +{
> + std::cout << "Initialize PKL "<< s_path << std::endl;
> + type = XML_PKL;
> +}
> +
> +int PKL::Parse()
> +{
> + string node;
> + int type;
> + string s_value;
> + PKLTag_t i_tag = PKL_UNKNOWN;
> + cout << "PKL::Parse Enter "<< endl;
> + if (this->OpenXml())
> + return -1;
> + /* read 1st node and verify that is a CPL*/
> + if ( (type = ReadNextNode(this->p_xmlReader, node)) > 0) {
> + if ( ! ((type == XML_READER_STARTELEM) && (node == "PackingList")) ) {
> + msg_Err( this->p_demux, "Not a valid XML Packing List");
> + goto error;
> + }
> + } else {
> + msg_Err( this->p_demux, "XML read failed");
> + goto error;
> + }
> + while( ( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) {
> + cout << "PKL::Parse node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
table maybe
> + if( node =="Id")
> + i_tag = PKL_ID;
> + else if( node == "IssueDate")
> + i_tag = PKL_ISSUE_DATE;
> + else if( node == "Issuer")
> + i_tag = PKL_ISSUER;
> + else if( node == "Creator")
> + i_tag = PKL_CREATOR;
> + else if( node == "AssetList") {
> + i_tag = PKL_ASSET_LIST;
> + if ( this->ParseAssetList(node, type) )
> + goto error;
> + } else if( node == "AnnotationText")
> + i_tag = PKL_ANNOTATION_TEXT;
> + else if( node == "IconId")
> + i_tag = PKL_ICON_ID;
> + else if( node == "GroupId")
> + i_tag = PKL_GROUP_ID;
> + else if( node == "Signer") {
> + i_tag = PKL_SIGNER;
> + if ( this->ParseSigner(node, type) )
> + goto error;
> + } else if( node == "ds:Signature") {
> + i_tag = PKL_SIGNATURE;
> + if ( this->ParseSignature(node, type) )
> + goto error;
> + } else {
> + i_tag = PKL_UNKNOWN;
> + goto error;
> + }
> + break;
> + case XML_READER_TEXT:
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + break;
> +
> + case XML_READER_ENDELEM:
> + switch (i_tag) {
> + case PKL_ID:
> + if( node != "Id" )
> + goto error;
> + this->s_id = s_value;
> + break;
> + case PKL_ISSUE_DATE:
> + if( node != "IssueDate" )
> + goto error;
> + this->s_issue_date= s_value;
> + break;
> + case PKL_ISSUER:
> + if( node != "Issuer" )
> + goto error;
> + this->s_issuer = s_value;
> + break;
> + case PKL_CREATOR:
> + if( node != "Creator" )
> + goto error;
> + this->s_creator = s_value;
> + break;
> + case PKL_ASSET_LIST:
> + /* impossible */
> + break;
> + case PKL_ANNOTATION_TEXT:
> + if( node != "AnnotationText" )
> + goto error;
> + this->s_annotation = s_value;
> + break;
> + case PKL_ICON_ID:
> + if( node != "IconId" )
> + goto error;
> + this->s_icon_id = s_value;
> + break;
> + case PKL_GROUP_ID:
> + if( node != "GroupId" )
> + goto error;
> + this->s_group_id = s_value;
> + break;
> + case PKL_SIGNER:
> + case PKL_SIGNATURE:
> + /* impossible */
> + break;
> + case ASSET_UNKNOWN:
> + default:
> + goto error;
> + }
> + break;
> + }
> + }
> + /* TODO verify presence of mandatory fields*/
> +
> + /* Close PKL XML*/
> + this->CloseXml();
> + return 0;
> +error:
> + this->CloseXml();
> + return -1;
> +}
> +
> +int PKL::FindCPLs()
> +{
> + AssetList::iterator index = this->asset_list->begin();
> + Asset *asset;
> + CPL *cpl;
> + cout << "Enter PKL::FindCPLs" << this->asset_list->size() <<endl;
> + if ( this->vec_cpl.size() != 0 ) {
> + msg_Err(this->p_demux, "CPLs already checked");
> + return -1;
> + }
> +
> + while (index != this->asset_list->end()) {
for?
> + asset = *index;
> + if ( asset->getType().find("text/xml") == string::npos) {
> + /* not an xml file */
> + index++;
> + continue;
> + }
> +
> + cpl = new CPL(this->p_demux,
> + this->s_dcp_path + asset->getPath(),
> + this->asset_list);
> + cout << "IsCPL ? " << asset->getPath() << cpl->IsCPL() <<endl;
> + if ( cpl->IsCPL() )
> + /* CPL Found */
> + this->vec_cpl.push_back(cpl);
> +
> + index++;
> + }
> + cout << "found " << this->vec_cpl.size() << " cpls" <<endl;
> + return this->vec_cpl.size();
> +}
> +
> +
> +int PKL::ParseAssetList(string p_node, int p_type) {
> + string node;
> + int type;
> +
> + cout << "PKL::ParseAssetList Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "AssetList")
> + goto error;
> + while( ( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) {
> + cout << "PKL::ParseAssetList node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
> + if( node =="Asset") {
> + if ( this->ParseAsset(node, type) )
> + goto error;
> + } else
> + goto error;
> + break;
> + case XML_READER_TEXT:
> + /* impossible */
impossible so useless
> + break;
> + case XML_READER_ENDELEM:
> + if ( node == p_node) {
> + /* parse of chunklist finished */
> + goto end;
> + }
> + break;
> + }
> + }
> +end:
> + return 0;
> +error:
> + return -1;
> +}
> +
> +int PKL::ParseAsset(string p_node, int p_type) {
> + string node;
> + int type;
> + string s_value;
> + Asset *asset = NULL;
> +
> + cout << "PKL::ParseAsset Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "Asset")
> + goto error;
> +
> + /* 1st node shall be Id" */
> + if (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0)
> + if ( ! ((type == XML_READER_STARTELEM) && (node == "Id")))
> + goto error;
> + if (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0)
> + if (type == XML_READER_TEXT) {
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + }
> + if (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0)
> + if (type == XML_READER_ENDELEM) {
> + asset = AssetMap::getAssetById(this->asset_list, s_value);
> + cout << "Found asset with id=" << s_value << endl;
> + if (asset == NULL)
> + goto error;
> + }
> + if ( asset->ParsePKL(this->p_xmlReader) )
> + goto error;
> + return 0;
> +error:
> + return -1;
> +}
> +
> +int PKL::ParseSigner(string p_node, int p_type)
> +{
> + string node;
> + int type;
> + bool b_stop_parse = false;
> +
> + cout << "PKL::ParseSigner Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "Signer")
> + goto error;
> +
> + while( (! b_stop_parse) &&
why testing when you could just break or return?
> + (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) ) {
> + /* TODO not implemented. Just pase until end of Sihne node */
> + if ((node == p_node) && (type = XML_READER_ENDELEM))
> + b_stop_parse = true;
> + }
> +
> + if (b_stop_parse == false) {
> + cout << "Parse of Signer finished bad" << endl;
> + goto error;
> + }
> + return 0;
> +
> +error :
> + return -1;
> +}
> +
> +int PKL::ParseSignature(string p_node, int p_type)
> +{
> + string node;
> + int type;
> + bool b_stop_parse = false;
> +
> + cout << "PKL::ParseSignature Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "ds:Signature")
> + goto error;
> +
> + while( (! b_stop_parse) &&
> + (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) ) {
> + /* TODO not implemented. Just pase until end of Sihne node */
> + if ((node == p_node) && (type = XML_READER_ENDELEM))
> + b_stop_parse = true;
> + }
> +
> + if (b_stop_parse == false) {
> + cout << "Parse of Signature finished bad" << endl;
> + goto error;
> + }
> + return 0;
> +
> +error :
> + return -1;
> +}
> +
> +/*
> + * Reel Class
> + */
> +int Reel::Parse(string p_node, int p_type) {
> + string node;
> + int type;
> + string s_value;
> + bool b_stop_parse = false;
> +
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "Reel")
> + goto error;
> +
> + while( (! b_stop_parse) &&
> + (( type = ReadNextNode(this->p_xmlReader, node ) ) > 0 ) ) {
> + switch (type) {
> + case XML_READER_STARTELEM:
> + if (node =="Id") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + this->s_id = s_value;
> + } else if ( node =="AssetList" ) {
> + if (this->ParseAssetList(node, type))
> + goto error;
> + } else {
> + /* unknown tag */
> + cout << "Reel::Parse, unknown tag: "<<node<<endl;
> + }
> + break;
> + case XML_READER_TEXT:
> + /* impossible */
> + goto error;
> + break;
> + case XML_READER_ENDELEM:
> + /* verify correctness of end node */
> + if ( node == p_node) {
> + /* TODO : verify id */
> + b_stop_parse = true;
> + }
> + }
> + }
> + return 0;
> +error:
> + return -1;
> +}
> +
> +
> +Asset * Reel::getTrack(TrackType_t e_track)
> +{
> +Asset * p_asset =NULL;
> +
> + switch (e_track) {
> + case TRACK_PICTURE:
> + p_asset = this->p_picture_track;
return this->p_picture_track;
> + break;
> + case TRACK_SOUND:
> + p_asset = this->p_sound_track;
> + break;
> + case TRACK_SUBTITLE:
> + p_asset = this->p_subtitle_track;
> + break;
> + case TRACK_UNKNOWN:
> + default:
> + break;
> + }
> + return p_asset;
> +}
> +
> +int Reel::ParseAssetList(string p_node, int p_type) {
> + string node;
> + int type;
> + string s_value;
> + bool b_stop_parse = false;
> +
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> + if( p_node != "AssetList")
> + goto error;
> +
> + while( (! b_stop_parse) &&
> + (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) ) {
> + switch (type) {
> + case XML_READER_STARTELEM:
> + if (node =="MainPicture") {
> + if ( this->ParseAsset(node, type, TRACK_PICTURE) )
> + goto error;
> + } else if (node =="MainSound") {
> + if ( this->ParseAsset(node, type, TRACK_SOUND) )
> + goto error;
> + } else if (node =="MainSubtitle") {
> + if ( this->ParseAsset(node, type, TRACK_SUBTITLE) )
> + goto error;
> + } else {
> + /* unknown tag */
> + cout << "Reel::ParseAssetList, unknown tag: "<<node<<endl;
> + }
> + break;
> + case XML_READER_TEXT:
> + /* impossible */
> + goto error;
> + break;
> + case XML_READER_ENDELEM:
> + /* verify correctness of end node */
> + if ( node == p_node) {
> + /* TODO : verify id */
> + b_stop_parse = true;
> + }
> + }
> + }
> + return 0;
> +error:
> + return -1;
> +}
> +
> +int Reel::ParseAsset(string p_node, int p_type, TrackType_t e_track) {
> + string node;
> + int type;
> + string s_value;
> + bool b_stop_parse = false;
> + Asset *asset = NULL;
> +
> + if (p_type != XML_READER_STARTELEM)
> + goto error;
> +
> + /* 1st node shall be Id */
> + if (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0)
> + if ( ! ((type == XML_READER_STARTELEM) && (node == "Id")))
> + goto error;
> +
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value) )
> + goto error;
> +
> + asset = AssetMap::getAssetById(this->p_asset_list, s_value);
> + cout << "Found asset with id=" << s_value << endl;
> + if (asset == NULL)
> + goto error;
> +
> + while( (! b_stop_parse) &&
> + (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) ) {
> + switch (type) {
> + case XML_READER_STARTELEM:
> + if (node =="EditRate") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="IntrinsicDuration") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="EntryPoint") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="Duration") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="Duration") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="KeyId") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="Hash") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="FrameRate") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="ScreenAspectRatio") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
> + } else if (node =="Language") {
> + if ( ReadEndNode(this->p_xmlReader, node, type, s_value))
> + goto error;
same code used for different conditions, just extend your condition.
> + } else {
> + /* unknown tag */
> + cout << "Reel::ParseAssetList, unknown tag: "<<node<<endl;
> + }
> + break;
> + case XML_READER_TEXT:
> + /* impossible */
> + goto error;
> + break;
> + case XML_READER_ENDELEM:
> + /* verify correctness of end node */
> + if ( node == p_node) {
> + /* TODO : verify id */
> + b_stop_parse = true;
> + }
> + }
> + }
> + /* store by track */
> + switch (e_track) {
> + case TRACK_PICTURE:
> + this->p_picture_track = asset;
> + break;
> + case TRACK_SOUND:
> + this->p_sound_track = asset;
> + break;
> + case TRACK_SUBTITLE:
> + this->p_subtitle_track = asset;
> + break;
> + case TRACK_UNKNOWN:
> + default:
> + break;
> + }
> + return 0;
> +error:
> + return -1;
> +}
> +
> +/*
> + * CPL Class
> + */
> +
> +CPL::CPL(demux_t * p_demux, string s_path, AssetList *_asset_list)
> + : XmlFile(p_demux, s_path), asset_list( _asset_list)
> +{
> + string node;
> + int type;
> +
> + if (this->OpenXml())
> + return;
> +
> + /* read 1st node and verify that is a CPL */
> + if ( (type = ReadNextNode(p_xmlReader, node)) > 0) {
> + if ( (type == XML_READER_STARTELEM) && (node == "CompositionPlaylist") ) {
> + this->type = XML_CPL;
> + }
> + }
> + /* close xml */
> + this->CloseXml();
> +};
> +
> +int CPL::Parse()
> +{
> + string node;
> + int type;
> + string s_value;
> + CPLTag_t i_tag = CPL_UNKNOWN;
> + cout << "CPL::Parse Enter "<< endl;
> + if (this->OpenXml())
> + return -1;
> + /* read 1st node and verify that is a CPL*/
> + if ( (type = ReadNextNode(this->p_xmlReader, node)) > 0) {
> + if ( ! ((type == XML_READER_STARTELEM) && (node == "CompositionPlaylist")) ) {
> + msg_Err( this->p_demux, "Not a valid XML Composition Play List");
> + goto error;
> + }
> + } else {
> + msg_Err( this->p_demux, "XML read failed");
> + goto error;
> + }
> + while( ( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) {
> + cout << "CPL::Parse node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
table?
> + if( node =="Id")
> + i_tag = CPL_ID;
> + else if( node == "AnnotationText")
> + i_tag = CPL_ANNOTATION_TEXT;
> + else if( node == "IconId")
> + i_tag = CPL_ICON_ID;
> + else if( node == "IssueDate")
> + i_tag = CPL_ISSUE_DATE;
> + else if( node == "Issuer")
> + i_tag = CPL_ISSUER;
> + else if( node == "Creator")
> + i_tag = CPL_CREATOR;
> + else if( node == "ContentTitleText")
> + i_tag = CPL_CONTENT_TITLE;
> + else if( node == "ContentKind")
> + i_tag = CPL_CONTENT_KIND;
> + else if( node == "ContentVersion") {
> + i_tag = CPL_CONTENT_VERSION;
> + if ( this->DummyParse(node,type) )
> + goto error;
> + }
> + else if( node == "RatingList") {
> + i_tag = CPL_RATING_LIST;
> + if ( this->DummyParse(node,type) )
> + goto error;
> + }
> + else if( node == "ReelList") {
> + i_tag = CPL_REEL_LIST;
> + if ( this->ParseReelList(node, type) )
> + goto error;
> + } else if( node == "Signer") {
> + i_tag = CPL_SIGNER;
> + if ( this->DummyParse(node, type) )
> + goto error;
> + } else if( node == "ds:Signature") {
> + i_tag = CPL_SIGNATURE;
> + if ( this->DummyParse(node, type) )
> + goto error;
> + } else {
> + i_tag = CPL_UNKNOWN;
> + goto error;
> + }
> + break;
> + case XML_READER_TEXT:
> + s_value = node;
> + if (unlikely(node.empty()))
> + goto error;
> + break;
> +
> + case XML_READER_ENDELEM:
> + switch (i_tag) {
> + case CPL_ID:
> + if( node != "Id" )
> + goto error;
> + this->s_id = s_value;
> + break;
> + case CPL_ANNOTATION_TEXT:
> + if( node != "AnnotationText" )
> + goto error;
> + this->s_annotation = s_value;
> + break;
> + case CPL_ICON_ID:
> + if( node != "IconId" )
> + goto error;
> + this->s_icon_id = s_value;
> + break;
> + case CPL_ISSUE_DATE:
> + if( node != "IssueDate" )
> + goto error;
> + this->s_issue_date= s_value;
> + break;
> + case CPL_ISSUER:
> + if( node != "Issuer" )
> + goto error;
> + this->s_issuer = s_value;
> + break;
> + case CPL_CREATOR:
> + if( node != "Creator" )
> + goto error;
> + this->s_creator = s_value;
> + break;
> + case CPL_CONTENT_TITLE:
> + if( node != "ContentTitleText" )
> + goto error;
> + this->s_content_title = s_value;
> + break;
> + case CPL_CONTENT_KIND:
> + if( node != "ContentKind" )
> + goto error;
> + this->s_content_kind = s_value;
> + break;
> + case CPL_CONTENT_VERSION:
> + case CPL_RATING_LIST:
> + case CPL_REEL_LIST:
> + case CPL_SIGNER:
> + case CPL_SIGNATURE:
> + /* impossible */
> + break;
> + case ASSET_UNKNOWN:
> + default:
> + goto error;
> + }
> + break;
> + }
> + }
> + /* TODO verify presence of mandatory fields*/
> +
> + /* Close Ckl XML*/
> + this->CloseXml();
> + return 0;
> +error:
> + this->CloseXml();
> + return -1;
> +}
> +
> +int CPL::ParseReelList(string p_node, int p_type) {
> + string node;
> + int type;
> + Reel *p_reel;
> + cout << "CPL::ParseReelList Enter = "<< p_node << endl;
> + if (p_type != XML_READER_STARTELEM)
> + return -1;
> + if( p_node != "ReelList")
> + return -1;
> + while( ( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) {
> + cout << "CPL::ParseReelList node = "<< node << endl;
> + switch (type) {
> + case XML_READER_STARTELEM:
> + p_reel = new Reel( this->asset_list, this->p_xmlReader );
check
> + if( node =="Reel") {
> + if ( p_reel->Parse(node, type) )
> + goto error;
> + } else
> + goto error;
> + this->vec_reel.push_back(p_reel);
> +
> + break;
> + case XML_READER_TEXT:
> + /* impossible */
> + break;
> + case XML_READER_ENDELEM:
> + if ( node == p_node) {
> + goto end;
> + }
> + break;
> + }
> + }
> +end:
> + return 0;
> +error:
> + delete p_reel;
> + return -1;
> +}
> +
> +
> +int CPL::DummyParse(string p_node, int p_type)
> +{
> + string node;
> + int type;
> + bool b_stop_parse = false;
> +
> + if (p_type != XML_READER_STARTELEM)
> + return -1;
> +
> + if (xml_ReaderIsEmptyElement( this->p_xmlReader))
> + b_stop_parse = true;
> +
> + while( (! b_stop_parse) &&
> + (( type = ReadNextNode( this->p_xmlReader, node ) ) > 0 ) ) {
> + /* TODO not implemented. Just pase until end of input node */
> + if ((node == p_node) && (type = XML_READER_ENDELEM))
> + b_stop_parse = true;
> + }
> +
> + return 0;
> +}
> +
> +
> +#if 0
> +int main()
> +{
> + AssetList _asset_list;
> + AssetList::iterator itor;
> + std::cout << "# creating Asset list :" << std::endl;
> + Asset *_Asset1 = new Asset();
> + _Asset1->setId("1234");
> + _asset_list.push_back(_Asset1);
> + Asset *_Asset2 = new Asset();
> + _Asset2->setId("5678");
> + _asset_list.push_back(_Asset2);
> + cout << "Size of asset list = "<<_asset_list.size()<<endl;
> + for (itor=_asset_list.begin(); itor != _asset_list.end() ; ++itor) {
> + std::cout << "Id=" << (*itor)->getId() << std::endl;
> + }
> +}
> +#endif
dead code
> diff --git a/modules/access/dcp/dcpparser.h b/modules/access/dcp/dcpparser.h
> new file mode 100644
> index 0000000..eadc0ad
> --- /dev/null
> +++ b/modules/access/dcp/dcpparser.h
> @@ -0,0 +1,297 @@
> +/*****************************************************************************
> + * Copyright (C) 2013 VLC authors and VideoLAN
> + *
> + * Authors: Nicolas Bertrand <nico at isf.cc>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +/**
> + * @file dcpparser.h
> + * @brief Parse DCP XML files
> + */
> +
> +
> +#ifndef _DCPPARSER_H
> +#define _DCPPARSER_H
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +/* VLC core API headers */
> +#include <vlc_common.h>
> +#include <vlc_demux.h>
> +#include <vlc_plugin.h>
> +
> +#include <iostream>
> +#include <string>
> +#include <list>
> +#include <vector>
> +
> +using namespace std;
> +typedef enum {
> + TRACK_UNKNOWN = 0,
> + TRACK_PICTURE,
> + TRACK_SOUND,
> + TRACK_SUBTITLE
> +} TrackType_t;
> +
> +typedef enum {
> + XML_UNKNOWN = 0,
> + XML_ASSETMAP,
> + XML_CPL,
> + XML_PKL,
> + XML_SUB,
> +} XmlType_t;
> +
> +class AssetList;
> +class PKL;
> +
> +/*! This struct stores the most important information about the DCP */
> +struct dcp_t
> +{
> + string path; /*!< Path to DCP directory */
> +
> + vector<PKL *> pkls;
> + AssetList *p_asset_list;
> +
> + string videofile; /*!< Video file name */
> + string audiofile; /*!< Audio file name */
> +};
> +
> +
> +class XmlFile
> +{
> +public:
> + XmlFile( demux_t * p_demux, string s_path);
> +
> + virtual ~XmlFile( );
> +
> + virtual int Parse() = 0;
> +
> + bool IsCPL() { return type == XML_CPL; }
> +protected:
> + demux_t *p_demux;
> + string s_path;
> + stream_t *p_stream;
> +
> + xml_t *p_xml;
> + xml_reader_t *p_xmlReader;
> +
> + int OpenXml();
> + void CloseXml();
> +
> + XmlType_t type;
> +};
> +
> +class Chunk {
> +public:
> + Chunk();
> + int Parse(xml_reader_t *p_xmlReader, string p_node, int p_type);
> + string getPath() { return this->s_path; };
> +private:
> + string s_path;
> + int i_vol_index;
> + int i_offset;
> + int i_length;
> +};
> +
> +class Asset {
> +public:
> + /* Constructor */
> + Asset ();
> + virtual ~Asset() {};
> +
> + void setId(string p_string ) { this->s_id = p_string; };
> + void setPath(string p_string) { this->s_path = p_string; };
> + void setPackingList(bool p_bool) { this->s_path = p_bool; };
> + string getId() const { return this->s_id; } ;
> + string getPath() const { return this->s_path; };
> + string getType() const { return this->s_type; };
> +
> + bool isPackingList() const { return this->b_is_packing_list; };
> +
> + int Parse( xml_reader_t *p_xmlReader, string node, int type);
> + int ParsePKL( xml_reader_t *p_xmlReader);
> +
> + // TODO: remove
> + void Dump();
> +
> +private:
> + string s_id;
> + string s_path;
> + string s_annotation;
> + bool b_is_packing_list;
> + string s_hash;
> + uint32_t ui_size;
> + string s_type;
> + string s_original_filename;
> + TrackType_t e_track_type;
> + string s_edit_rate;
> + int i_intrisic_duration;
> + int i_entry_point;
> + int i_duration;
> + /* encryption attribute */
> + string s_key_id;
> + /* Picture attributes */
> + string s_frame_rate;
> + string s_screen_aspect_ratio;
> + /* sound and subtitle */
> + string s_language;
> +
> + demux_t *p_demux;
> + std::vector<Chunk> chunk_vec;
> +
> +
> + int parseChunkList( xml_reader_t *p_xmlReader, string p_node, int p_type);
> +
> +};
> +
> +class AssetList: public std::list<Asset *> {};
> +
> +#if 0
> +class TrackFileAsset: public Asset
> +{
> +private:
> + string s_key_id;
> +};
> +
> +class MarkerAsset: public Asset
> +{
> +
> +private:
> + std:vector<string> vec_marker;
> +};
> +
> +class PictureTrackFileAsset: public TrackFileAsset
> +{
> +
> +private:
> + string s_frame_rate;
> + string s_screen_aspect_ratio;
> +};
> +
> +class SoundTrackFileAsset: public TrackFileAsset
> +{
> +
> +private:
> + string s_language;
> +};
> +
> +class SubtitleTrackFileAsset: public TrackFileAsset
> +{
> +
> +private:
> + string s_language;
> +};
> +#endif
> +
> +
> +class Reel
> +{
> +public:
> + Reel(AssetList *asset_list, xml_reader_t *xmlReader)
> + : p_asset_list(asset_list), p_xmlReader(xmlReader)
> + {};
> + int Parse(string p_node, int p_type);
> + Asset * getTrack(TrackType_t e_track);
> +
> +private:
> + AssetList *p_asset_list;
> + xml_reader_t *p_xmlReader;
> +
> + string s_id;
> + string s_annotation;
> + Asset *p_picture_track;
> + Asset *p_sound_track;
> + Asset *p_subtitle_track;
> + int ParseAssetList(string p_node, int p_type);
> + int ParseAsset(string p_node, int p_type, TrackType_t e_track);
> +};
> +
> +class CPL : public XmlFile
> +{
> +public:
> + CPL(demux_t *, string, AssetList*);
> + virtual int Parse();
> +
> + Reel *getReel(int pos) { return this->vec_reel[pos]; } ;
> +
> +private :
> + AssetList *asset_list;
> +
> + string s_id;
> + string s_annotation;
> + string s_icon_id;
> + string s_issue_date;
> + string s_issuer;
> + string s_creator;
> + string s_content_title;
> + string s_content_kind;
> + /* TODO: ContentVersion, RatingList, signer and signature */
> +
> + std::vector<Reel *> vec_reel;
> + int DummyParse(string p_node, int p_type);
> + int ParseReelList(string p_node, int p_type);
> +};
> +
> +
> +class PKL : public XmlFile
> +{
> +public:
> + PKL ( demux_t * p_demux, string s_path, AssetList *asset_list,
> + string s_dcp_path);
> + virtual int Parse();
> +
> + int FindCPLs();
> + CPL *getCPL(int pos) { return this->vec_cpl[pos]; };
> +
> +private:
> + AssetList *asset_list;
> +
> + string s_id;
> + string s_annotation;
> + string s_issue_date;
> + string s_issuer;
> + string s_creator;
> + string s_icon_id;
> + string s_group_id;
> + string s_dcp_path;
> + std::vector<CPL *> vec_cpl;
> +
> + int ParseAssetList(string p_node, int p_type);
> + int ParseAsset(string p_node, int p_type);
> + int ParseSigner(string p_node, int p_type);
> + int ParseSignature(string p_node, int p_type);
> +
> +};
> +
> +class AssetMap : public XmlFile {
> +
> +public:
> + AssetMap( demux_t * p_demux, string s_path, dcp_t *_p_dcp)
> + : XmlFile( p_demux, s_path ), p_dcp( _p_dcp) {};
> +
> +
> + static Asset * getAssetById(AssetList*, const string p_id);
> +
> + virtual int Parse();
> +private:
> + dcp_t *p_dcp;
> +
> + int ParseAssetList (xml_reader_t *p_xmlReader, string p_node, int p_type);
> +};
> +#endif /* _DCPPARSER_H */
> --
> 1.7.9.5
Regards,
--
Denis Charmet - TypX
Le mauvais esprit est un art de vivre
More information about the vlc-devel
mailing list