[FFmpeg-devel] [PATCH] [GSoC v3 7/7] ffplay: fix for unwanted pkts when using abr
Hongcheng Zhong
sj.hc_Zhong at sjtu.edu.cn
Sun Aug 23 15:23:55 EEST 2020
From: spartazhc <spartazhc at 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 at gmail.com>
---
fftools/ffplay.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
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
--
2.28.0
More information about the ffmpeg-devel
mailing list