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
|
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2020, Raspberry Pi (Trading) Ltd.
*
* mjpeg_encoder.hpp - mjpeg video encoder.
*/
#pragma once
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include <functional>
struct jpeg_compress_struct;
typedef std::function<void(void *, size_t, int64_t, unsigned int)> OutputReadyCallback;
struct StreamInfo
{
StreamInfo() : width(0), height(0), stride(0) {}
unsigned int width;
unsigned int height;
unsigned int stride;
libcamera::PixelFormat pixel_format;
std::optional<libcamera::ColorSpace> colour_space;
};
class MjpegEncoder
{
public:
MjpegEncoder();
~MjpegEncoder();
void EncodeBuffer(void *mem, void *dest, unsigned int size,
StreamInfo const &info, int64_t timestamp_us,
unsigned int cookie);
StreamInfo getStreamInfo(libcamera::Stream *stream);
void SetOutputReadyCallback(OutputReadyCallback callback) { output_ready_callback_ = callback; }
private:
static const int NUM_ENC_THREADS = 4;
void encodeThread(int num);
/*
* Handle the output buffers in another thread so as not to block the
* encoders. The application can take its time, after which we return
* this buffer to the encoder for re-use.
*/
void outputThread();
bool abortEncode_;
bool abortOutput_;
uint64_t index_;
struct EncodeItem
{
void *mem;
void *dest;
unsigned int size;
StreamInfo info;
int64_t timestamp_us;
uint64_t index;
unsigned int cookie;
};
std::queue<EncodeItem> encode_queue_;
std::mutex encode_mutex_;
std::condition_variable encode_cond_var_;
std::thread encode_thread_[NUM_ENC_THREADS];
void encodeJPEG(struct jpeg_compress_struct &cinfo, EncodeItem &item,
uint8_t *&encoded_buffer, size_t &buffer_len);
struct OutputItem
{
void *mem;
size_t bytes_used;
int64_t timestamp_us;
uint64_t index;
unsigned int cookie;
};
std::queue<OutputItem> output_queue_[NUM_ENC_THREADS];
std::mutex output_mutex_;
std::condition_variable output_cond_var_;
std::thread output_thread_;
OutputReadyCallback output_ready_callback_ ;
};
|