2 * Common Source Code Project for Qt : movie saver.
3 * (C) 2016 K.Ohta <whatisthis.sowhat _at_ gmail.com>
5 * History: May 27, 2016 : Initial. This refer from avidemux 2.5.6 .
8 #ifndef _QT_OSD_MOVIE_SAVER_H
9 #define _QT_OSD_MOVIE_SAVER_H
14 #include <QStringList>
20 #if defined(USE_LIBAV)
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"
31 // Copy from FFMPEG-3.0.2; doc/example/muxing.c .
33 #define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
35 //#define SCALE_FLAGS SWS_BICUBLIN
36 #define SCALE_FLAGS SWS_POINT
39 VIDEO_CODEC_MPEG4 = 0,
41 VIDEO_CODEC_HEVC, // ToDo
42 VIDEO_CODEC_VP9, // ToDo
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)
58 AUIIO_CODEC_OPUS, // ToDo
63 VIDEO_CONTAINER_TYPE_MP4 = 0,
64 VIDEO_CONTAINER_TYPE_MKV,
65 VIDEO_CONTAINER_TYPE_WEBM, // ToDo
66 VIDEO_CONTAINER_TYPE_END,
70 // a wrapper around a single output AVStream
71 typedef struct OutputStream {
74 /* pts of the next frame that will be generated */
81 float t, tincr, tincr2;
83 struct SwsContext *sws_ctx;
84 struct SwrContext *swr_ctx;
85 #if (LIBAVCODEC_VERSION_MAJOR > 56)
86 AVCodecContext *context;
94 class DLL_PREFIX VIDEO_DATA {
101 VIDEO_DATA(int n_frames, int width, int height, QImage *pp) {
102 frame_data = QImage(*pp);
110 class DLL_PREFIX MOVIE_SAVER: public QThread
116 //QMutex *video_queue_mutex;
120 CSP_Logger *p_logger;
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;
139 OutputStream video_st;
140 OutputStream audio_st;
143 bool debug_timestamp;
148 int audio_sample_rate;
162 uint64_t totalSrcFrame;
163 uint64_t totalDstFrame;
164 uint64_t totalAudioFrame;
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?
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;
184 QSize video_geometry;
185 int video_encode_threads;
187 bool dequeue_audio(int16_t *);
188 bool dequeue_video(uint32_t *);
190 QString create_date_file_name(void);
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)
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);
225 QString ts2str(int64_t ts);
226 QString ts2timestr(int64_t ts, void *timebase);
227 QString err2str(int errnum);
228 void do_close_main();
232 MOVIE_SAVER(int width, int height, int fps, OSD *osd, config_t *cfg);
234 bool is_recording(void);
235 QString get_avio_version();
239 void enqueue_video(int frames, int width, int height, QImage *p);
240 void enqueue_audio(int16_t *p, int size);
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);
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);
252 void do_clear_options_list(void);
253 void do_add_option(QString key, QString value);
254 void do_reset_encoder_options(void);
258 int sig_ready_to_record();
259 int sig_set_state_saving_movie(bool);