[FFmpeg-soc] [soc]: r5831 - seek2010/seek2010.patch

mchinen subversion at mplayerhq.hu
Tue Jun 15 18:52:35 CEST 2010


Author: mchinen
Date: Tue Jun 15 18:52:35 2010
New Revision: 5831

Log:
adding thread-safe (optional flag) support for av_build_index

Modified:
   seek2010/seek2010.patch

Modified: seek2010/seek2010.patch
==============================================================================
--- seek2010/seek2010.patch	Sat Jun 12 19:10:27 2010	(r5830)
+++ seek2010/seek2010.patch	Tue Jun 15 18:52:35 2010	(r5831)
@@ -1,19 +1,19 @@
 Index: ffplay.c
 ===================================================================
---- ffplay.c	(revision 23548)
+--- ffplay.c	(revision 23615)
 +++ ffplay.c	(working copy)
 @@ -2501,6 +2501,8 @@
          goto fail;
      }
  
-+    av_build_index(ic, 0);    
++    av_build_index(ic, AV_BUILD_INDEX_THREADSAFE);    
 +
      for(;;) {
          if (is->abort_request)
              break;
 Index: libavformat/mov.c
 ===================================================================
---- libavformat/mov.c	(revision 23548)
+--- libavformat/mov.c	(revision 23615)
 +++ libavformat/mov.c	(working copy)
 @@ -2495,7 +2495,10 @@
      int sample, time_sample;
@@ -52,7 +52,7 @@ Index: libavformat/mov.c
          st = s->streams[i];
 Index: libavformat/avidec.c
 ===================================================================
---- libavformat/avidec.c	(revision 23548)
+--- libavformat/avidec.c	(revision 23615)
 +++ libavformat/avidec.c	(working copy)
 @@ -1084,7 +1084,8 @@
      int i, index;
@@ -125,7 +125,7 @@ Index: libavformat/avidec.c
  
 Index: libavformat/avformat.h
 ===================================================================
---- libavformat/avformat.h	(revision 23548)
+--- libavformat/avformat.h	(revision 23615)
 +++ libavformat/avformat.h	(working copy)
 @@ -390,6 +390,21 @@
      int min_distance;         /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */
@@ -159,7 +159,7 @@ Index: libavformat/avformat.h
  } AVStream;
  
  #define AV_PROGRAM_RUNNING 1
-@@ -1131,6 +1149,23 @@
+@@ -1131,6 +1149,24 @@
  int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
  
  /**
@@ -178,12 +178,13 @@ Index: libavformat/avformat.h
 + * Part of the new seeking api.  incomplete.
 + */
 +int av_build_index(AVFormatContext *s, int flags);
++#define AV_BUILD_INDEX_THREADSAFE 0x0001
 +
 +/**
   * Ensures the index uses less memory than the maximum specified in
   * AVFormatContext.max_index_size by discarding entries if it grows
   * too large.
-@@ -1149,6 +1184,15 @@
+@@ -1149,6 +1185,15 @@
                         int size, int distance, int flags);
  
  /**
@@ -201,9 +202,9 @@ Index: libavformat/avformat.h
   * This is not supposed to be called directly by a user application,
 Index: libavformat/utils.c
 ===================================================================
---- libavformat/utils.c	(revision 23548)
+--- libavformat/utils.c	(revision 23615)
 +++ libavformat/utils.c	(working copy)
-@@ -1001,7 +1001,38 @@
+@@ -1031,7 +1031,38 @@
          pkt->convergence_duration = pc->convergence_duration;
  }
  
@@ -242,7 +243,7 @@ Index: libavformat/utils.c
  static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
  {
      AVStream *st;
-@@ -1359,6 +1390,7 @@
+@@ -1389,6 +1420,7 @@
      int a, b, m;
      int64_t timestamp;
  
@@ -250,7 +251,7 @@ Index: libavformat/utils.c
      a = - 1;
      b = nb_entries;
  
-@@ -1675,6 +1707,11 @@
+@@ -1705,6 +1737,11 @@
          timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
      }
  
@@ -262,7 +263,7 @@ Index: libavformat/utils.c
      /* first, we try the format specific seek */
      if (s->iformat->read_seek)
          ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
-@@ -1712,9 +1749,368 @@
+@@ -1742,9 +1779,416 @@
      // try some generic seek like av_seek_frame_generic() but with new ts semantics
  }
  
@@ -352,7 +353,7 @@ Index: libavformat/utils.c
 +    return 0;
 +}
 +
-+static int av_fill_table_internal(AVFormatContext *s, AVPacket *pkt, ByteIOContext *pb)
++static int av_fill_table_internal(AVFormatContext *s, AVPacket *pkt)
 +{
 +    AVStream *st;
 +    int len, ret, i;
@@ -485,7 +486,7 @@ Index: libavformat/utils.c
 +    return 0;
 +}
 +
-+static int av_fill_table_frame(AVFormatContext *s, AVPacket *pkt, ByteIOContext *pb)
++static int av_fill_table_frame(AVFormatContext *s, AVPacket *pkt)
 +{
 +    AVPacketList *pktl;
 +    int eof=0;
@@ -518,7 +519,7 @@ Index: libavformat/utils.c
 +            }
 +        }
 +        {
-+            int ret= av_fill_table_internal(s, pkt, pb);
++            int ret = av_fill_table_internal(s, pkt);
 +            if(ret<0){
 +                if(pktl && ret != AVERROR(EAGAIN)){
 +                    eof=1;
@@ -574,36 +575,84 @@ Index: libavformat/utils.c
 +	    s->streams[i]->seek_table.flags |= AV_SEEKTABLE_COPIED;
 +	}
 +    } else {
++	AVFormatContext *build_ic;
 +        AVPacket pkt;
 +
-+        /* default table generation behavior from av_seek_frame_generic */
-+	/* TODO: see why s->data_offset is the file length for avi/mp4 and others */
-+	
-+	/* use an independent file pointer so that we can use this call in multithreaded contexts*/
-+	/* not complete yet - see av_read_packet to see how we need to swap out the old file pointers*/
-+	ByteIOContext* pb;
-+
 +	printf("SEEK_TABLE_DEBUG: building index from scratch\n");
 +
-+        if ((ret=url_fopen(&pb, s->filename, URL_RDONLY)) < 0) {
-+	    return ret;
++	/* if the client needs it to be threadsafe, create a new format context to read from. */
++	if(flags & AV_BUILD_INDEX_THREADSAFE) {
++	    printf("SEEK_TABLE_DEBUG: making thread-safe copy of streams\n");
++	    build_ic = avformat_alloc_context();
++	    ret = av_open_input_file(&build_ic, s->filename, s->iformat, 0, NULL);
++
++	    if(ret < 0) {
++		printf("SEEK_TABLE_DEBUG: error re-opening file/streams: %i\n",ret);
++		goto cleanup;
++	    }
++	    if(build_ic->nb_streams != s->nb_streams) {
++		ret = -1;
++		printf("SEEK_TABLE_DEBUG: cloned AVFormatContext has different number of streams!");
++		goto cleanup;
++	    }
++	    
++	    for(i = 0; i < build_ic->nb_streams; i++) {
++		AVStream *build_st= build_ic->streams[i];
++		AVCodecContext *avctx = build_st->codec;
++		AVCodec *pCodec;
++		build_ic->streams[i]->discard = AVDISCARD_DEFAULT;
++
++		//compare with the orignal stream's context, and if opened, copy settings and open the clone
++		if(s->streams[i]->codec->priv_data) {
++		    printf("SEEK_TABLE_DEBUG: copying stream based on priv_data\n");
++		    if((ret = avcodec_copy_context(avctx, s->streams[i]->codec)) < 0) {
++			printf("SEEK_TABLE_DEBUG: error copying codec:%i\n",ret);
++			goto cleanup;
++		    }
++		    pCodec = avcodec_find_decoder(avctx->codec_id);
++		    if((ret = avcodec_open(avctx,pCodec)) < 0) {
++			printf("SEEK_TABLE_DEBUG: error opening codec:%i\n",ret);
++			goto cleanup;
++		    }
++		}
++	    }
++	} else {
++	    build_ic = s;
 +	}
-+	
-+        if ((ret = url_fseek(pb, 0/*s->data_offset*/, SEEK_SET)) < 0){
++
++        /* default table generation behavior from av_seek_frame_generic */
++	/* TODO: see why s->data_offset is the file length for avi/mp4 and others */
++        if ((ret = url_fseek(build_ic->pb, 0/*s->data_offset*/, SEEK_SET)) < 0){
 +	    printf("SEEK_TABLE_DEBUG: error building index: %i\n",ret);
-+            return ret;
++            goto cleanup;
 +	}
 +
 +        for(i=0;; i++) {
 +            do{
-+                ret = av_fill_table_frame(s, &pkt, pb);
++                ret = av_fill_table_frame(build_ic, &pkt);
 +            }while(ret == AVERROR(EAGAIN));
 +            if(ret<0)
 +                break;
 +            av_free_packet(&pkt);
-+            }
-+	if (pb)
-+	    url_fclose(pb);
++	}
++	ret = 0;
++    cleanup:
++	if(flags & AV_BUILD_INDEX_THREADSAFE) {
++	    if(build_ic) {
++		//take the index over from our clone
++		for(i = 0; i < build_ic->nb_streams; i++) {
++		    if(ret >= 0) { 
++			printf("SEEK_TABLE_DEBUG: copying over %i frames from clone stream\n",build_ic->streams[i]->seek_table.nb_index_entries);
++			s->streams[i]->seek_table = build_ic->streams[i]->seek_table;
++			memset(&build_ic->streams[i]->seek_table,0,sizeof(AVSeekTable));
++		    }
++		    avcodec_close(build_ic->streams[i]->codec);
++		}
++		av_close_input_file(build_ic);
++	    }
++	}
++	if(ret < 0) 
++	    return ret;
 +    }
 +    
 +    /* return seek to start of stream.  Not sure if this the desired behavior. */
@@ -621,7 +670,7 @@ Index: libavformat/utils.c
 +	    return ret;
 +	}
 +    }
-+    printf("SEEK_TABLE_DEBUG: finished building index\n");
++    printf("SEEK_TABLE_DEBUG: finished building index");
 +    return 0;
 +}
 +
@@ -631,7 +680,7 @@ Index: libavformat/utils.c
   * Returns TRUE if the stream has accurate duration in any stream.
   *
   * @return TRUE if the stream has accurate duration for at least one component.
-@@ -2422,6 +2818,7 @@
+@@ -2452,6 +2896,7 @@
          }
          av_metadata_free(&st->metadata);
          av_free(st->index_entries);
@@ -639,7 +688,7 @@ Index: libavformat/utils.c
          av_free(st->codec->extradata);
          av_free(st->codec);
  #if LIBAVFORMAT_VERSION_INT < (53<<16)
-@@ -2971,6 +3368,7 @@
+@@ -3001,6 +3446,7 @@
      for(i=0;i<s->nb_streams;i++) {
          av_freep(&s->streams[i]->priv_data);
          av_freep(&s->streams[i]->index_entries);


More information about the FFmpeg-soc mailing list