diff mbox series

[FFmpeg-devel,GSoC,v3,7/7] ffplay: fix for unwanted pkts when using abr

Message ID 20200823122355.188611-7-sj.hc_Zhong@sjtu.edu.cn
State New
Headers show
Series [FFmpeg-devel,GSoC,v3,1/7] avformat/abr: Adaptive Bitrate support | expand

Checks

Context Check Description
andriy/default pending
andriy/make_warn warning New warnings during build
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Hongcheng Zhong Aug. 23, 2020, 12:23 p.m. UTC
From: spartazhc <spartazhc@gmail.com>

HLS use abr may switch streams, ffplay should allow pkt whic same type
(for example: video pkt) but different stream index to queue.

But in the begining, avformat_find_stream_info() will add pkts to
packet_buffer from all streams to find info. This will cause problem
because these unwanted pkts can be added to ffplay's packet_queue now.

The exactly packet number added is depend on stream, but it should be less
than the packet number in the segments which are downloaded during
hls_read_headeri().

So abr_init_duration will be passed to ffplay via abr_initial, pkts
do not needed will be unref as usual.

Signed-off-by: spartazhc <spartazhc@gmail.com>
---
 fftools/ffplay.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 30944ba4be..5ec2a8578c 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -2858,6 +2858,7 @@  static int read_thread(void *arg)
     int st_index[AVMEDIA_TYPE_NB];
     AVPacket pkt1, *pkt = &pkt1;
     int64_t stream_start_time;
+    int64_t abr_init_duration = 0;
     int pkt_in_play_range = 0;
     AVDictionaryEntry *t;
     SDL_mutex *wait_mutex = SDL_CreateMutex();
@@ -3018,6 +3019,21 @@  static int read_thread(void *arg)
 
     /* clean packet list filled in hls_read_header if abr is enabled */
     if (abr) {
+        AVDictionary *abr_initial = NULL;
+        AVDictionaryEntry *en = NULL;
+        av_opt_get_dict_val(ic, "abr_initial", AV_OPT_SEARCH_CHILDREN, &abr_initial);
+        en = av_dict_get(abr_initial, "abr_init_duration", NULL, 0);
+        if (en) {
+            if (st_index[AVMEDIA_TYPE_VIDEO] != -1) {
+                abr_init_duration = strtol(en->value, NULL, 10);
+                if (abr_init_duration < 0) {
+                    ret = AVERROR(EINVAL);
+                    goto fail;
+                }
+            }
+            av_log(NULL, AV_LOG_VERBOSE, "[ffplay-abr]: abr_init_duration=%ld\n", abr_init_duration);
+        }
+        av_dict_free(&abr_initial);
         is->abr_list = av_mallocz(sizeof(ABRList));
         if (!is->abr_list) {
             ret = AVERROR(ENOMEM);
@@ -3158,12 +3174,13 @@  static int read_thread(void *arg)
                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
                 <= ((double)duration / 1000000);
-        if (abr) {
+        if (abr && pkt_ts >= (stream_start_time + abr_init_duration)) {
+            int test = abr_check_list(is->abr_list, AVMEDIA_TYPE_VIDEO, pkt->stream_index);
             if ((pkt->stream_index == is->audio_stream
                     || abr_check_list(is->abr_list, AVMEDIA_TYPE_AUDIO, pkt->stream_index)) && pkt_in_play_range) {
                 packet_queue_put(&is->audioq, pkt);
             } else if ((pkt->stream_index == is->video_stream
-                    || abr_check_list(is->abr_list, AVMEDIA_TYPE_VIDEO, pkt->stream_index)) && pkt_in_play_range
+                    || (is->video_stream != -1 && abr_check_list(is->abr_list, AVMEDIA_TYPE_VIDEO, pkt->stream_index))) && pkt_in_play_range
                     && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
                 packet_queue_put(&is->videoq, pkt);
             } else if ((pkt->stream_index == is->subtitle_stream