OSDN Git Service

[Qt][MOVIE_SAVER] Safer closing files.
[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 <QThread>
15 #include <QSize>
16
17 #if defined(USE_LIBAV)
18 extern "C" {
19         #include "libavutil/channel_layout.h"
20         #include "libavutil/opt.h"
21         #include "libavutil/mathematics.h"
22         #include "libavutil/timestamp.h"
23         #include "libavformat/avformat.h"
24         #include "libswscale/swscale.h"
25         #include "libswresample/swresample.h"
26 }
27 #endif
28 // Copy from FFMPEG-3.0.2; doc/example/muxing.c .
29
30 #define STREAM_PIX_FMT  AV_PIX_FMT_YUV420P /* default pix_fmt */
31
32 //#define SCALE_FLAGS SWS_BICUBLIN
33 #define SCALE_FLAGS SWS_POINT
34
35 // a wrapper around a single output AVStream
36 typedef struct OutputStream {
37         AVStream *st;
38
39         /* pts of the next frame that will be generated */
40         int64_t next_pts;
41         int samples_count;
42
43         AVFrame *frame;
44         AVFrame *tmp_frame;
45
46         float t, tincr, tincr2;
47
48         struct SwsContext *sws_ctx;
49         struct SwrContext *swr_ctx;
50 } OutputStream;
51
52 class OSD;
53
54 QT_BEGIN_NAMESPACE
55 class MOVIE_SAVER: public QThread
56 {
57         Q_OBJECT
58 private:
59         int n_encode_audio;
60         int n_encode_video;
61
62 protected:
63         OSD *p_osd;
64
65         bool req_close;
66         
67         bool have_video;
68         bool have_audio;
69         bool encode_video;
70         bool encode_audio;
71         int64_t audio_count;
72         int64_t video_count;
73         QStringList encode_opt_keys;
74         QStringList encode_options;
75 #if defined(USE_LIBAV)
76         AVOutputFormat *stream_format;
77         AVFormatContext *output_context;
78         AVCodec *audio_codec, *video_codec;
79         AVDictionary *raw_options_list;
80
81         OutputStream video_st;
82         OutputStream audio_st;
83 #endif   
84         QString _filename;
85         bool bRunThread;
86         bool debug_timestamp;
87         
88         uint min_rate;
89         uint max_rate;
90         uint buffer_size;
91         int audio_sample_rate;
92         int _width;
93         int _height;
94         int old_width;
95         int old_height;
96         
97         bool recording;
98         int rec_fps;
99
100         
101         uint64_t audio_size;
102         uint64_t video_size;
103         uint32_t ptsFrame;
104
105         uint64_t totalSrcFrame;
106         uint64_t totalDstFrame;
107         uint64_t totalAudioFrame;
108
109         int16_t audio_frame_buf[2 * 48000 * sizeof(int16_t)]; // 1Sec
110         uint32_t video_frame_buf[1280 * 1024 * sizeof(uint32_t)]; // 1 frame : right?
111
112         QQueue<QImage *> video_data_queue;
113         QQueue<QByteArray *> audio_data_queue;
114         int64_t audio_remain;
115         int64_t video_remain;
116         uint32_t audio_offset;
117         uint32_t audio_frame_offset;
118         uint32_t video_offset;
119         uint64_t audio_frame_number;
120         uint64_t audio_frame_max;
121         uint64_t video_frame_number;
122         uint64_t video_frame_max;
123
124         int audio_bit_rate;
125         int video_bit_rate;
126         QSize video_geometry;
127         int video_encode_threads;
128         
129         bool dequeue_audio(int16_t *);
130         bool dequeue_video(uint32_t *);
131         
132         QString create_date_file_name(void);
133
134         // Got from FFMPEG 3.0.2, doc/examples/muxer.c 
135         //void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
136         void log_packet(const void *_fmt_ctx, const void *_pkt);
137         //int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
138         int write_frame(void *_fmt_ctx, const void *_time_base, void *_st, void *_pkt);
139         //void add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, enum AVCodecID codec_id)
140         bool add_stream(void *_ost, void *_oc, void **_codec, uint64_t codec_id);
141         //AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int sample_rate, int nb_samples)
142         void *alloc_audio_frame(uint64_t _sample_fmt, uint64_t channel_layout,
143                                                         int sample_rate, int nb_samples);
144         //static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
145         bool open_audio(void);
146         //static AVFrame *get_audio_frame(OutputStream *ost)
147         void *get_audio_frame();
148         //static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
149         int write_audio_frame();
150         //static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
151         void *alloc_picture(uint64_t _pix_fmt, int width, int height);
152         //void open_video(OutputStream *_ost, AVDictionary *_opt_arg)
153         bool open_video();
154         //AVFrame *get_video_frame(OutputStream *ost)
155         void *get_video_frame(void);
156         //static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
157         int write_video_frame();
158         //void MOVIE_SAVER::close_stream(AVFormatContext *oc, OutputStream *ost)
159         void close_stream(void *_oc, void *_ost);
160
161
162         QString ts2str(int64_t ts);
163         QString ts2timestr(int64_t ts, void *timebase);
164         QString err2str(int errnum);
165         void do_close_main();
166
167 public:
168         MOVIE_SAVER(int width, int height, int fps, OSD *osd);
169         ~MOVIE_SAVER();
170         bool is_recording(void);
171
172 public slots:
173         void run();
174         void enqueue_video(QImage *p);
175         void enqueue_audio(int16_t *p, int size);
176         void do_close();
177         bool do_open(QString filename, int _fps, int sample_rate);
178         void do_set_width(int width);
179         void do_set_height(int height);
180         void do_set_record_fps(int fps);
181
182         void do_set_video_bitrate(int kbps);
183         void do_set_audio_bitrate(int kbps);
184         void do_set_video_geometry(QSize geometry);
185         void do_set_video_threads(int threads);
186         
187         void do_clear_options_list(void);
188         void do_add_option(QString key, QString value);
189         void do_reset_encoder_options(void);
190         
191         void do_exit();
192 };
193 QT_END_NAMESPACE
194
195 #endif