player.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #pragma once
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <stdbool.h>
  5. #include "idatastruct.h"
  6. #ifdef __cplusplus
  7. extern "C"
  8. {
  9. #endif // __cplusplus
  10. #include <libavcodec/avcodec.h>
  11. #include <libavformat/avformat.h>
  12. #include <libswscale/swscale.h>
  13. #include <libswresample/swresample.h>
  14. #include <libavutil/frame.h>
  15. #include <libavutil/time.h>
  16. #include <libavutil/imgutils.h>
  17. #include <libavutil/mem.h>
  18. #if defined(_WIN32)
  19. #include <SDL.h>
  20. #include <SDL_video.h>
  21. #include <SDL_render.h>
  22. #include <SDL_rect.h>
  23. #include <SDL_mutex.h>
  24. #else
  25. #include <SDL2/SDL.h>
  26. #include <SDL2/SDL_video.h>
  27. #include <SDL2/SDL_render.h>
  28. #include <SDL2/SDL_rect.h>
  29. #include <SDL2/SDL_mutex.h>
  30. #endif
  31. #ifdef __cplusplus
  32. }
  33. #endif // __cplusplus
  34. /* no AV sync correction is done if below the minimum AV sync threshold */
  35. #define AV_SYNC_THRESHOLD_MIN 0.04
  36. /* AV sync correction is done if above the maximum AV sync threshold */
  37. #define AV_SYNC_THRESHOLD_MAX 0.1
  38. /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
  39. #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
  40. /* no AV correction is done if too big error */
  41. #define AV_NOSYNC_THRESHOLD 10.0
  42. /* polls for possible required screen refresh at least this often, should be less than 1/fps */
  43. #define REFRESH_RATE 0.01
  44. #define SDL_AUDIO_BUFFER_SIZE 1024
  45. #define MAX_AUDIO_FRAME_SIZE 192000
  46. #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
  47. #define MIN_FRAMES 25
  48. /* Minimum SDL audio buffer size, in samples. */
  49. #define SDL_AUDIO_MIN_BUFFER_SIZE 512
  50. /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
  51. #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
  52. #define VIDEO_PICTURE_QUEUE_SIZE 3
  53. #define SUBPICTURE_QUEUE_SIZE 16
  54. #define SAMPLE_QUEUE_SIZE 9
  55. #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
  56. #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
  57. #ifndef RVC_MAX_DISPLAYNUM
  58. #define RVC_MAX_DISPLAYNUM 5
  59. #endif
  60. #ifndef RVC_DEFAULT_SLEEP_TIME
  61. #define RVC_DEFAULT_SLEEP_TIME 10*1000
  62. #endif
  63. typedef struct play_clock_s{
  64. double pts; // 当前帧(待播放)显示时间戳,播放后,当前帧变成上一帧
  65. double pts_drift; // 当前帧显示时间戳与当前系统时钟时间的差值
  66. double last_updated; // 当前时钟(如视频时钟)最后一次更新时间,也可称当前时钟时间
  67. double speed; // 时钟速度控制,用于控制播放速度
  68. int serial; // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列
  69. int paused; // 暂停标志
  70. int *queue_serial; // 指向packet_serial
  71. }play_clock_t;
  72. typedef struct sdl_video_s{
  73. SDL_Window *window;
  74. SDL_Renderer *renderer;
  75. SDL_Texture *texture;
  76. SDL_Rect rect;
  77. }sdl_video_t;
  78. typedef struct packet_queue_s{
  79. AVPacketList *first_pkt, *last_pkt;
  80. int nb_packets; // 队列中packet的数量
  81. int packet_queue_size; // 队列所占内存空间大小
  82. int64_t duration; // 队列中所有packet总的播放时长
  83. int abort_flag;
  84. int serial; // 播放序列,所谓播放序列就是一段连续的播放动作,一个seek操作会启动一段新的播放序列
  85. SDL_mutex *mutex;
  86. SDL_cond * packet_cond;
  87. }packet_queue_t;
  88. /* Common struct for handling all types of decoded data and allocated render buffers. */
  89. typedef struct frame_s{
  90. AVFrame *frame;
  91. int serial;
  92. double pts; /* presentation timestamp for the frame */
  93. double duration; /* estimated duration of the frame */
  94. int64_t pos; // frame对应的packet在输入文件中的地址偏移
  95. int width;
  96. int height;
  97. int format;
  98. AVRational sar;
  99. int uploaded;
  100. int flip_v;
  101. }frame_t;
  102. typedef struct frame_queue_s{
  103. frame_t queue[FRAME_QUEUE_SIZE];
  104. int rindex; // 读索引。待播放时读取此帧进行播放,播放后此帧成为上一帧
  105. int windex; // 写索引
  106. int size; // 总帧数
  107. int max_size; // 队列可存储最大帧数
  108. int keep_last;
  109. int rindex_shown; // 当前是否有帧在显示
  110. SDL_mutex *frame_mutex;
  111. SDL_cond *frame_cond;
  112. packet_queue_t *pktq; // 指向对应的packet_queue
  113. }frame_queue_t;
  114. typedef struct play_media_callback_s {
  115. void (*cb_play_media_finished)(void* user_data);
  116. int (*cb_playing_audiodata)(audio_param_t* param, const void* input, unsigned long uaudiolen, void* user_data);
  117. void* user_data;
  118. }play_media_callback_t;
  119. typedef enum eMediaType_s {
  120. eAudio_Type,
  121. eVideo_Type,
  122. eImage_Type
  123. }eMediaType_t;
  124. static const char* Media_Type_Table[] = {
  125. "Audio",
  126. "Video",
  127. "Image"
  128. };
  129. typedef enum eWindType_s {
  130. eVideoSize_Type,
  131. eFullScreen_Type,
  132. eSpecified_Type
  133. }eWindType_t;
  134. typedef struct player_stat_s{
  135. AVFormatContext *p_fmt_ctx[MAX_FILECOUNT];
  136. AVStream *p_audio_stream[MAX_FILECOUNT];
  137. AVStream *p_video_stream[MAX_FILECOUNT];
  138. AVCodecContext *p_acodec_ctx[MAX_FILECOUNT];
  139. AVCodecContext *p_vcodec_ctx[MAX_FILECOUNT];
  140. int audio_idx[MAX_FILECOUNT];
  141. int video_idx[MAX_FILECOUNT];
  142. sdl_video_t sdl_video;
  143. play_clock_t audio_clk; // 音频时钟
  144. play_clock_t video_clk; // 视频时钟
  145. double frame_timer;
  146. packet_queue_t audio_pkt_queue;
  147. packet_queue_t video_pkt_queue;
  148. frame_queue_t audio_frm_queue;
  149. frame_queue_t video_frm_queue;
  150. struct SwsContext *img_convert_ctx[MAX_FILECOUNT];
  151. struct SwrContext *audio_swr_ctx;
  152. AVFrame *p_frm_yuv[MAX_FILECOUNT];
  153. uint8_t *p_video_buffer[MAX_FILECOUNT];
  154. audio_param_t audio_param_src;
  155. audio_param_t audio_param_tgt;
  156. int audio_hw_buf_size; // SDL音频缓冲区大小(单位字节)
  157. uint8_t *p_audio_frm; // 指向待播放的一帧音频数据,指向的数据区将被拷入SDL音频缓冲区。若经过重采样则指向audio_frm_rwr,否则指向frame中的音频
  158. uint8_t *audio_frm_rwr; // 音频重采样的输出缓冲区
  159. unsigned int audio_frm_size; // 待播放的一帧音频数据(audio_buf指向)的大小
  160. unsigned int audio_frm_rwr_size; // 申请到的音频缓冲区audio_frm_rwr的实际尺寸
  161. int audio_cp_index; // 当前音频帧中已拷入SDL音频缓冲区的位置索引(指向第一个待拷贝字节)
  162. int audio_write_buf_size; // 当前音频帧中尚未拷入SDL音频缓冲区的数据量,audio_frm_size = audio_cp_index + audio_write_buf_size
  163. double audio_clock;
  164. int audio_clock_serial;
  165. int paused;
  166. int step;
  167. volatile bool buser_stop;
  168. SDL_cond *continue_read_thread;
  169. SDL_Thread *read_tid; // demux解复用线程
  170. SDL_Thread* audio_decode_tid; // 音频解码线程
  171. volatile bool baudio_decode_finished;
  172. SDL_Thread* video_decode_tid; // 视频解码线程
  173. volatile bool bvideo_decode_finished;
  174. SDL_Thread* video_playing_tid; // 视频播放线程
  175. SDL_cond* audio_play_cond;
  176. SDL_mutex* audio_play_wait_mutex;
  177. play_media_callback_t* prvc_cb; // 播放状态回调函数
  178. char* piconpath; // icon图标路径
  179. char* paudiodev; // 音频输出设备名
  180. eMediaType_t eMType; // 媒体类型
  181. eWindType_t eWindType; // 视频框大小类型
  182. volatile uint8_t uVolume; // 音量大小1-128
  183. char* straudiodev; // 获取到的音频设备名
  184. CMediaHostApi* rvc_hostapi;
  185. SDL_AudioDeviceID m_audio_dev;
  186. char strPlayLists[MAX_FILECOUNT][MAX_PATH]; //播放列表,全路径
  187. uint8_t uFilesCount; //播放文件数
  188. volatile int icurrent_index; //当前播放文件索引
  189. volatile int iaudio_dec_index; //当前音频解码器索引
  190. bool bCirclePlay;
  191. bool bvice_monitor;
  192. int iDisplayCx;
  193. int iDisplayCy;
  194. int iDisplayWidth;
  195. int iDisplayHeight;
  196. int (*on_audio_volume)(int* audiodata, void* user_data);
  197. int (*on_audio_play_finished)(void* user_data);
  198. void* user_data;
  199. }player_stat_t;
  200. typedef struct rvc_media_player_param_s{
  201. char* p_input_file;
  202. eMediaType_t eType;
  203. eWindType_t eWindType;
  204. int idisplaycx;
  205. int idisplaycy;
  206. int idisplaywidth;
  207. int idisplayheight;
  208. bool bvicemonitor;
  209. char strPlayLists[MAX_FILECOUNT][MAX_PATH]; //播放列表,全路径
  210. uint8_t uFilesCount; //播放文件数
  211. play_media_callback_t* cb;
  212. }rvc_media_player_param_t;
  213. double get_clock(play_clock_t *c);
  214. void set_clock_at(play_clock_t *c, double pts, int serial, double time);
  215. void set_clock(play_clock_t *c, double pts, int serial);
  216. class CMediaPlayer
  217. {
  218. public:
  219. CMediaPlayer(CMediaHostApi* pHostApi);
  220. ~CMediaPlayer();
  221. int InitParam(rvc_media_player_param_t* pMedia_Player);
  222. int Initialize_Player_Stat(rvc_media_player_param_t* pMedia_Player);
  223. int UnInitialize_Player_Stat();
  224. int SetVolume(uint8_t uVolume);
  225. bool GetPlayingFlag();
  226. int StartMediaPlay();
  227. int StopMediaPlay();
  228. int ExitMediaPlayingThread();
  229. int64_t GetMediaPlayingThreadId();
  230. int GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int* iheight);
  231. uint8_t GetVolume();
  232. bool SetFinishedFlag();
  233. eMediaType_t GetPlayingMediaType();
  234. private:
  235. player_stat_t* m_player_stat;
  236. bool m_bplaying;
  237. uint8_t m_uvolume;
  238. CMediaHostApi* m_hostapi;
  239. char* m_piconpath; // ico图标路径
  240. char* m_paudiodev; // 音频输出设备
  241. };