Blue Brain BioExplorer
encoder.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 EPFL/Blue Brain Project
3  * All rights reserved. Do not distribute without permission.
4  *
5  * This file is part of Blue Brain BioExplorer <https://github.com/BlueBrain/BioExplorer>
6  *
7  * This library is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Lesser General Public License version 3.0 as published
9  * by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #pragma once
22 
23 extern "C"
24 {
25 #include <libavcodec/avcodec.h>
26 #include <libavformat/avformat.h>
27 #include <libavutil/opt.h>
28 #include <libswscale/swscale.h>
29 }
30 
33 
34 #include <atomic>
35 #include <condition_variable>
36 #include <functional>
37 #include <mutex>
38 #include <queue>
39 #include <thread>
40 
41 namespace core
42 {
43 class Picture
44 {
45 public:
46  AVFrame *frame{nullptr};
47 
48  int init(enum AVPixelFormat pix_fmt, int width, int height)
49  {
50  frame = av_frame_alloc();
51  frame->format = pix_fmt;
52  frame->width = width;
53  frame->height = height;
54  return av_frame_get_buffer(frame, 32);
55  }
56 
58  {
59  if (frame)
60  av_frame_free(&frame);
61  }
62 };
63 
64 template <typename T, size_t S = 2>
65 class MTQueue
66 {
67 public:
68  explicit MTQueue(const size_t maxSize = S)
69  : _maxSize(maxSize)
70  {
71  }
72 
73  void clear()
74  {
75  std::unique_lock<std::mutex> lock(_mutex);
76  std::queue<T>().swap(_queue);
77  _condition.notify_all();
78  }
79 
80  void push(const T &element)
81  {
82  std::unique_lock<std::mutex> lock(_mutex);
83  _condition.wait(lock, [&] { return _queue.size() < _maxSize; });
84  _queue.push(element);
85  _condition.notify_all();
86  }
87 
88  T pop()
89  {
90  std::unique_lock<std::mutex> lock(_mutex);
91  _condition.wait(lock, [&] { return !_queue.empty(); });
92 
93  T element = _queue.front();
94  _queue.pop();
95  _condition.notify_all();
96  return element;
97  }
98  size_t size() const
99  {
100  std::unique_lock<std::mutex> lock(_mutex);
101  return _queue.size();
102  }
103 
104 private:
105  std::queue<T> _queue;
106  mutable std::mutex _mutex;
107  mutable std::condition_variable _condition;
108  const size_t _maxSize;
109 };
110 
111 class Encoder
112 {
113 public:
114  using DataFunc = std::function<void(const char *data, size_t size)>;
115 
116  Encoder(const int width, const int height, const int fps,
117  const int64_t kbps, const DataFunc &dataFunc);
118  ~Encoder();
119 
120  void encode(FrameBuffer &fb);
121 
123  const int width;
124  const int height;
125  const int64_t kbps;
126 
127 private:
128  const int _fps;
129  AVFormatContext *formatContext{nullptr};
130  AVStream *stream{nullptr};
131 
132  AVCodecContext *codecContext{nullptr};
133  AVCodec *codec{nullptr};
134 
135  SwsContext *sws_context{nullptr};
136  Picture picture;
137 
138  int64_t _frameNumber{0};
139 
140  const bool _async = true;
141  std::thread _thread;
142  std::atomic_bool _running{true};
143 
144  struct Image
145  {
146  int width{0};
147  int height{0};
148  std::vector<uint8_t> data;
149  bool empty() const { return width == 0 || height == 0; }
150  void clear() { width = height = 0; }
151  } _image[2];
152 
153  MTQueue<int> _queue;
154  int _currentImage{0};
155 
156  void _runAsync();
157  void _encode();
158  void _toPicture(const uint8_t *const data, const int width,
159  const int height);
160 
161  Timer _timer;
162  float _leftover{0.f};
163 };
164 } // namespace core
std::function< void(const char *data, size_t size)> DataFunc
Definition: encoder.h:114
void encode(FrameBuffer &fb)
Definition: encoder.cpp:135
const int width
Definition: encoder.h:123
DataFunc _dataFunc
Definition: encoder.h:122
Encoder(const int width, const int height, const int fps, const int64_t kbps, const DataFunc &dataFunc)
Definition: encoder.cpp:35
const int64_t kbps
Definition: encoder.h:125
const int height
Definition: encoder.h:124
This class represents a frame buffer for an engine specific code. It provides an API for utilizing an...
Definition: FrameBuffer.h:39
void clear()
Definition: encoder.h:73
size_t size() const
Definition: encoder.h:98
void push(const T &element)
Definition: encoder.h:80
MTQueue(const size_t maxSize=S)
Definition: encoder.h:68
AVFrame * frame
Definition: encoder.h:46
int init(enum AVPixelFormat pix_fmt, int width, int height)
Definition: encoder.h:48