[FFmpeg-devel] [PATCH v2 5/5] libdc1394: Fix PTS wrapping

Forest Crossman cyrozap at gmail.com
Fri Oct 16 00:30:39 EEST 2020


Without this, the timestamp will unexpectedly wrap around after
approximately 2146 frames (on a 64-bit system, at least), which is about
19 minutes at the lowest framerate supported by the IIDC standard and
about 9 seconds at the highest supported framerate.

To fix this, we use av_rescale() to do the PTS calculation, then we
change both the current_frame and frame_rate variables to int64_t (for
consistency) and keep the PTS wraparound bits set to 64. For all intents
and purposes, however, the PTS will never wrap around, because even at
240 fps--the highest framerate supported by the IIDC standard--it would
take over 292 million years of continuous recording before an overflow
would occur.

Signed-off-by: Forest Crossman <cyrozap at gmail.com>
---
 libavdevice/libdc1394.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c
index 90252f7c4a..1e138edac2 100644
--- a/libavdevice/libdc1394.c
+++ b/libavdevice/libdc1394.c
@@ -40,8 +40,8 @@ typedef struct dc1394_data {
     dc1394_t *d;
     dc1394camera_t *camera;
     dc1394video_frame_t *frame;
-    int current_frame;
-    int  frame_rate;        /**< frames per 1000 seconds (fps * 1000) */
+    int64_t current_frame;
+    int64_t frame_rate;     /**< frames per 1000 seconds (fps * 1000) */
     char *video_size;       /**< String describing video size, set by a private option. */
     char *pixel_format;     /**< Set by a private option. */
     char *framerate;        /**< Set by a private option. */
@@ -133,8 +133,8 @@ static inline int dc1394_read_common(AVFormatContext *c,
              break;
 
     if (!fps->frame_rate || !fmt->width) {
-        av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", av_get_pix_fmt_name(pix_fmt),
-                                                                                                width, height, dc1394->frame_rate);
+        av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%"PRId64":1000fps\n",
+               av_get_pix_fmt_name(pix_fmt), width, height, dc1394->frame_rate);
         ret = AVERROR(EINVAL);
         goto out;
     }
@@ -342,14 +342,14 @@ static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt)
     /* discard stale frame */
     if (dc1394->current_frame++) {
         if (dc1394_capture_enqueue(dc1394->camera, dc1394->frame) != DC1394_SUCCESS)
-            av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame);
+            av_log(c, AV_LOG_ERROR, "failed to release %"PRId64" frame\n", dc1394->current_frame);
     }
 
     res = dc1394_capture_dequeue(dc1394->camera, DC1394_CAPTURE_POLICY_WAIT, &dc1394->frame);
     if (res == DC1394_SUCCESS) {
         pkt->data = (uint8_t *)dc1394->frame->image;
         pkt->size = dc1394->frame->image_bytes;
-        pkt->pts = dc1394->current_frame * 1000000 / dc1394->frame_rate;
+        pkt->pts = av_rescale(dc1394->current_frame, 1000000, dc1394->frame_rate);
         pkt->flags |= AV_PKT_FLAG_KEY;
         pkt->stream_index = dc1394->stream_index;
     } else {
-- 
2.20.1



More information about the ffmpeg-devel mailing list