Analysis of ffplay player (7)----Analysis of audio and video pause module

1. Pause the trigger process

1. Call toggle_pause through SDL trigger event

2.toggle_pause calls stream_toggle_pause

3.stream_toggle_pause modifies the pause variable

2. toggle_pause

static void toggle_pause(VideoState *is)
{
    
    
    stream_toggle_pause(is);
    is->step = 0;
}

3. stream_toggle_pause

static void stream_toggle_pause(VideoState *is)
{
    
    
    // 如果当前是暂停 -> 恢复播放
    // 正常播放 -> 暂停
    if (is->paused) {
    
    // 当前是暂停,那这个时候进来这个函数就是要恢复播放
        /* 恢复暂停状态时也需要恢复时钟,需要更新vidclk */
        // 加上 暂停->恢复 经过的时间
        is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
        if (is->read_pause_return != AVERROR(ENOSYS)) {
    
    
            is->vidclk.paused = 0;
        }
        // 设置时钟的意义,暂停状态下读取的是单纯pts
        // 重新矫正video时钟

        set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
    }
    set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
    // 切换 pause/resume 两种状态
    is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
    printf("is->step = %d; stream_toggle_pause\n", is->step);
}

This function can know that if the current state is suspended, then it will enter the if function

Take a look at the if function flow. First we know that we

is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;

This is based on the previous one plus the time from pause to start.

set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);

When get_clock is in the paused state, it gets the pts of the clock.

set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);

The same is true for setting the external clock

is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;

Just invert paused

Take a look at which functions these 4 pauses will affect

  1. video_refresh If it is paused and there is no forced refresh, this function will not be called. I have said before when to force refresh, such as modifying the ffplay window size.
  2. The pause in read_thread will only be effective for network streams. In other cases, pause will not affect read_thread, but will continue to read data and write it to the queue.
  3. get_clock will be called in get_master_clock, and if get_clock is in the paused state, it will directly return pts
  4. The audio_decode_frame function will be affected by paused and will directly return -1. Then sdl_audio_callback will make a judgment after receiving it, and then output the mute data without pausing.

Guess you like

Origin blog.csdn.net/m0_60565784/article/details/131903625