OSDN Git Service

[Build][Win32] Separate GUI(and fmgen and emuutils) to separate DLLs.
[csp-qt/common_source_project-fm7.git] / source / src / qt / avio / movie_saver.h
1 /*
2  * Common Source Code Project for Qt : movie saver.
3  * (C) 2016 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  *  License: GPLv2
5  *  History: May 27, 2016 : Initial. This refer from avidemux 2.5.6 .
6  */
7
8 #ifndef _QT_OSD_MOVIE_SAVER_H
9 #define _QT_OSD_MOVIE_SAVER_H
10
11 #include <QByteArray>
12 #include <QQueue>
13 #include <QString>
14 #include <QStringList>
15 #include <QThread>
16 #include <QSize>
17 #include <QImage>
18 #include "config.h"
19
20 #if defined(USE_LIBAV)
21 extern "C" {
22         #include "libavutil/channel_layout.h"
23         #include "libavutil/opt.h"
24         #include "libavutil/mathematics.h"
25         #include "libavutil/timestamp.h"
26         #include "libavformat/avformat.h"
27         #include "libswscale/swscale.h"
28         #include "libswresample/swresample.h"
29 }
30 #endif
31 // Copy from FFMPEG-3.0.2; doc/example/muxing.c .
32
33 #define STREAM_PIX_FMT  AV_PIX_FMT_YUV420P /* default pix_fmt */
34 extern DLL_PREFIX CSP_Logger *csp_logger;
35
36 //#define SCALE_FLAGS SWS_BICUBLIN
37 #define SCALE_FLAGS SWS_POINT
38
39 enum {
40         VIDEO_CODEC_MPEG4 = 0,
41         VIDEO_CODEC_H264,
42         VIDEO_CODEC_END,
43 };
44
45 enum {
46         AUDIO_CODEC_MP3 = 0,
47         AUDIO_CODEC_AAC,
48         AUDIO_CODEC_VORBIS,
49         AUDIO_CODEC_END,
50 };
51
52 enum {
53         VIDEO_CONTAINER_TYPE_MP4 = 0,
54         VIDEO_CONTAINER_TYPE_MKV,
55         VIDEO_CONTAINER_TYPE_END,
56
57 };
58         
59 // a wrapper around a single output AVStream
60 typedef struct OutputStream {
61         AVStream *st;
62
63         /* pts of the next frame that will be generated */
64         int64_t next_pts;
65         int samples_count;
66
67         AVFrame *frame;
68         AVFrame *tmp_frame;
69
70         float t, tincr, tincr2;
71
72         struct SwsContext *sws_ctx;
73         struct SwrContext *swr_ctx;
74 } OutputStream;
75
76 class OSD;
77 class QMutex;
78 QT_BEGIN_NAMESPACE
79 class DLL_PREFIX VIDEO_DATA {
80
81 public:
82         int frames;
83         int _width;
84         int _height;
85         QImage frame_data;
86         VIDEO_DATA(int n_frames, int width, int height, QImage *pp) {
87                 frame_data = QImage(*pp);
88                 frames = n_frames;
89                 _width = width;
90                 _height = height;
91         };
92         ~VIDEO_DATA() {};
93 };
94
95 class DLL_PREFIX MOVIE_SAVER: public QThread
96 {
97         Q_OBJECT
98 private:
99         int n_encode_audio;
100         int n_encode_video;
101         //QMutex *video_queue_mutex;
102 protected:
103         OSD *p_osd;
104         config_t *p_config;
105         
106         bool req_close;
107         bool req_stop;
108
109         bool have_video;
110         bool have_audio;
111         bool encode_video;
112         bool encode_audio;
113         int64_t audio_count;
114         int64_t video_count;
115         QStringList encode_opt_keys;
116         QStringList encode_options;
117 #if defined(USE_LIBAV)
118         AVOutputFormat *stream_format;
119         AVFormatContext *output_context;
120         AVCodec *audio_codec, *video_codec;
121         AVDictionary *raw_options_list;
122
123         OutputStream video_st;
124         OutputStream audio_st;
125 #endif   
126         QString _filename;
127         bool bRunThread;
128         bool debug_timestamp;
129         
130         uint min_rate;
131         uint max_rate;
132         uint buffer_size;
133         int audio_sample_rate;
134         int _width;
135         int _height;
136         int old_width;
137         int old_height;
138         
139         bool recording;
140         int rec_fps;
141
142         
143         uint64_t audio_size;
144         uint64_t video_size;
145         uint32_t ptsFrame;
146
147         uint64_t totalSrcFrame;
148         uint64_t totalDstFrame;
149         uint64_t totalAudioFrame;
150         int left_frames;
151         
152         int16_t audio_frame_buf[2 * 48000 * sizeof(int16_t)]; // 1Sec
153         uint32_t video_frame_buf[1280 * 1024 * sizeof(uint32_t)]; // 1 frame : right?
154
155         QQueue<VIDEO_DATA *> video_data_queue;
156         QQueue<QByteArray *> audio_data_queue;
157         int64_t audio_remain;
158         int64_t video_remain;
159         uint32_t audio_offset;
160         uint32_t audio_frame_offset;
161         uint32_t video_offset;
162         uint64_t audio_frame_number;
163         uint64_t audio_frame_max;
164         uint64_t video_frame_number;
165         uint64_t video_frame_max;
166
167         int audio_bit_rate;
168         int video_bit_rate;
169         QSize video_geometry;
170         int video_encode_threads;
171         
172         bool dequeue_audio(int16_t *);
173         bool dequeue_video(uint32_t *);
174         
175         QString create_date_file_name(void);
176
177         // Got from FFMPEG 3.0.2, doc/examples/muxer.c 
178         //void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
179         void log_packet(const void *_fmt_ctx, const void *_pkt);
180         //int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
181         int write_frame(void *_fmt_ctx, const void *_time_base, void *_st, void *_pkt);
182         //void add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, enum AVCodecID codec_id)
183         bool add_stream(void *_ost, void *_oc, void **_codec, uint64_t codec_id);
184         //AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int sample_rate, int nb_samples)
185         void *alloc_audio_frame(uint64_t _sample_fmt, uint64_t channel_layout,
186                                                         int sample_rate, int nb_samples);
187         //static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
188         bool open_audio(void);
189         //static AVFrame *get_audio_frame(OutputStream *ost)
190         void *get_audio_frame();
191         //static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
192         int write_audio_frame();
193         //static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
194         void *alloc_picture(uint64_t _pix_fmt, int width, int height);
195         //void open_video(OutputStream *_ost, AVDictionary *_opt_arg)
196         bool open_video();
197         //AVFrame *get_video_frame(OutputStream *ost)
198         void *get_video_frame(void);
199         //static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
200         int write_video_frame();
201         //void MOVIE_SAVER::close_stream(AVFormatContext *oc, OutputStream *ost)
202         void close_stream(void *_oc, void *_ost);
203         //void MOVIE_SAVER::setup_h264(AVCodecContext *_codec)
204         void setup_h264(void *_codec);
205         //void MOVIE_SAVER::setup_mpeg4(AVCodecContext *_codec)
206         void setup_mpeg4(void *_codec);
207         //void MOVIE_SAVER::setup_audio(AVCodecContext *_codec_context, AVCodec **_codec)
208         void setup_audio(void *_codec_context, void **_codec);
209
210         QString ts2str(int64_t ts);
211         QString ts2timestr(int64_t ts, void *timebase);
212         QString err2str(int errnum);
213         void do_close_main();
214         bool do_open_main();
215
216 public:
217         MOVIE_SAVER(int width, int height, int fps, OSD *osd, config_t *cfg);
218         ~MOVIE_SAVER();
219         bool is_recording(void);
220
221 public slots:
222         void run();
223         void enqueue_video(int frames, int width, int height, QImage *p);
224         void enqueue_audio(int16_t *p, int size);
225         void do_close();
226         void do_open(QString filename, int _fps, int sample_rate);
227         void do_set_width(int width);
228         void do_set_height(int height);
229         void do_set_record_fps(int fps);
230
231         void do_set_video_bitrate(int kbps);
232         void do_set_audio_bitrate(int kbps);
233         void do_set_video_geometry(QSize geometry);
234         void do_set_video_threads(int threads);
235         
236         void do_clear_options_list(void);
237         void do_add_option(QString key, QString value);
238         void do_reset_encoder_options(void);
239         
240         void do_exit();
241 signals:
242         int sig_ready_to_record();
243         int sig_set_state_saving_movie(bool);
244 };
245 QT_END_NAMESPACE
246
247 #endif