FFmpeg: 简易ijkplayer播放器实现--06封装打开和关闭stream

文章目录

      • 流程图
      • stream open
      • stream close

流程图

请添加图片描述

stream open

  • 初始化SDL以允许⾳频输出;
  • 初始化帧Frame队列
  • 初始化包Packet队列
  • 初始化时钟Clock
  • 初始化音量
  • 创建解复用读取线程read_thread
  • 创建视频刷新线程video_refresh_thread
int FFPlayer::stream_open(const char *file_name)
{
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
    {
        av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
        av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
        return -1;
    }
    // 初始化Frame帧队列
    if (frame_queue_init(&pictq, &videoq, VIDEO_PICTURE_QUEUE_SIZE_DEFAULT) < 0)
        goto fail;
    if (frame_queue_init(&sampq, &audioq, SAMPLE_QUEUE_SIZE) < 0)
        goto fail;

    // 初始化Packet包队列
    if (packet_queue_init(&videoq) < 0 ||
            packet_queue_init(&audioq) < 0 )
        goto fail;

    // 初始化时钟
    init_clock(&audclk);
    // 创建解复用器读数据线程read_thread
    read_thread_ = new std::thread(&FFPlayer::read_thread, this);
    // 创建视频刷新线程
    video_refresh_thread_ = new std::thread(FFPlayer::video_refresh_thread, this);
    return 0;
fail:
    stream_close();
    return -1;
}

调用过程
MainWind::OnPlayOrPause()
IjkMediaPlayer::ijkmp_prepare_async()
FFPlayer::ffp_prepare_async_l()
stream_open()

stream close

  • 请求关闭read_thread线程
  • 关闭解复用器
  • 关闭stream,⽐如调⽤stream_component_close:关闭解码线程,释放解码器资源,关闭对应的⾳频、视频设备,包队列,帧队列,释放其他资源
void FFPlayer::stream_close()
{
    abort_request = 1; // 请求退出
    if(read_thread_ && read_thread_->joinable()) {
        read_thread_->join();       // 等待线程退出
    }
    /* close each stream */
    if (audio_stream >= 0)
        stream_component_close(audio_stream);  // 解码器线程请求abort的时候有调用 packet_queue_abort
    if (video_stream >= 0)
        stream_component_close(video_stream);


    // 关闭解复用器 avformat_close_input(&is->ic);
    // 释放packet队列
    packet_queue_destroy(&videoq);
    packet_queue_destroy(&audioq);
    // 释放frame队列
    frame_queue_destory(&pictq);
    frame_queue_destory(&sampq);

    if(input_filename_) {
        free(input_filename_);
        input_filename_ = NULL;
    }
}

调用过程
MainWind::OnStop()
IjkMediaPlayer::ijkmp_destroy()
FFPlayer::ffp_destroy()
stream_close();

上一篇:Activiti——数据库、数据表的创建方式(springboot)


下一篇:vue2 的版本 使用 Ant Design Vue 1.78版本的组件库 做自定义接口 调用后端的接口上传excel文件