savevideofile.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #ifndef SAVEVIDEOFILE_H
  2. #define SAVEVIDEOFILE_H
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <QThread>
  8. #include <QMutex>
  9. #include <QDebug>
  10. extern"C"
  11. {
  12. #include <libavutil/avassert.h>
  13. #include <libavutil/channel_layout.h>
  14. #include <libavutil/opt.h>
  15. #include <libavutil/mathematics.h>
  16. #include <libavutil/time.h>
  17. // #include <libavutil/timestamp.h>
  18. #include <libavformat/avformat.h>
  19. #include <libswscale/swscale.h>
  20. #include <libswresample/swresample.h>
  21. #include <libavutil/imgutils.h>
  22. }
  23. #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
  24. // a wrapper around a single output AVStream
  25. typedef struct OutputStream
  26. {
  27. AVStream *st;
  28. AVCodecContext *enc;
  29. /* pts of the next frame that will be generated */
  30. int64_t next_pts;
  31. int samples_count;
  32. AVFrame *frame;
  33. AVFrame *tmp_frame;
  34. /// 如果是视频这是yuv420p数据
  35. /// 如果是音频这是存放pcm数据,用来取出刚好的一帧数据传给编码器编码
  36. uint8_t *frameBuffer;
  37. int frameBufferSize;
  38. } OutputStream;
  39. struct BufferDataNode
  40. {
  41. uint8_t * buffer;
  42. int bufferSize;
  43. int64_t time;
  44. BufferDataNode * next;
  45. };
  46. class SaveVideoFileThread : public QThread
  47. {
  48. Q_OBJECT
  49. public:
  50. explicit SaveVideoFileThread();
  51. ~SaveVideoFileThread();
  52. void setFileName(QString filePath);
  53. void setQuantity(int value);
  54. void setWidth(int width,int height);
  55. bool startEncode();
  56. bool stopEncode();
  57. ///time是毫秒
  58. void videoDataQuene_Input(uint8_t * buffer, int size, int64_t time);
  59. BufferDataNode *videoDataQuene_get(int64_t time);
  60. void audioDataQuene_Input(const uint8_t * buffer,const int &size);
  61. bool audioDataQuene_get(BufferDataNode &node);
  62. int getONEFrameSize(){return mONEFrameSize;}
  63. void setContainsVideo(bool);
  64. void setContainsAudio(bool);
  65. void setVideoFrameRate(int value);
  66. ///获取时间戳(毫秒)
  67. int64_t getVideoPts();
  68. int64_t getAudioPts();
  69. signals:
  70. void sig_StartWriteFile(QString filePath);
  71. void sig_StopWriteFile(QString filePath);
  72. protected:
  73. void run();
  74. private:
  75. QString mFilePath;
  76. int m_videoFrameRate;
  77. bool isStop;
  78. int64_t audio_pts, video_pts; //时间(毫秒)
  79. int mBitRate; //video bitRate
  80. int mONEFrameSize;
  81. int WIDTH;
  82. int HEIGHT;
  83. bool m_containsVideo;
  84. bool m_containsAudio;
  85. QMutex mVideoMutex;
  86. BufferDataNode * videoDataQueneHead;
  87. BufferDataNode * videoDataQueneTail;
  88. QMutex mAudioMutex;
  89. QList<BufferDataNode> mAudioDataList;
  90. BufferDataNode * lastVideoNode; //上一次的帧(帧不足的时候用上一次的帧来补全)
  91. int videoBufferCount;
  92. void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost);
  93. void close_audio(AVFormatContext *oc, OutputStream *ost);
  94. void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost);
  95. void close_video(AVFormatContext *oc, OutputStream *ost);
  96. void add_video_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, AVCodecID codec_id);
  97. void add_audio_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, AVCodecID codec_id);
  98. bool write_audio_frame(AVFormatContext *oc, OutputStream *ost);
  99. bool write_video_frame(AVFormatContext *oc, OutputStream *ost, double time);
  100. };
  101. #endif // SAVEVIDEOFILE_H