OSDN Git Service

[Qt][AVIO] Add some codec entries (still not implement).
[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
35 //#define SCALE_FLAGS SWS_BICUBLIN
36 #define SCALE_FLAGS SWS_POINT
37
38 enum {
39         VIDEO_CODEC_MPEG4 = 0,
40         VIDEO_CODEC_H264,
41         VIDEO_CODEC_HEVC,  // ToDo
42         VIDEO_CODEC_VP9,   // ToDo
43         VIDEO_CODEC_END,
44         // ToDo: HWACCEL feature (maybe will not imprement).
45         VIDEO_CODEC_ACCEL_VAAPI = 32, // Intel VAAPI (GNU/Linux and some systems)
46         VIDEO_CODEC_ACCEL_QSV   = 64, // Intel QSV (libmfx)
47         VIDEO_CODEC_ACCEL_NVENC = 96, // NVidia NVENC (maybe Windows Only)
48         VIDEO_CODEC_ACCEL_AMF   = 128, // AMD UVD/VCE (Windows Only)
49         VIDEO_CODEC_ACCEL_VDPAU = 4096, // NVidia VDPAU (GNU/Linux and some systems; Only for decoding (and scaling)).
50         VIDEO_CODEC_ACCEL_DXVA2 = 8192, // Microsoft DXVA2 (Windows only)
51         VIDEO_CODEC_ACCEL_D3D11 = 12228, // Microsoft Direct3D 11 (Windows only)
52 };
53
54 enum {
55         AUDIO_CODEC_MP3 = 0,
56         AUDIO_CODEC_AAC,
57         AUDIO_CODEC_VORBIS,
58         AUIIO_CODEC_OPUS, // ToDo
59         AUDIO_CODEC_END,
60 };
61
62 enum {
63         VIDEO_CONTAINER_TYPE_MP4 = 0,
64         VIDEO_CONTAINER_TYPE_MKV,
65         VIDEO_CONTAINER_TYPE_WEBM, // ToDo
66         VIDEO_CONTAINER_TYPE_END,
67
68 };
69         
70 // a wrapper around a single output AVStream
71 typedef struct OutputStream {
72         AVStream *st;
73
74         /* pts of the next frame that will be generated */
75         int64_t next_pts;
76         int samples_count;
77
78         AVFrame *frame;
79         AVFrame *tmp_frame;
80
81         float t, tincr, tincr2;
82
83         struct SwsContext *sws_ctx;
84         struct SwrContext *swr_ctx;
85 #if (LIBAVCODEC_VERSION_MAJOR > 56)
86         AVCodecContext *context;
87 #endif   
88 } OutputStream;
89
90 class OSD;
91 class QMutex;
92 class CSP_Logger;
93 QT_BEGIN_NAMESPACE
94 class DLL_PREFIX VIDEO_DATA {
95
96 public:
97         int frames;
98         int _width;
99         int _height;
100         QImage frame_data;
101         VIDEO_DATA(int n_frames, int width, int height, QImage *pp) {
102                 frame_data = QImage(*pp);
103                 frames = n_frames;
104                 _width = width;
105                 _height = height;
106         };
107         ~VIDEO_DATA() {};
108 };
109
110 class DLL_PREFIX MOVIE_SAVER: public QThread
111 {
112         Q_OBJECT
113 private:
114         int n_encode_audio;
115         int n_encode_video;
116         //QMutex *video_queue_mutex;
117 protected:
118         OSD *p_osd;
119         config_t *p_config;
120         CSP_Logger *p_logger;
121         
122         bool req_close;
123         bool req_stop;
124
125         bool have_video;
126         bool have_audio;
127         bool encode_video;
128         bool encode_audio;
129         int64_t audio_count;
130         int64_t video_count;
131         QStringList encode_opt_keys;
132         QStringList encode_options;
133 #if defined(USE_LIBAV)
134         AVOutputFormat *stream_format;
135         AVFormatContext *output_context;
136         AVCodec *audio_codec, *video_codec;
137         AVDictionary *raw_options_list;
138 #endif
139         OutputStream video_st;
140         OutputStream audio_st;
141         QString _filename;
142         bool bRunThread;
143         bool debug_timestamp;
144         
145         uint min_rate;
146         uint max_rate;
147         uint buffer_size;
148         int audio_sample_rate;
149         int _width;
150         int _height;
151         int old_width;
152         int old_height;
153         
154         bool recording;
155         int rec_fps;
156
157         
158         uint64_t audio_size;
159         uint64_t video_size;
160         uint32_t ptsFrame;
161
162         uint64_t totalSrcFrame;
163         uint64_t totalDstFrame;
164         uint64_t totalAudioFrame;
165         int left_frames;
166         
167         int16_t audio_frame_buf[2 * 48000 * sizeof(int16_t)]; // 1Sec
168         uint32_t video_frame_buf[1280 * 1024 * sizeof(uint32_t)]; // 1 frame : right?
169
170         QQueue<VIDEO_DATA *> video_data_queue;
171         QQueue<QByteArray *> audio_data_queue;
172         int64_t audio_remain;
173         int64_t video_remain;
174         uint32_t audio_offset;
175         uint32_t audio_frame_offset;
176         uint32_t video_offset;
177         uint64_t audio_frame_number;
178         uint64_t audio_frame_max;
179         uint64_t video_frame_number;
180         uint64_t video_frame_max;
181
182         int audio_bit_rate;
183         int video_bit_rate;
184         QSize video_geometry;
185         int video_encode_threads;
186         
187         bool dequeue_audio(int16_t *);
188         bool dequeue_video(uint32_t *);
189         
190         QString create_date_file_name(void);
191
192         // Got from FFMPEG 3.0.2, doc/examples/muxer.c 
193         //void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
194         void log_packet(const void *_fmt_ctx, const void *_pkt);
195         //int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
196         int write_frame(void *_fmt_ctx, const void *_time_base, void *_st, void *_pkt);
197         //void add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, enum AVCodecID codec_id)
198         bool add_stream(void *_ost, void *_oc, void **_codec, uint64_t codec_id);
199         //AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int sample_rate, int nb_samples)
200         void *alloc_audio_frame(uint64_t _sample_fmt, uint64_t channel_layout,
201                                                         int sample_rate, int nb_samples);
202         //static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
203         bool open_audio(void);
204         //static AVFrame *get_audio_frame(OutputStream *ost)
205         void *get_audio_frame();
206         //static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
207         int write_audio_frame();
208         //static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
209         void *alloc_picture(uint64_t _pix_fmt, int width, int height);
210         //void open_video(OutputStream *_ost, AVDictionary *_opt_arg)
211         bool open_video();
212         //AVFrame *get_video_frame(OutputStream *ost)
213         void *get_video_frame(void);
214         //static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
215         int write_video_frame();
216         //void MOVIE_SAVER::close_stream(AVFormatContext *oc, OutputStream *ost)
217         void close_stream(void *_oc, void *_ost);
218         //void MOVIE_SAVER::setup_h264(AVCodecContext *_codec)
219         void setup_h264(void *_codec);
220         //void MOVIE_SAVER::setup_mpeg4(AVCodecContext *_codec)
221         void setup_mpeg4(void *_codec);
222         //void MOVIE_SAVER::setup_audio(AVCodecContext *_codec_context, AVCodec **_codec)
223         void setup_audio(void *_codec_context, void **_codec);
224
225         QString ts2str(int64_t ts);
226         QString ts2timestr(int64_t ts, void *timebase);
227         QString err2str(int errnum);
228         void do_close_main();
229         bool do_open_main();
230
231 public:
232         MOVIE_SAVER(int width, int height, int fps, OSD *osd, config_t *cfg);
233         ~MOVIE_SAVER();
234         bool is_recording(void);
235         QString get_avio_version();
236
237 public slots:
238         void run();
239         void enqueue_video(int frames, int width, int height, QImage *p);
240         void enqueue_audio(int16_t *p, int size);
241         void do_close();
242         void do_open(QString filename, int _fps, int sample_rate);
243         void do_set_width(int width);
244         void do_set_height(int height);
245         void do_set_record_fps(int fps);
246
247         void do_set_video_bitrate(int kbps);
248         void do_set_audio_bitrate(int kbps);
249         void do_set_video_geometry(QSize geometry);
250         void do_set_video_threads(int threads);
251         
252         void do_clear_options_list(void);
253         void do_add_option(QString key, QString value);
254         void do_reset_encoder_options(void);
255         
256         void do_exit();
257 signals:
258         int sig_ready_to_record();
259         int sig_set_state_saving_movie(bool);
260 };
261 QT_END_NAMESPACE
262
263 #endif