avformat/flvenc: do not attempt to write duration and filesize when not seekable
authorSteven Liu <lq@chinaffmpeg.org>
Wed, 12 Oct 2016 10:11:41 +0000 (18:11 +0800)
committerMichael Niedermayer <michael@niedermayer.cc>
Thu, 20 Oct 2016 16:07:24 +0000 (18:07 +0200)
Its impossible to update the filesize & duration values if seekback is not
possible as with live streams

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavformat/flvenc.c

index 99903f5..e50f8e4 100644 (file)
@@ -234,16 +234,18 @@ static void write_metadata(AVFormatContext *s, unsigned int ts)
     metadata_count_pos = avio_tell(pb);
     metadata_count = 4 * !!flv->video_par +
                      5 * !!flv->audio_par +
-                     1 * !!flv->data_par  +
-                     2; // +2 for duration and file size
-
+                     1 * !!flv->data_par;
+    if (pb->seekable) {
+        metadata_count += 2; // +2 for duration and file size
+    }
     avio_wb32(pb, metadata_count);
 
-    put_amf_string(pb, "duration");
-    flv->duration_offset = avio_tell(pb);
-
-    // fill in the guessed duration, it'll be corrected later if incorrect
-    put_amf_double(pb, s->duration / AV_TIME_BASE);
+    if (pb->seekable) {
+        put_amf_string(pb, "duration");
+        flv->duration_offset = avio_tell(pb);
+        // fill in the guessed duration, it'll be corrected later if incorrect
+        put_amf_double(pb, s->duration / AV_TIME_BASE);
+    }
 
     if (flv->video_par) {
         put_amf_string(pb, "width");
@@ -319,9 +321,11 @@ static void write_metadata(AVFormatContext *s, unsigned int ts)
         metadata_count++;
     }
 
-    put_amf_string(pb, "filesize");
-    flv->filesize_offset = avio_tell(pb);
-    put_amf_double(pb, 0); // delayed write
+    if (pb->seekable) {
+        put_amf_string(pb, "filesize");
+        flv->filesize_offset = avio_tell(pb);
+        put_amf_double(pb, 0); // delayed write
+    }
 
     put_amf_string(pb, "");
     avio_w8(pb, AMF_END_OF_OBJECT);
@@ -543,16 +547,19 @@ static int flv_write_trailer(AVFormatContext *s)
 
     file_size = avio_tell(pb);
 
-    /* update information */
-    if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0)
-        av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n");
-    else
-        put_amf_double(pb, flv->duration / (double)1000);
-    if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0)
-        av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n");
-    else
-        put_amf_double(pb, file_size);
-
+    if (pb->seekable) {
+        /* update information */
+        if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) {
+            av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n");
+        } else {
+            put_amf_double(pb, flv->duration / (double)1000);
+        }
+        if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) {
+            av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n");
+        } else {
+            put_amf_double(pb, file_size);
+        }
+    }
     avio_seek(pb, file_size, SEEK_SET);
     return 0;
 }