[FFmpeg-devel] avformat/dashdec: control download speed when in live stream mode

Submitted by Steven Liu on Jan. 2, 2019, 8:52 a.m.

Details

Message ID 20190102085223.14309-1-lq@chinaffmpeg.org
State New
Headers show

Commit Message

Steven Liu Jan. 2, 2019, 8:52 a.m.
fix ticket: 7369
check the duration is less than the fragment duration,
retry when the condition is true.

Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
 libavformat/dashdec.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Patch hide | download patch | download mbox

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index f4f4e935de..11c1307b18 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -108,6 +108,7 @@  struct representation {
     int64_t cur_seg_offset;
     int64_t cur_seg_size;
     struct fragment *cur_seg;
+    int64_t last_load_time;
 
     /* Currently active Media Initialization Section */
     struct fragment *init_section;
@@ -1084,6 +1085,8 @@  static int parse_manifest_representation(AVFormatContext *s, const char *url,
         }
     }
 
+    if (rep)
+        rep->last_load_time = get_current_time_in_sec();
     video_rep_idx += type == AVMEDIA_TYPE_VIDEO;
     audio_rep_idx += type == AVMEDIA_TYPE_AUDIO;
     subtitle_rep_idx += type == AVMEDIA_TYPE_SUBTITLE;
@@ -1382,6 +1385,9 @@  static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls)
     } else {
         num = pls->first_seq_no;
     }
+
+    if (pls)
+        pls->last_load_time = get_current_time_in_sec();
     return num;
 }
 
@@ -1461,6 +1467,7 @@  static int refresh_manifest(AVFormatContext *s)
 {
 
     int ret = 0, i;
+    int64_t cur_time = get_current_time_in_sec();
     DASHContext *c = s->priv_data;
 
     // save current context
@@ -1505,6 +1512,11 @@  static int refresh_manifest(AVFormatContext *s)
     for (i = 0; i < n_videos; i++) {
         struct representation *cur_video = videos[i];
         struct representation *ccur_video = c->videos[i];
+        if (cur_video)
+            cur_video->last_load_time = cur_time;
+        if (ccur_video)
+            ccur_video->last_load_time = cur_time;
+
         if (cur_video->timelines) {
             // calc current time
             int64_t currentTime = get_segment_start_time_based_on_timeline(cur_video, cur_video->cur_seq_no) / cur_video->fragment_timescale;
@@ -1521,6 +1533,11 @@  static int refresh_manifest(AVFormatContext *s)
     for (i = 0; i < n_audios; i++) {
         struct representation *cur_audio = audios[i];
         struct representation *ccur_audio = c->audios[i];
+        if (cur_audio)
+            cur_audio->last_load_time = cur_time;
+        if (ccur_audio)
+            ccur_audio->last_load_time = cur_time;
+
         if (cur_audio->timelines) {
             // calc current time
             int64_t currentTime = get_segment_start_time_based_on_timeline(cur_audio, cur_audio->cur_seq_no) / cur_audio->fragment_timescale;
@@ -1629,6 +1646,8 @@  static struct fragment *get_current_fragment(struct representation *pls)
         av_free(tmpfilename);
         seg->size = -1;
     }
+    if (pls)
+        pls->last_load_time = get_current_time_in_sec();
 
     return seg;
 }
@@ -1747,6 +1766,10 @@  static int read_data(void *opaque, uint8_t *buf, int buf_size)
     DASHContext *c = v->parent->priv_data;
 
 restart:
+    if (c->is_live && v->fragment_duration != 0 && v->fragment_timescale != 0)
+        if (get_current_time_in_sec() - v->last_load_time < (v->fragment_duration / v->fragment_timescale)) {
+            goto restart;
+        }
     if (!v->input) {
         free_fragment(&v->cur_seg);
         v->cur_seg = get_current_fragment(v);