ffplay源码分析2-数据结构

“ffplay源码分析”系列文章如下:
[1]. ffplay源码分析1-概述
[2]. ffplay源码分析2-数据结构
[3]. ffplay源码分析3-代码框架
[4]. ffplay源码分析4-音视频同步
[5]. ffplay源码分析5-图像格式转换
[6]. ffplay源码分析6-音频重采样
[7]. ffplay源码分析7-播放控制

2. 数据结构

几个关键的数据结构如下:

2.1 struct VideoState typedef struct VideoState { SDL_Thread *read_tid; // demux解复用线程 AVInputFormat *iformat; int abort_request; int force_refresh; int paused; int last_paused; int queue_attachments_req; int seek_req; // 标识一次SEEK请求 int seek_flags; // SEEK标志,诸如AVSEEK_FLAG_BYTE等 int64_t seek_pos; // SEEK的目标位置(当前位置+增量) int64_t seek_rel; // 本次SEEK的位置增量 int read_pause_return; AVFormatContext *ic; int realtime; Clock audclk; // 音频时钟 Clock vidclk; // 视频时钟 Clock extclk; // 外部时钟 FrameQueue pictq; // 视频frame队列 FrameQueue subpq; // 字幕frame队列 FrameQueue sampq; // 音频frame队列 Decoder auddec; // 音频解码器 Decoder viddec; // 视频解码器 Decoder subdec; // 字幕解码器 int audio_stream; // 音频流索引 int av_sync_type; double audio_clock; // 每个音频帧更新一下此值,以pts形式表示 int audio_clock_serial; // 播放序列,seek可改变此值 double audio_diff_cum; /* used for AV difference average computation */ double audio_diff_avg_coef; double audio_diff_threshold; int audio_diff_avg_count; AVStream *audio_st; // 音频流 PacketQueue audioq; // 音频packet队列 int audio_hw_buf_size; // SDL音频缓冲区大小(单位字节) uint8_t *audio_buf; // 指向待播放的一帧音频数据,指向的数据区将被拷入SDL音频缓冲区。若经过重采样则指向audio_buf1,否则指向frame中的音频 uint8_t *audio_buf1; // 音频重采样的输出缓冲区 unsigned int audio_buf_size; /* in bytes */ // 待播放的一帧音频数据(audio_buf指向)的大小 unsigned int audio_buf1_size; // 申请到的音频缓冲区audio_buf1的实际尺寸 int audio_buf_index; /* in bytes */ // 当前音频帧中已拷入SDL音频缓冲区的位置索引(指向第一个待拷贝字节) int audio_write_buf_size; // 当前音频帧中尚未拷入SDL音频缓冲区的数据量,audio_buf_size = audio_buf_index + audio_write_buf_size int audio_volume; // 音量 int muted; // 静音状态 struct AudioParams audio_src; // 音频frame的参数 #if CONFIG_AVFILTER struct AudioParams audio_filter_src; #endif struct AudioParams audio_tgt; // SDL支持的音频参数,重采样转换:audio_src->audio_tgt struct SwrContext *swr_ctx; // 音频重采样context int frame_drops_early; // 丢弃视频packet计数 int frame_drops_late; // 丢弃视频frame计数 enum ShowMode { SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB } show_mode; int16_t sample_array[SAMPLE_ARRAY_SIZE]; int sample_array_index; int last_i_start; RDFTContext *rdft; int rdft_bits; FFTSample *rdft_data; int xpos; double last_vis_time; SDL_Texture *vis_texture; SDL_Texture *sub_texture; SDL_Texture *vid_texture; int subtitle_stream; // 字幕流索引 AVStream *subtitle_st; // 字幕流 PacketQueue subtitleq; // 字幕packet队列 double frame_timer; // 记录最后一帧播放的时刻 double frame_last_returned_time; double frame_last_filter_delay; int video_stream; AVStream *video_st; // 视频流 PacketQueue videoq; // 视频队列 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity struct SwsContext *img_convert_ctx; struct SwsContext *sub_convert_ctx; int eof; char *filename; int width, height, xleft, ytop; int step; #if CONFIG_AVFILTER int vfilter_idx; AVFilterContext *in_video_filter; // the first filter in the video chain AVFilterContext *out_video_filter; // the last filter in the video chain AVFilterContext *in_audio_filter; // the first filter in the audio chain AVFilterContext *out_audio_filter; // the last filter in the audio chain AVFilterGraph *agraph; // audio filter graph #endif int last_video_stream, last_audio_stream, last_subtitle_stream; SDL_cond *continue_read_thread; } VideoState; 2.2 struct Clock 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; // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列 int serial; /* clock is based on a packet with this serial */ // 暂停标志 int paused; // 指向packet_serial int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */ } Clock; 2.3 struct PacketQueue typedef struct PacketQueue { MyAVPacketList *first_pkt, *last_pkt; int nb_packets; // 队列中packet的数量 int size; // 队列所占内存空间大小 int64_t duration; // 队列中所有packet总的播放时长 int abort_request; int serial; // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列 SDL_mutex *mutex; SDL_cond *cond; } PacketQueue;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxxfg.html