Support non interleaved avi files that have 0<size<sample_size.
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 22 Oct 2009 18:32:27 +0000 (18:32 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 22 Oct 2009 18:32:27 +0000 (18:32 +0000)
(No i do not have a sample its thus also untested)
The new code is also simpler.

Originally committed as revision 20347 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/avidec.c

index 30c1eee..37d15c2 100644 (file)
@@ -171,7 +171,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
             if(last_pos == pos || pos == base - 8)
                 avi->non_interleaved= 1;
             if(last_pos != pos)
-                av_add_index_entry(st, pos, ast->cum_len / FFMAX(1, ast->sample_size), len, 0, key ? AVINDEX_KEYFRAME : 0);
+                av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
 
             if(ast->sample_size)
                 ast->cum_len += len;
@@ -222,7 +222,7 @@ static void clean_index(AVFormatContext *s){
         ts= st->index_entries[0].timestamp;
 
         for(j=0; j<size; j+=max){
-            av_add_index_entry(st, pos+j, ts + j/ast->sample_size, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
+            av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
         }
     }
 }
@@ -684,14 +684,11 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
             if(!st->nb_index_entries)
                 continue;
 
-            if(ast->sample_size)
-                ts /= ast->sample_size;
-
             last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
             if(!ast->remaining && ts > last_ts)
                 continue;
 
-            ts = av_rescale_q(ts, st->time_base, AV_TIME_BASE_Q);
+            ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
 
 //            av_log(s, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset);
             if(ts < best_ts){
@@ -704,14 +701,13 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
             return -1;
 
         best_ast = best_st->priv_data;
-        best_ts = av_rescale_q(best_ts, AV_TIME_BASE_Q, best_st->time_base);
+        best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base);
         if(best_ast->remaining)
             i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
         else{
             i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
             if(i>=0)
-                best_ast->frame_offset= best_st->index_entries[i].timestamp
-                                      * FFMAX(1, best_ast->sample_size);
+                best_ast->frame_offset= best_st->index_entries[i].timestamp;
         }
 
 //        av_log(s, AV_LOG_DEBUG, "%d\n", i);
@@ -781,7 +777,7 @@ resync:
                 int index;
                 assert(st->index_entries);
 
-                index= av_index_search_timestamp(st, pkt->dts, 0);
+                index= av_index_search_timestamp(st, ast->frame_offset, 0);
                 e= &st->index_entries[index];
 
                 if(index >= 0 && e->timestamp == ast->frame_offset){
@@ -912,7 +908,7 @@ resync:
                 {
                     uint64_t pos= url_ftell(pb) - 8;
                     if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
-                        av_add_index_entry(st, pos, ast->frame_offset / FFMAX(1, ast->sample_size), size, 0, AVINDEX_KEYFRAME);
+                        av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
                     }
                 }
                 goto resync;
@@ -969,7 +965,7 @@ static int avi_read_idx1(AVFormatContext *s, int size)
         if(last_pos == pos)
             avi->non_interleaved= 1;
         else
-            av_add_index_entry(st, pos, ast->cum_len / FFMAX(1, ast->sample_size), len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
+            av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
         if(ast->sample_size)
             ast->cum_len += len;
         else
@@ -1062,6 +1058,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
     AVStream *st;
     int i, index;
     int64_t pos;
+    AVIStream *ast;
 
     if (!avi->index_loaded) {
         /* we only load the index on demand */
@@ -1071,13 +1068,14 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
     assert(stream_index>= 0);
 
     st = s->streams[stream_index];
-    index= av_index_search_timestamp(st, timestamp, flags);
+    ast= st->priv_data;
+    index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
     if(index<0)
         return -1;
 
     /* find the position */
     pos = st->index_entries[index].pos;
-    timestamp = st->index_entries[index].timestamp;
+    timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
 
 //    av_log(s, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp);
 
@@ -1110,7 +1108,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
         assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
         index = av_index_search_timestamp(
                 st2,
-                av_rescale_q(timestamp, st->time_base, st2->time_base),
+                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
                 flags | AVSEEK_FLAG_BACKWARD);
         if(index<0)
             index=0;
@@ -1125,8 +1123,6 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
 //        av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp);
         /* extract the current frame number */
         ast2->frame_offset = st2->index_entries[index].timestamp;
-        if(ast2->sample_size)
-            ast2->frame_offset *=ast2->sample_size;
     }
 
     /* do the seek */