|
|
|
@ -76,10 +76,8 @@ int ff_imf_xml_read_uuid(xmlNodePtr element, AVUUID uuid) |
|
|
|
|
|
|
|
|
|
xmlChar *element_text = xmlNodeListGetString(element->doc, element->xmlChildrenNode, 1); |
|
|
|
|
ret = av_uuid_urn_parse(element_text, uuid); |
|
|
|
|
if (ret) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid UUID\n"); |
|
|
|
|
if (ret) |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
xmlFree(element_text); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
@ -90,10 +88,8 @@ int ff_imf_xml_read_rational(xmlNodePtr element, AVRational *rational) |
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
|
|
xmlChar *element_text = xmlNodeListGetString(element->doc, element->xmlChildrenNode, 1); |
|
|
|
|
if (sscanf(element_text, "%i %i", &rational->num, &rational->den) != 2) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid rational number\n"); |
|
|
|
|
if (sscanf(element_text, "%i %i", &rational->num, &rational->den) != 2) |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
xmlFree(element_text); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
@ -104,10 +100,8 @@ int ff_imf_xml_read_uint32(xmlNodePtr element, uint32_t *number) |
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
|
|
xmlChar *element_text = xmlNodeListGetString(element->doc, element->xmlChildrenNode, 1); |
|
|
|
|
if (sscanf(element_text, "%" PRIu32, number) != 1) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid unsigned 32-bit integer"); |
|
|
|
|
if (sscanf(element_text, "%" PRIu32, number) != 1) |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
xmlFree(element_text); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
@ -181,10 +175,8 @@ static int fill_content_title(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
xmlNodePtr element = NULL; |
|
|
|
|
|
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(cpl_element, "ContentTitle"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "ContentTitle element not found in the IMF CPL\n"); |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(cpl_element, "ContentTitle"))) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
cpl->content_title_utf8 = xmlNodeListGetString(cpl_element->doc, |
|
|
|
|
element->xmlChildrenNode, |
|
|
|
|
1); |
|
|
|
@ -242,22 +234,15 @@ static int fill_timecode(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
element = ff_imf_xml_get_child_element_by_name(tc_element, "TimecodeDropFrame"); |
|
|
|
|
if (!element) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "CompositionTimecode element is missing\
|
|
|
|
|
a TimecodeDropFrame child element\n"); |
|
|
|
|
if (!element) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ff_imf_xml_read_boolean(element, &df)) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "TimecodeDropFrame element is invalid\n"); |
|
|
|
|
if (ff_imf_xml_read_boolean(element, &df)) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
element = ff_imf_xml_get_child_element_by_name(tc_element, "TimecodeStartAddress"); |
|
|
|
|
if (!element) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "CompositionTimecode element is missing\
|
|
|
|
|
a TimecodeStartAddress child element\n"); |
|
|
|
|
if (!element) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tc_str = xmlNodeListGetString(element->doc, element->xmlChildrenNode, 1); |
|
|
|
|
ret = parse_cpl_tc_type(tc_str, comps); |
|
|
|
@ -280,10 +265,8 @@ static int fill_edit_rate(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
xmlNodePtr element = NULL; |
|
|
|
|
|
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(cpl_element, "EditRate"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "EditRate element not found in the IMF CPL\n"); |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(cpl_element, "EditRate"))) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ff_imf_xml_read_rational(element, &cpl->edit_rate); |
|
|
|
|
} |
|
|
|
@ -292,10 +275,8 @@ static int fill_id(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
xmlNodePtr element = NULL; |
|
|
|
|
|
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(cpl_element, "Id"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Id element not found in the IMF CPL\n"); |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(cpl_element, "Id"))) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ff_imf_xml_read_uuid(element, cpl->id_uuid); |
|
|
|
|
} |
|
|
|
@ -306,22 +287,19 @@ static int fill_marker(xmlNodePtr marker_elem, FFIMFMarker *marker) |
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
|
|
/* read Offset */ |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(marker_elem, "Offset"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Offset element not found in a Marker\n"); |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(marker_elem, "Offset"))) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((ret = ff_imf_xml_read_uint32(element, &marker->offset))) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
/* read Label and Scope */ |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(marker_elem, "Label"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Label element not found in a Marker\n"); |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(marker_elem, "Label"))) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if (!(marker->label_utf8 = xmlNodeListGetString(element->doc, element->xmlChildrenNode, 1))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Empty Label element found in a Marker\n"); |
|
|
|
|
|
|
|
|
|
if (!(marker->label_utf8 = xmlNodeListGetString(element->doc, element->xmlChildrenNode, 1))) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(marker->scope_utf8 = xmlGetNoNsProp(element, "scope"))) { |
|
|
|
|
marker->scope_utf8 |
|
|
|
|
= xmlCharStrdup("http://www.smpte-ra.org/schemas/2067-3/2013#standard-markers"); |
|
|
|
@ -334,7 +312,8 @@ static int fill_marker(xmlNodePtr marker_elem, FFIMFMarker *marker) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int fill_base_resource(xmlNodePtr resource_elem, FFIMFBaseResource *resource, FFIMFCPL *cpl) |
|
|
|
|
static int fill_base_resource(void *log_ctx, xmlNodePtr resource_elem, |
|
|
|
|
FFIMFBaseResource *resource, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
xmlNodePtr element = NULL; |
|
|
|
|
int ret = 0; |
|
|
|
@ -343,14 +322,14 @@ static int fill_base_resource(xmlNodePtr resource_elem, FFIMFBaseResource *resou |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(resource_elem, "EditRate"))) { |
|
|
|
|
resource->edit_rate = cpl->edit_rate; |
|
|
|
|
} else if ((ret = ff_imf_xml_read_rational(element, &resource->edit_rate))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid EditRate element found in a Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid EditRate element found in a Resource\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read EntryPoint */ |
|
|
|
|
if ((element = ff_imf_xml_get_child_element_by_name(resource_elem, "EntryPoint"))) { |
|
|
|
|
if ((ret = ff_imf_xml_read_uint32(element, &resource->entry_point))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid EntryPoint element found in a Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid EntryPoint element found in a Resource\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -359,11 +338,11 @@ static int fill_base_resource(xmlNodePtr resource_elem, FFIMFBaseResource *resou |
|
|
|
|
|
|
|
|
|
/* read IntrinsicDuration */ |
|
|
|
|
if (!(element = ff_imf_xml_get_child_element_by_name(resource_elem, "IntrinsicDuration"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "IntrinsicDuration element missing from Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "IntrinsicDuration element missing from Resource\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if ((ret = ff_imf_xml_read_uint32(element, &resource->duration))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid IntrinsicDuration element found in a Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid IntrinsicDuration element found in a Resource\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
resource->duration -= resource->entry_point; |
|
|
|
@ -371,7 +350,7 @@ static int fill_base_resource(xmlNodePtr resource_elem, FFIMFBaseResource *resou |
|
|
|
|
/* read SourceDuration */ |
|
|
|
|
if ((element = ff_imf_xml_get_child_element_by_name(resource_elem, "SourceDuration"))) { |
|
|
|
|
if ((ret = ff_imf_xml_read_uint32(element, &resource->duration))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "SourceDuration element missing from Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "SourceDuration element missing from Resource\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -383,38 +362,38 @@ static int fill_base_resource(xmlNodePtr resource_elem, FFIMFBaseResource *resou |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int fill_trackfile_resource(xmlNodePtr tf_resource_elem, |
|
|
|
|
static int fill_trackfile_resource(void *log_ctx, xmlNodePtr tf_resource_elem, |
|
|
|
|
FFIMFTrackFileResource *tf_resource, |
|
|
|
|
FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
xmlNodePtr element = NULL; |
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
|
|
if ((ret = fill_base_resource(tf_resource_elem, (FFIMFBaseResource *)tf_resource, cpl))) |
|
|
|
|
if ((ret = fill_base_resource(log_ctx, tf_resource_elem, (FFIMFBaseResource *)tf_resource, cpl))) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
/* read TrackFileId */ |
|
|
|
|
if ((element = ff_imf_xml_get_child_element_by_name(tf_resource_elem, "TrackFileId"))) { |
|
|
|
|
if ((ret = ff_imf_xml_read_uuid(element, tf_resource->track_file_uuid))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid TrackFileId element found in Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid TrackFileId element found in Resource\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "TrackFileId element missing from Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "TrackFileId element missing from Resource\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int fill_marker_resource(xmlNodePtr marker_resource_elem, |
|
|
|
|
static int fill_marker_resource(void *log_ctx, xmlNodePtr marker_resource_elem, |
|
|
|
|
FFIMFMarkerResource *marker_resource, |
|
|
|
|
FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
xmlNodePtr element = NULL; |
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
|
|
if ((ret = fill_base_resource(marker_resource_elem, (FFIMFBaseResource *)marker_resource, cpl))) |
|
|
|
|
if ((ret = fill_base_resource(log_ctx, marker_resource_elem, (FFIMFBaseResource *)marker_resource, cpl))) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
/* read markers */ |
|
|
|
@ -436,8 +415,10 @@ static int fill_marker_resource(xmlNodePtr marker_resource_elem, |
|
|
|
|
ret = fill_marker(element, |
|
|
|
|
&marker_resource->markers[marker_resource->marker_count]); |
|
|
|
|
marker_resource->marker_count++; |
|
|
|
|
if (ret) |
|
|
|
|
if (ret) { |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid Marker element\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
element = xmlNextElementSibling(element); |
|
|
|
@ -446,7 +427,7 @@ static int fill_marker_resource(xmlNodePtr marker_resource_elem, |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int push_marker_sequence(xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
static int push_marker_sequence(void *log_ctx, xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
int ret = 0; |
|
|
|
|
AVUUID uuid; |
|
|
|
@ -458,14 +439,14 @@ static int push_marker_sequence(xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
|
|
|
|
|
/* read TrackID element */ |
|
|
|
|
if (!(track_id_elem = ff_imf_xml_get_child_element_by_name(marker_sequence_elem, "TrackId"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "TrackId element missing from Sequence\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "TrackId element missing from Sequence\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if (ff_imf_xml_read_uuid(track_id_elem, uuid)) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid TrackId element found in Sequence\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid TrackId element found in Sequence\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_DEBUG, |
|
|
|
|
"Processing IMF CPL Marker Sequence for Virtual Track " AV_PRI_UUID "\n", |
|
|
|
|
AV_UUID_ARG(uuid)); |
|
|
|
@ -479,7 +460,7 @@ static int push_marker_sequence(xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
av_uuid_copy(cpl->main_markers_track->base.id_uuid, uuid); |
|
|
|
|
|
|
|
|
|
} else if (!av_uuid_equal(cpl->main_markers_track->base.id_uuid, uuid)) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Multiple marker virtual tracks were found\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Multiple marker virtual tracks were found\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -496,7 +477,7 @@ static int push_marker_sequence(xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
cpl->main_markers_track->resource_count + resource_elem_count, |
|
|
|
|
sizeof(FFIMFMarkerResource)); |
|
|
|
|
if (!tmp) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot allocate Marker Resources\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Cannot allocate Marker Resources\n"); |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
} |
|
|
|
|
cpl->main_markers_track->resources = tmp; |
|
|
|
@ -504,7 +485,7 @@ static int push_marker_sequence(xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
resource_elem = xmlFirstElementChild(resource_list_elem); |
|
|
|
|
while (resource_elem) { |
|
|
|
|
imf_marker_resource_init(&cpl->main_markers_track->resources[cpl->main_markers_track->resource_count]); |
|
|
|
|
ret = fill_marker_resource(resource_elem, |
|
|
|
|
ret = fill_marker_resource(log_ctx, resource_elem, |
|
|
|
|
&cpl->main_markers_track->resources[cpl->main_markers_track->resource_count], |
|
|
|
|
cpl); |
|
|
|
|
cpl->main_markers_track->resource_count++; |
|
|
|
@ -533,7 +514,7 @@ static int has_stereo_resources(xmlNodePtr element) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
static int push_main_audio_sequence(void *log_ctx, xmlNodePtr audio_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
int ret = 0; |
|
|
|
|
AVUUID uuid; |
|
|
|
@ -546,14 +527,14 @@ static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cp |
|
|
|
|
|
|
|
|
|
/* read TrackID element */ |
|
|
|
|
if (!(track_id_elem = ff_imf_xml_get_child_element_by_name(audio_sequence_elem, "TrackId"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "TrackId element missing from audio sequence\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "TrackId element missing from audio sequence\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if ((ret = ff_imf_xml_read_uuid(track_id_elem, uuid))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid TrackId element found in audio sequence\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid TrackId element found in audio sequence\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_DEBUG, |
|
|
|
|
"Processing IMF CPL Audio Sequence for Virtual Track " AV_PRI_UUID "\n", |
|
|
|
|
AV_UUID_ARG(uuid)); |
|
|
|
@ -597,7 +578,7 @@ static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cp |
|
|
|
|
(vt->resource_count + resource_elem_count) |
|
|
|
|
* sizeof(FFIMFTrackFileResource)); |
|
|
|
|
if (!tmp) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot allocate Main Audio Resources\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Cannot allocate Main Audio Resources\n"); |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
} |
|
|
|
|
vt->resources = tmp; |
|
|
|
@ -605,11 +586,11 @@ static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cp |
|
|
|
|
resource_elem = xmlFirstElementChild(resource_list_elem); |
|
|
|
|
while (resource_elem) { |
|
|
|
|
imf_trackfile_resource_init(&vt->resources[vt->resource_count]); |
|
|
|
|
ret = fill_trackfile_resource(resource_elem, |
|
|
|
|
ret = fill_trackfile_resource(log_ctx, resource_elem, |
|
|
|
|
&vt->resources[vt->resource_count], |
|
|
|
|
cpl); |
|
|
|
|
if (ret) |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid Resource\n"); |
|
|
|
|
else |
|
|
|
|
vt->resource_count++; |
|
|
|
|
|
|
|
|
@ -619,7 +600,7 @@ static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cp |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
static int push_main_image_2d_sequence(void *log_ctx, xmlNodePtr image_sequence_elem, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
int ret = 0; |
|
|
|
|
AVUUID uuid; |
|
|
|
@ -631,17 +612,17 @@ static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL |
|
|
|
|
|
|
|
|
|
/* skip stereoscopic resources */ |
|
|
|
|
if (has_stereo_resources(image_sequence_elem)) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Stereoscopic 3D image virtual tracks not supported\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Stereoscopic 3D image virtual tracks not supported\n"); |
|
|
|
|
return AVERROR_PATCHWELCOME; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read TrackId element*/ |
|
|
|
|
if (!(track_id_elem = ff_imf_xml_get_child_element_by_name(image_sequence_elem, "TrackId"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "TrackId element missing from audio sequence\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "TrackId element missing from audio sequence\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if ((ret = ff_imf_xml_read_uuid(track_id_elem, uuid))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid TrackId element found in audio sequence\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid TrackId element found in audio sequence\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -654,10 +635,10 @@ static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL |
|
|
|
|
av_uuid_copy(cpl->main_image_2d_track->base.id_uuid, uuid); |
|
|
|
|
|
|
|
|
|
} else if (!av_uuid_equal(cpl->main_image_2d_track->base.id_uuid, uuid)) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Multiple MainImage virtual tracks found\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Multiple MainImage virtual tracks found\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_DEBUG, |
|
|
|
|
"Processing IMF CPL Main Image Sequence for Virtual Track " AV_PRI_UUID "\n", |
|
|
|
|
AV_UUID_ARG(uuid)); |
|
|
|
@ -678,7 +659,7 @@ static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL |
|
|
|
|
(cpl->main_image_2d_track->resource_count + resource_elem_count) |
|
|
|
|
* sizeof(FFIMFTrackFileResource)); |
|
|
|
|
if (!tmp) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot allocate Main Image Resources\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Cannot allocate Main Image Resources\n"); |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
} |
|
|
|
|
cpl->main_image_2d_track->resources = tmp; |
|
|
|
@ -687,11 +668,11 @@ static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL |
|
|
|
|
while (resource_elem) { |
|
|
|
|
imf_trackfile_resource_init( |
|
|
|
|
&cpl->main_image_2d_track->resources[cpl->main_image_2d_track->resource_count]); |
|
|
|
|
ret = fill_trackfile_resource(resource_elem, |
|
|
|
|
ret = fill_trackfile_resource(log_ctx, resource_elem, |
|
|
|
|
&cpl->main_image_2d_track->resources[cpl->main_image_2d_track->resource_count], |
|
|
|
|
cpl); |
|
|
|
|
if (ret) |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Invalid Resource\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid Resource\n"); |
|
|
|
|
else |
|
|
|
|
cpl->main_image_2d_track->resource_count++; |
|
|
|
|
|
|
|
|
@ -701,7 +682,7 @@ static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int fill_virtual_tracks(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
static int fill_virtual_tracks(void *log_ctx, xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
{ |
|
|
|
|
int ret = 0; |
|
|
|
|
xmlNodePtr segment_list_elem = NULL; |
|
|
|
@ -710,14 +691,14 @@ static int fill_virtual_tracks(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
xmlNodePtr sequence_elem = NULL; |
|
|
|
|
|
|
|
|
|
if (!(segment_list_elem = ff_imf_xml_get_child_element_by_name(cpl_element, "SegmentList"))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "SegmentList element missing\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "SegmentList element missing\n"); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* process sequences */ |
|
|
|
|
segment_elem = xmlFirstElementChild(segment_list_elem); |
|
|
|
|
while (segment_elem) { |
|
|
|
|
av_log(NULL, AV_LOG_DEBUG, "Processing IMF CPL Segment\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_DEBUG, "Processing IMF CPL Segment\n"); |
|
|
|
|
|
|
|
|
|
sequence_list_elem = ff_imf_xml_get_child_element_by_name(segment_elem, "SequenceList"); |
|
|
|
|
if (!sequence_list_elem) |
|
|
|
@ -726,16 +707,16 @@ static int fill_virtual_tracks(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
sequence_elem = xmlFirstElementChild(sequence_list_elem); |
|
|
|
|
while (sequence_elem) { |
|
|
|
|
if (xmlStrcmp(sequence_elem->name, "MarkerSequence") == 0) |
|
|
|
|
ret = push_marker_sequence(sequence_elem, cpl); |
|
|
|
|
ret = push_marker_sequence(log_ctx, sequence_elem, cpl); |
|
|
|
|
|
|
|
|
|
else if (xmlStrcmp(sequence_elem->name, "MainImageSequence") == 0) |
|
|
|
|
ret = push_main_image_2d_sequence(sequence_elem, cpl); |
|
|
|
|
ret = push_main_image_2d_sequence(log_ctx, sequence_elem, cpl); |
|
|
|
|
|
|
|
|
|
else if (xmlStrcmp(sequence_elem->name, "MainAudioSequence") == 0) |
|
|
|
|
ret = push_main_audio_sequence(sequence_elem, cpl); |
|
|
|
|
ret = push_main_audio_sequence(log_ctx, sequence_elem, cpl); |
|
|
|
|
|
|
|
|
|
else |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_INFO, |
|
|
|
|
"The following Sequence is not supported and is ignored: %s\n", |
|
|
|
|
sequence_elem->name); |
|
|
|
@ -753,7 +734,7 @@ static int fill_virtual_tracks(xmlNodePtr cpl_element, FFIMFCPL *cpl) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ff_imf_parse_cpl_from_xml_dom(xmlDocPtr doc, FFIMFCPL **cpl) |
|
|
|
|
int ff_imf_parse_cpl_from_xml_dom(void *log_ctx, xmlDocPtr doc, FFIMFCPL **cpl) |
|
|
|
|
{ |
|
|
|
|
int ret = 0; |
|
|
|
|
xmlNodePtr cpl_element = NULL; |
|
|
|
@ -766,20 +747,28 @@ int ff_imf_parse_cpl_from_xml_dom(xmlDocPtr doc, FFIMFCPL **cpl) |
|
|
|
|
|
|
|
|
|
cpl_element = xmlDocGetRootElement(doc); |
|
|
|
|
if (!cpl_element || xmlStrcmp(cpl_element->name, "CompositionPlaylist")) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "The root element of the CPL is not CompositionPlaylist\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "The root element of the CPL is not CompositionPlaylist\n"); |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
goto cleanup; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((ret = fill_content_title(cpl_element, *cpl))) |
|
|
|
|
if ((ret = fill_content_title(cpl_element, *cpl))) { |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Cannot read the ContentTitle element from the IMF CPL\n"); |
|
|
|
|
goto cleanup; |
|
|
|
|
if ((ret = fill_id(cpl_element, *cpl))) |
|
|
|
|
} |
|
|
|
|
if ((ret = fill_id(cpl_element, *cpl))) { |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Id element not found in the IMF CPL\n"); |
|
|
|
|
goto cleanup; |
|
|
|
|
if ((ret = fill_edit_rate(cpl_element, *cpl))) |
|
|
|
|
} |
|
|
|
|
if ((ret = fill_edit_rate(cpl_element, *cpl))) { |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "EditRate element not found in the IMF CPL\n"); |
|
|
|
|
goto cleanup; |
|
|
|
|
if ((ret = fill_timecode(cpl_element, *cpl))) |
|
|
|
|
} |
|
|
|
|
if ((ret = fill_timecode(cpl_element, *cpl))) { |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Invalid CompositionTimecode element found in the IMF CPL\n"); |
|
|
|
|
goto cleanup; |
|
|
|
|
if ((ret = fill_virtual_tracks(cpl_element, *cpl))) |
|
|
|
|
} |
|
|
|
|
if ((ret = fill_virtual_tracks(log_ctx, cpl_element, *cpl))) |
|
|
|
|
goto cleanup; |
|
|
|
|
|
|
|
|
|
cleanup: |
|
|
|
@ -875,7 +864,7 @@ void ff_imf_cpl_free(FFIMFCPL *cpl) |
|
|
|
|
av_freep(&cpl); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ff_imf_parse_cpl(AVIOContext *in, FFIMFCPL **cpl) |
|
|
|
|
int ff_imf_parse_cpl(void *log_ctx, AVIOContext *in, FFIMFCPL **cpl) |
|
|
|
|
{ |
|
|
|
|
AVBPrint buf; |
|
|
|
|
xmlDoc *doc = NULL; |
|
|
|
@ -885,7 +874,7 @@ int ff_imf_parse_cpl(AVIOContext *in, FFIMFCPL **cpl) |
|
|
|
|
|
|
|
|
|
ret = avio_read_to_bprint(in, &buf, SIZE_MAX); |
|
|
|
|
if (ret < 0 || !avio_feof(in)) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot read IMF CPL\n"); |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Cannot read IMF CPL\n"); |
|
|
|
|
if (ret == 0) |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
goto clean_up; |
|
|
|
@ -895,21 +884,21 @@ int ff_imf_parse_cpl(AVIOContext *in, FFIMFCPL **cpl) |
|
|
|
|
|
|
|
|
|
doc = xmlReadMemory(buf.str, buf.len, NULL, NULL, 0); |
|
|
|
|
if (!doc) { |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_ERROR, |
|
|
|
|
"XML parsing failed when reading the IMF CPL\n"); |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
goto clean_up; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((ret = ff_imf_parse_cpl_from_xml_dom(doc, cpl))) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "Cannot parse IMF CPL\n"); |
|
|
|
|
if ((ret = ff_imf_parse_cpl_from_xml_dom(log_ctx, doc, cpl))) { |
|
|
|
|
av_log(log_ctx, AV_LOG_ERROR, "Cannot parse IMF CPL\n"); |
|
|
|
|
} else { |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_INFO, |
|
|
|
|
"IMF CPL ContentTitle: %s\n", |
|
|
|
|
(*cpl)->content_title_utf8); |
|
|
|
|
av_log(NULL, |
|
|
|
|
av_log(log_ctx, |
|
|
|
|
AV_LOG_INFO, |
|
|
|
|
"IMF CPL Id: " AV_PRI_UUID "\n", |
|
|
|
|
AV_UUID_ARG((*cpl)->id_uuid)); |
|
|
|
|