diff --git a/camera.cpp b/camera.cpp index 207c506..986e54b 100644 --- a/camera.cpp +++ b/camera.cpp @@ -106,8 +106,6 @@ struct CameraPriv { std::unique_ptr ctrls; std::vector> frame_buffers; std::map mapped_buffers; - bool ts_initialized; - uint64_t ts_start; bool in_error; }; @@ -248,6 +246,7 @@ bool camera_create( // this improves performance by a lot. // https://forums.raspberrypi.com/viewtopic.php?t=352554 // https://github.com/raspberrypi/rpicam-apps/blob/6de1ab6a899df35f929b2a15c0831780bd8e750e/core/rpicam_app.cpp#L1012 + int allocator_fd = create_dma_allocator(); if (allocator_fd < 0) { set_error("failed to open dma heap allocator"); @@ -322,19 +321,11 @@ static void on_request_complete(Request *request) { FrameBuffer *buffer = request->buffers().at(camp->video_stream); - uint64_t ts = buffer->metadata().timestamp / 1000; - - if (!camp->ts_initialized) { - camp->ts_initialized = true; - camp->ts_start = ts; - } - ts -= camp->ts_start; - camp->frame_cb( camp->mapped_buffers.at(buffer), buffer->planes()[0].fd.get(), buffer_size(buffer->planes()), - ts); + buffer->metadata().timestamp / 1000); request->reuse(Request::ReuseFlag::ReuseBuffers); diff --git a/camera.h b/camera.h index fe3a28c..caa4056 100644 --- a/camera.h +++ b/camera.h @@ -6,9 +6,9 @@ typedef void camera_t; typedef void (*camera_frame_cb)( - uint8_t *mapped_buffer, + uint8_t *buffer_mapped, int buffer_fd, - uint64_t size, + uint64_t buffer_size, uint64_t timestamp); typedef void (*camera_error_cb)(); diff --git a/encoder.h b/encoder.h index 713cc99..2c8d948 100644 --- a/encoder.h +++ b/encoder.h @@ -5,11 +5,14 @@ typedef void encoder_t; -typedef void (*encoder_output_cb)(const uint8_t *mapped, uint64_t size, uint64_t ts); +typedef void (*encoder_output_cb)( + const uint8_t *buffer_mapped, + uint64_t buffer_size, + uint64_t timestamp); const char *encoder_get_error(); bool encoder_create(const parameters_t *params, int stride, int colorspace, encoder_output_cb output_cb, encoder_t **enc); -void encoder_encode(encoder_t *enc, uint8_t *mapped_buffer, int buffer_fd, size_t size, uint64_t ts); +void encoder_encode(encoder_t *enc, uint8_t *buffer_mapped, int buffer_fd, size_t buffer_size, uint64_t timestamp); void encoder_reload_params(encoder_t *enc, const parameters_t *params); #endif diff --git a/encoder_hard_h264.c b/encoder_hard_h264.c index e2b2a10..79e38ea 100644 --- a/encoder_hard_h264.c +++ b/encoder_hard_h264.c @@ -264,7 +264,7 @@ bool encoder_hard_h264_create(const parameters_t *params, int stride, int colors return false; } -void encoder_hard_h264_encode(encoder_hard_h264_t *enc, uint8_t *mapped, int fd, size_t size, uint64_t ts) { +void encoder_hard_h264_encode(encoder_hard_h264_t *enc, uint8_t *buffer_mapped, int buffer_fd, size_t buffer_size, uint64_t timestamp) { encoder_hard_h264_priv_t *encp = (encoder_hard_h264_priv_t *)enc; int index = encp->cur_buffer++; @@ -277,12 +277,12 @@ void encoder_hard_h264_encode(encoder_hard_h264_t *enc, uint8_t *mapped, int fd, buf.field = V4L2_FIELD_NONE; buf.memory = V4L2_MEMORY_DMABUF; buf.length = 1; - buf.timestamp.tv_sec = ts / 1000000; - buf.timestamp.tv_usec = ts % 1000000; + buf.timestamp.tv_sec = timestamp / 1000000; + buf.timestamp.tv_usec = timestamp % 1000000; buf.m.planes = planes; - buf.m.planes[0].m.fd = fd; - buf.m.planes[0].bytesused = size; - buf.m.planes[0].length = size; + buf.m.planes[0].m.fd = buffer_fd; + buf.m.planes[0].bytesused = buffer_size; + buf.m.planes[0].length = buffer_size; int res = ioctl(encp->fd, VIDIOC_QBUF, &buf); if (res != 0) { fprintf(stderr, "encoder_hard_h264_encode(): ioctl(VIDIOC_QBUF) failed\n"); diff --git a/encoder_hard_h264.h b/encoder_hard_h264.h index dfaa92d..d0f3074 100644 --- a/encoder_hard_h264.h +++ b/encoder_hard_h264.h @@ -7,11 +7,14 @@ typedef void encoder_hard_h264_t; -typedef void (*encoder_hard_h264_output_cb)(const uint8_t *mapped, uint64_t size, uint64_t ts); +typedef void (*encoder_hard_h264_output_cb)( + const uint8_t *buffer_mapped, + uint64_t buffer_size, + uint64_t timestamp); const char *encoder_hard_h264_get_error(); bool encoder_hard_h264_create(const parameters_t *params, int stride, int colorspace, encoder_hard_h264_output_cb output_cb, encoder_hard_h264_t **enc); -void encoder_hard_h264_encode(encoder_hard_h264_t *enc, uint8_t *mapped, int fd, size_t size, uint64_t ts); +void encoder_hard_h264_encode(encoder_hard_h264_t *enc, uint8_t *buffer_mapped, int buffer_fd, size_t buffer_size, uint64_t timestamp); void encoder_hard_h264_reload_params(encoder_hard_h264_t *enc, const parameters_t *params); #endif diff --git a/encoder_soft_h264.c b/encoder_soft_h264.c index 96f031c..29ffb34 100644 --- a/encoder_soft_h264.c +++ b/encoder_soft_h264.c @@ -97,10 +97,10 @@ bool encoder_soft_h264_create(const parameters_t *params, int stride, int colors return false; } -void encoder_soft_h264_encode(encoder_soft_h264_t *enc, uint8_t *mapped, int fd, size_t size, uint64_t ts) { +void encoder_soft_h264_encode(encoder_soft_h264_t *enc, uint8_t *buffer_mapped, int buffer_fd, size_t buffer_size, uint64_t timestamp) { encoder_soft_h264_priv_t *encp = (encoder_soft_h264_priv_t *)enc; - encp->x_pic_in.img.plane[0] = mapped; // Y + encp->x_pic_in.img.plane[0] = buffer_mapped; // Y encp->x_pic_in.img.plane[1] = encp->x_pic_in.img.plane[0] + encp->x_pic_in.img.i_stride[0] * encp->params->height; // U encp->x_pic_in.img.plane[2] = encp->x_pic_in.img.plane[1] + (encp->x_pic_in.img.i_stride[0] / 2) * (encp->params->height / 2); // V encp->x_pic_in.i_pts = encp->next_pts++; @@ -113,7 +113,7 @@ void encoder_soft_h264_encode(encoder_soft_h264_t *enc, uint8_t *mapped, int fd, pthread_mutex_unlock(&encp->mutex); - encp->output_cb(nal->p_payload, frame_size, ts); + encp->output_cb(nal->p_payload, frame_size, timestamp); } void encoder_soft_h264_reload_params(encoder_soft_h264_t *enc, const parameters_t *params) { diff --git a/encoder_soft_h264.h b/encoder_soft_h264.h index 60c8834..dcd6fab 100644 --- a/encoder_soft_h264.h +++ b/encoder_soft_h264.h @@ -5,11 +5,14 @@ typedef void encoder_soft_h264_t; -typedef void (*encoder_soft_h264_output_cb)(const uint8_t *mapped, uint64_t size, uint64_t ts); +typedef void (*encoder_soft_h264_output_cb)( + const uint8_t *buffer_mapped, + uint64_t buffer_size, + uint64_t timestamp); const char *encoder_soft_h264_get_error(); bool encoder_soft_h264_create(const parameters_t *params, int stride, int colorspace, encoder_soft_h264_output_cb output_cb, encoder_soft_h264_t **enc); -void encoder_soft_h264_encode(encoder_soft_h264_t *enc, uint8_t *mapped, int fd, size_t size, uint64_t ts); +void encoder_soft_h264_encode(encoder_soft_h264_t *enc, uint8_t *buffer_mapped, int buffer_fd, size_t buffer_size, uint64_t timestamp); void encoder_soft_h264_reload_params(encoder_soft_h264_t *enc, const parameters_t *params); #endif diff --git a/main.c b/main.c index 53b378a..c0cbf17 100644 --- a/main.c +++ b/main.c @@ -21,27 +21,27 @@ static text_t *text; static encoder_t *enc; static void on_frame( - uint8_t *mapped, - int fd, - uint64_t size, - uint64_t ts) { + uint8_t *buffer_mapped, + int buffer_fd, + uint64_t buffer_size, + uint64_t timestamp) { // mapped DMA buffers require a DMA_BUF_IOCTL_SYNC before and after usage. // https://forums.raspberrypi.com/viewtopic.php?t=352554 struct dma_buf_sync dma_sync = {0}; dma_sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW; - ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_sync); + ioctl(buffer_fd, DMA_BUF_IOCTL_SYNC, &dma_sync); - text_draw(text, mapped); + text_draw(text, buffer_mapped); dma_sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; - ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_sync); + ioctl(buffer_fd, DMA_BUF_IOCTL_SYNC, &dma_sync); - encoder_encode(enc, mapped, fd, size, ts); + encoder_encode(enc, buffer_mapped, buffer_fd, buffer_size, timestamp); } -static void on_encoder_output(const uint8_t *mapped, uint64_t size, uint64_t ts) { +static void on_encoder_output(const uint8_t *buffer_mapped, uint64_t buffer_size, uint64_t timestamp) { pthread_mutex_lock(&pipe_out_mutex); - pipe_write_buf(pipe_out_fd, mapped, size, ts); + pipe_write_buf(pipe_out_fd, buffer_mapped, buffer_size, timestamp); pthread_mutex_unlock(&pipe_out_mutex); }