音视频流媒体开发【三十六】FFmpeg+QT播放器5-其他功能

2023-03-29  本文已影响0人  AlanGe

音视频流媒体开发-目录

5-stream_open和stream_close

进⼀步掌握:

stream_open

stream_open主要⼯作内容:

这⾥需要注意的是我们只是列举了主要的逻辑,还有其他逻辑在后续不断优化的时候添加。

stream_close

stream_close主要⼯作内容:

6-解复⽤、数据读取read_thread设计

read_thread线程

实现解复⽤

stream_component_open

打开对应的解码器并做初始化
创建和启动解码线程
初始化⾳频或视频输出设备

stream_component_close

关闭解码器线程
释放解码器资源
关闭⾳频或视频输出设备

7-解码线程Decoder封装

int audio_thread(void* arg); // ffplayer

int video_thread(void* arg);// ffplayer

8-⾳频输出

我们采⽤SDL作为⾳频输出。


9-视频渲染输出

⽬前使⽤qt输出, ui模块需要传⼊qt输出画⾯的回调。

重点内容

  1. 创建视频刷新线程video_refresh_thread,然后调⽤输出画⾯的回调函数。
  2. 设置视频刷新回调函数 从MainWind-> IjkMediaPlayer -> FFPlayer
  3. av_read_frame的video packet发给video packet queue
  4. 在DisplayWind 渲染画⾯
  5. 在调⽤stream_component_close的时候记得关闭 视频刷新线程video_refresh_thread

10-基本的⾳视频同步

难点

步骤

  1. 时钟结构设计和API设计
// 这⾥讲的系统时钟 是通过av_gettime_relative()获取到的时钟,单位为微妙
typedef struct Clock {
    double pts;            // 时钟基础, 当前帧(待播放)显示时间戳,播放后,当前帧变成上⼀帧
    // 当前pts与当前系统时钟的差值, audio、video对于该值是独⽴的
    double pts_drift;      // clock base minus time at which we updated the clock
    // 当前时钟(如视频时钟)最后⼀次更新时间,也可称当前时钟时间
    double last_updated;   // 最后⼀次更新的系统时钟
} Clock;
  1. stream_open中初始化时钟init_clock(&vidclk); init_clock(&audclk);
  2. 设置audio的时钟,在audio_decode_frame设置audio_clock, 然后在sdl_audio_callback设置audio时钟set_clock(&is->audclk, is->audio_clock);
  3. video时间戳⽐对audio时钟,在video_refresh
// 对⽐audio的时间戳
double diff = vp->pts - get_master_clock();
std::cout << __FUNCTION__ << "vp->pts:" << vp->pts << " - af->pts:" <<
get_master_clock() << ", diff:" << diff << std::endl;
if(diff > 0) {
    *remaining_time = FFMIN(*remaining_time, diff);
    return;
}

练习

上一篇 下一篇

猜你喜欢

热点阅读