qt/LedOK/wProgramManager/wEditProgram/wElement/videoplayer.h
2022-01-04 18:11:48 +08:00

154 lines
4.6 KiB
C++

/************************************************************
*Copyright (C), 2017-2027,lcb0281@gmail.com
*FileName: videoplayer.h
*Date: 2019-06-15
*Author: Caibiao Lee
*Version: V1.0
*Description: 音视频读取解码显示播放模块
*Others: 该模块代码由网上拷贝,我只是添加了
注释,规范了一些编码规范
*History:
***********************************************************/
#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H
#include <QThread>
#include <QImage>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include <libavutil/time.h>
#include "libavutil/pixfmt.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include <SDL.h>
#include <SDL_audio.h>
#include <SDL_types.h>
#include <SDL_name.h>
#include <SDL_main.h>
#include <SDL_config.h>
}
#define VIDEO_PICTURE_QUEUE_SIZE 1
#define MAX_AUDIO_SIZE (25 * 16 * 1024)
#define MAX_VIDEO_SIZE (25 * 256 * 1024)
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 /**1 second of 48khz 32bit audio**/
class VideoPlayer; /**前置声明**/
typedef struct PacketQueue
{
AVPacketList *first_pkt; /**队列头指针**/
AVPacketList *last_pkt; /**队列尾指针**/
int nb_packets; /**队列长度**/
int size; /**该节点数据大小**/
SDL_mutex *mutex; /**互斥量**/
SDL_cond *cond; /**状态变量**/
} PacketQueue;
typedef struct VideoState
{
DECLARE_ALIGNED(16,uint8_t,audio_buf2) [AVCODEC_MAX_AUDIO_FRAME_SIZE * 4];//字节对齐,提升效率
AVFormatContext *pFormatContext; /**文件格式上下文**/
PacketQueue audioq;//音频队列
AVFrame *audio_frame;/**解码音频过程中的使用缓存**/
AVStream *audio_st; /**音频流**/
AVStream *video_st;//视频流
AVPacket audio_pkt;
PacketQueue videoq;//视频队列
struct SwrContext *swr_ctx; /**用于解码后的音频格式转换**/
uint8_t *audio_buf;
uint8_t *audio_pkt_data;
int audio_pkt_size;
int s32VStreamCount; /**视频流数量**/
int s32AStreamCount; /**音频流数量**/
int audio_src_channels;
int audio_tgt_channels;
int audio_src_freq;
int audio_tgt_freq;
int audio_hw_buf_size;
unsigned int audio_buf_size;
unsigned int audio_buf_index;
int64_t audio_src_channel_layout;
int64_t audio_tgt_channel_layout;
enum AVSampleFormat audio_src_fmt;
enum AVSampleFormat audio_tgt_fmt;
double audio_clock; /**音频时钟**/
double video_clock; /**<pts of last decoded frame / predicted pts of next decoded frame**/
/**跳转相关的变量**/
int seek_req; /**跳转标志**/
int64_t seek_pos; /**跳转的位置 -- 微秒**/
int seek_flag_audio;/**跳转标志 -- 用于音频线程中**/
int seek_flag_video;/**跳转标志 -- 用于视频线程中**/
double seek_time; /**跳转的时间(秒) 值和seek_pos是一样的**/
/**播放控制相关**/
bool isPause; /**暂停标志**/
bool quit; /**停止**/
bool readFinished; /**文件读取完毕**/
bool readThreadFinished;
bool videoThreadFinished;
SDL_Thread *video_tid; /**视频线程id**/
SDL_AudioDeviceID audioID; /**SDL Audio Device IDs.**/
VideoPlayer *player; /**记录下这个类的指针 主要用于在线程里面调用激发信号的函数**/
}VideoState;
class VideoPlayer : public QThread
{
Q_OBJECT
public:
enum PlayerState
{
Playing,
Pause,
Stop
};
explicit VideoPlayer();
~VideoPlayer();
bool setFileName(QString path);
bool play();
bool pause();
bool stop(bool isWait = false); //参数表示是否等待所有的线程执行完毕再返回
void seek(int64_t pos); //单位是微秒
int64_t getTotalTime(); //单位微秒
double getCurrentTime(); //单位秒
void disPlayVideo(QImage img);
void disPlayVideo(uchar *ptr,uint width,uint height);
int SaveYuv(unsigned char *buf, int wrap, int xsize, int ysize, char *filename);
signals:
void sig_GetOneFrame(QImage); //获取到一帧图像 就发送此信号
void sigYuv_liuyi(uchar *ptr,uint width,uint height); //获取到一帧图像 就发送此信号
void sig_StateChanged(VideoPlayer::PlayerState state);
void sig_TotalTimeChanged(qint64 uSec); //获取到视频时长的时候激发此信号
protected:
void run();
private:
QString mFileName;
VideoState mVideoState;
PlayerState mPlayerState; //播放状态
};
#endif // VIDEOPLAYER_H