123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- #pragma once
- #include <stdio.h>
- #include <stdint.h>
- //#include <stdbool.h>
- #include "idatastruct.h"
- #ifndef INT64_C
- #define INT64_C(c) (c##LL)
- #define UINT64_C(c) (c##UL)
- #endif
- #ifdef __cplusplus
- extern "C"
- {
- #endif // __cplusplus
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- #include <libswresample/swresample.h>
- #include <libavutil/frame.h>
- #include <libavutil/time.h>
- #include <libavutil/imgutils.h>
- #include <libavutil/mem.h>
- #if defined(_WIN32)
- #include <SDL.h>
- #include <SDL_video.h>
- #include <SDL_render.h>
- #include <SDL_rect.h>
- #include <SDL_mutex.h>
- #include <SDL_syswm.h>
- #else
- #include <SDL2/SDL.h>
- #include <SDL2/SDL_video.h>
- #include <SDL2/SDL_render.h>
- #include <SDL2/SDL_rect.h>
- #include <SDL2/SDL_mutex.h>
- #endif
- #ifdef __cplusplus
- }
- #endif // __cplusplus
- /* 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
- /* polls for possible required screen refresh at least this often, should be less than 1/fps */
- #define REFRESH_RATE 0.01
- #define SDL_AUDIO_BUFFER_SIZE 1024
- #define MAX_AUDIO_FRAME_SIZE 192000
- #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
- #define MIN_FRAMES 25
- /* 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 */
- #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
- #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))
- #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
- #ifndef RVC_MAX_DISPLAYNUM
- #define RVC_MAX_DISPLAYNUM 5
- #endif
- #ifndef RVC_DEFAULT_SLEEP_TIME
- #define RVC_DEFAULT_SLEEP_TIME 10*1000
- #endif
- #ifndef isnan
- #define isnan(x) ((x)!=(x))
- #endif
- typedef struct play_clock_s{
- double pts; // 当前帧(待播放)显示时间戳,播放后,当前帧变成上一帧
- double pts_drift; // 当前帧显示时间戳与当前系统时钟时间的差值
- double last_updated; // 当前时钟(如视频时钟)最后一次更新时间,也可称当前时钟时间
- double speed; // 时钟速度控制,用于控制播放速度
- int serial; // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列
- int paused; // 暂停标志
- int *queue_serial; // 指向packet_serial
- }play_clock_t;
- typedef struct sdl_video_s{
- SDL_Window *window;
- SDL_Renderer *renderer;
- SDL_Texture *texture;
- SDL_Rect rect;
- }sdl_video_t;
- typedef struct packet_queue_s{
- AVPacketList *first_pkt, *last_pkt;
- int nb_packets; // 队列中packet的数量
- int packet_queue_size; // 队列所占内存空间大小
- int64_t duration; // 队列中所有packet总的播放时长
- int abort_flag;
- int serial; // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列
- SDL_mutex *mutex;
- SDL_cond * packet_cond;
- }packet_queue_t;
- /* Common struct for handling all types of decoded data and allocated render buffers. */
- typedef struct frame_s{
- AVFrame *frame;
- int serial;
- double pts; /* presentation timestamp for the frame */
- double duration; /* estimated duration of the frame */
- int64_t pos; // frame对应的packet在输入文件中的地址偏移
- int width;
- int height;
- int format;
- AVRational sar;
- int uploaded;
- int flip_v;
- }frame_t;
- typedef struct frame_queue_s{
- frame_t queue[FRAME_QUEUE_SIZE];
- int rindex; // 读索引。待播放时读取此帧进行播放,播放后此帧成为上一帧
- int windex; // 写索引
- int size; // 总帧数
- int max_size; // 队列可存储最大帧数
- int keep_last;
- int rindex_shown; // 当前是否有帧在显示
- SDL_mutex *frame_mutex;
- SDL_cond *frame_cond;
- packet_queue_t *pktq; // 指向对应的packet_queue
- }frame_queue_t;
- typedef struct play_media_callback_s {
- void (*cb_play_media_finished)(void* user_data);
- int (*cb_playing_audiodata)(audio_param_t* param, const void* input, unsigned long uaudiolen, void* user_data);
- void* user_data;
- }play_media_callback_t;
- typedef enum eMediaType_s {
- eAudio_Type,
- eVideo_Type,
- eImage_Type
- }eMediaType_t;
- static const char* Media_Type_Table[] = {
- "Audio",
- "Video",
- "Image"
- };
- typedef enum m_eWindType_s {
- eVideoSize_Type,
- eFullScreen_Type,
- eSpecified_Type
- }m_eWindType_t;
- typedef struct player_stat_s{
- AVFormatContext *m_pfmt_ctx[MAX_FILECOUNT];
- AVStream *m_paudio_stream[MAX_FILECOUNT];
- AVStream *m_pvideo_stream[MAX_FILECOUNT];
- AVCodecContext *m_pacodec_ctx[MAX_FILECOUNT];
- AVCodecContext *m_pvcodec_ctx[MAX_FILECOUNT];
- int audio_idx[MAX_FILECOUNT];
- int video_idx[MAX_FILECOUNT];
- sdl_video_t sdl_video;
- play_clock_t audio_clk; // 音频时钟
- play_clock_t video_clk; // 视频时钟
- double frame_timer;
- packet_queue_t audio_pkt_queue;
- packet_queue_t video_pkt_queue;
- frame_queue_t audio_frm_queue;
- frame_queue_t video_frm_queue;
- struct SwsContext *m_pimg_convert_ctx[MAX_FILECOUNT];
- struct SwrContext *m_paudio_swr_ctx;
- AVFrame *m_pfrm_yuv[MAX_FILECOUNT];
- uint8_t *m_pvideo_buffer[MAX_FILECOUNT];
- audio_param_t m_audio_param_src;
- audio_param_t m_audio_param_tgt;
- int audio_hw_buf_size; // SDL音频缓冲区大小(单位字节)
- uint8_t *m_paudio_frm; // 指向待播放的一帧音频数据,指向的数据区将被拷入SDL音频缓冲区。若经过重采样则指向audio_frm_rwr,否则指向frame中的音频
- uint8_t *m_paudio_frm_rwr; // 音频重采样的输出缓冲区
- uint32_t audio_frm_size; // 待播放的一帧音频数据(audio_buf指向)的大小
- uint32_t audio_frm_rwr_size; // 申请到的音频缓冲区audio_frm_rwr的实际尺寸
- int audio_cp_index; // 当前音频帧中已拷入SDL音频缓冲区的位置索引(指向第一个待拷贝字节)
- int audio_write_buf_size; // 当前音频帧中尚未拷入SDL音频缓冲区的数据量,audio_frm_size = audio_cp_index + audio_write_buf_size
- double audio_clock;
- int audio_clock_serial;
-
- int m_ipaused;
- int m_istep;
- volatile bool buser_stop;
- SDL_cond* m_continue_read_thread;
- SDL_Thread* m_read_tid; // demux解复用线程
- SDL_Thread* m_audio_decode_tid; // 音频解码线程
- volatile bool m_baudio_decode_finished;
- SDL_Thread* m_video_decode_tid; // 视频解码线程
- volatile bool m_bvideo_decode_finished;
- SDL_Thread* m_video_playing_tid; // 视频播放线程
- SDL_sem* m_audio_play_wait_sem;
-
- play_media_callback_t* m_prvc_cb; // 播放状态回调函数
- char* m_piconpath; // icon图标路径
- char* m_paudiodev; // 音频输出设备名
- eMediaType_t m_eMType; // 媒体类型
- m_eWindType_t m_eWindType; // 视频框大小类型
- volatile uint8_t uVolume; // 音量大小1-128
- char* m_straudiodev; // 获取到的音频设备名
- CMediaHostApi* rvc_hostapi;
- SDL_AudioDeviceID m_audio_dev;
-
- char m_strPlayLists[MAX_FILECOUNT][MAX_PATH]; // 播放列表,全路径
- uint8_t m_uFilesCount; // 播放文件数
- volatile int m_icurrent_index; // 当前播放文件索引
- volatile int m_iaudio_dec_index; // 当前音频解码器索引
- bool bvice_monitor;
- int iDisplayCx;
- int iDisplayCy;
- int iDisplayWidth;
- int iDisplayHeight;
- int (*on_audio_volume)(int* audiodata, void* user_data);
- int (*on_audio_play_finished)(void* user_data);
- void* user_data;
- }player_stat_t;
- typedef struct rvc_media_player_param_s{
- char* p_input_file;
- eMediaType_t eType;
- m_eWindType_t m_eWindType;
- int idisplaycx;
- int idisplaycy;
- int idisplaywidth;
- int idisplayheight;
- bool bvicemonitor;
- char m_strPlayLists[MAX_FILECOUNT][MAX_PATH]; // 播放列表,全路径
- uint8_t m_uFilesCount; // 播放文件数
- play_media_callback_t* cb;
- }rvc_media_player_param_t;
- double get_clock(play_clock_t *c);
- void set_clock_at(play_clock_t *c, double pts, int serial, double time);
- void set_clock(play_clock_t *c, double pts, int serial);
- class CMediaPlayer
- {
- public:
- CMediaPlayer(CMediaHostApi* pHostApi);
- ~CMediaPlayer();
- int InitParam(rvc_media_player_param_t* pMedia_Player);
- int Initialize_Player_Stat(rvc_media_player_param_t* pMedia_Player);
- int UnInitialize_Player_Stat();
- int SetVolume(uint8_t uVolume);
- bool GetPlayingFlag();
- int StartMediaPlay();
- int StopMediaPlay();
- int ExitMediaPlayingThread();
- int64_t GetMediaPlayingThreadId();
- int GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int* iheight);
- uint8_t GetVolume();
- bool SetFinishedFlag();
- eMediaType_t GetPlayingMediaType();
- player_stat_t* GetPlayerStat();
- CMediaHostApi* GetMediaHostApi();
- bool GetMediaPlayStartedFlag();
- void SetMediaPlayStartedFlag(bool bflag);
- void StartMediaPlayFailed();
- SDL_mutex* GetMeidaPlayStartWaitMutex();
- private:
- player_stat_t* m_player_stat;
- bool m_bplaying;
- uint8_t m_uvolume;
- CMediaHostApi* m_hostapi;
- char* m_piconpath; // ico图标路径
- char* m_paudiodev; // 音频输出设备
- SDL_Thread* m_mediaplay_tid;
- bool m_bmediaplay_started_flag;
- SDL_sem* m_mediaplay_started_sem;
- bool m_bmediaplay_start_failed;
- SDL_mutex* m_meida_play_start_wait_mutex;
- };
|