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 A4DAA40872 for ; Tue, 1 Feb 2022 04:51:41 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0621468B1BB; Tue, 1 Feb 2022 06:51:39 +0200 (EET) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05olkn2085.outbound.protection.outlook.com [40.92.89.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 810FB68AF5C for ; Tue, 1 Feb 2022 06:51:32 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gh7J0glYBDv8BOFTPIdQMtCW44CNdyFT1XOLDtZ2zYMROhg2tNgUUvGZQWjX95CwAZ+FsoQtJB1cadb9XcYdfOcbaScQbkeDsArxSBt4/M7ZkPy93+OIxfmK6979fn8qnlAYu+Xt8ZbhfkWzBJ5gyyUpgwX4yP9utmBes1BM5IUJWDFtgb/SbZrYK8ySSfbOutIPgSTDjLQi2hzLRswBdN2uueH8LrYbc90kj2zGbkSpmu6yiSIpcC+0zHs384u5NB27hIL5J8OG+K2cb5hefUiGbRfGikRZB9EmgRbehxTe2OET/zYEw44w31eQ+t4pHXkG5g3qC73T/pyGD9WRnw== 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=DSXwrBo5TFu1fNmpIwQvMMXqfuiCbW8UxFebBKlZmhI=; b=CaHZN+v3Dw0YOiZF+ol3GbettN05IWE5Xh7pPPZpiMg7MSxaFzFB6qU3WlacxaArDjqEaaRO4N7SPZWbf39FaJDBlHLR7QbpMbIDeA0UoTx3VKba7oixhPoKuXHGMvdffMTU+a7SUmM6H4o5DTTUeHJ+YyK8IDUGXMfPZnGv+Cn9207/ZM+LCoAznV0RLuLUhcrK1JtomwISqe5lymTDzWNNDBId2n5+6YSc5xyfCo7b/E3eV1KItI7akh6kjVHP+uykPHMMI30rFRwRHFH63cu7LQ5ijhJQxRu7QDnL6/kfglqHepjL5P7z38Q5z6/QQQo+DntnX9Pi2jo4Vh8DEA== 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=DSXwrBo5TFu1fNmpIwQvMMXqfuiCbW8UxFebBKlZmhI=; b=Jgs3GuADd33aR3vJgII9lL9nl2w7OjyrxGZBjFF0uSD1l+b4Rg/PEuHStrKRHodHqTQloH590YRjzO89u8P6gOpLKeCrMw9Z+HOBbPL7XParLj7PUlojaIfGu/+5WeQykOKD5rM9Dn/z7WcUFlNk0EsNSDiLDlOmPJ/Jd4trXJGtILfgy3nSNnfzIxMBetoZRGnPnQZn+wrbK23XF7+3NsrlRuAZZDtDO//h0N4A+W0uKq/7jc8kYd/zg78mYJKcwqbyEO5RJ8NeKCTW4WJd0mfNFtrry+YuJ4oKi/BEKYM+s6P8emtIQq/dQtrxrcVOivVjAA8yFLXNPQqnSpVZkQ== Received: from PR3PR03MB6665.eurprd03.prod.outlook.com (2603:10a6:102:7d::6) by DB3PR0302MB3273.eurprd03.prod.outlook.com (2603:10a6:8:9::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4930.21; Tue, 1 Feb 2022 04:36:39 +0000 Received: from PR3PR03MB6665.eurprd03.prod.outlook.com ([fe80::a114:1ab8:c6:582f]) by PR3PR03MB6665.eurprd03.prod.outlook.com ([fe80::a114:1ab8:c6:582f%9]) with mapi id 15.20.4930.022; Tue, 1 Feb 2022 04:36:39 +0000 Message-ID: Date: Tue, 1 Feb 2022 05:36:38 +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: X-TMN: [CCIMvAnxnxHzZn46SpnxGcGlV6z0AEbx] X-ClientProxiedBy: AM6P194CA0099.EURP194.PROD.OUTLOOK.COM (2603:10a6:209:8f::40) To PR3PR03MB6665.eurprd03.prod.outlook.com (2603:10a6:102:7d::6) X-Microsoft-Original-Message-ID: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9956703f-2582-423f-2741-08d9e53c703b X-MS-TrafficTypeDiagnostic: DB3PR0302MB3273:EE_ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: BiC0Z65VMmOsjbAv+9SojWNsWZW1u4hjo26Ut1JRBEsjR/PluBP/q0nSBN82EaAO/or2nvvBMe8PZV+n6dGg6Wr5RHdIbYFT6d3S6LCNv6WETkzPF2U4qsUfQzP5YXV3tZguRVB9kJ+xPslOVFw4cuLGWi0ubyIMQ1I9CPN80q+QGo9th68NVrwkaFWK4hlCQVJ3SA0ATEXW0sJrrdjRFZfC/eGrVSuzPUlXMIvbFmx6eiJjGOJrOy3PfUl0yuw0R88Ho97DTSA2m9XCdRk6j3dKQ+tN67CH/j0Zn94mN3EpMGg7lsl1rTscbv9tM0QZsJdNOKu2FJLNowVCUcGjawM4H2GS/AYN1/8cjfGJYvNFKCUiwzOuTLjEz761dF6Fzg91CcnJyhFaIeEdH4YCUY38ju5RH3ZuKvxePEP7fE/GMHLv8T3hmNQd2I/wTJswS1Ja9KcfYzkKPlmS1o5OngmcFFbTfMZ2wAlP0iKjCz+Q6htloRNN/0dTjqqQ6kPY1hBiDcj46H9Cvmam80h0kCl+oil5MkVrkBcIYNVkXwv9HnyAYWES5/2dvcarzmC9d6Qj0R5lwHpjqWUgWE1crw== X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?MWliMDlEbU5DQ1FFTm9VNlNrQjJUdlB0aFVEZFRqNkthRDVlbGdYMWlJMURK?= =?utf-8?B?QlV3OVRJUTRsa2VtejVaZ3FGN3hIQ1dtTlY2aDdrRVB1V2dSa1dmUU9sMmhR?= =?utf-8?B?NmVaaTBPZkJ2SXIvL1RCL2JaOC9FVzRsdnZRTVVYaVpXcFpOUDFGS1RjUVhN?= =?utf-8?B?b2V5UGYraUZib2RjRE5FZlIyV251VDBPSDRNbHN4K2ZOZC90aXVlYTZQZit5?= =?utf-8?B?bXEyWU81ckYxSHl1aHdDSy9TMEwvbnBGSDZYTktyT1ZWdkFyYkQySlYwcWtK?= =?utf-8?B?a21UTkI3dVlNbHdKQlhXK0toWmw2Y3BDZHhYc05HM29IczJ5Z3RnRGgzVDV6?= =?utf-8?B?MjZ3VCtSZTN5cFVZbHBlL2l3K3Q1TmhZVzBQVTVPZUxmYTdmaitGL0pzTDFL?= =?utf-8?B?UERxQjJIcW1ocDN5UkFabU5YNTlIclNDdXVidmlUSWFkQ3pHQzNrbEc1dytX?= =?utf-8?B?bjFFSVp5R3BISVIrZjQyS01QZzllb3pTbnpnM29nWS95VFZFNU1zU1FTWnhQ?= =?utf-8?B?ODZIK0VuVGsxQXJVMlVzNnhoQUZSWnpmTzFIRDkrOFp0ejhyczBUeGhDTm9H?= =?utf-8?B?cUNWSzFyV1VlbG9OYWZKTHc4c3J2N3lQbWFsNVYwUEFONFkzS2hzMlRhNnNG?= =?utf-8?B?enZkTy9SazNRcGtCZlkra05XalppZXppUFI3K2hZUnBxOGozNTEySG8rWTM0?= =?utf-8?B?bjhxU2NuVzRsUFZ0dmluaGlrL0pFUTZSTDBQaVFjNFR0T0owL015OENwT0Iv?= =?utf-8?B?YW1JNVRSZm1LMWlpWmwyM0kxQnpGTUYyd0JxbFJuaTcvdHR2aGhlaXBRbW9O?= =?utf-8?B?eVdQSHhSOVA1RDE3NHJqVG1JSExDZUxNUVVvajd4a0g1dFprWXYyVkZ4VkhK?= =?utf-8?B?ODlwWk1MYWc3Zm54c0ttSzIraXN2WG5UL09odzJwczlRQWlDR3doWFVMTXZF?= =?utf-8?B?dytwdThHV1JoWFRRSmR2VmExMXpibkJvSDhWak9xd1YzY2JMdW1oT3VlV3Nx?= =?utf-8?B?ZUtqQnk4YW1GRC8rMUtrMU00dGc5R0VFd01GUmdhOE03WktDMEgxR2wvL0lP?= =?utf-8?B?MW0yaGZIQ3pTWW03dzFYOHh6ZTNGRENPZ1htQmIyK2ZiOWZRMStWRWVMdld3?= =?utf-8?B?YU1oSXpiMmFHa0VFUUp6cm4yNFBjY2U0aElyUjJ5SGtUVk5kdjFoc3Vzekp0?= =?utf-8?B?R0VuVTArUDVFNTlNSGhycCtYK3dCWW5RZHB6bVZQbklwandSRThQTjV6NlI0?= =?utf-8?B?bmo0ZUVoS2Z4Q0tqWStXU1pYblJxbDhhQXBRQUZRenA3TVRQQT09?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9956703f-2582-423f-2741-08d9e53c703b X-MS-Exchange-CrossTenant-AuthSource: PR3PR03MB6665.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Feb 2022 04:36:39.5546 (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: DB3PR0302MB3273 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: Pierre-Anthony Lemieux: > On Sun, Jan 30, 2022 at 2:16 PM Andreas Rheinhardt > wrote: >> >> 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 > > Ok. Would the "reason for end skip" be 1 (convergence)? > I guess so given that this is not the end of the logical track. - Andreas _______________________________________________ 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".