summaryrefslogtreecommitdiff
path: root/camera.c
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-02-23 13:29:17 -0500
committerpommicket <pommicket@gmail.com>2025-02-25 15:16:08 -0500
commit78f28b310251cd3e35d588c9f1476e3d0ef6d983 (patch)
treea077d205c55a8daefc18085ac6c589ce1aacf003 /camera.c
parent31d0e293b384ac89543c309c8c3b300130495c2e (diff)
actual video recording is workign!
Diffstat (limited to 'camera.c')
-rw-r--r--camera.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/camera.c b/camera.c
index 74434c8..b9b2200 100644
--- a/camera.c
+++ b/camera.c
@@ -10,6 +10,7 @@
#include "ds.h"
#include "3rd_party/stb_image_write.h"
#include <jpeglib.h>
+#include <libavcodec/avcodec.h>
#define CAMERA_MAX_BUFFERS 4
struct Camera {
@@ -925,3 +926,36 @@ void camera_hash_str(Camera *camera, char str[HASH_SIZE * 2 + 1]) {
const char *camera_devnode(Camera *camera) {
return camera->devnode;
}
+
+bool camera_copy_to_av_frame(Camera *camera, struct AVFrame *frame_out) {
+ uint8_t *frame_in = camera_curr_frame(camera);
+ int32_t frame_width = camera_frame_width(camera);
+ int32_t frame_height = camera_frame_height(camera);
+ if (!frame_in
+ || frame_width != frame_out->width
+ || frame_height != frame_out->height
+ || camera_pixel_format(camera) != V4L2_PIX_FMT_YUV420
+ || frame_out->format != AV_PIX_FMT_YUV420P) {
+ return false;
+ }
+ // copy Y plane
+ for (int64_t y = 0; y < frame_height; y++) {
+ memcpy(&frame_out->data[0][y * frame_out->linesize[0]],
+ &frame_in[y * frame_width], frame_width);
+ }
+ // copy Cb plane
+ int64_t cb_offset = (int64_t)frame_width * frame_height;
+ for (int64_t y = 0; y < frame_height / 2; y++) {
+ memcpy(&frame_out->data[1][y * frame_out->linesize[1]],
+ &frame_in[cb_offset + y * (frame_width / 2)],
+ frame_width / 2);
+ }
+ // copy Cr plane
+ int64_t cr_offset = cb_offset + (int64_t)frame_width / 2 * frame_height / 2;
+ for (int64_t y = 0; y < frame_height / 2; y++) {
+ memcpy(&frame_out->data[2][y * frame_out->linesize[2]],
+ &frame_in[cr_offset + y * (frame_width / 2)],
+ frame_width / 2);
+ }
+ return true;
+}