in src/media_tools/media_import.c [3107:3795]
GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc)
{
GF_Err e;
GF_DIMSDescription dims;
Bool destroy_esd, inRootOD, do_compress, use_dict, is_dims;
u32 i, track, tkID, di, mtype, max_size, count, streamType, oti, timescale, specInfoSize, header_end, dts_inc, par_den, par_num;
GF_ISOSample *samp;
GF_XMLAttribute *att;
s64 media_size, media_done, offset;
u64 duration, sample_duration;
FILE *nhml, *mdia, *info;
char *dictionary = NULL;
char *ext, szName[1000], szMedia[1000], szMediaTemp[1000], szInfo[1000], szXmlFrom[1000], szXmlTo[1000], szXmlHeaderEnd[1000];
char *specInfo;
GF_GenericSampleDescription sdesc;
GF_DOMParser *parser;
GF_XMLNode *root, *node, *childnode;
char *szRootName, *szSampleName, *szImpName;
szRootName = dims_doc ? "DIMSStream" : "NHNTStream";
szSampleName = dims_doc ? "DIMSUnit" : "NHNTSample";
szImpName = dims_doc ? "DIMS" : "NHML";
if (import->flags & GF_IMPORT_PROBE_ONLY) {
import->nb_tracks = 1;
import->tk_info[0].track_num = 1;
import->tk_info[0].type = 0;
import->tk_info[0].flags = GF_IMPORT_USE_DATAREF;
return GF_OK;
}
nhml = gf_fopen(import->in_name, "rt");
if (!nhml) return gf_import_message(import, GF_URL_ERROR, "Cannot find %s file %s", szImpName, import->in_name);
strcpy(szName, import->in_name);
ext = strrchr(szName, '.');
if (ext) ext[0] = 0;
strcpy(szMedia, szName);
strcat(szMedia, ".media");
strcpy(szInfo, szName);
strcat(szInfo, ".info");
parser = gf_xml_dom_new();
e = gf_xml_dom_parse(parser, import->in_name, nhml_on_progress, import);
if (e) {
gf_fclose(nhml);
gf_import_message(import, e, "Error parsing %s file: Line %d - %s", szImpName, gf_xml_dom_get_line(parser), gf_xml_dom_get_error(parser));
gf_xml_dom_del(parser);
return e;
}
root = gf_xml_dom_get_root(parser);
if (!root) {
e = gf_import_message(import, GF_BAD_PARAM, "Error parsing %s file - no root node found", szImpName);
gf_xml_dom_del(parser);
return e;
}
mdia = NULL;
destroy_esd = GF_FALSE;
dts_inc = 0;
inRootOD = GF_FALSE;
do_compress = GF_FALSE;
is_dims = GF_FALSE;
specInfo = NULL;
samp = NULL;
memset(&dims, 0, sizeof(GF_DIMSDescription));
dims.profile = dims.level = 255;
dims.streamType = GF_TRUE;
dims.containsRedundant = 1;
if (stricmp(root->name, szRootName)) {
e = gf_import_message(import, GF_BAD_PARAM, "Error parsing %s file - \"%s\" root expected, got \"%s\"", szImpName, szRootName, root->name);
goto exit;
}
use_dict = GF_FALSE;
memset(&sdesc, 0, sizeof(GF_GenericSampleDescription));
tkID = mtype = streamType = oti = par_den = par_num = 0;
timescale = 1000;
i=0;
strcpy(szXmlHeaderEnd, "");
header_end = 0;
while ((att = (GF_XMLAttribute *)gf_list_enum(root->attributes, &i))) {
if (!stricmp(att->name, "streamType")) {
NHML_SCAN_INT("%u", streamType)
} else if (!stricmp(att->name, "mediaType") && (strlen(att->value)==4)) {
mtype = GF_4CC(att->value[0], att->value[1], att->value[2], att->value[3]);
} else if (!stricmp(att->name, "mediaSubType") && (strlen(att->value)==4)) {
sdesc.codec_tag = GF_4CC(att->value[0], att->value[1], att->value[2], att->value[3]);
} else if (!stricmp(att->name, "objectTypeIndication")) {
NHML_SCAN_INT("%u", oti)
} else if (!stricmp(att->name, "timeScale")) {
NHML_SCAN_INT("%u", timescale)
} else if (!stricmp(att->name, "width")) {
NHML_SCAN_INT("%hu", sdesc.width)
} else if (!stricmp(att->name, "height")) {
NHML_SCAN_INT("%hu", sdesc.height)
} else if (!stricmp(att->name, "parNum")) {
NHML_SCAN_INT("%u", par_num)
} else if (!stricmp(att->name, "parDen")) {
NHML_SCAN_INT("%u", par_den)
} else if (!stricmp(att->name, "sampleRate")) {
NHML_SCAN_INT("%u", sdesc.samplerate)
} else if (!stricmp(att->name, "numChannels")) {
NHML_SCAN_INT("%hu", sdesc.nb_channels)
} else if (!stricmp(att->name, "baseMediaFile")) {
strcpy(szMedia, att->value);
} else if (!stricmp(att->name, "specificInfoFile")) {
strcpy(szInfo, att->value);
} else if (!stricmp(att->name, "headerEnd")) {
NHML_SCAN_INT("%u", header_end)
} else if (!stricmp(att->name, "trackID")) {
NHML_SCAN_INT("%u", tkID)
} else if (!stricmp(att->name, "inRootOD")) {
inRootOD = (!stricmp(att->value, "yes") );
} else if (!stricmp(att->name, "DTS_increment")) {
NHML_SCAN_INT("%u", dts_inc)
} else if (!stricmp(att->name, "gzipSamples")) {
do_compress = (!stricmp(att->value, "yes")) ? GF_TRUE : GF_FALSE;
} else if (!stricmp(att->name, "gzipDictionary")) {
u64 d_size;
if (stricmp(att->value, "self")) {
FILE *d = gf_fopen(att->value, "rb");
if (!d) {
gf_import_message(import, GF_IO_ERR, "Cannot open dictionary file %s", att->value);
continue;
}
gf_fseek(d, 0, SEEK_END);
d_size = gf_ftell(d);
dictionary = (char*)gf_malloc(sizeof(char)*(size_t)(d_size+1));
gf_fseek(d, 0, SEEK_SET);
d_size = fread(dictionary, sizeof(char), (size_t)d_size, d);
dictionary[d_size]=0;
}
use_dict = GF_TRUE;
}
/*unknow desc related*/
else if (!stricmp(att->name, "compressorName")) {
strcpy(sdesc.compressor_name, att->value);
} else if (!stricmp(att->name, "codecVersion")) {
NHML_SCAN_INT("%hu", sdesc.version)
} else if (!stricmp(att->name, "codecRevision")) {
NHML_SCAN_INT("%hu", sdesc.revision)
} else if (!stricmp(att->name, "codecVendor") && (strlen(att->value)==4)) {
sdesc.vendor_code = GF_4CC(att->value[0], att->value[1], att->value[2], att->value[3]);
} else if (!stricmp(att->name, "temporalQuality")) {
NHML_SCAN_INT("%u", sdesc.temporal_quality)
} else if (!stricmp(att->name, "spatialQuality")) {
NHML_SCAN_INT("%u", sdesc.spatial_quality)
} else if (!stricmp(att->name, "horizontalResolution")) {
NHML_SCAN_INT("%u", sdesc.h_res)
} else if (!stricmp(att->name, "verticalResolution")) {
NHML_SCAN_INT("%u", sdesc.v_res)
} else if (!stricmp(att->name, "bitDepth")) {
NHML_SCAN_INT("%hu", sdesc.depth)
} else if (!stricmp(att->name, "bitsPerSample")) {
NHML_SCAN_INT("%hu", sdesc.bits_per_sample)
}
/*DIMS stuff*/
else if (!stricmp(att->name, "profile")) {
NHML_SCAN_INT("%c", dims.profile)
} else if (!stricmp(att->name, "level")) {
NHML_SCAN_INT("%c", dims.level)
} else if (!stricmp(att->name, "pathComponents")) {
NHML_SCAN_INT("%c", dims.pathComponents)
} else if (!stricmp(att->name, "useFullRequestHost") && !stricmp(att->value, "yes")) {
dims.fullRequestHost = GF_TRUE;
} else if (!stricmp(att->name, "stream_type") && !stricmp(att->value, "secondary")) {
dims.streamType = GF_FALSE;
} else if (!stricmp(att->name, "contains_redundant")) {
if (!stricmp(att->value, "main")) {
dims.containsRedundant = 1;
} else if (!stricmp(att->value, "redundant")) {
dims.containsRedundant = 2;
} else if (!stricmp(att->value, "main+redundant")) {
dims.containsRedundant = 3;
}
} else if (!stricmp(att->name, "text_encoding")) {
dims.textEncoding = att->value;
} else if (!stricmp(att->name, "content_encoding")) {
if (!strcmp(att->value, "deflate")) {
dims.contentEncoding = att->value;
do_compress = GF_TRUE;
}
} else if (!stricmp(att->name, "content_script_types")) {
dims.content_script_types = att->value;
} else if (!stricmp(att->name, "mime_type")) {
dims.mime_type = att->value;
} else if (!stricmp(att->name, "media_namespace")) {
dims.mime_type = att->value;
} else if (!stricmp(att->name, "media_schema_location")) {
dims.xml_schema_loc = att->value;
} else if (!stricmp(att->name, "xml_namespace")) {
dims.mime_type = att->value;
} else if (!stricmp(att->name, "xml_schema_location")) {
dims.xml_schema_loc = att->value;
} else if (!stricmp(att->name, "xmlHeaderEnd")) {
strcpy(szXmlHeaderEnd, att->value);
}
}
if (sdesc.samplerate && !timescale) {
timescale = sdesc.samplerate;
}
if (!sdesc.bits_per_sample) {
sdesc.bits_per_sample = 16;
}
if (dims_doc || (sdesc.codec_tag==GF_ISOM_SUBTYPE_3GP_DIMS)) {
mtype = GF_ISOM_MEDIA_DIMS;
sdesc.codec_tag=GF_ISOM_SUBTYPE_3GP_DIMS;
is_dims = GF_TRUE;
streamType = 0;
import->flags &= ~GF_IMPORT_USE_DATAREF;
}
mdia = gf_fopen(szMedia, "rb");
specInfoSize = 0;
if (!streamType && !mtype && !sdesc.codec_tag) {
e = gf_import_message(import, GF_NOT_SUPPORTED, "Error parsing %s file - StreamType or MediaType not specified", szImpName);
goto exit;
}
info = gf_fopen(szInfo, "rb");
if (info) {
gf_fseek(info, 0, SEEK_END);
specInfoSize = (u32) gf_ftell(info);
specInfo = (char*)gf_malloc(sizeof(char) * specInfoSize);
gf_fseek(info, 0, SEEK_SET);
specInfoSize = (u32) fread(specInfo, sizeof(char), specInfoSize, info);
gf_fclose(info);
} else if (header_end) {
/* for text based streams, the decoder specific info can be at the beginning of the file */
specInfoSize = header_end;
specInfo = (char*)gf_malloc(sizeof(char) * (specInfoSize+1));
specInfoSize = (u32) fread(specInfo, sizeof(char), specInfoSize, mdia);
specInfo[specInfoSize] = 0;
header_end = specInfoSize;
} else if (strlen(szXmlHeaderEnd)) {
/* for XML based streams, the decoder specific info can be up to some element in the file */
samp = gf_isom_sample_new();
max_size = 0;
strcpy(szXmlFrom, "doc.start");
e = gf_import_sample_from_xml(import, samp, szMedia, szXmlFrom, szXmlHeaderEnd, &max_size);
if (e) {
gf_isom_sample_del(&samp);
goto exit;
}
specInfo = (char*)gf_malloc(sizeof(char) * (samp->dataLength+1));
memcpy(specInfo, samp->data, samp->dataLength);
specInfoSize = samp->dataLength;
specInfo[specInfoSize] = 0;
gf_isom_sample_del(&samp);
}
i=0;
while ((node = (GF_XMLNode *) gf_list_enum(root->content, &i))) {
if (node->type) continue;
if (stricmp(node->name, "DecoderSpecificInfo") ) continue;
e = gf_xml_parse_bit_sequence(node, &specInfo, &specInfoSize);
break;
}
/*compressing samples, remove data ref*/
if (do_compress) import->flags &= ~GF_IMPORT_USE_DATAREF;
if (streamType) {
if (!import->esd) {
import->esd = gf_odf_desc_esd_new(2);
destroy_esd = GF_TRUE;
import->esd->ESID = tkID;
}
/*update stream type/oti*/
if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG);
if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
import->esd->decoderConfig->streamType = streamType;
import->esd->decoderConfig->objectTypeIndication = oti;
if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo);
import->esd->decoderConfig->decoderSpecificInfo = NULL;
import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);
import->esd->decoderConfig->decoderSpecificInfo->dataLength = specInfoSize;
import->esd->decoderConfig->decoderSpecificInfo->data = specInfo;
specInfo = NULL;
specInfoSize = 0;
import->esd->slConfig->timestampResolution = timescale;
switch (import->esd->decoderConfig->streamType) {
case GF_STREAM_SCENE:
mtype = GF_ISOM_MEDIA_SCENE;
break;
case GF_STREAM_VISUAL:
mtype = GF_ISOM_MEDIA_VISUAL;
#ifndef GPAC_DISABLE_AV_PARSERS
if (import->esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) {
GF_M4VDecSpecInfo dsi;
if (!import->esd->decoderConfig->decoderSpecificInfo) {
e = GF_NON_COMPLIANT_BITSTREAM;
goto exit;
}
e = gf_m4v_get_config(import->esd->decoderConfig->decoderSpecificInfo->data, import->esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);
sdesc.width = dsi.width;
sdesc.height = dsi.height;
if (e) goto exit;
}
#endif
break;
case GF_STREAM_AUDIO:
mtype = GF_ISOM_MEDIA_AUDIO;
if (!sdesc.samplerate) sdesc.samplerate = 44100;
if (!sdesc.nb_channels) sdesc.nb_channels = 2;
break;
case GF_STREAM_MPEG7:
mtype = GF_ISOM_MEDIA_MPEG7;
break;
case GF_STREAM_IPMP:
mtype = GF_ISOM_MEDIA_IPMP;
break;
case GF_STREAM_OCI:
mtype = GF_ISOM_MEDIA_OCI;
break;
case GF_STREAM_MPEGJ:
mtype = GF_ISOM_MEDIA_MPEGJ;
break;
/*note we cannot import OD from NHNT*/
case GF_STREAM_OD:
e = GF_NOT_SUPPORTED;
goto exit;
case GF_STREAM_INTERACT:
mtype = GF_ISOM_MEDIA_SCENE;
break;
default:
if (!mtype) mtype = GF_ISOM_MEDIA_ESM;
break;
}
track = gf_isom_new_track(import->dest, import->esd->ESID, mtype, timescale);
if (!track) {
e = gf_isom_last_error(import->dest);
goto exit;
}
e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? szMedia : NULL, NULL, &di);
if (e) goto exit;
gf_import_message(import, GF_OK, "NHML import - Stream Type %s - ObjectTypeIndication 0x%02x", gf_odf_stream_type_name(import->esd->decoderConfig->streamType), import->esd->decoderConfig->objectTypeIndication);
} else if (is_dims) {
track = gf_isom_new_track(import->dest, tkID, mtype, timescale);
if (!track) {
e = gf_isom_last_error(import->dest);
goto exit;
}
e = gf_isom_new_dims_description(import->dest, track, &dims, NULL, NULL, &di);
if (e) goto exit;
gf_import_message(import, GF_OK, "3GPP DIMS import");
} else if (mtype == GF_ISOM_MEDIA_MPEG_SUBT || mtype == GF_ISOM_MEDIA_SUBT || mtype == GF_ISOM_MEDIA_TEXT) {
track = gf_isom_new_track(import->dest, tkID, mtype, timescale);
if (!track) {
e = gf_isom_last_error(import->dest);
goto exit;
}
if(sdesc.codec_tag == GF_ISOM_SUBTYPE_STPP) {
e = gf_isom_new_xml_subtitle_description(import->dest, track,
dims.mime_type, dims.xml_schema_loc, NULL,
&di);
} else if (sdesc.codec_tag == GF_ISOM_SUBTYPE_SBTT) {
e = gf_isom_new_stxt_description(import->dest, track, GF_ISOM_SUBTYPE_SBTT,
dims.mime_type, dims.textEncoding, specInfo,
&di);
} else if (sdesc.codec_tag == GF_ISOM_SUBTYPE_STXT) {
e = gf_isom_new_stxt_description(import->dest, track, GF_ISOM_SUBTYPE_STXT,
dims.mime_type, dims.textEncoding, specInfo,
&di);
} else {
e = GF_NOT_SUPPORTED;
}
if (e) goto exit;
} else if (mtype == GF_ISOM_MEDIA_META) {
track = gf_isom_new_track(import->dest, tkID, mtype, timescale);
if (!track) {
e = gf_isom_last_error(import->dest);
goto exit;
}
if(sdesc.codec_tag == GF_ISOM_SUBTYPE_METX) {
e = gf_isom_new_xml_metadata_description(import->dest, track,
dims.mime_type, dims.xml_schema_loc, dims.textEncoding,
&di);
} else if (sdesc.codec_tag == GF_ISOM_SUBTYPE_METT) {
e = gf_isom_new_stxt_description(import->dest, track, GF_ISOM_SUBTYPE_METT,
dims.mime_type, dims.textEncoding, specInfo,
&di);
} else {
e = GF_NOT_SUPPORTED;
}
if (e) goto exit;
} else {
char szT[5];
sdesc.extension_buf = specInfo;
sdesc.extension_buf_size = specInfoSize;
if (!sdesc.vendor_code) sdesc.vendor_code = GF_4CC('G', 'P', 'A', 'C');
track = gf_isom_new_track(import->dest, tkID, mtype, timescale);
if (!track) {
e = gf_isom_last_error(import->dest);
goto exit;
}
e = gf_isom_new_generic_sample_description(import->dest, track, (import->flags & GF_IMPORT_USE_DATAREF) ? szMedia : NULL, NULL, &sdesc, &di);
if (e) goto exit;
strcpy(szT, gf_4cc_to_str(mtype));
gf_import_message(import, GF_OK, "NHML import - MediaType \"%s\" - SubType \"%s\"", szT, gf_4cc_to_str(sdesc.codec_tag));
}
gf_isom_set_track_enabled(import->dest, track, 1);
import->final_trackID = gf_isom_get_track_id(import->dest, track);
if (import->esd && !import->esd->ESID) import->esd->ESID = import->final_trackID;
if (sdesc.width && sdesc.height) {
gf_isom_set_visual_info(import->dest, track, di, sdesc.width, sdesc.height);
if (par_den && par_num) {
gf_media_change_par(import->dest, track, par_num, par_den);
} else {
gf_media_update_par(import->dest, track);
}
}
else if (sdesc.samplerate && sdesc.nb_channels) {
gf_isom_set_audio_info(import->dest, track, di, sdesc.samplerate, sdesc.nb_channels, (u8) sdesc.bits_per_sample);
}
duration = (u64) ( ((Double) import->duration)/ 1000 * timescale);
samp = gf_isom_sample_new();
samp->data = (char*)gf_malloc(sizeof(char) * 1024);
max_size = 1024;
count = 0;
media_size = 0;
if (mdia) {
gf_fseek(mdia, 0, SEEK_END);
media_size = gf_ftell(mdia);
gf_fseek(mdia, 0, SEEK_SET);
}
/* if we've read the header from the same file, mark the header data as used */
media_done = header_end;
samp->IsRAP = RAP;
i=0;
while ((node = (GF_XMLNode *) gf_list_enum(root->content, &i))) {
u32 j, dims_flags;
Bool append, compress, has_subbs;
if (node->type) continue;
if (stricmp(node->name, szSampleName) ) continue;
strcpy(szMediaTemp, "");
strcpy(szXmlFrom, "");
strcpy(szXmlTo, "");
/*by default handle all samples as contigous*/
offset = 0;
samp->dataLength = 0;
dims_flags = 0;
append = GF_FALSE;
compress = do_compress;
sample_duration = 0;
j=0;
while ( (att = (GF_XMLAttribute *)gf_list_enum(node->attributes, &j))) {
if (!stricmp(att->name, "DTS") || !stricmp(att->name, "time")) {
u32 h, m, s, ms;
u64 dst_val;
if (strchr(att->value, ':') && sscanf(att->value, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) {
samp->DTS = (u64) ( (Double) ( ((h*3600.0 + m*60.0 + s)*1000 + ms) / 1000.0) * timescale );
} else if (sscanf(att->value, ""LLU, &dst_val)==1) {
samp->DTS = dst_val;
}
}
else if (!stricmp(att->name, "CTSOffset")) samp->CTS_Offset = atoi(att->value);
else if (!stricmp(att->name, "isRAP") && !samp->IsRAP) {
samp->IsRAP = (!stricmp(att->value, "yes")) ? RAP : RAP_NO;
}
else if (!stricmp(att->name, "isSyncShadow")) samp->IsRAP = !stricmp(att->value, "yes") ? RAP_REDUNDANT : RAP_NO;
else if (!stricmp(att->name, "mediaOffset")) offset = (s64) atof(att->value) ;
else if (!stricmp(att->name, "dataLength")) samp->dataLength = atoi(att->value);
else if (!stricmp(att->name, "mediaFile")) strcpy(szMediaTemp, att->value);
else if (!stricmp(att->name, "xmlFrom")) strcpy(szXmlFrom, att->value);
else if (!stricmp(att->name, "xmlTo")) strcpy(szXmlTo, att->value);
/*DIMS flags*/
else if (!stricmp(att->name, "is-Scene") && !stricmp(att->value, "yes"))
dims_flags |= GF_DIMS_UNIT_S;
else if (!stricmp(att->name, "is-RAP") && !stricmp(att->value, "yes")) {
dims_flags |= GF_DIMS_UNIT_M;
samp->IsRAP = RAP;
}
else if (!stricmp(att->name, "is-redundant") && !stricmp(att->value, "yes"))
dims_flags |= GF_DIMS_UNIT_I;
else if (!stricmp(att->name, "redundant-exit") && !stricmp(att->value, "yes"))
dims_flags |= GF_DIMS_UNIT_D;
else if (!stricmp(att->name, "priority") && !stricmp(att->value, "high"))
dims_flags |= GF_DIMS_UNIT_P;
else if (!stricmp(att->name, "compress") && !stricmp(att->value, "yes"))
dims_flags |= GF_DIMS_UNIT_C;
else if (!stricmp(att->name, "duration") )
sscanf(att->value, ""LLU, &sample_duration);
}
if (samp->IsRAP==RAP)
dims_flags |= GF_DIMS_UNIT_M;
if (!count && samp->DTS) samp->DTS = 0;
if (!(dims_flags & GF_DIMS_UNIT_C)) compress = GF_FALSE;
count++;
has_subbs = GF_FALSE;
j=0;
while ((childnode = (GF_XMLNode *) gf_list_enum(node->content, &j))) {
if (childnode->type) continue;
if (stricmp(childnode->name, "BS") ) continue;
has_subbs = GF_TRUE;
break;
}
if (import->flags & GF_IMPORT_USE_DATAREF) {
if (offset) offset = media_done;
e = gf_isom_add_sample_reference(import->dest, track, di, samp, offset);
} else if (strlen(szXmlFrom) && strlen(szXmlTo)) {
char *xml_file;
if (strlen(szMediaTemp)) xml_file = szMediaTemp;
else xml_file = szMedia;
samp->dataLength = max_size;
e = gf_import_sample_from_xml(import, samp, xml_file, szXmlFrom, szXmlTo, &max_size);
} else if (is_dims && !strlen(szMediaTemp)) {
GF_BitStream *bs;
char *content = gf_xml_dom_serialize(node, GF_TRUE);
samp->dataLength = 3 + (u32) strlen(content);
if (samp->dataLength>max_size) {
samp->data = (char*)gf_realloc(samp->data, sizeof(char) * samp->dataLength);
max_size = samp->dataLength;
}
bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_WRITE);
gf_bs_write_u16(bs, samp->dataLength-2);
gf_bs_write_u8(bs, (u8) dims_flags);
gf_bs_write_data(bs, content, (samp->dataLength-3));
gf_free(content);
gf_bs_del(bs);
/*same DIMS unit*/
if (gf_isom_get_sample_from_dts(import->dest, track, samp->DTS))
append = GF_TRUE;
} else if (has_subbs) {
if (samp->data) gf_free(samp->data );
samp->data = 0;
samp->dataLength = 0;
e = gf_xml_parse_bit_sequence(node, &samp->data, &samp->dataLength);
max_size = samp->dataLength;
} else {
Bool close = GF_FALSE;
FILE *f = mdia;
if (strlen(szMediaTemp)) {
f = gf_fopen(szMediaTemp, "rb");
close = GF_TRUE;
if (offset) gf_fseek(f, offset, SEEK_SET);
} else {
if (!offset) offset = media_done;
}
if (!f) {
e = gf_import_message(import, GF_BAD_PARAM, "%s import failure: file %s not found", szImpName, close ? szMediaTemp : szMedia);
goto exit;
}
if (!samp->dataLength) {
u64 cur_pos = gf_ftell(f);
gf_fseek(f, 0, SEEK_END);
assert(gf_ftell(f) < 1<<31);
samp->dataLength = (u32) gf_ftell(f);
gf_fseek(f, cur_pos, SEEK_SET);
}
gf_fseek(f, offset, SEEK_SET);
if (is_dims) {
GF_BitStream *bs;
if (samp->dataLength+3>max_size) {
samp->data = (char*)gf_realloc(samp->data, sizeof(char) * (samp->dataLength+3));
max_size = samp->dataLength+3;
}
bs = gf_bs_new(samp->data, samp->dataLength+3, GF_BITSTREAM_WRITE);
gf_bs_write_u16(bs, samp->dataLength+1);
gf_bs_write_u8(bs, (u8) dims_flags);
if (samp->dataLength != fread( samp->data+3, sizeof(char), samp->dataLength, f)) {
GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[NHML import dims] Failed to fully read samp->dataLength\n"));
}
gf_bs_del(bs);
samp->dataLength+=3;
/*same DIMS unit*/
if (gf_isom_get_sample_from_dts(import->dest, track, samp->DTS))
append = GF_TRUE;
} else {
if (samp->dataLength>max_size) {
samp->data = (char*)gf_realloc(samp->data, sizeof(char) * samp->dataLength);
max_size = samp->dataLength;
}
if (samp->dataLength != fread( samp->data, sizeof(char), samp->dataLength, f)) {
GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[NHML import] Failed to fully read samp->dataLength\n"));
}
}
if (close) gf_fclose(f);
}
if (e) goto exit;
if (is_dims) {
if (strstr(samp->data+3, "svg ")) dims_flags |= GF_DIMS_UNIT_S;
if (dims_flags & GF_DIMS_UNIT_S) dims_flags |= GF_DIMS_UNIT_P;
samp->data[2] = dims_flags;
}
if (compress) {
#ifndef GPAC_DISABLE_ZLIB
e = compress_sample_data(samp, &max_size, use_dict ? &dictionary : NULL, is_dims ? 3 : 0);
if (e) goto exit;
if (is_dims) {
GF_BitStream *bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_WRITE);
gf_bs_write_u16(bs, samp->dataLength-2);
gf_bs_del(bs);
}
#else
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Error: your version of GPAC was compile with no libz support. Abort."));
e = GF_NOT_SUPPORTED;
goto exit;
#endif
}
if (is_dims && (samp->dataLength > 0xFFFF)) {
e = gf_import_message(import, GF_BAD_PARAM, "DIMS import failure: sample data is too long - maximum size allowed: 65532 bytes");
goto exit;
}
if ((samp->IsRAP==RAP_REDUNDANT) && !is_dims) {
e = gf_isom_add_sample_shadow(import->dest, track, samp);
} else if (append) {
e = gf_isom_append_sample_data(import->dest, track, samp->data, samp->dataLength);
} else {
e = gf_isom_add_sample(import->dest, track, di, samp);
}
if (e) goto exit;
samp->IsRAP = RAP_NO;
samp->CTS_Offset = 0;
if (sample_duration)
samp->DTS += sample_duration;
else
samp->DTS += dts_inc;
media_done += samp->dataLength;
gf_set_progress(is_dims ? "Importing DIMS" : "Importing NHML", (u32) media_done, (u32) (media_size ? media_size : media_done+1) );
if (duration && (samp->DTS > duration)) break;
if (import->flags & GF_IMPORT_DO_ABORT) break;
}
if (sample_duration) {
gf_isom_set_last_sample_duration(import->dest, track, (u32) sample_duration);
}
if (media_done!=media_size) gf_set_progress(is_dims ? "Importing DIMS" : "Importing NHML", (u32) media_size, (u32) media_size);
gf_media_update_bitrate(import->dest, track);
if (inRootOD) gf_isom_add_track_to_root_od(import->dest, track);
exit:
gf_fclose(nhml);
if (samp) {
samp->dataLength = 1;
gf_isom_sample_del(&samp);
}
if (mdia) gf_fclose(mdia);
if (import->esd && destroy_esd) {
gf_odf_desc_del((GF_Descriptor *) import->esd);
import->esd = NULL;
}
gf_xml_dom_del(parser);
if (specInfo) gf_free(specInfo);
if (dictionary) gf_free(dictionary);
return e;
}