Support lowres capture
This commit is contained in:
parent
a816336de5
commit
50f2a9eb87
@ -115,6 +115,10 @@ int camera_set_params(camera_t *camera)
|
||||
// DEVICE_SET_OPTION(camera->camera, VBLANK, 1636);
|
||||
// DEVICE_SET_OPTION(camera->camera, HBLANK, 6906);
|
||||
|
||||
// DEVICE_SET_OPTION(camera->isp_srgb, RED_BALANCE, 2120);
|
||||
// DEVICE_SET_OPTION(camera->isp_srgb, BLUE_BALANCE, 1472);
|
||||
// DEVICE_SET_OPTION(camera->isp_srgb, DIGITAL_GAIN, 1007);
|
||||
|
||||
DEVICE_SET_OPTION2(camera->codec_jpeg, JPEG, COMPRESSION_QUALITY, 80);
|
||||
|
||||
DEVICE_SET_OPTION2(camera->codec_h264, MPEG_VIDEO, BITRATE, 5000 * 1000);
|
||||
|
@ -32,9 +32,11 @@ typedef struct camera_s {
|
||||
device_t *legacy_isp; // convert pRAA/YUVU into YUVU
|
||||
device_t *isp_srgb;
|
||||
device_t *isp_yuuv;
|
||||
device_t *isp_yuuv_low;
|
||||
device_t *isp_yuuv_lowres;
|
||||
device_t *codec_jpeg; // encode YUVU into JPEG
|
||||
device_t *codec_h264; // encode YUVU into H264
|
||||
device_t *codec_jpeg_lowres; // encode YUVU into JPEG
|
||||
device_t *codec_h264_lowres; // encode YUVU into H264
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -12,31 +12,22 @@ void write_yuvu(buffer_t *buffer);
|
||||
|
||||
int camera_configure_isp(camera_t *camera, float high_div, float low_div)
|
||||
{
|
||||
buffer_list_t *src = camera->camera->capture_list;
|
||||
|
||||
camera->isp_srgb = device_open("ISP", "/dev/video13");
|
||||
camera->isp_yuuv = device_open("ISP-YUUV", "/dev/video14");
|
||||
camera->isp_yuuv->output_device = camera->isp_srgb;
|
||||
camera->codec_jpeg = device_open("JPEG", "/dev/video31");
|
||||
camera->codec_h264 = device_open("H264", "/dev/video11");
|
||||
|
||||
if (device_open_buffer_list_output(camera->isp_srgb, src) < 0 ||
|
||||
device_open_buffer_list_capture(camera->isp_yuuv, src, high_div, V4L2_PIX_FMT_YUYV, true) < 0) {
|
||||
if (device_open_buffer_list_output(camera->isp_srgb, camera->camera->capture_list) < 0 ||
|
||||
device_open_buffer_list_capture(camera->isp_yuuv, camera->camera->capture_list, high_div, V4L2_PIX_FMT_YUYV, true) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (low_div >= 1) {
|
||||
camera->isp_yuuv_low = device_open("ISP-YUUV-LOW", "/dev/video15");
|
||||
camera->isp_yuuv_low->output_device = camera->isp_srgb;
|
||||
camera->isp_yuuv->output_device = camera->isp_srgb;
|
||||
|
||||
if (device_open_buffer_list_capture(camera->isp_yuuv_low, src, low_div, V4L2_PIX_FMT_YUYV, true) < 0) {
|
||||
return -1;
|
||||
}
|
||||
link_t *links = camera->links;
|
||||
*links++ = (link_t){ camera->camera->capture_list, { camera->isp_srgb->output_list } };
|
||||
|
||||
src = camera->isp_yuuv_low->capture_list;
|
||||
} else {
|
||||
src = camera->isp_yuuv->capture_list;
|
||||
}
|
||||
buffer_list_t *src = camera->isp_yuuv->capture_list;
|
||||
|
||||
if (device_open_buffer_list_output(camera->codec_jpeg, src) < 0 ||
|
||||
device_open_buffer_list_capture(camera->codec_jpeg, src, 1.0, V4L2_PIX_FMT_JPEG, true) < 0) {
|
||||
@ -48,22 +39,38 @@ int camera_configure_isp(camera_t *camera, float high_div, float low_div)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// DEVICE_SET_OPTION(camera->isp_srgb, RED_BALANCE, 2120);
|
||||
// DEVICE_SET_OPTION(camera->isp_srgb, BLUE_BALANCE, 1472);
|
||||
// DEVICE_SET_OPTION(camera->isp_srgb, DIGITAL_GAIN, 1007);
|
||||
|
||||
link_t *links = camera->links;
|
||||
|
||||
*links++ = (link_t){ camera->camera->capture_list, { camera->isp_srgb->output_list } };
|
||||
|
||||
if (camera->isp_yuuv_low) {
|
||||
*links++ = (link_t){ camera->isp_yuuv->capture_list, { } };
|
||||
*links++ = (link_t){ camera->isp_yuuv_low->capture_list, { camera->codec_jpeg->output_list, camera->codec_h264->output_list }, { write_yuvu } };
|
||||
} else {
|
||||
*links++ = (link_t){ camera->isp_yuuv->capture_list, { camera->codec_jpeg->output_list, camera->codec_h264->output_list }, { write_yuvu } };
|
||||
}
|
||||
|
||||
*links++ = (link_t){ camera->isp_yuuv->capture_list, { camera->codec_jpeg->output_list, camera->codec_h264->output_list }, { write_yuvu } };
|
||||
*links++ = (link_t){ camera->codec_jpeg->capture_list, { }, { http_jpeg_capture, http_jpeg_needs_buffer } };
|
||||
*links++ = (link_t){ camera->codec_h264->capture_list, { }, { http_h264_capture, http_h264_needs_buffer } };
|
||||
|
||||
// all done
|
||||
if (low_div < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
camera->isp_yuuv_lowres = device_open("ISP-YUUV-LOW", "/dev/video15");
|
||||
camera->codec_jpeg_lowres = device_open("JPEG-LOW", "/dev/video31");
|
||||
camera->codec_h264_lowres = device_open("H264-LOW", "/dev/video11");
|
||||
|
||||
if (device_open_buffer_list_capture(camera->isp_yuuv_lowres, camera->camera->capture_list, low_div, V4L2_PIX_FMT_YUYV, true) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
camera->isp_yuuv_lowres->output_device = camera->isp_srgb;
|
||||
src = camera->isp_yuuv_lowres->capture_list;
|
||||
|
||||
if (device_open_buffer_list_output(camera->codec_jpeg_lowres, src) < 0 ||
|
||||
device_open_buffer_list_capture(camera->codec_jpeg_lowres, src, 1.0, V4L2_PIX_FMT_JPEG, true) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (device_open_buffer_list_output(camera->codec_h264_lowres, src) < 0 ||
|
||||
device_open_buffer_list_capture(camera->codec_h264_lowres, src, 1.0, V4L2_PIX_FMT_H264, true) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*links++ = (link_t){ camera->isp_yuuv_lowres->capture_list, { camera->codec_jpeg_lowres->output_list, camera->codec_h264_lowres->output_list }, { write_yuvu } };
|
||||
*links++ = (link_t){ camera->codec_jpeg_lowres->capture_list, { }, { http_jpeg_lowres_capture, http_jpeg_needs_buffer } };
|
||||
*links++ = (link_t){ camera->codec_h264_lowres->capture_list, { }, { http_h264_lowres_capture, http_h264_needs_buffer } };
|
||||
return 0;
|
||||
}
|
||||
|
@ -47,12 +47,16 @@ void http_404(http_worker_t *worker, FILE *stream);
|
||||
void http_snapshot(http_worker_t *worker, FILE *stream);
|
||||
void http_stream(http_worker_t *worker, FILE *stream);
|
||||
void http_jpeg_capture(struct buffer_s *buf);
|
||||
void http_jpeg_lowres_capture(struct buffer_s *buf);
|
||||
bool http_jpeg_needs_buffer();
|
||||
|
||||
// H264
|
||||
bool http_h264_needs_buffer();
|
||||
void http_h264_capture(buffer_t *buf);
|
||||
void http_h264_lowres_capture(buffer_t *buf);
|
||||
void http_h264_video(http_worker_t *worker, FILE *stream);
|
||||
void http_mkv_video(http_worker_t *worker, FILE *stream);
|
||||
void http_mp4_video(http_worker_t *worker, FILE *stream);
|
||||
void http_mov_video(http_worker_t *worker, FILE *stream);
|
||||
|
||||
#define HTTP_LOW_RES_PARAM "res=low"
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <libavformat/avio.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
DECLARE_BUFFER_LOCK(http_h264);
|
||||
buffer_lock_t *http_h264_buffer_for_res(http_worker_t *worker);
|
||||
|
||||
static const char *const VIDEO_HEADER =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
@ -307,7 +307,7 @@ static void http_ffmpeg_video(http_worker_t *worker, FILE *stream, const char *c
|
||||
av_dict_set_int(&status.output_opts, "nobuffer", 1, 0);
|
||||
av_dict_set_int(&status.output_opts, "flush_packets", 1, 0);
|
||||
|
||||
int n = buffer_lock_write_loop(&http_h264, 0, (buffer_write_fn)http_ffmpeg_video_buf_part, &status);
|
||||
int n = buffer_lock_write_loop(http_h264_buffer_for_res(worker), 0, (buffer_write_fn)http_ffmpeg_video_buf_part, &status);
|
||||
http_ffmpeg_close_status(&status);
|
||||
|
||||
if (status.wrote_header) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "hw/device.h"
|
||||
|
||||
DEFINE_BUFFER_LOCK(http_h264, 0);
|
||||
DEFINE_BUFFER_LOCK(http_h264_lowres, 0);
|
||||
|
||||
static const char *const VIDEO_HEADER =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
@ -21,9 +22,22 @@ void http_h264_capture(buffer_t *buf)
|
||||
buffer_lock_capture(&http_h264, buf);
|
||||
}
|
||||
|
||||
void http_h264_lowres_capture(buffer_t *buf)
|
||||
{
|
||||
buffer_lock_capture(&http_h264_lowres, buf);
|
||||
}
|
||||
|
||||
bool http_h264_needs_buffer()
|
||||
{
|
||||
return buffer_lock_needs_buffer(&http_h264);
|
||||
return buffer_lock_needs_buffer(&http_h264) | buffer_lock_needs_buffer(&http_h264_lowres);
|
||||
}
|
||||
|
||||
buffer_lock_t *http_h264_buffer_for_res(http_worker_t *worker)
|
||||
{
|
||||
if (strstr(worker->client_method, HTTP_LOW_RES_PARAM))
|
||||
return &http_h264_lowres;
|
||||
else
|
||||
return &http_h264;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -67,7 +81,7 @@ void http_h264_video(http_worker_t *worker, FILE *stream)
|
||||
{
|
||||
http_video_status_t status = { stream };
|
||||
|
||||
int n = buffer_lock_write_loop(&http_h264, 0, (buffer_write_fn)http_video_buf_part, &status);
|
||||
int n = buffer_lock_write_loop(http_h264_buffer_for_res(worker), 0, (buffer_write_fn)http_video_buf_part, &status);
|
||||
|
||||
if (status.wrote_header) {
|
||||
return;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "hw/buffer_lock.h"
|
||||
|
||||
DEFINE_BUFFER_LOCK(http_jpeg, 1000);
|
||||
DEFINE_BUFFER_LOCK(http_jpeg_lowres, 1000);
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
#define CONTENT_TYPE "image/jpeg"
|
||||
@ -31,7 +32,7 @@ static const char *const STREAM_BOUNDARY = "\r\n"
|
||||
|
||||
bool http_jpeg_needs_buffer()
|
||||
{
|
||||
return buffer_lock_needs_buffer(&http_jpeg);
|
||||
return buffer_lock_needs_buffer(&http_jpeg) | buffer_lock_needs_buffer(&http_jpeg_lowres);
|
||||
}
|
||||
|
||||
void http_jpeg_capture(buffer_t *buf)
|
||||
@ -39,6 +40,19 @@ void http_jpeg_capture(buffer_t *buf)
|
||||
buffer_lock_capture(&http_jpeg, buf);
|
||||
}
|
||||
|
||||
void http_jpeg_lowres_capture(buffer_t *buf)
|
||||
{
|
||||
buffer_lock_capture(&http_jpeg_lowres, buf);
|
||||
}
|
||||
|
||||
buffer_lock_t *http_jpeg_buffer_for_res(http_worker_t *worker)
|
||||
{
|
||||
if (strstr(worker->client_method, HTTP_LOW_RES_PARAM))
|
||||
return &http_jpeg_lowres;
|
||||
else
|
||||
return &http_jpeg;
|
||||
}
|
||||
|
||||
int http_snapshot_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, FILE *stream)
|
||||
{
|
||||
fprintf(stream, "HTTP/1.1 200 OK\r\n");
|
||||
@ -51,7 +65,7 @@ int http_snapshot_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, FI
|
||||
|
||||
void http_snapshot(http_worker_t *worker, FILE *stream)
|
||||
{
|
||||
int n = buffer_lock_write_loop(&http_jpeg, 1, (buffer_write_fn)http_snapshot_buf_part, stream);
|
||||
int n = buffer_lock_write_loop(http_jpeg_buffer_for_res(worker), 1, (buffer_write_fn)http_snapshot_buf_part, stream);
|
||||
|
||||
if (n <= 0) {
|
||||
http_500_header(stream);
|
||||
@ -79,7 +93,7 @@ int http_stream_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, FILE
|
||||
|
||||
void http_stream(http_worker_t *worker, FILE *stream)
|
||||
{
|
||||
int n = buffer_lock_write_loop(&http_jpeg, 0, (buffer_write_fn)http_stream_buf_part, stream);
|
||||
int n = buffer_lock_write_loop(http_jpeg_buffer_for_res(worker), 0, (buffer_write_fn)http_stream_buf_part, stream);
|
||||
|
||||
if (n == 0) {
|
||||
http_500_header(stream);
|
||||
|
Loading…
x
Reference in New Issue
Block a user