mirror of
https://github.com/pikvm/ustreamer.git
synced 2025-12-24 03:00:01 +00:00
refactoring
This commit is contained in:
parent
55709a8e8a
commit
dd73b431f7
@ -230,7 +230,7 @@ static void *_capture_worker_thread(void *v_ctx_ptr) {
|
||||
A_PTHREAD_M_UNLOCK(ctx->has_job_mutex);
|
||||
|
||||
if (!*ctx->workers_stop) {
|
||||
int compressed;
|
||||
unsigned long compressed;
|
||||
time_t start_sec;
|
||||
time_t stop_sec;
|
||||
long start_msec;
|
||||
@ -241,7 +241,7 @@ static void *_capture_worker_thread(void *v_ctx_ptr) {
|
||||
|
||||
LOG_DEBUG("Worker %d compressing JPEG ...", ctx->index);
|
||||
|
||||
compressed = jpeg_compress_buffer(ctx->dev, ctx->index); // FIXME
|
||||
compressed = jpeg_compress_buffer(ctx->dev, ctx->index);
|
||||
|
||||
assert(!_capture_release_buffer(ctx->dev, &ctx->buf_info)); // FIXME
|
||||
*ctx->has_job = false;
|
||||
@ -257,7 +257,7 @@ static void *_capture_worker_thread(void *v_ctx_ptr) {
|
||||
*ctx->last_comp_time = last_comp_time;
|
||||
A_PTHREAD_M_UNLOCK(ctx->last_comp_time_mutex);
|
||||
|
||||
LOG_INFO("Compressed JPEG size=%d; time=%LG (worker %d)", compressed, last_comp_time, ctx->index);
|
||||
LOG_INFO("Compressed JPEG size=%ld; time=%LG (worker %d)", compressed, last_comp_time, ctx->index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
88
src/device.c
88
src/device.c
@ -44,7 +44,7 @@ static void _device_open_alloc_picbufs(struct device_t *dev);
|
||||
static int _device_open_mmap(struct device_t *dev);
|
||||
static int _device_open_queue_buffers(struct device_t *dev);
|
||||
|
||||
static const char *_format_to_string_auto(char *buf, const size_t length, const unsigned format);
|
||||
static const char *_format_to_string_auto(char *buf, const size_t size, const unsigned format);
|
||||
static const char *_format_to_string_null(const unsigned format);
|
||||
static const char *_standard_to_string(const v4l2_std_id standard);
|
||||
|
||||
@ -123,25 +123,25 @@ int device_open(struct device_t *dev) {
|
||||
void device_close(struct device_t *dev) {
|
||||
if (dev->run->pictures) {
|
||||
LOG_DEBUG("Releasing picture buffers ...");
|
||||
for (unsigned index = 0; index < dev->run->n_buffers && dev->run->pictures[index]; ++index) {
|
||||
free(dev->run->pictures[index]);
|
||||
for (unsigned index = 0; index < dev->run->n_buffers && dev->run->pictures[index].data; ++index) {
|
||||
free(dev->run->pictures[index].data);
|
||||
}
|
||||
free(dev->run->pictures);
|
||||
dev->run->pictures = NULL;
|
||||
}
|
||||
|
||||
if (dev->run->buffers) {
|
||||
LOG_DEBUG("Unmapping device buffers ...");
|
||||
if (dev->run->hw_buffers) {
|
||||
LOG_DEBUG("Unmapping HW buffers ...");
|
||||
for (unsigned index = 0; index < dev->run->n_buffers; ++index) {
|
||||
if (dev->run->buffers[index].start != MAP_FAILED) {
|
||||
if (munmap(dev->run->buffers[index].start, dev->run->buffers[index].length) < 0) {
|
||||
if (dev->run->hw_buffers[index].start != MAP_FAILED) {
|
||||
if (munmap(dev->run->hw_buffers[index].start, dev->run->hw_buffers[index].length) < 0) {
|
||||
LOG_PERROR("Can't unmap device buffer %d", index);
|
||||
}
|
||||
}
|
||||
}
|
||||
dev->run->n_buffers = 0;
|
||||
free(dev->run->buffers);
|
||||
dev->run->buffers = NULL;
|
||||
free(dev->run->hw_buffers);
|
||||
dev->run->hw_buffers = NULL;
|
||||
}
|
||||
|
||||
if (dev->run->fd >= 0) {
|
||||
@ -327,30 +327,30 @@ static int _device_open_mmap(struct device_t *dev) {
|
||||
LOG_ERROR("Insufficient buffer memory: %d", req.count);
|
||||
return -1;
|
||||
} else {
|
||||
LOG_INFO("Requested %d device buffers, got %d", dev->n_buffers, req.count);
|
||||
LOG_INFO("Requested %d HW buffers, got %d", dev->n_buffers, req.count);
|
||||
}
|
||||
|
||||
LOG_DEBUG("Allocating device buffers ...");
|
||||
LOG_DEBUG("Allocating HW buffers ...");
|
||||
|
||||
A_CALLOC(dev->run->buffers, req.count, sizeof(*dev->run->buffers));
|
||||
A_CALLOC(dev->run->hw_buffers, req.count, sizeof(*dev->run->hw_buffers));
|
||||
for (dev->run->n_buffers = 0; dev->run->n_buffers < req.count; ++dev->run->n_buffers) {
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_buffer buf_info;
|
||||
|
||||
MEMSET_ZERO(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = dev->run->n_buffers;
|
||||
MEMSET_ZERO(buf_info);
|
||||
buf_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf_info.memory = V4L2_MEMORY_MMAP;
|
||||
buf_info.index = dev->run->n_buffers;
|
||||
|
||||
LOG_DEBUG("Calling ioctl(VIDIOC_QUERYBUF) for device buffer %d ...", dev->run->n_buffers);
|
||||
if (xioctl(dev->run->fd, VIDIOC_QUERYBUF, &buf) < 0) {
|
||||
if (xioctl(dev->run->fd, VIDIOC_QUERYBUF, &buf_info) < 0) {
|
||||
LOG_PERROR("Can't VIDIOC_QUERYBUF");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Mapping device buffer %d ...", dev->run->n_buffers);
|
||||
dev->run->buffers[dev->run->n_buffers].length = buf.length;
|
||||
dev->run->buffers[dev->run->n_buffers].start = mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, dev->run->fd, buf.m.offset);
|
||||
if (dev->run->buffers[dev->run->n_buffers].start == MAP_FAILED) {
|
||||
dev->run->hw_buffers[dev->run->n_buffers].length = buf_info.length;
|
||||
dev->run->hw_buffers[dev->run->n_buffers].start = mmap(NULL, buf_info.length, PROT_READ|PROT_WRITE, MAP_SHARED, dev->run->fd, buf_info.m.offset);
|
||||
if (dev->run->hw_buffers[dev->run->n_buffers].start == MAP_FAILED) {
|
||||
LOG_PERROR("Can't map device buffer %d", dev->run->n_buffers);
|
||||
return -1;
|
||||
}
|
||||
@ -360,15 +360,15 @@ static int _device_open_mmap(struct device_t *dev) {
|
||||
|
||||
static int _device_open_queue_buffers(struct device_t *dev) {
|
||||
for (unsigned index = 0; index < dev->run->n_buffers; ++index) {
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_buffer buf_info;
|
||||
|
||||
MEMSET_ZERO(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = index;
|
||||
MEMSET_ZERO(buf_info);
|
||||
buf_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf_info.memory = V4L2_MEMORY_MMAP;
|
||||
buf_info.index = index;
|
||||
|
||||
LOG_DEBUG("Calling ioctl(VIDIOC_QBUF) for buffer %d ...", index);
|
||||
if (xioctl(dev->run->fd, VIDIOC_QBUF, &buf) < 0) {
|
||||
if (xioctl(dev->run->fd, VIDIOC_QBUF, &buf_info) < 0) {
|
||||
LOG_PERROR("Can't VIDIOC_QBUF");
|
||||
return -1;
|
||||
}
|
||||
@ -377,34 +377,30 @@ static int _device_open_queue_buffers(struct device_t *dev) {
|
||||
}
|
||||
|
||||
static void _device_open_alloc_picbufs(struct device_t *dev) {
|
||||
unsigned max_picture_size = dev->run->width * dev->run->height << 1;
|
||||
|
||||
LOG_DEBUG("Allocating picture buffers ...");
|
||||
|
||||
A_CALLOC(dev->run->pictures, dev->run->n_buffers, sizeof(*dev->run->pictures));
|
||||
|
||||
unsigned picture_size = dev->run->width * dev->run->height << 1;
|
||||
|
||||
for (unsigned index = 0; index < dev->run->n_buffers; ++index) {
|
||||
LOG_DEBUG("Allocating picture buffer %d ...", index);
|
||||
A_MALLOC(dev->run->pictures[index], picture_size);
|
||||
A_MALLOC(dev->run->pictures[index].data, max_picture_size);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *_format_to_string_auto(char *buf, const size_t length, const unsigned format) {
|
||||
if (length < 8) {
|
||||
buf[0] = '\0';
|
||||
static const char *_format_to_string_auto(char *buf, const size_t size, const unsigned format) {
|
||||
assert(size >= 8);
|
||||
buf[0] = format & 0x7f;
|
||||
buf[1] = (format >> 8) & 0x7f;
|
||||
buf[2] = (format >> 16) & 0x7f;
|
||||
buf[3] = (format >> 24) & 0x7f;
|
||||
if (format & (1 << 31)) {
|
||||
buf[4] = '-';
|
||||
buf[5] = 'B';
|
||||
buf[6] = 'E';
|
||||
buf[7] = '\0';
|
||||
} else {
|
||||
buf[0] = format & 0x7f;
|
||||
buf[1] = (format >> 8) & 0x7f;
|
||||
buf[2] = (format >> 16) & 0x7f;
|
||||
buf[3] = (format >> 24) & 0x7f;
|
||||
if (format & (1 << 31)) {
|
||||
buf[4] = '-';
|
||||
buf[5] = 'B';
|
||||
buf[6] = 'E';
|
||||
buf[7] = '\0';
|
||||
} else {
|
||||
buf[4] = '\0';
|
||||
}
|
||||
buf[4] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
23
src/device.h
23
src/device.h
@ -9,20 +9,25 @@
|
||||
#define STANDARD_UNKNOWN V4L2_STD_UNKNOWN
|
||||
|
||||
|
||||
struct buffer_t {
|
||||
struct hw_buffer_t {
|
||||
void *start;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
struct picture_t {
|
||||
unsigned char *data;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
struct device_runtime_t {
|
||||
int fd;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned format;
|
||||
unsigned n_buffers;
|
||||
struct buffer_t *buffers;
|
||||
unsigned char **pictures;
|
||||
bool capturing;
|
||||
int fd;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned format;
|
||||
unsigned n_buffers;
|
||||
struct hw_buffer_t *hw_buffers;
|
||||
struct picture_t *pictures;
|
||||
bool capturing;
|
||||
};
|
||||
|
||||
struct device_t {
|
||||
|
||||
17
src/jpeg.c
17
src/jpeg.c
@ -42,11 +42,11 @@ struct mjpg_destination_mgr {
|
||||
struct jpeg_destination_mgr mgr; // Default manager
|
||||
JOCTET *buffer; // Start of buffer
|
||||
unsigned char *outbuffer_cursor;
|
||||
int *written;
|
||||
unsigned long *written;
|
||||
};
|
||||
|
||||
|
||||
static void _jpeg_set_dest_picture(j_compress_ptr jpeg, unsigned char *picture, int *written);
|
||||
static void _jpeg_set_dest_picture(j_compress_ptr jpeg, unsigned char *picture, unsigned long *written);
|
||||
|
||||
static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg,
|
||||
unsigned char *line_buffer, const unsigned char *data,
|
||||
@ -65,20 +65,20 @@ static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg);
|
||||
static void _jpeg_term_destination(j_compress_ptr jpeg);
|
||||
|
||||
|
||||
int jpeg_compress_buffer(struct device_t *dev, int index) {
|
||||
unsigned long jpeg_compress_buffer(struct device_t *dev, int index) {
|
||||
// This function based on compress_image_to_jpeg() from mjpg-streamer
|
||||
|
||||
struct jpeg_compress_struct jpeg;
|
||||
struct jpeg_error_mgr jpeg_error;
|
||||
unsigned char *line_buffer;
|
||||
int written = -1;
|
||||
|
||||
A_CALLOC(line_buffer, dev->run->width * 3, sizeof(unsigned char));
|
||||
|
||||
jpeg.err = jpeg_std_error(&jpeg_error);
|
||||
jpeg_create_compress(&jpeg);
|
||||
|
||||
_jpeg_set_dest_picture(&jpeg, dev->run->pictures[index], &written);
|
||||
dev->run->pictures[index].size = 0;
|
||||
_jpeg_set_dest_picture(&jpeg, dev->run->pictures[index].data, &dev->run->pictures[index].size);
|
||||
|
||||
jpeg.image_width = dev->run->width;
|
||||
jpeg.image_height = dev->run->height;
|
||||
@ -91,7 +91,7 @@ int jpeg_compress_buffer(struct device_t *dev, int index) {
|
||||
jpeg_start_compress(&jpeg, TRUE);
|
||||
|
||||
# define WRITE_SCANLINES(_func) \
|
||||
_func(&jpeg, line_buffer, dev->run->buffers[index].start, dev->run->width, dev->run->height)
|
||||
_func(&jpeg, line_buffer, dev->run->hw_buffers[index].start, dev->run->width, dev->run->height)
|
||||
|
||||
switch (dev->run->format) {
|
||||
case V4L2_PIX_FMT_YUYV: WRITE_SCANLINES(_jpeg_write_scanlines_yuyv); break;
|
||||
@ -105,10 +105,11 @@ int jpeg_compress_buffer(struct device_t *dev, int index) {
|
||||
jpeg_finish_compress(&jpeg);
|
||||
jpeg_destroy_compress(&jpeg);
|
||||
free(line_buffer);
|
||||
return written;
|
||||
assert(dev->run->pictures[index].size > 0);
|
||||
return dev->run->pictures[index].size;
|
||||
}
|
||||
|
||||
static void _jpeg_set_dest_picture(j_compress_ptr jpeg, unsigned char *picture, int *written) {
|
||||
static void _jpeg_set_dest_picture(j_compress_ptr jpeg, unsigned char *picture, unsigned long *written) {
|
||||
struct mjpg_destination_mgr *dest;
|
||||
|
||||
if (jpeg->dest == NULL) {
|
||||
|
||||
@ -5,4 +5,4 @@
|
||||
#include "device.h"
|
||||
|
||||
|
||||
int jpeg_compress_buffer(struct device_t *dev, int index);
|
||||
unsigned long jpeg_compress_buffer(struct device_t *dev, int index);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user