Skip to content

Commit

Permalink
avformat/imf: open resources only when first needed
Browse files Browse the repository at this point in the history
IMF CPLs can reference thousands of files, which can result in system limits
for the number of open files to be exceeded. The following patch opens and
closes files as needed.

Addresses https://trac.ffmpeg.org/ticket/9623
  • Loading branch information
palemieux authored and vs49688 committed Feb 20, 2022
1 parent c439c6b commit ef0d524
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions libavformat/imfdec.c
Expand Up @@ -103,10 +103,11 @@ typedef struct IMFVirtualTrackPlaybackCtx {
int32_t index; /**< Track index in playlist */
AVRational current_timestamp; /**< Current temporal position */
AVRational duration; /**< Overall duration */
uint32_t resource_count; /**< Number of resources */
uint32_t resource_count; /**< Number of resources (<= INT32_MAX) */
unsigned int resources_alloc_sz; /**< Size of the buffer holding the resource */
IMFVirtualTrackResourcePlaybackCtx *resources; /**< Buffer holding the resources */
uint32_t current_resource_index; /**< Current resource */
int32_t current_resource_index; /**< Index of the current resource in resources,
or < 0 if a current resource has yet to be selected */
int64_t last_pts; /**< Last timestamp */
} IMFVirtualTrackPlaybackCtx;

Expand Down Expand Up @@ -435,7 +436,6 @@ static int open_track_file_resource(AVFormatContext *s,
IMFContext *c = s->priv_data;
IMFAssetLocator *asset_locator;
void *tmp;
int ret;

asset_locator = find_asset_map_locator(&c->asset_locator_map, track_file_resource->track_file_uuid);
if (!asset_locator) {
Expand All @@ -452,7 +452,7 @@ static int open_track_file_resource(AVFormatContext *s,
UID_ARG(asset_locator->uuid),
asset_locator->absolute_uri);

if (track->resource_count > UINT32_MAX - track_file_resource->base.repeat_count
if (track->resource_count > INT32_MAX - track_file_resource->base.repeat_count
|| (track->resource_count + track_file_resource->base.repeat_count)
> INT_MAX / sizeof(IMFVirtualTrackResourcePlaybackCtx))
return AVERROR(ENOMEM);
Expand All @@ -470,8 +470,6 @@ static int open_track_file_resource(AVFormatContext *s,
vt_ctx.locator = asset_locator;
vt_ctx.resource = track_file_resource;
vt_ctx.ctx = NULL;
if ((ret = open_track_resource_context(s, &vt_ctx)) != 0)
return ret;
track->resources[track->resource_count++] = vt_ctx;
track->duration = av_add_q(track->duration,
av_make_q((int)track_file_resource->base.duration
Expand Down Expand Up @@ -501,6 +499,7 @@ static int open_virtual_track(AVFormatContext *s,

if (!(track = av_mallocz(sizeof(IMFVirtualTrackPlaybackCtx))))
return AVERROR(ENOMEM);
track->current_resource_index = -1;
track->index = track_index;
track->duration = av_make_q(0, 1);

Expand Down Expand Up @@ -551,6 +550,9 @@ static int set_context_streams_from_tracks(AVFormatContext *s)
AVStream *first_resource_stream;

/* Open the first resource of the track to get stream information */
ret = open_track_resource_context(s, &c->tracks[i]->resources[0]);
if (ret)
return ret;
first_resource_stream = c->tracks[i]->resources[0].ctx->streams[0];
av_log(s, AV_LOG_DEBUG, "Open the first resource of track %d\n", c->tracks[i]->index);

Expand Down Expand Up @@ -741,7 +743,8 @@ static IMFVirtualTrackResourcePlaybackCtx *get_resource_context_for_timestamp(AV
track->index);
if (open_track_resource_context(s, &(track->resources[i])) != 0)
return NULL;
avformat_close_input(&(track->resources[track->current_resource_index].ctx));
if (track->current_resource_index > 0)
avformat_close_input(&track->resources[track->current_resource_index].ctx);
track->current_resource_index = i;
}

Expand Down

0 comments on commit ef0d524

Please sign in to comment.