|
|
|
@ -15,9 +15,9 @@ |
|
|
|
|
class VideoEncoder { |
|
|
|
|
public: |
|
|
|
|
VideoEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, |
|
|
|
|
int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height) |
|
|
|
|
int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, bool write) |
|
|
|
|
: filename(filename), type(type), in_width(in_width), in_height(in_height), fps(fps), |
|
|
|
|
bitrate(bitrate), codec(codec), out_width(out_width), out_height(out_height) { } |
|
|
|
|
bitrate(bitrate), codec(codec), out_width(out_width), out_height(out_height), write(write) { } |
|
|
|
|
virtual ~VideoEncoder(); |
|
|
|
|
virtual int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) = 0; |
|
|
|
|
virtual void encoder_open(const char* path) = 0; |
|
|
|
@ -26,8 +26,20 @@ public: |
|
|
|
|
void publisher_init(); |
|
|
|
|
static void publisher_publish(VideoEncoder *e, int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr<capnp::byte> header, kj::ArrayPtr<capnp::byte> dat); |
|
|
|
|
|
|
|
|
|
void writer_open(const char* path) { |
|
|
|
|
if (this->write) write_handler_thread = std::thread(VideoEncoder::write_handler, this, path); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void writer_close() { |
|
|
|
|
if (this->write) { |
|
|
|
|
to_write.push(NULL); |
|
|
|
|
write_handler_thread.join(); |
|
|
|
|
} |
|
|
|
|
assert(to_write.empty()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
bool write; |
|
|
|
|
const char* filename; |
|
|
|
|
int in_width, in_height; |
|
|
|
|
int out_width, out_height, fps; |
|
|
|
@ -42,4 +54,9 @@ private: |
|
|
|
|
// publishing
|
|
|
|
|
std::unique_ptr<PubMaster> pm; |
|
|
|
|
const char *service_name; |
|
|
|
|
|
|
|
|
|
// writing support
|
|
|
|
|
static void write_handler(VideoEncoder *e, const char *path); |
|
|
|
|
std::thread write_handler_thread; |
|
|
|
|
SafeQueue<kj::Array<capnp::word>* > to_write; |
|
|
|
|
}; |
|
|
|
|