changeset 708:d79164865a7c libavformat

more fine grained discarding of packets
author michael
date Thu, 17 Mar 2005 01:25:01 +0000
parents cc612862d461
children ee513d354673
files asf.c avformat.h avidec.c flvdec.c matroska.c mov.c mpeg.c nut.c rm.c utils.c
diffstat 10 files changed, 40 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/asf.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/asf.c	Thu Mar 17 01:25:01 2005 +0000
@@ -545,7 +545,10 @@
 	    asf->packet_size_left -= rsize;
 	    //printf("___objsize____  %d   %d    rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize);
 
-	    if (asf->stream_index < 0 || s->streams[asf->stream_index]->discard) {
+	    if (asf->stream_index < 0
+                || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL
+                || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)
+                ) {
                 asf->packet_time_start = 0;
 		/* unhandled packet (should not happen) */
 		url_fskip(pb, asf->packet_frag_size);
--- a/avformat.h	Wed Mar 16 19:11:58 2005 +0000
+++ b/avformat.h	Thu Mar 17 01:25:01 2005 +0000
@@ -5,7 +5,7 @@
 extern "C" {
 #endif
 
-#define LIBAVFORMAT_BUILD       4622
+#define LIBAVFORMAT_BUILD       4623
 
 #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVFORMAT_VERSION     FFMPEG_VERSION
@@ -211,6 +211,15 @@
     int min_distance;         /* min distance between this and the previous keyframe, used to avoid unneeded searching */
 } AVIndexEntry;
 
+enum AVDiscard{
+//we leave some space between them for extensions (drop some keyframes for intra only or drop just some bidir frames)
+    AVDISCARD_NONE   =-16, ///< discard nothing
+    AVDISCARD_DEFAULT=  0, ///< discard useless packets like 0 size packets in avi
+    AVDISCARD_BIDIR  = 16, ///< discard all bidirectional frames
+    AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
+    AVDISCARD_ALL    = 48, ///< discard all
+};
+
 typedef struct AVStream {
     int index;    /* stream index in AVFormatContext */
     int id;       /* format specific stream id */
@@ -227,7 +236,7 @@
     int pts_wrap_bits; /* number of bits in pts (used for wrapping control) */
     /* ffmpeg.c private use */
     int stream_copy; /* if TRUE, just copy stream */
-    int discard; ///< if 1, packets can be discarded at will and dont need to be demuxed
+    enum AVDiscard discard; ///< selects which packets can be discarded at will and dont need to be demuxed
     //FIXME move stuff to a flags field?
     /* quality, as it has been removed from AVCodecContext and put in AVVideoFrame
      * MN:dunno if thats the right place, for it */
@@ -680,3 +689,4 @@
 #endif
 
 #endif /* AVFORMAT_H */
+
--- a/avidec.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/avidec.c	Thu Mar 17 01:25:01 2005 +0000
@@ -532,7 +532,11 @@
           st = s->streams[n];
           ast = st->priv_data;
           
-          if(st->discard){
+          if(   (st->discard >= AVDISCARD_DEFAULT && size==0)
+             /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & PKT_FLAG_KEY))*/ //FIXME needs a little reordering
+             || st->discard >= AVDISCARD_ALL){
+                if(ast->sample_size) ast->frame_offset += pkt->size;
+                else                 ast->frame_offset++;
                 url_fskip(pb, size);
                 goto resync;
           }
@@ -554,7 +558,6 @@
             ast->packet_size= size + 8;
             ast->remaining= size;
             goto resync;
-
           }
         }
         /* palette changed chunk */
--- a/flvdec.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/flvdec.c	Thu Mar 17 01:25:01 2005 +0000
@@ -105,7 +105,11 @@
         st->codec.frame_rate_base= 1;
         st->codec.frame_rate= 1000;
     }
-    if(st->discard){
+//    av_log(NULL, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard);
+    if(  (st->discard >= AVDISCARD_NONKEY && !((flags >> 4)==1 ||  is_audio))
+       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags >> 4)==3 && !is_audio))
+       || st->discard >= AVDISCARD_ALL
+       ){
         url_fskip(&s->pb, size);
         continue;
     }
@@ -158,7 +162,7 @@
     pkt->pts = pts;
     pkt->stream_index = st->index;
     
-    if (!is_audio && ((flags >> 4)==1))
+    if (is_audio || ((flags >> 4)==1))
 	pkt->flags |= PKT_FLAG_KEY;
     
     return ret;
--- a/matroska.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/matroska.c	Thu Mar 17 01:25:01 2005 +0000
@@ -2420,7 +2420,7 @@
                     av_free(origdata);
                     break;
                 }
-                if(matroska->ctx->streams[ matroska->tracks[track]->stream_index ]->discard){
+                if(matroska->ctx->streams[ matroska->tracks[track]->stream_index ]->discard >= AVDISCARD_ALL){
                     av_free(origdata);
                     break;                
                 }
--- a/mov.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/mov.c	Thu Mar 17 01:25:01 2005 +0000
@@ -1855,7 +1855,7 @@
     }
 
 //av_log(NULL, AV_LOG_DEBUG, "chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset);
-    if(!sc->is_ff_stream || s->streams[sc->ffindex]->discard) {
+    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
         mov->next_chunk_offset = offset;
 	offset = 0x0FFFFFFFFFFFFFFFLL;
--- a/mpeg.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/mpeg.c	Thu Mar 17 01:25:01 2005 +0000
@@ -1541,7 +1541,7 @@
     if (codec_id != CODEC_ID_PCM_S16BE)
         st->need_parsing = 1;
  found:
-    if(st->discard)
+    if(st->discard >= AVDISCARD_ALL)
         goto skip;
     if (startcode >= 0xa0 && startcode <= 0xbf) {
         int b1, freq;
--- a/nut.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/nut.c	Thu Mar 17 01:25:01 2005 +0000
@@ -1222,14 +1222,18 @@
 static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type, int64_t frame_start){
     AVFormatContext *s= nut->avf;
     ByteIOContext *bc = &s->pb;
-    int size, stream_id, key_frame;
-    int64_t pts;
+    int size, stream_id, key_frame, discard;
+    int64_t pts, last_IP_pts;
     
     size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, frame_start);
     if(size < 0)
         return -1;
 
-    if(s->streams[ stream_id ]->discard){
+    discard= s->streams[ stream_id ]->discard;
+    last_IP_pts= s->streams[ stream_id ]->last_IP_pts;
+    if(  (discard >= AVDISCARD_NONKEY && !key_frame)
+       ||(discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE && last_IP_pts > pts)
+       || discard >= AVDISCARD_ALL){
         url_fskip(bc, size);
         return 1;
     }
--- a/rm.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/rm.c	Thu Mar 17 01:25:01 2005 +0000
@@ -854,7 +854,8 @@
             rm->remaining_len-= len;
         }
 
-        if(st->discard){
+        if(  (st->discard >= AVDISCARD_NONKEY && !(flags&2))
+           || st->discard >= AVDISCARD_ALL){
             url_fskip(pb, len);
             goto resync;
         }
--- a/utils.c	Wed Mar 16 19:11:58 2005 +0000
+++ b/utils.c	Thu Mar 17 01:25:01 2005 +0000
@@ -821,7 +821,7 @@
                 compute_pkt_fields(s, st, NULL, pkt);
                 s->cur_st = NULL;
                 return 0;
-            } else if (s->cur_len > 0 && !st->discard) {
+            } else if (s->cur_len > 0 && st->discard < AVDISCARD_ALL) {
                 len = av_parser_parse(st->parser, &st->codec, &pkt->data, &pkt->size, 
                                       s->cur_ptr, s->cur_len,
                                       s->cur_pkt.pts, s->cur_pkt.dts);