[FFmpeg-devel] [PATCH] avformat/thp: implement seeking

Paul B Mahol onemda at gmail.com
Sun Nov 22 00:58:51 CET 2015


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 libavformat/thp.c | 44 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/libavformat/thp.c b/libavformat/thp.c
index 5569027..c661569 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -114,6 +114,7 @@ static int thp_read_header(AVFormatContext *s)
             st->codec->codec_tag = 0;  /* no fourcc */
             st->codec->width = avio_rb32(pb);
             st->codec->height = avio_rb32(pb);
+            st->start_time = 0;
             st->nb_frames =
             st->duration = thp->framecnt;
             thp->vst = st;
@@ -135,6 +136,7 @@ static int thp_read_header(AVFormatContext *s)
             st->codec->codec_tag = 0;  /* no fourcc */
             st->codec->channels    = avio_rb32(pb); /* numChannels.  */
             st->codec->sample_rate = avio_rb32(pb); /* Frequency.  */
+            st->start_time         = 0;
             st->duration           = avio_rb32(pb);
 
             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
@@ -153,6 +155,7 @@ static int thp_read_packet(AVFormatContext *s,
     ThpDemuxContext *thp = s->priv_data;
     AVIOContext *pb = s->pb;
     unsigned int size;
+    AVStream *st;
     int ret;
 
     if (thp->audiosize == 0) {
@@ -161,6 +164,8 @@ static int thp_read_packet(AVFormatContext *s,
             return AVERROR_EOF;
 
         avio_seek(pb, thp->next_frame, SEEK_SET);
+        st = s->streams[thp->video_stream_index];
+        av_add_index_entry(st, thp->next_frame, thp->frame, thp->next_framesz, 0, AVINDEX_KEYFRAME);
 
         /* Locate the next frame and read out its size.  */
         thp->next_frame += FFMAX(thp->next_framesz, 1);
@@ -185,7 +190,10 @@ static int thp_read_packet(AVFormatContext *s,
         }
 
         pkt->stream_index = thp->video_stream_index;
+        pkt->pts = thp->frame - !thp->has_audio;
     } else {
+        int64_t pos = avio_tell(pb);
+
         ret = av_get_packet(pb, pkt, thp->audiosize);
         if (ret < 0)
             return ret;
@@ -195,8 +203,7 @@ static int thp_read_packet(AVFormatContext *s,
         }
 
         pkt->stream_index = thp->audio_stream_index;
-        if (thp->audiosize >= 8)
-            pkt->duration = AV_RB32(&pkt->data[4]);
+        pkt->pos = pos;
 
         thp->audiosize = 0;
         thp->frame++;
@@ -205,11 +212,42 @@ static int thp_read_packet(AVFormatContext *s,
     return 0;
 }
 
+static int thp_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t timestamp, int flags)
+{
+    ThpDemuxContext *thp = s->priv_data;
+    AVStream *st = s->streams[stream_index];
+    int index = av_index_search_timestamp(st, timestamp, flags);
+
+    if (stream_index != thp->video_stream_index)
+        return -1;
+
+    if (index >= 0 && index < st->nb_index_entries) {
+        AVIndexEntry *e   = &st->index_entries[index];
+
+        thp->next_frame   = e->pos;
+        thp->next_framesz = e->size;
+        thp->frame        = index;
+        thp->audiosize    = 0;
+        return 0;
+    } else if (st->nb_index_entries && st->index_entries[st->nb_index_entries - 1].timestamp <= timestamp) {
+        AVIndexEntry *e = &st->index_entries[st->nb_index_entries - 1];
+
+        thp->next_frame   = e->pos;
+        thp->next_framesz = e->size;
+        thp->frame        = st->nb_index_entries - 1;
+        thp->audiosize    = 0;
+    }
+
+    return -1;
+}
+
 AVInputFormat ff_thp_demuxer = {
     .name           = "thp",
     .long_name      = NULL_IF_CONFIG_SMALL("THP"),
     .priv_data_size = sizeof(ThpDemuxContext),
     .read_probe     = thp_probe,
     .read_header    = thp_read_header,
-    .read_packet    = thp_read_packet
+    .read_packet    = thp_read_packet,
+    .read_seek      = thp_read_seek,
 };
-- 
1.9.1



More information about the ffmpeg-devel mailing list