1 // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 // (c) 2020 Henner Zeller <h.zeller@acm.org>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation version 2.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://gnu.org/licenses/gpl-2.0.txt>
15 
16 #ifndef VIDEO_DISPLAY_H_
17 #define VIDEO_DISPLAY_H_
18 
19 #include <signal.h>
20 
21 #include "image-source.h"
22 #include "terminal-canvas.h"
23 #include "timg-time.h"
24 
25 struct AVCodecContext;
26 struct AVFormatContext;
27 struct AVFrame;
28 struct AVPacket;
29 struct SwsContext;
30 
31 namespace timg {
32 
33 // Video loader, meant for one video to load, and if successful, Play().
34 class VideoLoader final : public ImageSource {
35 public:
36     VideoLoader(const std::string &filename);
37     ~VideoLoader() final;
38 
39     static const char *VersionInfo();
40 
41     // Attempt to load given filename as video, open stream and set-up scaling.
42     // Returns true on success.
43     bool LoadAndScale(const DisplayOptions &options,
44                       int frame_offset, int frame_count) final;
45 
46     // Play video up to given duration.
47     //
48     // The reference to the "interrupt_received" can be updated by a signal
49     // while the method is running and shall be checked often.
50     void SendFrames(Duration duration, int loops,
51                     const volatile sig_atomic_t &interrupt_received,
52                     const Renderer::WriteFramebufferFun &sink) final;
53 
54 private:
55     void AlphaBlendFramebuffer();
56 
57     DisplayOptions options_;
58     bool maybe_transparent_ = false;
59     int frame_offset_ = 0;
60     int frame_count_ = -1;
61 
62     int video_stream_index_ = -1;
63     AVFormatContext *format_context_ = nullptr;
64     AVCodecContext *codec_context_ = nullptr;
65     SwsContext *sws_context_ = nullptr;
66     timg::Duration frame_duration_;  // 1/fps
67     timg::Framebuffer *terminal_fb_ = nullptr;
68     int center_indentation_ = 0;
69 };
70 
71 }  // namespace timg
72 
73 #endif // VIDEO_DISPLAY_H_
74