[FFmpeg-soc] [soc]: r4659 - seek_api/mpeg.c

spyfeng subversion at mplayerhq.hu
Sat Jul 11 19:03:09 CEST 2009


Author: spyfeng
Date: Sat Jul 11 19:03:08 2009
New Revision: 4659

Log:
fix bugs get the correct frame size.

Modified:
   seek_api/mpeg.c

Modified: seek_api/mpeg.c
==============================================================================
--- seek_api/mpeg.c	Sat Jul 11 08:47:39 2009	(r4658)
+++ seek_api/mpeg.c	Sat Jul 11 19:03:08 2009	(r4659)
@@ -546,6 +546,8 @@ static int mpegps_read_packet(AVFormatCo
     pkt->pts = pts;
     pkt->dts = dts;
     pkt->stream_index = st->index;
+    av_log(s, AV_LOG_DEBUG, "packet index = %d pts = %"PRId64" dts = %"PRId64" size = %d packet pos = %"PRId64"\n",
+            pkt->stream_index, pkt->pts, pkt->dts, pkt->size, pkt->pos);
 #if 0
     av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n",
            pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size);
@@ -589,35 +591,64 @@ static int64_t mpegps_read_dts(AVFormatC
 }
 
 /* 0 for success and -1 for error */
-static int find_keyframe(AVFormatContext *s, int stream_index, int64_t *ret_pos, int64_t *pts, int64_t target_ts, int flags)
+static int find_keyframe(AVFormatContext *s, int stream_index, int index, int64_t *ret_pos, int64_t *pts, int64_t target_ts, int flags)
 {
     AVPacket pkt1, *pkt = &pkt1;
-    int64_t prev_pts = *pts, prev_pos = *ret_pos;
-
+    int64_t target_index_pts, prev_pts = *pts, prev_pos = *ret_pos, base_pos = *ret_pos;
+    int prev_stream_index, tmp_stream_index = stream_index;
+    int count_flag = 0;
+    AVStream *st = s->streams[stream_index];
+    AVIndexEntry *e;
+    if (index != -1) {
+        e = &st->index_entries[index];
+        target_index_pts = e->timestamp;
+    }
+begin:
     url_fseek(s->pb, *ret_pos, SEEK_SET);
     for (;;) {
+        prev_pts = *pts;
+        prev_pos = *ret_pos;
+        prev_stream_index = tmp_stream_index;
         if (av_read_frame(s, pkt) < 0)
             return -1;
 
+        count_flag ++;
+        *pts = pkt->pts;
+        *ret_pos = pkt->pos;
+        tmp_stream_index = pkt->stream_index;
         av_free_packet(pkt);
         if (!(pkt->flags & PKT_FLAG_KEY) || (stream_index != pkt->stream_index)) {
-            if (!(flags & AVSEEK_FLAG_ANY))
+            if (!(flags & AVSEEK_FLAG_ANY)) {
                 continue;
+            }
         }
-
-        *pts = pkt->pts;
-        *ret_pos = pkt->pos;
-
-        if (*pts < target_ts) {
-            prev_pts = *pts;
-            prev_pos = *ret_pos;
-        } else
+        if (*pts > target_ts)
             break;
+        else if (flags & AVSEEK_FLAG_BACKWARD && *pts == target_index_pts)
+        //else if (flags & AVSEEK_FLAG_BACKWARD)
+            break;
+    }
+    av_read_frame_flush(s);
+    if (count_flag == 1 && index) {
+        index --;
+        e = &st->index_entries[index];
+        *ret_pos = e->pos;
+        *pts = e->timestamp;
+        base_pos = *ret_pos;
+        goto begin;
     }
 
-    if (flags & AVSEEK_FLAG_BACKWARD && ((prev_pts + *pts) >> 2 > target_ts)) {
-        *ret_pos = prev_pts;
-        *pts = prev_pos;
+    // find the frame before the target frame
+    url_fseek(s->pb,base_pos, SEEK_SET);
+    if (prev_pts != pkt->pts || prev_pos != pkt->pos) {
+        for (;;) {
+            if (av_read_frame(s, pkt) < 0)
+                return -1;
+            av_free_packet(pkt);
+
+            if (pkt->pts == prev_pts && pkt->pos == prev_pos)
+                break;
+        }
     }
     return 0;
 }
@@ -676,16 +707,12 @@ static int mpegps_read_seek(struct AVFor
                 pts = st->index_entries[index].timestamp;
                 pos = st->index_entries[index].pos;
             }
-
-            if (find_keyframe(s, stream_index, &pos, &pts, ts, flags) == 0) {
+        }
+            if (find_keyframe(s, stream_index, index, &pos, &pts, ts, flags) == 0) {
                 goto success;
             } else {
                 return -1;
             }
-        } else {
-            url_fseek(s->pb, pos, SEEK_SET);
-            goto success;
-        }
     }
 
     // search the scr use binary search
@@ -698,7 +725,7 @@ static int mpegps_read_seek(struct AVFor
     pts = ret_ts;
     pos = ret_pos;
 
-    if (find_keyframe(s, stream_index, &pos, &pts, ts, flags) == 0) {
+    if (find_keyframe(s, stream_index, -1, &pos, &pts, ts, flags) == 0) {
         goto success;
     } else {
         return -1;


More information about the FFmpeg-soc mailing list