You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

615 lines
25 KiB

/*
* ioxml.c
*
* Copyright (C) Marzio Malanchini - Febrary 2002
*
* This file is part of transcode, a video stream processing tool
*
* transcode is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* transcode 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "transcode.h"
#include "libtc/libtc.h"
#ifdef HAVE_LIBXML2
#include "tcinfo.h"
#include "magic.h"
#include "tc.h"
#include "ioxml.h"
#define AUDIO_VIDEO_UNKNOWN 0x00
#define AUDIO_ITEM 0x01
#define VIDEO_ITEM 0x02
#define UNSUPPORTED_PARAM 0x00
#define IN_VIDEO_CODEC 0x01
#define IN_AUDIO_CODEC 0x02
#define IN_VIDEO_MAGIC 0x03
#define IN_AUDIO_MAGIC 0x04
#define OUT_VIDEO_HEIGHT 0x05
#define OUT_VIDEO_WIDTH 0x06
#define OUT_VIDEO_RES_FILTER 0x07
audiovideo_limit_t f_det_time(char *p_options)
{
char *p_data,*p_temp,*p_temp1;
double s_hh,s_mm,s_ss,s_app;
audiovideo_limit_t s_limit;
s_hh=s_mm=s_ss=0;
s_limit.s_frame=0;
if (strcasecmp(p_options,"smpte") == 0)
s_limit.s_smpte=smpte;
else if (strcasecmp(p_options,"smpte-25") == 0)
s_limit.s_smpte=smpte25;
else if (strcasecmp(p_options,"smpte-30-drop") == 0)
s_limit.s_smpte=smpte30drop;
else if (strcasecmp(p_options,"npt") == 0)
s_limit.s_smpte=npt;
else
s_limit.s_smpte=npt;
p_data=strstr(p_options,"=");
if ((p_data != NULL) || (s_limit.s_smpte == npt))
{
if (p_data != NULL)
p_temp1=p_data+1;
else
p_temp1=p_options;
if (strstr(p_temp1,":") != NULL)
{
if ((p_temp = strtok(p_temp1,":")) != NULL)
s_hh=strtod(p_temp,NULL);
if ((p_temp = strtok(NULL,":")) != NULL)
s_mm=strtod(p_temp,NULL);
if ((p_temp = strtok(NULL,":")) != NULL)
s_ss=strtod(p_temp,NULL);
if ((p_temp = strtok(NULL,":")) != NULL)
s_limit.s_frame=strtod(p_temp,NULL);
s_limit.s_time=3600*s_hh+60*s_mm+s_ss;
}
else
{
s_app=strtod(p_temp1,NULL);
switch (*(p_temp1+strlen(p_temp1)-1)) //find the last char of temp1
{
case 'h':
s_app*=60;
case 'm':
s_app*=60;
case 's':
s_limit.s_time=(long)s_app;
s_limit.s_frame=0;
break;
default:
s_limit.s_time=0;
s_limit.s_frame=(long)s_app;
;;
}
}
}
else
{
tc_log_warn(__FILE__,"Invalid parameter %s force default",p_options);
s_limit.s_time=-1;
s_limit.s_frame=0;
}
return(s_limit);
}
void f_free_tree(audiovideo_t *p_node)
{
if (p_node) {
audiovideo_t *p_temp = NULL , *p_temp1 = NULL;
for (p_temp=p_node->p_next;p_temp !=NULL;) {
//first element is static
p_temp1 = p_temp->p_next;
free(p_temp);
p_temp=p_temp1;
}
}
}
int f_parse_tree(xmlNodePtr p_node,audiovideo_t *p_audiovideo)
{
static audiovideo_t *p_temp;
audiovideo_limit_t s_limit;
static int s_type,s_param;
int s_rc;
static int s_video_codec=TC_CODEC_UNKNOWN,s_audio_codec=TC_CODEC_UNKNOWN;
s_rc=0;
if (p_node != NULL)
{
if (xmlStrcmp(p_node->name, (const xmlChar*)"smil") == 0)
{
if(f_parse_tree(p_node->xmlChildrenNode,p_audiovideo))
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"seq") == 0)
{
s_type=AUDIO_VIDEO_UNKNOWN;
p_temp=tc_zalloc(sizeof(audiovideo_t));
p_temp->s_end_a_time=-1;
p_temp->s_end_v_time=-1;
p_temp->s_start_a_time=-1;
p_temp->s_start_v_time=-1;
p_temp->s_end_audio=-1;
p_temp->s_end_video=-1;
p_temp->s_start_audio=-1;
p_temp->s_start_video=-1;
p_temp->s_video_smpte=npt; //force npt
p_temp->s_audio_smpte=npt; //force npt
p_temp->s_a_real_codec=TC_CODEC_UNKNOWN;
p_temp->s_v_real_codec=TC_CODEC_UNKNOWN;
p_temp->s_a_codec=TC_CODEC_UNKNOWN;
p_temp->s_v_codec=TC_CODEC_UNKNOWN;
p_temp->s_a_magic=TC_MAGIC_UNKNOWN;
p_temp->s_v_magic=TC_MAGIC_UNKNOWN;
p_temp->s_a_rate=0;
p_temp->s_a_bits=0;
p_temp->s_a_chan=0;
p_temp->s_v_width=0;
p_temp->s_v_height=0;
p_temp->s_v_tg_width=0;
p_temp->s_v_tg_height=0;
p_temp->s_v_tg_width=0; //target width
p_temp->s_v_tg_height=0; //target height
if(p_audiovideo == NULL)
p_audiovideo=p_temp;
else
p_audiovideo->p_next=p_temp;
if(f_parse_tree(p_node->xmlChildrenNode,p_temp)) //visit the branch
s_rc=1;
if(f_parse_tree(p_node->next,p_temp)) //eventually go to the next seq item
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"video") == 0)
{
if (s_type!=AUDIO_VIDEO_UNKNOWN)
{
p_temp=tc_zalloc(sizeof(audiovideo_t));
p_temp->s_end_a_time=-1;
p_temp->s_end_v_time=-1;
p_temp->s_start_a_time=-1;
p_temp->s_start_v_time=-1;
p_temp->s_end_audio=-1;
p_temp->s_end_video=-1;
p_temp->s_start_audio=-1;
p_temp->s_start_video=-1;
p_temp->s_video_smpte=npt; //force npt
p_temp->s_audio_smpte=npt; //force npt
p_temp->s_a_codec=TC_CODEC_UNKNOWN;
p_temp->s_v_codec=TC_CODEC_UNKNOWN;
p_temp->s_a_real_codec=TC_CODEC_UNKNOWN;
p_temp->s_v_real_codec=TC_CODEC_UNKNOWN;
p_temp->s_a_magic=TC_MAGIC_UNKNOWN;
p_temp->s_v_magic=TC_MAGIC_UNKNOWN;
p_temp->s_a_rate=0;
p_temp->s_a_bits=0;
p_temp->s_a_chan=0;
p_temp->s_v_width=0;
p_temp->s_v_height=0;
p_temp->s_v_tg_width=0; //target width
p_temp->s_v_tg_height=0; //target height
if(p_audiovideo != NULL)
p_audiovideo->p_next=p_temp;
p_audiovideo=p_temp;
}
s_type=VIDEO_ITEM; //set origin to video
if(f_parse_tree((xmlNodePtr)p_node->properties,p_audiovideo)) //visit the properties
s_rc=1;
if(f_parse_tree(p_node->xmlChildrenNode,p_audiovideo)) //visit the branch
s_rc=1;
if(f_parse_tree(p_node->next,p_audiovideo)) //eventually go to the next audio/video item
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"audio") == 0)
{
if (s_type!=AUDIO_VIDEO_UNKNOWN)
{
p_temp=tc_zalloc(sizeof(audiovideo_t));
p_temp->s_end_a_time=-1;
p_temp->s_end_v_time=-1;
p_temp->s_start_a_time=-1;
p_temp->s_start_v_time=-1;
p_temp->s_end_audio=-1;
p_temp->s_end_video=-1;
p_temp->s_start_audio=-1;
p_temp->s_start_video=-1;
p_temp->s_video_smpte=npt; //force npt
p_temp->s_audio_smpte=npt; //force npt
p_temp->s_a_codec=TC_CODEC_UNKNOWN;
p_temp->s_v_codec=TC_CODEC_UNKNOWN;
p_temp->s_a_real_codec=TC_CODEC_UNKNOWN;
p_temp->s_v_real_codec=TC_CODEC_UNKNOWN;
p_temp->s_a_magic=TC_MAGIC_UNKNOWN;
p_temp->s_v_magic=TC_MAGIC_UNKNOWN;
p_temp->s_a_rate=0;
p_temp->s_a_bits=0;
p_temp->s_a_chan=0;
p_temp->s_v_width=0;
p_temp->s_v_height=0;
p_temp->s_v_tg_width=0; //target width
p_temp->s_v_tg_height=0; //target height
if(p_audiovideo != NULL)
p_audiovideo->p_next=p_temp;
p_audiovideo=p_temp;
}
s_type=AUDIO_ITEM; //set origin to audio
if(f_parse_tree((xmlNodePtr)p_node->properties,p_audiovideo)) //visit the properties
s_rc=1;
if(f_parse_tree(p_node->xmlChildrenNode,p_audiovideo)) //visit the branch
s_rc=1;
if(f_parse_tree(p_node->next,p_audiovideo)) //eventually go to the next audio/video item
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"param") == 0)
{
if(f_parse_tree((xmlNodePtr)p_node->properties,p_audiovideo)) //visit the properties
s_rc=1;
if(f_parse_tree(p_node->xmlChildrenNode,p_audiovideo)) //visit the branch
s_rc=1;
if(f_parse_tree(p_node->next,p_audiovideo)) //eventually go to the next audio/video item
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"src") == 0)
{
if (s_type==AUDIO_ITEM)
{
p_audiovideo->p_nome_audio=p_node->xmlChildrenNode->content; //set the audio file name
}
else
{
p_audiovideo->p_nome_video=p_node->xmlChildrenNode->content; //set the video file name
}
if(f_parse_tree(p_node->next,p_audiovideo)) //goto to begin and end of clip
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"clipBegin") == 0)
{
s_limit=f_det_time((char *)p_node->xmlChildrenNode->content);
if (s_type==AUDIO_ITEM)
{
p_audiovideo->s_audio_smpte=s_limit.s_smpte;
p_audiovideo->s_start_a_time=s_limit.s_time;
p_audiovideo->s_start_audio=s_limit.s_frame;
}
else
{
p_audiovideo->s_video_smpte=s_limit.s_smpte;
p_audiovideo->s_start_v_time=s_limit.s_time;
p_audiovideo->s_start_video=s_limit.s_frame;
}
if(f_parse_tree(p_node->next,p_audiovideo)) //goto the next param.
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"clipEnd") == 0)
{
s_limit=f_det_time((char *)p_node->xmlChildrenNode->content);
if (s_type==AUDIO_ITEM)
{
p_audiovideo->s_audio_smpte=s_limit.s_smpte;
p_audiovideo->s_end_a_time=s_limit.s_time;
p_audiovideo->s_end_audio=s_limit.s_frame+1;
}
else
{
p_audiovideo->s_video_smpte=s_limit.s_smpte;
p_audiovideo->s_end_v_time=s_limit.s_time;
p_audiovideo->s_end_video=s_limit.s_frame+1;
}
if(f_parse_tree(p_node->next,p_audiovideo)) //goto the next param.
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"name") == 0)
{
if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"in-video-module") == 0)
s_param=IN_VIDEO_MAGIC;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"in-audio-module") == 0)
s_param=IN_AUDIO_MAGIC;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"in-video-codec") == 0)
s_param=IN_VIDEO_CODEC;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"in-audio-codec") == 0)
s_param=IN_AUDIO_CODEC;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"target-height") == 0)
s_param=OUT_VIDEO_HEIGHT;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"target-width") == 0)
s_param=OUT_VIDEO_WIDTH;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"resize-filter") == 0)
s_param=OUT_VIDEO_RES_FILTER;
else
s_param=UNSUPPORTED_PARAM;
if(f_parse_tree(p_node->next,p_audiovideo)) //goto the next param.
s_rc=1;
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"value") == 0)
{
if ((s_type==AUDIO_ITEM) && ((s_param==IN_VIDEO_CODEC)||(s_param==IN_VIDEO_MAGIC)||(s_param==OUT_VIDEO_HEIGHT)||(s_param==OUT_VIDEO_WIDTH)))
{
if (s_param==OUT_VIDEO_HEIGHT)
tc_log_warn(__FILE__,"The target-height parameter cannot be used in audio item, %s skipped.",(char *)p_node->xmlChildrenNode->content);
else if (s_param==OUT_VIDEO_WIDTH)
tc_log_warn(__FILE__,"The target-width parameter cannot be used in audio item, %s skipped.",(char *)p_node->xmlChildrenNode->content);
else if (s_param==IN_VIDEO_MAGIC)
tc_log_warn(__FILE__,"The in-video-module parameter cannot be used in audio item, %s skipped.",(char *)p_node->xmlChildrenNode->content);
else if (s_param==IN_VIDEO_CODEC)
tc_log_warn(__FILE__,"The in-video-codec parameter cannot be used in audio item, %s skipped.",(char *)p_node->xmlChildrenNode->content);
s_rc=1;
}
else
{
switch(s_param)
{
case OUT_VIDEO_RES_FILTER:
p_audiovideo->p_v_resize_filter=p_node->xmlChildrenNode->content;
break;
case OUT_VIDEO_HEIGHT:
p_audiovideo->s_v_tg_height=atoi((char *)p_node->xmlChildrenNode->content);
break;
case OUT_VIDEO_WIDTH:
p_audiovideo->s_v_tg_width=atoi((char *)p_node->xmlChildrenNode->content);
break;
case IN_VIDEO_MAGIC:
if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"dv") == 0)
p_audiovideo->s_v_magic=TC_MAGIC_DV_PAL; //the same for PAL and NTSC
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"avi") == 0)
p_audiovideo->s_v_magic=TC_MAGIC_AVI;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"mov") == 0)
p_audiovideo->s_v_magic=TC_MAGIC_AVI;
else
{
tc_log_warn(__FILE__,"The in-video-magic %s parameter isn't yet supported.",(char *)p_node->xmlChildrenNode->content);
s_rc=1;
}
break;
case IN_AUDIO_MAGIC:
if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"dv") == 0)
p_audiovideo->s_a_magic=TC_MAGIC_DV_PAL; //the same for PAL and NTSC
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"avi") == 0)
p_audiovideo->s_a_magic=TC_MAGIC_AVI;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"mov") == 0)
p_audiovideo->s_a_magic=TC_MAGIC_AVI;
else
{
tc_log_warn(__FILE__,"The in-audio-magic %s parameter isn't yet supported.",(char *)p_node->xmlChildrenNode->content);
s_rc=1;
}
break;
case IN_VIDEO_CODEC:
if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"rgb") == 0)
p_audiovideo->s_v_codec=CODEC_RGB;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"yuv2") == 0)
p_audiovideo->s_v_codec=CODEC_YUV;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"yuv420p") == 0)
p_audiovideo->s_v_codec=CODEC_YUV;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"yv12") == 0)
p_audiovideo->s_v_codec=CODEC_YUV;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"yuy2") == 0)
p_audiovideo->s_v_codec=CODEC_YUY2;
else if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"raw") == 0)
p_audiovideo->s_v_codec=CODEC_RAW;
else
{
tc_log_warn(__FILE__,"The in-video-codec %s parameter isn't yet supported.",(char *)p_node->xmlChildrenNode->content);
s_rc=1;
}
if (s_video_codec == TC_CODEC_UNKNOWN)
s_video_codec=p_audiovideo->s_v_codec;
else if (s_video_codec != p_audiovideo->s_v_codec)
{
tc_log_warn(__FILE__,"The XML file must contain the same video codec.");
s_rc=1;
}
break;
case IN_AUDIO_CODEC:
if (xmlStrcmp((char *)p_node->xmlChildrenNode->content, (const xmlChar*)"pcm") == 0)
p_audiovideo->s_a_codec=CODEC_PCM;
else
{
tc_log_warn(__FILE__,"The in-audio-codec %s parameter isn't yet supported.",(char *)p_node->xmlChildrenNode->content);
s_rc=1;
}
if (s_audio_codec == TC_CODEC_UNKNOWN)
s_audio_codec=p_audiovideo->s_a_codec;
else if (s_audio_codec != p_audiovideo->s_a_codec)
{
tc_log_warn(__FILE__,"The XML file must contain the same audio codec.");
s_rc=1;
}
break;
case UNSUPPORTED_PARAM:
tc_log_warn(__FILE__,"The %s parameter isn't yet supported.",(char *)p_node->xmlChildrenNode->content);
s_rc=1;
break;
}
}
if(f_parse_tree(p_node->next,p_audiovideo)) //goto the next param.
s_rc=1;
}
}
return(s_rc);
}
void f_delete_unused_node(xmlNodePtr p_node)
{
while (p_node != NULL)
{
xmlNodePtr p_kill_node = NULL;
f_delete_unused_node(p_node->xmlChildrenNode);
if (xmlStrcmp(p_node->name, (const xmlChar*)"smil") == 0)
{
//leave it in the tree
}
else if (xmlStrcmp(p_node->name, (const xmlChar*)"seq") == 0)
{
if (p_node->xmlChildrenNode == NULL)
{
//This node don't have any video sections so i can kill it
p_kill_node = p_node;
}
}
else if ((xmlStrcmp(p_node->name, (const xmlChar*)"param") == 0) ||(xmlStrcmp(p_node->name, (const xmlChar*)"video") == 0) || (xmlStrcmp(p_node->name, (const xmlChar*)"audio") == 0))
{
//leave it in the tree
}
else
{
//not an interesting node
p_kill_node = p_node;
}
p_node = p_node->next;
if (p_kill_node != NULL)
{
//kill the node from the tree
xmlUnlinkNode(p_kill_node);
xmlFreeNode(p_kill_node);
}
}
}
int f_complete_tree(audiovideo_t *p_audiovideo)
{
audiovideo_t *p_temp;
int s_video_codec=TC_CODEC_UNKNOWN,s_audio_codec=TC_CODEC_UNKNOWN;
for (p_temp=p_audiovideo->p_next;p_temp != NULL;p_temp=p_temp->p_next)
{
if (p_temp->p_nome_video != NULL)
{
if (p_temp->s_start_v_time == -1)
{
p_temp->s_start_video=0;
p_temp->s_start_v_time=0;
}
if (p_temp->s_end_v_time == -1)
{
p_temp->s_end_video=LONG_MAX;
p_temp->s_end_v_time=0;
}
if (p_audiovideo->s_v_codec != TC_CODEC_UNKNOWN)
{
if ((s_video_codec!=TC_CODEC_UNKNOWN) && (p_audiovideo->s_v_codec != s_video_codec))
{
tc_log_error(__FILE__,"The file must contain the same video codec (found 0x%lx but 0x%x is already defined)",p_audiovideo->s_v_codec,s_video_codec);
return(1);
}
s_video_codec=p_audiovideo->s_v_codec;
}
}
if (p_temp->p_nome_audio != NULL)
{
if (p_temp->s_start_a_time == -1)
{
p_temp->s_start_audio=0;
p_temp->s_start_a_time=0;
}
if (p_temp->s_end_a_time == -1)
{
p_temp->s_end_audio=LONG_MAX;
p_temp->s_end_a_time=0;
}
if (p_audiovideo->s_a_codec != TC_CODEC_UNKNOWN)
{
if ((s_audio_codec!=TC_CODEC_UNKNOWN) && (p_audiovideo->s_a_codec != s_audio_codec))
{
tc_log_error(__FILE__,"The file must contain the same audio codec (found 0x%lx but 0x%x is already defined)",p_audiovideo->s_a_codec,s_audio_codec);
return(1);
}
s_audio_codec=p_audiovideo->s_a_codec;
}
}
else
{
p_temp->p_nome_audio=p_temp->p_nome_video; //force audio to has the same input file of video
p_temp->s_start_audio=p_temp->s_start_video;
p_temp->s_end_audio=p_temp->s_end_video;
p_temp->s_end_a_time=p_temp->s_end_v_time;
p_temp->s_start_a_time=p_temp->s_start_v_time;
}
}
for (p_temp=p_audiovideo->p_next;p_temp != NULL;p_temp=p_temp->p_next) //initialize all unset codec
{
if (p_temp->p_nome_video != NULL)
p_audiovideo->s_v_codec=s_video_codec;
if (p_temp->p_nome_audio != NULL)
p_audiovideo->s_a_codec=s_audio_codec;
}
return(0);
}
int f_manage_input_xml(const char *p_name,int s_type,audiovideo_t *p_audiovideo)
{
static xmlDocPtr p_doc;
xmlNodePtr p_node;
xmlNsPtr ns;
if (s_type) //read the file from p_name
{
p_doc = xmlParseFile(p_name);
p_node = xmlDocGetRootElement(p_doc);
if (p_node == NULL)
{
xmlFreeDoc(p_doc);
tc_log_error(__FILE__,"Invalid file format");
return(-1);
}
ns = xmlSearchNsByHref(p_doc, p_node, (const xmlChar *) "http://www.w3.org/2001/SMIL20/Language");
if (ns == NULL)
{
xmlFreeDoc(p_doc);
tc_log_error(__FILE__,"Invalid Namespace");
return(-1);
}
ns = xmlSearchNs(p_doc, p_node, (const xmlChar *) "smil2");
if (ns == NULL)
{
xmlFreeDoc(p_doc);
tc_log_error(__FILE__,"Invalid Namespace");
return(-1);
}
if (xmlStrcmp(p_node->name, (const xmlChar *) "smil"))
{
xmlFreeDoc(p_doc);
tc_log_error(__FILE__,"Invalid Namespace");
return(-1);
}
f_delete_unused_node(p_node);
memset(p_audiovideo,'\0',sizeof(audiovideo_t));
if(f_parse_tree(p_node,p_audiovideo))
return(1);
if (f_complete_tree(p_audiovideo))
return(1);
}
else
{
f_free_tree(p_audiovideo);
xmlFreeDoc(p_doc);
}
return(0);
}
#endif