]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/asfenc.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavformat / asfenc.c
index a287ac55ad464c7a7558b426277346107a3f6ec9..92ac818a8fc7a8bf08e95f08ad57510fabf40e4b 100644 (file)
@@ -30,7 +30,7 @@
 
 
 #define ASF_INDEXED_INTERVAL    10000000
-#define ASF_INDEX_BLOCK         600
+#define ASF_INDEX_BLOCK         (1<<9)
 
 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
 #define ASF_PACKET_ERROR_CORRECTION_FLAGS (\
@@ -208,11 +208,13 @@ typedef struct {
     /* only for reading */
     uint64_t data_offset;                ///< beginning of the first data packet
 
-    int64_t last_indexed_pts;
     ASFIndex* index_ptr;
-    uint32_t nb_index_count;
     uint32_t nb_index_memory_alloc;
     uint16_t maximum_packet;
+    uint32_t next_packet_number;
+    uint16_t next_packet_count;
+    int      next_start_sec;
+    int      end_sec;
 } ASFContext;
 
 static const AVCodecTag codec_asf_bmp_tags[] = {
@@ -400,7 +402,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
 
         enc = s->streams[n]->codec;
         asf->streams[n].num = n + 1;
-        asf->streams[n].seq = 0;
+        asf->streams[n].seq = 1;
 
 
         switch(enc->codec_type) {
@@ -557,10 +559,8 @@ static int asf_write_header(AVFormatContext *s)
     s->packet_size  = PACKET_SIZE;
     asf->nb_packets = 0;
 
-    asf->last_indexed_pts = 0;
     asf->index_ptr = av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK );
     asf->nb_index_memory_alloc = ASF_INDEX_BLOCK;
-    asf->nb_index_count = 0;
     asf->maximum_packet = 0;
 
     /* the data-chunk-size has to be 50, which is data_size - asf->data_offset
@@ -782,14 +782,42 @@ static void put_frame(
     stream->seq++;
 }
 
+static void update_index(AVFormatContext *s, int start_sec,
+                         uint32_t packet_number, uint16_t packet_count)
+{
+    ASFContext *asf = s->priv_data;
+
+    if (start_sec > asf->next_start_sec) {
+        int i;
+
+        if (!asf->next_start_sec) {
+            asf->next_packet_number = packet_number;
+            asf->next_packet_count  = packet_count;
+        }
+
+        if (start_sec > asf->nb_index_memory_alloc) {
+            asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1);
+            asf->index_ptr = av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc );
+        }
+        for (i = asf->next_start_sec; i < start_sec; i++) {
+            asf->index_ptr[i].packet_number = asf->next_packet_number;
+            asf->index_ptr[i].packet_count  = asf->next_packet_count;
+        }
+    }
+    asf->maximum_packet     = FFMAX(asf->maximum_packet, packet_count);
+    asf->next_packet_number = packet_number;
+    asf->next_packet_count  = packet_count;
+    asf->next_start_sec     = start_sec;
+}
+
 static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ASFContext *asf = s->priv_data;
     ASFStream *stream;
-    int64_t duration;
     AVCodecContext *codec;
-    int64_t packet_st,pts;
-    int start_sec,i;
+    uint32_t packet_number;
+    int64_t pts;
+    int start_sec;
     int flags= pkt->flags;
 
     codec = s->streams[pkt->stream_index]->codec;
@@ -800,30 +828,22 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
     assert(pts != AV_NOPTS_VALUE);
-    duration = pts * 10000;
-    asf->duration= FFMAX(asf->duration, duration + pkt->duration * 10000);
+    pts *= 10000;
+    asf->duration= FFMAX(asf->duration, pts + pkt->duration * 10000);
 
-    packet_st = asf->nb_packets;
+    packet_number = asf->nb_packets;
     put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags);
 
+    start_sec = (int)((PREROLL_TIME * 10000 + pts + ASF_INDEXED_INTERVAL - 1)
+              / ASF_INDEXED_INTERVAL);
+
     /* check index */
     if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) {
-        start_sec = (int)(duration / INT64_C(10000000));
-        if (start_sec != (int)(asf->last_indexed_pts / INT64_C(10000000))) {
-            for(i=asf->nb_index_count;i<start_sec;i++) {
-                if (i>=asf->nb_index_memory_alloc) {
-                    asf->nb_index_memory_alloc += ASF_INDEX_BLOCK;
-                    asf->index_ptr = (ASFIndex*)av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc );
-                }
-                // store
-                asf->index_ptr[i].packet_number = (uint32_t)packet_st;
-                asf->index_ptr[i].packet_count  = (uint16_t)(asf->nb_packets-packet_st);
-                asf->maximum_packet = FFMAX(asf->maximum_packet, (uint16_t)(asf->nb_packets-packet_st));
-            }
-            asf->nb_index_count = start_sec;
-            asf->last_indexed_pts = duration;
-        }
+        uint16_t packet_count = asf->nb_packets - packet_number;
+        update_index(s, start_sec, packet_number, packet_count);
     }
+    asf->end_sec = start_sec;
+
     return 0;
 }
 
@@ -858,8 +878,9 @@ static int asf_write_trailer(AVFormatContext *s)
 
     /* write index */
     data_size = avio_tell(s->pb);
-    if ((!asf->is_streamed) && (asf->nb_index_count != 0)) {
-        asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count);
+    if (!asf->is_streamed && asf->next_start_sec) {
+        update_index(s, asf->end_sec + 1, 0, 0);
+        asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->next_start_sec);
     }
     avio_flush(s->pb);
 
@@ -889,8 +910,10 @@ AVOutputFormat ff_asf_muxer = {
     .write_header   = asf_write_header,
     .write_packet   = asf_write_packet,
     .write_trailer  = asf_write_trailer,
-    .flags = AVFMT_GLOBALHEADER,
-    .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0},
+    .flags          = AVFMT_GLOBALHEADER,
+    .codec_tag      = (const AVCodecTag* const []){
+        codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0
+    },
 };
 #endif
 
@@ -906,7 +929,9 @@ AVOutputFormat ff_asf_stream_muxer = {
     .write_header   = asf_write_stream_header,
     .write_packet   = asf_write_packet,
     .write_trailer  = asf_write_trailer,
-    .flags = AVFMT_GLOBALHEADER,
-    .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0},
+    .flags          = AVFMT_GLOBALHEADER,
+    .codec_tag      = (const AVCodecTag* const []){
+        codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0
+    },
 };
 #endif //CONFIG_ASF_STREAM_MUXER