Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts()
@ 2022-03-11 17:16 pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 2/7] avformat/imf: add support for input seeking pal
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

---
 libavformat/imfdec.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/libavformat/imfdec.c b/libavformat/imfdec.c
index 3ce850b75a..b98af020d2 100644
--- a/libavformat/imfdec.c
+++ b/libavformat/imfdec.c
@@ -154,6 +154,25 @@ static int imf_uri_is_dos_abs_path(const char *string)
     return 0;
 }
 
+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 1;
+
+    if (dst_den != 1)
+        return 1;
+
+    *ts = dst_num;
+
+    return 0;
+}
+
 /**
  * Parse a ASSETMAP XML file to extract the UUID-URI mapping of assets.
  * @param s the current format context, if any (can be NULL).
@@ -772,25 +791,6 @@ static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrac
     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 1;
-
-    if (dst_den != 1)
-        return 1;
-
-    *ts = dst_num;
-
-    return 0;
-}
-
 static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     IMFVirtualTrackResourcePlaybackCtx *resource = NULL;
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH v4 2/7] avformat/imf: add support for input seeking
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
@ 2022-03-11 17:16 ` pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 3/7] avformat/imf: clean-up and reduce logging pal
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

The IMF demuxer did not implement AVInputFormat::read_seek2(), resulting in
inefficient input seeking.

Addresses https://trac.ffmpeg.org/ticket/9648

Byte- and frame-seeking are not supported.

---
 libavformat/imfdec.c | 129 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 102 insertions(+), 27 deletions(-)

diff --git a/libavformat/imfdec.c b/libavformat/imfdec.c
index b98af020d2..f208b262c3 100644
--- a/libavformat/imfdec.c
+++ b/libavformat/imfdec.c
@@ -359,13 +359,15 @@ static IMFAssetLocator *find_asset_map_locator(IMFAssetLocatorMap *asset_map, FF
 }
 
 static int open_track_resource_context(AVFormatContext *s,
-                                       IMFVirtualTrackResourcePlaybackCtx *track_resource)
+                                       IMFVirtualTrackPlaybackCtx *track,
+                                       int32_t resource_index)
 {
     IMFContext *c = s->priv_data;
     int ret = 0;
-    int64_t entry_point;
+    int64_t seek_offset = 0;
     AVDictionary *opts = NULL;
     AVStream *st;
+    IMFVirtualTrackResourcePlaybackCtx *track_resource = track->resources + resource_index;
 
     if (track_resource->ctx) {
         av_log(s,
@@ -416,32 +418,27 @@ static int open_track_resource_context(AVFormatContext *s,
 
     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 " 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 = 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,
-               AV_LOG_DEBUG,
-               "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, 0, entry_point, entry_point, entry_point, 0);
+    /* Determine the seek offset into the Track File, taking into account:
+     * - the current timestamp within the virtual track
+     * - the entry point of the resource
+     */
+    if (imf_time_to_ts(&seek_offset,
+                       av_sub_q(track->current_timestamp, track_resource->ts_offset),
+                       st->time_base))
+        av_log(s, AV_LOG_WARNING, "Incoherent stream timebase " AVRATIONAL_FORMAT
+               "and composition timeline position: " AVRATIONAL_FORMAT "\n",
+               st->time_base.num, st->time_base.den,
+               track->current_timestamp.den, track->current_timestamp.num);
+
+    if (seek_offset) {
+        av_log(s, AV_LOG_DEBUG, "Seek at resource %s entry point: %" PRIi64 "\n",
+               track_resource->locator->absolute_uri, seek_offset);
+        ret = avformat_seek_file(track_resource->ctx, 0, seek_offset, seek_offset, seek_offset, 0);
         if (ret < 0) {
             av_log(s,
                    AV_LOG_ERROR,
                    "Could not seek at %" PRId64 "on %s: %s\n",
-                   entry_point,
+                   seek_offset,
                    track_resource->locator->absolute_uri,
                    av_err2str(ret));
             avformat_close_input(&track_resource->ctx);
@@ -584,7 +581,7 @@ 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]);
+        ret = open_track_resource_context(s, c->tracks[i], 0);
         if (ret)
             return ret;
         first_resource_stream = c->tracks[i]->resources[0].ctx->streams[0];
@@ -774,7 +771,7 @@ static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrac
                        "Switch resource on track %d: re-open context\n",
                        track->index);
 
-                ret = open_track_resource_context(s, track->resources + i);
+                ret = open_track_resource_context(s, track, i);
                 if (ret != 0)
                     return ret;
                 if (track->current_resource_index > 0)
@@ -942,6 +939,83 @@ static int imf_probe(const AVProbeData *p)
     return AVPROBE_SCORE_MAX;
 }
 
+static void rescale_interval(AVRational tb_in, AVRational tb_out,
+                             int64_t *min_ts, int64_t *ts, int64_t *max_ts)
+{
+    *ts = av_rescale_q(*ts, tb_in, tb_out);
+    *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out, AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
+    *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out, AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+}
+
+static int coherent_ts(int64_t ts, AVRational in_tb, AVRational out_tb)
+{
+    int dst_num;
+    int dst_den;
+    int ret;
+
+    ret = av_reduce(&dst_num, &dst_den, ts * in_tb.num * out_tb.den,
+                    in_tb.den * out_tb.num, INT64_MAX);
+    if (!ret || dst_den != 1)
+        return 0;
+
+    return 1;
+}
+
+static int imf_seek(AVFormatContext *s, int stream_index, int64_t min_ts,
+                    int64_t ts, int64_t max_ts, int flags)
+{
+    IMFContext *c = s->priv_data;
+    uint32_t i;
+
+    if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME))
+        return AVERROR(ENOSYS);
+
+    /* rescale timestamps to Composition edit units */
+    if (stream_index < 0)
+        rescale_interval(AV_TIME_BASE_Q,
+                         av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
+                         &min_ts, &ts, &max_ts);
+    else
+        rescale_interval(s->streams[stream_index]->time_base,
+                         av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
+                         &min_ts, &ts, &max_ts);
+
+    /* requested timestamp bounds are too close */
+    if (max_ts < min_ts)
+        return -1;
+
+    /* clamp requested timestamp to provided bounds */
+    ts = FFMAX(FFMIN(ts, max_ts), min_ts);
+
+    av_log(s, AV_LOG_DEBUG, "Seeking to Composition Playlist edit unit %" PRIi64 "\n", ts);
+
+    /* set the dts of each stream and temporal offset of each track */
+    for (i = 0; i < c->track_count; i++) {
+        AVStream *st = s->streams[i];
+        IMFVirtualTrackPlaybackCtx *t = c->tracks[i];
+        int64_t dts;
+
+        if (!coherent_ts(ts, av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
+                         st->time_base))
+            av_log(s, AV_LOG_WARNING, "Seek position is not coherent across tracks\n");
+
+        dts = av_rescale(ts,
+                         st->time_base.den * c->cpl->edit_rate.den,
+                         st->time_base.num * c->cpl->edit_rate.num);
+
+        av_log(s, AV_LOG_DEBUG, "Seeking to dts=%" PRId64 " on stream_index=%d\n",
+               dts, i);
+
+        t->current_timestamp = av_mul_q(av_make_q(dts, 1), st->time_base);
+        if (t->current_resource_index >= 0) {
+            avformat_close_input(&t->resources[t->current_resource_index].ctx);
+            t->current_resource_index = -1;
+        }
+    }
+
+    return 0;
+}
+
 static const AVOption imf_options[] = {
     {
         .name        = "assetmaps",
@@ -966,7 +1040,7 @@ static const AVClass imf_class = {
 const AVInputFormat ff_imf_demuxer = {
     .name           = "imf",
     .long_name      = NULL_IF_CONFIG_SMALL("IMF (Interoperable Master Format)"),
-    .flags          = AVFMT_EXPERIMENTAL,
+    .flags          = AVFMT_EXPERIMENTAL | AVFMT_NO_BYTE_SEEK,
     .flags_internal = FF_FMT_INIT_CLEANUP,
     .priv_class     = &imf_class,
     .priv_data_size = sizeof(IMFContext),
@@ -974,4 +1048,5 @@ const AVInputFormat ff_imf_demuxer = {
     .read_header    = imf_read_header,
     .read_packet    = imf_read_packet,
     .read_close     = imf_close,
+    .read_seek2     = imf_seek,
 };
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH v4 3/7] avformat/imf: clean-up and reduce logging
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 2/7] avformat/imf: add support for input seeking pal
@ 2022-03-11 17:16 ` pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 4/7] avformat/seek: add ff_rescale_interval() function pal
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

---
 libavformat/imfdec.c | 93 ++++++++++++++------------------------------
 1 file changed, 29 insertions(+), 64 deletions(-)

diff --git a/libavformat/imfdec.c b/libavformat/imfdec.c
index f208b262c3..ac212b05e1 100644
--- a/libavformat/imfdec.c
+++ b/libavformat/imfdec.c
@@ -203,11 +203,8 @@ static int parse_imf_asset_map_from_xml_dom(AVFormatContext *s,
     }
 
     if (asset_map_element->type != XML_ELEMENT_NODE || av_strcasecmp(asset_map_element->name, "AssetMap")) {
-        av_log(s,
-               AV_LOG_ERROR,
-               "Unable to parse asset map XML - wrong root node name[%s] type[%d]\n",
-               asset_map_element->name,
-               (int)asset_map_element->type);
+        av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - wrong root node name[%s] type[%d]\n",
+               asset_map_element->name, (int)asset_map_element->type);
         return AVERROR_INVALIDDATA;
     }
 
@@ -333,11 +330,8 @@ static int parse_assetmap(AVFormatContext *s, const char *url)
 
     ret = parse_imf_asset_map_from_xml_dom(s, doc, &c->asset_locator_map, base_url);
     if (!ret)
-        av_log(s,
-               AV_LOG_DEBUG,
-               "Found %d assets from %s\n",
-               c->asset_locator_map.asset_count,
-               url);
+        av_log(s, AV_LOG_DEBUG, "Found %d assets from %s\n",
+               c->asset_locator_map.asset_count, url);
 
     xmlFreeDoc(doc);
 
@@ -370,9 +364,7 @@ static int open_track_resource_context(AVFormatContext *s,
     IMFVirtualTrackResourcePlaybackCtx *track_resource = track->resources + resource_index;
 
     if (track_resource->ctx) {
-        av_log(s,
-               AV_LOG_DEBUG,
-               "Input context already opened for %s.\n",
+        av_log(s, AV_LOG_DEBUG, "Input context already opened for %s.\n",
                track_resource->locator->absolute_uri);
         return 0;
     }
@@ -400,11 +392,8 @@ static int open_track_resource_context(AVFormatContext *s,
                               NULL,
                               &opts);
     if (ret < 0) {
-        av_log(s,
-               AV_LOG_ERROR,
-               "Could not open %s input context: %s\n",
-               track_resource->locator->absolute_uri,
-               av_err2str(ret));
+        av_log(s, AV_LOG_ERROR, "Could not open %s input context: %s\n",
+               track_resource->locator->absolute_uri, av_err2str(ret));
         goto cleanup;
     }
     av_dict_free(&opts);
@@ -427,8 +416,7 @@ static int open_track_resource_context(AVFormatContext *s,
                        st->time_base))
         av_log(s, AV_LOG_WARNING, "Incoherent stream timebase " AVRATIONAL_FORMAT
                "and composition timeline position: " AVRATIONAL_FORMAT "\n",
-               st->time_base.num, st->time_base.den,
-               track->current_timestamp.den, track->current_timestamp.num);
+               AVRATIONAL_ARG(st->time_base), AVRATIONAL_ARG(track->current_timestamp));
 
     if (seek_offset) {
         av_log(s, AV_LOG_DEBUG, "Seek at resource %s entry point: %" PRIi64 "\n",
@@ -465,9 +453,7 @@ static int open_track_file_resource(AVFormatContext *s,
 
     asset_locator = find_asset_map_locator(&c->asset_locator_map, track_file_resource->track_file_uuid);
     if (!asset_locator) {
-        av_log(s,
-               AV_LOG_ERROR,
-               "Could not find asset locator for UUID: " FF_IMF_UUID_FORMAT "\n",
+        av_log(s, AV_LOG_ERROR, "Could not find asset locator for UUID: " FF_IMF_UUID_FORMAT "\n",
                UID_ARG(track_file_resource->track_file_uuid));
         return AVERROR_INVALIDDATA;
     }
@@ -618,9 +604,7 @@ static int open_cpl_tracks(AVFormatContext *s)
 
     if (c->cpl->main_image_2d_track) {
         if ((ret = open_virtual_track(s, c->cpl->main_image_2d_track, track_index++)) != 0) {
-            av_log(s,
-                   AV_LOG_ERROR,
-                   "Could not open image track " FF_IMF_UUID_FORMAT "\n",
+            av_log(s, AV_LOG_ERROR, "Could not open image track " FF_IMF_UUID_FORMAT "\n",
                    UID_ARG(c->cpl->main_image_2d_track->base.id_uuid));
             return ret;
         }
@@ -628,9 +612,7 @@ static int open_cpl_tracks(AVFormatContext *s)
 
     for (uint32_t i = 0; i < c->cpl->main_audio_track_count; i++) {
         if ((ret = open_virtual_track(s, &c->cpl->main_audio_tracks[i], track_index++)) != 0) {
-            av_log(s,
-                   AV_LOG_ERROR,
-                   "Could not open audio track " FF_IMF_UUID_FORMAT "\n",
+            av_log(s, AV_LOG_ERROR, "Could not open audio track " FF_IMF_UUID_FORMAT "\n",
                    UID_ARG(c->cpl->main_audio_tracks[i].base.id_uuid));
             return ret;
         }
@@ -706,13 +688,9 @@ static IMFVirtualTrackPlaybackCtx *get_next_track_with_minimum_timestamp(AVForma
 
     AVRational minimum_timestamp = av_make_q(INT32_MAX, 1);
     for (uint32_t i = c->track_count; i > 0; i--) {
-        av_log(s,
-               AV_LOG_DEBUG,
-               "Compare track %d timestamp " AVRATIONAL_FORMAT
+        av_log(s, AV_LOG_TRACE, "Compare track %d timestamp " AVRATIONAL_FORMAT
                " to minimum " AVRATIONAL_FORMAT
-               " (over duration: " AVRATIONAL_FORMAT
-               ")\n",
-               i,
+               " (over duration: " AVRATIONAL_FORMAT ")\n", i,
                AVRATIONAL_ARG(c->tracks[i - 1]->current_timestamp),
                AVRATIONAL_ARG(minimum_timestamp),
                AVRATIONAL_ARG(c->tracks[i - 1]->duration));
@@ -723,12 +701,8 @@ static IMFVirtualTrackPlaybackCtx *get_next_track_with_minimum_timestamp(AVForma
         }
     }
 
-    av_log(s,
-           AV_LOG_DEBUG,
-           "Found next track to read: %d (timestamp: %lf / %lf)\n",
-           track->index,
-           av_q2d(track->current_timestamp),
-           av_q2d(minimum_timestamp));
+    av_log(s, AV_LOG_DEBUG, "Found next track to read: %d (timestamp: %lf / %lf)\n",
+           track->index, av_q2d(track->current_timestamp), av_q2d(minimum_timestamp));
     return track;
 }
 
@@ -742,7 +716,7 @@ static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrac
     }
 
     av_log(s,
-           AV_LOG_DEBUG,
+           AV_LOG_TRACE,
            "Looking for track %d resource for timestamp = %lf / %lf\n",
            track->index,
            av_q2d(track->current_timestamp),
@@ -750,15 +724,9 @@ static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrac
     for (uint32_t i = 0; i < track->resource_count; i++) {
 
         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 at timestamp %lf: "
-                   "entry=%" PRIu32
-                   ", duration=%" PRIu32
-                   ", editrate=" AVRATIONAL_FORMAT,
-                   i,
-                   track->index,
-                   av_q2d(track->current_timestamp),
+            av_log(s, AV_LOG_DEBUG, "Found resource %d in track %d to read at timestamp %lf: "
+                   "entry=%" PRIu32 ", duration=%" PRIu32 ", editrate=" AVRATIONAL_FORMAT "\n",
+                   i, track->index, av_q2d(track->current_timestamp),
                    track->resources[i].resource->base.entry_point,
                    track->resources[i].resource->base.duration,
                    AVRATIONAL_ARG(track->resources[i].resource->base.edit_rate));
@@ -766,9 +734,7 @@ static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrac
             if (track->current_resource_index != i) {
                 int ret;
 
-                av_log(s,
-                       AV_LOG_DEBUG,
-                       "Switch resource on track %d: re-open context\n",
+                av_log(s, AV_LOG_TRACE, "Switch resource on track %d: re-open context\n",
                        track->index);
 
                 ret = open_track_resource_context(s, track, i);
@@ -804,15 +770,13 @@ static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
         return ret;
 
     ret = av_read_frame(resource->ctx, pkt);
-    if (ret) {
-        av_log(s, AV_LOG_ERROR, "Failed to read frame\n");
+    if (ret)
         return ret;
-    }
 
     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);
+            pkt->stream_index, pkt->pos, AVRATIONAL_ARG(pkt->time_base));
 
     /* IMF resources contain only one stream */
 
@@ -832,9 +796,10 @@ static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
         if (pkt->dts != AV_NOPTS_VALUE)
             pkt->dts += delta_ts;
     } else {
-        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);
+        av_log(s, AV_LOG_WARNING, "Incoherent time stamp " AVRATIONAL_FORMAT
+               " for time base " AVRATIONAL_FORMAT,
+               AVRATIONAL_ARG(resource->ts_offset),
+               AVRATIONAL_ARG(pkt->time_base));
     }
 
     /* advance the track timestamp by the packet duration */
@@ -857,7 +822,7 @@ static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
         if (!ret)
             pkt->duration = new_pkt_dur;
         else
-            av_log(s, AV_LOG_WARNING, "Incoherent time base in packet duration calculation");
+            av_log(s, AV_LOG_WARNING, "Incoherent time base in packet duration calculation\n");
 
         /* shrink the packet itself for audio essence */
 
@@ -882,7 +847,7 @@ static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
                                      av_make_q(1, st->codecpar->sample_rate));
 
                 if (ret || skip_samples < 0 || skip_samples > UINT32_MAX) {
-                    av_log(s, AV_LOG_WARNING, "Cannot skip audio samples");
+                    av_log(s, AV_LOG_WARNING, "Cannot skip audio samples\n");
                 } else {
                     uint8_t *side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
                     if (!side_data)
@@ -896,7 +861,7 @@ static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
             next_timestamp = resource->end_time;
 
         } else {
-            av_log(s, AV_LOG_WARNING, "Non-audio packet duration reduced");
+            av_log(s, AV_LOG_WARNING, "Non-audio packet duration reduced\n");
         }
     }
 
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH v4 4/7] avformat/seek: add ff_rescale_interval() function
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 2/7] avformat/imf: add support for input seeking pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 3/7] avformat/imf: clean-up and reduce logging pal
@ 2022-03-11 17:16 ` pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 5/7] avformat/tests: add test for ff_rescale_interval() pal
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

Refactors a function used by avformat/concat and avformat/imf.

---
 libavformat/internal.h | 20 ++++++++++++++++++++
 libavformat/seek.c     | 10 ++++++++++
 2 files changed, 30 insertions(+)

diff --git a/libavformat/internal.h b/libavformat/internal.h
index f24c68703f..5529403a68 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -1023,4 +1023,24 @@ void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputForm
  */
 int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size);
 
+/**
+ * Rescales a timestamp and the endpoints of an interval to which the temstamp
+ * belongs, from a timebase `tb_in` to a timebase `tb_out`.
+ *
+ * The upper (lower) bound of the output interval is rounded up (down) such that
+ * the output interval always falls within the intput interval. The timestamp is
+ * rounded to the nearest integer and halfway cases away from zero, and can
+ * therefore fall outside of the output interval.
+ * 
+ * Useful to simplify the rescaling of the arguments of AVInputFormat::read_seek2()
+ *
+ * @param[in] tb_in      Timebase of the input `min_ts`, `ts` and `max_ts`
+ * @param[in] tb_out     Timebase of the ouput `min_ts`, `ts` and `max_ts`
+ * @param[in,out] min_ts Lower bound of the interval
+ * @param[in,out] ts     Timestamp
+ * @param[in,out] max_ts Upper bound of the interval
+ */
+void ff_rescale_interval(AVRational tb_in, AVRational tb_out,
+                         int64_t *min_ts, int64_t *ts, int64_t *max_ts);
+
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 405ca316b3..890aea7f8a 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -751,3 +751,13 @@ int avformat_flush(AVFormatContext *s)
     ff_read_frame_flush(s);
     return 0;
 }
+
+void ff_rescale_interval(AVRational tb_in, AVRational tb_out,
+                         int64_t *min_ts, int64_t *ts, int64_t *max_ts)
+{
+    *ts     = av_rescale_q    (*    ts, tb_in, tb_out);
+    *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out,
+                               AV_ROUND_UP   | AV_ROUND_PASS_MINMAX);
+    *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out,
+                               AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+}
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH v4 5/7] avformat/tests: add test for ff_rescale_interval()
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
                   ` (2 preceding siblings ...)
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 4/7] avformat/seek: add ff_rescale_interval() function pal
@ 2022-03-11 17:16 ` pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 6/7] avformat/imf: refactor to use ff_rescale_interval() pal
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

---
 libavformat/Makefile           |  1 +
 libavformat/tests/.gitignore   |  1 +
 libavformat/tests/seek_utils.c | 57 ++++++++++++++++++++++++++++++++++
 tests/fate/libavformat.mak     |  5 +++
 4 files changed, 64 insertions(+)
 create mode 100644 libavformat/tests/seek_utils.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 6566e40cac..3acc939551 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -707,6 +707,7 @@ SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
 
 TESTPROGS = seek                                                        \
             url                                                         \
+            seek_utils
 #           async                                                       \
 
 FIFO-MUXER-TESTPROGS-$(CONFIG_NETWORK)   += fifo_muxer
diff --git a/libavformat/tests/.gitignore b/libavformat/tests/.gitignore
index aabf76345e..cdd0cce061 100644
--- a/libavformat/tests/.gitignore
+++ b/libavformat/tests/.gitignore
@@ -6,3 +6,4 @@
 /seek
 /srtp
 /url
+/seek_utils
diff --git a/libavformat/tests/seek_utils.c b/libavformat/tests/seek_utils.c
new file mode 100644
index 0000000000..cc679dca05
--- /dev/null
+++ b/libavformat/tests/seek_utils.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Pierre-Anthony Lemieux <pal@palemieux.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavformat/internal.h"
+
+int main(void)
+{
+  int64_t ts_min;
+  int64_t ts;
+  int64_t ts_max;
+
+  ts_min = 10;
+  ts     = 20;
+  ts_max = 30;
+
+  ff_rescale_interval(av_make_q(1, 1), av_make_q(10, 1), &ts_min, &ts, &ts_max);
+
+  if (ts_min != 1 || ts != 2 || ts_max != 3)
+    return 1;
+
+  ts_min = 10;
+  ts     = 32;
+  ts_max = 32;
+
+  ff_rescale_interval(av_make_q(1, 1), av_make_q(3, 1), &ts_min, &ts, &ts_max);
+
+  if (ts_min != 4 || ts != 11 || ts_max != 10)
+    return 1;
+
+  ts_min = 10;
+  ts     = 10;
+  ts_max = 32;
+
+  ff_rescale_interval(av_make_q(1, 1), av_make_q(3, 1), &ts_min, &ts, &ts_max);
+
+  if (ts_min != 4 || ts != 3 || ts_max != 10)
+    return 1;
+
+  return 0;
+}
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index 59ff0ebc8d..d2acb4c9e0 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -26,6 +26,11 @@ FATE_LIBAVFORMAT-$(CONFIG_IMF_DEMUXER) += fate-imf
 fate-imf: libavformat/tests/imf$(EXESUF)
 fate-imf: CMD = run libavformat/tests/imf$(EXESUF)
 
+FATE_LIBAVFORMAT += fate-seek_utils
+fate-seek_utils: libavformat/tests/seek_utils$(EXESUF)
+fate-seek_utils: CMD = run libavformat/tests/seek_utils$(EXESUF)
+fate-seek_utils: CMP = null
+
 FATE_LIBAVFORMAT += $(FATE_LIBAVFORMAT-yes)
 FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT)
 fate-libavformat: $(FATE_LIBAVFORMAT)
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH v4 6/7] avformat/imf: refactor to use ff_rescale_interval()
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
                   ` (3 preceding siblings ...)
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 5/7] avformat/tests: add test for ff_rescale_interval() pal
@ 2022-03-11 17:16 ` pal
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 7/7] avformat/concat: " pal
  2022-03-12  2:36 ` [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() Zane van Iperen
  6 siblings, 0 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

---
 libavformat/imfdec.c | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/libavformat/imfdec.c b/libavformat/imfdec.c
index ac212b05e1..a19e431df3 100644
--- a/libavformat/imfdec.c
+++ b/libavformat/imfdec.c
@@ -904,14 +904,6 @@ static int imf_probe(const AVProbeData *p)
     return AVPROBE_SCORE_MAX;
 }
 
-static void rescale_interval(AVRational tb_in, AVRational tb_out,
-                             int64_t *min_ts, int64_t *ts, int64_t *max_ts)
-{
-    *ts = av_rescale_q(*ts, tb_in, tb_out);
-    *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out, AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
-    *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out, AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
-}
-
 static int coherent_ts(int64_t ts, AVRational in_tb, AVRational out_tb)
 {
     int dst_num;
@@ -937,13 +929,13 @@ static int imf_seek(AVFormatContext *s, int stream_index, int64_t min_ts,
 
     /* rescale timestamps to Composition edit units */
     if (stream_index < 0)
-        rescale_interval(AV_TIME_BASE_Q,
-                         av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
-                         &min_ts, &ts, &max_ts);
+        ff_rescale_interval(AV_TIME_BASE_Q,
+                            av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
+                            &min_ts, &ts, &max_ts);
     else
-        rescale_interval(s->streams[stream_index]->time_base,
-                         av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
-                         &min_ts, &ts, &max_ts);
+        ff_rescale_interval(s->streams[stream_index]->time_base,
+                            av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
+                            &min_ts, &ts, &max_ts);
 
     /* requested timestamp bounds are too close */
     if (max_ts < min_ts)
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH v4 7/7] avformat/concat: refactor to use ff_rescale_interval()
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
                   ` (4 preceding siblings ...)
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 6/7] avformat/imf: refactor to use ff_rescale_interval() pal
@ 2022-03-11 17:16 ` pal
  2022-03-12  2:36 ` [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() Zane van Iperen
  6 siblings, 0 replies; 8+ messages in thread
From: pal @ 2022-03-11 17:16 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pierre-Anthony Lemieux

From: Pierre-Anthony Lemieux <pal@palemieux.com>

---
 libavformat/concatdec.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index 0603c6e254..cfe1329105 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -816,16 +816,6 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
     return 0;
 }
 
-static void rescale_interval(AVRational tb_in, AVRational tb_out,
-                             int64_t *min_ts, int64_t *ts, int64_t *max_ts)
-{
-    *ts     = av_rescale_q    (*    ts, tb_in, tb_out);
-    *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out,
-                               AV_ROUND_UP   | AV_ROUND_PASS_MINMAX);
-    *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out,
-                               AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
-}
-
 static int try_seek(AVFormatContext *avf, int stream,
                     int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
 {
@@ -838,8 +828,8 @@ static int try_seek(AVFormatContext *avf, int stream,
     if (stream >= 0) {
         if (stream >= cat->avf->nb_streams)
             return AVERROR(EIO);
-        rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
-                         &min_ts, &ts, &max_ts);
+        ff_rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
+                            &min_ts, &ts, &max_ts);
     }
     return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags);
 }
@@ -853,8 +843,8 @@ static int real_seek(AVFormatContext *avf, int stream,
     if (stream >= 0) {
         if (stream >= avf->nb_streams)
             return AVERROR(EINVAL);
-        rescale_interval(avf->streams[stream]->time_base, AV_TIME_BASE_Q,
-                         &min_ts, &ts, &max_ts);
+        ff_rescale_interval(avf->streams[stream]->time_base, AV_TIME_BASE_Q,
+                            &min_ts, &ts, &max_ts);
     }
 
     left  = 0;
-- 
2.17.1

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts()
  2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
                   ` (5 preceding siblings ...)
  2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 7/7] avformat/concat: " pal
@ 2022-03-12  2:36 ` Zane van Iperen
  6 siblings, 0 replies; 8+ messages in thread
From: Zane van Iperen @ 2022-03-12  2:36 UTC (permalink / raw)
  To: ffmpeg-devel

lgtm. Will apply in a few days.

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-03-12  2:36 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-11 17:16 [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() pal
2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 2/7] avformat/imf: add support for input seeking pal
2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 3/7] avformat/imf: clean-up and reduce logging pal
2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 4/7] avformat/seek: add ff_rescale_interval() function pal
2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 5/7] avformat/tests: add test for ff_rescale_interval() pal
2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 6/7] avformat/imf: refactor to use ff_rescale_interval() pal
2022-03-11 17:16 ` [FFmpeg-devel] [PATCH v4 7/7] avformat/concat: " pal
2022-03-12  2:36 ` [FFmpeg-devel] [PATCH v4 1/7] avformat/imf: relocate static function imf_time_to_ts() Zane van Iperen

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git