You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					83 lines
				
				3.0 KiB
			
		
		
			
		
	
	
					83 lines
				
				3.0 KiB
			| 
											4 years ago
										 | #include <cassert>
 | ||
| 
											3 years ago
										 | #include "system/loggerd/encoder/encoder.h"
 | ||
| 
											4 years ago
										 | 
 | ||
|  | VideoEncoder::~VideoEncoder() {}
 | ||
|  | 
 | ||
|  | void VideoEncoder::publisher_init() {
 | ||
|  |   // publish
 | ||
|  |   service_name = this->type == DriverCam ? "driverEncodeData" :
 | ||
|  |     (this->type == WideRoadCam ? "wideRoadEncodeData" :
 | ||
|  |     (this->in_width == this->out_width ? "roadEncodeData" : "qRoadEncodeData"));
 | ||
|  |   pm.reset(new PubMaster({service_name}));
 | ||
|  | }
 | ||
|  | 
 | ||
|  | void VideoEncoder::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) {
 | ||
|  |   // broadcast packet
 | ||
|  |   MessageBuilder msg;
 | ||
|  |   auto event = msg.initEvent(true);
 | ||
|  |   auto edat = (e->type == DriverCam) ? event.initDriverEncodeData() :
 | ||
|  |     ((e->type == WideRoadCam) ? event.initWideRoadEncodeData() :
 | ||
|  |     (e->in_width == e->out_width ? event.initRoadEncodeData() : event.initQRoadEncodeData()));
 | ||
|  |   auto edata = edat.initIdx();
 | ||
| 
											4 years ago
										 |   struct timespec ts;
 | ||
|  |   timespec_get(&ts, TIME_UTC);
 | ||
|  |   edat.setUnixTimestampNanos((uint64_t)ts.tv_sec*1000000000 + ts.tv_nsec);
 | ||
| 
											4 years ago
										 |   edata.setFrameId(extra.frame_id);
 | ||
|  |   edata.setTimestampSof(extra.timestamp_sof);
 | ||
|  |   edata.setTimestampEof(extra.timestamp_eof);
 | ||
|  |   edata.setType(e->codec);
 | ||
| 
											4 years ago
										 |   edata.setEncodeId(e->cnt++);
 | ||
| 
											4 years ago
										 |   edata.setSegmentNum(segment_num);
 | ||
|  |   edata.setSegmentId(idx);
 | ||
|  |   edata.setFlags(flags);
 | ||
|  |   edata.setLen(dat.size());
 | ||
|  |   edat.setData(dat);
 | ||
|  |   if (flags & V4L2_BUF_FLAG_KEYFRAME) edat.setHeader(header);
 | ||
|  | 
 | ||
|  |   auto words = new kj::Array<capnp::word>(capnp::messageToFlatArray(msg));
 | ||
|  |   auto bytes = words->asBytes();
 | ||
|  |   e->pm->send(e->service_name, bytes.begin(), bytes.size());
 | ||
|  |   if (e->write) {
 | ||
|  |     e->to_write.push(words);
 | ||
|  |   } else {
 | ||
|  |     delete words;
 | ||
|  |   }
 | ||
|  | }
 | ||
|  | 
 | ||
|  | // TODO: writing should be moved to loggerd
 | ||
|  | void VideoEncoder::write_handler(VideoEncoder *e, const char *path) {
 | ||
|  |   VideoWriter writer(path, e->filename, e->codec != cereal::EncodeIndex::Type::FULL_H_E_V_C, e->out_width, e->out_height, e->fps, e->codec);
 | ||
|  | 
 | ||
|  |   bool first = true;
 | ||
|  |   kj::Array<capnp::word>* out_buf;
 | ||
|  |   while ((out_buf = e->to_write.pop())) {
 | ||
|  |     capnp::FlatArrayMessageReader cmsg(*out_buf);
 | ||
|  |     cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();
 | ||
|  | 
 | ||
|  |     auto edata = (e->type == DriverCam) ? event.getDriverEncodeData() :
 | ||
|  |       ((e->type == WideRoadCam) ? event.getWideRoadEncodeData() :
 | ||
|  |       (e->in_width == e->out_width ? event.getRoadEncodeData() : event.getQRoadEncodeData()));
 | ||
|  |     auto idx = edata.getIdx();
 | ||
|  |     auto flags = idx.getFlags();
 | ||
|  | 
 | ||
|  |     if (first) {
 | ||
|  |       assert(flags & V4L2_BUF_FLAG_KEYFRAME);
 | ||
|  |       auto header = edata.getHeader();
 | ||
|  |       writer.write((uint8_t *)header.begin(), header.size(), idx.getTimestampEof()/1000, true, false);
 | ||
|  |       first = false;
 | ||
|  |     }
 | ||
|  | 
 | ||
|  |     // dangerous cast from const, but should be fine
 | ||
|  |     auto data = edata.getData();
 | ||
|  |     if (data.size() > 0) {
 | ||
|  |       writer.write((uint8_t *)data.begin(), data.size(), idx.getTimestampEof()/1000, false, flags & V4L2_BUF_FLAG_KEYFRAME);
 | ||
|  |     }
 | ||
|  | 
 | ||
|  |     // free the data
 | ||
|  |     delete out_buf;
 | ||
|  |   }
 | ||
|  | 
 | ||
|  |   // VideoWriter is freed on out of scope
 | ||
|  | }
 |