ffplay---源码解析(零):ffmpeg-4.2.1代码架构简述

本文介绍了ffplay播放器的源码分析,涵盖代码架构、线程使用及音视频同步等内容。ffplay基于SDL库,包含读线程、音频和视频解码线程、音频输出线程及视频输出线程。主要功能包括文件读取、解封装、解码、音视频输出和同步。文章将通过多个部分逐步深入解析ffplay的内部工作原理。
摘要由CSDN通过智能技术生成

/* Minimum SDL audio buffer size, in samples. */
// 最小音频缓冲
#define SDL_AUDIO_MIN_BUFFER_SIZE 512
/* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
// 计算实际音频缓冲大小,并不需要太频繁回调,这里设置的是最大音频回调次数是每秒30次
#define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30

/* Step size for volume control in dB */
// 音频控制 以db为单位的步进
#define SDL_VOLUME_STEP (0.75)

/* no AV sync correction is done if below the minimum AV sync threshold */
// 最低同步阈值,如果低于该值,则不需要同步校正
#define AV_SYNC_THRESHOLD_MIN 0.04
/* AV sync correction is done if above the maximum AV sync threshold */
// 最大同步阈值,如果大于该值,则需要同步校正
#define AV_SYNC_THRESHOLD_MAX 0.1
/* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
// 帧补偿同步阈值,如果帧持续时间比这更长,则不用来补偿同步
#define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
/* no AV correction is done if too big error */
// 同步阈值。如果误差太大,则不进行校正
#define AV_NOSYNC_THRESHOLD 10.0

/* maximum audio speed change to get correct sync */
// 正确同步的最大音频速度变化值(百分比)
#define SAMPLE_CORRECTION_PERCENT_MAX 10

/* external clock speed adjustment constants for realtime sources based on buffer fullness */
// 根据实时码流的缓冲区填充时间做外部时钟调整
// 最小值
#define EXTERNAL_CLOCK_SPEED_MIN  0.900
// 最大值
#define EXTERNAL_CLOCK_SPEED_MAX  1.010
// 步进
#define EXTERNAL_CLOCK_SPEED_STEP 0.001

/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
// 使用差值来实现平均值
#define AUDIO_DIFF_AVG_NB   20

/* polls for possible required screen refresh at least this often, should be less than 1/fps */
// 刷新频率 应该小于 1/fps
#define REFRESH_RATE 0.01

/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
/* TODO: We assume that a decoded and resampled frame fits into this buffer */
// 采样大小
#define SAMPLE_ARRAY_SIZE (8 * 65536)

#define CURSOR_HIDE_DELAY 1000000

#define USE_ONEPASS_SUBTITLE_RENDER 1

// 冲采样标志
static unsigned sws_flags = SWS_BICUBIC;

// 包列表结构
typedef struct MyAVPacketList {
   
    AVPacket pkt;
    struct MyAVPacketList *next;
    int serial;
} MyAVPacketList;

// 待解码包队列
typedef struct PacketQueue {
   
    MyAVPacketList *first_pkt, *last_pkt;
    int nb_packets;
    int size;
    int64_t duration;
    int abort_request;
    int serial;
    SDL_mutex *mutex;
    SDL_cond *cond;
} PacketQueue;

#define VIDEO_PICTURE_QUEUE_SIZE 3
#define SUBPICTURE_QUEUE_SIZE 16
#define SAMPLE_QUEUE_SIZE 9
#define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))

// 音频参数
typedef struct AudioParams {
   
    int freq;                                   // 频率
    int channels;                               // 声道数
    int64_t channel_layout;             // 声道设计,单声道,双声道还是立体声
    enum AVSampleFormat fmt;        // 采样格式
    int frame_size;                         //  采样大小
    int bytes_per_sec;                      // 每秒多少字节
} AudioParams;

// 时钟
typedef struct Clock {
   
    double pts;                 // 时钟基准 /* clock base */
    double pts_drift;           // 更新时钟的差值 /* clock base minus time at which we updated the clock */
    double last_updated;        // 上一次更新的时间
    double speed;               // 速度
    int serial;                     // 时钟基于使用该序列的包 /* clock is based on a packet with this serial */
    int paused;                 // 停止标志
    int *queue_serial;          // 指向当前数据包队列序列的指针,用于过时的时钟检测 /* pointer to the current packet queue serial, used for obsolete clock detection */
} Clock;

/* Common struct for handling all types of decoded data and allocated render buffers. */
// 解码帧结构
typedef struct Frame {
   
    AVFrame *frame;     // 帧数据
    AVSubtitle sub;         // 字幕
    int serial;                 // 序列
    double pts;             // 帧的显示时间戳 /* presentation timestamp for the frame */
    double duration;        // 帧显示时长 /* estimated duration of the frame */
    int64_t pos;                // 文件中的位置 /* byte position of the frame in the input file */
    int width;                  // 帧的宽度
    int height;                 // 帧的高度
    int format;             // 格式
    AVRational sar;         // 额外参数
    int uploaded;           // 上载
    int flip_v;                 // 反转
} Frame;

// 解码后的帧队列
typedef struct FrameQueue {
   
    Frame queue[FRAME_QUEUE_SIZE];  // 队列数组
    int rindex;                                         // 读索引
    int windex;                                     // 写索引
    int size;                                               // 大小
    int max_size;                                       // 最大大小
    int keep_last;                                      // 保持上一个
    int rindex_shown;
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值