235 lines
8.0 KiB
C++
235 lines
8.0 KiB
C++
#ifndef FF_FFPLAY_H
|
||
#define FF_FFPLAY_H
|
||
#include <thread>
|
||
#include <functional>
|
||
#include "ffmsg_queue.h"
|
||
#include "ff_ffplay_def.h"
|
||
#include "sonic.h"
|
||
extern "C" {
|
||
#include "libavcodec/avcodec.h"
|
||
}
|
||
class Decoder
|
||
{
|
||
public:
|
||
int packet_pending_ = 0;
|
||
AVPacket pkt_;
|
||
PacketQueue *queue_; // 数据包队列
|
||
AVCodecContext *avctx_; // 解码器上下文
|
||
int pkt_serial_; // 包序列
|
||
int finished_; // =0,解码器处于工作状态;=非0,解码器处于空闲状态
|
||
std::thread *decoder_thread_ = NULL;
|
||
|
||
int64_t start_pts;
|
||
AVRational start_pts_tb;
|
||
int64_t next_pts;
|
||
AVRational next_pts_tb;
|
||
Decoder();
|
||
~Decoder();
|
||
void decoder_init(AVCodecContext *avctx, PacketQueue *queue);
|
||
// 创建和启动线程
|
||
int decoder_start(enum AVMediaType codec_type, const char *thread_name, void* arg);
|
||
// 停止线程
|
||
void decoder_abort(FrameQueue *fq);
|
||
void decoder_destroy();
|
||
int decoder_decode_frame(AVFrame *frame);
|
||
int get_video_frame(AVFrame *frame);
|
||
int queue_picture(FrameQueue *fq, AVFrame *src_frame, double pts,
|
||
double duration, int64_t pos, int serial);
|
||
int audio_thread(void* arg);
|
||
int video_thread(void* arg);
|
||
};
|
||
class FFPlayer
|
||
{
|
||
public:
|
||
FFPlayer();
|
||
int ffp_create();
|
||
void ffp_destroy();
|
||
int ffp_prepare_async_l(char *file_name);
|
||
|
||
// 播放控制
|
||
int ffp_start_l();
|
||
int ffp_stop_l();
|
||
int stream_open( const char *file_name);
|
||
void stream_close();
|
||
// 打开指定stream对应解码器、创建解码线程、以及初始化对应的输出
|
||
int stream_component_open(int stream_index);
|
||
// 关闭指定stream的解码线程,释放解码器资源
|
||
void stream_component_close(int stream_index);
|
||
|
||
int audio_open(int64_t wanted_channel_layout,
|
||
int wanted_nb_channels, int wanted_sample_rate,
|
||
struct AudioParams *audio_hw_params);
|
||
void audio_close();
|
||
|
||
//获取播放时长
|
||
long ffp_get_duration_l();
|
||
long ffp_get_current_position_l();
|
||
|
||
// 暂停恢复
|
||
int ffp_pause_l();
|
||
void toggle_pause(int pause_on);
|
||
void toggle_pause_l(int pause_on);
|
||
void stream_update_pause_l();
|
||
void stream_toggle_pause_l(int pause_on);
|
||
|
||
// seek相关
|
||
int ffp_seek_to_l(long msec);
|
||
// 单位是秒 整数
|
||
int ffp_forward_to_l(long incr);
|
||
// 单位是秒 负数
|
||
int ffp_back_to_l(long incr);
|
||
int ffp_forward_or_back_to_l(long incr);
|
||
void stream_seek(int64_t pos, int64_t rel, int seek_by_bytes);
|
||
|
||
// 截屏相关
|
||
int ffp_screenshot_l(char *screen_path);
|
||
void screenshot(AVFrame *frame);
|
||
|
||
// 变速相关
|
||
int get_target_frequency();
|
||
int get_target_channels();
|
||
void ffp_set_playback_rate(float rate);
|
||
float ffp_get_playback_rate();
|
||
bool is_normal_playback_rate();
|
||
int ffp_get_playback_rate_change();
|
||
void ffp_set_playback_rate_change(int change);
|
||
|
||
//音量相关
|
||
void ffp_set_playback_volume(int value);
|
||
|
||
//播放完毕相关判断 1. av_read_frame返回eof; 2. audio没有数据可以输出; 3.video没有数据可以输出
|
||
void check_play_finish(); //如果已经结束则通知ui调用停止函数
|
||
// 供外包获取信息
|
||
int64_t ffp_get_property_int64(int id, int64_t default_value);
|
||
void ffp_track_statistic_l(AVStream *st, PacketQueue *q, FFTrackCacheStatistic *cache);
|
||
void ffp_audio_statistic_l();
|
||
void ffp_video_statistic_l();
|
||
MessageQueue msg_queue_;
|
||
char *input_filename_;
|
||
int realtime = 0;
|
||
int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue);
|
||
int read_thread();
|
||
std::thread *read_thread_;
|
||
|
||
int video_refresh_thread();
|
||
void video_refresh(double *remaining_time);
|
||
double vp_duration( Frame *vp, Frame *nextvp);
|
||
double compute_target_delay(double delay);
|
||
void update_video_pts(double pts, int64_t pos, int serial);
|
||
// 视频画面输出相关
|
||
std::thread *video_refresh_thread_ = NULL;
|
||
|
||
std::function<int(const Frame *)> video_refresh_callback_ = NULL;
|
||
void AddVideoRefreshCallback(std::function<int(const Frame *)> callback);
|
||
|
||
int get_master_sync_type();
|
||
double get_master_clock();
|
||
int av_sync_type = AV_SYNC_AUDIO_MASTER; // 音视频同步类型, 默认audio master
|
||
Clock audclk; // 音频时钟
|
||
Clock vidclk; // 视频时钟
|
||
// Clock extclk;
|
||
|
||
double audio_clock = 0; // 当前音频帧的PTS+当前帧Duration
|
||
int audio_clock_serial; // 播放序列,seek可改变此值, 解码后保存
|
||
int64_t audio_callback_time = 0;
|
||
// 帧队列
|
||
FrameQueue pictq; // 视频Frame队列
|
||
FrameQueue sampq; // 采样Frame队列
|
||
|
||
// 包队列
|
||
PacketQueue audioq; // 音频packet队列
|
||
PacketQueue videoq; // 视频队列
|
||
int abort_request = 0;
|
||
|
||
AVStream *audio_st = NULL; // 音频流
|
||
AVStream *video_st = NULL; // 音频流
|
||
int force_refresh = 0;
|
||
double frame_timer = 0;
|
||
|
||
int audio_stream = -1;
|
||
int video_stream = -1;
|
||
|
||
Decoder auddec; // 音频解码器
|
||
Decoder viddec; // 视频解码器
|
||
|
||
|
||
int eof = 0;
|
||
int audio_no_data = 0;
|
||
int video_no_data = 0;
|
||
AVFormatContext *ic = NULL;
|
||
|
||
int paused = 0;
|
||
// 音频输出相关
|
||
struct AudioParams audio_src; // 保存最新解码的音频参数
|
||
struct AudioParams audio_tgt; // 保存SDL音频输出需要的参数
|
||
struct SwrContext *swr_ctx = NULL; // 音频重采样context
|
||
int audio_hw_buf_size = 0; // SDL音频缓冲区的大小(字节为单位)
|
||
// 指向待播放的一帧音频数据,指向的数据区将被拷入SDL音频缓冲区。若经过重采样则指向audio_buf1,
|
||
// 否则指向frame中的音频
|
||
uint8_t *audio_buf = NULL; // 指向需要重采样的数据
|
||
uint8_t *audio_buf1 = NULL; // 指向重采样后的数据
|
||
unsigned int audio_buf_size = 0; // 待播放的一帧音频数据(audio_buf指向)的大小
|
||
unsigned int audio_buf1_size = 0; // 申请到的音频缓冲区audio_buf1的实际尺寸
|
||
int audio_buf_index = 0; // 更新拷贝位置 当前音频帧中已拷入SDL音频缓冲区
|
||
int audio_write_buf_size;
|
||
int audio_volume = 50; // 音量相关
|
||
int startup_volume = 50; // 起始音量
|
||
// seek相关
|
||
int64_t seek_req = 0;
|
||
int64_t seek_rel = 0;
|
||
int64_t seek_flags = 0;
|
||
int64_t seek_pos = 0; // seek的位置
|
||
|
||
// 截屏相关
|
||
bool req_screenshot_ = false;
|
||
char *screen_path_ = NULL;
|
||
|
||
//单步运行
|
||
int step = 0;
|
||
int framedrop = 1;
|
||
int frame_drops_late = 0;
|
||
|
||
int pause_req = 0;
|
||
int auto_resume = 0;
|
||
int buffering_on = 0;
|
||
// 变速相关
|
||
float pf_playback_rate = 1.0; // 播放速率
|
||
int pf_playback_rate_changed = 0; // 播放速率改变
|
||
// 变速相关
|
||
sonicStreamStruct *audio_speed_convert = nullptr;
|
||
int max_frame_duration = 3600;
|
||
|
||
|
||
// 统计相关的操作
|
||
FFStatistic stat;
|
||
};
|
||
|
||
inline static void ffp_notify_msg1(FFPlayer *ffp, int what)
|
||
{
|
||
msg_queue_put_simple3(&ffp->msg_queue_, what, 0, 0);
|
||
}
|
||
|
||
inline static void ffp_notify_msg2(FFPlayer *ffp, int what, int arg1)
|
||
{
|
||
msg_queue_put_simple3(&ffp->msg_queue_, what, arg1, 0);
|
||
}
|
||
|
||
inline static void ffp_notify_msg3(FFPlayer *ffp, int what, int arg1, int arg2)
|
||
{
|
||
msg_queue_put_simple3(&ffp->msg_queue_, what, arg1, arg2);
|
||
}
|
||
|
||
inline static void ffp_notify_msg4(FFPlayer *ffp, int what, int arg1, int arg2, void *obj, int obj_len)
|
||
{
|
||
msg_queue_put_simple4(&ffp->msg_queue_, what, arg1, arg2, obj, obj_len);
|
||
}
|
||
|
||
inline static void ffp_remove_msg(FFPlayer *ffp, int what)
|
||
{
|
||
msg_queue_remove(&ffp->msg_queue_, what);
|
||
}
|
||
|
||
|
||
|
||
#endif // FF_FFPLAY_H
|