ffmpeg版本5-1-6
数据结构
FrameQueue
typedef struct FrameQueue {Frame queue[FRAME_QUEUE_SIZE];//存储解码后帧数据(视频YUV/RGB、音频PCM、字幕)的预分配内存池int rindex;//指向当前待读取(播放)的帧位置,相当于队列头部int windex;//指向下一个可写入(解码)的帧位置,相当于队列尾部int size;//当前队列中已存储的帧数量。用于判断队列空满,避免“假溢出”int max_size;//最大存储帧数int keep_last;//关键标志。为1时,队列会保留最近已显示的一帧(由rindex指向),用于特殊情况下的重绘或seek操作int rindex_shown;// 配合keep_last使用。为1表示rindex指向的帧是已显示的“保留帧”,实际待读帧是(rindex + rindex_shown) % max_sizeSDL_mutex *mutex;SDL_cond *cond;PacketQueue *pktq;//指向对应的压缩数据包队列。关联关系有助于在队列终止(如abort_request)时快速通知对方,实现协同退出} FrameQueue;
PacketQueue
typedef struct PacketQueue {AVFifo *pkt_list; //数据存储区。一个环形缓冲区,用于存放 MyAVPacketList元素,每个元素包含一个 AVPacket和其序列号int nb_packets;// 包数量。记录队列中当前存在的 AVPacket 数量int size;// 内存大小。统计队列中所有 AVPacket 数据(包括其数据体)所占用的总内存字节数,用于控制缓存大小int64_t duration;//总时长。统计队列中所有数据包解码后播放的总持续时间(以时间基为单位),用于控制缓存时长 int abort_request;//中止请求标志。设置为 1 时,表示队列应中止所有操作并准备退出,用于安全快速地停止播放 int serial;//队列序列号。用于标识数据包的连续性。在 seek 操作或插入刷新包 (flush_pkt) 后,此序列号会增加,以区分不连续的数据段 SDL_mutex *mutex;SDL_cond *cond;
} PacketQueue;
VideoState
typedef struct VideoState {SDL_Thread *read_tid;const AVInputFormat *iformat;int abort_request;int force_refresh;int paused;int last_paused;int queue_attachments_req;int seek_req;int seek_flags;int64_t seek_pos;int64_t seek_rel;int read_pause_return;AVFormatContext *ic;int realtime;Clock audclk;Clock vidclk;Clock extclk;FrameQueue pictq;FrameQueue subpq;FrameQueue sampq;Decoder auddec;Decoder viddec;Decoder subdec;int audio_stream;int av_sync_type;double audio_clock;int audio_clock_serial;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;int audio_hw_buf_size;uint8_t *audio_buf;uint8_t *audio_buf1;unsigned int audio_buf_size; /* in bytes */unsigned int audio_buf1_size;int audio_buf_index; /* in bytes */int audio_write_buf_size;int audio_volume;int muted;struct AudioParams audio_src;struct AudioParams audio_filter_src;struct AudioParams audio_tgt;struct SwrContext *swr_ctx;int frame_drops_early;int frame_drops_late;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;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 discontinuitystruct SwsContext *sub_convert_ctx;int eof;char *filename;int width, height, xleft, ytop;int step;int vfilter_idx;AVFilterContext *in_video_filter; // the first filter in the video chainAVFilterContext *out_video_filter; // the last filter in the video chainAVFilterContext *in_audio_filter; // the first filter in the audio chainAVFilterContext *out_audio_filter; // the last filter in the audio chainAVFilterGraph *agraph; // audio filter graphint last_video_stream, last_audio_stream, last_subtitle_stream;SDL_cond *continue_read_thread;
} VideoState;
数据处理流程