[gegl] ff-load: improve random frame access



commit c5cdf47b0f5a2c6a27df8c59981e3969736230e0
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Nov 24 11:00:20 2015 +0100

    ff-load: improve random frame access
    
    mp4, ogv, avi, mkv and wmv as created by gegl's ff:save (and probably of some
    other origins) are within a couple of frames of accurate seeking now.

 operations/external/ff-load.c |   20 ++++++++++++++++----
 1 files changed, 16 insertions(+), 4 deletions(-)
---
diff --git a/operations/external/ff-load.c b/operations/external/ff-load.c
index bdb01e2..07797df 100644
--- a/operations/external/ff-load.c
+++ b/operations/external/ff-load.c
@@ -315,10 +315,13 @@ decode_frame (GeglOperation *operation,
   decodeframe = frame;
   if (frame > prevframe + 20 || frame < prevframe )
   {
-    int64_t seek_target = av_rescale_q ((frame - 16) / o->frame_rate * AV_TIME_BASE, AV_TIME_BASE_Q, 
p->video_stream->time_base);
+ 
+    int64_t seek_target = av_rescale_q ((frame * AV_TIME_BASE * 1.0) / o->frame_rate
+, AV_TIME_BASE_Q, p->video_stream->time_base) / p->video_stream->codec->ticks_per_frame;
+
     if (av_seek_frame (p->video_fcontext, p->video_index, seek_target, (AVSEEK_FLAG_BACKWARD )) < 0)
       fprintf (stderr, "video seek error!\n");
-   else
+    else
       avcodec_flush_buffers (p->video_stream->codec);
   }
 
@@ -352,8 +355,17 @@ decode_frame (GeglOperation *operation,
 
           if(got_picture)
           {
-             p->prevpts = av_frame_get_best_effort_timestamp (p->lavc_frame) * av_q2d 
(p->video_stream->time_base);
-             decodeframe = roundf (av_frame_get_best_effort_timestamp (p->lavc_frame) * av_q2d 
(p->video_stream->time_base) * o->frame_rate) - 1;
+             if ((pkt.dts != pkt.pts) || (p->lavc_frame->key_frame==0) )
+             {
+               p->prevpts += 1.0 / o->frame_rate;
+               decodeframe = floorf( p->prevpts * o->frame_rate) - 2;
+             }
+             else
+             {
+               p->lavc_frame->pts = pkt.dts;    //av_frame_get_best_effort_timestamp (p->lavc_frame);
+               p->prevpts = p->lavc_frame->pts * av_q2d (p->video_stream->time_base) * 
p->video_stream->codec->ticks_per_frame;
+               decodeframe = floorf( p->prevpts * o->frame_rate);
+             }
           }
 
           if (decoded_bytes != pkt.size)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]