Skip to content

Commit

Permalink
Rename IMFAssetMap to IMFAssetLocatorMap and handle multiple ASSETMAP…
Browse files Browse the repository at this point in the history
… files
  • Loading branch information
valnoel committed Jul 2, 2021
1 parent 4a8cc29 commit 3c1ad0a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 44 deletions.
21 changes: 11 additions & 10 deletions libavformat/imf_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ typedef struct IMFAssetLocator {
} IMFAssetLocator;

/**
* IMF Asset Map
* IMF Asset locator map
* Results from the parsing of one or more ASSETMAP XML files
*/
typedef struct IMFAssetMap {
typedef struct IMFAssetLocatorMap {
uint8_t asset_count;
IMFAssetLocator **assets;
} IMFAssetMap;
} IMFAssetLocatorMap;

int xml_read_ulong(xmlNodePtr element, unsigned long *number);

Expand All @@ -67,21 +68,21 @@ xmlNodePtr xml_get_child_element_by_name(xmlNodePtr parent, const char *name_utf
* Parse a ASSETMAP XML file to extract the UUID-URI mapping of assets.
* @param s the current format context, if any (can be NULL).
* @param doc the XML document to be parsed.
* @param asset_map pointer on the IMFAssetMap pointer to fill.
* @param asset_map pointer on the IMFAssetLocatorMap pointer to fill.
* @param base_url the url of the asset map XML file, if any (can be NULL).
* @return a negative value in case of error, 0 otherwise.
*/
int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAssetMap **asset_map, const char *base_url);
int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAssetLocatorMap **asset_map, const char *base_url);

/**
* Allocate a IMFAssetMap pointer and return it.
* @return the allocated IMFAssetMap pointer.
* Allocate a IMFAssetLocatorMap pointer and return it.
* @return the allocated IMFAssetLocatorMap pointer.
*/
IMFAssetMap *imf_asset_map_alloc(void);
IMFAssetLocatorMap *imf_asset_locator_map_alloc(void);

/**
* Free a IMFAssetMap pointer.
* Free a IMFAssetLocatorMap pointer.
*/
void imf_asset_map_free(IMFAssetMap *asset_map);
void imf_asset_locator_map_free(IMFAssetLocatorMap *asset_map);

#endif
61 changes: 36 additions & 25 deletions libavformat/imfdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ typedef struct IMFTrack {
typedef struct IMFContext {
const AVClass *class;
const char *base_url;
char *asset_map_path;
char *asset_map_paths;
AVIOInterruptCB *interrupt_callback;
AVDictionary *avio_opts;
IMFCPL *cpl;
IMFAssetMap *asset_map;
IMFAssetLocatorMap *asset_locator_map;
unsigned int track_count;
IMFTrack **tracks;
} IMFContext;

int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAssetMap **asset_map, const char *base_url) {
int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAssetLocatorMap **asset_map, const char *base_url) {
xmlNodePtr asset_map_element = NULL;
xmlNodePtr node = NULL;
char *uri;
Expand Down Expand Up @@ -148,10 +148,10 @@ int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAsset
return ret;
}

IMFAssetMap *imf_asset_map_alloc(void) {
IMFAssetMap *asset_map;
IMFAssetLocatorMap *imf_asset_locator_map_alloc(void) {
IMFAssetLocatorMap *asset_map;

asset_map = av_malloc(sizeof(IMFAssetMap));
asset_map = av_malloc(sizeof(IMFAssetLocatorMap));
if (!asset_map)
return NULL;

Expand All @@ -160,7 +160,7 @@ IMFAssetMap *imf_asset_map_alloc(void) {
return asset_map;
}

void imf_asset_map_free(IMFAssetMap *asset_map) {
void imf_asset_locator_map_free(IMFAssetLocatorMap *asset_map) {
if (asset_map == NULL) {
return;
}
Expand All @@ -184,11 +184,13 @@ static int parse_assetmap(AVFormatContext *s, const char *url, AVIOContext *in)
int ret = 0;
int64_t filesize = 0;

c->base_url = av_dirname(strdup(url));
c->asset_map = imf_asset_map_alloc();
if (!c->asset_map) {
av_log(s, AV_LOG_ERROR, "Unable to allocate asset map locator\n");
return AVERROR_BUG;
const char *base_url = av_dirname(strdup(url));
if (c->asset_locator_map == NULL) {
c->asset_locator_map = imf_asset_locator_map_alloc();
if (!c->asset_locator_map) {
av_log(s, AV_LOG_ERROR, "Unable to allocate asset map locator\n");
return AVERROR_BUG;
}
}

av_log(s, AV_LOG_DEBUG, "Asset Map URL: %s\n", url);
Expand Down Expand Up @@ -217,12 +219,12 @@ static int parse_assetmap(AVFormatContext *s, const char *url, AVIOContext *in)

doc = xmlReadMemory(buf.str, filesize, url, NULL, 0);

ret = parse_imf_asset_map_from_xml_dom(s, doc, &c->asset_map, c->base_url);
ret = parse_imf_asset_map_from_xml_dom(s, doc, &c->asset_locator_map, base_url);
if (ret != 0) {
goto cleanup;
}

av_log(s, AV_LOG_DEBUG, "Found %d assets from %s\n", c->asset_map->asset_count, url);
av_log(s, AV_LOG_DEBUG, "Found %d assets from %s\n", c->asset_locator_map->asset_count, url);

cleanup:
xmlFreeDoc(doc);
Expand All @@ -233,7 +235,7 @@ static int parse_assetmap(AVFormatContext *s, const char *url, AVIOContext *in)
return ret;
}

static IMFAssetLocator *find_asset_map_locator(IMFAssetMap *asset_map, UUID uuid) {
static IMFAssetLocator *find_asset_map_locator(IMFAssetLocatorMap *asset_map, UUID uuid) {
IMFAssetLocator *asset_locator;
for (int i = 0; i < asset_map->asset_count; ++i) {
asset_locator = asset_map->assets[i];
Expand Down Expand Up @@ -279,7 +281,7 @@ static int open_track_file_resource(AVFormatContext *s, IMFTrackFileResource *tr

int ret = 0;

if (!(asset_locator = find_asset_map_locator(c->asset_map, track_file_resource->track_file_uuid))) {
if (!(asset_locator = find_asset_map_locator(c->asset_locator_map, track_file_resource->track_file_uuid))) {
av_log(s, AV_LOG_ERROR, "Could not find asset locator for UUID: " UUID_FORMAT "\n", UID_ARG(track_file_resource->track_file_uuid));
return AVERROR_INVALIDDATA;
}
Expand Down Expand Up @@ -386,25 +388,34 @@ static int imf_close(AVFormatContext *s);

static int imf_read_header(AVFormatContext *s) {
IMFContext *c = s->priv_data;
char *asset_map_path;
int ret;

c->base_url = av_dirname(av_strdup(s->url));

av_log(s, AV_LOG_DEBUG, "start parsing IMF CPL: %s\n", s->url);

if ((ret = parse_imf_cpl(s->pb, &c->cpl)) < 0)
goto fail;

av_log(s, AV_LOG_INFO, "parsed IMF CPL: " UUID_FORMAT "\n", UID_ARG(c->cpl->id_uuid));
av_log(s, AV_LOG_DEBUG, "parsed IMF CPL: " UUID_FORMAT "\n", UID_ARG(c->cpl->id_uuid));

if (!c->asset_map_path) {
c->asset_map_path = av_append_path_component(av_dirname(av_strdup(s->url)), "ASSETMAP.xml");
if (!c->asset_map_paths) {
c->asset_map_paths = av_append_path_component(c->base_url, "ASSETMAP.xml");
}

av_log(s, AV_LOG_DEBUG, "start parsing IMF Asset Map: %s\n", c->asset_map_path);
// Parse each asset map XML file
asset_map_path = strtok(c->asset_map_paths, ",");
while (asset_map_path != NULL) {
av_log(s, AV_LOG_DEBUG, "start parsing IMF Asset Map: %s\n", asset_map_path);

if ((ret = parse_assetmap(s, c->asset_map_path, NULL)) < 0)
goto fail;
if ((ret = parse_assetmap(s, asset_map_path, NULL)) < 0)
goto fail;

asset_map_path = strtok(NULL, ",");
}

av_log(s, AV_LOG_DEBUG, "parsed IMF Asset Map \n");
av_log(s, AV_LOG_DEBUG, "parsed IMF Asset Maps\n");

if ((ret = open_cpl_tracks(s)) != 0) {
goto fail;
Expand Down Expand Up @@ -510,14 +521,14 @@ static int imf_close(AVFormatContext *s) {
av_log(s, AV_LOG_DEBUG, "Close IMF package\n");
av_dict_free(&c->avio_opts);
av_freep(&c->base_url);
imf_asset_map_free(c->asset_map);
imf_asset_locator_map_free(c->asset_locator_map);
imf_cpl_free(c->cpl);

return 0;
}

static const AVOption imf_options[] = {
{"assetmap", "IMF CPL-related asset map absolute path. If not specified, the CPL sibling `ASSETMAP.xml` file is used.", offsetof(IMFContext, asset_map_path), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM},
{"assetmaps", "IMF CPL-related asset map comma-separated absolute paths. If not specified, the CPL sibling `ASSETMAP.xml` file is used.", offsetof(IMFContext, asset_map_paths), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM},
{NULL}};

static const AVClass imf_class = {
Expand Down
18 changes: 9 additions & 9 deletions libavformat/tests/imf.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ static const IMFAssetLocator ASSET_MAP_EXPECTED_LOCATORS[5] = {
};

static int test_asset_map_parsing() {
IMFAssetMap *asset_map;
IMFAssetLocatorMap *asset_locator_map;
xmlDoc *doc;
int ret;

Expand All @@ -292,32 +292,32 @@ static int test_asset_map_parsing() {
}

printf("Allocate asset map\n");
asset_map = imf_asset_map_alloc();
asset_locator_map = imf_asset_locator_map_alloc();

printf("Parse asset map XML document\n");
ret = parse_imf_asset_map_from_xml_dom(NULL, doc, &asset_map, doc->name);
ret = parse_imf_asset_map_from_xml_dom(NULL, doc, &asset_locator_map, doc->name);
if (ret) {
printf("Asset map parsing failed.\n");
goto cleanup;
}

printf("Compare assets count: %d to 5\n", asset_map->asset_count);
if (asset_map->asset_count != 5) {
printf("Asset map parsing failed: found %d assets instead of 5 expected.\n", asset_map->asset_count);
printf("Compare assets count: %d to 5\n", asset_locator_map->asset_count);
if (asset_locator_map->asset_count != 5) {
printf("Asset map parsing failed: found %d assets instead of 5 expected.\n", asset_locator_map->asset_count);
ret = 1;
goto cleanup;
}

for (int i = 0; i < asset_map->asset_count; ++i) {
for (int i = 0; i < asset_locator_map->asset_count; ++i) {
printf("For asset: %d:\n", i);
ret = check_asset_locator_attributes(asset_map->assets[i], ASSET_MAP_EXPECTED_LOCATORS[i]);
ret = check_asset_locator_attributes(asset_locator_map->assets[i], ASSET_MAP_EXPECTED_LOCATORS[i]);
if (ret > 0) {
goto cleanup;
}
}

cleanup:
imf_asset_map_free(asset_map);
imf_asset_locator_map_free(asset_locator_map);
xmlFreeDoc(doc);
return ret;
}
Expand Down

0 comments on commit 3c1ad0a

Please sign in to comment.