From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id A0ECC407B5 for ; Sun, 30 Jan 2022 22:16:28 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 827A968B160; Mon, 31 Jan 2022 00:16:26 +0200 (EET) Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-oln040092071024.outbound.protection.outlook.com [40.92.71.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AA20068AAC1 for ; Mon, 31 Jan 2022 00:16:20 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FnQDhoA4INmWCWOb0pJp7ubE17UcScWlgzE7pm5yjl4jOr+MocbwscJ1vq1YP3zt1N/gJd4CKjbLAosBW+wBJvU7WmK3+WRcswnwNvnAuD2YUZ+LZ8G8uBhXeAoMI7SD1r5L7XqjP3I/4JRHUDfpU6ImRYCenYA8o2XW4eDwRnE0i9L8UDMiC/g2gf1vzDx/W4FFPRl/G1TIdR+UPULa6SXe6/WrDODfYTAS66W2jhgMum8qCgIcius5rWde7Fq65D2cSGYFc9fQsmHhLJyESmYILr0bkN2t0OSw39GN9r9etnVO0QcQ5gaTeiR/JcqcwKj3LpsmZG33iMdb5G2NqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=qLz11ufN4/h1faQTu1NieUSve0hlr4wfF3AMZQZ9Sxk=; b=PL/9N/CNQvF9FyBkC9dUq0DfKy8U/Coueb+U74+W8tVAYZqSOUDIJyxhtrscRyZvWxDDF8m7GEIJHswQoRRJKDYjvItDmokphGUcfi1RMaKPItesy0kO37FR2tId9/I9gDH9RQBciMG9cdPuuZij9MH5a9rVKLkPs+HcBDue96LmHmEZih4LAh75g49sDztwJD37iYdRBuci8Z+nHn2m/qX5z+06Zma1brAiL+etK6M/4OpKXrS5XTsn3nY6wDjX4pyec8gSpdsDpQf6RPVWjhNtsa5xzkwMa1+J6efK9xMpYXTeprK4xS7q1T49FBtiiSYRa+INWs90HBlZivYkSQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qLz11ufN4/h1faQTu1NieUSve0hlr4wfF3AMZQZ9Sxk=; b=cby3GRwjqagOcgiYiUOANAvfFUpH2tUgYF9HCpOdlTFCxs79jtY2Oekn2x8/FwkoAYJVSAis7kLfyow2CEHA+WMfOKzsuI4Mo2Oj4A7eF7pIbvEzA5fFbNlxkxXYnUUuUNuH/4dsOtYF7fZrK/dgz3111dIqlaP1IZBnfcvT0CTkPHpk9DQdJACsGYNgeKaelZ8CPyNhYKW8IzvEykuVxowJinbaqD/s/CYXdVDYsFCztZxQQgyuN3GIcJaEgNsok551LojbVW9zyGOxDS1ACs69ImuGd51AWJ5v8HbRdySWOervGNLfi9wN+6ercYUUYaQ3YqWyNMRTWaXnNYgl/g== Received: from AM7PR03MB6660.eurprd03.prod.outlook.com (2603:10a6:20b:1c1::22) by HE1PR0302MB2713.eurprd03.prod.outlook.com (2603:10a6:3:ee::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4930.21; Sun, 30 Jan 2022 22:16:18 +0000 Received: from AM7PR03MB6660.eurprd03.prod.outlook.com ([fe80::ac56:2ff4:d304:ab22]) by AM7PR03MB6660.eurprd03.prod.outlook.com ([fe80::ac56:2ff4:d304:ab22%6]) with mapi id 15.20.4930.021; Sun, 30 Jan 2022 22:16:18 +0000 Message-ID: Date: Sun, 30 Jan 2022 23:16:17 +0100 Content-Language: en-US To: ffmpeg-devel@ffmpeg.org References: <20220130220055.2595-1-pal@sandflow.com> <20220130220055.2595-3-pal@sandflow.com> From: Andreas Rheinhardt In-Reply-To: <20220130220055.2595-3-pal@sandflow.com> X-TMN: [kaRP6jiDI24yEChJj9Se97yzNkLlZWgB] X-ClientProxiedBy: FR0P281CA0044.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:48::7) To AM7PR03MB6660.eurprd03.prod.outlook.com (2603:10a6:20b:1c1::22) X-Microsoft-Original-Message-ID: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d10f2421-03d3-4b23-b016-08d9e43e237e X-MS-TrafficTypeDiagnostic: HE1PR0302MB2713:EE_ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PLhATUaj98/fOlPXcgDEvcMyLa6lTrOXbG+W3cVGMLVH2i5kR2UkvxCV3cSnlAsO3AWiy8P5hrPrX6qx3d6nVzm+LWRMqQ9X4ee+r2/Z9E3hhpMgJJgf21VnHjdbIvtxfJoGIFa4ahHRFb5lrpxzLUiH8ANzK9FVVCv6lXv1hHeYmxTUtUaRd3uM1w3HIeXqlQjQZNH3hsYMIyKXzM0y+PYmuBLx0COXvzu8m94Mde86HvFAj9k6tphRLTVk32tykVFt7Ougt/iaDOgmlJoqccn71xZgvd6VrLPWUgSmsHM8BQawJXNtpALEo4M+00XfsyqsGexzyKpkmZPFbynXMQoxsxMyuBZA4ZyjH3qo+AwMZyxpZwLQwccw/XK8ulto9yHSC/0kVTOXcgI8jYs4UyUIaiunW88biTt5vvGdMqR9teuddhFSjpfFb2/laaNWauRye7HAsIdINJa4tm4WvauksycXUlfreFKyjoYCaNFnbmYvo3YFJ7sFfAfOKx6Unk/xc96bvnfrjqqes8IxYsF8tYnUxrkLVMZ/LmAAXCVG+0FXsRkeKbyn7NQwhyCPztM56rS3G6OEhlNE7+NpYA== X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?NXpZQmxxMWMzUlphMW05UWVwSDdyZVhLSDN4b2lnZm9BWXhtVGltZnB0OStE?= =?utf-8?B?VGhHYXgxWHA0SXJyckNlNDNZYWJLbGpqamJRMW13T29GWmZLQ3dpdDBUTk5P?= =?utf-8?B?Nm9Zc1lUS2lqU1pDS3hzZ2l4YUNzaGozUTFyMzcxcUVWUHhPVXI4Vm9uZkVj?= =?utf-8?B?WHFFU3J3UElSZ2Y5VTJOcVc0bXZmdEhWM3NsT1F0Q2pXZnlqalZtbzJ3Nkl5?= =?utf-8?B?M3NENkR0cy9XSk1YRm9zLy9NYVFnZGZ4aHh2V09ibzNQeWd3ai9OaHYvY0xN?= =?utf-8?B?c0RQYVJuV0lKQ2tIdzdDMEtRN2Q5UjlXbENYajdURUE4bHV4NHlWaU94c2lj?= =?utf-8?B?Q3dydlZLb01WeG9PZUd1NDdDMzdnMEp0bzlJZWllamtBdEVweUtqVkJNRk9F?= =?utf-8?B?eEJiZ3NicVBxa0VqUUdnZlFsZEhGT2dXRFBWL1Rab3FLVjRjTHI5VXkyNjUv?= =?utf-8?B?TWNhOFhQTHlEMFg4NGxnblpmOW5tTmVqbzZsYktIUmVXWFUxanJNVXl1eFRi?= =?utf-8?B?citjKzRwZnZKSjVYaGhkQVhGb1NPYXVseGNCM3pwbGFLYlV4QkxpQXhjYnRz?= =?utf-8?B?OHZWNVo5aER0Uk01V0dDbHpKUTk3SUd6aWRCa1dhVFZOK2FwMys2UHpMQldo?= =?utf-8?B?OHhwaVRHTmVqcXlmcU1xcFVqajhFUm9hMzZNa3VMd1dCNW4vRCtJSlcrM09X?= =?utf-8?B?aXlFVEtYSUFkSXE5SEdZOGNLVjFrSTZxM2JON1krSGw0cnpxdm9KUFE5NE0r?= =?utf-8?B?blhhZmFTZmVOU0gzUlFuU1k1VUd5N0JacFZEeUVIUnVWc0YxMngyeDl4aC9o?= =?utf-8?B?N2srU2ZTbWhzWWdZMWxZRFBSaXh3OG5PUkxsejVLRHcrNTBXbHRtWGJhUnBY?= =?utf-8?B?MUR4ZUlsaXV0S2F1Rkd2b1hwY3FtYnhUUVpnWFpUQ2xNS3FUSW82SHNzb0VP?= =?utf-8?B?WjIyUm9WRDdDTHFObWZnSEgwTnFtbkx4N1pEbXg1SGI3QXZhSEpXRWU5WGlK?= =?utf-8?B?b3BxaVZFd0tOVkxPOGVDSFMyU0UwZFJvUjdUK0F0NTNHVXdmK0xRcmlSSEtH?= =?utf-8?B?MG55azY3L2VLZFoya2dTaGwrSU1YWmhRWW9NSWNocjlKVy95UjNINzMwY0FJ?= =?utf-8?B?aHJhWU1iVEJ4b1Rrenk5aFgzaGEvTnBiMitsTTlxOFRFeHdVUkdRZEpiNmRZ?= =?utf-8?B?L2xtTmhEdFFhckZPdE9lRVlyTUsxZzNhMTdJZWRTeE1OS1ZZU1pjMGlITS8r?= =?utf-8?B?d3B0UTNYQWtrb3ZIVFF1TFIwb2wvaHl4Y2F5cld1RzFLLzRMUT09?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: d10f2421-03d3-4b23-b016-08d9e43e237e X-MS-Exchange-CrossTenant-AuthSource: AM7PR03MB6660.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2022 22:16:18.5183 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0302MB2713 Subject: Re: [FFmpeg-devel] [PATCH v1 3/4] avformat/imf: fix packet pts, dts and muxing X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: pal@sandflow.com: > From: Pierre-Anthony Lemieux > > The IMF demuxer does not set the DTS and PTS of packets accurately in all > scenarios. Moreover, audio packets are not trimmed when they exceed the > duration of the underlying resource. > > Closes https://trac.ffmpeg.org/ticket/9611 > > --- > libavformat/imfdec.c | 225 +++++++++++++++++++++++++------------------ > 1 file changed, 132 insertions(+), 93 deletions(-) > > diff --git a/libavformat/imfdec.c b/libavformat/imfdec.c > index 6b50b582f6..05dcb6ff31 100644 > --- a/libavformat/imfdec.c > +++ b/libavformat/imfdec.c > @@ -65,6 +65,7 @@ > #include "avio_internal.h" > #include "imf.h" > #include "internal.h" > +#include "libavcodec/packet.h" > #include "libavutil/avstring.h" > #include "libavutil/bprint.h" > #include "libavutil/opt.h" > @@ -97,6 +98,9 @@ typedef struct IMFVirtualTrackResourcePlaybackCtx { > IMFAssetLocator *locator; > FFIMFTrackFileResource *resource; > AVFormatContext *ctx; > + AVRational start_time; > + AVRational end_time; > + AVRational ts_offset; > } IMFVirtualTrackResourcePlaybackCtx; > > typedef struct IMFVirtualTrackPlaybackCtx { > @@ -108,7 +112,6 @@ typedef struct IMFVirtualTrackPlaybackCtx { > IMFVirtualTrackResourcePlaybackCtx *resources; /**< Buffer holding the resources */ > 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; > > typedef struct IMFContext { > @@ -342,6 +345,7 @@ static int open_track_resource_context(AVFormatContext *s, > int ret = 0; > int64_t entry_point; > AVDictionary *opts = NULL; > + AVStream *st; > > if (track_resource->ctx) { > av_log(s, > @@ -383,23 +387,28 @@ static int open_track_resource_context(AVFormatContext *s, > } > av_dict_free(&opts); > > - /* Compare the source timebase to the resource edit rate, > - * considering the first stream of the source file > - */ > - if (av_cmp_q(track_resource->ctx->streams[0]->time_base, > - av_inv_q(track_resource->resource->base.edit_rate))) > + /* make sure there is only one stream in the file */ > + > + if (track_resource->ctx->nb_streams != 1) { > + ret = AVERROR_INVALIDDATA; > + goto cleanup; > + } > + > + st = track_resource->ctx->streams[0]; > + > + /* Warn if the resource time base does not match the file time base */ > + if (av_cmp_q(st->time_base, av_inv_q(track_resource->resource->base.edit_rate))) > av_log(s, > AV_LOG_WARNING, > - "Incoherent source stream timebase %d/%d regarding resource edit rate: %d/%d", > - track_resource->ctx->streams[0]->time_base.num, > - track_resource->ctx->streams[0]->time_base.den, > + "Incoherent source stream timebase " AVRATIONAL_FORMAT > + "regarding resource edit rate: " AVRATIONAL_FORMAT, > + st->time_base.num, > + st->time_base.den, > track_resource->resource->base.edit_rate.den, > track_resource->resource->base.edit_rate.num); > > - entry_point = (int64_t)track_resource->resource->base.entry_point > - * track_resource->resource->base.edit_rate.den > - * AV_TIME_BASE > - / track_resource->resource->base.edit_rate.num; > + entry_point = av_rescale_q(track_resource->resource->base.entry_point, st->time_base, > + av_inv_q(track_resource->resource->base.edit_rate)); > > if (entry_point) { > av_log(s, > @@ -407,7 +416,7 @@ static int open_track_resource_context(AVFormatContext *s, > "Seek at resource %s entry point: %" PRIu32 "\n", > track_resource->locator->absolute_uri, > track_resource->resource->base.entry_point); > - ret = avformat_seek_file(track_resource->ctx, -1, entry_point, entry_point, entry_point, 0); > + ret = avformat_seek_file(track_resource->ctx, 0, entry_point, entry_point, entry_point, 0); > if (ret < 0) { > av_log(s, > AV_LOG_ERROR, > @@ -470,11 +479,16 @@ static int open_track_file_resource(AVFormatContext *s, > vt_ctx.locator = asset_locator; > vt_ctx.resource = track_file_resource; > vt_ctx.ctx = NULL; > - track->resources[track->resource_count++] = vt_ctx; > - track->duration = av_add_q(track->duration, > + vt_ctx.start_time = track->duration; > + vt_ctx.ts_offset = av_sub_q(vt_ctx.start_time, > + av_div_q(av_make_q((int)track_file_resource->base.entry_point, 1), > + track_file_resource->base.edit_rate)); > + vt_ctx.end_time = av_add_q(track->duration, > av_make_q((int)track_file_resource->base.duration > * track_file_resource->base.edit_rate.den, > track_file_resource->base.edit_rate.num)); > + track->resources[track->resource_count++] = vt_ctx; > + track->duration = vt_ctx.end_time; > } > > return 0; > @@ -701,11 +715,14 @@ static IMFVirtualTrackPlaybackCtx *get_next_track_with_minimum_timestamp(AVForma > return track; > } > > -static IMFVirtualTrackResourcePlaybackCtx *get_resource_context_for_timestamp(AVFormatContext *s, > - IMFVirtualTrackPlaybackCtx *track) > +static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrackPlaybackCtx *track, IMFVirtualTrackResourcePlaybackCtx **resource) > { > - AVRational edit_unit_duration = av_inv_q(track->resources[0].resource->base.edit_rate); > - AVRational cumulated_duration = av_make_q(0, edit_unit_duration.den); > + *resource = NULL; > + > + if (av_cmp_q(track->current_timestamp, track->duration) >= 0) { > + av_log(s, AV_LOG_DEBUG, "Reached the end of the virtual track\n"); > + return AVERROR_EOF; > + } > > av_log(s, > AV_LOG_DEBUG, > @@ -714,119 +731,141 @@ static IMFVirtualTrackResourcePlaybackCtx *get_resource_context_for_timestamp(AV > av_q2d(track->current_timestamp), > av_q2d(track->duration)); > for (uint32_t i = 0; i < track->resource_count; ++i) { > - cumulated_duration = av_add_q(cumulated_duration, > - av_make_q((int)track->resources[i].resource->base.duration > - * edit_unit_duration.num, > - edit_unit_duration.den)); > > - if (av_cmp_q(av_add_q(track->current_timestamp, edit_unit_duration), cumulated_duration) <= 0) { > + if (av_cmp_q(track->resources[i].end_time, track->current_timestamp) > 0) { > av_log(s, > AV_LOG_DEBUG, > - "Found resource %d in track %d to read for timestamp %lf " > - "(on cumulated=%lf): entry=%" PRIu32 > + "Found resource %d in track %d to read at timestamp %lf: " > + "entry=%" PRIu32 > ", duration=%" PRIu32 > - ", editrate=" AVRATIONAL_FORMAT > - " | edit_unit_duration=%lf\n", > + ", editrate=" AVRATIONAL_FORMAT, > i, > track->index, > av_q2d(track->current_timestamp), > - av_q2d(cumulated_duration), > track->resources[i].resource->base.entry_point, > track->resources[i].resource->base.duration, > - AVRATIONAL_ARG(track->resources[i].resource->base.edit_rate), > - av_q2d(edit_unit_duration)); > + AVRATIONAL_ARG(track->resources[i].resource->base.edit_rate)); > > if (track->current_resource_index != i) { > + int ret; > + > av_log(s, > AV_LOG_DEBUG, > "Switch resource on track %d: re-open context\n", > track->index); > - if (open_track_resource_context(s, &(track->resources[i])) != 0) > - return NULL; > + > + ret = open_track_resource_context(s, &(track->resources[i])); > + if (ret != 0) > + return ret; > if (track->current_resource_index > 0) > avformat_close_input(&track->resources[track->current_resource_index].ctx); > track->current_resource_index = i; > } > > - return &(track->resources[track->current_resource_index]); > + *resource = &(track->resources[track->current_resource_index]); > + return 0; > } > } > - return NULL; > + > + av_log(s, AV_LOG_ERROR, "Could not find IMF track resource to read\n"); > + return AVERROR_STREAM_NOT_FOUND; > +} > + > +static int imf_time_to_ts(int64_t *ts, AVRational t, AVRational time_base) > +{ > + int dst_num; > + int dst_den; > + AVRational r; > + > + r = av_div_q(t, time_base); > + > + if ((av_reduce(&dst_num, &dst_den, r.num, r.den, INT64_MAX) != 1)) > + return 0; > + > + if (dst_den != 1) > + return 0; > + > + *ts = dst_num; > + > + return 1; > } > > static int imf_read_packet(AVFormatContext *s, AVPacket *pkt) > { > - IMFContext *c = s->priv_data; > - IMFVirtualTrackResourcePlaybackCtx *resource_to_read = NULL; > - AVRational edit_unit_duration; > + IMFVirtualTrackResourcePlaybackCtx *resource = NULL; > int ret = 0; > IMFVirtualTrackPlaybackCtx *track; > - FFStream *track_stream; > + int64_t delta_ts; > + AVStream *st; > + AVRational next_timestamp; > > track = get_next_track_with_minimum_timestamp(s); > > - if (av_cmp_q(track->current_timestamp, track->duration) == 0) > - return AVERROR_EOF; > + ret = get_resource_context_for_timestamp(s, track, &resource); > + if (ret) > + return ret; > > - resource_to_read = get_resource_context_for_timestamp(s, track); > + ret = av_read_frame(resource->ctx, pkt); > + if (ret) { > + av_log(s, AV_LOG_ERROR, "Failed to read frame\n"); > + return ret; > + } > > - if (!resource_to_read) { > - edit_unit_duration > - = av_inv_q(track->resources[track->current_resource_index].resource->base.edit_rate); > + av_log(s, AV_LOG_DEBUG, "Got packet: pts=%" PRId64 ", dts=%" PRId64 > + ", duration=%" PRId64 ", stream_index=%d, pos=%" PRId64 > + ", time_base=" AVRATIONAL_FORMAT "\n", pkt->pts, pkt->dts, pkt->duration, > + pkt->stream_index, pkt->pos, pkt->time_base.num, pkt->time_base.den); > > - if (av_cmp_q(av_add_q(track->current_timestamp, edit_unit_duration), track->duration) > 0) > - return AVERROR_EOF; > + /* IMF resources contain only one stream */ > > - av_log(s, AV_LOG_ERROR, "Could not find IMF track resource to read\n"); > - return AVERROR_STREAM_NOT_FOUND; > - } > + if (pkt->stream_index != 0) > + return AVERROR_INVALIDDATA; > + st = resource->ctx->streams[0]; > > - while (!ff_check_interrupt(c->interrupt_callback) && !ret) { > - ret = av_read_frame(resource_to_read->ctx, pkt); > - av_log(s, > - AV_LOG_DEBUG, > - "Got packet: pts=%" PRId64 > - ", dts=%" PRId64 > - ", duration=%" PRId64 > - ", stream_index=%d, pos=%" PRId64 > - "\n", > - pkt->pts, > - pkt->dts, > - pkt->duration, > - pkt->stream_index, > - pkt->pos); > - > - track_stream = ffstream(s->streams[track->index]); > - if (ret >= 0) { > - /* Update packet info from track */ > - if (pkt->dts < track_stream->cur_dts && track->last_pts > 0) > - pkt->dts = track_stream->cur_dts; > - > - pkt->pts = track->last_pts; > - pkt->dts = pkt->dts > - - (int64_t)track->resources[track->current_resource_index].resource->base.entry_point; > - pkt->stream_index = track->index; > - > - /* Update track cursors */ > - track->current_timestamp > - = av_add_q(track->current_timestamp, > - av_make_q((int)pkt->duration > - * resource_to_read->ctx->streams[0]->time_base.num, > - resource_to_read->ctx->streams[0]->time_base.den)); > - track->last_pts += pkt->duration; > + pkt->stream_index = track->index; > > - return 0; > - } else if (ret != AVERROR_EOF) { > - av_log(s, > - AV_LOG_ERROR, > - "Could not get packet from track %d: %s\n", > - track->index, > - av_err2str(ret)); > - return ret; > + /* adjust the packet PTS and DTS based on the temporal position of the resource within the timeline */ > + > + if ((imf_time_to_ts(&delta_ts, resource->ts_offset, st->time_base) == 0)) > + av_log(s, AV_LOG_WARNING, "Incoherent time stamp " AVRATIONAL_FORMAT " for time base " AVRATIONAL_FORMAT, > + resource->ts_offset.num, resource->ts_offset.den, pkt->time_base.num, > + pkt->time_base.den); > + if (pkt->pts != AV_NOPTS_VALUE) > + pkt->pts += delta_ts; > + if (pkt->dts != AV_NOPTS_VALUE) > + pkt->dts += delta_ts; > + > + /* advance the track timestamp by the packet duration */ > + > + next_timestamp = av_add_q(track->current_timestamp, > + av_mul_q(av_make_q((int)pkt->duration, 1), st->time_base)); > + > + /* if necessary, clamp the next timestamp to the end of the current resource */ > + > + if (av_cmp_q(next_timestamp, resource->end_time) > 0) { > + > + next_timestamp = resource->end_time; > + > + /* shrink the packet duration */ > + > + if ((imf_time_to_ts(&pkt->duration, av_sub_q(resource->end_time, track->current_timestamp), st->time_base) == 0)) > + av_log(s, AV_LOG_WARNING, "Incoherent time base during packet duration calculation"); > + > + /* shrink the packet size itself for audio samples */ > + /* only AV_CODEC_ID_PCM_S24LE is supported in IMF */ > + > + if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE) { > + int bytes_per_sample = av_get_exact_bits_per_sample(st->codecpar->codec_id) >> 3; > + int64_t nbsamples = av_rescale_q(pkt->duration, st->time_base, av_make_q(1, st->codecpar->sample_rate)); > + av_shrink_packet(pkt, nbsamples * st->codecpar->channels * bytes_per_sample); > + } else { > + av_log(s, AV_LOG_WARNING, "Cannot shrink packets for non-PCM essence"); AV_PKT_DATA_SKIP_SAMPLES > } > } > > - return AVERROR_EOF; > + track->current_timestamp = next_timestamp; > + > + return 0; > } > > static int imf_close(AVFormatContext *s) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".