diff --git a/ijkmedia/ijkplayer/ff_ffplay.c b/ijkmedia/ijkplayer/ff_ffplay.c index b236b57d824033badfffd2989016d32add886a8c..b894f76062f6f024c761493897ef04d7067bec84 100644 --- a/ijkmedia/ijkplayer/ff_ffplay.c +++ b/ijkmedia/ijkplayer/ff_ffplay.c @@ -1931,6 +1931,7 @@ static int read_thread(void *arg) int last_error = 0; int last_buffered_time_percentage = -1; int last_buffered_size_percentage = -1; + int hwm_in_ms = ffp->fast_high_water_mark_in_ms; // use fast water mark for first loading memset(st_index, -1, sizeof(st_index)); is->last_video_stream = is->video_stream = -1; @@ -2099,6 +2100,8 @@ static int read_thread(void *arg) // FIXME the +-2 is due to rounding being not done in the correct direction in generation // of the seek_pos/seek_rel variables + hwm_in_ms = ffp->fast_high_water_mark_in_ms; + ffp_toggle_buffering(ffp, 1); ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, @@ -2140,6 +2143,7 @@ static int read_thread(void *arg) step_to_next_frame_l(ffp); SDL_UnlockMutex(ffp->is->play_mutex); ffp_notify_msg1(ffp, FFP_MSG_SEEK_COMPLETE); + ffp_toggle_buffering(ffp, 1); } if (is->queue_attachments_req) { if (is->video_st && (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) { @@ -2254,10 +2258,10 @@ static int read_thread(void *arg) } do { - int buf_size_percent = -1; - int buf_time_percent = -1; - int hwm_in_bytes = ffp->high_water_mark_in_bytes; - int hwm_in_ms = ffp->high_water_mark_in_ms; + int buf_size_percent = -1; + int buf_time_percent = -1; + int hwm_in_bytes = ffp->high_water_mark_in_bytes; + int need_start_buffering = 0; if (hwm_in_ms > 0) { int cached_duration_in_ms = -1; int64_t audio_cached_duration = -1; @@ -2304,10 +2308,22 @@ static int read_thread(void *arg) if (buf_time_percent >= 0) { // alwas depend on cache duration if valid if (buf_time_percent >= 100) - ffp_toggle_buffering(ffp, 0); + need_start_buffering = 1; } else { if (buf_size_percent >= 100) - ffp_toggle_buffering(ffp, 0); + need_start_buffering = 1; + } + + if (need_start_buffering) { + if (hwm_in_ms < ffp->normal_high_water_mark_in_ms) + hwm_in_ms = ffp->normal_high_water_mark_in_ms; + + hwm_in_ms *= 2; + + if (hwm_in_ms > ffp->max_high_water_mark_in_ms) + hwm_in_ms = ffp->max_high_water_mark_in_ms; + + ffp_toggle_buffering(ffp, 0); } } while(0); diff --git a/ijkmedia/ijkplayer/ff_ffplay_def.h b/ijkmedia/ijkplayer/ff_ffplay_def.h index bceb4b29521db1eee0a291c90e12e4ac19c4a591..2b34edd317c2634b4cebb5100bf2cc5f62635a12 100644 --- a/ijkmedia/ijkplayer/ff_ffplay_def.h +++ b/ijkmedia/ijkplayer/ff_ffplay_def.h @@ -28,8 +28,12 @@ #include "ff_ffplay_config.h" #include "ff_ffmsg_queue.h" -#define DEFAULT_HIGH_WATER_MARK_IN_MS (10 * 1000) -#define DEFAULT_HIGH_WATER_MARK_IN_BYTES (128 * 1024) +#define DEFAULT_HIGH_WATER_MARK_IN_BYTES (128 * 1024) + +#define DEFAULT_MAX_HIGH_WATER_MARK_IN_MS (10 * 1000) +#define DEFAULT_NORMAL_HIGH_WATER_MARK_IN_MS (2 * 1000) +#define DEFAULT_FAST_HIGH_WATER_MARK_IN_MS (100) + #define MAX_QUEUE_SIZE (15 * 1024 * 1024) #define MIN_FRAMES 50000 @@ -430,8 +434,10 @@ typedef struct FFPlayer { MessageQueue msg_queue; - int high_water_mark_in_ms; int high_water_mark_in_bytes; + int max_high_water_mark_in_ms; + int normal_high_water_mark_in_ms; + int fast_high_water_mark_in_ms; int max_buffer_size; int skip_loop_filter; @@ -502,12 +508,14 @@ inline static void ffp_reset_internal(FFPlayer *ffp) ffp->prepared = 0; ffp->auto_start = 0; - ffp->high_water_mark_in_ms = DEFAULT_HIGH_WATER_MARK_IN_MS; ffp->high_water_mark_in_bytes = DEFAULT_HIGH_WATER_MARK_IN_BYTES; - ffp->max_buffer_size = MAX_QUEUE_SIZE; + ffp->max_high_water_mark_in_ms = DEFAULT_MAX_HIGH_WATER_MARK_IN_MS; + ffp->normal_high_water_mark_in_ms = DEFAULT_NORMAL_HIGH_WATER_MARK_IN_MS; + ffp->fast_high_water_mark_in_ms = DEFAULT_FAST_HIGH_WATER_MARK_IN_MS; + ffp->max_buffer_size = MAX_QUEUE_SIZE; - ffp->skip_loop_filter = AVDISCARD_ALL; - ffp->skip_frame = AVDISCARD_NONREF; + ffp->skip_loop_filter = AVDISCARD_ALL; + ffp->skip_frame = AVDISCARD_NONREF; msg_queue_flush(&ffp->msg_queue); }