forked from jtanx/omxcv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathomxcv-impl.h
123 lines (99 loc) · 3.48 KB
/
omxcv-impl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* @file omxcv-impl.cpp
* @brief Actual implementation class
*/
#ifndef __OMXCV_IMPL_H
#define __OMXCV_IMPL_H
#include <thread>
#include <mutex>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <utility>
#include <opencv2/opencv.hpp>
//Sigh
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/avutil.h>
#include <libavutil/mathematics.h>
#include <libavformat/avio.h>
//Without the right struct packing the buffers will be screwed...
//nFlags won't be set correctly...
#pragma pack(4)
#include <bcm_host.h>
#include <ilclient.h>
//For OMX_IndexParamNalStreamFormatSelect
#include <OMX_Broadcom.h>
#pragma pack()
}
//Determine what frame allocation routine to use
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1)
#define OMXCV_AV_FRAME_ALLOC av_frame_alloc
#define OMXCV_AV_FRAME_FREE av_frame_free
#else
#define OMXCV_AV_FRAME_ALLOC avcodec_alloc_frame
#define OMXCV_AV_FRAME_FREE avcodec_free_frame
#endif
#define OMX_ENCODE_PORT_IN 200
#define OMX_ENCODE_PORT_OUT 201
#define OMX_JPEG_PORT_IN 340
#define OMX_JPEG_PORT_OUT 341
//The maximum size of a NALU. We'll just assume 512 KB.
#define MAX_NALU_SIZE (512*1024)
#define CHECKED(c, v) if ((c)) throw std::invalid_argument(v)
extern void BGR2RGB(const cv::Mat &src, uint8_t *dst, int stride);
namespace omxcv {
/**
* Our implementation class of the encoder.
*/
class OmxCvImpl {
public:
OmxCvImpl(const char *name, int width, int height, int bitrate, int fpsnum=-1, int fpsden=-1);
virtual ~OmxCvImpl();
bool process(const cv::Mat &mat);
private:
int m_width, m_height, m_stride, m_bitrate, m_fpsnum, m_fpsden;
uint8_t *m_sps, *m_pps;
uint16_t m_sps_length, m_pps_length;
uint32_t m_nalu_filled, m_nalu_required;
uint8_t *m_nalu_buffer;
bool m_initted_header;
std::string m_filename;
std::condition_variable m_input_signaller;
std::deque<std::pair<OMX_BUFFERHEADERTYPE *, int64_t>> m_input_queue;
std::thread m_input_worker;
std::mutex m_input_mutex;
std::atomic<bool> m_stop;
/** The OpenMAX IL client **/
ILCLIENT_T *m_ilclient;
COMPONENT_T *m_encoder_component;
/** Writing out stuff **/
AVFormatContext *m_mux_ctx;
AVStream *m_video_stream;
std::chrono::steady_clock::time_point m_frame_start;
int m_frame_count;
bool lav_init();
bool dump_codec_private();
void input_worker();
bool write_data(OMX_BUFFERHEADERTYPE *out, int64_t timestamp);
};
class OmxCvJpegImpl {
public:
OmxCvJpegImpl(int width, int height, int quality=90);
virtual ~OmxCvJpegImpl();
bool process(const char *filename, const cv::Mat &mat);
private:
int m_width, m_height, m_stride, m_quality;
std::condition_variable m_input_signaller;
std::deque<std::pair<OMX_BUFFERHEADERTYPE *, std::string>> m_input_queue;
std::thread m_input_worker;
std::mutex m_input_mutex;
std::atomic<bool> m_stop;
ILCLIENT_T *m_ilclient;
COMPONENT_T *m_encoder_component;
void input_worker();
};
}
#endif // __OMXCV_IMPL_H